if(typeof(Packages) == 'undefined') Packages = {$i: {}, $: {}};var pPackagePath = '/System/Software/JS/';/*************************************************************** * Accounts - singleton - contains the tools to communicate with a WEB server * * The Accounts Singleton does 3 distinctly different tasks * 1. Allows an ordinary user to log into their webspace * Initialised by the WEB server, so that the url is the path to their webspace * 2. Allows a restricted user to log into their sub account * A parent URL contains the url to the parent account, instead of asking for username, it asks for account name * and logs into to the account as /Accounts//.admin?user=User&pass=. * 3. Allows a non user, to sign up and become a restricted user * Automated account sign up works by having a template user on the server. * A template user is defined as an ordinary user, except the template account flag is set (also disabled is recommended) * The new user account is created in the Accounts folder, and a dummy Admin (disabled) is created * During account creation, the template user's permissions are copied to the restricted user of the new account * * singleFieldLogin: * When enabled, a password field will not be shown. * Instead the username will be split on the hyphen '-' character * The section before the hyphen is the username, and the section after the password **************************************************************/ Package("Library").Accounts = function() { this.textVar = GetTextRef(this); var LOGGEDIN = 1; // Verified var LOGGEDOUT = 2; // Verified var LOGGINGIN = 3; // In process of var LOGINFAIL = 4; // Server said no var LOGINCREATE = 5; this.status = LOGGEDOUT; this.folders; this.reloadOnLogin = 0; this.login = {username: "", password: "", confirmpassword: "", accountname: ""}; this.url = Packages.Library.$.GetMasterpath({}); if(!this.url.match(/\/$/)) this.url += "/"; this.singleFieldLogin = 0; // Set up onload subscriber event Packages.Library.$.EventSubscribe({eventname: "GetGlobalReplacements", callback: Packages.Library.$.GetGlobalReplacementUsername}); /******************************* * UpdateScreen - displays the appropriate form for logging in / out * depending on current state * * Also used for updating the state * * param - status : (optional) status to set to * param - message : (optional) message to display * * returns the HTML markup for the form ******************************/ this.UpdateScreen = function(status, message) { if(status != null) this.status = status; var html = "Login status unknown"; if(this.status == LOGGEDIN ) html = this.ScreenLoggedIn(); if(this.status == LOGGEDOUT) html = this.ScreenLoginForm(); if(this.status == LOGGINGIN) html = "Logging in ..."; if(this.status == LOGINFAIL) html = this.ScreenLoginForm("Failed to log on
Please check your login and try again"); if(this.status == LOGINCREATE) html = this.ScreenCreateAccount(); // Prefix with message if(message != null) html = "

" + message + "<\/h2>" + html; // Put HTML in sensible place if(Packages.Library.$c.IsNode != 1) { var elem = document.getElementById('account_signform'); if(elem) elem.innerHTML = html; } return html; }; /***************************** * ScreenLoggedIn - called to display logged in screen ****************************/ this.ScreenLoggedIn = function() { var html = ""; html += "
Logged in as " + this.genericname + "<\/div>"; html += "
<\/div>"; }, pageInfo : function() { return "
<\/div>"; }, packageTests : function() { return "
This will take a while to run and save all results"; }, debugWindow : function() { return ""; }, packageTestAll : function() { return "
Tests every filetype packages test"; }, speedTest : function() { return "
Tests Packages.Library.$.ToHex 1 million times"; } } }; /*************************************************************** * PackageTestAll - opens a new tab for each file type, and runs * the tests for it **************************************************************/ Packages.Library.$.PackageTestAll = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.PackageTestAll", options: options, doNotTest: 1, specification: {} })) return; if(Packages.Library.$v.testing == 1) return; // Because this would be a terrible idea var filetypesFolder = Packages.Library.$.GetSubFolder({container: pFolders, offset: "/System/Software/JS/FileType"}); for(var i = 0; i < filetypesFolder.length; i++) { var filetype = filetypesFolder[i].name; filetype = filetype.replace(/\.\$jscb.*/, ""); // Strip $jscb section window.open("/dummy." + filetype + "?req-createorget=1&runAction=PackageTest&req-mimeoff=1&req-enhanced=1"); } }; /*************************************************************** * DebugSpeedTest - tests ToHex a million times **************************************************************/ Packages.Library.$.DebugSpeedTest = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.DebugSpeedTest", options: options, doNotTest: 1, specification: {} })) return; var data; for(var n = 0; n < 1000000; n++) { data = Packages.Library.$.ToHex({num: n}) } return data; };/*************************************************************** * Constants **************************************************************/ Package("Library").$c.Documenter = { FN_HASH: 0, FN_CLASS: 1, FN_API: 2 }; /*************************************************************** * Documenter - creates documentation for the Javascript source code, by * dynamically analysing the code **************************************************************/ Package("Library").Documenter = function() { this.textVar = GetTextRef(this); /*************************************************************** * CreateDocument - creates the documentation and returns the HTML **************************************************************/ this.CreateDocument = function() { // Get all of the JS source code for this page this.jsSrcCode = ""; var scriptElems = document.getElementsByTagName("script"); for(var i = 0; i < scriptElems.length; i++) { this.jsSrcCode += scriptElems[i].innerText; } var html = ""; html += this.DocumentPackage(Packages, "Packages"); html += this.AnalyseSubscribers(); return html; }; /*************************************************************** * DocumentPackage - creates the documentation about this * package and returns the html - recursive * * param - packs : the Package object * param - packsname : the name of the package being examined * * returns the html for the documentation **************************************************************/ this.DocumentPackage = function(packs, packsname) { var html = "

