mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-20 18:07:58 +01:00
Take a crack at killing security warnings. Fail miserably. Keep the new code because it's a bit nicer.
--HG-- branch : xslt
This commit is contained in:
@@ -94,98 +94,11 @@ function Liberator()
|
|||||||
{
|
{
|
||||||
this.wrappedJSObject = this;
|
this.wrappedJSObject = this;
|
||||||
|
|
||||||
this.__defineGetter__("helpNamespaces", function () this.NAMESPACES ? this.NAMESPACES.slice() : null);
|
|
||||||
this.__defineSetter__("helpNamespaces", function (namespaces) {
|
|
||||||
if (!this.NAMESPACES)
|
|
||||||
parseHelpTags(namespaces);
|
|
||||||
});
|
|
||||||
|
|
||||||
function xpath(doc, expression)
|
|
||||||
{
|
|
||||||
let result = doc.evaluate(expression, doc,
|
|
||||||
function lookupNamespaceURI(prefix) ({
|
|
||||||
xhtml: "http://www.w3.org/1999/xhtml",
|
|
||||||
liberator: "http://vimperator.org/namespaces/liberator",
|
|
||||||
}[prefix] || null),
|
|
||||||
5, null);
|
|
||||||
result.__iterator__ = function () { let elem; while ((elem = this.iterateNext())) yield elem; };
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.httpGet = httpGet;
|
|
||||||
function httpGet(url)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
let xmlhttp = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
|
|
||||||
xmlhttp.open("GET", url, false);
|
|
||||||
xmlhttp.send(null);
|
|
||||||
return xmlhttp;
|
|
||||||
}
|
|
||||||
catch (e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
const self = this;
|
const self = this;
|
||||||
this.HELP_TAGS = {};
|
this.HELP_TAGS = {};
|
||||||
this.FILE_MAP = {};
|
this.FILE_MAP = {};
|
||||||
this.OVERLAY_MAP = {};
|
this.OVERLAY_MAP = {};
|
||||||
this.NAMESPACES = null;
|
this.NAMESPACES = [];
|
||||||
var HELP_FILES = null;
|
|
||||||
|
|
||||||
function XSLTProcessor(sheet)
|
|
||||||
{
|
|
||||||
let xslt = Cc["@mozilla.org/document-transformer;1?type=xslt"].createInstance(Ci.nsIXSLTProcessor);
|
|
||||||
xslt.importStylesheet(httpGet(sheet).responseXML);
|
|
||||||
return xslt;
|
|
||||||
}
|
|
||||||
|
|
||||||
function findHelpFile(file)
|
|
||||||
{
|
|
||||||
let result = [];
|
|
||||||
for each (let namespace in self.NAMESPACES)
|
|
||||||
{
|
|
||||||
let url = ["chrome://", namespace, "/locale/", file, ".xml"].join("");
|
|
||||||
let res = httpGet(url);
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
if (res.responseXML.documentElement.localName == "document")
|
|
||||||
self.FILE_MAP[file] = url;
|
|
||||||
if (res.responseXML.documentElement.localName == "overlay")
|
|
||||||
self.OVERLAY_MAP[file] = url;
|
|
||||||
if (res.responseXML.documentElement.localName == "document")
|
|
||||||
result = [url, res.responseXML];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseHelpTags(namespaces)
|
|
||||||
{
|
|
||||||
HELP_FILES = [];
|
|
||||||
self.NAMESPACES = Array.slice(namespaces);
|
|
||||||
|
|
||||||
findHelpFile("all");
|
|
||||||
|
|
||||||
const XSLT = XSLTProcessor("chrome://liberator/content/help.xsl");
|
|
||||||
self.HELP_TAGS.all = "all";
|
|
||||||
for each (let namespace in self.NAMESPACES)
|
|
||||||
{
|
|
||||||
let files = xpath(
|
|
||||||
httpGet("chrome://" + namespace + "/locale/all.xml").responseXML,
|
|
||||||
"//liberator:include/@href");
|
|
||||||
for each (let file in files)
|
|
||||||
{
|
|
||||||
let [url, doc] = findHelpFile(file.value);
|
|
||||||
if (!doc)
|
|
||||||
continue;
|
|
||||||
self.FILE_MAP[file.value] = url;
|
|
||||||
doc = XSLT.transformToDocument(doc);
|
|
||||||
for (let elem in xpath(doc, "//liberator:tag/text()"))
|
|
||||||
self.HELP_TAGS[elem.textContent] = file.value;
|
|
||||||
HELP_FILES.push(file.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Liberator.prototype = {
|
Liberator.prototype = {
|
||||||
contractID: "@mozilla.org/network/protocol;1?name=liberator",
|
contractID: "@mozilla.org/network/protocol;1?name=liberator",
|
||||||
@@ -203,6 +116,13 @@ Liberator.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
init: function (obj)
|
||||||
|
{
|
||||||
|
for each (let prop in ["HELP_TAGS", "FILE_MAP", "OVERLAY_MAP", "NAMESPACES"])
|
||||||
|
for (let [k, v] in Iterator(obj[prop]))
|
||||||
|
this[prop][k] = v
|
||||||
|
},
|
||||||
|
|
||||||
scheme: "liberator",
|
scheme: "liberator",
|
||||||
defaultPort: -1,
|
defaultPort: -1,
|
||||||
allowPort: function (port, scheme) false,
|
allowPort: function (port, scheme) false,
|
||||||
|
|||||||
@@ -389,7 +389,7 @@ function Buffer() //{{{
|
|||||||
let xpath = ["input[not(@type) or @type='text' or @type='password' or @type='file']",
|
let xpath = ["input[not(@type) or @type='text' or @type='password' or @type='file']",
|
||||||
"textarea[not(@disabled) and not(@readonly)]"];
|
"textarea[not(@disabled) and not(@readonly)]"];
|
||||||
|
|
||||||
let elements = [m for (m in buffer.evaluateXPath(xpath))].filter(function (match) {
|
let elements = [m for (m in util.evaluateXPath(xpath))].filter(function (match) {
|
||||||
let computedStyle = util.computedStyle(match);
|
let computedStyle = util.computedStyle(match);
|
||||||
return computedStyle.visibility != "hidden" && computedStyle.display != "none";
|
return computedStyle.visibility != "hidden" && computedStyle.display != "none";
|
||||||
});
|
});
|
||||||
@@ -802,7 +802,7 @@ function Buffer() //{{{
|
|||||||
}
|
}
|
||||||
|
|
||||||
let nFeed = 0;
|
let nFeed = 0;
|
||||||
for (let link in buffer.evaluateXPath(["link[@href and (@rel='feed' or (@rel='alternate' and @type))]"], doc))
|
for (let link in util.evaluateXPath(["link[@href and (@rel='feed' or (@rel='alternate' and @type))]"], doc))
|
||||||
{
|
{
|
||||||
let rel = link.rel.toLowerCase();
|
let rel = link.rel.toLowerCase();
|
||||||
let feed = { title: link.title, href: link.href, type: link.type || "" };
|
let feed = { title: link.title, href: link.href, type: link.type || "" };
|
||||||
@@ -1012,48 +1012,6 @@ function Buffer() //{{{
|
|||||||
*/
|
*/
|
||||||
addPageInfoSection: addPageInfoSection,
|
addPageInfoSection: addPageInfoSection,
|
||||||
|
|
||||||
/**
|
|
||||||
* Evaluates an XPath expression in the current or provided
|
|
||||||
* document. It provides the xhtml, xhtml2 and liberator XML
|
|
||||||
* namespaces. The result may be used as an iterator.
|
|
||||||
*
|
|
||||||
* @param {string} expression The XPath expression to evaluate.
|
|
||||||
* @param {Document} doc The document to evaluate the expression in.
|
|
||||||
* @default The current document.
|
|
||||||
* @param {Node} elem The context element.
|
|
||||||
* @default <b>doc</b>
|
|
||||||
* @param {boolean} asIterator Whether to return the results as an
|
|
||||||
* XPath iterator.
|
|
||||||
*/
|
|
||||||
evaluateXPath: function (expression, doc, elem, asIterator)
|
|
||||||
{
|
|
||||||
if (!doc)
|
|
||||||
doc = window.content.document;
|
|
||||||
if (!elem)
|
|
||||||
elem = doc;
|
|
||||||
if (util.isArray(expression))
|
|
||||||
expression = util.makeXPath(expression);
|
|
||||||
|
|
||||||
let result = doc.evaluate(expression, elem,
|
|
||||||
function lookupNamespaceURI(prefix)
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
xhtml: "http://www.w3.org/1999/xhtml",
|
|
||||||
xhtml2: "http://www.w3.org/2002/06/xhtml2",
|
|
||||||
liberator: NS.uri
|
|
||||||
}[prefix] || null;
|
|
||||||
},
|
|
||||||
asIterator ? XPathResult.ORDERED_NODE_ITERATOR_TYPE : XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
|
|
||||||
null
|
|
||||||
);
|
|
||||||
|
|
||||||
result.__iterator__ = asIterator
|
|
||||||
? function () { let elem; while ((elem = this.iterateNext())) yield elem; }
|
|
||||||
: function () { for (let i = 0; i < this.snapshotLength; i++) yield this.snapshotItem(i); };
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the currently selected word. If the selection is
|
* Returns the currently selected word. If the selection is
|
||||||
* null, it tries to guess the word that the caret is
|
* null, it tries to guess the word that the caret is
|
||||||
@@ -1162,7 +1120,7 @@ function Buffer() //{{{
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = buffer.evaluateXPath(options.get("hinttags").defaultValue, frame.document);
|
let res = util.evaluateXPath(options.get("hinttags").defaultValue, frame.document);
|
||||||
for (let [, regex] in Iterator(regexes))
|
for (let [, regex] in Iterator(regexes))
|
||||||
{
|
{
|
||||||
for (let i in util.range(res.snapshotLength, 0, -1))
|
for (let i in util.range(res.snapshotLength, 0, -1))
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ function Hints() //{{{
|
|||||||
if (elem.id)
|
if (elem.id)
|
||||||
{
|
{
|
||||||
// TODO: (possibly) do some guess work for label-like objects
|
// TODO: (possibly) do some guess work for label-like objects
|
||||||
let label = buffer.evaluateXPath("//label[@for='" + elem.id + "']", doc).snapshotItem(0);
|
let label = util.evaluateXPath("//label[@for='" + elem.id + "']", doc).snapshotItem(0);
|
||||||
if (label)
|
if (label)
|
||||||
return [label.textContent.toLowerCase(), true];
|
return [label.textContent.toLowerCase(), true];
|
||||||
}
|
}
|
||||||
@@ -284,7 +284,7 @@ function Hints() //{{{
|
|||||||
let baseNodeAbsolute = util.xmlToDom(<span highlight="Hint"/>, doc);
|
let baseNodeAbsolute = util.xmlToDom(<span highlight="Hint"/>, doc);
|
||||||
|
|
||||||
let elem, text, span, rect, showText;
|
let elem, text, span, rect, showText;
|
||||||
let res = buffer.evaluateXPath(hintMode.tags(), doc, null, true);
|
let res = util.evaluateXPath(hintMode.tags(), doc, null, true);
|
||||||
|
|
||||||
let fragment = util.xmlToDom(<div highlight="hints"/>, doc);
|
let fragment = util.xmlToDom(<div highlight="hints"/>, doc);
|
||||||
let start = pageHints.length;
|
let start = pageHints.length;
|
||||||
@@ -440,7 +440,7 @@ function Hints() //{{{
|
|||||||
// FIXME: Broken for imgspans.
|
// FIXME: Broken for imgspans.
|
||||||
for (let [, { doc: doc }] in Iterator(docs))
|
for (let [, { doc: doc }] in Iterator(docs))
|
||||||
{
|
{
|
||||||
for (let elem in buffer.evaluateXPath("//*[@liberator:highlight and @number]", doc))
|
for (let elem in util.evaluateXPath("//*[@liberator:highlight and @number]", doc))
|
||||||
{
|
{
|
||||||
let group = elem.getAttributeNS(NS.uri, "highlight");
|
let group = elem.getAttributeNS(NS.uri, "highlight");
|
||||||
css.push(highlight.selector(group) + "[number='" + elem.getAttribute("number") + "'] { " + elem.style.cssText + " }");
|
css.push(highlight.selector(group) + "[number='" + elem.getAttribute("number") + "'] { " + elem.style.cssText + " }");
|
||||||
@@ -466,7 +466,7 @@ function Hints() //{{{
|
|||||||
|
|
||||||
for (let [,{ doc: doc, start: start, end: end }] in Iterator(docs))
|
for (let [,{ doc: doc, start: start, end: end }] in Iterator(docs))
|
||||||
{
|
{
|
||||||
for (let elem in buffer.evaluateXPath("//*[@liberator:highlight='hints']", doc))
|
for (let elem in util.evaluateXPath("//*[@liberator:highlight='hints']", doc))
|
||||||
elem.parentNode.removeChild(elem);
|
elem.parentNode.removeChild(elem);
|
||||||
for (let i in util.range(start, end + 1))
|
for (let i in util.range(start, end + 1))
|
||||||
{
|
{
|
||||||
@@ -778,7 +778,7 @@ function Hints() //{{{
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
buffer.evaluateXPath(val, document.implementation.createDocument("", "", null));
|
util.evaluateXPath(val, document.implementation.createDocument("", "", null));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (e)
|
catch (e)
|
||||||
|
|||||||
@@ -638,7 +638,7 @@ const liberator = (function () //{{{
|
|||||||
toolbox = document.getElementById("navigator-toolbox");
|
toolbox = document.getElementById("navigator-toolbox");
|
||||||
if (toolbox)
|
if (toolbox)
|
||||||
{
|
{
|
||||||
function findToolbar(name) buffer.evaluateXPath(
|
function findToolbar(name) util.evaluateXPath(
|
||||||
"./*[@toolbarname=" + util.escapeString(name, "'") + "]",
|
"./*[@toolbarname=" + util.escapeString(name, "'") + "]",
|
||||||
document, toolbox).snapshotItem(0);
|
document, toolbox).snapshotItem(0);
|
||||||
|
|
||||||
@@ -859,7 +859,7 @@ const liberator = (function () //{{{
|
|||||||
completion.toolbar = function toolbar(context) {
|
completion.toolbar = function toolbar(context) {
|
||||||
context.title = ["Toolbar"];
|
context.title = ["Toolbar"];
|
||||||
context.keys = { text: function (item) item.getAttribute("toolbarname"), description: function () "" };
|
context.keys = { text: function (item) item.getAttribute("toolbarname"), description: function () "" };
|
||||||
context.completions = buffer.evaluateXPath("./*[@toolbarname]", document, toolbox);
|
context.completions = util.evaluateXPath("./*[@toolbarname]", document, toolbox);
|
||||||
};
|
};
|
||||||
|
|
||||||
completion.window = function window(context) {
|
completion.window = function window(context) {
|
||||||
@@ -1377,6 +1377,73 @@ const liberator = (function () //{{{
|
|||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* Initialize the help system.
|
||||||
|
*/
|
||||||
|
initHelp: function ()
|
||||||
|
{
|
||||||
|
if (services.get("liberator:").NAMESPACES.length)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let namespaces = [config.name.toLowerCase(), "liberator"];
|
||||||
|
let tagMap = {};
|
||||||
|
let fileMap = {};
|
||||||
|
let overlayMap = {};
|
||||||
|
function XSLTProcessor(sheet)
|
||||||
|
{
|
||||||
|
let xslt = Cc["@mozilla.org/document-transformer;1?type=xslt"].createInstance(Ci.nsIXSLTProcessor);
|
||||||
|
xslt.importStylesheet(util.httpGet(sheet).responseXML);
|
||||||
|
return xslt;
|
||||||
|
}
|
||||||
|
|
||||||
|
function findHelpFile(file)
|
||||||
|
{
|
||||||
|
let result = [];
|
||||||
|
for (let [, namespace] in Iterator(namespaces))
|
||||||
|
{
|
||||||
|
let url = ["chrome://", namespace, "/locale/", file, ".xml"].join("");
|
||||||
|
let res = util.httpGet(url);
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
if (res.responseXML.documentElement.localName == "document")
|
||||||
|
fileMap[file] = url;
|
||||||
|
if (res.responseXML.documentElement.localName == "overlay")
|
||||||
|
overlayMap[file] = url;
|
||||||
|
if (res.responseXML.documentElement.localName == "document")
|
||||||
|
result = [url, res.responseXML];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
findHelpFile("all");
|
||||||
|
tagMap.all = "all";
|
||||||
|
|
||||||
|
const XSLT = XSLTProcessor("chrome://liberator/content/help.xsl");
|
||||||
|
for (let [, namespace] in Iterator(namespaces))
|
||||||
|
{
|
||||||
|
let files = util.evaluateXPath(
|
||||||
|
"//liberator:include/@href",
|
||||||
|
util.httpGet("chrome://" + namespace + "/locale/all.xml").responseXML);
|
||||||
|
for (let file in files)
|
||||||
|
{
|
||||||
|
let [url, doc] = findHelpFile(file.value);
|
||||||
|
if (!doc)
|
||||||
|
continue;
|
||||||
|
fileMap[file.value] = url;
|
||||||
|
doc = XSLT.transformToDocument(doc);
|
||||||
|
for (let elem in util.evaluateXPath("//liberator:tag/text()", doc))
|
||||||
|
tagMap[elem.textContent] = file.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
services.get("liberator:").init({
|
||||||
|
HELP_TAGS: tagMap, FILE_MAP: fileMap,
|
||||||
|
OVERLAY_MAP: overlayMap, NAMESPACES: namespaces
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the help page containing the specified <b>topic</b> if it
|
* Opens the help page containing the specified <b>topic</b> if it
|
||||||
* exists.
|
* exists.
|
||||||
@@ -1726,7 +1793,7 @@ const liberator = (function () //{{{
|
|||||||
let start = Date.now();
|
let start = Date.now();
|
||||||
liberator.log("Initializing liberator object...", 0);
|
liberator.log("Initializing liberator object...", 0);
|
||||||
|
|
||||||
services.get("liberator:").helpNamespaces = [config.name.toLowerCase(), "liberator"];
|
liberator.initHelp();
|
||||||
|
|
||||||
config.features.push(getPlatformFeature());
|
config.features.push(getPlatformFeature());
|
||||||
|
|
||||||
|
|||||||
@@ -1949,7 +1949,7 @@ function ItemList(id) //{{{
|
|||||||
|
|
||||||
divNodes.noCompletions.style.display = haveCompletions ? "none" : "block";
|
divNodes.noCompletions.style.display = haveCompletions ? "none" : "block";
|
||||||
|
|
||||||
completionElements = buffer.evaluateXPath("//xhtml:div[@liberator:highlight='CompItem']", doc);
|
completionElements = util.evaluateXPath("//xhtml:div[@liberator:highlight='CompItem']", doc);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -365,6 +365,48 @@ const util = { //{{{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluates an XPath expression in the current or provided
|
||||||
|
* document. It provides the xhtml, xhtml2 and liberator XML
|
||||||
|
* namespaces. The result may be used as an iterator.
|
||||||
|
*
|
||||||
|
* @param {string} expression The XPath expression to evaluate.
|
||||||
|
* @param {Document} doc The document to evaluate the expression in.
|
||||||
|
* @default The current document.
|
||||||
|
* @param {Node} elem The context element.
|
||||||
|
* @default <b>doc</b>
|
||||||
|
* @param {boolean} asIterator Whether to return the results as an
|
||||||
|
* XPath iterator.
|
||||||
|
*/
|
||||||
|
evaluateXPath: function (expression, doc, elem, asIterator)
|
||||||
|
{
|
||||||
|
if (!doc)
|
||||||
|
doc = window.content.document;
|
||||||
|
if (!elem)
|
||||||
|
elem = doc;
|
||||||
|
if (util.isArray(expression))
|
||||||
|
expression = util.makeXPath(expression);
|
||||||
|
|
||||||
|
let result = doc.evaluate(expression, elem,
|
||||||
|
function lookupNamespaceURI(prefix)
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
xhtml: "http://www.w3.org/1999/xhtml",
|
||||||
|
xhtml2: "http://www.w3.org/2002/06/xhtml2",
|
||||||
|
liberator: NS.uri
|
||||||
|
}[prefix] || null;
|
||||||
|
},
|
||||||
|
asIterator ? XPathResult.ORDERED_NODE_ITERATOR_TYPE : XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
result.__iterator__ = asIterator
|
||||||
|
? function () { let elem; while ((elem = this.iterateNext())) yield elem; }
|
||||||
|
: function () { for (let i = 0; i < this.snapshotLength; i++) yield this.snapshotItem(i); };
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The identity function.
|
* The identity function.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -89,7 +89,7 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<code><!-- Why is the XSLT processor mangling newlines? -->
|
<code><!-- Why is the XSLT processor mangling newlines? -->
|
||||||
<ex>:autocmd LocationChange .* :set editor=<str>gvim -f</str></ex>

|
<ex>:autocmd LocationChange .* :set editor=<str>gvim -f</str></ex>
|
||||||
<ex>:autocmd LocationChange mail\\.google\\.com :set editor=<str>gvim -f -c 'set ft=mail'</str></ex>
|
<ex>:autocmd LocationChange mail\\.google\\.com :set editor=<str>gvim -f -c 'set ft=mail'</str></ex>
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user