From db9cc3b6b96700b056639b1a0cb7d4021693623a Mon Sep 17 00:00:00 2001 From: "Vincenzo (Wilk) Ferrari" Date: Fri, 26 Sep 2014 15:22:05 +0200 Subject: [PATCH 01/13] removed useless Ext.Error dependency --- Promise.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/Promise.js b/Promise.js index 4d0b999..045ffc1 100644 --- a/Promise.js +++ b/Promise.js @@ -6,8 +6,6 @@ * */ Ext.define('Ext.ux.Promise', { - requires: ['Ext.Error'], - inheritableStatics: { /** * Pending state From 47db461e159cb7af593ecf8efbc2d98f6f39c21d Mon Sep 17 00:00:00 2001 From: "Vincenzo (Wilk) Ferrari" Date: Fri, 26 Sep 2014 15:26:25 +0200 Subject: [PATCH 02/13] ignored build folder --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index f26b195..fe92425 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.*~ demo/ node_modules/ -.idea/ \ No newline at end of file +.idea/ +build/ \ No newline at end of file From 18ab84f9d58873ad435d2b8152f406c9fe8208b6 Mon Sep 17 00:00:00 2001 From: "Vincenzo (Wilk) Ferrari" Date: Fri, 26 Sep 2014 15:28:47 +0200 Subject: [PATCH 03/13] removed grunt support --- Gruntfile.js | 32 -------------------------------- package.json | 33 --------------------------------- 2 files changed, 65 deletions(-) delete mode 100644 Gruntfile.js delete mode 100644 package.json diff --git a/Gruntfile.js b/Gruntfile.js deleted file mode 100644 index fac7833..0000000 --- a/Gruntfile.js +++ /dev/null @@ -1,32 +0,0 @@ -module.exports = function (grunt) { - require('load-grunt-tasks')(grunt); - - grunt.initConfig ({ - uglify: { - dist: { - src: ['Deferred.js'] , - dest: 'Deferred.min.js' - } - } , - jshint: { - dist: { - options: { - globals: { - Ext: true - } , - eqeqeq: true , - undef: true , - eqnull: true , - browser: true , - smarttabs: true , - loopfunc: true - } , - src: ['Deferred.js'] - } - } - }); - - grunt.registerTask ('check', ['jshint']); - grunt.registerTask ('minify', ['uglify']); - grunt.registerTask ('build', ['check', 'minify']); -}; diff --git a/package.json b/package.json deleted file mode 100644 index d8d9c8c..0000000 --- a/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "Ext.ux.Deferred", - "version": "0.0.2", - "description": "Promises for ExtJS 4 and Sencha Touch", - "main": "Deferred.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "repository": { - "type": "git", - "url": "https://github.com/wilk/Ext.ux.Deferred.git" - }, - "keywords": [ - "extjs", - "senchatouch", - "promise", - "ux", - "extension", - "defer" - ], - "author": "Vincenzo (Wilk)", - "license": "MIT", - "bugs": { - "url": "https://github.com/wilk/Ext.ux.Deferred/issues" - }, - "homepage": "https://github.com/wilk/Ext.ux.Deferred", - "devDependencies": { - "load-grunt-tasks": "~0.2.1", - "grunt": "~0.4.2", - "grunt-contrib-jshint": "~0.8.0", - "grunt-contrib-uglify": "~0.3.0" - } -} From b2285549af23a658a10a75468748b256d3e3b3c2 Mon Sep 17 00:00:00 2001 From: "Vincenzo (Wilk) Ferrari" Date: Fri, 26 Sep 2014 15:36:53 +0200 Subject: [PATCH 04/13] moved sources from root to src --- src/Deferred.js | 106 ++++++++++++++++++++ src/Promise.js | 251 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 357 insertions(+) create mode 100644 src/Deferred.js create mode 100644 src/Promise.js diff --git a/src/Deferred.js b/src/Deferred.js new file mode 100644 index 0000000..cb23f3c --- /dev/null +++ b/src/Deferred.js @@ -0,0 +1,106 @@ +/** + * @class Ext.ux.Deferred + * @author Vincenzo Ferrari + * + * Deferred for ExtJS and Sencha Touch + * + */ +Ext.define('Ext.ux.Deferred', { + requires: ['Ext.ux.Promise'], + + /** + * internal promise needed from resolve and reject methods + * @private + */ + internalPromise: null, + + inheritableStatics: { + /** + * @method when + * It encapsulates the given promises in a new one that is returned. + * When the new promise is executed, the listeners attached will be notified. + * @param {Function/Ext.ux.Promise/Function[]/Ext.ux.Promise[]} args One or more Ext.ux.Promise or one or more Function that return an Ext.ux.Promise + * The returned promise will be solved or rejected after each given promise have finished + * @return {Ext.ux.Promise} The promise + * @static + */ + when: function () { + var deferred = Ext.create('Ext.ux.Deferred'), + promises = arguments, + promisesLen = promises.length, + rejectedCounter = 0, + resolved = {}, + rejected = {}; + + // Make a single promise for those passed + for (var i = 0; i < promises.length; i++) { + // Use a closure to work with the current one specified by index 'i' + (function (i) { + var promise = promises[i]; + + // This let 'when' to accept functions that return a promise invoking them afterwards + if (typeof promise === 'function') promise = promise(); + + if (promise instanceof Ext.ux.Promise) { + promise.then(function () { + promisesLen--; + resolved[i] = arguments.length === 1 ? arguments[0] : arguments; + + // Execute the promise only if there's no other pending promise + if (promisesLen === 0) { + // If an error occurred or one of the promises has been rejected + // reject the wrapping promise, even if it's the only rejected + if (rejectedCounter > 0) deferred.reject(rejected); + else deferred.resolve(resolved); + } + }, function () { + promisesLen--; + rejectedCounter++; + rejected[i] = arguments.length === 1 ? arguments[0] : arguments; + + if (promisesLen === 0) { + deferred.reject(rejected); + } + }); + } + })(i); + } + + return deferred.promise(); + } + }, + + /** + * @method resolve + * Solve the promise and launch the callback attached with then (or success or done) method. + * The given data is passed to the ballback + * @param {Object} args Data to pass to the attached function + * @return {Ext.ux.Deferred} this + */ + resolve: function () { + return this.internalPromise.resolve.apply(this.internalPromise, arguments); + }, + + /** + * @method reject + * Reject the promise and launch the callback attached with then (or failure or fail) method. + * The given data is passed to the ballback + * @param {Object} args Data to pass to the attached function + * @return {Ext.ux.Deferred} this + */ + reject: function () { + return this.internalPromise.reject.apply(this.internalPromise, arguments); + }, + + /** + * @method promise + * Provides a new instance of Ext.ux.Promise + * @return {Ext.ux.Promise} The promise + */ + promise: function () { + var me = this; + + if (me.internalPromise instanceof Ext.ux.Promise) return me.internalPromise; + else return me.internalPromise = Ext.create('Ext.ux.Promise'); + } +}); diff --git a/src/Promise.js b/src/Promise.js new file mode 100644 index 0000000..045ffc1 --- /dev/null +++ b/src/Promise.js @@ -0,0 +1,251 @@ +/** + * @class Ext.ux.Promise + * @author Vincenzo Ferrari + * + * Promise for ExtJS and Sencha Touch + * + */ +Ext.define('Ext.ux.Promise', { + inheritableStatics: { + /** + * Pending state + * @type Number + * @static + */ + PENDING: 0, + + /** + * Fulfilled state + * @type Number + * @static + */ + FULFILLED: 1, + + /** + * Rejected state + * @type Number + * @static + */ + REJECTED: 2 + }, + + config: { + /** + * The promise state + * @property + */ + state: 0 + }, + + /** + * The internal deferred + * @private + */ + deferred: null, + + /** + * Internal success queue + * @private + */ + successQueue: [], + + /** + * Internal failure queue + * @private + */ + failureQueue: [], + + /** + * Creates a new promise + * @param {object} cfg The configuration options may be specified as follows: + * + * // with a configuration set + * var config = { + * deferred: deferred // deferred is an instace of Ext.ux.Deferred + * }; + * + * var promise = Ext.create('Ext.ux.Promise', config); + * + * @return {Ext.ux.Promise} An instance of Ext.ux.Promise or null if an error occurred. + */ + constructor: function (cfg) { + var me = this; + + me.initConfig(cfg); + + // Reset internal configurations + me.successQueue = []; + me.failureQueue = []; + me.deferred = null; + + return me; + }, + + /** + * @method + * Resolve the promise, called directly from the parent deferred + * @private + */ + resolve: function () { + var me = this, + results = [], + errors = [], + args = Array.prototype.slice.call(arguments, 0); + + me.setState(Ext.ux.Promise.FULFILLED); + + // Resolve it only if it needed + if (me.successQueue.length > 0) { + while (me.successQueue.length > 0) { + var onSuccess = me.successQueue.shift(); + + if (typeof onSuccess === 'function') { + try { + var result = onSuccess.apply(null, arguments); + if (result) results.push(result); + } + catch (err) { + errors.push(err); + } + } + } + + // If there's an error, reject the associated deferred + if (errors.length > 0) me.deferred.reject(errors); + else { + // Otherwise resolve it with every result + results = args.concat(results); + me.deferred.resolve(results); + } + } + }, + + /** + * @method + * Reject the promise, called directly from the parent deferred + * @private + */ + reject: function () { + var me = this, + results = [], + errors = [], + args = Array.prototype.slice.call(arguments, 0); + + me.setState(Ext.ux.Promise.REJECTED); + + if (me.failureQueue.length > 0) { + while (me.failureQueue.length > 0) { + var onFailure = me.failureQueue.shift(); + + if (typeof onFailure === 'function') { + try { + var result = onFailure.apply(null, arguments); + if (result) results.push(result); + } + catch (err) { + errors.push(err); + } + } + } + + if (errors.length > 0) me.deferred.reject(errors); + else { + results = args.concat(results); + me.deferred.reject(results); + } + } + }, + + /** + * @method then + * Attaches two callbacks to the deferred internal reference, one for success and one for failure. + * They are called by deferred.resolve and deferred.reject + * @param {Function} onSuccess Success callback, called by deferred.resolve + * @param {Function} onFailure Failure callback, called by deferred.reject + * @return {Ext.ux.Promise} this + */ + then: function (onSuccess, onFailure) { + var me = this; + + if (typeof onSuccess !== 'function' && typeof onFailure !== 'function') throw new Error('Ext.ux.Promise.then(): onSuccess or onFailure callback is needed'); + + if (!(me.deferred instanceof Ext.ux.Deferred)) me.deferred = Ext.create('Ext.ux.Deferred'); + + if (typeof onSuccess === 'function') me.successQueue.push(onSuccess); + if (typeof onFailure === 'function') me.failureQueue.push(onFailure); + + return me.deferred.promise(); + }, + + /** + * @method success + * Attaches the success callback to the promise + * @param {Function} onSuccess Callback successful promise + * @returns {Ext.ux.Promise} Return itself + */ + success: function (onSuccess) { + this.then(onSuccess); + + return this; + }, + + /** + * @method done + * Alias for success + * @param {Function} onSuccess Callback exectued after the promise is resolved + * @returns {Ext.ux.Promise} Return itself + */ + done: function (onSuccess) { + this.then(onSuccess); + + return this; + }, + + /** + * @method failure + * Attaches the failure callback to the promise + * @param {Function} onFailure Callback executed after the promise is rejected + * @returns {Ext.ux.Promise} Return itself + */ + failure: function (onFailure) { + this.then(undefined, onFailure); + + return this; + }, + + /** + * @method fail + * Alias for failure + * @param {Function} onFailure Callback executed after the promise is rejected + * @returns {Ext.ux.Promise} Return itself + */ + fail: function (onFailure) { + this.then(undefined, onFailure); + + return this; + }, + + /** + * Check if the promise is resolved or not + * @returns {boolean} true if the promise is resolved, false otherwise + */ + resolved: function () { + return this.getState() === Ext.ux.Promise.FULFILLED; + }, + + /** + * Check if the promise is rejected or not + * @returns {boolean} true if the promise is rejected, false otherwise + */ + rejected: function () { + return this.getState() === Ext.ux.Promise.REJECTED; + }, + + /** + * Check if the promise is pending or not + * @returns {boolean} true if the promise is pending, false otherwise + */ + pending: function () { + return this.getState() === Ext.ux.Promise.PENDING; + } +}); \ No newline at end of file From 0c4a6b77d33ff8e7efc8316068dbe65a58699884 Mon Sep 17 00:00:00 2001 From: "Vincenzo (Wilk) Ferrari" Date: Fri, 26 Sep 2014 15:37:05 +0200 Subject: [PATCH 05/13] added package configuration --- .sencha/package/Boot.js | 1141 +++++++++++++++++++++++++++ .sencha/package/Microloader.js | 390 +++++++++ .sencha/package/bootstrap-impl.xml | 301 +++++++ .sencha/package/build-impl.xml | 359 +++++++++ .sencha/package/build.properties | 8 + .sencha/package/codegen.json | 118 +++ .sencha/package/defaults.properties | 155 ++++ .sencha/package/find-cmd-impl.xml | 58 ++ .sencha/package/init-impl.xml | 266 +++++++ .sencha/package/js-impl.xml | 71 ++ .sencha/package/plugin.xml | 32 + .sencha/package/refresh-impl.xml | 11 + .sencha/package/resources-impl.xml | 32 + .sencha/package/sass-impl.xml | 114 +++ .sencha/package/sencha.cfg | 60 ++ .sencha/package/slice-impl.xml | 108 +++ .sencha/package/sub-builds.xml | 185 +++++ .sencha/package/testing.properties | 17 + 18 files changed, 3426 insertions(+) create mode 100644 .sencha/package/Boot.js create mode 100644 .sencha/package/Microloader.js create mode 100644 .sencha/package/bootstrap-impl.xml create mode 100644 .sencha/package/build-impl.xml create mode 100644 .sencha/package/build.properties create mode 100644 .sencha/package/codegen.json create mode 100644 .sencha/package/defaults.properties create mode 100644 .sencha/package/find-cmd-impl.xml create mode 100644 .sencha/package/init-impl.xml create mode 100644 .sencha/package/js-impl.xml create mode 100644 .sencha/package/plugin.xml create mode 100644 .sencha/package/refresh-impl.xml create mode 100644 .sencha/package/resources-impl.xml create mode 100644 .sencha/package/sass-impl.xml create mode 100644 .sencha/package/sencha.cfg create mode 100644 .sencha/package/slice-impl.xml create mode 100644 .sencha/package/sub-builds.xml create mode 100644 .sencha/package/testing.properties diff --git a/.sencha/package/Boot.js b/.sencha/package/Boot.js new file mode 100644 index 0000000..7cb0bb5 --- /dev/null +++ b/.sencha/package/Boot.js @@ -0,0 +1,1141 @@ +// @tag core +// @define Ext.Boot +// @define Ext + + +// here, the extra check for window['Ext'] is needed for use with cmd-test +// code injection. we need to make that this file will sync up with page global +// scope to avoid duplicate Ext.Boot state. That check is after the initial Ext check +// to allow the sandboxing template to inject an appropriate Ext var and prevent the +// global detection. +var Ext = Ext || window['Ext'] || {}; + +// +/* + * @class Ext.Boot + * @singleton + */ +Ext.Boot = Ext.Boot || (function (emptyFn) { + + var doc = document, + _config = { + /* + * @cfg {Boolean} [disableCaching=true] + * If `true` current timestamp is added to script URL's to prevent caching. + * In debug builds, adding a "cache" or "disableCacheBuster" query parameter + * to the page's URL will set this to `false`. + */ + disableCaching: + (/[?&](?:cache|disableCacheBuster)\b/i.test(location.search) || + (location.href.substring(0,5) === 'file:') || + /(^|[ ;])ext-cache=1/.test(doc.cookie)) ? false : + true, + + /* + * @cfg {String} [disableCachingParam="_dc"] + * The query parameter name for the cache buster's timestamp. + */ + disableCachingParam: '_dc', + + /* + * @cfg {Boolean} loadDelay + * Millisecond delay between asynchronous script injection (prevents stack + * overflow on some user agents) 'false' disables delay but potentially + * increases stack load. + */ + loadDelay: false, + + /* + * @cfg {Boolean} preserveScripts + * `false` to remove asynchronously loaded scripts, `true` to retain script + * element for browser debugger compatibility and improved load performance. + */ + preserveScripts: true, + + /* + * @cfg {String} charset + * Optional charset to specify encoding of dynamic content. + */ + charset: undefined + }, + + // The request object currently being processed + _currentRequest, + + // A queue of requests which arrived during the time that an "exclusive" load was being processed. + _suspendedQueue = [], + + // Keyed by absolute URL this object holds "true" if that URL is already loaded + // or an array of callbacks to call once it loads. + _items = { + /* + 'http://foo.com/bar/baz/Thing.js': { + done: true, + el: scriptEl || linkEl, + preserve: true, + requests: [ request1, ... ] + } + */ + }, + cssRe = /\.css(?:\?|$)/i, + pathTailRe = /\/[^\/]*$/, + resolverEl = doc.createElement('a'), + isBrowser = typeof window !== 'undefined', + _environment = { + browser: isBrowser, + node: !isBrowser && (typeof require === 'function'), + phantom: (typeof phantom !== 'undefined' && phantom.fs) + }, + _listeners = [], + + // track new entries as they are created, used to fire onBootReady listeners + _entries = 0, + + // when loadSync is called, need to cause subsequent load requests to also be loadSync, + // eg, when Ext.require(...) is called + _syncMode = 0; + + var Boot = { + loading: 0, + + loaded: 0, + + env: _environment, + + /* + * Configuration + * @private + */ + config: _config, + + /* + * @private + * @property + */ + scripts: _items, + + /* + * contains the current script name being loaded + * (loadSync or sequential load only) + */ + currentFile: null, + + /* + * This method returns a canonical URL for the given URL. + * + * For example, the following all produce the same canonical URL (which is the + * last one): + * + * http://foo.com/bar/baz/zoo/derp/../../goo/Thing.js?_dc=12345 + * http://foo.com/bar/baz/zoo/derp/../../goo/Thing.js + * http://foo.com/bar/baz/zoo/derp/../jazz/../../goo/Thing.js + * http://foo.com/bar/baz/zoo/../goo/Thing.js + * http://foo.com/bar/baz/goo/Thing.js + * + * @private + */ + canonicalUrl: function (url) { + // @TODO - see if we need this fallback logic + // http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue + resolverEl.href = url; + + var ret = resolverEl.href, + dc = _config.disableCachingParam, + pos = dc ? ret.indexOf(dc + '=') : -1, + c, end; + + // If we have a _dc query parameter we need to remove it from the canonical + // URL. + if (pos > 0 && ((c = ret.charAt(pos - 1)) === '?' || c === '&')) { + end = ret.indexOf('&', pos); + end = (end < 0) ? '' : ret.substring(end); + if (end && c === '?') { + ++pos; // keep the '?' + end = end.substring(1); // remove the '&' + } + ret = ret.substring(0, pos - 1) + end; + } + + return ret; + }, + + init: function () { + var scriptEls = doc.getElementsByTagName('script'), + len = scriptEls.length, + re = /\/ext(\-[a-z\-]+)?\.js$/, + entry, script, src, state, baseUrl, key, n; + + // Since we are loading after other scripts, and we needed to gather them + // anyway, we track them in _scripts so we don't have to ask for them all + // repeatedly. + for(n = 0; n < len; n++) { + src = (script = scriptEls[n]).src; + if (!src) { + continue; + } + state = script.readyState || null; + + // If we find a script file called "ext-*.js", then the base path is that file's base path. + if (!baseUrl) { + if (re.test(src)) { + Boot.hasAsync = ("async" in script) || !('readyState' in script); + baseUrl = src; + } + } + + if (!_items[key = Boot.canonicalUrl(src)]) { + _items[key] = entry = { + key: key, + url: src, + done: state === null || // non-IE + state === 'loaded' || state === 'complete', // IE only + el: script, + prop: 'src' + }; + + if (!entry.done) { // in IE we can add onreadystatechange + Boot.watch(entry); + } + } + } + if (!baseUrl) { + script = scriptEls[scriptEls.length - 1]; + baseUrl = script.src; + Boot.hasAsync = ("async" in script) || !('readyState' in script); + } + Boot.baseUrl = baseUrl.substring(0, baseUrl.lastIndexOf('/') + 1); + }, + + create: function (url, key) { + var css = url && cssRe.test(url), + el = doc.createElement(css ? 'link' : 'script'), + prop; + + if (css) { + el.rel = 'stylesheet'; + prop = 'href'; + } else { + el.type = 'text/javascript'; + if (!url) { + return el; + } + prop = 'src'; + + if(Boot.hasAsync) { + el.async = false; + } + } + + key = key || url; + return _items[key] = { + key: key, + url: url, + css: css, + done: false, + el: el, + prop: prop, + loaded: false, + evaluated: false + }; + }, + + /* + * Get the config value corresponding to the specified name. If no name is given, will return the config object + * @param {String} name The config property name + * @return {Object} + */ + getConfig: function(name) { + return name ? _config[name] : _config; + }, + + /* + * Set the configuration. + * @param {Object} config The config object to override the default values. + * @return {Ext.Boot} this + */ + setConfig: function (name, value) { + if (typeof name === 'string') { + _config[name] = value; + } else { + for (var s in name) { + Boot.setConfig(s, name[s]); + } + } + + return Boot; + }, + + getHead: function () { + return Boot.docHead || + (Boot.docHead = doc.head || + doc.getElementsByTagName('head')[0]); + }, + + inject: function (content, url, asset) { + var head = Boot.getHead(), + base, el, css = false, key = Boot.canonicalUrl(url), + entry; + + if (cssRe.test(url)) { + css = true; + el = doc.createElement('style'); + el.type = 'text/css'; + el.textContent = content; + + if (asset) { + if ('id' in asset) { + el.id = asset.id; + } + + if ('disabled' in asset) { + el.disabled = asset.disabled; + } + } + + base = doc.createElement('base'); + base.href = key.replace(pathTailRe, '/'); + head.appendChild(base); + head.appendChild(el); + head.removeChild(base); + } else { + // Debugger friendly, file names are still shown even though they're + // eval'ed code. Breakpoints work on both Firebug and Chrome's Web + // Inspector. + if (url) { + content += "\n//# sourceURL=" + key; + } + Ext.globalEval(content); + } + + entry = _items[key] || (_items[key] = { + key: key, + css: css, + url: url, + el: el + }); + entry.done = true; + return entry; + }, + + /* + * This method loads the specified scripts or CSS files and calls either the + * given `success` callback when all of the files have successfully loaded or the + * `failure` callback should any fail to load. + * + * Ext.Boot.load({ + * url: 'http://foo.com/bar/Thing.js', + * + * success: function () { + * }, + * + * failure: function () { + * }, + * + * scope: this + * }); + * + * Ext.Boot.load({ + * url: [ + * 'http://foo.com/bar/baz/Goo.js', + * 'http://foo.com/bar/Thing.js' + * ], + * charset: 'utf-8', + * cache: false, // add "cache buster" + * + * success: function () { + * }, + * + * failure: function () { + * }, + * + * scope: this, + * prependBaseUrl: false + * }); + * + * @param {Object} request The load request object. **IMPORTANT:** This object + * should not be reused by the caller as it is used to track the given callbacks + * until the script loads. + * + * @param {Boolean} [request.cache] An override for the cache busting specified by + * for the script. Overrides the `disableCaching` value passed to `setConfig`. + * + * @param {String} [request.charset] The charset for the script. Overrides the + * default `charset` passed to `setConfig`. + * + * @param {Boolean} [request.sync=false] Pass `true` to load scripts synchronously. + * + * @param {Function} request.success The function to execute once the script node + * loads. For IE less than version 9, this function will only once the readyState + * is `loaded` or `complete`. + * + * @param {Function} request.failure The function to execute if the script node + * fails to load such as a 404 status is returned. + * + * @param {Object} [request.scope] The scope with which to call the `success` and + * `failure` functions. + * + * @param {Object} [request.sequential] Load in strict order. + * + * @param {boolean} [request.prependBaseUrl] whether to prepend Ext.Boot.baseUrl + * to the beginning of each url of the request + * + * @return {Ext.Boot} this + */ + load: function (request) { + if (request.sync || _syncMode) { + return this.loadSync(request); + } + + // Allow a raw array of paths to be passed. + if (!request.url) { + request = { + url: request + }; + } + + // If there is a request in progress, we must + // queue this new request to be fired when the current request completes. + if (_currentRequest) { + _suspendedQueue.push(request); + } else { + Boot.expandLoadOrder(request); + + var url = request.url, + urls = url.charAt ? [ url ] : url, + length = urls.length, + i; + + // Start the counter here. This is reduced as we notify this fellow of script + // loads. + request.urls = urls; + request.loaded = 0; + request.loading = length; + request.charset = request.charset || _config.charset; + request.buster = (('cache' in request) ? !request.cache : _config.disableCaching) && + (_config.disableCachingParam + '=' + (+new Date())); + + _currentRequest = request; + request.sequential = false; + + for (i = 0; i < length; ++i) { + Boot.loadUrl(urls[i], request); + } + } + + return this; + }, + + loadUrl: function(url, request) { + var entry, + buster = request.buster, + charset = request.charset, + head = Boot.getHead(), + el, key; + + if (request.prependBaseUrl) { + url = Boot.baseUrl + url; + } + + if (request.sequential) { + Boot.currentFile = url; + } else { + Boot.currentFile = null; + } + + key = Boot.canonicalUrl(url); + if (!(entry = _items[key])) { + // we're creating a new entry; + _entries++; + + // Not already loaded or loading, so we need to create a new script + // element and tracking entry. + entry = Boot.create(url, key); + el = entry.el; + if (!entry.css && charset) { + el.charset = charset; + } + entry.requests = [request]; + + Boot.watch(entry); + + if (buster) { + // Check for the presence of a querystring. + url += (url.indexOf('?') === -1 ? '?' : '&') + buster; + } + + if(!Boot.hasAsync && !entry.css) { + entry.loaded = false; + entry.evaluated = false; + + var onLoadWas, + newOnLoad = function() { + entry.loaded = true; + var rurls = request.urls, + rlen = rurls.length, r, e, k; + for(r = 0; r < rlen; r++) { + k = Boot.canonicalUrl(rurls[r]); + e = _items[k]; + if(e) { + if(!e.loaded) { + return; + } else if(!e.evaluated) { + head.appendChild(e.el); + e.evaluated = true; + e.onLoadWas.apply(e.el, arguments); + } + } + } + }; + /* + * When available (IE9m), we need to use the onreadystatechange / readyState + * mechanism to monitor script load and cause script evaluation by appending + * elements to the document. Modern browsers use the onload mechanism. + */ + if (!('readyState' in el)) { + onLoadWas = el.onload; + el.onload = newOnLoad; + } else { + // IE9m Compatability + onLoadWas = el.onreadystatechange; + el.onreadystatechange = function() { + if (this.readyState === 'loaded' || this.readyState === 'complete') { + newOnLoad.apply(this, arguments); + } + }; + } + + entry.onLoadWas = onLoadWas; + el[entry.prop] = url; // IE starts loading scripts here + } else { + el[entry.prop] = url; // IE starts loading scripts here + head.appendChild(el); // others start loading here + } + } + else if (entry.done) { + Boot.notify(entry, request); + } + // If the script is already in the document, we must assume we are here + // because whatever was in the script seemed to be not present... which + // should mean that the script is loading at this time. Sadly, only IE + // and its readyState property can tell us the truth of the matter. In + // standards browsers we have no way to know. + else if (entry.requests) { + entry.requests.push(request); + } + else { + entry.requests = [ request ]; + } + }, + + loadSequential: function(request) { + if(!request.url) { + request = { + url: request + } + } + request.sequential = true; + Boot.load(request); + }, + + loadSequentialBasePrefix: function(request) { + if(!request.url) { + request = { + url: request + }; + } + request.prependBaseUrl = true; + Boot.loadSequential(request); + }, + + fetchSync: function(url) { + var exception, xhr, status, content; + + exception = false; + xhr = new XMLHttpRequest(); + + try { + xhr.open('GET', url, false); + xhr.send(null); + } catch (e) { + exception = true; + } + + status = (xhr.status === 1223) ? 204 : + (xhr.status === 0 && ((self.location || {}).protocol === 'file:' || + (self.location || {}).protocol === 'ionp:')) ? 200 : xhr.status; + content = xhr.responseText; + + xhr = null; // Prevent potential IE memory leak + + return { + content: content, + exception: exception, + status: status + }; + + + }, + + /* + * Performs the load of scripts synchronously. + * @param {type} request + * @return {Ext.Boot} this + * @private + */ + loadSync: function (request) { + _syncMode++; + var request = Boot.expandLoadOrder(request.url ? request : {url: request}), + url = request.url, + urls = url.charAt ? [ url ] : url, + length = urls.length, + buster = _config.disableCaching && + ('?' + _config.disableCachingParam + '=' + (+new Date())), + content, entry, i, key, status, exception; + + // Start the counter here. This is reduced as we notify this fellow of script + // loads. + request.loading = length; + request.urls = urls; + request.loaded = 0; + + // create a pseudo entry value to keep the listeners from firing until + // after the loop is complete + _entries++; + + for (i = 0; i < length; ++i) { + url = urls[i]; + if (request.prependBaseUrl) { + url = Boot.baseUrl + url; + } + Boot.currentFile = url; + + key = Boot.canonicalUrl(url); + if (!(entry = _items[key])) { + // we're creating a new entry + _entries++; + + _items[key] = entry = { + key: key, + url: url, + done: false, + requests: [request], + el: null + }; + } else { + // We already have a script tag for this URL... if it is still loading + // we need to boot it out and load synchronously. + if (entry.done) { + Boot.notify(entry, request); + continue; + } + if (entry.el) { + entry.preserve = false; + Boot.cleanup(entry); + } + + if (entry.requests) { + entry.requests.push(request); + } else { + entry.requests = [request]; + } + } + + entry.sync = true; + + if (buster) { + url += buster; + } + + ++Boot.loading; + + + content = Boot.fetchSync(url); + entry.done = true; + + exception = content.exception; + status = content.status; + content = content.content || ''; + + if ((exception || status === 0) && !_environment.phantom) { + entry.error = + // + ("Failed loading synchronously via XHR: '" + url + + "'. It's likely that the file is either being loaded from a " + + "different domain or from the local file system where cross " + + "origin requests are not allowed for security reasons. Try " + + "asynchronous loading instead.") || + // + true; + } + else if ((status >= 200 && status < 300) || status === 304 + || _environment.phantom + || (status === 0 && content.length > 0) + ) { + Boot.inject(content, url); + } + else { + entry.error = + // + ("Failed loading synchronously via XHR: '" + url + + "'. Please verify that the file exists. XHR status code: " + + status) || + // + true; + } + + Boot.notifyAll(entry); + } + _syncMode--; + + // once the loop is complete, we can attempt to fire any pending listeners + _entries--; + Boot.fireListeners(); + Boot.currentFile = null; + return this; + }, + + loadSyncBasePrefix: function(request) { + if(!request.url) { + request = { + url: request + }; + } + request.prependBaseUrl = true; + Boot.loadSync(request); + }, + + notify: function (entry, request) { + if (request.preserve) { + // If one listener explicitly passes preserve:true we honor it. + entry.preserve = true; + } + + ++request.loaded; + + // + if (!request.loading) { + throw new Error('Unexpected script load notification ' + entry.url); + } + // + + if (entry.error) { + (request.errors || (request.errors = [])).push(entry); + } + + if (! --request.loading) { + // There is no current request, new load calls can go ahead. + _currentRequest = null; + + var errors = request.errors, + fn = request[errors ? 'failure' : 'success'], + delay = ('delay' in request) ? request.delay : + (errors ? 1 : _config.chainDelay), + scope = request.scope || request; + + // If there were queued requests which arrived during the time this request was processing + // Fire them off now. + if (_suspendedQueue.length) { + Boot.load(_suspendedQueue.shift()); + } + + if (fn) { + if (delay === 0 || delay > 0) { + // Free the stack (and defer the next script) + setTimeout(function() { + fn.call(scope, request); + }, delay); + } else { + fn.call(scope, request); + } + } + + } else if (!_syncMode && request.sequential && (request.loaded < request.urls.length)) { + Boot.loadUrl(request.urls[request.loaded], request); + } + }, + + notifyAll: function (entry) { + var requests = entry.requests, + length = requests && requests.length, + i; + + entry.done = true; + entry.requests = null; + --Boot.loading; + ++Boot.loaded; + + for (i = 0; i < length; ++i) { + Boot.notify(entry, requests[i]); + } + + if (!length) { + entry.preserve = true; + } + + Boot.cleanup(entry); + _entries--; + Boot.fireListeners(); + }, + + watch: function (entry) { + var el = entry.el, + requests = entry.requests, + listener = requests && requests[0], + onLoadFn = function () { + if (!entry.done) { + Boot.notifyAll(entry); + } + }; + + el.onerror = function () { + entry.error = true; + Boot.notifyAll(entry); + }; + + entry.preserve = (listener && ('preserve' in listener)) + ? listener.preserve : _config.preserveScripts; + + /* + * When available (IE9m), we need to use the onreadystatechange / readyState + * mechanism to monitor script load and cause script evaluation by appending + * elements to the document. Modern browsers use the onload mechanism. + */ + if (!('readyState' in el)) { + el.onload = onLoadFn; + } else { + // IE9m Compatability + el.onreadystatechange = function() { + if (this.readyState === 'loaded' || this.readyState === 'complete') { + onLoadFn(); + } + }; + } + + ++Boot.loading; + }, + + /* + * @private + */ + cleanup: function (entry) { + var el = entry.el, + prop; + + if(!el) { + return; + } + + if (!entry.preserve) { + entry.el = null; + + el.parentNode.removeChild(el); // Remove, since its useless now + + for (prop in el) { + try { + if (prop !== entry.prop) { + // If we set the src property to null IE + // will try and request a script at './null' + el[prop] = null; + } + delete el[prop]; // and prepare for GC + } catch (cleanEx) { + //ignore + } + } + } + + // Setting to null can cause exceptions if IE ever needs to call these + // again (like onreadystatechange). This emptyFn has nothing locked in + // closure scope so it is about as safe as null for memory leaks. + el.onload = el.onerror = el.onreadystatechange = emptyFn; + }, + + fireListeners: function() { + var listener; + while(!_entries && (listener = _listeners.shift())) { + listener(); + } + }, + + onBootReady: function(listener) { + if (!_entries) { + listener(); + } else { + _listeners.push(listener); + } + }, + + /* + * @private + * @param manifest + * @returns {*} + */ + createLoadOrderMap: function(loadOrder) { + var len = loadOrder.length, + loadOrderMap = {}, + i, element; + + for(i = 0; i < len; i++) { + element = loadOrder[i]; + loadOrderMap[element.path] = element; + } + + return loadOrderMap; + }, + + /* + * @private + * @param index + * @param indexMap + * @returns {{}} + */ + getLoadIndexes: function(index, indexMap, loadOrder, includeUses, skipLoaded) { + var item = loadOrder[index], + len, i, reqs, key, entry, stop, added, idx, ridx; + + if(indexMap[index]) { + // prevent cycles + return indexMap; + } + + indexMap[index] = true; + + stop = false; + while(!stop) { + added = false; + + // iterate the requirements for each index and + // accumulate in the index map + for(idx in indexMap) { + if(indexMap.hasOwnProperty(idx)) { + item = loadOrder[idx]; + if(!item) { + continue; + } + key = Boot.canonicalUrl(item.path); + entry = _items[key]; + if(!skipLoaded || !entry || !entry.done) { + reqs = item.requires; + if(includeUses && item.uses) { + reqs = reqs.concat(item.uses); + } + for(len = reqs.length, i = 0; i < len; i++) { + ridx = reqs[i]; + // if we find a requirement that wasn't + // already in the index map, + // set the added flag to indicate we need to + // reprocess + if(!indexMap[ridx]) { + indexMap[ridx] = true; + added = true; + } + } + } + } + } + + // if we made a pass through the index map and didn't add anything + // then we can stop + if(!added) { + stop = true; + } + } + + return indexMap; + }, + + getPathsFromIndexes: function(indexMap, loadOrder) { + var indexes = [], + paths = [], + index, len, i; + + for(index in indexMap) { + if(indexMap.hasOwnProperty(index) && indexMap[index]) { + indexes.push(index); + } + } + + indexes.sort(function(a, b){ + return a-b; + }); + + // convert indexes back into load paths + for (len = indexes.length, i = 0; i < len; i++) { + paths.push(loadOrder[indexes[i]].path); + } + + return paths; + }, + + /* + * @private + * @param url + * @returns {Array} + */ + expandUrl: function(url, loadOrder, loadOrderMap, indexMap, includeUses, skipLoaded) { + if(typeof url == 'string') { + url = [url]; + } + + if(loadOrder) { + loadOrderMap = loadOrderMap || Boot.createLoadOrderMap(loadOrder); + indexMap = indexMap || {}; + var len = url.length, + unmapped = [], + i, item; + + for(i = 0; i < len; i++) { + item = loadOrderMap[url[i]]; + if(item) { + Boot.getLoadIndexes(item.idx, indexMap, loadOrder, includeUses, skipLoaded); + } else { + unmapped.push(url[i]); + } + } + + + + return Boot.getPathsFromIndexes(indexMap, loadOrder).concat(unmapped); + } + return url; + }, + + expandUrls: function(urls, loadOrder, loadOrderMap, includeUses) { + if(typeof urls == "string") { + urls = [urls]; + } + + var expanded = [], + len = urls.length, + i; + + for(i = 0; i < len; i++) { + expanded = expanded.concat( + Boot.expandUrl(urls[i], loadOrder, loadOrderMap, {}, includeUses, true)); + } + + if(expanded.length == 0) { + expanded = urls; + } + + return expanded; + }, + + /* + * @private + */ + expandLoadOrder: function(request) { + var urls = request.url, + loadOrder = request.loadOrder, + loadOrderMap = request.loadOrderMap, + expanded; + + if(!request.expanded) { + expanded = Boot.expandUrls(urls, loadOrder, loadOrderMap); + request.expanded = true; + } else { + expanded = urls; + } + + request.url = expanded; + + // if we added some urls to the request to honor the indicated + // load order, the request needs to be sequential + if(urls.length != expanded.length) { + request.sequential = true; + } + + return request; + } + }; + + /* + * Turns on or off the "cache buster" applied to dynamically loaded scripts. Normally + * dynamically loaded scripts have an extra query parameter appended to avoid stale + * cached scripts. This method can be used to disable this mechanism, and is primarily + * useful for testing. This is done using a cookie. + * @param {Boolean} disable True to disable the cache buster. + * @param {String} [path="/"] An optional path to scope the cookie. + */ + Ext.disableCacheBuster = function (disable, path) { + var date = new Date(); + date.setTime(date.getTime() + (disable ? 10*365 : -1) * 24*60*60*1000); + date = date.toGMTString(); + doc.cookie = 'ext-cache=1; expires=' + date + '; path='+(path || '/'); + }; + +// + if (_environment.node) { + Boot.load = Boot.loadSync = function (request) { + // @TODO + require(filePath); + onLoad.call(scope); + }; + Boot.init = emptyFn; + } +// + + Boot.init(); + return Boot; + +// NOTE: We run the eval at global scope to protect the body of the function and allow +// compressors to still process it. +}(function() {}));//(eval("/*@cc_on!@*/!1")); + +/* + * This method evaluates the given code free of any local variable. In some browsers this + * will be at global scope, in others it will be in a function. + * @parma {String} code The code to evaluate. + * @private + * @method + */ +Ext.globalEval = this.execScript + ? function(code) { + execScript(code); +} + : function($$code) { + // IMPORTANT: because we use eval we cannot place this in the above function or it + // will break the compressor's ability to rename local variables... + (function(){ + // This var should not be replaced by the compressor. We need to do this so + // that Ext refers to the global Ext, if we're sandboxing it may + // refer to the local instance inside the closure + var Ext = this.Ext; + eval($$code); + }()); +}; + +// +/* + * Only IE8 & IE/Quirks lack Function.prototype.bind so we polyfill that here. + */ +if (!Function.prototype.bind) { + (function () { + var slice = Array.prototype.slice, + // To reduce overhead on call of the bound fn we have two flavors based on + // whether we have args to prepend or not: + bind = function (me) { + var args = slice.call(arguments, 1), + method = this; + + if (args.length) { + return function () { + var t = arguments; + // avoid the slice/concat if the caller does not supply args + return method.apply(me, t.length ? args.concat(slice.call(t)) : args); + }; + } + // this is the majority use case - just fn.bind(this) and no args + + args = null; + return function () { + return method.apply(me, arguments); + }; + }; + Function.prototype.bind = bind; + bind.$extjs = true; // to detect this polyfill if one want to improve it + }()); +} +// + +// diff --git a/.sencha/package/Microloader.js b/.sencha/package/Microloader.js new file mode 100644 index 0000000..16fabcf --- /dev/null +++ b/.sencha/package/Microloader.js @@ -0,0 +1,390 @@ +// here, the extra check for window['Ext'] is needed for use with cmd-test +// code injection. we need to make that this file will sync up with page global +// scope to avoid duplicate Ext.Boot state. That check is after the initial Ext check +// to allow the sandboxing template to inject an appropriate Ext var and prevent the +// global detection. +var Ext = Ext || window['Ext'] || {}; + + +// +/** + * @Class Ext.Microloader + * @singleton + */ +Ext.Microloader = Ext.Microloader || (function () { + var apply = function (dest, src, defaults) { + if (defaults) { + apply(dest, defaults); + } + + if (dest && src && typeof src == 'object') { + for (var key in src) { + dest[key] = src[key]; + } + } + return dest; + }, + Boot = Ext.Boot, + _listeners = [], + _loaded = false, + _tags = {}, + Microloader = { + + /** + * the global map of tags used + */ + platformTags: _tags, + + /** + * The defult function that detects various platforms and sets tags + * in the platform map accrodingly. Examples are iOS, android, tablet, etc. + * @param tags the set of tags to populate + */ + detectPlatformTags: function () { + var ua = navigator.userAgent, + isMobile = _tags.isMobile = /Mobile(\/|\s)/.test(ua), + isPhone, isDesktop, isTablet, touchSupported, isIE10, isBlackberry, + element = document.createElement('div'), + uaTagChecks = [ + 'iPhone', + 'iPod', + 'Android', + 'Silk', + 'Android 2', + 'BlackBerry', + 'BB', + 'iPad', + 'RIM Tablet OS', + 'MSIE 10', + 'Trident', + 'Chrome', + 'Tizen', + 'Firefox', + 'Safari', + 'Windows Phone' + ], + isEventSupported = function(name, tag) { + if (tag === undefined) { + tag = window; + } + + var eventName = 'on' + name.toLowerCase(), + isSupported = (eventName in element); + + if (!isSupported) { + if (element.setAttribute && element.removeAttribute) { + element.setAttribute(eventName, ''); + isSupported = typeof element[eventName] === 'function'; + + if (typeof element[eventName] !== 'undefined') { + element[eventName] = undefined; + } + + element.removeAttribute(eventName); + } + } + + return isSupported; + }, + uaTags = {}, + len = uaTagChecks.length, check, c; + + for (c = 0; c < len; c++) { + check = uaTagChecks[c]; + uaTags[check] = new RegExp(check).test(ua); + } + + isPhone = + (uaTags.iPhone || uaTags.iPod) || + (!uaTags.Silk && (uaTags.Android && (uaTags['Android 2'] || isMobile))) || + ((uaTags.BlackBerry || uaTags.BB) && uaTags.isMobile) || + (uaTags['Windows Phone']); + + isTablet = + (!_tags.isPhone) && ( + uaTags.iPad || + uaTags.Android || + uaTags.Silk || + uaTags['RIM Tablet OS'] || + (uaTags['MSIE 10'] && /; Touch/.test(ua)) + ); + + touchSupported = + // if the browser has touch events we can be reasonably sure the device has + // a touch screen + isEventSupported('touchend') || + // browsers that use pointer event have maxTouchPoints > 0 if the + // device supports touch input + // http://www.w3.org/TR/pointerevents/#widl-Navigator-maxTouchPoints + navigator.maxTouchPoints || + // IE10 uses a vendor-prefixed maxTouchPoints property + navigator.msMaxTouchPoints; + + isDesktop = !isPhone && !isTablet; + isIE10 = uaTags['MSIE 10']; + isBlackberry = uaTags.Blackberry || uaTags.BB; + + apply(_tags, Microloader.loadPlatformsParam(), { + phone: isPhone, + tablet: isTablet, + desktop: isDesktop, + touch: touchSupported, + ios: (uaTags.iPad || uaTags.iPhone || uaTags.iPod), + android: uaTags.Android || uaTags.Silk, + blackberry: isBlackberry, + safari: uaTags.Safari && isBlackberry, + chrome: uaTags.Chrome, + ie10: isIE10, + windows: isIE10 || uaTags.Trident, + tizen: uaTags.Tizen, + firefox: uaTags.Firefox + }); + + if (Ext.beforeLoad) { + Ext.beforeLoad(_tags); + } + }, + + /** + * Extracts user supplied platform tags from the "platformTags" query parameter + * of the form: + * + * ?platformTags=name:state,name:state,... + * + * (each tag defaults to true when state is unspecified) + * + * Example: + * ?platformTags=isTablet,isPhone:false,isDesktop:0,iOS:1,Safari:true, ... + * + * @returns {Object} the platform tags supplied by the query string + */ + loadPlatformsParam: function () { + // Check if the ?platform parameter is set in the URL + var paramsString = window.location.search.substr(1), + paramsArray = paramsString.split("&"), + params = {}, i, + platforms = {}, + tmpArray, tmplen, platform, name, enabled; + + for (i = 0; i < paramsArray.length; i++) { + tmpArray = paramsArray[i].split("="); + params[tmpArray[0]] = tmpArray[1]; + } + + if (params.platformTags) { + tmpArray = params.platform.split(/\W/); + for (tmplen = tmpArray.length, i = 0; i < tmplen; i++) { + platform = tmpArray[i].split(":"); + name = platform[0]; + if (platform.length > 1) { + enabled = platform[1]; + if (enabled === 'false' || enabled === '0') { + enabled = false; + } else { + enabled = true; + } + } + platforms[name] = enabled; + } + } + return platform; + }, + + initPlatformTags: function () { + Microloader.detectPlatformTags(); + }, + + getPlatformTags: function () { + return Microloader.platformTags; + }, + + filterPlatform: function (platform) { + platform = [].concat(platform); + var tags = Microloader.getPlatformTags(), + len, p, tag; + + for (len = platform.length, p = 0; p < len; p++) { + tag = platform[p]; + if (tags.hasOwnProperty(tag)) { + return !!tags[tag]; + } + } + return false; + }, + + init: function () { + Microloader.initPlatformTags(); + Ext.filterPlatform = Microloader.filterPlatform; + }, + + initManifest: function (manifest) { + Microloader.init(); + var tmpManifest = manifest || Ext.manifest; + + if (typeof tmpManifest === "string") { + var url = Boot.baseUrl + tmpManifest + ".json", + content = Boot.fetchSync(url); + tmpManifest = JSON.parse(content.content); + } + + Ext.manifest = tmpManifest; + return tmpManifest; + }, + + /** + * + * @param manifestDef + */ + load: function (manifestDef) { + var manifest = Microloader.initManifest(manifestDef), + loadOrder = manifest.loadOrder, + loadOrderMap = (loadOrder) ? Boot.createLoadOrderMap(loadOrder) : null, + urls = [], + js = manifest.js || [], + css = manifest.css || [], + resources = js.concat(css), + resource, i, len, include, + loadedFn = function () { + _loaded = true; + Microloader.notify(); + }; + + for (len = resources.length, i = 0; i < len; i++) { + resource = resources[i]; + include = true; + if (resource.platform && !Microloader.filterPlatform(resource.platform)) { + include = false; + } + if (include) { + urls.push(resource.path); + } + } + + + if (loadOrder) { + manifest.loadOrderMap = loadOrderMap; + } + + Boot.load({ + url: urls, + loadOrder: loadOrder, + loadOrderMap: loadOrderMap, + sequential: true, + success: loadedFn, + failure: loadedFn + }); + }, + + onMicroloaderReady: function (listener) { + if (_loaded) { + listener(); + } else { + _listeners.push(listener); + } + }, + + /** + * @private + */ + notify: function () { + var listener; + while((listener = _listeners.shift())) { + listener(); + } + } + }; + + return Microloader; +}()); + +// + +/** + * the current application manifest + * + * + * { + * name: 'name', + * version: , + * debug: { + * hooks: { + * "*": true + * } + * }, + * localStorage: false, + * mode: production, + * js: [ + * ... + * { + * path: '../boo/baz.js', + * version: , + * update: full | delta | , + * platform: ['phone', 'ios', 'android'] + * }, + * { + * path: 'http://some.domain.com/api.js', + * remote: true + * }, + * ... + * ], + * css: [ + * ... + * { + * path: '../boo/baz.css', + * version: , + * update: full | delta | , + * platform: ['phone', 'ios', 'android'] + * }, + * ... + * ], + * localStorage: false, + * paths: {...}, + * loadOrder: [ + * ... + * { + * path: '../foo/bar.js", + * idx: 158, + * requires; [1,2,3,...,145,157], + * uses: [182, 193] + * }, + * ... + * ], + * classes: { + * ... + * 'Ext.panel.Panel': { + * requires: [...], + * uses: [...], + * aliases: [...], + * alternates: [...], + * mixins: [...] + * }, + * 'Ext.rtl.util.Renderable': { + * requires: [...], + * uses: [...], + * aliases: [...], + * alternates: [...], + * mixins: [...] + * override: 'Ext.util.Renderable' + * }, + * ... + * }, + * packages: { + * ... + * "sencha-core": { + * version: '1.2.3.4', + * requires: [] + * }, + * "ext": { + * version: '5.0.0.0', + * requires: ["sencha-core"] + * }. + * ... + * } + * } + * + * + * @type {String/Object} + */ +Ext.manifest = Ext.manifest || "bootstrap"; + +Ext.Microloader.load(); \ No newline at end of file diff --git a/.sencha/package/bootstrap-impl.xml b/.sencha/package/bootstrap-impl.xml new file mode 100644 index 0000000..398bccb --- /dev/null +++ b/.sencha/package/bootstrap-impl.xml @@ -0,0 +1,301 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = 0) { + project.setProperty('sencha.5.filters', 'true'); + } else { + project.setProperty('sencha.5.filters', 'false'); + } + } catch (err) { + project.setProperty('sencha.5.filters', 'false'); + } + ]]> + + + + + + + + + + + + + + + + + + + + + + include + -namespace=Ext.ux + and + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${bootstrap.file.content} + ${bootstrap.files.content} + ${bootstrap.data.content} + ${bootstrap.overrides.content} + ${bootstrap.launch.content} + + + + + + + + + + \ No newline at end of file diff --git a/.sencha/package/build-impl.xml b/.sencha/package/build-impl.xml new file mode 100644 index 0000000..78bd898 --- /dev/null +++ b/.sencha/package/build-impl.xml @@ -0,0 +1,359 @@ + + + + + + + + Using Sencha Cmd from ${cmd.dir} for ${ant.file} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.sencha/package/build.properties b/.sencha/package/build.properties new file mode 100644 index 0000000..83e7e5f --- /dev/null +++ b/.sencha/package/build.properties @@ -0,0 +1,8 @@ +# ============================================================================= +# This file provides an override point for default variables defined in +# defaults.properties. +# +# IMPORTANT - Sencha Cmd will merge your changes with its own during upgrades. +# To avoid potential merge conflicts avoid making large, sweeping changes to +# this file. +# ============================================================================= diff --git a/.sencha/package/codegen.json b/.sencha/package/codegen.json new file mode 100644 index 0000000..7905e1f --- /dev/null +++ b/.sencha/package/codegen.json @@ -0,0 +1,118 @@ +{ + "sources": { + "sencha.cfg.tpl.merge": { + "6d1982cce48163a98dc46012d1d0cdfa209fbda6": "eJzFVdFq2zAUfc9XXNzBWmicvg0GgXZlD9vDWsge96LIcqJFljRJTuqN/vuOJNvJmqbbYLASim1dnXPuuVdXZ/R5LUizRpCpKeDZMr5hK0FT8mvTqooaFvg6LRUxriDrjBUudCQ1lbM+vvzqjZ6cTYbXGDr/YTerT3h4nEzORiKPEEHB0G4tE7D0A+lrT4ubxYK4cQ5xRle+TPsqUbNWBdoy1UalgCveP4SCGsG0BwYLSWEtlfBZl2fez7zjdM50NbxvmbvoE+IKH1IwwOLehOeMCXuVJX3QZLDoaGdc5S8Ta2mZFqq8j/+hgFkIMADZc85SxCxFlJ57X2I5WmDIh06Jkbx2piGmuz3lJXkRsimwaKmY3kBFnb/gl75cZsk6hmTAY12daSE6FtC2IduaUj1QiT3PKR1rGAPLUdkc4bmOWUn0jJumYVMvLHMsiIqU9CE2Um1UJZxHiYXbZ4uaykqkinoBpOF702LXUpB4sEpyGVSH0G+tdECMJggo56qt8IrSRt5lK1V1KDVBWRbW81df2qurN++GhUq6x5js3yrHo9kK5yAYPXij1L63YimAFtloJ7ECgSu5RTkYBbaKW4ue/m6AKPpuBztrg0ELSs6U6oAzpgroldAi62EWbbXs8pGEcULz/ogCQkkdPYlBOHdv4cMZEc1m1z0WXT/lP7BqTOtZq8bVp4ZlY/qKpnYqYGvRFzWd0xzsBXN8jRRq42hxu1gAKHuXjul+nHxkW7bgTtowdkLrsa/PGsmhG2CU0UdNCebTxe7b+w8SwDjw/ykDUL+cAQLGDCL5UeuQbKxxITUOTkkkTFmls4GehHjRp3jELsJv/EPADCRpJJwwEv3XT3BDVsWZXsQuXbM8zeMdkqQUZNqAGXQoIp9f0D2rIK0OV0bPlpznRgcmMfDFA2us+sXhc3+R6nV4nxxS9lv8SdYh4EVi3y6n/S4/HscBhu40yoI7SubWKWqH4YmbY1OkeZEv1tDZX4QBEtfkaV0DHXTN/+kfNN1i8uIGus83ukROU7pPteRpRX5P3mISCWV2B8MHNWdbgzwb4VZplhtdoxQBM19iLmqxg3eYJT5un/wEixPeXA\u003d\u003d" + }, + "build.properties.merge": { + "8b81315dbe73ce9c08478f4c1d2df84f456efcf5": "eJytkEtOxEAMRPdzipKyhbkBCzQrFnzE5AKetJNYdOzI3UnE7XGA3GC8K5f9/GnwdM84NWhHKeglM2a3VRIXkMJWdg+B2UQrenMk7mnJFSu50C1HXWREOUEUAfr3yzk4M3sVLudTE8bL68f7Z/v81uIRV9ZuJFymhE1yxsQ+ML5tcUReh6BuUkdILbBNkRYXHbDMg1P6BaI10GqSYrXKWoUOSmfaZ+mi88+f6GvvzRTmA8rGPO/6mFMtYPW4fiff97U/al6C1w\u003d\u003d" + }, + "testing.properties.merge": { + "e65f969c42eb4f355c850fc58fea852582f20db8": "eJyVkUFywyAQBO9+xVb5oIutH/gX+QCCkbUOAooFOf59FsmqpHKKOFEwOzM0Z7r9f53O9DGx0Mge5DBygFDKMSEX1m0VOBpepLqhsndXnpPvv2Z/oefEdiKdLRNoMAJqdyqMI5lAJiXP1hSOQbbZ5msh0mskmuOvnDHHWY32JjbmDEkxOCqxBai6K5DC4d693RAWzjHMCOVCkmB5ZLhW9EWdINjJtBJv9T7cU0vXsk/2rWwxn9AisHA6AooLcgNhqi8riYXdimAn0P+07vXsCOuD8rNimLWaiDKkmBrK7UOUyR0B2RRQdzXedyp+CMVaUi0rQn3ninMxvurPspjBQ/54jjHvYLbHycGKG5Fm2SIf0u/ut9M3l43NIg\u003d\u003d" + }, + "package.json.tpl.merge": { + "12322b2f0769f491000df8ec0e012dd2d78a7eaf": "eJx1zrEKwjAQgOG9TxE6S9HV2VFcFBdxONJrDW1y8XIRSum7m2pTJzMd/3cHGQuVXunAYrlX5ei79pTmqdx8QQa/wiXNK2hGEOLZwJEbLMWQLURrgYfZzg9iUTksXqOA6bE+YNBsvBhy8+6RXKvqX1PUKA+6gxbz5Qs5LNu7altt19+Q9SDXP9oQW5BPzqknDX0qwhGXxPiMhjGkersXU/EGNatRVA\u003d\u003d" + }, + "theme.html.tpl.merge": { + "32f685a8af28baafcc7999862d0bd1f25df0e48b": "eJx1U02P0zAQvedXzPoEFW66CwfUTXopiwAhgbTlwNF1po13HdvY0zYR4r9jOwXSBXxI5HnzPqyxq6s3n9abr5/voKVOr4rqivMCANbWDV7tW4Jn8jncLK5vePy8nMM9GtkKeG/kvOA8Es68FkWzSkyoSJHG1V1P8OEeNi12CO+ENxhCVY7Y2NchiWhLjuO3gzrWbG0NoSG+GRwykOOuZoQ9lcnmFqK1D0j1l81b/pqtilHonBk+WtGA0Bp8EvTYgFbmMYAwDQTplaOQ+1LuTExwbNY1CzRoDC0iMaBof3aVITBoPe5qhr3onMZ5LpVngVF1yngQRzFWGQQva7a1lgJ54eYPga2qcgR/Rc++o1ha85Nq9kg8nV0ogx6+/8bS6oTfK7OE64Xrby+QSKR2Ca8WfyHOBkXKRlY8qSB1xEvcHtHvtD0t4aiC2uoJ/KP4k6znQSuJnlPMgPTivwjMnoS2TkhFQ0z9T+VyBmjCwSNsbTNAYzGAsZRzaeGAWgRvD6aJ85Q23iMfwO5g50UXK04Y1OVJmcae4NSigRRGmT3MymnE3MeTw0XykZjrT1JvhXzcZ98lxPGZ4ISP13F6hDzB8jzCqpw8gaQXZ51/Cclv5CfT2f4m" + }, + "custom.js.merge": { + "199e99bbd15c3c0415569425cb21e77c95e9042a": "eJxlj0FOxDAMRfdziq9ZwUjTHIAlYslquIAncdtA4lSxC8PtSdoREmIV6f/4+dmdDjjhbY6KMSZGeycWrmQcQAqCGlWLMmEpUQzXb1xY/Ex4zgFnRMNXTAlSWseovCTybbbUDl6XsJHa1FH3sYX8B03cqqlS4OPQ//2V8CQ7K5fPriEBNjPU17gYjCZE6UnmYbacfj/GsaUNslUIhbVzu5lwq/2qVjIohGixCCVkkjiyWrOFzqWaXw0sViPr0IRYGVQ7yq+55X2HdObg7meo45udt4XnKyk7Je0Z5SWxqyyB6/Cu/Uh3ODj3crNhN28ar/f1D49P/7rLXUd7+QPuPI9g" + }, + "config.rb.tpl.merge": { + "33f446bd02c3fd24eb27891582eff6a2e789796b": "eJxLLi2KT8ksUrBVcMvMSdUDMvMSc1M14uPdPH1c4+M1ufJLSwpKS+KLSypzUoGqrPJSi0tSU7gALskTcA\u003d\u003d" + }, + "all.scss.merge": { + "da39a3ee5e6b4b0d3255bfef95601890afd80709": "eJwDAAAAAAE\u003d" + } + }, + "targets": { + ".sencha/package/sencha.cfg": { + "source": "sencha.cfg.tpl.merge", + "version": "6d1982cce48163a98dc46012d1d0cdfa209fbda6", + "parameters": { + "pkgName": "Ext.ux.Deferred", + "senchadir": ".sencha", + "touchRelPath": "../../${touch.dir}", + "extRelPath": "../../ext", + "pkgType": "code" + } + }, + ".sencha/package/build.properties": { + "source": "build.properties.merge", + "version": "8b81315dbe73ce9c08478f4c1d2df84f456efcf5", + "parameters": { + "pkgName": "Ext.ux.Deferred", + "senchadir": ".sencha", + "touchRelPath": "../../${touch.dir}", + "extRelPath": "../../ext", + "pkgType": "code" + } + }, + ".sencha/package/testing.properties": { + "source": "testing.properties.merge", + "version": "e65f969c42eb4f355c850fc58fea852582f20db8", + "parameters": { + "pkgName": "Ext.ux.Deferred", + "senchadir": ".sencha", + "touchRelPath": "../../${touch.dir}", + "extRelPath": "../../ext", + "pkgType": "code" + } + }, + "package.json": { + "source": "package.json.tpl.merge", + "version": "12322b2f0769f491000df8ec0e012dd2d78a7eaf", + "parameters": { + "pkgName": "Ext.ux.Deferred", + "senchadir": ".sencha", + "touchRelPath": "../../${touch.dir}", + "extRelPath": "../../ext", + "pkgType": "code" + } + }, + "sass/example/theme.html": { + "source": "theme.html.tpl.merge", + "version": "32f685a8af28baafcc7999862d0bd1f25df0e48b", + "parameters": { + "pkgName": "Ext.ux.Deferred", + "senchadir": ".sencha", + "touchRelPath": "../../${touch.dir}", + "extRelPath": "../../ext", + "pkgType": "code" + } + }, + "sass/example/custom.js": { + "source": "custom.js.merge", + "version": "199e99bbd15c3c0415569425cb21e77c95e9042a", + "parameters": { + "pkgName": "Ext.ux.Deferred", + "senchadir": ".sencha", + "touchRelPath": "../../${touch.dir}", + "extRelPath": "../../ext", + "pkgType": "code" + } + }, + "sass/config.rb": { + "source": "config.rb.tpl.merge", + "version": "33f446bd02c3fd24eb27891582eff6a2e789796b", + "parameters": { + "pkgName": "Ext.ux.Deferred", + "senchadir": ".sencha", + "touchRelPath": "../../${touch.dir}", + "extRelPath": "../../ext", + "pkgType": "code" + } + }, + "sass/etc/all.scss": { + "source": "all.scss.merge", + "version": "da39a3ee5e6b4b0d3255bfef95601890afd80709", + "parameters": { + "pkgName": "Ext.ux.Deferred", + "senchadir": ".sencha", + "touchRelPath": "../../${touch.dir}", + "extRelPath": "../../ext", + "pkgType": "code" + } + } + } +} \ No newline at end of file diff --git a/.sencha/package/defaults.properties b/.sencha/package/defaults.properties new file mode 100644 index 0000000..dab58b1 --- /dev/null +++ b/.sencha/package/defaults.properties @@ -0,0 +1,155 @@ +# ============================================================================= +# This file defines properties used by build-impl.xml and the associated +# *-impl.xml files (sass-impl.xml, js-impl.xml, etc.), which are the core of +# the applications build process. +# +# IMPORTANT - This file is not modifiable by a package, and will be overwritten +# during each app upgrade. Please use build.properties for defining package +# customizations to these properties. +# ============================================================================= + +# =========================================== +# properties defining various directory +# locations +# =========================================== +build.dir=${package.build.dir} +build.resources.dir=${build.dir}/resources +package.resources.dir=${package.dir}/resources +package.sass.dir=${package.dir}/sass +package.licenses.dir=${package.dir}/licenses + +# =========================================== +# definitions of various file name patterns +# used for output artifacts +# =========================================== +build.name.prefix=${build.dir}/${package.name} +build.name.css.prefix=${build.resources.dir}/${package.name} +build.name.ruby=config.rb + +build.debug.suffix=-debug +build.all.suffix=-all +build.rtl.suffix=-rtl + +build.all.debug.suffix=${build.all.suffix}${build.debug.suffix} +build.all.rtl.suffix=${build.all.suffix}${build.rtl.suffix} +build.all.rtl.debug.suffix=${build.all.suffix}${build.rtl.suffix}${build.debug.suffix} + +# =========================================== +# define the output js file names for dev, +# debug, and compressed (no suffix) +# =========================================== +build.all.js=${build.name.prefix}.js +build.all.debug.js=${build.name.prefix}${build.debug.suffix}.js + +# =========================================== +# output file names for the scss files +# =========================================== +build.all.scss=${build.name.prefix}${build.all.debug.suffix}.scss +build.all.rtl.scss=${build.name.prefix}${build.all.rtl.debug.suffix}.scss + +# =========================================== +# output file names for the css files +# generated from the scss files by running +# a compass compilation +# =========================================== +build.all.css.debug.prefix=${package.name}${build.all.debug.suffix} +build.all.css.debug=${build.resources.dir}/${build.all.css.debug.prefix}.css +build.all.rtl.css.debug.prefix=${package.name}${build.all.rtl.debug.suffix} +build.all.rtl.css.debug=${build.resources.dir}/${build.all.rtl.css.debug.prefix}.css +build.all.css.prefix=${package.name}${build.all.suffix} +build.all.css=${build.resources.dir}/${build.all.css.prefix}.css +build.all.rtl.css.prefix=${package.name}${build.all.rtl.suffix} +build.all.rtl.css=${build.resources.dir}/${build.all.rtl.css.prefix}.css + +build.all.ruby=${build.dir}/${build.name.ruby} + +# =========================================== +# options to pass to the 'sencha fs slice' command +# =========================================== +build.slice.options= + +# =========================================== +# preprocessor options used when generating +# concatenated js output files +# =========================================== +build.compile.js.debug.options=debug:true +build.compile.js.options=debug:false + +# enables / disables removing text references from +# package js build files +build.remove.references=false + +# This property can be modified to change general build options +# such as excluding files from the set. The format expects newlines +# for each argument, for example: +# +# build.operations=\ +# exclude\n \ +# -namespace=Ext\n +# +# NOTE: modifications to build.operations are intended to be +# placed in an override of the "-after-init" target, where it +# can be calculated based on other +# ant properties +# +# build.operations= + +# =========================================== +# compression option used to generate '-all' +# js output file +# =========================================== +build.compile.js.compress=+yui + +# =========================================== +# selector count threshold to use when +# splitting a single css file into multiple +# css files (IE selector limit workaround) +# =========================================== +build.css.selector.limit=4095 + +# controls the ruby command used to execute compass. a full path +# to ruby may be specified rather than allowing the system shell +# to resolve the command +build.ruby.path=ruby + +# controls the working directory of the child compass process +# and the output location for the .sass-cache folder +compass.working.dir=${build.dir} + +# enables / disables console highlighting for compass +compass.compile.boring=false + +# enables / disables forced rebuilds for compass +compass.compile.force=true + +# enables / disables stack traces in compass failure output +compass.compile.trace=true + +# =========================================== +# Options for sub-packages + +# Set to true/1 to enable build.version inheritance by sub-pacakges +build.subpkgs.inherit.version=0 + +# =========================================== +# theme slicing example page settings +# =========================================== +package.example.dir=${package.dir}/sass/example +package.example.base=${build.all.rtl.css.debug.prefix} +package.example.css.rel=resources/${package.example.base}.css +package.example.css=${build.dir}/${package.example.css.rel} +package.example.scss=${build.dir}/${package.example.base}.scss +package.example.theme.html=${package.example.dir}/theme.html + +bootstrap.base.path=${package.example.dir} +bootstrap.example.js=${package.example.dir}/bootstrap.js + + +# =========================================== +# options controlling output packaging +# operations for output '.pkg' file +# =========================================== +pkg.build.dir=${workspace.build.dir}/${package.name} +pkg.file.name=${package.name}.pkg +pkg.includes=**/* +pkg.excludes=package.json diff --git a/.sencha/package/find-cmd-impl.xml b/.sencha/package/find-cmd-impl.xml new file mode 100644 index 0000000..55d6826 --- /dev/null +++ b/.sencha/package/find-cmd-impl.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + source ~/.bash_profile; sencha which -p cmd.dir -o '$cmddir$' + + + + + + \ No newline at end of file diff --git a/.sencha/package/init-impl.xml b/.sencha/package/init-impl.xml new file mode 100644 index 0000000..a561649 --- /dev/null +++ b/.sencha/package/init-impl.xml @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + Switch package version to ${build.version} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.sencha/package/js-impl.xml b/.sencha/package/js-impl.xml new file mode 100644 index 0000000..50e6992 --- /dev/null +++ b/.sencha/package/js-impl.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.sencha/package/plugin.xml b/.sencha/package/plugin.xml new file mode 100644 index 0000000..d57eba8 --- /dev/null +++ b/.sencha/package/plugin.xml @@ -0,0 +1,32 @@ + + + + + + diff --git a/.sencha/package/refresh-impl.xml b/.sencha/package/refresh-impl.xml new file mode 100644 index 0000000..91f01b0 --- /dev/null +++ b/.sencha/package/refresh-impl.xml @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/.sencha/package/resources-impl.xml b/.sencha/package/resources-impl.xml new file mode 100644 index 0000000..19e2d48 --- /dev/null +++ b/.sencha/package/resources-impl.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + Merging resources from base package ${base.path} + + + + + + + + + + + + + + + + Merging resources from current package ${package.resources.dir} + + + + + \ No newline at end of file diff --git a/.sencha/package/sass-impl.xml b/.sencha/package/sass-impl.xml new file mode 100644 index 0000000..d86e2d6 --- /dev/null +++ b/.sencha/package/sass-impl.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.sencha/package/sencha.cfg b/.sencha/package/sencha.cfg new file mode 100644 index 0000000..4f09bde --- /dev/null +++ b/.sencha/package/sencha.cfg @@ -0,0 +1,60 @@ +# The name of the package - should match the "name" property in ./package.json +# +package.name=Ext.ux.Deferred + +# The namespace to which this package's SASS corresponds. The default value of +# "Ext" means that the files in ./sass/src (and ./sass/var) match classes in +# the Ext" root namespace. In other words, "Ext.panel.Panel" maps to +# ./sass/src/panel/Panel.scss. +# +# To style classes from any namespace, set this to blank. If this is blank, +# then to style "Ext.panel.Panel" you would put SASS in +# ./sass/src/Ext/panel/Panel.scss. +# +package.sass.namespace=Ext + +# This is the comma-separated list of folders where classes reside. These +# classes must be explicitly required to be included in the build. +# +package.classpath=${package.dir}/src + +# This is the comma-separated list of folders of overrides. All files in this +# path will be given a tag of "packageOverrides" which is automatically +# required in generated apps by the presence of this line in app.js: +# +# //@require @packageOverrides +# +package.overrides=${package.dir}/overrides + +# This is the folder where SASS "src" resides. This is searched for SCSS +# files that match the JavaScript classes used by the application. +# +package.sass.srcpath=${package.dir}/sass/src + +# This is the folder where SASS "vars" resides. This is searched for SCSS +# files that match the JavaScript classes used by the application. +# +package.sass.varpath=${package.dir}/sass/var + +# This file is automatically imported into the SASS build before "vars". +# +package.sass.etcpath=${package.dir}/sass/etc/all.scss + +# This is the folder in which to place "sencha packaage build" output. +# +package.build.dir=${package.dir}/build + +# The folder that contains example application(s) for this package. +# +package.examples.dir=${package.dir}/examples + +# The folder that contains sub-packages of this package. Only valid for "framework" +# package type. +# +package.subpkgs.dir=${package.dir}/packages + +#============================================================================== +# Custom Properties - Place customizations below this line to avoid merge +# conflicts with newer versions + +package.cmd.version=5.0.0.160 diff --git a/.sencha/package/slice-impl.xml b/.sencha/package/slice-impl.xml new file mode 100644 index 0000000..931b7f1 --- /dev/null +++ b/.sencha/package/slice-impl.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + = 0) { + project.setProperty('override.tpl.type', 'jsonp'); + project.setProperty('override.tpl', 'Ext.Loader.loadScriptsSync'); + } + } catch (err) { + } + ]]> + + + + + + + + + + + + + + + + +/* + * This file is generated by Sencha Cmd and should NOT be edited. It redirects + * to the most recently built CSS file for the application to allow theme.html + * to load properly for image slicing (required to support non-CSS3 browsers + * such as IE9 and below). + */ +@import '${package.example.css.path}'; + + + + + + Capture theme image to ${build.dir}/theme-capture.png + + + + + + + Slicing theme images to ${build.resources.dir} + + + + + + + + + + \ No newline at end of file diff --git a/.sencha/package/sub-builds.xml b/.sencha/package/sub-builds.xml new file mode 100644 index 0000000..c1f0542 --- /dev/null +++ b/.sencha/package/sub-builds.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + package + upgrade + + + + + + + + + + Building example in @{example-dir} + + app + build + + + + + + + + + Upgrading example in @{example-dir} + + + app + upgrade + + + + + + + + + + Cleaning example in @{example-dir} + + + + + \ No newline at end of file diff --git a/.sencha/package/testing.properties b/.sencha/package/testing.properties new file mode 100644 index 0000000..60749a3 --- /dev/null +++ b/.sencha/package/testing.properties @@ -0,0 +1,17 @@ +# =========================================== +# This file defines properties used by +# build-impl.xml, which is the base impl +# of an applications build process. The +# properties from this file correspond to the +# 'testing' build environment, specified +# by 'sencha app build testing'. These will +# take precedence over defaults provided by +# build.properties. +# =========================================== + +# =========================================== +# compression option used to generate '-all' +# js output file. this value disables +# compression for testing builds +# =========================================== +build.compile.js.compress= From 84c2b2634a4b325daeec0827006fd479c45f8e56 Mon Sep 17 00:00:00 2001 From: "Vincenzo (Wilk) Ferrari" Date: Fri, 26 Sep 2014 15:37:21 +0200 Subject: [PATCH 06/13] added package building config --- build.xml | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 build.xml diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..682a241 --- /dev/null +++ b/build.xml @@ -0,0 +1,37 @@ + + + + + + + + From 8f3524f448f68c35a1e21bd9226fb4ca2dcfa844 Mon Sep 17 00:00:00 2001 From: "Vincenzo (Wilk) Ferrari" Date: Fri, 26 Sep 2014 15:37:32 +0200 Subject: [PATCH 07/13] added package json for sencha package --- package.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 0000000..29ecc50 --- /dev/null +++ b/package.json @@ -0,0 +1,12 @@ +{ + "name": "Ext.ux.Deferred", + "type": "code", + "creator": "Vincenzo Ferrari", + "summary": "Promises for ExtJS 4 and Sencha Touch", + "detailedDescription": "Ext.ux.Deferred provides promises for ExtJS and Sencha Touch. It allows to manage async functions with ease. Ext.ux.Deferred follows the PromisesA/+ standard", + "version": "1.0.1", + "compatVersion": "1.0.1", + "format": "1", + "local": true, + "requires": [] +} From 0e7372555f71e4ba51f787f99dc5c7bb5351e163 Mon Sep 17 00:00:00 2001 From: "Vincenzo (Wilk) Ferrari" Date: Fri, 26 Sep 2014 15:37:53 +0200 Subject: [PATCH 08/13] removed old sources --- Deferred.js | 106 ---------------------- Promise.js | 251 ---------------------------------------------------- 2 files changed, 357 deletions(-) delete mode 100644 Deferred.js delete mode 100644 Promise.js diff --git a/Deferred.js b/Deferred.js deleted file mode 100644 index cb23f3c..0000000 --- a/Deferred.js +++ /dev/null @@ -1,106 +0,0 @@ -/** - * @class Ext.ux.Deferred - * @author Vincenzo Ferrari - * - * Deferred for ExtJS and Sencha Touch - * - */ -Ext.define('Ext.ux.Deferred', { - requires: ['Ext.ux.Promise'], - - /** - * internal promise needed from resolve and reject methods - * @private - */ - internalPromise: null, - - inheritableStatics: { - /** - * @method when - * It encapsulates the given promises in a new one that is returned. - * When the new promise is executed, the listeners attached will be notified. - * @param {Function/Ext.ux.Promise/Function[]/Ext.ux.Promise[]} args One or more Ext.ux.Promise or one or more Function that return an Ext.ux.Promise - * The returned promise will be solved or rejected after each given promise have finished - * @return {Ext.ux.Promise} The promise - * @static - */ - when: function () { - var deferred = Ext.create('Ext.ux.Deferred'), - promises = arguments, - promisesLen = promises.length, - rejectedCounter = 0, - resolved = {}, - rejected = {}; - - // Make a single promise for those passed - for (var i = 0; i < promises.length; i++) { - // Use a closure to work with the current one specified by index 'i' - (function (i) { - var promise = promises[i]; - - // This let 'when' to accept functions that return a promise invoking them afterwards - if (typeof promise === 'function') promise = promise(); - - if (promise instanceof Ext.ux.Promise) { - promise.then(function () { - promisesLen--; - resolved[i] = arguments.length === 1 ? arguments[0] : arguments; - - // Execute the promise only if there's no other pending promise - if (promisesLen === 0) { - // If an error occurred or one of the promises has been rejected - // reject the wrapping promise, even if it's the only rejected - if (rejectedCounter > 0) deferred.reject(rejected); - else deferred.resolve(resolved); - } - }, function () { - promisesLen--; - rejectedCounter++; - rejected[i] = arguments.length === 1 ? arguments[0] : arguments; - - if (promisesLen === 0) { - deferred.reject(rejected); - } - }); - } - })(i); - } - - return deferred.promise(); - } - }, - - /** - * @method resolve - * Solve the promise and launch the callback attached with then (or success or done) method. - * The given data is passed to the ballback - * @param {Object} args Data to pass to the attached function - * @return {Ext.ux.Deferred} this - */ - resolve: function () { - return this.internalPromise.resolve.apply(this.internalPromise, arguments); - }, - - /** - * @method reject - * Reject the promise and launch the callback attached with then (or failure or fail) method. - * The given data is passed to the ballback - * @param {Object} args Data to pass to the attached function - * @return {Ext.ux.Deferred} this - */ - reject: function () { - return this.internalPromise.reject.apply(this.internalPromise, arguments); - }, - - /** - * @method promise - * Provides a new instance of Ext.ux.Promise - * @return {Ext.ux.Promise} The promise - */ - promise: function () { - var me = this; - - if (me.internalPromise instanceof Ext.ux.Promise) return me.internalPromise; - else return me.internalPromise = Ext.create('Ext.ux.Promise'); - } -}); diff --git a/Promise.js b/Promise.js deleted file mode 100644 index 045ffc1..0000000 --- a/Promise.js +++ /dev/null @@ -1,251 +0,0 @@ -/** - * @class Ext.ux.Promise - * @author Vincenzo Ferrari - * - * Promise for ExtJS and Sencha Touch - * - */ -Ext.define('Ext.ux.Promise', { - inheritableStatics: { - /** - * Pending state - * @type Number - * @static - */ - PENDING: 0, - - /** - * Fulfilled state - * @type Number - * @static - */ - FULFILLED: 1, - - /** - * Rejected state - * @type Number - * @static - */ - REJECTED: 2 - }, - - config: { - /** - * The promise state - * @property - */ - state: 0 - }, - - /** - * The internal deferred - * @private - */ - deferred: null, - - /** - * Internal success queue - * @private - */ - successQueue: [], - - /** - * Internal failure queue - * @private - */ - failureQueue: [], - - /** - * Creates a new promise - * @param {object} cfg The configuration options may be specified as follows: - * - * // with a configuration set - * var config = { - * deferred: deferred // deferred is an instace of Ext.ux.Deferred - * }; - * - * var promise = Ext.create('Ext.ux.Promise', config); - * - * @return {Ext.ux.Promise} An instance of Ext.ux.Promise or null if an error occurred. - */ - constructor: function (cfg) { - var me = this; - - me.initConfig(cfg); - - // Reset internal configurations - me.successQueue = []; - me.failureQueue = []; - me.deferred = null; - - return me; - }, - - /** - * @method - * Resolve the promise, called directly from the parent deferred - * @private - */ - resolve: function () { - var me = this, - results = [], - errors = [], - args = Array.prototype.slice.call(arguments, 0); - - me.setState(Ext.ux.Promise.FULFILLED); - - // Resolve it only if it needed - if (me.successQueue.length > 0) { - while (me.successQueue.length > 0) { - var onSuccess = me.successQueue.shift(); - - if (typeof onSuccess === 'function') { - try { - var result = onSuccess.apply(null, arguments); - if (result) results.push(result); - } - catch (err) { - errors.push(err); - } - } - } - - // If there's an error, reject the associated deferred - if (errors.length > 0) me.deferred.reject(errors); - else { - // Otherwise resolve it with every result - results = args.concat(results); - me.deferred.resolve(results); - } - } - }, - - /** - * @method - * Reject the promise, called directly from the parent deferred - * @private - */ - reject: function () { - var me = this, - results = [], - errors = [], - args = Array.prototype.slice.call(arguments, 0); - - me.setState(Ext.ux.Promise.REJECTED); - - if (me.failureQueue.length > 0) { - while (me.failureQueue.length > 0) { - var onFailure = me.failureQueue.shift(); - - if (typeof onFailure === 'function') { - try { - var result = onFailure.apply(null, arguments); - if (result) results.push(result); - } - catch (err) { - errors.push(err); - } - } - } - - if (errors.length > 0) me.deferred.reject(errors); - else { - results = args.concat(results); - me.deferred.reject(results); - } - } - }, - - /** - * @method then - * Attaches two callbacks to the deferred internal reference, one for success and one for failure. - * They are called by deferred.resolve and deferred.reject - * @param {Function} onSuccess Success callback, called by deferred.resolve - * @param {Function} onFailure Failure callback, called by deferred.reject - * @return {Ext.ux.Promise} this - */ - then: function (onSuccess, onFailure) { - var me = this; - - if (typeof onSuccess !== 'function' && typeof onFailure !== 'function') throw new Error('Ext.ux.Promise.then(): onSuccess or onFailure callback is needed'); - - if (!(me.deferred instanceof Ext.ux.Deferred)) me.deferred = Ext.create('Ext.ux.Deferred'); - - if (typeof onSuccess === 'function') me.successQueue.push(onSuccess); - if (typeof onFailure === 'function') me.failureQueue.push(onFailure); - - return me.deferred.promise(); - }, - - /** - * @method success - * Attaches the success callback to the promise - * @param {Function} onSuccess Callback successful promise - * @returns {Ext.ux.Promise} Return itself - */ - success: function (onSuccess) { - this.then(onSuccess); - - return this; - }, - - /** - * @method done - * Alias for success - * @param {Function} onSuccess Callback exectued after the promise is resolved - * @returns {Ext.ux.Promise} Return itself - */ - done: function (onSuccess) { - this.then(onSuccess); - - return this; - }, - - /** - * @method failure - * Attaches the failure callback to the promise - * @param {Function} onFailure Callback executed after the promise is rejected - * @returns {Ext.ux.Promise} Return itself - */ - failure: function (onFailure) { - this.then(undefined, onFailure); - - return this; - }, - - /** - * @method fail - * Alias for failure - * @param {Function} onFailure Callback executed after the promise is rejected - * @returns {Ext.ux.Promise} Return itself - */ - fail: function (onFailure) { - this.then(undefined, onFailure); - - return this; - }, - - /** - * Check if the promise is resolved or not - * @returns {boolean} true if the promise is resolved, false otherwise - */ - resolved: function () { - return this.getState() === Ext.ux.Promise.FULFILLED; - }, - - /** - * Check if the promise is rejected or not - * @returns {boolean} true if the promise is rejected, false otherwise - */ - rejected: function () { - return this.getState() === Ext.ux.Promise.REJECTED; - }, - - /** - * Check if the promise is pending or not - * @returns {boolean} true if the promise is pending, false otherwise - */ - pending: function () { - return this.getState() === Ext.ux.Promise.PENDING; - } -}); \ No newline at end of file From 21eec648ed3bbf918d3c079921836d4fafaca8b9 Mon Sep 17 00:00:00 2001 From: "Vincenzo (Wilk) Ferrari" Date: Fri, 26 Sep 2014 16:37:31 +0200 Subject: [PATCH 09/13] ignored useless file --- bower.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index d4223fe..3383720 100644 --- a/bower.json +++ b/bower.json @@ -16,8 +16,9 @@ ], "license": "MIT", "ignore": [ - "**/.*", - "package.json", + ".gitignore", + ".git", + ".idea", "node_modules", "bower_components", "bower.json", From bee5782720e6446197c91aaa2d2141f9be9794d4 Mon Sep 17 00:00:00 2001 From: "Vincenzo (Wilk) Ferrari" Date: Fri, 26 Sep 2014 16:39:16 +0200 Subject: [PATCH 10/13] moved main file to src --- bower.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index 3383720..f3be0ce 100644 --- a/bower.json +++ b/bower.json @@ -6,13 +6,16 @@ "Vincenzo (Wilk) Ferrari " ], "description": "Promises for ExtJS 4 and Sencha Touch", - "main": ["Deferred.js"], + "main": ["src/Deferred.js"], "keywords": [ + "sencha", "extjs", "senchatouch", "promise", "defer", - "async" + "async", + "ux", + "user extension" ], "license": "MIT", "ignore": [ From 77bdaaedcc35129601c2609e283a41d1d17e27cc Mon Sep 17 00:00:00 2001 From: "Vincenzo (Wilk) Ferrari" Date: Fri, 26 Sep 2014 16:41:43 +0200 Subject: [PATCH 11/13] fixed doc for the new folder structure --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b9b7944..f487fb9 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,7 @@ $ bower install ext.ux.deferred Now, you got the extension at the following path: *YOUR_PROJECT_PATH/bower_components/ext.ux.deferred/* -It contains **Deferred.js** file. +It contains the **src** folder that is the source folder, containing **Deferred.js** and **Promise.js** files. Let's setup the **Ext.Loader** to require the right file: @@ -141,8 +141,8 @@ Let's setup the **Ext.Loader** to require the right file: Ext.Loader.setConfig({ enabled: true , paths: { - 'Ext.ux.Deferred': 'bower_components/ext.ux.deferred/Deferred.js', - 'Ext.ux.Promise': 'bower_components/ext.ux.deffered/Promise.js' + 'Ext.ux.Deferred': 'bower_components/ext.ux.deferred/src/Deferred.js', + 'Ext.ux.Promise': 'bower_components/ext.ux.deffered/src/Promise.js' } }); From 93e5cc83896a1c13508252638c9efaa1fe597407 Mon Sep 17 00:00:00 2001 From: "Vincenzo (Wilk) Ferrari" Date: Fri, 26 Sep 2014 16:42:40 +0200 Subject: [PATCH 12/13] updated version to 1.0.1 --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index f3be0ce..40bf948 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "Ext.ux.Deferred", - "version": "0.0.6", + "version": "1.0.1", "homepage": "https://github.com/wilk/Ext.ux.Deferred", "authors": [ "Vincenzo (Wilk) Ferrari " From 65714c54b589c6aeccc141eecc894faffb935547 Mon Sep 17 00:00:00 2001 From: "Vincenzo (Wilk) Ferrari" Date: Fri, 26 Sep 2014 16:44:37 +0200 Subject: [PATCH 13/13] added sencha cmd package files and folder structure --- bower.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index 40bf948..0934152 100644 --- a/bower.json +++ b/bower.json @@ -1,12 +1,14 @@ { "name": "Ext.ux.Deferred", - "version": "1.0.1", + "version": "1.0.2", "homepage": "https://github.com/wilk/Ext.ux.Deferred", "authors": [ "Vincenzo (Wilk) Ferrari " ], "description": "Promises for ExtJS 4 and Sencha Touch", - "main": ["src/Deferred.js"], + "main": [ + "src/Deferred.js" + ], "keywords": [ "sencha", "extjs",