" + packsname + "<\/h4>"; html += ""; html += "
    "; for(var packname in packs) { if(packname == '$i') continue; var fullpackname = packsname + (packname.match(/^[0-9]/) ? "[" + packname + "]" : "." + packname); var pack = eval(fullpackname); html += "
  • "; switch (typeof(pack)) { case 'object': { if(packname == '$') { // The library public 'CLASS' .$. methods html += this.Document$Functions(pack, fullpackname); } else { // The class itself if(packname == 'view') { html += "Skipping: " + packname; } else { html += this.DocumentPackage(pack, fullpackname); } } break; } case 'function': { try{ var obj = new pack(); html += this.DocumentClass(obj, pack, packname); }catch(e) {html += "Error instantiating: " + packname} break; } default: { html += "Variable: " + packname + " = " + pack; } } html += "<\/li>"; } html += "<\/ul>"; return html; }; /*************************************************************** * Document$Functions - creates the documentation about this * packages .$. functions and returns the html * * param - packs : the hash containing the API functions * param - classname : the name of this class * * returns the html markup for this documentation **************************************************************/ this.Document$Functions = function(packs, classname) { var html = "

    API Functions: " + classname + "<\/h4>"; html += ""; html += "
      "; for(var packname in packs) { var fullpackname = "packs[\"" + packname + "\"]"; var pack = eval(fullpackname); html += "
    • "; html += this.ProcessItem(pack, packname, this.jsSrcCode, Package("Library").$c.Documenter.FN_API); html += "<\/li>"; } html += "<\/ul>"; return html; }; /*************************************************************** * DocumentClass - creates the documentation about this class * * param - object : blank object * param - packs : class reference * param - classname : the class name **************************************************************/ this.DocumentClass = function(object, packs, classname) { var html = "

      Class: " + classname + "<\/h4>"; html += ""; html += "
        "; //alert(this.Display.toString()); //alert(Packages.FileType.mhtm.view.toString()); var classJSsrc = packs.toString(); for(var packname in object) { if(packname == '$i') continue; var fullpackname = "object[\"" + packname + "\"]"; var pack = eval(fullpackname); html += "
      • "; html += this.ProcessItem(pack, packname, classJSsrc, Package("Library").$c.Documenter.FN_CLASS); html += "<\/li>"; } html += "<\/ul>"; return html; }; /*************************************************************** * DocumentHash - creates the documentation about this hash * * param - packs : the hash object * param - hashname : the name of the hash **************************************************************/ this.DocumentHash = function(packs, hashname) { var html = "

        Hash: " + hashname + "<\/h4>"; html += ""; html += "
          "; for(var packname in packs) { var fullpackname = "packs[\"" + packname + "\"]"; var pack = eval(fullpackname); html += "
        • "; html += this.ProcessItem(pack, packname, "", Package("Library").$c.Documenter.FN_HASH); html += "<\/li>"; } html += "<\/ul>"; return html; }; /*************************************************************** * DocumentFunction - creates the documentation about a function * * param - func : the actual function * param - functionname : the name of the function * param - srcCode : the source code containing this method * param - mode : see Package("Library").$c.Documenter.FN_ * * returns the html for this function documentation **************************************************************/ this.DocumentFunction = function(func, functionname, srcCode, mode) { var html = "

          Function: " + functionname + "<\/h4>"; if(srcCode == "" || mode == null) return html; // No comment available // Try and get help text (about method) var safefunctionname = functionname.replace(/\$/, "\\$"); var re = new RegExp("\\/\\*+?\\n\\s*?\\* " + safefunctionname + " - ((.|\\n)*?)[\\s\\*]*?(param - |\\**?\\/)", "m"); if(srcCode.match(re)) { html += Packages.Library.$.MakeHelp({help: RegExp.$1}); } else { html += "ERROR: No comment for method"; } // Try and get params html += ""; html += "
            "; var re; if(mode == Package("Library").$c.Documenter.FN_CLASS) { re = new RegExp("this\\." + safefunctionname + " = function\\((.*?)\\)", "m"); } if(mode == Package("Library").$c.Documenter.FN_API) { re = new RegExp("Package.*?\\." + safefunctionname + " = function\\((.*?)\\) {", "m"); } if(re != null) { html += "
          • "; html += "Paramaters:"; html += "
              "; if(srcCode.match(re)) { var paramnames = RegExp.$1; if(paramnames.length > 0) { var params = paramnames.split(", "); for(var p = 0; p < params.length; p++) { // try and get the param comment var re = new RegExp("\\* " + safefunctionname + " - (.|\\n)*?param - " + params[p] + " : (.*)", "m"); var description = "ERROR: No Description for variable"; if(srcCode.match(re)) description = RegExp.$2; html += "
            • " + params[p] + ": " + description + "<\/li>"; } } } html += "<\/ul>"; html += "<\/li>"; } html += "
            • "; html += "Return value: "; if(functionname == "GetDetails") { try{ var res = func(); html += this.ProcessItem(res, "", this.jsSrcCode, Package("Library").$c.Documenter.FN_HASH); } catch (e) { html += Packages.Library.$.MakeHelp({help: "Failed to get return value with error '" + e.message + "'"}); } } html += "<\/li>"; html += "<\/ul>"; return html; }; /*************************************************************** * ProcessItem - processes the found item in a class or hash * * param - pack : the actual item object * param - packname : the name of the item * param - srcCode : the source code containing this method * param - mode : see Package("Library").$c.Documenter.FN_ * * returns the html returns by the documenter for this type **************************************************************/ this.ProcessItem = function(pack, packname, srcCode, mode) { var html = ""; switch (typeof(pack)) { case 'function': { html += this.DocumentFunction(pack, packname, srcCode, mode); break; } case 'object': { html += this.DocumentHash(pack, packname); break; } default: { html += "Variable: " + packname + " = " + pack; } } return html; }; /*************************************************************** * AnalyseSubscribers - processes all subscribers and the places * that fire them * * returns the html to describe this subscriber **************************************************************/ this.AnalyseSubscribers = function() { var html = "

              Subscribe Events<\/h3>"; var matches = this.jsSrcCode.match(/(.*?) = function(.|\n)+?Packages\.Library\.\$\.EventFire\("(.*?)"/g); if(matches == null) return ""; // Empty hash for event names var matchkeys = {}; for(var i = 0; i < matches.length; i++) { // Get the event name matches[i].match(/.*? = function(.|\n)+?Packages\.Library\.\$\.EventFire\("(.*?)"/g); var match = RegExp.$2; if(matchkeys[match] == null) matchkeys[match] = {fire: [], subscriber: []}; // Get the last function name var functionmatches = matches[i].match(/(.*?) = function\(/g); if(functionmatches == null) continue; var funcname = functionmatches[functionmatches.length - 1]; if(funcname.match(/\s(.*?) = function\(/)) { funcname = RegExp.$1; } matchkeys[match].fire.push(funcname); } matches = this.jsSrcCode.match(/(.*?) = function(.|\n)+?Packages\.Library\.\$\.EventSubscribe\("(.*?)", (.*?)\.bind\(/g); if(matches != null) { for(var i = 0; i < matches.length; i++) { // Get the event name matches[i].match(/.*? = function(.|\n)+?Packages\.Library\.\$\.EventSubscribe\("(.*?)", (.*?)\.bind\(/g); var match = RegExp.$2; var funcname = RegExp.$3; if(matchkeys[match] == null) matchkeys[match] = {fire: [], subscriber: []}; matchkeys[match].subscriber.push(funcname); } } for(var item in matchkeys) { // Output details for this event var match = matchkeys[item]; html += "

              Subscribe Event: " + item + "<\/h4>"; html += ""; html += "
                "; // Try and get help about the event var re = new RegExp("\\* " + item + " - EVENT - ((.|\\n)*?)\\*+\\/", ""); if(this.jsSrcCode.match(re)) { html += "
              • About<\/h4>"; var comment = RegExp.$1; html += comment.replace(/\n/g, "
                "); html += "<\/li>"; } html += "
              • Fires: [" + match.fire.length + "]<\/h4>"; // List found fires html += "
                  "; for(var i = 0; i < match.fire.length; i++) { html += "
                • " + match.fire[i] + "<\/li>"; } html += "<\/ul><\/li>"; html += "
                • Subscribers [" + match.subscriber.length + "]:<\/h4>"; // List found subscriber html += "
                    "; for(var i = 0; i < match.subscriber.length; i++) { html += "
                  • " + match.subscriber[i] + "<\/li>"; } html += "<\/ul><\/li>"; html += "<\/ul>
                    "; } return html; }; };/* Dynamic Load - the ability to request resources on the server in a hidden iframe, and then once loaded put its contents into the main page. This is also heavily used to allow JavaScript the 'special' ability to exceed the bounds of the client side. This is essential since in this case, JavaScript contains the specific actions for doing a specific task. The server itself only has generic commands to serve a number of different tasks. Before anything gets loaded, there is first a check to see if it has already been loaded. This can be overridden to force another load. Although this is an object, each object should be used only once. The system is used in the following ways LOAD TYPE LT_SCRIPT : Used to load a JS file as a standard library file LT_CSS : Used to load a CSS file as an ordinary style sheet (no callback supported) LT_TEXT : Loads the content into a textarea (useful for getting plain text or HTML from the server) Optional properties ScriptPackage:(LT_SCRIPT only) checks this package exists before firing callback ForceReload : Skip the checking of existance, and load anyway UseTerminator : (optional) if 1 asks the server to print a terminator line at the end so we knows the output has finished queryParams : (optional) hash of query params to send with the request className : (optional) classname to place on loaded element tag (LT_SCRIPT only) CALLBACKS The callback subroutine is fired when all of the request files have been retrieved. This only applies to files that support callbacks (eg CSS does not). LT_SCRIPT is only partially supported, and requires a 'ScriptPackage' option to be defined to check the specified package exists Callbacks are a JS function, which is executed. If the callback returns a string, this will be loaded into the target element. If nothing is returned this does not apply. Use: Create an instance of this class with the following properties targetID : (optional) the element ID of the target to load response into callback : function to execute upon completion useContent : 1 put the loaded content into the TargetElement, 0 (default) do not displayLoadingIcon : 1 (default) display loading icon, 0 not to divParams : (optional) if specified includes a list of params to insert in the empty Div Call 'Request' with the following properties Files : an array of files entries, each of the type filepath : the complete filepath for this file mode : one of the LT_ LOAD TYPES (Optional properties) ScriptPackage, queryParams Wait, the callback will be executed once loaded (or never if something goes wrong) */ /********************************************************************* * Constructor - Create an instance of this class with the following properties * * param - options : hash of options, may contain: * targetID : (optional) the element ID of the target to load response into * callback : function to execute upon completion * useContent : 1 put the loaded content into the TargetElement, 0 (default) do not * displayLoadingIcon : 1 (default) display loading icon, 0 not to * divParams : (optional) if specified includes a string of params to insert in the empty Div ********************************************************************/ Package("Library").DynamicLoad = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.DynamicLoad", options: options, specification: { targetID: {type: "string"}, callback: {type: "function"}, useContent: {type: "boolean"}, displayLoadingIcon: {type: "boolean"}, divParams: {type: "string"} } })) return; this.TargetID = options.targetID; this.Callback = options.callback; this.UseContent = options.useContent; this.DisplayLoadingIcon = options.displayLoadingIcon; this.DivParams = options.divParams; this.textVar = GetTextRef(this); if(this.TargetID == "") this.TargetID = null; /********************************************************************* * Request - Request a list of files * * param - Files : an array of files entries, each of the type * filepath : the complete filepath for this file * mode : one of the LT_ LOAD TYPES * (Optional properties) ScriptPackage, queryParams * ForceReload * * returns an empty div HTML markup ********************************************************************/ this.Request = function(Files) { this.Files = Files; // Get variables this.reqterminatorcode = "XXXX----TERMINATOR----XXXX---" + "TERMINATOR" + "---XXXX"; // Divided so that loading itself doesn't fail! if(Packages.Library.$v.testing == 1) return null; // Do nothing in test mode // Initialise our array of files we have loaded if(Packages.Library.DynamicLoad.$i == null) Packages.Library.DynamicLoad.$i = {}; if(Packages.Library.DynamicLoad.$i.LoadedFiles == null) Packages.Library.DynamicLoad.$i.LoadedFiles = {}; // Check our list and remove any entries we have already loaded for(var f = 0; f < Files.length; f++) { if(Files[f].ForceReload == 1) continue; // Is file loaded? if(Packages.Library.DynamicLoad.$i.LoadedFiles[Files[f].filepath + "_" + Files[f].mode]) { // File already loaded, skip Files[f] = Packages.Library.DynamicLoad.$i.LoadedFiles[Files[f].filepath + "_" + Files[f].mode]; } else { // Log this file as loaded (as its about to be) Packages.Library.DynamicLoad.$i.LoadedFiles[Files[f].filepath + "_" + Files[f].mode] = Files[f]; } } // Load the files for(var f = 0; f < Files.length; f++) { var filepath = Files[f].filepath; var mode = Files[f].mode; var getid = "getFile_" + mode + "_" + filepath.replace(/[\/\.\?&]/g, "_"); if(Files[f].getid != null) continue; // Already loading Files[f].getid = getid; // Is this particular file already loaded? if(this.IsFileLoaded(Files[f])) continue; // Assemble additional query params var query = ""; for(var parm in Files[f].queryParams) { query += parm + "=" + Files[f].queryParams[parm] + "&"; } Files[f].querystring = query; // Load this file if(this.Methods[mode].Load != null) { this.Methods[mode].Load(Files[f], this); } } // Have we finished yet? this.ContinuousCheckIsLoaded(); // Are we suppose to return empty DIV? if(this.TargetID == null) { // No, return nothing return null; } else { // Yes, return empty div return "
                    " + (this.DisplayLoadingIcon == 1 ? Packages.Library.$.GetLoaderImg() : "") + "<\/div>"; } }; /********************************************************************* * GetFiles - Gets the list of files this object is requesting * * returns the list of files ********************************************************************/ this.GetFiles = function() { return this.Files; }; /********************************************************************* * IsLoaded - Checks if the files are loaded * * return 1 if loaded, 0 if not ********************************************************************/ this.IsLoaded = function() { var loaded = 1; // so prove me wrong for(var f = 0; f < this.Files.length; f++) { var file = this.Files[f]; if(!this.IsFileLoaded(file)) loaded = 0; } return loaded; }; /********************************************************************* * ContinuousCheckIsLoaded - Checks if the files are loaded * * If everything has loaded, fires the callback, otherwise schedules another check * * return 1 if loaded, 0 if not ********************************************************************/ this.ContinuousCheckIsLoaded = function() { var loaded = this.IsLoaded(); var elem; if(Packages.Library.$c.IsNode != 1) elem = document.getElementById(this.TargetID); // UseContent first, incase needed by callback if(loaded == 1 && this.UseContent == 1) { if(elem == null) { loaded = 0; } else { elem.innerHTML = this.GetFileContent(this.Files[0]); } } if(loaded == 1 && this.Callback != null) { if(elem == null && this.TargetID != null) { loaded = 0; // No element, fail and try again } else { // Load was successful, fire callback (if we have one) var res = this.Callback(); if(res != null && elem != null) { elem.innerHTML = res; } } } if(loaded == 0) { // No success yet, try again soon setTimeout(this.ContinuousCheckIsLoaded.bind(this), 50); } return loaded; }; /********************************************************************* * IsFileLoaded - Checks if the specified file is loaded * * param - file : item from Files array * * return 1 if loaded, 0 if not ********************************************************************/ this.IsFileLoaded = function(file) { if(this.Methods[file.mode].Check != null) { return this.Methods[file.mode].Check(file, this); } return 1; // Assume OK }; /********************************************************************* * GetFileContent - Gets the content of the file * * param - file : (optional) entry from Files, if not specified returns the first file * * returns the content or null if not found / no Get ********************************************************************/ this.GetFileContent = function(file) { if(file == null) file = this.Files[0]; if(this.Methods[file.mode].Get != null) { return this.Methods[file.mode].Get(file, this); } return null; }; /********************************************************************* * GetFileStatus - Gets the HTTP status of the file * * param - file : (optional) entry from Files, if not specified returns the first file * * returns the content or null if not found / no Get ********************************************************************/ this.GetFileStatus = function(file) { if(file == null) file = this.Files[0]; return file.status; }; /******************************* MODE SPECIFIC OPTIONS *******************************************************/ this.Methods = {}; /***************************************************** * Load - does the work to load this type of data * * param - file : url of file to load * param - _this : reference to 'this' for the main object ****************************************************/ /***************************************************** * Check - checks if the file has finished loading or not * * param - file : url of file to load * param - _this : reference to 'this' for the main object * * returns 1 if loaded, or 0 if not ****************************************************/ /***************************************************** * Get - gets the data from the loaded file (some method only) * * param - file : url of file to load * param - _this : reference to 'this' for the main object * * returns the content ****************************************************/ this.Methods.LT_SCRIPT = {}; this.Methods.LT_SCRIPT.Load = function(file, _this) { var head = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); script.type = 'text/javascript'; var query = file.querystring; if(query.length > 0) query = "&" + query; script.src = file.filepath + "?req-plain=1" + query; script.id = file.getid; script.className = file.className; script.onload = function() { file.ready = 1; } head.appendChild(script); }; this.Methods.LT_SCRIPT.Check = function(file, _this) { // Check onload has fired if(file.skip == 1) return 1; if(file.ready != 1) return 0; if(file.ScriptPackage != null) { // Check if the package is loaded try{ var elem = document.getElementById(file.getid); if(elem != null) { try{ eval(elem.text); } catch(e){} } if(eval("Packages." + file.ScriptPackage) != null) return 1; }catch(e){}; } else { // Check if script exists in src try { var scripts = document.getElementsByTagName('script'); for(var s = 0; s < scripts.length; s++) { if(scripts[s].src.match(file.filepath)) return 1; } } catch(e) { return 1; // DOM not formed yet } } return 0; }; this.Methods.LT_CSS = {}; this.Methods.LT_CSS.Load = function(file, _this) { var head = document.getElementsByTagName('head')[0]; var style = document.createElement('link'); style.rel = 'stylesheet' style.type = 'text/css'; var query = file.querystring; if(query.length > 0) query = "&" + query; style.href = file.filepath + "?req-plain=1" + query; head.appendChild(style); }; this.Methods.LT_CSS.Check = function(file, _this) { try { var styles = document.getElementsByTagName('link'); for(var s = 0; s < styles.length; s++) { if(styles[s].href.match(file.filepath)) return 1; } return 0; } catch(e) { return 1; // DOM not formed yet } }; this.Methods.LT_TEXT = {}; this.Methods.LT_TEXT.Load = function(file, _this) { if(Packages.Library.$c.IsNode) { var path = pDocRootOffset; if(!path.match(/\/$/)) path += "/"; //if(file.system) path = "/web"; // System file //if(file.filepath.match(/^\//)) path = pDocRoot; // absolute to doc root var execSync = require('exec-sync'); file.filepath = file.filepath.replace(/^\//, ""); // Remove leading / var reqFilePath = path + file.filepath; reqFilePath = reqFilePath.replace(/\$/, "\\$"); // Escape $ for bash // Ensure reqFilePath starts with a leading '/' if(!reqFilePath.match(/^\//)) reqFilePath = "/" + reqFilePath; console.log(reqFilePath); var res = execSync('/web/System/Software/cmdline_integration.exe "' + pMasterPathAbs + '" FILE ' + reqFilePath); console.log(res); file.status = 200; file.ready = 1; file.content = res; } else if(Packages.Library.$c.HasDOM) { // Get an xmlhttp handle for this file if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari file.xmlhttp = new XMLHttpRequest(); } else { // code for IE6, IE5 file.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } var query = file.querystring; if(query.length > 0) query = "&" + query; if(file.plain != 0) query = "req-plain=1&req-mimeoff=1" + query; file.ready = 0; file.xmlhttp.open("GET", file.filepath + "?" + query, true); file.xmlhttp.onreadystatechange = function() { if (file.xmlhttp.readyState==4) { file.status = file.xmlhttp.status; file.ready = 1; file.content = file.xmlhttp.responseText; } } file.xmlhttp.send(); } else { Packages.Library.$.LogInfo({ mesg: "No method provided for LT_TEXT.Load", location: "DynamicLoad", level: 1 }); } }; this.Methods.LT_TEXT.Check = function(file, _this) { // Check onload has fired if(file.skip == 1) return 1; if(file.ready == 1) return 1; return 0; }; this.Methods.LT_TEXT.Get = function(file, _this) { // Get the response var response = file.content; return response; }; };Package("Library").Extensions = function() {}; /******************************************************************************* * foreach - iterates through the items in the array, calling the callback * function for each one * * param - array : the array * param - callback : the callback to fire for each one ******************************************************************************/ var foreach = function(array, callback) { for(var i = 0; i < array.length; i++) { callback(array[i]); } } /******************************************************************************* * countLines - counts the lines in the specified text * * Essentially splits on the \n and counts them, but if the area is blank, will return 0 * * param - text : text to count lines in * * return - lines : number of lines, or 0 if blank ******************************************************************************/ var countLines = function(lines) { if(lines.length == 0) return 0; return lines.split(/\n/).length; } Package("Library").File = function() { }; /********************************************************************* * Dump - Converts the specified object into text * * Skips keys $noDump * * param - options : hash of options, must contain: * obj : the array/object to be saved * may contain: * skiplist : array of 'keys' to skip in objects * prettyPrint : null (do not use), 1 use * internally * indent : internally used to count indents * * returns the JS code to recreate this object ********************************************************************/ Packages.Library.$.Dump = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.Dump", options: options, specification: { obj: {type: "object,array,string,number,boolean,function,DOMobject,null"}, // Null allowed skiplist: {type: "array"}, prettyPrint: {type: "boolean"}, indent: {type: "number"} } })) return null; var arr = options.obj; var type = Packages.Library.$.GetType({item: arr}); var skiplist = options.skiplist; var indents = options.indent; if(indents == null) indents = 0; indents++; var indent = ""; if(options.prettyPrint == 1) { for(var i = 0; i < indents; i++) { indent += " "; } } var indentless1 = indent.replace(/ $/, ""); // 1 tab less indent for closing braces / brackets if(skiplist == null) skiplist = []; if(type == 'function') return "null"; // Can't dump a function! if(type == 'DOMobject') return "null"; // Can't dump a DOMobject! if(type == 'null') return "null"; // Can't dump a DOMobject! if(arr == null) return "null"; if(typeof(arr) == 'object') { //Array/Hashes/Objects if(arr.$recursing != null) { alert("Detected recursion from: " + arr.$recursion.from); return "null"; // Can not recurse into self } var type = Packages.Library.$.GetType({item: arr}); if(type == "object") { // Prevent objects from recursing arr.$recursing = {from: "Packages.Library.$.Dump"}; } var values = ""; for(var item in arr) { if(item == "$noDump") continue; // Skip $noDump key if(item == "$id") continue; // Skip $id key if(item == "$recursing") continue; // Skip $recursing key if(Packages.Library.$.Contains({array: skiplist, item: item})) continue; var value = arr[item]; values += indent; if(type == "array") { // array values += ""; } else { // hash values += item + ":"; } try { values += Packages.Library.$.Dump({obj: value, skiplist: skiplist, prettyPrint: options.prettyPrint, indent: indents}); } catch(e) {} values += ","; if(indents != null) values += "\n"; } if(arr.$recursing != null) delete arr.$recursing; if(values.length > 0 ) values = values.replace(/,\n?$/, ""); // Remove trailing comma and optionally line break if(indents != null) values = "\n" + values + "\n" + indentless1; if(type == "array") { // array return "[" + values + "]"; } else { // hash return "{" + values + "}"; } } else { //Stings/Chars/Numbers etc. if(typeof(arr) == "number") { // number } else if(typeof(arr) == "boolean") { arr = arr ? "true" : "false"; } else if(typeof(arr) == null) { arr = "null"; } else { // string arr = "\"" + Packages.Library.$.ConvertCRToNat({str: arr}) + "\""; } return arr; } return "null"; }; /********************************************************************* * ConvertCRToNat - Converts the carriage return version of text into Nat standard (\escaped) * * [escapedbackslash] used as a unique value. Replaces the '\\' first, so that subsequent * \\s are not confused as a \'. Finally the [escapedbackslash] is replaced with a '\\' * * param - options : hash of options, must contain: * str : source string * * returns the Nat version of string ********************************************************************/ Packages.Library.$.ConvertCRToNat = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.ConvertCRToNat", options: options, specification: { str: {type: "string", required: 1} } })) return null; var str = options.str; if(str == null) str = "null"; str = str.replace(/\\/g, "\\\\"); // Escape backslashes str = str.replace(/\n/g, "\\n"); str = str.replace(/\r/g, ""); str = str.replace(/\f/g, ""); str = str.replace(/\"/g, "\\\""); return str; }; /********************************************************************* * ConvertCRToXML - Converts the text into the escaped and XML safe * standard * * param - options : hash of options, must contain: * str : source string * * returns the xml version of string ********************************************************************/ Packages.Library.$.ConvertCRToXML = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.ConvertCRToXML", options: options, specification: { str: {type: "string", required: 1} } })) return null; var str = options.str; str = str.replace(/\\n/g, "\\\\n"); str = str.replace(/\n/g, "\\n"); str = Packages.Library.$.ConvertCRToXMLContent({str: str}); return str; }; /********************************************************************* * ConvertCRToXMLContent - Converts the text into the escaped and XML safe * standard for the content * * param - options : hash of options, must contain: * str : source string * * returns the xml version of string ********************************************************************/ Packages.Library.$.ConvertCRToXMLContent = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.ConvertCRToXMLContent", options: options, specification: { str: {type: "string", required: 1} } })) return null; var str = options.str; str = str.replace(/\r/g, ""); str = str.replace(/\f/g, ""); str = str.replace(/&/gi, "&"); str = str.replace(/\"/gi,"""); str = str.replace(//gi, ">"); return str; }; /********************************************************************* * ConvertCRToPT - Converts the CR to P tags * * param - options : hash of options, must contain: * str : source string * * returns the

                    <\/p> version of string ********************************************************************/ Packages.Library.$.ConvertCRToPT = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.ConvertCRToPT", options: options, specification: { str: {type: "string", required: 1} } })) return null; var str = options.str; return "

                    " + str.replace(/\n/gi, "

                    ") + "

                    "; }; /********************************************************************* * ConvertCRToBR - Converts the Nat standard (\escaped) version of text into HTML safe
                    * * param - options : hash of options, must contain: * str : source string (may be null, in which case returns "") * * returns the
                    version of string ********************************************************************/ Packages.Library.$.ConvertCRToBR = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.ConvertCRToBR", options: options, specification: { str: {type: "string"} } })) return null; if(options.str == null) return ""; return options.str.replace(/\n/gi, "
                    "); }; /********************************************************************* * ConvertLegacy - Converts the Legacy Nat standard (\escaped) version * of text into CR version * * param - options : hash of options, must contain: * str : source string (can be null) * * returns the CR version of string ********************************************************************/ Packages.Library.$.ConvertLegacy = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.ConvertLegacy", options: options, specification: { str: {type: "string"} } })) return null; var str = options.str; if(str == null) return ""; if(typeof(str) == "number") str += ""; // Legacy update str = str.replace(/&mlt;/g, "<"); str = str.replace(/&mgt;/g, ">"); str = str.replace(/&mbn;/g, "\n"); str = str.replace(/\\\\/g, "[escapedbackslash]"); str = str.replace(/\\n/g, "\n"); str = str.replace(/\\q/gi, "\"").replace(/\\s/gi, "'").replace(/\\a/gi, "&").replace(/\\p/gi, "%").replace(/\\l/gi, "\/"); str = str.replace(/\[escapedbackslash\]/g, "\\"); return str; }; /********************************************************************* * ConvertXMLToCR - Converts the XML escaped standard version of text into CR * version, this includes the < > escapes * * param - options : hash of options, must contain: * str : source string * * returns the CR version of string ********************************************************************/ Packages.Library.$.ConvertXMLToCR = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.ConvertXMLToCR", options: options, specification: { str: {type: "string", required: 1} } })) return null; var str = options.str; // Do standard legacy update str = Packages.Library.$.ConvertLegacy({str: str}); if(str == null) return null; // Decode <>& str = str.replace(/</g, "<"); str = str.replace(/>/g, ">"); str = str.replace(/"/g, "\""); str = str.replace(/&/g, "&"); return str; }; /********************************************************************* * EscapeString - escapes a string ready for text format * * param - options : hash of options, must contain: * str : source string * * returns the escaped version of string ********************************************************************/ Packages.Library.$.EscapeString = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.EscapeString", options: options, specification: { str: {type: "string,number", required: 1} } })) return null; var str = options.str; str = Packages.Library.$.ForceString({xValue: str}); str = str.replace(/\\/g, "\\\\"); str = str.replace(/\n/g, "\\n"); return str; }; /********************************************************************* * UnEscapeString - unescapes a string ready for use * * param - options : hash of options, must contain: * str : source string * * returns the unescaped version of string ********************************************************************/ Packages.Library.$.UnEscapeString = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.UnEscapeString", options: options, specification: { str: {type: "string", required: 1} } })) return null; var str = options.str; str = Packages.Library.$.ForceString({xValue: str}); str = str.replace(/\\n/g, "\n"); str = str.replace(/\\\\/g, "\\"); return str; }; /********************************************************************* * ConvertToHTML - escapes special HTML chars with HTML entities * * param - options : hash of options, must contain: * str : source string * * returns the escaped version of string ********************************************************************/ Packages.Library.$.ConvertToHTML = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.ConvertToHTML", options: options, specification: { str: {type: "string,number", required: 1} } })) return null; var str = options.str; str = Packages.Library.$.ForceString({xValue: str}); str = str.replace(/£/g, "£"); return str; }; /********************************************************************* * ConvertFromHTML - deescapes special HTML chars with HTML entities * * param - options : hash of options, must contain: * str : source string * * returns the deescaped version of string ********************************************************************/ Packages.Library.$.ConvertFromHTML = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.ConvertFromHTML", options: options, specification: { str: {type: "string,number", required: 1} } })) return null; var str = options.str; str = Packages.Library.$.ForceString({xValue: str}); str = str.replace(/£/g, "£"); return str; }; /********************************************************************* * SetFile - Sets the contents of a file on the server * * param - options : hash of options, must contain: * filepath : path + filename + extension * content : content, may not be an empty string * may contain: * isBase64 : 1 if content is already in base64, 0 (default) if plain * callback : callback to fire when file submitted * overwrite : 1 (default) force overwrite, 0 do not overwrite * reqFiles : 1 (default) request files, 0 do not * page : the page to request if not masterpath/.admin * async : (see ServerRequest) * * returns 1 if OK, 0 if not ********************************************************************/ Packages.Library.$.SetFile = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.SetFile", options: options, specification: { filepath: {type: "string", required: 1}, content: {type: "string,number,boolean", required: 1}, isBase64: {type: "boolean"}, callback: {type: "function"}, overwrite: {type: "boolean"}, reqFiles: {type: "boolean"}, page: {type: "string"} } })) return 0; if(Packages.Library.$v.testing == 1) return 1; // Do nothing in test mode if(options.overwrite == null) options.overwrite = 1; if(options.reqFiles == null) options.reqFiles = 1; var query = { createFile64: options.filepath, "req-files": options.reqFiles, createFile64Overwrite: options.overwrite }; var content = options.content; if(options.isBase64 != 1) content = btoa(content); var post = { contents64: content }; if(options.page == null) options.page = Packages.Library.$.GetMasterpath({}) + ".admin"; new Packages.Library.ServerRequest().ServerRequest({ page: options.page, query: query, post: post, async: options.async, callback: options.callback, maskContent: "Saving file: " + options.filepath }); return 1; }; /********************************************************************* * GetFile - Gets the contents of a file on the server * * Syncronous, ie, this returns the content of the file * * param - options : hash of options, must contain: * filepath : path + filename + extension * may contain: * plain : 1 force plain response, 0 as it comes * * returns result : hash of result data, consisting of * status : status returned * content : content returned ********************************************************************/ Packages.Library.$.GetFile = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.GetFile", options: options, specification: { filepath: {type: "string", required: 1}, plain: {type: "boolean"} } })) return {status: 0}; var query = ""; if(options.plain != 0) query = "req-plain=1&req-mimeoff=1" + query; // Get an xmlhttp handle for this file var xmlhttp; if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp = new XMLHttpRequest(); } else { // code for IE6, IE5 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.open('GET', options.filepath + "?" + query, false); // `false` makes the request synchronous xmlhttp.send(null); return { status: xmlhttp.status, content: xmlhttp.responseText }; }; /********************************************************************* * GetContentFromURL - Gets third party content from a URL via the server * * Avoids cross site scripting attack errors * * param - options : hash of options, must contain: * url : url to fetch from * callback : callback when loaded, passes in options containing * content : the content of the url * content64 : base64 version of content * callbackData : as callbackData * callbackData : data passed to callback * filepath : location to save the file from masterpath ********************************************************************/ Packages.Library.$.GetContentFromURL = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.GetContentFromURL", options: options, specification: { url: {type: "string", required: 1}, callback: {type: "function"}, callbackData: {type: "object"}, filepath: {type: "string"} } })) return; var url = options.url; url = url.replace(/^http:\/\//, ""); var getOptions = options; // Fetch new Packages.Library.ServerRequest().ServerRequest({ page: Packages.Library.$.GetMasterpath({}) + ".admin", query: { getcontenturl: url, getcontenturlfilepath: options.filepath }, callback: function(options) { var response = options.response; // getcontenturlResponse var openmatch = ""; var closematch = ""; response = response.substr(response.indexOf(openmatch) + openmatch.length, response.indexOf(closematch) - (response.indexOf(openmatch) + openmatch.length)); if(getOptions.callback != null) getOptions.callback({ content: atob(response), content64: response, callbackData: getOptions.callbackData }); } }); }; /********************************************************************* * MakeFolder - Creates a folder, updates file mgr (if present) when done * * param - options : hash of options, must contain: * folderpath : the complete folder path from masterpath to create ********************************************************************/ Packages.Library.$.MakeFolder = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.MakeFolder", options: options, specification: { folderpath: {type: "string", required: 1} } })) return; var query = { "req-files": 1, createFolder: options.folderpath }; new Packages.Library.ServerRequest().ServerRequest({ page: "/.admin", query: query, callback: Packages.Library.$.ReloadFileMgr }); } /********************************************************************* * SetAttributes - creates a text file of attributes from the hash specified * * param - options, hash of options, must include: * data : the hash of data, single tier * * returns the attributes as a text block ********************************************************************/ Packages.Library.$.SetAttributes = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.SetAttributes", options: options, specification: { data: {type: "object", required: 1} } })) return null; var lines = []; for(var key in options.data) { if(key.match(/^\$noDump$/)) continue; // Skip lines.push(key + "=" + Packages.Library.$.EscapeString({str: options.data[key]})); } return lines.join("\n"); }; /********************************************************************* * GetAttributes - returns the attributes in 'text' * * param - options, hash of options, must include: * text : the text to extract from * * returns the attributes as a hash ********************************************************************/ Packages.Library.$.GetAttributes = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.GetAttributes", options: options, specification: { text: {type: "string", required: 1} } })) return null; var data = {}; options.text = options.text.replace(/\r/g,""); // Remove unwanted line chars var lines = options.text.split(/\n/); for(var i = 0; i < lines.length; i++) { if(lines[i].match(/^([^\s]+?)=(.+)$/)) { data[RegExp.$1] = Packages.Library.$.UnEscapeString({str: RegExp.$2}); } } return data; }; /********************************************************************* * GetAttribute - returns the value of the attribute from 'text' * * param - options, hash of options, must include: * text : the text to extract from * attr : the attribute to search for * * returns the value or null if not found ********************************************************************/ Packages.Library.$.GetAttribute = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.GetAttribute", options: options, specification: { text: {type: "string", required: 1}, attr: {type: "string", required: 1, min: 1} } })) return null; var data = Packages.Library.$.GetAttributes(options) return data[options.attr]; }; /********************************************************************* * MakeElemFileDropable - gets the attributes for an element to allow * it to be a receiver of a drag and dropped file * * param - options, hash of options, must include: * path : the path this element represents * * returns the attributes to be placed into the element as a string * or null if an error occured ********************************************************************/ Packages.Library.$.MakeElemFileDropable = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.MakeElemFileDropable", options: options, specification: { path: {type: "string", required: 1} } })) return null; var attributes = ""; attributes += "ondrop=\"e = event || window.event; Packages.Library.$._FileDrop(e, '" + options.path + "')\" "; attributes += "ondragover=\"e = event || window.event; if (e.preventDefault) { e.preventDefault(); } return false;\" "; attributes += "ondragenter=\"e = event || window.event; if (e.preventDefault) { e.preventDefault(); } return false;\" "; return attributes; } /******************************************************************************* * _FileDrop - callback when a file dropped into MakeElemFileDropable * * param - event : the event * param - path : the path of where the item was dropped ******************************************************************************/ Packages.Library.$._FileDrop = function(event, path) { event.preventDefault && event.preventDefault(); // Lock, so only 3 processes can occur at once var lock = 0; var callback = function(evt, file) { if(path.length > 0) path += "/"; Packages.Library.$.UploadFile({ base64: evt.target.result.substr(evt.target.result.indexOf(',') + 1), filepath: path + file.name, filename: file.name, callback: function(options) {lock --; Packages.Library.$.ReloadFileMgr(options)} }); }; var files = event.dataTransfer.files; for(var i = 0; i < files.length; i++) { var file = files[i]; var inScope = function(file) { if(lock >= 3) { setTimeout(function() {inScope(file)}, 50); return; } lock ++; var reader = new FileReader(); //attach event handlers here... reader.onload = function(evt) {callback(evt, file)}; reader.readAsDataURL(file); }; inScope(file); } return false; }; /************************************************************************************************* * ReloadFileMgr - callback when a file system altering ServerRequest is performed * * Called by ServerRequest * * param - options : hash of options, must contain * serverReqElem : element containing content * response : the content ************************************************************************************************/ Packages.Library.$.ReloadFileMgr = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.ReloadFileMgr", options: options, specification: { serverReqElem: {type: "DOMobject", required: 1}, response: {type: "string", required: 1} } })) return null; var elem = options.serverReqElem; if(Packages.Library.$v.testing == 1) return 1; // Do nothing in test mode if(elem == null) return 1; // Logged out // Get file list if returned var content = ""; var folderElem = document.getElementById('pJSData'); if(folderElem != null) { content = folderElem.innerHTML; } // Replace all 'var ' so that global variables are affected // Be really specific, we only want to reload some vars content = content.replace(/var (qPermissions|qVersions|pApps|pFolders|pContainerFolders)/g, "$1"); eval(content); Packages.Library.$.EventFire({eventname: "pFolderChanged", data: {}}); return 1; }; /************************************************************************************************* * FindInFolders - gets an array of files / folders matching a certain critera in the folder * specified * * RECURSIVE * * param - options : hash of options, must contain: * regExp : regExp to apply to filename * may contain: * type : either "file" or "folder", if null, finds either * folder : the starting folder, or pFolders if not specified * path : starting path * internally: * recurse : 1 if recursing, else null * * returns an array of matching file hashes, each of the form: * name : the filename without extension * path : the file path * or null if an error occured ************************************************************************************************/ Packages.Library.$.FindInFolders = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.FindInFolders", options: options, specification: { regExp: {type: "string", required: 1}, type: {type: "string"}, folder: {type: "array"}, path: {type: "string"} } })) return null; var folder = options.folder; var path = options.path; if(folder == null) folder = pFolders; if(Packages.Library.$v.testing == 1 && options.recursing != 1) { // Set a standard set of folders folder = Packages.Library.$.GetTestSampleFolderList({}); } if(path == null) path = ""; var matches = []; var regExp = new RegExp(options.regExp); for(var i = 0; i < folder.length; i++) { var item = folder[i]; var match = 1; if(!item.name.match(regExp)) match = 0; if(options.type != null && options.type != item.type) match = 0; if(match) { matches.push({ name: Packages.Library.$.GetFileName({filepath: item.name}), path: path + item.name }); } // Recurse if(item.type == "folder") { options.folder = item.subfolders; options.path = path + item.name + "/"; options.recursing = 1; matches = matches.concat(Packages.Library.$.FindInFolders(options)); } } return matches; }; /************************************************************************************************* * GetSubFolder - gets the subfolder from the specified container folder offset by offset * * param - options : hash of options, must include: * container : the containining folder listing * offset : the path from the container to the sub folder with '/' separators * * returns the subfolder listing or null if an error occurs ************************************************************************************************/ Packages.Library.$.GetSubFolder = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.GetSubFolder", options: options, specification: { container: {type: "array", required: 1}, offset: {type: "string", required: 1} } })) return null; var container = options.container; if(options.offset == "") return container; if(options.offset.match(/^\//)) options.offset = options.offset.substring(1); var offsets = options.offset.split("/"); for(var i = 0; i < offsets.length; i++) { var found = 0; for(var j = 0; j < container.length; j++) { var entry = container[j].name; entry = entry.replace(/.\$jsc.*$/, ""); entry = entry.replace(/.\$jsc.*\//, "/"); if(entry == offsets[i]) { container = container[j].subfolders; found = 1; break; } } if(found == 0) { Packages.Library.$.LogInfo({mesg: "Could not find [" + options.offset + "]", location: "Packages.Library.$.GetSubFolder", type: "Info", level: 3}); return null; } } return container; }; /************************************************************************************************* * GetFolderList - gets all of the files in the folders and subfolders in one array * * param - options : hash of options, including: * container : the container folder * may include: * extensions : array of valid file extensions, or null for all * prefix : path prefix * * returns the array ************************************************************************************************/ Packages.Library.$.GetFolderList = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.GetFolderList", options: options, specification: { container: {type: "array", required: 1}, extensions: {type: "array"}, prefix: {type: "string"} } })) return null; if(options.prefix == null) options.prefix = ""; var container = options.container; var listing = []; for(var i = 0; i < container.length; i++) { if(container[i].type == "folder") listing = listing.concat(Packages.Library.$.GetFolderList({ container: container[i].subfolders, extensions: options.extensions, prefix: options.prefix + container[i].name + "/"} )); if(container[i].type == "file") { var lastdot = container[i].name.lastIndexOf("."); var extension = lastdot != -1 ? container[i].name.substr(lastdot + 1) : ""; if(extension == null || Packages.Library.$.Contains({array: options.extensions, item: extension})) listing.push(options.prefix + container[i].name); } } return listing; }; /************************************************************************************************* * FileExist - tests if the specified file exists * * param - options : hash of options, must contain: * filepath : filepath to check * may contain: * folder : the starting folder, or pFolders if not specified * * returns 1 if file found, or 0 if not, or null if invalid arguments ************************************************************************************************/ Packages.Library.$.FileExist = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.FileExist", options: options, specification: { filepath: {type: "string", required: 1}, folder: {type: "array"} } })) return 0; var folder = options.folder; if(folder == null) folder = pFolders; var filepath = options.filepath; var path = ""; var file = filepath; if(filepath.match(/\//)) { path = filepath.substr(0, filepath.lastIndexOf("/")); file = filepath.substr(filepath.lastIndexOf("/") + 1); } folder = Packages.Library.$.GetSubFolder({container: folder, offset: path}); for(var i = 0; i < folder.length; i++) { if(folder[i].name == file) return 1; } return 0; };Package("Library").Font = function() {}; Packages.Library.$c.Font = {}; Packages.Library.$c.Font.Fonts = [ "Sans", "Sans-Serif", "Monospace", "Condiment", "Chela One", "Give You Glory", "Sirin Stencil", "Petit Formal Script", "Jolly Lodger", "Fugaz One", "Paprika", "Mrs Saint Delafield", "Sanchez", "Playfair Display SC", "Cherry Swash", "Audiowide", "Montserrat", "Cutive", "Nunito", "Patrick Hand", "Pompiere", "Poiret One", "Henny Penny", "Kite One", "Crete Round", "Cinzel", "Diplomata", "Quando", "Handlee", "Asset", "Josefin Sans", "Josefin Slab", "Source Code Pro", "Exo", "Chango", "Cinzel Decorative" ]; /********************************************************************* * GetFontOptions - gets an array of available fonts in the correct format * to display in as radio buttons in a form * * returns array of font hashes, each of the form: * name : name to display, wrapped in CSS to give correct appearance * value : CSS font name ********************************************************************/ Packages.Library.$.GetFontOptions = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.GetFontOptions", options: options, specification: {} })) return null; var options = []; for(var i = 0; i < Packages.Library.$c.Font.Fonts.length; i++) { var font = Packages.Library.$c.Font.Fonts[i]; options.push({ name: "" + font + "<\/span>", value: font }); // Request font Packages.Library.$.RequestFont({font: font}); } return options; }; /********************************************************************* * RequestFont - requests the specified font be loaded into the browser * * If a DOM is available, the linktag will be loaded * * param - options : hash of options, must contain: * font : name of font as in the constant array * * return - linktag : the link tag to place in the head ********************************************************************/ Packages.Library.$.RequestFont = function(options) { if(!Packages.Library.$.ValidateOptions({ calledFrom: "Packages.Library.$.RequestFont", options: options, specification: { font: {type: "string", required: 1} } })) return ""; // Test font is in our list var match = 0; for(var i = 0; i < Packages.Library.$c.Font.Fonts.length; i++) { if(options.font == Packages.Library.$c.Font.Fonts[i]) match = 1; } if(match == 0) return ""; // No match if(options.font.match(/^sans/i)) return ""; // Don't load Sans var familyname = options.font.replace(/ /, '+'); var linktag = ""; if(Packages.Library.$c.HasDOM == 1) { var link = document.createElement('link'); link.href = "http://fonts.googleapis.com/css?family=" + familyname; link.rel = 'stylesheet'; link.type = 'text/css'; var linkelem = document.getElementsByTagName('link')[0]; if(linkelem == null) linkelem = document.getElementsByTagName('script')[0]; linkelem.parentNode.insertBefore(link, linkelem); } return linktag; };Package("Library.Gallery.Effects.Cut").view = function(parent, divid) { this.parent = parent; this.textVar = GetTextRef(this); this.currentpageid = -1; /************************************************ * Display - gets the html markup for this effect * * returns the html ***********************************************/ this.Display = function() { var html = ""; html += "
                    "; html += "<\/span>" return html; }; /************************************************ * Update - called on a timer to update the effect ***********************************************/ this.Update = function () { var node = parent.GetPageNode(parent.current + 0, divid); var elem = document.getElementById(divid + '_galpage'); if(elem == null) return; if(node.parentNode != elem) { if(node.parentNode != null) node.parentNode.removeChild(node); Packages.Library.$.EmptyNode({node: elem}); elem.appendChild(node); } // Preload node = parent.GetPageNode(parent.current + 1, divid); }; }; Packages.Library.Gallery.Effects.Cut.$.GetDetails = function() { return { name: "Cut", description:"Cuts (without transition effect) between the images.", category: "Effects" }; };Package("Library.Gallery.Effects.Fade").view = function(parent, divid) { this.parent = parent; this.textVar = GetTextRef(this); this.gal_back = -1; this.gal_front = -1; this.gal_preload = -1; /************************************************ * Display - gets the html markup for this effect * * returns the html ***********************************************/ this.Display = function() { var html = ""; html += "