]> git.donarmstrong.com Git - dactyl.git/blobdiff - common/modules/template.jsm
Import 1.0rc1 supporting Firefox up to 11.*
[dactyl.git] / common / modules / template.jsm
index 6e18dc506c676e085153eebcfb9f338d1dfe68be..61c64cdeae079190451c9041454b4f2477a3fd4c 100644 (file)
@@ -2,13 +2,13 @@
 //
 // This work is licensed for reuse under an MIT license. Details are
 // given in the LICENSE.txt file included with this file.
-"use strict";
+/* use strict */
 
+let global = this;
 Components.utils.import("resource://dactyl/bootstrap.jsm");
 defineModule("template", {
     exports: ["Binding", "Template", "template"],
-    require: ["util"],
-    use: ["messages", "services"]
+    require: ["util"]
 }, this);
 
 default xml namespace = XHTML;
@@ -22,7 +22,7 @@ var Binding = Class("Binding", {
         Object.defineProperties(node, this.constructor.properties);
 
         for (let [event, handler] in values(this.constructor.events))
-            node.addEventListener(event, handler, false);
+            node.addEventListener(event, util.wrapCallback(handler, true), false);
     },
 
     set collapsed(collapsed) {
@@ -57,7 +57,7 @@ var Binding = Class("Binding", {
         }
     },
 
-    events: Class.memoize(function () {
+    events: Class.Memoize(function () {
         let res = [];
         for (let obj in this.bindings)
             if (Object.getOwnPropertyDescriptor(obj, "events"))
@@ -66,7 +66,7 @@ var Binding = Class("Binding", {
         return res;
     }),
 
-    properties: Class.memoize(function () {
+    properties: Class.Memoize(function () {
         let res = {};
         for (let obj in this.bindings)
             for (let prop in properties(obj)) {
@@ -153,9 +153,11 @@ var Template = Module("Template", {
 
                 let obj = params.eventTarget;
                 let events = obj[this.getAttribute("events") || "events"];
+                if (Set.has(events, "input"))
+                    events["dactyl-input"] = events["input"];
 
                 for (let [event, handler] in Iterator(events))
-                    node.addEventListener(event, obj.closure(handler), false);
+                    node.addEventListener(event, util.wrapCallback(obj.closure(handler), true), false);
             }
         })
     },
@@ -171,7 +173,7 @@ var Template = Module("Template", {
                     <>&#xa0;</>)
                 })&#xa0;</span>
         }
-        <a xmlns:dactyl={NS} identifier={item.id || ""} dactyl:command={item.command || ""}
+        <a xmlns:dactyl={NS} identifier={item.id == null ? "" : item.id} dactyl:command={item.command || ""}
            href={item.item.url} highlight="URL">{text || ""}</a>
     </>,
 
@@ -204,7 +206,7 @@ var Template = Module("Template", {
     },
 
     helpLink: function (token, text, type) {
-        if (!services["dactyl:"].initialized)
+        if (!help.initialized)
             util.dactyl.initHelp();
 
         let topic = token; // FIXME: Evil duplication!
@@ -213,7 +215,7 @@ var Template = Module("Template", {
         else if (/^n_/.test(topic))
             topic = topic.slice(2);
 
-        if (services["dactyl:"].initialized && !Set.has(services["dactyl:"].HELP_TAGS, topic))
+        if (help.initialized && !Set.has(help.tags, topic))
             return <span highlight={type || ""}>{text || token}</span>;
 
         XML.ignoreWhitespace = false; XML.prettyPrinting = false;
@@ -224,7 +226,7 @@ var Template = Module("Template", {
         return <a highlight={"InlineHelpLink " + type} tag={topic} href={"dactyl://help-tag/" + topic} dactyl:command="dactyl.help" xmlns:dactyl={NS}>{text || topic}</a>;
     },
     HelpLink: function (token) {
-        if (!services["dactyl:"].initialized)
+        if (!help.initialized)
             util.dactyl.initHelp();
 
         let topic = token; // FIXME: Evil duplication!
@@ -233,7 +235,7 @@ var Template = Module("Template", {
         else if (/^n_/.test(topic))
             topic = topic.slice(2);
 
-        if (services["dactyl:"].initialized && !Set.has(services["dactyl:"].HELP_TAGS, topic))
+        if (help.initialized && !Set.has(help.tags, topic))
             return <>{token}</>;
 
         XML.ignoreWhitespace = false; XML.prettyPrinting = false;
@@ -256,13 +258,32 @@ var Template = Module("Template", {
         })(), template[help ? "HelpLink" : "helpLink"]);
     },
 
+    // Fixes some strange stack rewinds on NS_ERROR_OUT_OF_MEMORY
+    // exceptions that we can't catch.
+    stringify: function stringify(arg) {
+        if (!callable(arg))
+            return String(arg);
+
+        try {
+            this._sandbox.arg = arg;
+            return Cu.evalInSandbox("String(arg)", this._sandbox);
+        }
+        finally {
+            this._sandbox.arg = null;
+        }
+    },
+
+    _sandbox: Class.Memoize(function () Cu.Sandbox(global, { wantXrays: false })),
+
     // if "processStrings" is true, any passed strings will be surrounded by " and
     // any line breaks are displayed as \n
-    highlight: function highlight(arg, processStrings, clip) {
+    highlight: function highlight(arg, processStrings, clip, bw) {
         XML.ignoreWhitespace = false; XML.prettyPrinting = false;
         // some objects like window.JSON or getBrowsers()._browsers need the try/catch
         try {
-            let str = clip ? util.clip(String(arg), clip) : String(arg);
+            let str = this.stringify(arg);
+            if (clip)
+                str = util.clip(str, clip);
             switch (arg == null ? "undefined" : typeof arg) {
             case "number":
                 return <span highlight="Number">{str}</span>;
@@ -273,17 +294,21 @@ var Template = Module("Template", {
             case "boolean":
                 return <span highlight="Boolean">{str}</span>;
             case "function":
-                // Vim generally doesn't like /foo*/, because */ looks like a comment terminator.
-                // Using /foo*(:?)/ instead.
+                if (arg instanceof Ci.nsIDOMElement) // wtf?
+                    return util.objectToString(arg, !bw);
+
+                str = str.replace("/* use strict */ \n", "/* use strict */ ");
                 if (processStrings)
                     return <span highlight="Function">{str.replace(/\{(.|\n)*(?:)/g, "{ ... }")}</span>;
                     <>}</>; /* Vim */
+                arg = String(arg).replace("/* use strict */ \n", "/* use strict */ ");
                 return <>{arg}</>;
             case "undefined":
                 return <span highlight="Null">{arg}</span>;
             case "object":
                 if (arg instanceof Ci.nsIDOMElement)
-                    return util.objectToString(arg, false);
+                    return util.objectToString(arg, !bw);
+
                 // for java packages value.toString() would crash so badly
                 // that we cannot even try/catch it
                 if (/^\[JavaPackage.*\]$/.test(arg))
@@ -302,7 +327,10 @@ var Template = Module("Template", {
         }
     },
 
-    highlightFilter: function highlightFilter(str, filter, highlight) {
+    highlightFilter: function highlightFilter(str, filter, highlight, isURI) {
+        if (isURI)
+            str = util.losslessDecodeURI(str);
+
         return this.highlightSubstrings(str, (function () {
             if (filter.length == 0)
                 return;
@@ -364,6 +392,8 @@ var Template = Module("Template", {
         return <table>
                 <tr style="text-align: left;" highlight="Title">
                     <th colspan="2">{_("title.Jump")}</th>
+                    <th>{_("title.HPos")}</th>
+                    <th>{_("title.VPos")}</th>
                     <th>{_("title.Title")}</th>
                     <th>{_("title.URI")}</th>
                 </tr>
@@ -372,6 +402,8 @@ var Template = Module("Template", {
                     <tr>
                         <td class="indicator">{idx == index ? ">" : ""}</td>
                         <td>{Math.abs(idx - index)}</td>
+                        <td>{val.offset ? val.offset.x : ""}</td>
+                        <td>{val.offset ? val.offset.y : ""}</td>
                         <td style="width: 250px; max-width: 500px; overflow: hidden;">{val.title}</td>
                         <td><a href={val.URI.spec} highlight="URL jump-list">{util.losslessDecodeURI(val.URI.spec)}</a></td>
                     </tr>)