ao_module.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950
  1. /*
  2. ArOZ Online Module API wrapper
  3. This script is used for wrapping all the API that can be called by the ArOZ Online Module under VDI mode.
  4. For faster development, please include this script into your module and call through this script.
  5. Or otherwise, you can call directly to the ArOZ Online System via GET / POST request.
  6. <!> Warning! This script require jQuery to work.
  7. Although some functions might not require jquery, it is still recommended. You can include the jquery file from
  8. AOR/script/jquery.min.js
  9. Toby Chui @ IMUS Laboratory, All Right Reserved
  10. */
  11. //Check if current module is called in Virtal Desktop Mode
  12. var ao_module_virtualDesktop = !(!parent.isFunctionBar);
  13. //Get the current windowID if in Virtual Desktop Mode, return false if VDI is not detected
  14. var ao_module_windowID = false;
  15. var ao_module_parentID = false;
  16. var ao_module_callback = false;
  17. if (ao_module_virtualDesktop)ao_module_windowID = $(window.frameElement).parent().attr("id");
  18. if (ao_module_virtualDesktop)ao_module_parentID = $(window.frameElement).parent().find(".floatWindow").attr("puid");
  19. if (ao_module_virtualDesktop)ao_module_callback = $(window.frameElement).parent().find(".floatWindow").attr("callback");
  20. //Set the current FloatWindow with specified icon
  21. function ao_module_setWindowIcon(icon){
  22. if (ao_module_virtualDesktop){
  23. parent.setWindowIcon(ao_module_windowID + "",icon);
  24. return true;
  25. }
  26. return false;
  27. }
  28. //Set the current FloatWindow with specified title tag
  29. function ao_module_setWindowTitle(title){
  30. if (ao_module_virtualDesktop){
  31. parent.changeWindowTitle(ao_module_windowID + "",title);
  32. return true;
  33. }
  34. return false;
  35. }
  36. //Set the current FloatWindow to GlassEffect Window (Cannot switch back to origianl mode)
  37. function ao_module_setGlassEffectMode(){
  38. if (ao_module_virtualDesktop){
  39. parent.setGlassEffectMode(ao_module_windowID + "");
  40. return true;
  41. }
  42. return false;
  43. }
  44. //Set the current FloatWindow to Fixed Size Window (Non-resizable), default Resizable
  45. function ao_module_setFixedWindowSize(){
  46. if (ao_module_virtualDesktop){
  47. parent.setWindowFixedSize(ao_module_windowID + "");
  48. return true;
  49. }
  50. return false;
  51. }
  52. //Set the current FloatWindow size (width, height)
  53. function ao_module_setWindowSize(w,h){
  54. if (ao_module_virtualDesktop){
  55. parent.setWindowPreferdSize(ao_module_windowID + "",w,h);
  56. return true;
  57. }
  58. return false;
  59. }
  60. //Close the current window
  61. function ao_module_close(){
  62. if (ao_module_virtualDesktop){
  63. parent.closeWindow(ao_module_windowID);
  64. return true;
  65. }
  66. return false;
  67. }
  68. //Get the windows that is running the given module name and return an id list for floatWindow
  69. function ao_module_getProcessID(modulename){
  70. if (ao_module_virtualDesktop){
  71. return parent.getWindowFromModule(modulename);
  72. }
  73. return false;
  74. }
  75. //Crashed
  76. function ao_module_declareCrash(crashmsg){
  77. return false;
  78. }
  79. //Open file selector
  80. /**
  81. * File Explorer powered by ArOZ Online File System
  82. * To pop up a file selector and return an object of files, you can call the following function with the given variable.
  83. * Usage: ao_module_openFileSelector({uid},{call back function name in String},{window Width},{windowHeight},{allowMultipleFiles},{selectMode});
  84. * For example, this is a function which FFmpeg Factory calls to the file selector
  85. *
  86. * var uid = ao_module_utils.getRandomUID();
  87. * ao_module_openFileSelector(uid,"addFileFromSelector",undefined,undefined,true);
  88. *
  89. * This will allow the file selector get files (as selectMode default value is "file") and allow multiple selections
  90. * The selectMode option provide modes for file / folder / mix, where mix means user can select both files and folders
  91. * The allowMultiple means if the user can select multiple files. True for allow and false for disallow multi selections.
  92. *
  93. * To catch the callback of the selector, you can put the following script into your callBack function (In this case, 'addFileFromSelector')
  94. *
  95. * function addFileFromSelector(fileData){
  96. * result = JSON.parse(fileData);
  97. * for (var i=0; i < result.length; i++){
  98. * var filename = result[i].filename;
  99. * var filepath = result[i].filepath;
  100. * //DO SOMETHING HERE
  101. * }
  102. * }
  103. *
  104. * REMINDER
  105. * If you call this function in default mode, please use the "ao_module_openFileSelectorTab" and pass in the relative location of AOR (Root of ArOZ) as the first variable.
  106. * You will also need to handle the listen of change in the uid in localStorage for cross tab communication
  107. **/
  108. function ao_module_openFileSelector(uid,callBackFunctionName, windowWidth = 1080, windowHeight = 645, allowMultiple = false, selectMode = "file"){
  109. //selectMode: file / folder / mix
  110. //allowMultiple: true / false
  111. if (allowMultiple){
  112. allowMultiple = "true";
  113. }else{
  114. allowMultiple = "false";
  115. }
  116. if (ao_module_virtualDesktop){
  117. //Launch inside VDI
  118. ao_module_newfw("SystemAOB/functions/file_system/fileSelector.php?allowMultiple=" + allowMultiple + "&selectMode=" + selectMode,"Starting file selector","spinner",uid,windowWidth,windowHeight,ao_module_getLeft() + 30,ao_module_getTop() + 30,undefined,undefined,ao_module_windowID,callBackFunctionName);
  119. return true;
  120. }else{
  121. return false;
  122. }
  123. }
  124. //Request file selection OUTSIDE OF VDI MODE (REQUIRE localStorage)
  125. /**
  126. This function can be used to call the file selector in non-VDI mode.
  127. The following example shows the method of calling, similar to that in VDI mode.
  128. Assume we have a module at AOR/Dummy/index.php, the script running in that module has an aor = ../
  129. var uid = ao_module_utils.getRandomUID();
  130. ao_module_openFileSelectorTab(uid,"../",true,"file",fileProcesser);
  131. //fileProcessor will catch the file selection
  132. function fileProcesser(fileData){
  133. result = JSON.parse(fileData);
  134. for (var i=0; i < result.length; i++){
  135. var filename = result[i].filename;
  136. var filepath = result[i].filepath;
  137. //DO SOMETHING HERE
  138. }
  139. }
  140. **/
  141. var ao_module_fileSelectorCallBack,ao_module_fileSelectorWindowObject,ao_module_fileSelectorReplyObject,ao_module_fileSelectorFileAwait;
  142. function ao_module_openFileSelectorTab(uid, aor,allowMultiple = false, selectMode = "file",callBack=console.log){
  143. //selectMode: file / folder / mix
  144. //allowMultiple: true / false
  145. if (allowMultiple){
  146. allowMultiple = "true";
  147. }else{
  148. allowMultiple = "false";
  149. }
  150. if (aor.slice(-1) != "/"){
  151. aor = aor + "/";
  152. }
  153. ao_module_fileSelectorReplyObject = uid;
  154. ao_module_fileSelectorCallBack = callBack;
  155. var windowObject = window.open(aor + "/SystemAOB/functions/file_system/fileSelector.php?allowMultiple=" + allowMultiple + "&selectMode=" + selectMode + "&puid=" + uid);
  156. ao_module_fileSelectorWindowObject = windowObject;
  157. ao_module_fileSelectorFileAwait = setInterval(ao_module_listenFileSelectionInput,5000);
  158. return windowObject;
  159. }
  160. //Cross-tab File Selector Listener for File Selector Callback purpose. This is not a usable function. Do not touch this function.
  161. function ao_module_listenFileSelectionInput(){
  162. var ao_module_fileSelectorReturnedFiles = ao_module_readTmp(ao_module_fileSelectorReplyObject);
  163. if (ao_module_fileSelectorReturnedFiles == false && ao_module_fileSelectorReturnedFiles.length === undefined){
  164. }else{
  165. //File found! Closing all selection windows and load the files
  166. clearInterval(ao_module_fileSelectorFileAwait);
  167. if (ao_module_fileSelectorReturnedFiles.length == 0){
  168. //Cancel selection
  169. ao_module_fileSelectorCallBack(JSON.stringify([]));
  170. }else{
  171. ao_module_fileSelectorWindowObject.close();
  172. ao_module_removeTmp(ao_module_fileSelectorReplyObject);
  173. ao_module_fileSelectorReplyObject = undefined;
  174. ao_module_fileSelectorCallBack(JSON.stringify(ao_module_fileSelectorReturnedFiles));
  175. }
  176. }
  177. }
  178. //Open an ArOZ Online Path with the given targetPath from ArOZ Online Root
  179. /**
  180. For example, if you want to open the folder:
  181. "AOR/Audio/uploads/"
  182. Then you can call this function as follow:
  183. ao_module_openPath("Audio/uploads");
  184. **/
  185. function ao_module_openPath(targetPath, windowWidth = 1080, windowHeight = 580,posx = undefined,posy = undefined,resizable = true,glassEffect = true){
  186. if (ao_module_virtualDesktop){
  187. var uid = Date.now();
  188. parent.newEmbededWindow("SystemAOB/functions/file_system/index.php?controlLv=2&subdir=" + targetPath, "Loading", "folder open outline",uid,windowWidth,windowHeight,posx,posy,resizable,glassEffect);
  189. return uid;
  190. }
  191. return false;
  192. }
  193. //Open an ArOZ Online File with the given targetPath and filename (display name) from ArOZ Online Root
  194. /**
  195. For example, if you want to open the file:
  196. "AOR/Desktop/files/admin/helloworld.txt"
  197. Then you can call this function as follow:
  198. ao_module_openFile("Desktop/files/admin/helloworld.txt","helloworld.txt");
  199. The targetpath can be something different from the filename (display name). For example, an encoded file with path:
  200. "Desktop/files/TC/inithe38090e5b08fe9878ee5b48ee4babae38091546f75686f754d4144202d20546f75686f752026204e69746f72692047657420446f776e2120282b6c797269632920e380904844e38091205b373230705d.mp4"
  201. can be opened with filename
  202. "【小野崎人】TouhouMAD - Touhou %26 Nitori Get Down! (+lyric) 【HD】 [720p].mp4" with the following command:
  203. ao_module_openFile("Desktop/files/TC/inithe38090e5b08fe9878ee5b48ee4babae38091546f75686f754d4144202d20546f75686f752026204e69746f72692047657420446f776e2120282b6c797269632920e380904844e38091205b373230705d.mp4","【小野崎人】TouhouMAD - Touhou %26 Nitori Get Down! (+lyric) 【HD】 [720p].mp4");
  204. **/
  205. function ao_module_openFile(targetPath,filename){
  206. if (ao_module_virtualDesktop){
  207. parent.newEmbededWindow("SystemAOB/functions/file_system/index.php?controlLv=2&mode=file&dir=" + targetPath + "&filename=" + filename, filename, "file outline","fileOpenMiddleWare",0,0,-10,-10);
  208. return true;
  209. }
  210. return false;
  211. }
  212. //Open a FloatWindow
  213. /**
  214. Example 1: opening the Memo index with the following code:
  215. ao_module_newfw('Memo/index.php','Memo','sticky note outline','memoEmbedded',475,700);
  216. Example 2: opening the Memo index with minimal parameter:
  217. ao_module_newfw('Memo/index.php','Memo','sticky note outline','memoEmbedded');
  218. Example 3: opening a sub-module and tell the sub-module the parent's window id that is not yourself:
  219. ao_module_newfw('Memo/index.php','Memo','sticky note outline','memoEmbedded',undefined,undefined,undefined,undefined,undefined,undefined,"someoneElseUID");
  220. Example 4: opening a sub-module and ask for a callback: (Default parentUID is set to this module's WindowID and hence, the call back will be called to this content window)
  221. ao_module_newfw('Memo/index.php','Memo','sticky note outline','memoEmbedded',undefined,undefined,undefined,undefined,undefined,undefined,undefined,"callBackFunctionName");
  222. Reminder:
  223. - If you open multiple windows with the same UID, the previous one will be overwritten and reload to the latest page.
  224. - windowname parameter must not contain chars that cannot be put inside an id field (e.g. "&", "." etc)
  225. - For a list of icons, please reference https://tocas-ui.com/elements/icon/
  226. **/
  227. function ao_module_newfw(src,windowname,icon,uid,sizex = undefined,sizey = undefined,posx = undefined,posy = undefined,fixsize = undefined,glassEffect = undefined,parentUID=null, callbackFunct=null){
  228. if (parentUID === null){
  229. parentUID = ao_module_windowID;
  230. }
  231. if (ao_module_virtualDesktop){
  232. parent.newEmbededWindow(src,windowname,icon,uid,sizex,sizey,posx,posy,fixsize,glassEffect,parentUID,callbackFunct);
  233. return true;
  234. }
  235. return false;
  236. }
  237. //Launch a module using FloatWindow.php
  238. //Pass in the module folder name as the input. Example: ao_module_launchModule("Audio");
  239. //Please make sure the module support legacy FloatWindow.php launch method before calling.
  240. function ao_module_launchModule(moduleName){
  241. if (ao_module_virtualDesktop){
  242. parent.LaunchFloatWindowFromModule(moduleName,true);
  243. return true;
  244. }else{
  245. return false;
  246. }
  247. }
  248. //Request fullscreen access from VDI module
  249. function ao_module_fullScreen(){
  250. if (ao_module_virtualDesktop){
  251. parent.openFullscreen();
  252. return true;
  253. }
  254. return false;
  255. }
  256. //Get the basic information of the floatWindows (including the width, height, left and top value)
  257. function ao_module_getWidth(){
  258. if (ao_module_virtualDesktop){
  259. return parent.document.getElementById(ao_module_windowID).offsetWidth;
  260. }else{
  261. return -1;
  262. }
  263. }
  264. function ao_module_getHeight(){
  265. if (ao_module_virtualDesktop){
  266. return parent.document.getElementById(ao_module_windowID).offsetHeight;
  267. }else{
  268. return -1;
  269. }
  270. }
  271. function ao_module_getLeft(){
  272. if (ao_module_virtualDesktop){
  273. return parent.document.getElementById(ao_module_windowID).getBoundingClientRect().left;
  274. }else{
  275. return -1;
  276. }
  277. }
  278. function ao_module_getTop(){
  279. if (ao_module_virtualDesktop){
  280. return parent.document.getElementById(ao_module_windowID).getBoundingClientRect().top;
  281. }else{
  282. return -1;
  283. }
  284. }
  285. //Showing msgbox at the notification side bar
  286. /**
  287. For example, the most basic use of this command will be:
  288. ao_module_msgbox("This is a demo message from the aroz online module.","Hello World");
  289. You can add more object to the message including HTML tags in msg and title, and redirection path for opening the target etc.
  290. If auto close = false, the side bar will not get hidden after 4 seconds.
  291. **/
  292. function ao_module_msgbox(warningMsg,title="",redirectpath="",autoclose=true){
  293. if (ao_module_virtualDesktop){
  294. parent.msgbox(warningMsg,title,redirectpath,autoclose);
  295. return true;
  296. }
  297. return false;
  298. }
  299. //Focus this floatWindow and bring it to the front
  300. /**
  301. This function bring the current floatWindow content to the front of all FloatWindows.
  302. Please use this only in urgent / warning information. This might bring interuption to user's operation and making them unhappy :(
  303. **/
  304. function ao_module_focus(){
  305. if (ao_module_virtualDesktop){
  306. parent.focusFloatWindow(ao_module_windowID);
  307. return true;
  308. }else{
  309. return false;
  310. }
  311. }
  312. //Return the object in which the main interface iframe (The most backgound iframe. Mostly Desktop when you are using VDI mode. But you can change it if required).
  313. function ao_module_callToInterface(){
  314. return parent.callToInterface();
  315. }
  316. //Cross iFrame communication pipeline
  317. /**
  318. This function can send data to parent callback function if necessary.
  319. Data has to be an data object
  320. Given the following condition
  321. parentID: test
  322. callback: setBackgroundColor
  323. with a function named setBackgroundColor(data) in the parent window (iframe)
  324. Then you can use the following example to send data to the parent frame
  325. Example: ao_module_parentCallback({color:"white"});
  326. The returned value will be the data object in stringify JSON.
  327. To get the original value of the data received by another window:
  328. function setBackgroundColor(data){
  329. object = (JSON.parse(data));
  330. console.log(object.color);
  331. }
  332. Console output:
  333. >>white
  334. **/
  335. function ao_module_parentCallback(data){
  336. if (ao_module_virtualDesktop && ao_module_parentID !== undefined && ao_module_callback !== undefined){
  337. data = JSON.stringify(data);
  338. var ao_module_parentTarget = parent.getWindowObjectFromID(ao_module_parentID);
  339. if (ao_module_parentTarget !== null){
  340. ao_module_parentTarget.eval(ao_module_callback + "('" + data + "')");
  341. return true;
  342. }else{
  343. return false;
  344. }
  345. }else{
  346. return false;
  347. }
  348. }
  349. /**
  350. REMINDER
  351. When your module require save and loading data from localStorage, we recommend using the naming method as follow.
  352. [ModuleName]_[Username]_[Properties].
  353. For example, you are developing a new "MusicMixer" Module and want to store the "songList" properties for user "Admin". Then the recommended localStorage syntax will be:
  354. MusicMixer_Admin_songList
  355. Example:
  356. ao_module_getStorage("MusicMixer","Admin","songList");
  357. ao_module_saveStorage("MusicMixer","Admin","songList","{some JSON string here}");
  358. **/
  359. //Load something from localStorage with given tag
  360. function ao_module_getStorage(moduleName,itemname){
  361. moduleName = moduleName.split("_").join("-");
  362. username = ao_module_utils.getUserName().split("_").join("-");
  363. itemname = itemname.split("_").join("-");
  364. return localStorage.getItem(moduleName + "_" + username + "_" + itemname);
  365. }
  366. //Save something into localStoarge with give tag and value
  367. function ao_module_saveStorage(moduleName,itemname,value){
  368. moduleName = moduleName.split("_").join("-");
  369. username = ao_module_utils.getUserName().split("_").join("-");
  370. itemname = itemname.split("_").join("-");
  371. localStorage.setItem(moduleName + "_" + username + "_" + itemname, value);
  372. return true;
  373. }
  374. //Write something to tmp, which can be used as callback or anything that is not important
  375. //The value can also be an object
  376. function ao_module_writeTmp(uid,value){
  377. uid = "tmp_" + uid;
  378. localStorage.setItem(uid,JSON.stringify(value));
  379. }
  380. function ao_module_readTmp(uid){
  381. uid = "tmp_" + uid;
  382. var value = localStorage.getItem(uid);
  383. if (value == null || value == "null"){
  384. return false;
  385. }
  386. return JSON.parse(value);
  387. }
  388. function ao_module_removeTmp(uid){
  389. uid = "tmp_" + uid;
  390. if (ao_module_readTmp(uid) == false){
  391. localStorage.removeItem(uid);
  392. }
  393. }
  394. //Check if the storage exists on this browser or not
  395. function ao_module_checkStorage(id){
  396. if (typeof(Storage) !== "undefined") {
  397. return true;
  398. } else {
  399. return false;
  400. }
  401. }
  402. /*
  403. ArOZ Online Cluster Services Functions
  404. These functions are desgined for powering the cluster services of the ArOZ Cluster System.
  405. These 3 functions provide a GUI for user to select a desired parallel processing host / clusters.
  406. To use this in Tab Mode (Non-VDI mode), use the ao_module_openClusterSelectorTab() function instead.
  407. ao_module_openClusterSelector()
  408. Example Usage: (Node Selection)
  409. function openClusterSelect(){
  410. var uid = ao_module_utils.getRandomUID();
  411. if (ao_module_virtualDesktop){
  412. ao_module_openClusterSelector(uid,"clusterProcess");
  413. }else{
  414. ao_module_openClusterSelectorTab(uid,"../",undefined,undefined,clusterProcess);
  415. }
  416. }
  417. or (Disk Selection)
  418. function openClusterDriveSelect(){
  419. var uid = ao_module_utils.getRandomUID();
  420. if (ao_module_virtualDesktop){
  421. ao_module_openClusterSelector(uid,"diskProcess",undefined,undefined,undefined,"disk");
  422. }else{
  423. ao_module_openClusterSelectorTab(uid,"../",undefined,"disk",diskProcess);
  424. }
  425. }
  426. Example return functions:
  427. function diskProcess(diskInfo){
  428. result = JSON.parse(diskInfo);
  429. for (var i=0; i < result.length; i++){
  430. var diskID = result[i].diskID;
  431. //Do something here
  432. }
  433. }
  434. function clusterProcess(clusterData){
  435. $("#reply").html("");
  436. result = JSON.parse(clusterData);
  437. for (var i=0; i < result.length; i++){
  438. var clusterIP = result[i].hostIP;
  439. var clusterUUID = result[i].hostUUID;
  440. var online = result[i].hostOnline;
  441. //Do something here
  442. }
  443. }
  444. */
  445. var ao_module_clusterSelectorCallBack,ao_module_clusterSelectorWindowObject,ao_module_clusterSelectorReplyObject,ao_module_clusterSelectorFileAwait;
  446. function ao_module_openClusterSelector(uid,callBackFunctionName, windowWidth = 1080, windowHeight = 645, allowMultiple = false, selectMode = "node"){
  447. //selectMode: node / disk
  448. //allowMultiple: true / false
  449. if (allowMultiple){
  450. allowMultiple = "true";
  451. }else{
  452. allowMultiple = "false";
  453. }
  454. if (ao_module_virtualDesktop){
  455. //Launch inside VDI
  456. ao_module_newfw("SystemAOB/functions/cluster/clusterSelector.php?allowMultiple=" + allowMultiple + "&selectMode=" + selectMode,"Starting cluster selector","spinner",uid,windowWidth,windowHeight,ao_module_getLeft() + 30,ao_module_getTop() + 30,undefined,undefined,ao_module_windowID,callBackFunctionName);
  457. return true;
  458. }else{
  459. return false;
  460. }
  461. }
  462. function ao_module_openClusterSelectorTab(uid, aor,allowMultiple = false, selectMode = "node",callBack=console.log){
  463. //selectMode: node / disk
  464. //allowMultiple: true / false
  465. if (allowMultiple){
  466. allowMultiple = "true";
  467. }else{
  468. allowMultiple = "false";
  469. }
  470. if (aor.slice(-1) != "/"){
  471. aor = aor + "/";
  472. }
  473. ao_module_clusterSelectorReplyObject = uid;
  474. ao_module_clusterSelectorCallBack = callBack;
  475. var windowObject = window.open(aor + "/SystemAOB/functions/cluster/clusterSelector.php?allowMultiple=" + allowMultiple + "&selectMode=" + selectMode + "&puid=" + uid);
  476. ao_module_clusterSelectorWindowObject = windowObject;
  477. ao_module_clusterSelectorFileAwait = setInterval(ao_module_listenClusterSelectionInput,5000);
  478. return windowObject;
  479. }
  480. //Cross-tab File Selector Listener for File Selector Callback purpose. This is not a usable function. Do not touch this function.
  481. function ao_module_listenClusterSelectionInput(){
  482. var ao_module_clusterSelectorReturnedFiles = ao_module_readTmp(ao_module_clusterSelectorReplyObject);
  483. if (ao_module_clusterSelectorReturnedFiles == false && ao_module_clusterSelectorReturnedFiles.length === undefined){
  484. }else{
  485. //File found! Closing all selection windows and load the files
  486. clearInterval(ao_module_clusterSelectorFileAwait);
  487. if (ao_module_clusterSelectorReturnedFiles.length == 0){
  488. //Cancel selection
  489. ao_module_clusterSelectorCallBack(JSON.stringify([]));
  490. }else{
  491. ao_module_clusterSelectorWindowObject.close();
  492. ao_module_removeTmp(ao_module_clusterSelectorReplyObject);
  493. ao_module_clusterSelectorReplyObject = undefined;
  494. ao_module_clusterSelectorCallBack(JSON.stringify(ao_module_clusterSelectorReturnedFiles));
  495. }
  496. }
  497. }
  498. /*
  499. ArOZ Online Module Input Method Editor / Extension
  500. These functions for designed for custom input method.
  501. Please refer to the implementation comments listed below.
  502. */
  503. class ao_module_inputs{
  504. //Define this module window as an Input Method
  505. /*
  506. //The following function should be defined at the first line of Javascript of your input method for handling the key events
  507. //THESE SECTIONS OF CODE ARE FOR WEBAPP THAT IS DESIGNED TO BE A INPUT METHOD ONLY
  508. ao_module_inputs.defineInputMethod(function(e) {
  509. //Your code here, e is the event handler which should be passed through to this iframe by the typing target window
  510. });
  511. //You can also undefined the Input Method (Optional) on beforeUnload
  512. ao_module_inputs.undefineInputMethod();
  513. */
  514. static defineInputMethod(keyHandlerFunct){
  515. parent.window.inputMethod = ao_module_windowID;
  516. window.keyHandler = keyHandlerFunct;
  517. }
  518. //Undefined this module window as an Input Method
  519. static undefineInputMethod(){
  520. parent.window.inputMethod = undefined;
  521. window.keyHandler = undefined;
  522. }
  523. //Allow module to hook functions from local script to stdIn for Input Method bypass
  524. /*
  525. //THESE SECTION OF CODE IS DESIGN FOR MODULE THAT RECEIVE INPUT FROM INPUT METHODS
  526. //Assume you have an input field that is going to filled in by string returned by the input method.
  527. //Then, you can first hook the StdIn of your WebAPP as follow.
  528. ao_module_inputs.hookStdIn(function(text){
  529. //text variable is the string that the user typed via the IME
  530. $("#input").append(text);
  531. });
  532. //Next, you need to hand the key input event to the input method.
  533. document.addEventListener("keydown", ao_module_inputs.hookKeyHandler, false);
  534. */
  535. static hookStdIn(localFunction){
  536. //Check if any input method is hooked. If yes, allow hooking
  537. if (parent.window.inputMethod != undefined){
  538. window.stdIn = localFunction;
  539. }else{
  540. return false;
  541. }
  542. }
  543. //Do not include the following function into your code. This is used for callback purpose only.
  544. static hookKeyHandler(event){
  545. if (parent.window.inputMethod != undefined){
  546. var InputMethod = parent.window.document.getElementById(parent.window.inputMethod);
  547. if ($(InputMethod).length == 0){
  548. //Input method no longer exists
  549. return false;
  550. }
  551. $(InputMethod).find("iframe")[0].contentWindow.keyHandler(event);
  552. }else{
  553. return false;
  554. }
  555. }
  556. //Sent output text to the current focused Windows
  557. /*
  558. //This function send text (or character) to the focused windows's hookStdIn defined function
  559. //THIS FUNCTION IS FOR WEBAPP THAT IS DESIGNED FOR BEING AN INPUT METHOD ONLY
  560. ao_module_inputs.stdOut(text);
  561. */
  562. static stdOut(text){
  563. var targetWindow = parent.focusedWindow;
  564. if ($(targetWindow).parent().attr("id") == ao_module_windowID){
  565. //This is this windows. Ignore the StdOut
  566. return;
  567. }
  568. targetWindow = $(targetWindow).parent().find("iframe")[0];
  569. if (targetWindow.contentWindow != null && typeof targetWindow.contentWindow.stdIn != undefined && targetWindow.contentWindow.stdIn != undefined){
  570. //This module allow stdIn Hooking, send it text!
  571. targetWindow.contentWindow.stdIn(text);
  572. }else{
  573. //This module do not allow hooking to input methods
  574. return false;
  575. }
  576. }
  577. }
  578. /**
  579. ArOZ Online Module Functions for WebSocket Communication
  580. The default port for ArOZ Online Websocket Server is 65530.
  581. This function is not usable if you don't have a valid websocket setup.
  582. **/
  583. class ao_module_ws{
  584. constructor(webSocketLocation) {
  585. if (webSocketLocation == undefined){
  586. return false;
  587. }
  588. this.webSocketLocation = webSocketLocation;
  589. return true;
  590. }
  591. init(){
  592. this.websocket = new WebSocket(this.webSocketLocation);
  593. this.websocket.onopen = this.onOpen;
  594. this.websocket.onclose = this.onClose;
  595. this.websocket.onerror = this.onError;
  596. this.websocket.onmessage = this.onMessage;
  597. return this.websocket;
  598. }
  599. onOpen(evt){
  600. console.log(evt.data);
  601. }
  602. onClose(evt){
  603. console.log("DISCONNECTED");
  604. return true;
  605. }
  606. onMessage(evt){
  607. console.log(evt.data);
  608. }
  609. onError(evt){
  610. console.log(evt.data);
  611. }
  612. sendText(message){
  613. this.websocket.send(message);
  614. return true;
  615. }
  616. disconnect(){
  617. this.websocket.close();
  618. return this.websocket.readyState;
  619. }
  620. get ws(){
  621. return this.websocket;
  622. }
  623. get location(){
  624. return this.webSocketLocation;
  625. }
  626. get connected(){
  627. return this.websocket.readyState;
  628. }
  629. }
  630. /**
  631. ArOZ Online Module Utils for quick deploy of ArOZ Online WebApps
  632. ao_module_utils.objectToAttr(object); //object to DOM attr
  633. ao_module_utils.attrToObject(attr); //DOM attr to Object
  634. ao_module_utils.getRandomUID(); //Get random UUID from timestamp
  635. ao_module_utils.getIconFromExt(ext); //Get icon tag from file extension
  636. **/
  637. class ao_module_utils{
  638. //Two simple functions for converting any Javascript object into string that can be put into the attr value of an DOM object
  639. static objectToAttr(object){
  640. return encodeURIComponent(JSON.stringify(object));
  641. }
  642. static attrToObject(attr){
  643. return JSON.parse(decodeURIComponent(attr));
  644. }
  645. //Get the current username from localStorage
  646. //Warning! This value might not be accurate as the user might change this by themself. If you want to ensure their username, use PHP $_SESSION['login'] instead.
  647. static getUserName(){
  648. return localStorage.getItem("ArOZusername");
  649. }
  650. //Get a random id for a new floatWindow, use with var uid = ao_module_utils.getRandomUID();
  651. static getRandomUID(){
  652. return new Date().getTime();
  653. }
  654. //Get the icon of a file with given extension (ext), use with ao_module_utils.getIconFromExt("ext");
  655. static getIconFromExt(ext){
  656. var ext = ext.toLowerCase().trim();
  657. var iconList={
  658. md:"file text outline",
  659. txt:"file text outline",
  660. pdf:"file pdf outline",
  661. doc:"file word outline",
  662. docx:"file word outline",
  663. odt:"file word outline",
  664. xlsx:"file excel outline",
  665. ods:"file excel outline",
  666. ppt:"file powerpoint outline",
  667. pptx:"file powerpoint outline",
  668. odp:"file powerpoint outline",
  669. jpg:"file image outline",
  670. png:"file image outline",
  671. jpeg:"file image outline",
  672. gif:"file image outline",
  673. odg:"file image outline",
  674. psd:"file image outline",
  675. zip:"file archive outline",
  676. '7z':"file archive outline",
  677. rar:"file archive outline",
  678. tar:"file archive outline",
  679. mp3:"file audio outline",
  680. m4a:"file audio outline",
  681. flac:"file audio outline",
  682. wav:"file audio outline",
  683. aac:"file audio outline",
  684. mp4:"file video outline",
  685. webm:"file video outline",
  686. php:"file code outline",
  687. html:"file code outline",
  688. htm:"file code outline",
  689. js:"file code outline",
  690. css:"file code outline",
  691. xml:"file code outline",
  692. json:"file code outline",
  693. csv:"file code outline",
  694. odf:"file code outline",
  695. bmp:"file image outline",
  696. rtf:"file text outline",
  697. wmv:"file video outline",
  698. mkv:"file video outline",
  699. ogg:"file audio outline",
  700. stl:"cube",
  701. obj:"cube",
  702. "3ds":"cube",
  703. fbx:"cube",
  704. collada:"cube",
  705. step:"cube",
  706. iges:"cube",
  707. gcode:"cube",
  708. shortcut:"external square",
  709. opus:"file audio outline"
  710. };
  711. var icon = "";
  712. if (ext == ""){
  713. icon = "folder outline";
  714. }else{
  715. icon = iconList[ext];
  716. if (icon == undefined){
  717. icon = "file outline"
  718. }
  719. }
  720. return icon;
  721. }
  722. }
  723. class ao_module_codec{
  724. //Decode umfilename into standard filename in utf-8, which umfilename usually start with "inith"
  725. //Example: ao_module_codec.decodeUmFilename(umfilename_here);
  726. static decodeUmFilename(umfilename){
  727. if (umfilename.includes("inith")){
  728. var data = umfilename.split(".");
  729. if (data.length == 1){
  730. //This is a filename without extension
  731. data = data[0].replace("inith","");
  732. var decodedname = ao_module_codec.decode_utf8(ao_module_codec.hex2bin(data));
  733. if (decodedname != "false"){
  734. //This is a umfilename
  735. return decodedname;
  736. }else{
  737. //This is not a umfilename
  738. return umfilename;
  739. }
  740. }else{
  741. //This is a filename with extension
  742. var extension = data.pop();
  743. var filename = data[0];
  744. filename = filename.replace("inith",""); //Javascript replace only remove the first instances (i.e. the first inith in filename)
  745. var decodedname = ao_module_codec.decode_utf8(ao_module_codec.hex2bin(filename));
  746. if (decodedname != "false"){
  747. //This is a umfilename
  748. return decodedname + "." + extension;
  749. }else{
  750. //This is not a umfilename
  751. return umfilename;
  752. }
  753. }
  754. }else{
  755. //This is not umfilename as it doesn't have the inith prefix
  756. return umfilename;
  757. }
  758. }
  759. //Decode hexFoldername into standard foldername in utf-8, return the original name if it is not a hex foldername
  760. //Example: ao_module_codec.decodeHexFoldername(hexFolderName_here);
  761. static decodeHexFoldername(folderName){
  762. var decodedFoldername = ao_module_codec.decode_utf8(ao_module_codec.hex2bin(folderName));
  763. if (decodedFoldername == "false"){
  764. //This is not a hex encoded foldername
  765. decodedFoldername = folderName;
  766. }else{
  767. //This is a hex encoded foldername
  768. decodedFoldername = "*" + decodedFoldername;
  769. }
  770. return decodedFoldername;
  771. }
  772. static hex2bin(s){
  773. var ret = []
  774. var i = 0
  775. var l
  776. s += ''
  777. for (l = s.length; i < l; i += 2) {
  778. var c = parseInt(s.substr(i, 1), 16)
  779. var k = parseInt(s.substr(i + 1, 1), 16)
  780. if (isNaN(c) || isNaN(k)) return false
  781. ret.push((c << 4) | k)
  782. }
  783. return String.fromCharCode.apply(String, ret)
  784. }
  785. static decode_utf8(s) {
  786. return decodeURIComponent(escape(s));
  787. }
  788. }
  789. /**
  790. Screenshot related functions
  791. This function make use of the html2canvas JavaScript library. For license and author, please refer to the html2canvas.js head section.
  792. target value are used to defined the operation after the screenshot.
  793. default / newWindow --> Open screenshot in new window
  794. dataurl --> return data url of the image as string
  795. canvas --> return the canvas object
  796. **/
  797. //Updates Removed Screenshot feature due to waste of resources
  798. /**
  799. //Take a screenshot from module body
  800. function ao_html2canvas_screenshot(target="newWindow",callback){
  801. if (typeof html2canvas != undefined){
  802. html2canvas(document.body).then(function(canvas) {
  803. if (target == "newWindow"){
  804. window.open(canvas.toDataURL("image/png"), '_blank');
  805. return true;
  806. }else if (target == "dataurl"){
  807. callback(canvas.toDataURL("image/png"));
  808. }else if (target == "canvas"){
  809. callback(canvas);
  810. }else{
  811. window.open(canvas.toDataURL("image/png"), '_blank');
  812. return true;
  813. }
  814. });
  815. }else{
  816. return false;
  817. }
  818. }
  819. function ao_html2canvas_getPreview(w,h){
  820. if (typeof html2canvas != undefined){
  821. html2canvas(document.body,{width: w,height: h}).then(function(canvas) {
  822. parent.updatePreview(canvas);
  823. });
  824. }else{
  825. return false;
  826. }
  827. }
  828. **/