1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162 |
- /*
- ArOZ Online Module Javascript Wrapper
- This is a wrapper for module developers to access system API easier and need not to dig through the source code.
- Basically: Write less do more (?)
- WARNING! SOME FUNCTION ARE NOT COMPATIBILE WITH PREVIOUS VERSION OF AO_MODULE.JS.
- PLEASE REFER TO THE SYSTEM DOCUMENTATION FOR MORE INFORMATION.
- *** Please include this javascript file with relative path instead of absolute path.
- E.g. ../script/ao_module.js (OK)
- /script/ao_module.js (NOT OK)
- */
- var ao_module_virtualDesktop = false;
- try{
- ao_module_virtualDesktop = !(!parent.isDesktopMode);
- }catch(ex){
- //Running ArozOS inside iframe for some reason
- console.log("CORS Access Error. Entering compatibility mode with virtual desktop mode disabled.");
- }
- var ao_root = null;
- //Get the current windowID if in Virtual Desktop Mode, return false if VDI is not detected
- var ao_module_windowID = false;
- var ao_module_parentID = false;
- var ao_module_callback = false;
- var ao_module_ime = false;
- if (ao_module_virtualDesktop)ao_module_windowID = $(window.frameElement).parent().parent().attr("windowId");
- if (ao_module_virtualDesktop)ao_module_parentID = $(window.frameElement).parent().parent().attr("parent");
- if (ao_module_virtualDesktop)ao_module_callback = $(window.frameElement).parent().parent().attr("callback");
- if (ao_module_virtualDesktop)ao_module_parentURL = $(window.frameElement).parent().find("iframe").attr("src");
- ao_root = ao_module_getAORootFromScriptPath();
- /*
- Event bindings
- The following events are required for ao_module to operate normally
- under Web Desktop Mode.
- */
- document.addEventListener("DOMContentLoaded", function() {
- if (ao_module_virtualDesktop){
- if (parent.window.ime == null){
- return;
- }
- //Add window focus handler
- document.addEventListener("mousedown", function(event) {
- //When click on this document, focus this
- ao_module_focus();
- if (event.target.tagName == "INPUT" || event.target.tagName == "TEXTAREA"){
- }else{
- if (parent.window.ime.focus != null){
- if (ao_module_ime){
- //This is clicking on ime windows. Do not change focus
- }else{
- parent.window.ime.focus = null;
- }
- }
- }
- }, true);
-
- //Add IME registration handler
- var inputFields = document.querySelectorAll("input,textarea");
- for (var i = 0; i < inputFields.length; i++){
- if ($(inputFields[i]).attr("type") != undefined){
- var thisType = $(inputFields[i]).attr("type");
- if ((thisType == "text" || thisType =="search" || thisType =="url")){
- //Supported types of input
- ao_module_bindCustomIMEEvents(inputFields[i]);
- }else{
- //Not supported type of inputs
- }
- }else{
- //text area
- ao_module_bindCustomIMEEvents(inputFields[i]);
- }
- }
- }
- /*
- //Load html2canvas
- if ($){
- $.getScript(ao_root + "script/html2canvas.min.js", function() {
- console.log("Html2canvas loaded")
- });
- }
- */
- });
- /*
- Startup Section Script
-
- These functions handle the startup of an ao_module and adapt them into the
- standard arozos desktop eco-system api
- */
- //Function handle to bind custom IME events
- function ao_module_bindCustomIMEEvents(object){
- parent.bindObjectToIMEEvents(object);
- }
- function ao_module_screenshot(callback){
- html2canvas(document.querySelector("body")).then(screenshot => {
- return callback(screenshot);
- });
- }
- //Get the ao_root from script includsion path
- function ao_module_getAORootFromScriptPath(){
- var possibleRoot = "";
- $("script").each(function(){
- if (this.hasAttribute("src") && $(this).attr("src").includes("ao_module.js")){
- var tmp = $(this).attr("src");
- tmp = tmp.split("script/ao_module.js");
- possibleRoot = tmp[0];
- }
- });
- return possibleRoot;
- }
- //Get the input filename and filepath from the window hash paramter
- function ao_module_loadInputFiles(){
- try{
- if (window.location.hash.length == 0){
- return null;
- }
- var inputFileInfo = window.location.hash.substring(1,window.location.hash.length);
- inputFileInfo = JSON.parse(decodeURIComponent(inputFileInfo));
- if (inputFileInfo.length == 0){
- return null;
- }
- return inputFileInfo
- }catch{
- return null;
- }
- }
- //Set the ao_module window to fixed size (not allowing resize)
- function ao_module_setFixedWindowSize(){
- if (!ao_module_virtualDesktop){
- return;
- }
- parent.setFloatWindowResizePolicy(ao_module_windowID, false);
- }
- //Restore a float window to be resizble
- function ao_module_setResizableWindowSize(){
- if (!ao_module_virtualDesktop){
- return;
- }
- parent.setFloatWindowResizePolicy(ao_module_windowID, true);
- }
- //Update the window size of the given float window object
- function ao_module_setWindowSize(width, height){
- if (!ao_module_virtualDesktop){
- return;
- }
- parent.setFloatWindowSize(ao_module_windowID, width, height)
- }
- //Update the floatWindow title
- function ao_module_setWindowTitle(newTitle){
- if (!ao_module_virtualDesktop){
- document.title = newTitle;
- return;
- }
- parent.setFloatWindowTitle(ao_module_windowID, newTitle);
- }
- //Set new window theme, default dark, support {dark/white}
- function ao_module_setWindowTheme(newtheme="dark"){
- if (!ao_module_virtualDesktop){
- return;
- }
- parent.setFloatWindowTheme(ao_module_windowID, newtheme);
- }
- //Check if there are any windows with the same path.
- //If yes, replace its hash content and reload to the new one and close the current floatWindow
- function ao_module_makeSingleInstance(){
- $(window.parent.document).find(".floatWindow").each(function(){
- if ($(this).attr("windowid") == ao_module_windowID){
- return
- }
- var currentPath = window.location.pathname;
- if ("/" + $(this).find("iframe").attr('src').split("#").shift() == currentPath){
- //Another instance already running. Replace it with the current path
- $(this).find("iframe").attr('src', window.location.pathname.substring(1) + window.location.hash);
- $(this).find("iframe")[0].contentWindow.location.reload();
- //Move the other instant to top
- var targetfw = parent.getFloatWindowByID($(this).attr("windowid"))
- parent.MoveFloatWindowToTop(targetfw);
- //Close the instance
- ao_module_close();
- return true
- }
- });
- return false
- }
- //Use for cross frame communication, example:
- //let targetOpeningInstances = ao_module_getInstanceByPath("NotepadA/index.html")
- function ao_module_getInstanceByPath(matchingPath){
- let targetInstance = "";
- $(window.parent.document).find(".floatWindow").each(function(){
- if ($(this).attr("windowid") == ao_module_windowID){
- return
- }
- let thisfwPath = $(this).find("iframe").attr('src').split("#").shift();
- if (thisfwPath == matchingPath){
- targetInstance = $(this).attr("windowid");
- }
- });
- if (targetInstance == ""){
- return null;
- }
-
- return parent.getFloatWindowByID(targetInstance);
- }
- //Close the current window
- function ao_module_close(){
- ao_module_closeHandler();
- }
- //Close handler for WebApp special handling of ao_module_close()
- function ao_module_closeHandler(){
- if (!ao_module_virtualDesktop){
- window.close('','_parent','');
- window.location.href = ao_root + "SystemAO/closeTabInsturction.html";
- return;
- }
- parent.closeFwProcess(ao_module_windowID);
- }
- //Focus this floatWindow
- function ao_module_focus(){
- parent.MoveFloatWindowToTop(parent.getFloatWindowByID(ao_module_windowID));
- }
- //Set the floatWindow to top most mode
- function ao_module_setTopMost(){
- parent.PinFloatWindowToTopMostMode(parent.getFloatWindowByID(ao_module_windowID));
- }
- //Unset the floatWindow top most mode
- function ao_module_unsetTopMost(){
- parent.UnpinFloatWindowFromTopMostMode(parent.getFloatWindowByID(ao_module_windowID));
- }
- //Popup a file selection window for uplaod
- function ao_module_selectFiles(callback, fileType="file", accept="*", allowMultiple=false){
- var input = document.createElement('input');
- input.type = fileType;
- input.multiple = allowMultiple;
- input.accept = accept;
- input.onchange = e => {
- var files = e.target.files;
- callback(files);
- }
- input.click();
- }
- //Open a path with File Manager, optional highligh filename
- function ao_module_openPath(path, filename=undefined){
- //Trim away the last / if exists
- if (path.substr(path.length - 1, 1) == "/"){
- path = path.substr(0, path.length - 1);
- }
- if (filename == undefined){
- if (ao_module_virtualDesktop){
- parent.newFloatWindow({
- url: "SystemAO/file_system/file_explorer.html#" + encodeURIComponent(path),
- appicon: "SystemAO/file_system/img/small_icon.png",
- width:1080,
- height:580,
- title: "File Manager"
- });
- }else{
- window.open(ao_root + "SystemAO/file_system/file_explorer.html#" + encodeURIComponent(path))
- }
- }else{
- var fileObject = [{
- filepath: path + "/" + filename,
- filename: filename,
- }];
- if (ao_module_virtualDesktop){
- parent.newFloatWindow({
- url: "SystemAO/file_system/file_explorer.html#" + encodeURIComponent(JSON.stringify(fileObject)),
- appicon: "SystemAO/file_system/img/small_icon.png",
- width:1080,
- height:580,
- title: "File Manager"
- });
- }else{
- window.open(ao_root + "SystemAO/file_system/file_explorer.html#" + encodeURIComponent(JSON.stringify(fileObject)))
- }
- }
-
- }
- //Open a particular tab using System Setting module. Require
- //1) Setting Group
- //2) Setting Name
- function ao_module_openSetting(group, name){
- var requestObject = {
- group: group,
- name: name
- }
- requestObject = encodeURIComponent(JSON.stringify(requestObject));
- var openURL = "SystemAO/system_setting/index.html#" + requestObject;
- if (ao_module_virtualDesktop){
- ao_module_newfw({
- url: openURL,
- width: 1080,
- height: 580,
- appicon: "SystemAO/system_setting/img/small_icon.png",
- title: "System Setting"
- });
- }else{
- window.open(ao_root + openURL)
- }
- }
- /*
- ao_module_newfw(launchConfig) => Create a new floatWindow object from the given paramters
- Most basic usage: (With auto assign UID, size and location)
- ao_module_newfw({
- url: "Dummy/index.html",
- title: "Dummy Module",
- appicon: "Dummy/img/icon.png"
- });
- Example usage that involve all configs:
- ao_module_newfw({
- url: "Dummy/index.html",
- uid: "CustomUUID",
- width: 1024,
- height: 768,
- appicon: "Dummy/img/icon.png",
- title: "Dummy Module",
- left: 100,
- top: 100,
- parent: ao_module_windowID,
- callback: "childCallbackHandler"
- });
- */
- function ao_module_newfw(launchConfig){
- if (launchConfig["parent"] == undefined){
- launchConfig["parent"] = ao_module_windowID;
- }
- if (ao_module_virtualDesktop){
- parent.newFloatWindow(launchConfig);
- }else{
- window.open(ao_root + launchConfig.url);
- }
- }
- /*
- File Selector
- Open a file selector and return selected item back to the current window
- Tips: Unlike the beta version, you can use this function in both Virtual Desktop Mode and normal mode.
- Possible selection type:
- type => {file / folder / all / new}
- Example usage:
- ao_module_openFileSelector(fileSelected, "user:/Desktop", "file",true);
- function fileSelected(filedata){
- for (var i=0; i < filedata.length; i++){
- var filename = filedata[i].filename;
- var filepath = filedata[i].filepath;
- //Do something here
- }
- }
- If you want to create a new file or folder object, you can use the following options paramters
- option = {
- defaultName: "newfile.txt", //Default filename used in new operation
- fnameOverride: "myfunction", //For those defined with window.myfunction
- filter: ["mp3","aac","ogg","flac","wav"] //File extension filter
- }
- */
- let ao_module_fileSelectionListener;
- let ao_module_fileSelectorWindow;
- function ao_module_openFileSelector(callback,root="user:/", type="file",allowMultiple=false, options=undefined){
- var initInfo = {
- root: root,
- type: type,
- allowMultiple: allowMultiple,
- listenerUUID: "",
- options: options
- }
- var initInfoEncoded = encodeURIComponent(JSON.stringify(initInfo))
- if (ao_module_virtualDesktop){
- var callbackname = callback.name;
- if (typeof(options) != "undefined" && typeof(options.fnameOverride) != "undefined"){
- callbackname = options.fnameOverride;
- }
- console.log(callbackname);
- parent.newFloatWindow({
- url: "SystemAO/file_system/file_selector.html#" + initInfoEncoded,
- width: 700,
- height: 440,
- appicon: "SystemAO/file_system/img/selector.png",
- title: "Open",
- parent: ao_module_windowID,
- callback: callbackname
- });
- }else{
- //Create a return listener base on localStorage
- let listenerUUID = "fileSelector_" + new Date().getTime();
- ao_module_fileSelectionListener = setInterval(function(){
- if (localStorage.getItem(listenerUUID) === undefined || localStorage.getItem(listenerUUID)=== null){
- //Not ready
- }else{
- //File ready!
- var selectedFiles = JSON.parse(localStorage.getItem(listenerUUID));
- console.log("Removing Localstorage Item " + listenerUUID);
-
- localStorage.removeItem(listenerUUID);
- setTimeout(function(){
- localStorage.removeItem(listenerUUID);
- },500);
- if(selectedFiles == "&&selection_canceled&&"){
- //Selection canceled. Returm empty array
- callback([]);
- }else{
- //Files Selected
- callback(selectedFiles);
- }
-
- clearInterval(ao_module_fileSelectionListener);
- ao_module_fileSelectorWindow.close();
- }
- },1000);
- //Open the file selector in a new tab
- initInfo.listenerUUID = listenerUUID;
- initInfoEncoded = encodeURIComponent(JSON.stringify(initInfo))
- ao_module_fileSelectorWindow = window.open(ao_root + "SystemAO/file_system/file_selector.html#" + initInfoEncoded,);
- }
- }
- //Check if there is parent to callback
- function ao_module_hasParentCallback(){
- if (ao_module_virtualDesktop){
- //Check if parent callback exists
- var thisFw;
- $(parent.window.document.body).find(".floatWindow").each(function(){
- if ($(this).attr('windowid') == ao_module_windowID){
- thisFw = $(this);
- }
- });
- var parentWindowID = thisFw.attr("parent");
- var parentCallback = thisFw.attr("callback");
- if (parentWindowID == "" || parentCallback == ""){
- //No parent window defined
- return false;
- }
- //Check if parent windows is alive
- var parentWindow = undefined;
- $(parent.window.document.body).find(".floatWindow").each(function(){
- if ($(this).attr('windowid') == parentWindowID){
- parentWindow = $(this);
- }
- });
- if (parentWindow == undefined){
- //parent window not exists
- return false;
- }
- //Parent callback is set and ready to callback
- return true;
- }else{
- return false
- }
- }
- //Callback to parent with results
- function ao_module_parentCallback(data=""){
- if (ao_module_virtualDesktop){
- var thisFw;
- $(parent.window.document.body).find(".floatWindow").each(function(){
- if ($(this).attr('windowid') == ao_module_windowID){
- thisFw = $(this);
- }
- });
- var parentWindowID = thisFw.attr("parent");
- var parentCallback = thisFw.attr("callback");
- if (parentWindowID == "" || parentCallback == ""){
- //No parent window defined
- console.log("Undefined parent window ID or callback name");
- return false;
- }
- var parentWindow = undefined;
- $(parent.window.document.body).find(".floatWindow").each(function(){
- if ($(this).attr('windowid') == parentWindowID){
- parentWindow = $(this);
- }
- });
- if (parentWindow == undefined){
- //parent window not exists
- console.log("Parent Window not exists!")
- return false;
- }
- $(parentWindow).find('iframe')[0].contentWindow.eval(parentCallback + "(" + JSON.stringify(data) + ");")
- //Focus the parent windows
- parent.MoveFloatWindowToTop(parentWindow);
- return true;
- }else{
- console.log("[ao_module] WARNING! Invalid call to parentCallback under non-virtualDesktop mode");
- return false;
- }
- }
- function ao_module_agirun(scriptpath, data, callback, failedcallback = undefined, timeout=0){
- $.ajax({
- url: ao_root + "system/ajgi/interface?script=" + scriptpath,
- method: "POST",
- data: data,
- success: function(data){
- if (typeof(callback) != "undefined"){
- callback(data);
- }
- },
- error: function(){
- if (typeof(failedcallback) != "undefined"){
- failedcallback();
- }
- },
- timeout: timeout
- });
- }
- function ao_module_uploadFile(file, targetPath, callback=undefined, progressCallback=undefined, failedcallback=undefined) {
- let url = ao_root + 'system/file_system/upload'
- let formData = new FormData()
- let xhr = new XMLHttpRequest()
- formData.append('file', file);
- formData.append('path', targetPath);
- xhr.open('POST', url, true);
- xhr.upload.addEventListener("progress", function(e) {
- if (progressCallback !== undefined){
- progressCallback((e.loaded * 100.0 / e.total) || 100);
- }
- });
- xhr.addEventListener('readystatechange', function(e) {
- if (xhr.readyState == 4 && xhr.status == 200) {
- if (callback !== undefined){
- callback(e.target.response);
- }
- }
- else if (xhr.readyState == 4 && xhr.status != 200) {
- if (failedcallback !== undefined){
- failedcallback(xhr.status);
- }
- }
- })
- xhr.send(formData);
- }
- /*
- ao_module_storage, allow key-value storage per module settings.
- WARNING: NOT CROSS USER READ-WRITABLE
-
- ao_module_storage.setStorage(moduleName, configName,configValue);
- ao_module_storage.loadStorage(moduleName, configName);
- */
- class ao_module_storage {
- static setStorage(moduleName, configName,configValue){
- $.ajax({
- type: 'GET',
- url: ao_root + "system/file_system/preference",
- data: {key: moduleName + "/" + configName,value:configValue},
- success: function(data){},
- async:true
- });
- return true;
- }
-
- static loadStorage(moduleName, configName, callback=undefined){
- var result = "";
- if (callback == undefined){
- //Do not use async
- $.ajax({
- type: 'GET',
- url: ao_root + "system/file_system/preference",
- data: {key: moduleName + "/" + configName},
- success: function(data){
- if (data.error !== undefined){
- result = "";
- }else{
- result = data;
- }
- },
- error: function(data){result = "";},
- async:false,
- timeout: 3000
- });
- return result;
- }else{
- //Use sync method
- $.ajax({
- type: 'GET',
- url: ao_root + "system/file_system/preference",
- data: {key: moduleName + "/" + configName},
- success: function(data){
- if (data.error !== undefined){
- callback("");
- }else{
- callback(data);
- }
- },
- error: function(evt){
- callback("");
- },
- timeout: 30000
- });
- }
-
-
- }
- }
- class ao_module_codec{
- //Decode umfilename into standard filename in utf-8, which umfilename usually start with "inith"
- //Example: ao_module_codec.decodeUmFilename(umfilename_here);
- static decodeUmFilename(umfilename){
- if (umfilename.includes("inith")){
- var data = umfilename.split(".");
- if (data.length == 1){
- //This is a filename without extension
- data = data[0].replace("inith","");
- var decodedname = ao_module_codec.decode_utf8(ao_module_codec.hex2bin(data));
- if (decodedname != "false"){
- //This is a umfilename
- return decodedname;
- }else{
- //This is not a umfilename
- return umfilename;
- }
- }else{
- //This is a filename with extension
- var extension = data.pop();
- var filename = data[0];
- filename = filename.replace("inith",""); //Javascript replace only remove the first instances (i.e. the first inith in filename)
- var decodedname = ao_module_codec.decode_utf8(ao_module_codec.hex2bin(filename));
- if (decodedname != "false"){
- //This is a umfilename
- return decodedname + "." + extension;
- }else{
- //This is not a umfilename
- return umfilename;
- }
- }
-
- }else{
- //This is not umfilename as it doesn't have the inith prefix
- return umfilename;
- }
- }
-
- //Encode filename to UMfilename
- //Example: ao_module_codec.encodeUMFilename("test.stl");
- static encodeUMFilename(filename){
- if (filename.substring(0,5) != "inith"){
- //Check if the filename include extension.
- if (filename.includes(".")){
- //Filename with extension. pop it out first.
- var info = filename.split(".");
- var ext = info.pop();
- var filenameOnly = info.join(".");
- var encodedFilename = "inith" + ao_module_codec.decode_utf8(ao_module_codec.bin2hex(filenameOnly)) + "." + ext;
- return encodedFilename;
- }else{
- //Filename with no extension. Convert the whole name into UMfilename
- var encodedFilename = "inith" + ao_module_codec.decode_utf8(ao_module_codec.bin2hex(filename));
- return encodedFilename;
- }
- }else{
- //This is already a UMfilename. return the raw filename.
- return filename;
- }
- }
-
- //Decode hexFoldername into standard foldername in utf-8, return the original name if it is not a hex foldername
- //Example: ao_module_codec.decodeHexFoldername(hexFolderName_here);
- static decodeHexFoldername(folderName, prefix=true){
- var decodedFoldername = ao_module_codec.decode_utf8(ao_module_codec.hex2bin(folderName));
- if (decodedFoldername == "false"){
- //This is not a hex encoded foldername
- decodedFoldername = folderName;
- }else{
- //This is a hex encoded foldername
- if (prefix){
- decodedFoldername = "*" + decodedFoldername;
- }else{
- decodedFoldername =decodedFoldername;
- }
- }
- return decodedFoldername;
- }
-
- //Encode foldername into hexfoldername
- //Example: ao_module_codec.encodeHexFoldername("test");
- static encodeHexFoldername(folderName){
- var encodedFilename = "";
- if (ao_module_codec.decodeHexFoldername(folderName) == folderName){
- //This is not hex foldername. Encode it
- encodedFilename = ao_module_codec.decode_utf8(ao_module_codec.bin2hex(folderName));
- }else{
- //This folder name already encoded. Return the original value
- encodedFilename = folderName;
- }
-
- return encodedFilename;
- }
- static hex2bin(s){
- var ret = []
- var i = 0
- var l
- s += ''
- for (l = s.length; i < l; i += 2) {
- var c = parseInt(s.substr(i, 1), 16)
- var k = parseInt(s.substr(i + 1, 1), 16)
- if (isNaN(c) || isNaN(k)) return false
- ret.push((c << 4) | k)
- }
-
- return String.fromCharCode.apply(String, ret)
- }
-
- static bin2hex(s){
- var i
- var l
- var o = ''
- var n
- s += ''
- for (i = 0, l = s.length; i < l; i++) {
- n = s.charCodeAt(i)
- .toString(16)
- o += n.length < 2 ? '0' + n : n
- }
- return o
- }
-
- static decode_utf8(s) {
- return decodeURIComponent(escape(s));
- }
- }
- /**
- ArOZ Online Module Utils for quick deploy of ArOZ Online WebApps
- ao_module_utils.objectToAttr(object); //object to DOM attr
- ao_module_utils.attrToObject(attr); //DOM attr to Object
- ao_module_utils.getRandomUID(); //Get random UUID from timestamp
- ao_module_utils.getIconFromExt(ext); //Get icon tag from file extension
- ao_module_utils.stringToBlob(text, mimetype="text/plain") //Convert string to blob
- ao_module_utils.blobToFile(blob, filename, mimetype="text/plain") //Convert blob to file
- ao_module_utils.getDropFileInfo(dropEvent); //Get the filepath and filename list from file explorer drag drop
- ao_module_utils.readFileFromFileObject(fileObject, successCallback, failedCallback=undefined) //Read file object as text
- ao_module_utils.durationConverter(seconds) //Convert duration in seconds to Days / Hours / Minutes / Seconds
- ao_module_utils.formatBytes(byte, decimals); //Format file byte size to human readable size
- ao_module_utils.timeConverter(unix_timestamp); //Get human readable timestamp
- ao_module_utils.getWebSocketEndpoint() //Build server websocket endpoint root, e.g. wss://192.168.1.100:8080/
- ao_module_utils.formatBytes(bytes, decimalPlace=2) //Convert and rounds bytes into KB, MB, GB or TB
- **/
- class ao_module_utils{
-
- //Two simple functions for converting any Javascript object into string that can be put into the attr value of an DOM object
- static objectToAttr(object){
- return encodeURIComponent(JSON.stringify(object));
- }
-
- static attrToObject(attr){
- return JSON.parse(decodeURIComponent(attr));
- }
-
- //Get a random id for a new floatWindow, use with var uid = ao_module_utils.getRandomUID();
- static getRandomUID(){
- return new Date().getTime();
- }
- static stringToBlob(text, mimetype="text/plain"){
- var blob = new Blob([text], { type: mimetype });
- return blob
- }
- static blobToFile(blob, filename, mimetype="text/plain"){
- var file = new File([blob], filename, {type: mimetype});
- return file
- }
-
- //Get the icon of a file with given extension (ext), use with ao_module_utils.getIconFromExt("ext");
- static getIconFromExt(ext){
- var ext = ext.toLowerCase().trim();
- var iconList={
- md:"file text outline",
- txt:"file text outline",
- pdf:"file pdf outline",
- doc:"file word outline",
- docx:"file word outline",
- odt:"file word outline",
- xlsx:"file excel outline",
- ods:"file excel outline",
- ppt:"file powerpoint outline",
- pptx:"file powerpoint outline",
- odp:"file powerpoint outline",
- jpg:"file image outline",
- png:"file image outline",
- jpeg:"file image outline",
- gif:"file image outline",
- odg:"file image outline",
- psd:"file image outline",
- zip:"file archive outline",
- '7z':"file archive outline",
- rar:"file archive outline",
- tar:"file archive outline",
- mp3:"file audio outline",
- m4a:"file audio outline",
- flac:"file audio outline",
- wav:"file audio outline",
- aac:"file audio outline",
- mp4:"file video outline",
- webm:"file video outline",
- php:"file code outline",
- html:"file code outline",
- htm:"file code outline",
- js:"file code outline",
- css:"file code outline",
- xml:"file code outline",
- json:"file code outline",
- csv:"file code outline",
- odf:"file code outline",
- bmp:"file image outline",
- rtf:"file text outline",
- wmv:"file video outline",
- mkv:"file video outline",
- ogg:"file audio outline",
- stl:"cube",
- obj:"cube",
- "3ds":"cube",
- fbx:"cube",
- collada:"cube",
- step:"cube",
- iges:"cube",
- gcode:"cube",
- shortcut:"external square",
- opus:"file audio outline",
- apscene:"cubes"
- };
- var icon = "";
- if (ext == ""){
- icon = "folder outline";
- }else{
- icon = iconList[ext];
- if (icon == undefined){
- icon = "file outline"
- }
- }
- return icon;
- }
-
- //Get the drop file properties {filepath: xxx, filename: xxx} from file drop events from file exploere
- static getDropFileInfo(dropEvent){
- if (dropEvent.dataTransfer.getData("filedata") !== ""){
- var filelist = dropEvent.dataTransfer.getData("filedata");
- filelist = JSON.parse(filelist);
- return filelist;
- }
- }
- static readFileFromFileObject(fileObject, successCallback, failedCallback=undefined){
- let reader = new FileReader();
- reader.readAsText(fileObject);
- reader.onload = function() {
- successCallback(reader.result);
- };
- reader.onerror = function() {
- if (failedCallback != undefined){
- failedCallback(reader.error);
- }else{
- console.log(reader.error);
- }
- };
- }
- static durationConverter(seconds){
- var days = Math.floor(seconds / 86400);
- seconds -= days * 86400;
- var hours = Math.floor(seconds / 3600) % 24;
- seconds -= hours * 3600;
- var minutes = Math.floor(seconds / 60) % 60;
- seconds -= minutes * 60;
- var seconds = seconds % 60;
- var resultDuration = "";
- if (days > 0){
- resultDuration += days + " Day";
- if (days > 1){
- resultDuration+= "s"
- }
- resultDuration += " "
- }
- if (hours > 0){
- resultDuration += hours + " Hour"
- if (hours > 1){
- resultDuration += "s"
- }
- resultDuration += " "
- }
- if (minutes > 0){
- resultDuration += minutes + " Minute"
- if (minutes > 1){
- resultDuration += "s"
- }
- resultDuration += " "
- }
- if (seconds > 0){
- resultDuration += seconds + " Second"
- if (seconds > 1){
- resultDuration += "s"
- }
- resultDuration += " "
- }
-
- return resultDuration;
- }
- static timeConverter(UNIX_timestamp){
- var a = new Date(UNIX_timestamp * 1000);
- var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
- var year = a.getFullYear();
- var month = months[a.getMonth()];
- var date = a.getDate();
- var hour = a.getHours().toString().padStart(2, "0");
- var min = a.getMinutes().toString().padStart(2, "0");
- var sec = a.getSeconds().toString().padStart(2, "0");
- var time = date + ' ' + month + ' ' + year + ' ' + hour + ':' + min + ':' + sec ;
- return time;
- }
- static getWebSocketEndpoint(){
- let protocol = "wss://";
- if (location.protocol !== 'https:') {
- protocol = "ws://";
- }
- let port = window.location.port;
- if (window.location.port == ""){
- if (location.protocol !== 'https:') {
- port = "80";
- }else{
- port = "443";
- }
-
- }
- let wsept = (protocol + window.location.hostname + ":" + port);
- return wsept;
- }
-
- static formatBytes(a,b=2){if(0===a)return"0 Bytes";const c=0>b?0:b,d=Math.floor(Math.log(a)/Math.log(1024));return parseFloat((a/Math.pow(1024,d)).toFixed(c))+" "+["Bytes","KB","MB","GB","TB","PB","EB","ZB","YB"][d]}
- }
- /*
- Backend Programming Logic
- These code are design to use with ao_backend.js for wrapping
- AGI programming gateway content
- */
- function ao_module_backend(){
- return {
- timeout: 500,
- start: function(libraryPath){
- this.libpath = libraryPath;
-
- //Initialize the parent objects
- this.appdata.parent = this;
- this.file.parent = this;
- this.http.parent = this;
- },
- _agi_run: function(data, callback, failedcallback = undefined){
- $.ajax({
- url: ao_root + "system/ajgi/interface?script=" + this.libpath,
- method: "POST",
- data: data,
- success: function(data){
- if (typeof(callback) != "undefined"){
- callback(data);
- }
- },
- error: function(){
- if (typeof(failedcallback) != "undefined"){
- failedcallback();
- }
- console.log("Request failed");
- },
- timeout: this.timeout
- })
- },
- appdata: {
- readFile: function(filepath, callback=undefined){
- this.parent._agi_run({
- opr: "appdata.readFile",
- filepath: filepath
- }, callback)
- },
- listDir: function(filepath, callback=undefined){
- this.parent._agi_run({
- opr: "appdata.listDir",
- filepath: filepath
- }, callback)
- },
- },
- file: {
- writeFile: function(filepath, content, callback=undefined){
- this.parent._agi_run({
- opr: "file.writeFile",
- filepath: filepath,
- content: content,
- }, callback)
- },
- readFile: function(filepath, callback=undefined){
- this.parent._agi_run({
- opr: "file.readFile",
- filepath: filepath
- }, callback)
- },
- deleteFile: function(filepath, callback=undefined){
- this.parent._agi_run({
- opr: "file.deleteFile",
- filepath: filepath
- }, callback)
- },
- readdir: function(filepath, callback=undefined){
- this.parent._agi_run({
- opr: "file.readdir",
- filepath: filepath
- }, callback)
- },
- walk: function(filepath, mode="all", callback=undefined){
- this.parent._agi_run({
- opr: "file.walk",
- filepath: filepath,
- mode: mode,
- }, callback)
- },
- glob: function(wildcard, sort="user", callback=undefined){
- this.parent._agi_run({
- opr: "file.glob",
- wildcard: wildcard,
- sort: sort,
- }, callback)
- },
- aglob: function(wildcard, sort="user", callback=undefined){
- this.parent._agi_run({
- opr: "file.aglob",
- wildcard: wildcard,
- sort: sort,
- }, callback)
- },
- filesize: function(filepath, callback=undefined){
- this.parent._agi_run({
- opr: "file.filesize",
- filepath: filepath
- }, callback)
- },
- fileExists: function(filepath, callback=undefined){
- this.parent._agi_run({
- opr: "file.fileExists",
- filepath: filepath
- }, callback)
- },
- isDir: function(filepath, callback=undefined){
- this.parent._agi_run({
- opr: "file.isDir",
- filepath: filepath
- }, callback)
- },
- mkdir: function(filepath, callback=undefined){
- this.parent._agi_run({
- opr: "file.mkdir",
- filepath: filepath
- }, callback)
- },
- mtime: function(filepath, callback=undefined){
- this.parent._agi_run({
- opr: "file.mtime",
- filepath: filepath
- }, callback)
- },
- rootName: function(filepath, callback=undefined){
- this.parent._agi_run({
- opr: "file.rootName",
- filepath: filepath
- }, callback)
- }
- },
- http: {
- get: function(targetURL, callback=undefined){
- this.parent._agi_run({
- opr: "http.get",
- targetURL: targetURL
- }, callback)
- },
- post: function(targetURL, postdata="", callback=undefined){
- this.parent._agi_run({
- opr: "http.post",
- targetURL: targetURL,
- postdata: postdata
- }, callback)
- },
- head: function(targetURL, header="", callback=undefined){
- this.parent._agi_run({
- opr: "http.head",
- targetURL: targetURL,
- header: header
- }, callback)
- },
- download: function(targetURL, saveDir="tmp:/", saveFilename="", callback=undefined){
- if (saveFilename == ""){
- saveFilename = targetURL.split("/").pop();
- saveFilename = decodeURIComponent(saveFilename);
- }
- this.parent._agi_run({
- opr: "http.download",
- targetURL: targetURL,
- saveDir: saveDir,
- saveFilename: saveFilename
- }, callback)
- },
- }
- }
- }
|