UNPKG

ares-ide

Version:

A browser-based code editor and UI designer for Enyo 2 projects

390 lines (332 loc) 12.7 kB
/*$ * @name loadfile.js * @fileOverview basic config file loading routines used by the whole g11n package. * */ /*globals G11n IMPORTS root document enyo*/ //* @protected enyo.g11n.Utils = enyo.g11n.Utils || function() {}; enyo.g11n.Utils._fileCache = {}; /** Finds and returns the base URL. */ enyo.g11n.Utils._getBaseURL = function(doc) { if ('baseURI' in doc) { return doc.baseURI; } else { var baseTags = doc.getElementsByTagName ("base"); if (baseTags.length > 0) { return baseTags[0].href; } else { return window.location.href; } } } /** Returns a string with the URL that is the root path of the application. */ enyo.g11n.Utils._fetchAppRootPath = function() { var doc = window.document; //this might need to change for multiple window apps on webOS var match = enyo.g11n.Utils._getBaseURL(doc).match(new RegExp(".*:\/\/[^#]*\/")); if (match) { return match[0]; } } enyo.g11n.Utils._setRoot = function _setRoot(path) { var rootPath = path; if (!path && enyo.g11n.isEnyoAvailable()){ rootPath = enyo.g11n.Utils._fetchAppRootPath() + "assets" } else { rootPath = "."; } return enyo.g11n.root = rootPath; }; enyo.g11n.Utils._getRoot = function _getRoot() { return enyo.g11n.root || enyo.g11n.Utils._setRoot(); }; enyo.g11n.Utils._getEnyoRoot = function _getEnyoRoot(prefix) { var prependPath = ""; if (!enyo.g11n.isEnyoAvailable() && prefix){ prependPath = prefix; } return prependPath + enyo.path.paths.enyo + "/../lib/g11n/source"; }; /* * @private */ enyo.g11n.Utils._loadFile = function _loadFile(path) { var json, jsonString, platform = enyo.g11n.getPlatform(); // enyo.log("Utils._loadFile: loading file from " + path); if (platform === 'node') { // enyo.log("Utils._loadFile: #2 in node.js service, loading json file via fs"); // cache it ourselves try { if (!this.fs) { this.fs = IMPORTS.require("fs"); } jsonString = this.fs.readFileSync(path, 'utf8'); if (jsonString) { json = JSON.parse(jsonString); } } catch (e) { // remember that we could not load the file so that we don't spend a lot of // time in the future attempting to load the file. This is accomplished by // putting json as undefined into the cache for that path. // enyo.error(e); json = undefined; } } else { /* platform === 'browser' */ try { json = JSON.parse(enyo.xhr.request({url: path, sync: true}).responseText); } catch (e3) { } } return json; }; /** Loads a JSON file from disk, converts it to a JavaScript object, and returns the object. * params (Object): Parameters controlling the loading of the file The _params_ object may contain the following properties: * root: Absolute path to which the path section is relative * path: Relative path to the JSON file from the root, including the file name * cache: If set to false, the resulting JSON is not cached. Default is true to cache the JSON. The JavaScript object is kept in the cache until the timeout period has elapsed, at which point it may be unloaded from memory when _releaseAllJsonFiles_ is called and the garbage collector runs. */ enyo.g11n.Utils.getNonLocaleFile = function getNonLocaleFile(params) { var json, rootPath, fullPath; if (!params || !params.path) { return undefined; } // enyo.log("getNonLocaleFile: requested " + params.path); // only add the root if this is not an absolute path if (params.path.charAt(0) !== '/') { rootPath = params.root || this._getRoot(); fullPath = rootPath + "/" + params.path; } else { fullPath = params.path; } //enyo.log("root path: " + rootPath); //enyo.log("full path: " + fullPath); if (enyo.g11n.Utils._fileCache[fullPath] !== undefined) { // enyo.log("getNonLocaleFile: found in cache"); json = enyo.g11n.Utils._fileCache[fullPath].json; } else { json = enyo.g11n.Utils._loadFile(fullPath); if (!(params.cache !== undefined && params.cache === false)) { // enyo.log("getNonLocaleFile: Storing in cache the path " + params.path); enyo.g11n.Utils._fileCache[fullPath] = { path: fullPath, json: json, locale: undefined, timestamp: new Date() }; if (this.oldestStamp === undefined) { this.oldestStamp = enyo.g11n.Utils._fileCache[fullPath].timestamp; } } } return json; }; /** Loads a JSON file from disk, converts it to a JavaScript object, and returns the object. * params (Object): Parameters controlling the loading of the file The _params_ object may contain the following properties: * root: Root of the package, app, or library where the JSON files can be found. * path: Path relative to the root, underneath which the resources dir can be found. * locale: A locale instance that names which locale to load the JSON file for. * prefix: An optional prefix for the file name. File names are constructed as _prefix + locale name + ".json"_. * cache: If set to false, the resulting JSON is not cached. Default is true to cache the JSON. * merge: If set to true, the variant, region and language JSON files are merged according to rules defined in (define rules). Default is false. * type: One of "language", "region", or "either". This loads files specific to the language name, the region name, or either one if available. Default is "either". The JavaScript object is kept in the cache until the timeout period has elapsed, at which point it may be unloaded from memory when _releaseAllJsonFiles_ is called and the garbage collector runs. */ enyo.g11n.Utils.getJsonFile = function getJsonFile(params) { var json, path, rootPath, prefix, lang, reg, reg2, variant, cachePath; // var start = new Date(); if (!params || !params.path || !params.locale) { return undefined; } // enyo.log("getJsonFile: params is " + JSON.stringify(params) + " and default root is " + Utils._getRoot()); rootPath = (params.path.charAt(0) !== '/') ? (params.root || this._getRoot()) : ""; if (rootPath.slice(-1) !== '/') { rootPath += "/"; } if (params.path) { prefix = params.path; if (prefix.slice(-1) !== '/') { prefix += "/"; } } else { prefix = ""; } prefix += params.prefix || ""; rootPath += prefix; cachePath = rootPath + params.locale.toString() + ".json"; if (enyo.g11n.Utils._fileCache[cachePath] !== undefined) { // enyo.log("getJsonFile: found in cache"); json = enyo.g11n.Utils._fileCache[cachePath].json; } else { if (!params.merge) { path = rootPath + params.locale.toString() + ".json"; json = this._loadFile(path); if (!json && params.type !== "region" && params.locale.language) { path = rootPath + params.locale.language + ".json"; json = this._loadFile(path); } if (!json && params.type !== "language" && params.locale.region) { path = rootPath + params.locale.region + ".json"; json = this._loadFile(path); } if (!json && params.type !== "language" && params.locale.region) { path = rootPath + "_" + params.locale.region + ".json"; json = this._loadFile(path); } } else { if (params.locale.language) { path = rootPath + params.locale.language + ".json"; lang = this._loadFile(path); } if (params.locale.region) { path = rootPath + params.locale.language + "_" + params.locale.region + ".json"; reg = this._loadFile(path); if (params.locale.language !== params.locale.region){ path = rootPath + params.locale.region + ".json"; reg2 = this._loadFile(path); } } if (params.locale.variant) { path = rootPath + params.locale.language + "_" + params.locale.region + "_" + params.locale.variant + ".json"; variant = this._loadFile(path); } json = this._merge([lang,reg2, reg, variant]); } if (!(params.cache !== undefined && params.cache === false)) { // enyo.log("getJsonFile: Caching " + cachePath); enyo.g11n.Utils._fileCache[cachePath] = { path: cachePath, json: json, locale: params.locale, timestamp: new Date() }; if (this.oldestStamp === undefined) { this.oldestStamp = enyo.g11n.Utils._fileCache[cachePath].timestamp; } } } // var end = new Date(); // enyo.log("getJsonFile: length " + (end.getTime() - start.getTime())); return json; }; /** Merges an array of string tables together into a single table. Strings from later tables override strings with the same key from earlier tables. */ enyo.g11n.Utils._merge = function _merge(tables) { var i, len, mergedTable = {}; for (i = 0, len = tables.length; i < len; i++) { mergedTable = enyo.mixin(mergedTable, tables[i]); } return mergedTable; }; /** Expires and purges from the cache all JSON files that are older than the passed-in timeout limit, returning the number of items removed. * timeout (Number): Only files that are older than this number of milliseconds are expired and purged. If this parameter is not given, the default is 60000ms (i.e., 1 minute). * all (Boolean): If true, all files are purged; if false or undefined, files that belong to any of the current locales will be kept in memory, as they are likely to be used again soon. Caching guarantees that at least one reference to an object will exist in memory for the length of the timeout period, so that the garbage collector will not collect it. If other code still has a reference to an object loaded with _getJsonFile_, the object will remain in memory until the reference to it is removed. */ enyo.g11n.Utils.releaseAllJsonFiles = function releaseAllJsonFiles(timeout, all) { var now = new Date(), expireList = [], // len, // start = new Date(), oldest, path, i, cacheItem; timeout = timeout || 60000; // enyo.log("Utils.releaseAllJsonFiles: sweep through and release everything except locale " + exceptLocale); if (this.oldestStamp !== undefined && (this.oldestStamp.getTime() + timeout) < now.getTime()) { // enyo.log("Utils.releaseAllJsonFiles: past oldest timeout check"); oldest = now; for (path in enyo.g11n.Utils._fileCache) { if (path && enyo.g11n.Utils._fileCache[path]) { cacheItem = enyo.g11n.Utils._fileCache[path]; // enyo.log("Utils.releaseAllJsonFiles: path is " + path + " and item is " + JSON.stringify(cacheItem)); // enyo.log("Utils.releaseAllJsonFiles: testing " + cacheItem.path + " locale " + cacheItem.locale); if (!cacheItem.locale || all || (!enyo.g11n.currentLocale().isMatch(cacheItem.locale) && !enyo.g11n.formatLocale().isMatch(cacheItem.locale) && !enyo.g11n.phoneLocale().isMatch(cacheItem.locale))) { // enyo.log("Utils.releaseAllJsonFiles: testing for timeout"); // timeout is currently 60 seconds if ((cacheItem.timestamp.getTime() + timeout) < now.getTime()) { // enyo.log("Utils.releaseAllJsonFiles: #3 older than threshold, expiring file " + cacheItem.path); expireList.push(cacheItem.path); } else { if (cacheItem.timestamp.getTime() < oldest.getTime()) { oldest = cacheItem.timestamp; } // enyo.log("Utils.releaseAllJsonFiles: #4 not older than threshold, keeping file "); } } else { if (cacheItem.timestamp.getTime() < oldest.getTime()) { oldest = cacheItem.timestamp; } } } } // unset the oldest stamp if there were no entries left in the cache this.oldestStamp = (oldest.getTime() < now.getTime()) ? oldest : undefined; // enyo.log("Utils.releaseAllJsonFiles: oldestStamp is now " + this.oldestStamp + ". Expiring " + expireList.length + " files."); // do the actual expiration in a separate loop so that it doesn't screw up the iteration above for (i = 0; i < expireList.length; i++) { enyo.g11n.Utils._fileCache[expireList[i]] = undefined; } } return expireList.length; /* var end = new Date(); len = end.getTime() - start.getTime(); //enyo.log("releaseAllJsonFiles: length " + len); if ( this.totalReleaseTime === undefined ) { this.totalReleaseTime = 0; this.totalReleaseAttempts = 0; } this.totalReleaseTime += len; this.totalReleaseAttempts++; //enyo.log("releaseAllJsonFiles: total: " + this.totalReleaseTime + " average: " + (this.totalReleaseTime/this.totalReleaseAttempts)); */ }; enyo.g11n.Utils._cacheSize = function _cacheSize() { var count = 0, k; for (k in enyo.g11n.Utils._fileCache) { if (enyo.g11n.Utils._fileCache[k]) { count++; }} return count; };