зеркало из https://github.com/mozilla/ubiquity.git
Utils: Added parseHtml(), extracted from the feed-specific parseRemoteDocument().
This commit is contained in:
Родитель
2a0f4f1090
Коммит
9c771324d8
|
@ -1,112 +1,42 @@
|
|||
var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
var Utils = {
|
||||
__proto__: (Cu.import("resource://ubiquity/modules/utils.js", null)
|
||||
.Utils),
|
||||
__proto__: Cu.import("resource://ubiquity/modules/utils.js", null).Utils,
|
||||
__globalObject: this,
|
||||
|
||||
// Just like the standard Utils.uri, only if we get a malformed URI
|
||||
// error, we'll try re-evaluating the string using a base URI of the
|
||||
// feed making the call.
|
||||
uri: function uri(obj) {
|
||||
if (typeof obj !== "string") return this.__proto__.uri(obj);
|
||||
try {
|
||||
return this.__proto__.uri(obj);
|
||||
} catch (e if e.result === Cr.NS_ERROR_MALFORMED_URI) {
|
||||
} catch (e if (typeof obj !== "string" &&
|
||||
e.result === Cr.NS_ERROR_MALFORMED_URI)) {
|
||||
return this.__proto__.uri({uri: obj, base: feed.id});
|
||||
}
|
||||
}
|
||||
};
|
||||
Utils.url = Utils.uri;
|
||||
Utils.ajaxGet = function ajaxGet(url, callbackFunction, failureFunction) {
|
||||
jQuery.ajax({
|
||||
url: url,
|
||||
success: callbackFunction,
|
||||
error: failureFunction
|
||||
});
|
||||
};
|
||||
Utils.parseRemoteDocument = function parseRemoteDocument(remoteUrl,
|
||||
postParams,
|
||||
successCallback,
|
||||
errorCallback) {
|
||||
// based on code from http://mxr.mozilla.org/mozilla/source/browser/components/microsummaries/src/nsMicrosummaryService.js
|
||||
var rootElement = null;
|
||||
var iframe = null;
|
||||
|
||||
var parseHandler = {
|
||||
handleEvent: function handleEvent(event) {
|
||||
event.target.removeEventListener("DOMContentLoaded", this, false);
|
||||
var doc = iframe.contentDocument;
|
||||
rootElement.removeChild(iframe);
|
||||
successCallback(doc);
|
||||
}
|
||||
};
|
||||
|
||||
function parseHtml(htmlText) {
|
||||
var window = Utils.currentChromeWindow;
|
||||
var document = window.document;
|
||||
rootElement = document.documentElement;
|
||||
iframe = document.createElement('iframe');
|
||||
iframe.setAttribute("collapsed", true);
|
||||
// secure iframe against untrusted content
|
||||
iframe.setAttribute("type", "content");
|
||||
// needed to create a docshell
|
||||
rootElement.appendChild(iframe);
|
||||
// stop loading about:blank (not needed, and weird things could happpen apparently)
|
||||
iframe.docShell.QueryInterface(Ci.nsIWebNavigation)
|
||||
.stop(Ci.nsIWebNavigation.STOP_NETWORK);
|
||||
// turn off unneeded/unwanted/bad things
|
||||
iframe.docShell.allowJavascript = false;
|
||||
iframe.docShell.allowAuth = false;
|
||||
iframe.docShell.allowPlugins = false;
|
||||
iframe.docShell.allowMetaRedirects = false;
|
||||
iframe.docShell.allowSubframes = false;
|
||||
iframe.docShell.allowImages = false;
|
||||
|
||||
// Convert the HTML text into an input stream.
|
||||
var converter = (Cc["@mozilla.org/intl/scriptableunicodeconverter"]
|
||||
.createInstance(Ci.nsIScriptableUnicodeConverter));
|
||||
converter.charset = "UTF-8";
|
||||
var stream = converter.convertToInputStream(htmlText);
|
||||
// Set up a channel to load the input stream.
|
||||
var channel = (Cc["@mozilla.org/network/input-stream-channel;1"]
|
||||
.createInstance(Ci.nsIInputStreamChannel));
|
||||
channel.setURI(Utils.url(remoteUrl));
|
||||
channel.contentStream = stream;
|
||||
// Load in the background so we don't trigger web progress listeners.
|
||||
channel.QueryInterface(Ci.nsIRequest)
|
||||
.loadFlags |= Ci.nsIRequest.LOAD_BACKGROUND;
|
||||
// need to specify content type, so user isn't prompted to download "unknown" file type
|
||||
var baseChannel = channel.QueryInterface(Ci.nsIChannel);
|
||||
baseChannel.contentType = "text/html";
|
||||
// this will always be UTF-8 thanks to XMLHttpRequest and nsIScriptableUnicodeConverter
|
||||
baseChannel.contentCharset = "UTF-8";
|
||||
|
||||
// background loads don't fire "load" events, listen for DOMContentLoaded instead
|
||||
iframe.addEventListener("DOMContentLoaded", parseHandler, true);
|
||||
var uriLoader = Cc["@mozilla.org/uriloader;1"].getService(Ci.nsIURILoader);
|
||||
uriLoader.openURI(channel, true, iframe.docShell);
|
||||
}
|
||||
|
||||
Utils.ajaxGet = function ajaxGet(url, callbackFunction, failureFunction) (
|
||||
jQuery.ajax({url: url, success: callbackFunction, error: failureFunction}));
|
||||
Utils.parseRemoteDocument = function parseRemoteDocument(
|
||||
remoteUrl, postParams, successCallback, errorCallback) {
|
||||
var ajaxOptions = {
|
||||
url: remoteUrl,
|
||||
type: "GET",
|
||||
dataType: "text",
|
||||
success: parseHtml,
|
||||
success: function pRD_success(htm) { Utils.parseDocument(htm, callback) },
|
||||
error: errorCallback,
|
||||
};
|
||||
|
||||
if (postParams) {
|
||||
ajaxOptions.type = "POST";
|
||||
ajaxOptions.data = postParams;
|
||||
}
|
||||
|
||||
jQuery.ajax(ajaxOptions);
|
||||
return jQuery.ajax(ajaxOptions);
|
||||
};
|
||||
|
||||
var CmdUtils = {
|
||||
__proto__: (Cu.import("resource://ubiquity/modules/cmdutils.js", null)
|
||||
.CmdUtils),
|
||||
__proto__:
|
||||
Cu.import("resource://ubiquity/modules/cmdutils.js", null).CmdUtils,
|
||||
__globalObject: this,
|
||||
__nextId: 0,
|
||||
};
|
||||
|
|
|
@ -86,22 +86,22 @@ for each (let f in [
|
|||
// === {{{ Utils.Application }}} ===
|
||||
// Shortcut to [[https://developer.mozilla.org/en/FUEL/Application]].
|
||||
function Application()
|
||||
Cc["@mozilla.org/fuel/application;1"].getService(Ci.fuelIApplication),
|
||||
Cc["@mozilla.org/fuel/application;1"].getService(Ci.fuelIApplication),
|
||||
|
||||
// === {{{ Utils.ConsoleService }}} ===
|
||||
// Shortcut to {{{nsIConsoleService}}}.
|
||||
function ConsoleService()
|
||||
Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService),
|
||||
Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService),
|
||||
|
||||
// === {{{ Utils.ExtensionManager }}} ===
|
||||
// Shortcut to {{{nsIExtensionManager}}}.
|
||||
function ExtensionManager()
|
||||
Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager),
|
||||
Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager),
|
||||
|
||||
// === {{{ Utils.IOService }}} ===
|
||||
// Shortcut to {{{nsIIOService}}}.
|
||||
function IOService()
|
||||
Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService),
|
||||
Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService),
|
||||
|
||||
// === {{{ Utils.UnicodeConverter }}} ===
|
||||
// Shortcut to {{{nsIScriptableUnicodeConverter}}}.
|
||||
|
@ -129,20 +129,20 @@ for each (let f in [
|
|||
// The chrome application name found in {{{nsIXULAppInfo}}}.
|
||||
// Example values are {{{"Firefox"}}}, {{{"Songbird"}}}, {{{"Thunderbird"}}}.
|
||||
function appName()
|
||||
Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).name,
|
||||
Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).name,
|
||||
|
||||
// === {{{ Utils.appWindowType }}} ===
|
||||
// The name of "main" application windows for the chrome application.
|
||||
// Example values are {{{"navigator:browser"}}} for Firefox/Thunderbird
|
||||
// and {{{"Songbird:Main"}}} for Songbird.
|
||||
function appWindowType()
|
||||
({Songbird: "Songbird:Main"})[Utils.appName] || "navigator:browser",
|
||||
({Songbird: "Songbird:Main"})[Utils.appName] || "navigator:browser",
|
||||
|
||||
// === {{{ Utils.OS }}} ===
|
||||
// The platform name found in {{{nsIXULRuntime}}}.
|
||||
// See [[https://developer.mozilla.org/en/OS_TARGET]].
|
||||
function OS()
|
||||
Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS,
|
||||
Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS,
|
||||
|
||||
]) defineLazyProperty(Utils, f);
|
||||
|
||||
|
@ -178,17 +178,17 @@ function log(what) {
|
|||
try { return Utils.json.encode(o) } finally { return 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);
|
||||
});
|
||||
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));
|
||||
}
|
||||
|
@ -574,9 +574,57 @@ function getLocalUrl(url, charset) {
|
|||
return req.responseText;
|
||||
}
|
||||
|
||||
// ==={{{ Utils.parseHtml(htmlText, callback) }}}===
|
||||
// Parses {{{htmlText}}} to a DOM document and passes it to {{{callback}}}.
|
||||
|
||||
function parseHtml(htmlText, callback) {
|
||||
var {document} = Utils.currentChromeWindow;
|
||||
var iframe = document.createElement("iframe");
|
||||
iframe.setAttribute("collapsed", true); // hide
|
||||
iframe.setAttribute("type", "content"); // secure
|
||||
// needed to create a docshell
|
||||
document.documentElement.appendChild(iframe);
|
||||
var {docShell} = iframe;
|
||||
docShell.QueryInterface(Ci.nsIWebNavigation)
|
||||
.stop(Ci.nsIWebNavigation.STOP_NETWORK); // stop loading about:blank
|
||||
// turn off unneeded/unwanted/bad things
|
||||
(docShell.allowJavascript =
|
||||
docShell.allowAuth =
|
||||
docShell.allowPlugins =
|
||||
docShell.allowMetaRedirects =
|
||||
docShell.allowSubframes =
|
||||
docShell.allowImages = false);
|
||||
|
||||
// Convert the HTML text into an input stream.
|
||||
var converter = Utils.UnicodeConverter;
|
||||
converter.charset = "UTF-8";
|
||||
var stream = converter.convertToInputStream(htmlText);
|
||||
// Set up a channel to load the input stream.
|
||||
var channel = (Cc["@mozilla.org/network/input-stream-channel;1"]
|
||||
.createInstance(Ci.nsIInputStreamChannel));
|
||||
channel.setURI(Utils.IOService.newURI("about:blank", null, null));
|
||||
channel.contentStream = stream;
|
||||
// Load in the background so we don't trigger web progress listeners.
|
||||
channel.QueryInterface(Ci.nsIRequest)
|
||||
.loadFlags |= Ci.nsIRequest.LOAD_BACKGROUND;
|
||||
// need to specify content type,
|
||||
// so user isn't prompted to download "unknown" file type
|
||||
var baseChannel = channel.QueryInterface(Ci.nsIChannel);
|
||||
baseChannel.contentType = "text/html";
|
||||
baseChannel.contentCharset = "UTF-8";
|
||||
|
||||
// background loads don't fire "load" events
|
||||
listenOnce(iframe, "DOMContentLoaded", function onParsed() {
|
||||
var doc = iframe.contentDocument;
|
||||
iframe.parentNode.removeChild(iframe);
|
||||
callback(doc);
|
||||
}, true);
|
||||
Cc["@mozilla.org/uriloader;1"].getService(Ci.nsIURILoader)
|
||||
.openURI(channel, true, docShell);
|
||||
}
|
||||
|
||||
// ** {{{ Utils.trim(str) }}} **
|
||||
// **//Deprecated.//** Use native {{{trim()}}} instead.
|
||||
|
||||
Utils.trim = String.trim;
|
||||
|
||||
// === {{{ Utils.sortBy(array, key, descending = false) }}} ===
|
||||
|
@ -868,7 +916,7 @@ function notify(label, value, image, priority, buttons, target) {
|
|||
}
|
||||
|
||||
// === {{{ Utils.listenOnce(element, eventType, listener, useCapture) }}} ===
|
||||
//
|
||||
//
|
||||
// Same as [[https://developer.mozilla.org/en/DOM/element.addEventListener]],
|
||||
// except that the {{{listener}}} will be automatically removed on its
|
||||
// first execution.
|
||||
|
@ -1154,7 +1202,7 @@ for (let n in gClipboard.flavors) let (name = n) {
|
|||
}
|
||||
defineLazyProperty(
|
||||
gClipboard, function service()
|
||||
Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard));
|
||||
Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard));
|
||||
|
||||
// == {{{ Utils.history }}} ==
|
||||
// Contains functions that make it easy to access
|
||||
|
@ -1321,7 +1369,7 @@ Utils.gist = {
|
|||
//
|
||||
// {{{id}}} is an optional number that specifies target Gist.
|
||||
// The user needs to be the owner of that Gist.
|
||||
paste: function gist_paste(files, id) {
|
||||
paste: function gist_paste(files, id) {
|
||||
var data = id ? ["_method=put"] : [], i = 1;
|
||||
for (let name in files) {
|
||||
for (let [k, v] in new Iterator({
|
||||
|
|
Загрузка…
Ссылка в новой задаче