[Pkg-mozext-commits] [ubiquity-extension] 02/08: Imported Upstream version 0.6.4~pre20140729
Gabriele Giacone
gg0-guest at moszumanska.debian.org
Wed Jul 30 00:24:15 UTC 2014
This is an automated email from the git hooks/post-receive script.
gg0-guest pushed a commit to branch master
in repository ubiquity-extension.
commit 6a359ee7962248b3754c1e6ab0cab5f17e9a6724
Author: Gabriele Giacone <1o5g4r8o at gmail.com>
Date: Tue Jul 29 16:54:36 2014 +0200
Imported Upstream version 0.6.4~pre20140729
---
chrome.manifest | 2 -
chrome/content/browser.js | 2 +-
chrome/content/console.js | 21 -
chrome/content/console.xul | 5 -
chrome/content/editor.js | 1 -
chrome/skin/skins/default.css | 1 +
chrome/skin/skins/experimental.css | 4 +-
install.rdf | 4 +-
modules/annotation_memory.js | 10 +-
modules/default_feed_plugin.js | 4 +-
modules/nountypes.js | 59 ---
modules/parser/original/parser.js | 5 +-
modules/sandboxfactory.js | 35 +-
modules/setup.js | 24 +-
modules/utils.js | 47 +-
modules/webjsm.js | 28 +-
scripts/jquery_setup.js | 2 +-
scripts/math_parser.js | 920 +++++++++++++++++++++++++++++++++++++
standard-feeds/developer.js | 2 +-
standard-feeds/general.js | 137 ++----
standard-feeds/search.xhtml | 230 ++--------
tests/test_all.js | 6 +-
22 files changed, 1039 insertions(+), 510 deletions(-)
diff --git a/chrome.manifest b/chrome.manifest
index c7f7baa..4060b6b 100644
--- a/chrome.manifest
+++ b/chrome.manifest
@@ -15,8 +15,6 @@ content ubiquity chrome/content/
skin ubiquity skin chrome/skin/
overlay chrome://browser/content/browser.xul chrome://ubiquity/content/browser.xul
-overlay chrome://global/content/console.xul chrome://ubiquity/content/console.xul
-overlay chrome://console2/content/console2.xul chrome://ubiquity/content/console.xul
style chrome://global/content/customizeToolbar.xul chrome://ubiquity/skin/browser.css
diff --git a/chrome/content/browser.js b/chrome/content/browser.js
index 64d63c6..9285f45 100755
--- a/chrome/content/browser.js
+++ b/chrome/content/browser.js
@@ -79,7 +79,7 @@ addEventListener("load", function ubiquityBoot() {
});
var suggFrame = document.getElementById("ubiquity-suggest");
- MutationObserver(function resizeSuggs(ms) {
+ new MutationObserver(function resizeSuggs(ms) {
var doc = suggFrame.contentDocument;
suggFrame.height = (doc.body || doc.documentElement).clientHeight;
}).observe(suggFrame.contentDocument.body, {childList: true});
diff --git a/chrome/content/console.js b/chrome/content/console.js
deleted file mode 100644
index 7fb0282..0000000
--- a/chrome/content/console.js
+++ /dev/null
@@ -1,21 +0,0 @@
-Components.utils.import("resource://ubiquity/modules/sandboxfactory.js");
-
-function maybeFixUpUbiquityMessage(target) {
- var href = target && target.getAttribute("href");
- if (href && href != (href = SandboxFactory.unmungeUrl(href)))
- target.setAttribute("href", href);
-}
-
-{
- let box = document.getElementById("ConsoleBox");
- box = box.mConsoleRowBox || /* Console2 */ box;
- setTimeout(function () {
- Array.forEach(box.children, maybeFixUpUbiquityMessage);
- });
- MutationObserver(function (ms) {
- for (let m of ms) if (m.type == 'childList') {
- Array.forEach(m.addedNodes, maybeFixUpUbiquityMessage);
- break;
- }
- }).observe(box, {childList: true});
-}
diff --git a/chrome/content/console.xul b/chrome/content/console.xul
deleted file mode 100644
index 58cc8eb..0000000
--- a/chrome/content/console.xul
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0"?>
-<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <script type="application/javascript;version=1.8"
- src="chrome://ubiquity/content/console.js"/>
-</overlay>
diff --git a/chrome/content/editor.js b/chrome/content/editor.js
index 6bff5eb..bafbe67 100644
--- a/chrome/content/editor.js
+++ b/chrome/content/editor.js
@@ -1,6 +1,5 @@
Cu.import("resource://ubiquity/modules/prefcommands.js");
Cu.import("resource://ubiquity/modules/localization_utils.js");
-Cu.import("resource:///modules/source-editor.jsm");
var L = LocalizationUtils.propertySelector(
"chrome://ubiquity/locale/aboutubiquity.properties");
diff --git a/chrome/skin/skins/default.css b/chrome/skin/skins/default.css
index c83f07d..b570bc3 100644
--- a/chrome/skin/skins/default.css
+++ b/chrome/skin/skins/default.css
@@ -78,6 +78,7 @@
#suggestions {
margin: 0;
+ overflow: hidden;
}
.hilited {
diff --git a/chrome/skin/skins/experimental.css b/chrome/skin/skins/experimental.css
index a1a6b36..2550d3c 100755
--- a/chrome/skin/skins/experimental.css
+++ b/chrome/skin/skins/experimental.css
@@ -47,6 +47,7 @@
font-size: 26px;
color: black;
width: 100%;
+ height: 32px;
font-family: Geneva, Tahoma, Verdana;
text-shadow: #AFAFAF 0px 1px .2px;
}
@@ -63,6 +64,7 @@
background-image: url(chrome://ubiquity/skin/icons/suggestion_bd.png);
background-position: top right;
background-repeat: repeat-y;
+ overflow: visible;
}
#ubiquity-suggest {
@@ -70,7 +72,6 @@
border: none;
width: 300px;
height: 500px;
- overflow: hidden;
}
#ubiquity-preview-container {
@@ -106,6 +107,7 @@
font-family: Geneva, Tahoma, Verdana;
text-shadow: #333 0px 1px .2px;
color: #fff;
+ overflow: hidden;
}
/* below are the only Parser 2 debug changes*/
diff --git a/install.rdf b/install.rdf
index 00be2ac..194c3ec 100755
--- a/install.rdf
+++ b/install.rdf
@@ -11,8 +11,8 @@
with minimum and maximum supported versions. -->
<targetApplication><rdf:Description>
<!--Firefox--><id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</id>
- <minVersion>20.0</minVersion>
- <maxVersion>23.0a1</maxVersion>
+ <minVersion>28.0</minVersion>
+ <maxVersion>31.0a1</maxVersion>
</rdf:Description></targetApplication>
<!-- Front End MetaData -->
diff --git a/modules/annotation_memory.js b/modules/annotation_memory.js
index 9369bec..ea80314 100644
--- a/modules/annotation_memory.js
+++ b/modules/annotation_memory.js
@@ -65,7 +65,10 @@ function NiceConnection(connection) {
if (connection.constructor === NiceConnection)
return connection;
- this.createStatement = function nice_createStatement(sql) {
+ var me = Object.create(connection);
+ me.constructor = NiceConnection;
+
+ me.createStatement = function nice_createStatement(sql) {
try {
return connection.createStatement(sql);
} catch (e if e.result === Components.results.NS_ERROR_FAILURE) {
@@ -75,7 +78,7 @@ function NiceConnection(connection) {
}
};
- this.executeSimpleSQL = function nice_executeSimpleSQL(sql) {
+ me.executeSimpleSQL = function nice_executeSimpleSQL(sql) {
try {
connection.executeSimpleSQL(sql);
} catch (e if e.result === Components.results.NS_ERROR_FAILURE) {
@@ -85,8 +88,7 @@ function NiceConnection(connection) {
}
};
- this.constructor = NiceConnection;
- this.__proto__ = connection;
+ return me;
}
// == The AnnotationService Class ==
diff --git a/modules/default_feed_plugin.js b/modules/default_feed_plugin.js
index d17e2d3..378c2f9 100644
--- a/modules/default_feed_plugin.js
+++ b/modules/default_feed_plugin.js
@@ -46,6 +46,7 @@ Cu.import("resource://ubiquity/modules/utils.js");
Cu.import("resource://ubiquity/modules/codesource.js");
Cu.import("resource://ubiquity/modules/sandboxfactory.js");
Cu.import("resource://ubiquity/modules/feed_plugin_utils.js");
+Cu.import("resource://gre/modules/devtools/Console.jsm");
const Global = this;
const CONFIRM_URL = "chrome://ubiquity/content/confirm-add-command.xhtml";
@@ -308,8 +309,6 @@ DFPFeed.prototype = {
};
function makeBuiltinGlobalsMaker(msgService, webJsm) {
- webJsm.importScript("resource://ubiquity/scripts/jquery.js");
- webJsm.importScript("resource://ubiquity/scripts/jquery_setup.js");
webJsm.importScript("resource://ubiquity/scripts/template.js");
webJsm.importScript("resource://ubiquity/scripts/date.js");
@@ -338,6 +337,7 @@ function makeBuiltinGlobalsMaker(msgService, webJsm) {
globals: globalObjects[id] || (globalObjects[id] = {}),
displayMessage: displayMessage,
Template: webJsm.TrimPath,
+ console: console,
};
for (let key of jsmExports) globals[key] = Global[key];
for (let key of webExports) globals[key] = webJsm[key];
diff --git a/modules/nountypes.js b/modules/nountypes.js
index 097048e..1749410 100644
--- a/modules/nountypes.js
+++ b/modules/nountypes.js
@@ -1139,65 +1139,6 @@ function NounAsync(label, checker) {
};
}
-// === {{{ noun_type_async_restaurant }}} ===
-// **//FIXME//**
-// * {{{text}}} :
-// * {{{html}}} :
-// * {{{data}}} :
-
-var noun_type_async_restaurant = NounAsync("restaurant", getRestaurants);
-
-function getRestaurants(query, callback, selectionIndices) {
- if (!query) return;
-
- var baseUrl = "http://api.yelp.com/business_review_search";
- var queryToMatch = query.toLowerCase().replace(/\s+/g, '');
- var loc = CmdUtils.getGeoLocation();
- var near = loc ? loc.city + "," + loc.state : "";
-
- return jQuery.ajax({
- url: baseUrl + Utils.paramsToString({
- term: query,
- num_biz_requested: 1,
- location: near,
- category: "restaurants",
- ywsid: "HbSZ2zXYuMnu1VTImlyA9A",
- }),
- dataType: "json",
- error: function () {
- callback([]);
- },
- success: function (data) {
- var allBusinesses = data.businesses.map(
- function (business) {
- return {name: business.name.toLowerCase().replace(/\s+/g, ''),
- categories: business.categories};
- });
- // if the business's name or category overlaps with the query
- // then consider it a restaurant match
- for (let business of allBusinesses) {
- if (business.name.indexOf(queryToMatch) !== -1 ||
- queryToMatch.indexOf(business.name) !== -1) {
- callback([CmdUtils.makeSugg(query, null, null, .9,
- selectionIndices)]);
- return;
- }
- else {
- for (let category of business.categories) {
- if (category.name.indexOf(queryToMatch) !== -1 ||
- queryToMatch.indexOf(category.name) !== -1) {
- callback([CmdUtils.makeSugg(query, null, null, .9,
- selectionIndices)]);
- return;
- }
- }
- }
- }
- callback([]);
- }
- });
-}
-
// === {{{ noun_type_geo_country }}} ===
// === {{{ noun_type_geo_region }}} ===
// === {{{ noun_type_geo_subregion }}} ===
diff --git a/modules/parser/original/parser.js b/modules/parser/original/parser.js
index 716e0c4..36ddbe8 100644
--- a/modules/parser/original/parser.js
+++ b/modules/parser/original/parser.js
@@ -462,8 +462,9 @@ ParsedSentence.prototype = {
ams += _argSuggs[name].score || 1;
this.argMatchScore = ams;
}
- return (this.verbMatchScore * this.duplicateDefaultMatchScore +
- this.argMatchScore * this.frequencyMatchScore / 99);
+ return (this.verbMatchScore + this.argMatchScore / 99)
+ * this.duplicateDefaultMatchScore
+ * this.frequencyMatchScore;
}
};
diff --git a/modules/sandboxfactory.js b/modules/sandboxfactory.js
index 6ff7ba3..67a78e5 100644
--- a/modules/sandboxfactory.js
+++ b/modules/sandboxfactory.js
@@ -43,39 +43,13 @@ Cu.import("resource://ubiquity/modules/utils.js");
var defaultTarget = this;
-function SandboxFactory(globals, target, ignoreForcedProtection) {
- maybeInitialize();
+function SandboxFactory(globals, target) {
globals = globals || {};
this._target = target || defaultTarget;
- this._ignoreForcedProtection = ignoreForcedProtection;
this._makeGlobals = typeof globals == "function" ?
globals : function defaultMakeGlobals(id) globals;
}
-SandboxFactory.protectedFileUriPrefix = "";
-SandboxFactory.fileUri = "";
-SandboxFactory.isInitialized = false;
-
-SandboxFactory.unmungeUrl = function unmungeUrl(url) {
- if (this.isInitialized && ~url.lastIndexOf(this.protectedFileUriPrefix, 0))
- return url.slice(this.protectedFileUriPrefix.length);
- return url;
-};
-
-function maybeInitialize() {
- if (SandboxFactory.isInitialized) return;
-
- SandboxFactory.fileUri =
- Utils.ResProtocolHandler.resolveURI(
- Utils.uri("resource://ubiquity/modules/sandboxfactory.js"));
- // We need to prefix any source code URI's with a known
- // "protected" file URI so that XPConnect wrappers are implicitly
- // made for them.
- SandboxFactory.protectedFileUriPrefix = SandboxFactory.fileUri + "#";
-
- SandboxFactory.isInitialized = true;
-}
-
Utils.extend(SandboxFactory.prototype, {
makeSandbox: function makeSandbox(codeSource) {
var sandbox = Cu.Sandbox(this._target);
@@ -88,13 +62,10 @@ Utils.extend(SandboxFactory.prototype, {
codeSections = codeSections ||
[{filename: "<string>", lineNumber: 0, length: code.length}];
var retVal, currIndex = 0;
- for each (let section in codeSections) {
+ for (let section of codeSections) {
let sourceCode = code.slice(currIndex, currIndex += section.length);
- let filename = section.filename;
- if (!this._ignoreForcedProtection)
- filename = SandboxFactory.protectedFileUriPrefix + filename;
retVal = Cu.evalInSandbox(sourceCode, sandbox,
- 1.8, filename, section.lineNumber);
+ 1.8, section.filename, section.lineNumber);
}
return retVal;
}
diff --git a/modules/setup.js b/modules/setup.js
index dcbf09b..6aa3dda 100755
--- a/modules/setup.js
+++ b/modules/setup.js
@@ -108,21 +108,37 @@ var UbiquitySetup = {
return !this.baseUrl.lastIndexOf(profileUrl, 0);
},
+ _preloadCBs: [],
+
preload: function preload(callback) {
if (gWebJsModule) {
callback();
return;
}
+ this._preloadCBs.push(callback);
+ if (this._preloaded) return;
+ this._preloaded = true;
+
this.__maybeReset();
+ var self = this, wjm;
+
Utils.AddonManager.getAddonByID(
"ubiquity at labs.mozilla.com",
function setAddonInfo(addon) {
- this.version = addon.version;
- this.baseUrl = addon.getResourceURI("").spec;
- gWebJsModule = new WebJsModule(callback);
- }.bind(this));
+ self.version = addon.version;
+ self.baseUrl = addon.getResourceURI("").spec;
+ wjm = new WebJsModule(onWJMLoad);
+ });
+
+ function onWJMLoad() {
+ wjm.importScript("resource://ubiquity/scripts/jquery.js", function () {
+ wjm.importScript("resource://ubiquity/scripts/jquery_setup.js");
+ gWebJsModule = wjm;
+ for (var cb; cb = self._preloadCBs.pop();) cb();
+ });
+ }
},
get isResetScheduled()
diff --git a/modules/utils.js b/modules/utils.js
index bdd0f2f..dcc66f1 100755
--- a/modules/utils.js
+++ b/modules/utils.js
@@ -171,53 +171,12 @@ delete Utils.QueryInterface;
}) = Services;
Cu.import("resource://gre/modules/AddonManager.jsm", Utils);
+Cu.import("resource://gre/modules/devtools/Console.jsm");
// === {{{ Utils.log(a, b, c, ...) }}} ===
-// One of the most useful functions to know both for development and debugging.
-// This logging function takes an arbitrary number of arguments and
-// will log them to the most appropriate output. If you have Firebug,
-// the output will go to its console.
-// Otherwise, the output will be routed to the Javascript Console.
-//
-// {{{Utils.log()}}} implements smart pretty print, so you
-// can use it for inspecting arrays and objects.
-// See http://getfirebug.com/console.html for details.
-//
-// {{{a, b, c, ...}}} is an arbitrary list of things to be logged.
-
-function log(what) {
- if (!arguments.length) return;
-
- var args = Array.slice(arguments), formatting = typeof what === "string";
-
- var {Firebug} = Utils.currentChromeWindow;
- if (Firebug && Firebug.Console.isEnabled() &&
- Firebug.toggleBar(true, "console")) {
- if (formatting) args[0] = LOG_PREFIX + what;
- else args.unshift(LOG_PREFIX);
- Firebug.Console.logFormatted(args);
- return;
- }
+// Left for compatibility.
- function log_pp(o) {
- try { var p = uneval(o) } catch ([]) {}
- return p && p !== "({})" && (p !== "null" || o === null) ? p : o;
- }
- var lead = !formatting ? log_pp(args.shift()) :
- args.shift().replace(/%[sdifo]/g, function log_format($) {
- if (!args.length) return $;
- var a = args.shift();
- switch ($) {
- case "%s": return a;
- case "%d":
- case "%i": return parseInt(a);
- case "%f": return parseFloat(a);
- }
- return log_pp(a);
- });
- Utils.reportInfo(
- args.reduce(function log_acc(msg, arg) msg + " " + log_pp(arg), lead));
-}
+Utils.log = console.log;
// === {{{ Utils.dump(a, b, c, ...) }}} ===
// A nicer {{{dump()}}} variant that
diff --git a/modules/webjsm.js b/modules/webjsm.js
index 9d6da0d..cf74f2c 100644
--- a/modules/webjsm.js
+++ b/modules/webjsm.js
@@ -62,29 +62,22 @@ const Ci = Components.interfaces;
// use to host any JS code. If unspecified, the hidden DOM window is
// used.
+Components.utils.import("resource://ubiquity/modules/utils.js");
+
function WebJsModule(callback, window) {
- if (!window)
- window = Cc["@mozilla.org/appshell/appShellService;1"]
- .getService(Ci.nsIAppShellService)
- .hiddenDOMWindow;
+ if (!window) window = Utils.hiddenWindow;
var importedScripts = {};
var self = this;
var iframe = window.document.createElement("iframe");
iframe.setAttribute("src", "chrome://ubiquity/content/hiddenframe.html");
- iframe.addEventListener(
- "pageshow",
- function WJM__onPageShow() {
- iframe.removeEventListener("pageshow", arguments.callee, false);
-
- // Have our instance dynamically inherit the properties of the
- // hidden window.
- self.__proto__ = iframe.contentWindow;
- callback();
- },
- false
- );
+ Utils.listenOnce(iframe, "pageshow", function WJM__onPageShow() {
+ // Have our instance dynamically inherit the properties of the
+ // hidden window.
+ self.__proto__ = iframe.contentWindow;
+ callback();
+ });
window.document.documentElement.appendChild(iframe);
// === {{{WebJsModule#importScript()}}} ===
@@ -96,10 +89,11 @@ function WebJsModule(callback, window) {
// Once the script is imported, any globals it created can be
// directly accessed as properties of the {{{WebJsModule}}} instance.
- this.importScript = function WJM_importScript(url) {
+ this.importScript = function WJM_importScript(url, callback) {
if (url in importedScripts) return;
var doc = iframe.contentDocument, script = doc.createElement('script');
script.setAttribute('src', url);
+ if (callback) Utils.listenOnce(script, 'load', callback);
doc.documentElement.appendChild(script);
doc.documentElement.removeChild(script);
importedScripts[url] = true;
diff --git a/scripts/jquery_setup.js b/scripts/jquery_setup.js
index 8a00f28..92c865f 100644
--- a/scripts/jquery_setup.js
+++ b/scripts/jquery_setup.js
@@ -10,7 +10,7 @@ jQuery.ajaxSetup({
// that needs to be brought up as a result of the XHR is shown
// to the user, rather than being invisible and locking up the
// application.
- return Utils.currentChromeWindow.XMLHttpRequest();
+ return new Utils.currentChromeWindow.XMLHttpRequest;
}
});
diff --git a/scripts/math_parser.js b/scripts/math_parser.js
new file mode 100644
index 0000000..8b4f604
--- /dev/null
+++ b/scripts/math_parser.js
@@ -0,0 +1,920 @@
+/*
+ Based on ndef.parser, by Raphael Graf(r at undefined.ch)
+ http://www.undefined.ch/mparser/index.html
+
+ Ported to JavaScript and modified by Matthew Crumley (email at matthewcrumley.com, http://silentmatt.com/)
+
+ You are free to use and modify this code in anyway you find useful. Please leave this comment in the code
+ to acknowledge its original source. If you feel like it, I enjoy hearing about projects that use my code,
+ but don't feel like you have to let me know or ask permission.
+*/
+
+// Added by stlsmiths 6/13/2011
+// re-define Array.indexOf, because IE doesn't know it ...
+//
+// from http://stellapower.net/content/javascript-support-and-arrayindexof-ie
+ if (!Array.indexOf) {
+ Array.prototype.indexOf = function (obj, start) {
+ for (var i = (start || 0); i < this.length; i++) {
+ if (this[i] === obj) {
+ return i;
+ }
+ }
+ return -1;
+ }
+ }
+
+var Parser = (function (scope) {
+ function object(o) {
+ function F() {}
+ F.prototype = o;
+ return new F();
+ }
+
+ var TNUMBER = 0;
+ var TOP1 = 1;
+ var TOP2 = 2;
+ var TVAR = 3;
+ var TFUNCALL = 4;
+
+ function Token(type_, index_, prio_, number_) {
+ this.type_ = type_;
+ this.index_ = index_ || 0;
+ this.prio_ = prio_ || 0;
+ this.number_ = (number_ !== undefined && number_ !== null) ? number_ : 0;
+ this.toString = function () {
+ switch (this.type_) {
+ case TNUMBER:
+ return this.number_;
+ case TOP1:
+ case TOP2:
+ case TVAR:
+ return this.index_;
+ case TFUNCALL:
+ return "CALL";
+ default:
+ return "Invalid Token";
+ }
+ };
+ }
+
+ function Expression(tokens, ops1, ops2, functions) {
+ this.tokens = tokens;
+ this.ops1 = ops1;
+ this.ops2 = ops2;
+ this.functions = functions;
+ }
+
+ // Based on http://www.json.org/json2.js
+ var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ escapable = /[\\\'\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ meta = { // table of character substitutions
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ "'" : "\\'",
+ '\\': '\\\\'
+ };
+
+ function escapeValue(v) {
+ if (typeof v === "string") {
+ escapable.lastIndex = 0;
+ return escapable.test(v) ?
+ "'" + v.replace(escapable, function (a) {
+ var c = meta[a];
+ return typeof c === 'string' ? c :
+ '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ }) + "'" :
+ "'" + v + "'";
+ }
+ return v;
+ }
+
+ Expression.prototype = {
+ simplify: function (values) {
+ values = values || {};
+ var nstack = [];
+ var newexpression = [];
+ var n1;
+ var n2;
+ var f;
+ var L = this.tokens.length;
+ var item;
+ var i = 0;
+ for (i = 0; i < L; i++) {
+ item = this.tokens[i];
+ var type_ = item.type_;
+ if (type_ === TNUMBER) {
+ nstack.push(item);
+ }
+ else if (type_ === TVAR && (item.index_ in values)) {
+ item = new Token(TNUMBER, 0, 0, values[item.index_]);
+ nstack.push(item);
+ }
+ else if (type_ === TOP2 && nstack.length > 1) {
+ n2 = nstack.pop();
+ n1 = nstack.pop();
+ f = this.ops2[item.index_];
+ item = new Token(TNUMBER, 0, 0, f(n1.number_, n2.number_));
+ nstack.push(item);
+ }
+ else if (type_ === TOP1 && nstack.length > 0) {
+ n1 = nstack.pop();
+ f = this.ops1[item.index_];
+ item = new Token(TNUMBER, 0, 0, f(n1.number_));
+ nstack.push(item);
+ }
+ else {
+ while (nstack.length > 0) {
+ newexpression.push(nstack.shift());
+ }
+ newexpression.push(item);
+ }
+ }
+ while (nstack.length > 0) {
+ newexpression.push(nstack.shift());
+ }
+
+ return new Expression(newexpression, object(this.ops1), object(this.ops2), object(this.functions));
+ },
+
+ substitute: function (variable, expr) {
+ if (!(expr instanceof Expression)) {
+ expr = new Parser().parse(String(expr));
+ }
+ var newexpression = [];
+ var L = this.tokens.length;
+ var item;
+ var i = 0;
+ for (i = 0; i < L; i++) {
+ item = this.tokens[i];
+ var type_ = item.type_;
+ if (type_ === TVAR && item.index_ === variable) {
+ for (var j = 0; j < expr.tokens.length; j++) {
+ var expritem = expr.tokens[j];
+ var replitem = new Token(expritem.type_, expritem.index_, expritem.prio_, expritem.number_);
+ newexpression.push(replitem);
+ }
+ }
+ else {
+ newexpression.push(item);
+ }
+ }
+
+ var ret = new Expression(newexpression, object(this.ops1), object(this.ops2), object(this.functions));
+ return ret;
+ },
+
+ evaluate: function (values) {
+ values = values || {};
+ var nstack = [];
+ var n1;
+ var n2;
+ var f;
+ var L = this.tokens.length;
+ var item;
+ var i = 0;
+ for (i = 0; i < L; i++) {
+ item = this.tokens[i];
+ var type_ = item.type_;
+ if (type_ === TNUMBER) {
+ nstack.push(item.number_);
+ }
+ else if (type_ === TOP2) {
+ n2 = nstack.pop();
+ n1 = nstack.pop();
+ f = this.ops2[item.index_];
+ nstack.push(f(n1, n2));
+ }
+ else if (type_ === TVAR) {
+ if (item.index_ in values) {
+ nstack.push(values[item.index_]);
+ }
+ else if (item.index_ in this.functions) {
+ nstack.push(this.functions[item.index_]);
+ }
+ else {
+ throw new Error("undefined variable: " + item.index_);
+ }
+ }
+ else if (type_ === TOP1) {
+ n1 = nstack.pop();
+ f = this.ops1[item.index_];
+ nstack.push(f(n1));
+ }
+ else if (type_ === TFUNCALL) {
+ n1 = nstack.pop();
+ f = nstack.pop();
+ if (f.apply && f.call) {
+ if (Object.prototype.toString.call(n1) == "[object Array]") {
+ nstack.push(f.apply(undefined, n1));
+ }
+ else {
+ nstack.push(f.call(undefined, n1));
+ }
+ }
+ else {
+ throw new Error(f + " is not a function");
+ }
+ }
+ else {
+ throw new Error("invalid Expression");
+ }
+ }
+ if (nstack.length > 1) {
+ throw new Error("invalid Expression (parity)");
+ }
+ return nstack[0];
+ },
+
+ toString: function (toJS) {
+ var nstack = [];
+ var n1;
+ var n2;
+ var f;
+ var L = this.tokens.length;
+ var item;
+ var i = 0;
+ for (i = 0; i < L; i++) {
+ item = this.tokens[i];
+ var type_ = item.type_;
+ if (type_ === TNUMBER) {
+ nstack.push(escapeValue(item.number_));
+ }
+ else if (type_ === TOP2) {
+ n2 = nstack.pop();
+ n1 = nstack.pop();
+ f = item.index_;
+ if (toJS && f == "^") {
+ nstack.push("Math.pow(" + n1 + "," + n2 + ")");
+ }
+ else {
+ nstack.push("(" + n1 + f + n2 + ")");
+ }
+ }
+ else if (type_ === TVAR) {
+ nstack.push(item.index_);
+ }
+ else if (type_ === TOP1) {
+ n1 = nstack.pop();
+ f = item.index_;
+ if (f === "-") {
+ nstack.push("(" + f + n1 + ")");
+ }
+ else {
+ nstack.push(f + "(" + n1 + ")");
+ }
+ }
+ else if (type_ === TFUNCALL) {
+ n1 = nstack.pop();
+ f = nstack.pop();
+ nstack.push(f + "(" + n1 + ")");
+ }
+ else {
+ throw new Error("invalid Expression");
+ }
+ }
+ if (nstack.length > 1) {
+ throw new Error("invalid Expression (parity)");
+ }
+ return nstack[0];
+ },
+
+ variables: function () {
+ var L = this.tokens.length;
+ var vars = [];
+ for (var i = 0; i < L; i++) {
+ var item = this.tokens[i];
+ if (item.type_ === TVAR && (vars.indexOf(item.index_) == -1)) {
+ vars.push(item.index_);
+ }
+ }
+
+ return vars;
+ },
+
+ toJSFunction: function (param, variables) {
+ var f = new Function(param, "with(Parser.values) { return " + this.simplify(variables).toString(true) + "; }");
+ return f;
+ }
+ };
+
+ function add(a, b) {
+ return Number(a) + Number(b);
+ }
+ function sub(a, b) {
+ return a - b;
+ }
+ function mul(a, b) {
+ return a * b;
+ }
+ function div(a, b) {
+ return a / b;
+ }
+ function mod(a, b) {
+ return a % b;
+ }
+ function concat(a, b) {
+ return "" + a + b;
+ }
+
+ function neg(a) {
+ return -a;
+ }
+
+ function random(a) {
+ return Math.random() * (a || 1);
+ }
+ function fac(a) { //a!
+ a = Math.floor(a);
+ var b = a;
+ while (a > 1) {
+ b = b * (--a);
+ }
+ return b;
+ }
+
+ // TODO: use hypot that doesn't overflow
+ function pyt(a, b) {
+ return Math.sqrt(a * a + b * b);
+ }
+
+ function append(a, b) {
+ if (Object.prototype.toString.call(a) != "[object Array]") {
+ return [a, b];
+ }
+ a = a.slice();
+ a.push(b);
+ return a;
+ }
+
+ function Parser() {
+ this.success = false;
+ this.errormsg = "";
+ this.expression = "";
+
+ this.pos = 0;
+
+ this.tokennumber = 0;
+ this.tokenprio = 0;
+ this.tokenindex = 0;
+ this.tmpprio = 0;
+
+ this.ops1 = {
+ "sin": Math.sin,
+ "cos": Math.cos,
+ "tan": Math.tan,
+ "asin": Math.asin,
+ "acos": Math.acos,
+ "atan": Math.atan,
+ "sqrt": Math.sqrt,
+ "log": Math.log,
+ "abs": Math.abs,
+ "ceil": Math.ceil,
+ "floor": Math.floor,
+ "round": Math.round,
+ "-": neg,
+ "exp": Math.exp
+ };
+
+ this.ops2 = {
+ "+": add,
+ "-": sub,
+ "*": mul,
+ "/": div,
+ "%": mod,
+ "^": Math.pow,
+ ",": append,
+ "||": concat
+ };
+
+ this.functions = {
+ "random": random,
+ "fac": fac,
+ "min": Math.min,
+ "max": Math.max,
+ "pyt": pyt,
+ "pow": Math.pow,
+ "atan2": Math.atan2
+ };
+
+ this.consts = {
+ "E": Math.E,
+ "PI": Math.PI
+ };
+ }
+
+ Parser.parse = function (expr) {
+ return new Parser().parse(expr);
+ };
+
+ Parser.evaluate = function (expr, variables) {
+ return Parser.parse(expr).evaluate(variables);
+ };
+
+ Parser.Expression = Expression;
+
+ Parser.values = {
+ sin: Math.sin,
+ cos: Math.cos,
+ tan: Math.tan,
+ asin: Math.asin,
+ acos: Math.acos,
+ atan: Math.atan,
+ sqrt: Math.sqrt,
+ log: Math.log,
+ abs: Math.abs,
+ ceil: Math.ceil,
+ floor: Math.floor,
+ round: Math.round,
+ random: random,
+ fac: fac,
+ exp: Math.exp,
+ min: Math.min,
+ max: Math.max,
+ pyt: pyt,
+ pow: Math.pow,
+ atan2: Math.atan2,
+ E: Math.E,
+ PI: Math.PI
+ };
+
+ var PRIMARY = 1 << 0;
+ var OPERATOR = 1 << 1;
+ var FUNCTION = 1 << 2;
+ var LPAREN = 1 << 3;
+ var RPAREN = 1 << 4;
+ var COMMA = 1 << 5;
+ var SIGN = 1 << 6;
+ var CALL = 1 << 7;
+ var NULLARY_CALL = 1 << 8;
+
+ Parser.prototype = {
+ parse: function (expr) {
+ this.errormsg = "";
+ this.success = true;
+ var operstack = [];
+ var tokenstack = [];
+ this.tmpprio = 0;
+ var expected = (PRIMARY | LPAREN | FUNCTION | SIGN);
+ var noperators = 0;
+ this.expression = expr;
+ this.pos = 0;
+
+ while (this.pos < this.expression.length) {
+ if (this.isOperator()) {
+ if (this.isSign() && (expected & SIGN)) {
+ if (this.isNegativeSign()) {
+ this.tokenprio = 2;
+ this.tokenindex = "-";
+ noperators++;
+ this.addfunc(tokenstack, operstack, TOP1);
+ }
+ expected = (PRIMARY | LPAREN | FUNCTION | SIGN);
+ }
+ else if (this.isComment()) {
+
+ }
+ else {
+ if ((expected & OPERATOR) === 0) {
+ this.error_parsing(this.pos, "unexpected operator");
+ }
+ noperators += 2;
+ this.addfunc(tokenstack, operstack, TOP2);
+ expected = (PRIMARY | LPAREN | FUNCTION | SIGN);
+ }
+ }
+ else if (this.isNumber()) {
+ if ((expected & PRIMARY) === 0) {
+ this.error_parsing(this.pos, "unexpected number");
+ }
+ var token = new Token(TNUMBER, 0, 0, this.tokennumber);
+ tokenstack.push(token);
+
+ expected = (OPERATOR | RPAREN | COMMA);
+ }
+ else if (this.isString()) {
+ if ((expected & PRIMARY) === 0) {
+ this.error_parsing(this.pos, "unexpected string");
+ }
+ var token = new Token(TNUMBER, 0, 0, this.tokennumber);
+ tokenstack.push(token);
+
+ expected = (OPERATOR | RPAREN | COMMA);
+ }
+ else if (this.isLeftParenth()) {
+ if ((expected & LPAREN) === 0) {
+ this.error_parsing(this.pos, "unexpected \"(\"");
+ }
+
+ if (expected & CALL) {
+ noperators += 2;
+ this.tokenprio = -2;
+ this.tokenindex = -1;
+ this.addfunc(tokenstack, operstack, TFUNCALL);
+ }
+
+ expected = (PRIMARY | LPAREN | FUNCTION | SIGN | NULLARY_CALL);
+ }
+ else if (this.isRightParenth()) {
+ if (expected & NULLARY_CALL) {
+ var token = new Token(TNUMBER, 0, 0, []);
+ tokenstack.push(token);
+ }
+ else if ((expected & RPAREN) === 0) {
+ this.error_parsing(this.pos, "unexpected \")\"");
+ }
+
+ expected = (OPERATOR | RPAREN | COMMA | LPAREN | CALL);
+ }
+ else if (this.isComma()) {
+ if ((expected & COMMA) === 0) {
+ this.error_parsing(this.pos, "unexpected \",\"");
+ }
+ this.addfunc(tokenstack, operstack, TOP2);
+ noperators += 2;
+ expected = (PRIMARY | LPAREN | FUNCTION | SIGN);
+ }
+ else if (this.isConst()) {
+ if ((expected & PRIMARY) === 0) {
+ this.error_parsing(this.pos, "unexpected constant");
+ }
+ var consttoken = new Token(TNUMBER, 0, 0, this.tokennumber);
+ tokenstack.push(consttoken);
+ expected = (OPERATOR | RPAREN | COMMA);
+ }
+ else if (this.isOp2()) {
+ if ((expected & FUNCTION) === 0) {
+ this.error_parsing(this.pos, "unexpected function");
+ }
+ this.addfunc(tokenstack, operstack, TOP2);
+ noperators += 2;
+ expected = (LPAREN);
+ }
+ else if (this.isOp1()) {
+ if ((expected & FUNCTION) === 0) {
+ this.error_parsing(this.pos, "unexpected function");
+ }
+ this.addfunc(tokenstack, operstack, TOP1);
+ noperators++;
+ expected = (LPAREN);
+ }
+ else if (this.isVar()) {
+ if ((expected & PRIMARY) === 0) {
+ this.error_parsing(this.pos, "unexpected variable");
+ }
+ var vartoken = new Token(TVAR, this.tokenindex, 0, 0);
+ tokenstack.push(vartoken);
+
+ expected = (OPERATOR | RPAREN | COMMA | LPAREN | CALL);
+ }
+ else if (this.isWhite()) {
+ }
+ else {
+ if (this.errormsg === "") {
+ this.error_parsing(this.pos, "unknown character");
+ }
+ else {
+ this.error_parsing(this.pos, this.errormsg);
+ }
+ }
+ }
+ if (this.tmpprio < 0 || this.tmpprio >= 10) {
+ this.error_parsing(this.pos, "unmatched \"()\"");
+ }
+ while (operstack.length > 0) {
+ var tmp = operstack.pop();
+ tokenstack.push(tmp);
+ }
+ if (noperators + 1 !== tokenstack.length) {
+ //print(noperators + 1);
+ //print(tokenstack);
+ this.error_parsing(this.pos, "parity");
+ }
+
+ return new Expression(tokenstack, object(this.ops1), object(this.ops2), object(this.functions));
+ },
+
+ evaluate: function (expr, variables) {
+ return this.parse(expr).evaluate(variables);
+ },
+
+ error_parsing: function (column, msg) {
+ this.success = false;
+ this.errormsg = "parse error [column " + (column) + "]: " + msg;
+ throw new Error(this.errormsg);
+ },
+
+//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
+
+ addfunc: function (tokenstack, operstack, type_) {
+ var operator = new Token(type_, this.tokenindex, this.tokenprio + this.tmpprio, 0);
+ while (operstack.length > 0) {
+ if (operator.prio_ <= operstack[operstack.length - 1].prio_) {
+ tokenstack.push(operstack.pop());
+ }
+ else {
+ break;
+ }
+ }
+ operstack.push(operator);
+ },
+
+ isNumber: function () {
+ var r = false;
+ var str = "";
+ while (this.pos < this.expression.length) {
+ var code = this.expression.charCodeAt(this.pos);
+ if ((code >= 48 && code <= 57) || code === 46) {
+ str += this.expression.charAt(this.pos);
+ this.pos++;
+ this.tokennumber = parseFloat(str);
+ r = true;
+ }
+ else {
+ break;
+ }
+ }
+ return r;
+ },
+
+ // Ported from the yajjl JSON parser at http://code.google.com/p/yajjl/
+ unescape: function(v, pos) {
+ var buffer = [];
+ var escaping = false;
+
+ for (var i = 0; i < v.length; i++) {
+ var c = v.charAt(i);
+
+ if (escaping) {
+ switch (c) {
+ case "'":
+ buffer.push("'");
+ break;
+ case '\\':
+ buffer.push('\\');
+ break;
+ case '/':
+ buffer.push('/');
+ break;
+ case 'b':
+ buffer.push('\b');
+ break;
+ case 'f':
+ buffer.push('\f');
+ break;
+ case 'n':
+ buffer.push('\n');
+ break;
+ case 'r':
+ buffer.push('\r');
+ break;
+ case 't':
+ buffer.push('\t');
+ break;
+ case 'u':
+ // interpret the following 4 characters as the hex of the unicode code point
+ var codePoint = parseInt(v.substring(i + 1, i + 5), 16);
+ buffer.push(String.fromCharCode(codePoint));
+ i += 4;
+ break;
+ default:
+ throw this.error_parsing(pos + i, "Illegal escape sequence: '\\" + c + "'");
+ }
+ escaping = false;
+ } else {
+ if (c == '\\') {
+ escaping = true;
+ } else {
+ buffer.push(c);
+ }
+ }
+ }
+
+ return buffer.join('');
+ },
+
+ isString: function () {
+ var r = false;
+ var str = "";
+ var startpos = this.pos;
+ if (this.pos < this.expression.length && this.expression.charAt(this.pos) == "'") {
+ this.pos++;
+ while (this.pos < this.expression.length) {
+ var code = this.expression.charAt(this.pos);
+ if (code != "'" || str.slice(-1) == "\\") {
+ str += this.expression.charAt(this.pos);
+ this.pos++;
+ }
+ else {
+ this.pos++;
+ this.tokennumber = this.unescape(str, startpos);
+ r = true;
+ break;
+ }
+ }
+ }
+ return r;
+ },
+
+ isConst: function () {
+ var str;
+ for (var i in this.consts) {
+ if (true) {
+ var L = i.length;
+ str = this.expression.substr(this.pos, L);
+ if (i === str) {
+ this.tokennumber = this.consts[i];
+ this.pos += L;
+ return true;
+ }
+ }
+ }
+ return false;
+ },
+
+ isOperator: function () {
+ var code = this.expression.charCodeAt(this.pos);
+ if (code === 43) { // +
+ this.tokenprio = 0;
+ this.tokenindex = "+";
+ }
+ else if (code === 45) { // -
+ this.tokenprio = 0;
+ this.tokenindex = "-";
+ }
+ else if (code === 124) { // |
+ if (this.expression.charCodeAt(this.pos + 1) === 124) {
+ this.pos++;
+ this.tokenprio = 0;
+ this.tokenindex = "||";
+ }
+ else {
+ return false;
+ }
+ }
+ else if (code === 42) { // *
+ this.tokenprio = 1;
+ this.tokenindex = "*";
+ }
+ else if (code === 47) { // /
+ this.tokenprio = 2;
+ this.tokenindex = "/";
+ }
+ else if (code === 37) { // %
+ this.tokenprio = 2;
+ this.tokenindex = "%";
+ }
+ else if (code === 94) { // ^
+ this.tokenprio = 3;
+ this.tokenindex = "^";
+ }
+ else {
+ return false;
+ }
+ this.pos++;
+ return true;
+ },
+
+ isSign: function () {
+ var code = this.expression.charCodeAt(this.pos - 1);
+ if (code === 45 || code === 43) { // -
+ return true;
+ }
+ return false;
+ },
+
+ isPositiveSign: function () {
+ var code = this.expression.charCodeAt(this.pos - 1);
+ if (code === 43) { // -
+ return true;
+ }
+ return false;
+ },
+
+ isNegativeSign: function () {
+ var code = this.expression.charCodeAt(this.pos - 1);
+ if (code === 45) { // -
+ return true;
+ }
+ return false;
+ },
+
+ isLeftParenth: function () {
+ var code = this.expression.charCodeAt(this.pos);
+ if (code === 40) { // (
+ this.pos++;
+ this.tmpprio += 10;
+ return true;
+ }
+ return false;
+ },
+
+ isRightParenth: function () {
+ var code = this.expression.charCodeAt(this.pos);
+ if (code === 41) { // )
+ this.pos++;
+ this.tmpprio -= 10;
+ return true;
+ }
+ return false;
+ },
+
+ isComma: function () {
+ var code = this.expression.charCodeAt(this.pos);
+ if (code === 44) { // ,
+ this.pos++;
+ this.tokenprio = -1;
+ this.tokenindex = ",";
+ return true;
+ }
+ return false;
+ },
+
+ isWhite: function () {
+ var code = this.expression.charCodeAt(this.pos);
+ if (code === 32 || code === 9 || code === 10 || code === 13) {
+ this.pos++;
+ return true;
+ }
+ return false;
+ },
+
+ isOp1: function () {
+ var str = "";
+ for (var i = this.pos; i < this.expression.length; i++) {
+ var c = this.expression.charAt(i);
+ if (c.toUpperCase() === c.toLowerCase()) {
+ if (i === this.pos || (c != '_' && (c < '0' || c > '9'))) {
+ break;
+ }
+ }
+ str += c;
+ }
+ if (str.length > 0 && (str in this.ops1)) {
+ this.tokenindex = str;
+ this.tokenprio = 5;
+ this.pos += str.length;
+ return true;
+ }
+ return false;
+ },
+
+ isOp2: function () {
+ var str = "";
+ for (var i = this.pos; i < this.expression.length; i++) {
+ var c = this.expression.charAt(i);
+ if (c.toUpperCase() === c.toLowerCase()) {
+ if (i === this.pos || (c != '_' && (c < '0' || c > '9'))) {
+ break;
+ }
+ }
+ str += c;
+ }
+ if (str.length > 0 && (str in this.ops2)) {
+ this.tokenindex = str;
+ this.tokenprio = 5;
+ this.pos += str.length;
+ return true;
+ }
+ return false;
+ },
+
+ isVar: function () {
+ var str = "";
+ for (var i = this.pos; i < this.expression.length; i++) {
+ var c = this.expression.charAt(i);
+ if (c.toUpperCase() === c.toLowerCase()) {
+ if (i === this.pos || (c != '_' && (c < '0' || c > '9'))) {
+ break;
+ }
+ }
+ str += c;
+ }
+ if (str.length > 0) {
+ this.tokenindex = str;
+ this.tokenprio = 4;
+ this.pos += str.length;
+ return true;
+ }
+ return false;
+ },
+
+ isComment: function () {
+ var code = this.expression.charCodeAt(this.pos - 1);
+ if (code === 47 && this.expression.charCodeAt(this.pos) === 42) {
+ this.pos = this.expression.indexOf("*/", this.pos) + 2;
+ if (this.pos === 1) {
+ this.pos = this.expression.length;
+ }
+ return true;
+ }
+ return false;
+ }
+ };
+
+ scope.Parser = Parser;
+ return Parser
+})(typeof exports === 'undefined' ? {} : exports);
diff --git a/standard-feeds/developer.js b/standard-feeds/developer.js
index bda85e6..d28e569 100644
--- a/standard-feeds/developer.js
+++ b/standard-feeds/developer.js
@@ -2,7 +2,7 @@
// DEVELOPER COMMANDS
// -----------------------------------------------------------------
-var {slice} = Array, gXS = XMLSerializer(), H = Utils.escapeHtml;
+var {slice} = Array, gXS = new XMLSerializer(), H = Utils.escapeHtml;
function qsaa(lm, sl) slice(lm.querySelectorAll(sl));
function qstc(lm, sl) (lm = lm.querySelector(sl)) ? lm.textContent : "";
function qsxs(lm, sl) (
diff --git a/standard-feeds/general.js b/standard-feeds/general.js
index 37e63fc..8c7fda8 100644
--- a/standard-feeds/general.js
+++ b/standard-feeds/general.js
@@ -2,6 +2,8 @@
// TEXT COMMANDS
// -----------------------------------------------------------------
+Cu.import("resource://gre/modules/Services.jsm")
+
var H = Utils.escapeHtml;
/* Note that these text formatting commands are a little weird in that
@@ -118,121 +120,44 @@ CmdUtils.CreateCommand({
// CALCULATE COMMANDS
// -----------------------------------------------------------------
-//+ Carlos R. L. Rodrigues
-//@ http://jsfromhell.com/classes/math-parser [rev. #2]
-function MathParser(){
- var o = this, p = o.operator = {};
- p["+"] = function(n, m){return n + m;};
- p["-"] = function(n, m){return n - m;};
- p["*"] = function(n, m){return n * m;};
- p["/"] = function(m, n){return n / m;};
- p["%"] = function(m, n){return n % m;};
- p["^"] = function(m, n){return Math.pow(n, m);};
- p["~"] = function(m, n){return Math.sqrt(n, m);};
- o.custom = {}, p.f = function(s, n){
- if(Math[s]) return Math[s](n);
- else if(o.custom[s]) return o.custom[s].apply(o, n);
- else throw new Error("Function \"" + s + "\" not defined.");
- }, o.add = function(n, f){this.custom[n] = f;}
-};
-MathParser.prototype.eval = function(e){
- var e = e.split(""), v = [], p = [], a, c = 0, s = 0, x, t, d = 0;
- var n = "0123456789.", o = "+-*/^%~", f = this.operator;
- for(var i = 0, l = e.length; i < l; i++)
- if(o.indexOf(e[i]) > -1)
- e[i] == "-" && (s > 1 || !d) && ++s, !s && d && (p.push(e[i]), s = 2), "+-".indexOf(e[i]) < (d = 0) && (c = 1);
- else if(a = n.indexOf(e[i]) + 1 ? e[i++] : ""){
- while(n.indexOf(e[i]) + 1) a += e[i++];
- v.push(d = (s & 1 ? -1 : 1) * a), c && v.push(f[p.pop()](v.pop(), v.pop())) && (c = 0), --i, s = 0;
- }
- for(c = v[0], i = 0, l = p.length; l--; c = f[p[i]](c, v[++i]));
- return c;
-};
-MathParser.prototype.parse = function(e){
- var p = [], f = [], ag, n, c, a, o = this, v = "0123456789.+-*/^%~(, )";
- for(var x, i = 0, l = e.length; i < l; i++){
- if(v.indexOf(c = e.charAt(i)) < 0){
- for(a = c; v.indexOf(c = e.charAt(++i)) < 0; a += c); f.push((--i, a));
- }
- else if(!(c == "(" && p.push(i)) && c == ")"){
- if(a = e.slice(0, (n = p.pop()) - (x = v.indexOf(e.charAt(n - 1)) < 0 ? y = (c = f.pop()).length : 0)), x)
- for(var j = (ag = e.slice(n, ++i).split(",")).length; j--; ag[j] = o.eval(ag[j]));
- l = (e = a + (x ? o.operator.f(c, ag) : o.eval(e.slice(n, ++i))) + e.slice(i)).length, i -= i - n + c.length;
- }
- }
- return o.eval(e);
-};
-
-const GCalcHelp = "http://www.googleguide.com/help/calculator.html";
const noun_calc = {
- name: "calc",
label: "expression",
- rankLast: true,
- noExternalCalls: true,
- suggest: function n_calc_suggest(text, html, cb, selIndices) {
- var simple = this._simple.test(text);
- return [CmdUtils.makeSugg(text, "", simple, simple ? 1 : .5, selIndices)];
+ suggest: function (txt, htm, cb, si) {
+ if (!this._mathlike.test(txt)) return []
+ try {
+ var result = this.Parser.evaluate(txt)
+ , score = result === txt ? .3 : 1
+ }
+ catch (e) {
+ result = e.message
+ score = .1
+ }
+ return [CmdUtils.makeSugg(txt, htm, result, score, si)];
},
- _simple: /^[\d.+\-*\/^%~(, )]+$/,
-};
+ _mathlike: /^[\w.+\-*\/^%(, )|]+$/,
+}
+Services.scriptloader.loadSubScript
+("resource://ubiquity/scripts/math_parser.js", noun_calc)
CmdUtils.CreateCommand({
- names: ["calculate", "gcalculate"],
- argument: noun_calc,
- description: '\
- Calculates using <a href="' + GCalcHelp +'">Google Calculator</a>\
- which has all the features of a scientific calculator,\
- knows constants such as the speed of light,\
- and can convert between units and currencies.<br/>\
- Uses <a href="http://jsfromhell.com/classes/math-parser">MathParser</a>\
- instead for simple expressions like <code>22/7</code>.',
- help: ("Try <code>22/7, 25% of 700, sin(sqrt(ln(pi))), (1+i)^3, " +
- "15 mod 9, (5 choose 2) / 3!, speed of light in miles per hour, " +
- "3 dollars in euros, 242 in hex, MCMXVI in decimal</code>."),
+ names: "calculate",
+ description:
+ 'Calculates using\
+ <a href="http://silentmatt.com/javascript-expression-evaluator/">\
+ JavaScript Expression Evaluator</a>.',
+ help: "Try: <code>22/7, 3^4^5, sin(sqrt(log(PI)))</code>",
icon: "chrome://ubiquity/skin/icons/calculator.png",
- author: {name: "Axel Boldt", email: "axelboldt at yahoo.com"},
- contributor: {name: "satyr", email: "murky.satyr at gmail.com"},
- homepage: "http://math-www.uni-paderborn.de/~axel/",
+ author: "satyr",
license: "Public domain",
- _math_parser: new MathParser,
- // URL of Google page to which expression is to be appended.
- // We want only 1 result.
- _google_url: function (q) ("http://www.google.com/search?hl=en&num=1&q=" +
- encodeURIComponent(q)),
- _calc: function ({text: exp, data: simple}, cb, pb) {
- if (simple) {
- try { var result = this._math_parser.parse(exp) } catch (e) {}
- if (result != null) {
- cb(result);
- return;
- }
- }
- var url = this._google_url(exp), fn = function gcalc(result_page) {
- cb((/\/calculator-40\.gif.*?<b>(.*?)<\/b>/i.exec(result_page) || ",?")[1]);
- };
- pb ? CmdUtils.previewGet(pb, url, fn) : $.get(url, fn);
+ argument: noun_calc,
+ execute: function ({object: {data, score}}) {
+ if (score > .3) CmdUtils.setSelection(data)
+ displayMessage(data)
},
- execute: function ({object}) {
- this._calc(object, function (result) {
- CmdUtils.setSelection(result);
- });
+ preview: function (pb, {object: {data, score}}) {
+ pb.innerHTML = (score < .3 ? "<em class=error>" : "<strong>") + data
},
- preview: function (pb, {object}) {
- if (!object.text) {
- this.previewDefault(pb);
- return;
- }
- this._calc(object, function (result) {
- pb.innerHTML = (
- '<div class="calculate">' +
- '<b style="font-size:larger">' + result + '</b>' +
- (typeof result === "string"
- ? '<p><a href="' + GCalcHelp + '">Quick Reference</a></p>'
- : "") +
- '</div>');
- }, pb);
- }
-});
+})
// -----------------------------------------------------------------
// TRANSLATE COMMANDS
diff --git a/standard-feeds/search.xhtml b/standard-feeds/search.xhtml
index 996c853..6acefd3 100644
--- a/standard-feeds/search.xhtml
+++ b/standard-feeds/search.xhtml
@@ -234,7 +234,7 @@ body {margin:0; padding:0}
.adp-listheader, .adp-legal {display:none}
#trips, #addrs {
max-width: 40%;
- position:absolute; top:30px; right:4px; z-index:5;
+ position:absolute; bottom:12px; right:4px; z-index:5;
background-color:#000; opacity:0.666; font-size:76%;
border-radius:6px;
}
@@ -436,20 +436,6 @@ CmdUtils.CreateCommand({
});
CmdUtils.makeSearchCommand({
- names: ["IMDb", "internet movie database", "movie", "actor"],
- url: "http://www.imdb.com/find?s=all&q={QUERY}",
- defaultUrl: "http://www.imdb.com/",
- icon: "chrome://ubiquity/skin/icons/imdb.ico",
- parser: {
- container: "#main > table > tbody > tr",
- title: "td + td + td > a",
- thumbnail: "td:first > a > img",
- body: "td + td + td > a ~ *",
- maxResults: 8,
- },
-});
-
-CmdUtils.makeSearchCommand({
names: ["Yahoo!"],
url: "http://search.yahoo.com/search?ei=UTF-8&p={QUERY}",
defaultUrl: "http://www.yahoo.com",
@@ -637,40 +623,6 @@ CmdUtils.CreateCommand({
}
});
-CmdUtils.CreateCommand({
- names: ["VideoSurf", "videos"],
- homepage: "http://www.videosurf.com/",
- author: {name: "Udi Falkson", email: "udi at videosurf.com"},
- description: "Performs a VideoSurf video search with advanced preview.",
- help: ("Please email us at feedback at videosurf.com " +
- "if you have any trouble or feature ideas!"),
- icon: "chrome://ubiquity/skin/icons/videosurf.ico",
- arguments: [{role: "object", nountype: noun_arb_text, label: SEARCH_TERM}],
- preview: function vsurf_preview(pblock, {object: {text}}) {
- pblock.innerHTML = _("Loading videos...");
- var url = "http://www.videosurf.com/api/ext/services/ubiquityService.php";
- $.get(url, {query: text}, function vsurf_success(response) {
- pblock.innerHTML = response;
- function getThumb(img) $("#vs_thumb_" + img.id.split("_")[2], pblock)[0];
- var originalSrc = null;
- $(".tiles li a img", pblock).hover(
- function vsurf_mouseover({target: img}) {
- var thumb = getThumb(img);
- originalSrc = thumb.src;
- thumb.src = img.src;
- },
- function vsurf_mouseout({target: img}) {
- getThumb(img).src = originalSrc;
- });
- });
- },
- execute: function vsurf_execute({object: {text}}) {
- Utils.openUrlInBrowser(
- "http://www.videosurf.com/videos/" +
- encodeURI(text.trim()).replace(/%20/g, "+") + "?vlt=ubiquity");
- }
-});
-
CmdUtils.makeSearchCommand({
names: ["YouTube"],
url: ("http://www.youtube.com/results?search_type=search_videos" +
@@ -747,7 +699,7 @@ CmdUtils.makeSearchCommand({
CmdUtils.makeSearchCommand({
names: ["Bugzilla"],
url: "https://bugzilla.mozilla.org/buglist.cgi?quicksearch=%s",
- defaultUrl: "https://bugzilla.mozilla.com",
+ defaultUrl: "https://bugzilla.mozilla.org",
help: "Bugzilla QuickSearch".link(
"https://bugzilla.mozilla.org/page.cgi?id=quicksearch.html"),
icon: "chrome://ubiquity/skin/icons/mozilla.ico",
@@ -781,148 +733,18 @@ CmdUtils.makeSearchCommand({
});
CmdUtils.makeSearchCommand({
- names: ["eBay"],
- url: "http://search.ebay.com/search/search.dll?satitle={QUERY}",
- defaultUrl: "http://www.ebay.com/",
- icon: "chrome://ubiquity/skin/icons/ebay.ico",
- parser: {
- container: "#ResultSet .li, #ResultSet .pcell, #ResultSet .tri-i",
- title: ".ttl, a.ittl",
- body: ".bids, .prc, .tme, .pctr, .fc",
- thumbnail: ".pic img",
- maxResults: 30,
- },
-});
-
-CmdUtils.makeSearchCommand({
- names: ["Ask.com"],
- url: "http://www.ask.com/web?q={QUERY}",
- defaultUrl: "http://www.ask.com/",
- icon: "chrome://ubiquity/skin/icons/ask.ico",
- parser: {
- container: "#teoma-results > div > div",
- title: ".title",
- body: ".abstract",
- maxResults: 10,
- },
-});
-
-CmdUtils.makeSearchCommand({
- names: ["Answers.com"],
- url: "http://www.answers.com/{QUERY}",
- defaultUrl: "http://www.answers.com",
- icon: "chrome://ubiquity/skin/icons/answers.ico",
+ name: "IMDb",
+ url: "http://www.imdb.com/find?q=%s",
+ defaultUrl: "http://www.imdb.com",
+ icon: "chrome://ubiquity/skin/icons/imdb.ico",
parser: {
- container: "#new_left > a + div",
- title: ".DsAndEntryName a",
- body: ".content",
+ container : ".findResult",
+ title : ".result_text",
+ thumbnail : ".primary_photo",
+ maxResults : 8,
},
});
-var formatYelpBusiness = function(biz) {
- var phone = biz.phone.replace(/(\d\d\d)(\d\d\d)(\d\d\d\d)/, "$1.$2.$3");
- var name = CmdUtils.renderTemplate('<span class="name"><a href="${url}">${name}</a></span>',biz);
- return _("${name} in ${city} {if phone}(${phone}){/if} ? ${avg_rating} stars.",
- {name:name, phone:phone, city: biz.city, avg_rating: biz.avg_rating});
-};
-
-CmdUtils.CreateCommand({
- names: ["Yelp"],
- arguments: [
- {role: "object", label: "restaurant", nountype: noun_type_async_restaurant},
- {role: "location", nountype: noun_type_geo_town}
- ],
- icon: "chrome://ubiquity/skin/icons/yelp.ico",
- description: "Searches <a href=\"http://www.yelp.com\">Yelp</a> for restaurants matching your words. Previews the top results.",
- help: "You can search for restaurants near a certain location using the <i>near</i> modifier. For example, try "yelp pizza near boston".",
- execute: function( args ) {
- var object = args.object;
- var location = args.location;
-
- // if no location was specified, use geolocation
- var near = "";
- if (location.text) {
- near = location.text;
- } else {
- var loc = CmdUtils.getGeoLocation();
- if (loc)
- near = loc.city + ", " + loc.state;
- }
-
- var doc = context.focusedWindow.document;
- var focused = context.focusedElement;
-
- if (doc.designMode == "on") {
- var data = globals.yelp[0];
-
- var name = CmdUtils.renderTemplate(
- "<img style='float:left;margin:5px;border:solid #ccc 5px;' src='${photoUrl}'/><a href='${url}'>${name}</a>",
- { url: data.url,
- photoUrl: data.photo_url_small,
- name: data.name });
-
- var stars = CmdUtils.renderTemplate(
- "<img style='position:relative;top:5px;' src='${starUrl}'/>",
- {starUrl: data.rating_img_url});
-
- var templateParams = { city: data.city, name: name, stars: stars };
- if( data.neighborhoods.length > 0 ) {
- templateParams.whereUrl = data.neighborhoods[0].url;
- templateParams.where = data.neighborhoods[0].name;
- }
-
- var msg = _("${name} is a ${stars} restaurant in{if defined('where')} <a href='${whereUrl}'>${where},</a>{/if} ${city}.", templateParams)
- + "<br/>"
- + _("It's been reviewed ${times} times.", {times: data.review_count});
-
- CmdUtils.setSelection( msg );
- return;
- }
-
- var query = object.text;
- var url = "http://www.yelp.com/search?find_desc={QUERY}&find_loc={NEAR}";
- url = url.replace( /{QUERY}/g, query);
- url = url.replace( /{NEAR}/g, near);
-
- Utils.openUrlInBrowser( url );
- },
-
- preview: function( pblock, args ) {
- var {object, location} = args;
- var query = object.text;
- var url = "http://api.yelp.com/business_review_search?";
-
- if(!query.length && !location.text){
- pblock.innerHTML = _("Searches yelp for restaurants in your area");
- return;
- }
-
- var near = "";
- if (location.text) {
- near = location.text;
- } else {
- var loc = CmdUtils.getGeoLocation();
- if (loc)
- near = loc.city + ", " + loc.state;
- }
-
- var params = {
- term: query,
- num_biz_requested: 4,
- location: near,
- ywsid: "HbSZ2zXYuMnu1VTImlyA9A"
- };
-
- CmdUtils.previewGet( pblock, url, params, function(data) {
- globals.yelp = data.businesses;
- pblock.innerHTML = CmdUtils.renderTemplate(
- feed.dom.getElementById("yelp-search").innerHTML,
- {businesses: data.businesses,
- _MODIFIERS: {yelpBusiness: formatYelpBusiness}}
- );
- }, "json");
- }
-});
// -----------------------------------------------------------------
// WEATHER COMMANDS
@@ -1520,9 +1342,12 @@ MAP_INIT = '!'+ function init([lat, lng, type, zoom]){
'tied' in it || it.addEventListener('click', fn, it.tied = true)
}
function mapact(key, url){
- var ev = document.createEvent('MessageEvent')
- ev.initMessageEvent('action', 0, 0, url || '', '*', key || '', self)
- dispatchEvent(ev)
+ dispatchEvent(new MessageEvent('action', {
+ data: url || '',
+ origin: '*',
+ lastEventId: key || '',
+ source: self,
+ }))
}
}
{ let loc = CmdUtils.geoLocation
@@ -1592,16 +1417,19 @@ CmdUtils.CreateCommand({
'('+ uneval([gCoords.lat, gCoords.lon, dat.type, dat.zoom]) +')'
pb.appendChild(script)
}
- var win = doc.defaultView, ev = doc.createEvent('MessageEvent')
- ev.initMessageEvent('go', 0, 0, JSON.stringify({
- q: q, dest: dest,
- lat: gCoords.lat,
- lon: gCoords.lon,
- lang: lang || 'en',
- type: dat.type,
- zoom: dat.zoom,
- }), '*', '', win)
- win.dispatchEvent(ev)
+ var win = doc.defaultView
+ win.dispatchEvent(new win.MessageEvent('go', {
+ data: JSON.stringify({
+ q: q, dest: dest,
+ lat: gCoords.lat,
+ lon: gCoords.lon,
+ lang: lang || 'en',
+ type: dat.type,
+ zoom: dat.zoom,
+ }),
+ origin: '*',
+ source: win,
+ }))
win.addEventListener('action', this._act, false)
this._act.me = this
},
diff --git a/tests/test_all.js b/tests/test_all.js
index 47ab0e3..bfd80c6 100755
--- a/tests/test_all.js
+++ b/tests/test_all.js
@@ -573,10 +573,8 @@ function testUtilsEllipsify() {
}
function testL10nUtilsPropertySelector() {
- var ps = LocalizationUtils.propertySelector("data:," + encodeURI(<![CDATA[
- foo=%S %S
- colon:works too
- ]]>));
+ var ps = LocalizationUtils.propertySelector(
+ "data:," + encodeURI("\n foo=%S %S\n colon:works too\n"));
this.assertEquals(ps("foo", "bar", "baz"), "bar baz");
this.assertEquals(ps("colon"), "works too");
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/ubiquity-extension.git
More information about the Pkg-mozext-commits
mailing list