From 3f86fd756a146bab5386503dfb2ca11c46f30352 Mon Sep 17 00:00:00 2001 From: Jesse Hallett Date: Fri, 13 Dec 2013 14:08:16 -0800 Subject: Modifies fiveui.RuleSet.load to return promises --- src/js/chrome/js/platform-ajax.js | 17 +--- src/js/firefox/js/platform-ajax.js | 4 +- src/js/fiveui/js/rules.js | 158 +++++++++++++++++++------------------ src/js/fiveui/js/settings.js | 20 ++--- src/js/tests/specs/settings.js | 2 +- 5 files changed, 92 insertions(+), 109 deletions(-) diff --git a/src/js/chrome/js/platform-ajax.js b/src/js/chrome/js/platform-ajax.js index 32aac99..e5b4d1c 100644 --- a/src/js/chrome/js/platform-ajax.js +++ b/src/js/chrome/js/platform-ajax.js @@ -13,27 +13,12 @@ fiveui.ajax = fiveui.ajax || {}; */ fiveui.ajax.get = function(url, options) { - _.defaults(options, { - success:function() {}, - error: function() {} - }); - - jQuery.ajax(url, { + return jQuery.ajax(url, { cache: false, dataType: 'text', - success:function(text) { - // strip out everything else from the args - options.success(text); - }, - - error:function() { - // call with no context - options.error(); - }, - }); }; diff --git a/src/js/firefox/js/platform-ajax.js b/src/js/firefox/js/platform-ajax.js index e32225a..9b80633 100644 --- a/src/js/firefox/js/platform-ajax.js +++ b/src/js/firefox/js/platform-ajax.js @@ -5,4 +5,6 @@ var fiveui = fiveui || {}; fiveui.ajax = fiveui.ajax || {}; -fiveui.ajax.get = function () {}; +fiveui.ajax.get = function () { + return $.Deferred().promise(); +}; diff --git a/src/js/fiveui/js/rules.js b/src/js/fiveui/js/rules.js index 94d714f..16fb635 100644 --- a/src/js/fiveui/js/rules.js +++ b/src/js/fiveui/js/rules.js @@ -69,108 +69,87 @@ fiveui.RuleSet.fromJSON = function(id, obj) { /** - * Options is an object that can contain a success and error continuation. + * Returns a promise. */ fiveui.RuleSet.load = function(manifest_url, options) { - _.defaults(options, { - success: function() {}, - error: function() { throw "failed when loading url"; } - }); - var match = manifest_url.match(/\/[^\/]*$/); if(match) { var base_url = manifest_url.substring(0,match.index); - var loadDependencies = function(manifest, dependencies, rules) { - if (_.isEmpty(dependencies)) { - loadRules(manifest, rules); - } else { - // XXX there's likely problems here, how should we make sure that the - // url is what we expect? - var dep_file = dependencies.pop(); - var dep_url = base_url + '/' + dep_file; - - fiveui.ajax.get(dep_url, { - success: function(text) { - manifest.dependencies.push({'url': dep_url, 'content': text}); - loadDependencies(manifest, dependencies, rules); - }, - - error: options.error - }); + // fetch the manifest, and load its rules + return fiveui.ajax.get(manifest_url).then(function success(text) { + // cleanup the parsed JSON object + var sanitized = fiveui.utils.filterJSON(text,'json'); + var obj = null; + + try { + obj = JSON.parse(sanitized); + } catch(e) { + return failure('failed to parse manifest'); } - }; - - // iterate over rules, retrieving the - var loadRules = function(manifest, rules) { - if(rules.length == 0) { - options.success(manifest); - } else { + // set defaults in the parsed manifest + var manifest = fiveui.RuleSet.sanitize(obj); - // XXX there's likely problems here, how should we make sure that the - // url is what we expect? - var rule_file = rules.pop(); - var rule_url = base_url + '/' + rule_file; + return $.when( + loadDependencies(manifest.dependencies), + loadRules(manifest.rules) + ) + .then(function(dependencies, rules) { - fiveui.ajax.get(rule_url, { + return _.extend(manifest, { + // explicitly zero out the patterns, they shouldn't be part of the + // manifest. + patterns: [], - success: function(text) { - manifest.rules.push(text); - loadRules(manifest, rules); - }, + // overwrite any source present with the one given by the user. + source: manifest_url, - error: options.error + dependencies: dependencies, + rules: rules }); - } - }; + }); + }, - // fetch the manifest, and load its rules - fiveui.ajax.get(manifest_url, { - - success: function(text) { - // cleanup the parsed JSON object - var sanitized = fiveui.utils.filterJSON(text,'json'); - var obj = null; - - try { - obj = JSON.parse(sanitized); - } catch(e) { - options.error('failed to parse manifest'); - return; - } + function error() { + return failure('failed to retrieve manifest'); + }); - // set defaults in the parsed manifest - var manifest = fiveui.RuleSet.sanitize(obj); - // explicitly zero out the patterns, they shouldn't be part of the - // manifest. - manifest.patterns = []; + } else { + return failure("unable to parse manifest url"); + } - var dependencies = manifest.dependencies; - manifest.dependencies = []; + function loadDependencies(dependencyFiles) { + var deps = dependencyFiles.map(function(dep_file) { + // XXX there's likely problems here, how should we make sure that the + // url is what we expect? + var dep_url = base_url + '/' + dep_file; - // remove the rules, as they'll be added back once processed. - var rules = manifest.rules; - manifest.rules = []; + return fiveui.ajax.get(dep_url).then(function success(text) { + return {'url': dep_url, 'content': text}; + }); + }); - // overwrite any source present with the one given by the user. - manifest.source = manifest_url; + return whenAll(deps); + } - loadDependencies(manifest, dependencies, rules); - }, + function loadRules(ruleFiles) { + var rules = ruleFiles.map(function(rule_file) { + // XXX there's likely problems here, how should we make sure that the + // url is what we expect? + var rule_url = base_url + '/' + rule_file; - error: function() { - options.error('failed to retrieve manifest'); - }, + return fiveui.ajax.get(rule_url).then(function(text) { + // Ensure that resulting promise holds only a single value. + return text; + }); }); - - } else { - options.error("unable to parse manifest url"); + return whenAll(rules); } }; @@ -294,5 +273,32 @@ fiveui.RuleSets = Backbone.Collection.extend({ }); +/** + * Creates a resolved promise. + */ +function success(val) { + var deferred = $.Deferred(); + deferred.resolve(val); + return deferred.promise(); +} + +/** + * Creates a rejected promise. + */ +function failure(reason) { + var deferred = $.Deferred(); + deferred.reject(reason); + return deferred.promise(); +} + +/** + * Given an array of promises, returns a promise that will resolve to + * the array of resolved values of the input promises. + */ +function whenAll(promises) { + return $.when.apply($, promises).then(function() { + return Array.prototype.slice.call(arguments); + }); +} })(); diff --git a/src/js/fiveui/js/settings.js b/src/js/fiveui/js/settings.js index 6c0958e..1b5d4f8 100644 --- a/src/js/fiveui/js/settings.js +++ b/src/js/fiveui/js/settings.js @@ -43,11 +43,7 @@ _.extend(fiveui.Settings.prototype, { */ get: function(key) { var value = this.store.getItem(key); - if (value == null) { - return null; - } else { - return JSON.parse(value); - } + return value ? JSON.parse(value) : null; }, /** @@ -203,13 +199,11 @@ _.extend(fiveui.Settings.prototype, { return false; } - var pat = _.find(rs.patterns, function(pat) { + return _.some(rs.patterns, function(pat) { var regex = fiveui.utils.compilePattern(pat); return regex.test(url); }); - return pat != null; - }); }, @@ -228,7 +222,7 @@ fiveui.Settings.manager = function(chan, settings) { // create a new rule set, and call the response continuation with the created // object. msg.register('addRuleSet', function(ruleSet,respond){ - var id = settings.addRuleSet(ruleSet) + var id = settings.addRuleSet(ruleSet); respond(settings.getRuleSet(id)); }); @@ -249,12 +243,8 @@ fiveui.Settings.manager = function(chan, settings) { // Retrieve the manifest, and return the object to the caller. Invokes the // response continuation with an error object when rule set fails to load. msg.register('loadRuleSet', function(url, respond) { - fiveui.RuleSet.load(url, { - success:respond, - - error:function(msg) { - respond({ error : msg }); - }, + fiveui.RuleSet.load(url).then(respond, function error(msg) { + respond({ error : msg }); }); }); diff --git a/src/js/tests/specs/settings.js b/src/js/tests/specs/settings.js index 088b94d..19eb556 100644 --- a/src/js/tests/specs/settings.js +++ b/src/js/tests/specs/settings.js @@ -27,7 +27,7 @@ describe('fiveui.Settings', function() { expect(settings.get(key)).toEqual(value); }); - it('matches urls when there\s a valid pattern registered', function() { + it('matches urls when there\'s a valid pattern registered', function() { var rset = new fiveui.RuleSet({ patterns: ['http://.*'] }); settings.addRuleSet(rset); expect(settings.checkUrl('http://foo').id).toBe(0); -- cgit v1.2.3