mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-27 08:29:26 +00:00
a51002fbca
- Bug 1202386: Add logging macros for HAL IPC, r=shuang (246eb96f38)
- Bug 1202386: Output clear HAL IPC errors, r=shuang (eaba0dc9a8)
- Bug 1202704: Move Bluetooth IPC pack functions to generic HAL IPC, r=shuang (4c745de79c)
- Bug 1202704: Move Bluetooth IPC unpack functions to generic HAL IPC, r=shuang (4f8600030b)
- Bug 1202704: Move Bluetooth's |UnpackPDUInitOp| to generic HAL IPC code, r=shuang (345f21c637)
- Bug 1209085: Add 6-argument operator () to |UnpackPDUInitOp|, r=joliu (f5f8cf2dd9)
- Bug 1123760 - make autocomplete dropmarker in the urlbar actually work when activated through a11y APIs, r=surkov (eee42195f4)
- Bug 1123760 - bustage follow-up: remove unused variable, rs=bustage on a CLOSED TREE (6de8519b23)
- Bug 1152836 - QR Decoder: Let everywhere, style nits: 580ms -> 400ms r=past (92a7fd6a15)
- Bug 1212430 - Remove CrashAtUnhandlableOOM() and replace with AutoEnterOOMUnsafeRegion r=jandem (f595b87951)
- Bug 1175755 - Only clear GC statistics aborted flag at the end of the outermost nested GC r=bbouvier (ca73f34c69)
- reapply Bug 1221385 - Handle OOM during JitRuntime (e7def65b78)
- No bug: Clarify documentation for js::NewObjectMetadataState. DONTBUILD r=fitzgen (41022b4137)
- Bug 1211164 - Collect JS deprecated language extension telemetry for Add-ons. r=till,bsmedberg (eacd40ad66)
- Bug 1212296 - undo a state change on OOM. r=till (6e272353d0)
- Bug 1214006 - Take account of the fact that JSScript::atoms may be null while tracing r=terrence (19f61d7494)
- missing bits of Bug 1208665 (c31173b0d4)
- Bug 1221891 - "Fix a typo in TraceLoggingGraph.h". r=hv1989 (e1fc11f8df)
- Bug 1221460 - "TraceLogger: Enable several new optimizations in 'TLLOG=IonCompiler'". r=hv1989 (ab3398646e)
- Bug 1204365 - Repair external view source file name and extension. r=mconley (f033e55a0e)
- Bug 1163693 - Fix View Source external editor fallback. r=jryans. (9c8becc93b)
- Bug 1207629 - Don't assume that viewSourceUtils.js has Services in scope. r=jryans (07977953c0)
- add back some telemetry (1e3b5bde5b)
- Bug 1186785 - Replace nsBaseHashtable::EnumerateRead() calls in toolkit/ with iterators. r=froydnj. (e93e098dd8)
- add back some crashreporter (80e325b3be)
- Bug 1220035 - Fix -Wimplicit-fallthrough warnings in xpcom. r=mccr8 (2ef9ecad5f)
- Bug 1215629 - Remove nsDebug logger. r=froydnj (46784f05fd)
- Bug 1137963 - Use a spin lock for TraceRefCnt. r=waldo, r=froydnj (b2420c97c0)
- Bug 1196430 - part 1 - rename serialNumberRecord to SerialNumberRecord; r=mccr8 (933670070d)
- Bug 1196430 - part 2 - give SerialNumberRecord a proper constructor; r=mccr8 (3ddf3d5e69)
- Bug 1196430 - part 3 - remove unnecessary nsString.h include from nsTraceRefcnt.cpp; r=mccr8 (034954e692)
- Bug 1196430 - part 4 - record allocation stacks for classes in XPCOM_MEM_LOG_CLASSES; r=mccr8 (366b612807)
- Bug 1196430 - part 5 - dump allocation stacks for leaked objects in XPCOM_MEM_LOG_CLASSES; r=mccr8 (dce7b9cca2)
- Bug 1180745 - Fix logging test screenshotting errors. r=jgriffin (a589f0d322)
- Bug 1091285 - move dumpScreen in a new mozscreenshot package. r=jgriffin This also completely remove build/automationutils.py. (6e633359ef)
- some crashreporter stuff (2d0bc9c95d)
- Bug 1196430 - part 6 - move cut-and-paste stack fixer code into mozrunner; r=wlach (ffc7ccd521)
- Bug 1196430 - part 7 - teach process_leak_log how to symbolicate leaked object stacks; r=mccr8 (0b5a4ace7c)
- Bug 1196430 - part 8 - use less reinterpret_cast in nsTraceRefcnt.cpp; r=mccr8 (758cfca0aa)
- Bug 1196430 follow-up: Hide the usage of gCodeAddressService behind #ifdef MOZ_STACKWALKING (e8d62dd73e)
- Bug 487494 - Add an xpcshell selftest for readable stacks from assertions.;r=ted (ea15cf3cbb)
- Bug 1156977 - Assert when aClassName is empty in BloatEntry. r=froydnj Bug 1116550 - Part 1: Turn HaveLeaks and Clear into methods. r=froydnj (8d7f88f498)
- Bug 1116550 - Part 2: Print out negative values for leaks when there are more dtors than ctors. r=froydnj (7c9e3e7848)
- Bug 1190483 - Add a way to record a DMD log late in shutdown. r=erahm (df7c22e64d)
- Bug 1174344 - make error message for mismatched leak log entries more helpful; r=mccr8 (7f969e72c0)
- Bug 1190483 - Followup to address review comment. (d3873f76fd)
- Bug 1186025. Optimize the usage of regions. r=mstange (263080a66e)
- Bug 1211841 - Style off the main thread markers differently, r=jsantell (1a183c5d3e)
- Bug 1211839 - Don't allow off the main thread markers to nest under main thread markers, r=smaug, jsantell (f4d4b7ccf1)
- Bug 1207161 - fix run-by-dir leak in test_bug846906.xul; r=mccr8 (5511752103)
- Bug 1205348 - Always do shutdown CCs when NS_FREE_PERMANENT_DATA is defined. r=smaug (7fd7a7455c)
- Bug 1208157, part 1 - Add and use nsCycleCollector::IsIdle() predicate. r=smaug (a06c2bd1db)
- Bug 1208157, part 2 - Make the fields of nsCycleCollector private. r=smaug (494637fbef)
- Bug 1207368 - Use swap() instead of forget() to remove MessageElement::mMessage. r=froydnj (8c58d38a55)
- Bug 1181520 - Remove support for passing in reftest arguments via the command line, r=jmaher (75e9440e40)
- Bug 1196814 - Fail Android mochitest, robocop, reftests when Fennec is not installed; r=jmaher (6ec15636eb)
- Bug 1183717 - Increase default timeout for Android Debug reftests; r=jmaher (1b07fc1c9b)
- Bug 1181516 - Allow reftests to take paths to multiple directories containing tests on the command line, r=jmaher (1e27ef0d69)
- Bug 1198944 - remove vmware recording support from mochitest; r=khuey (06e79556fb)
- Bug 1162003 - Enable run-by-dir mode on Fx desktop opt builds. r=jmaher (0ef288a33c)
- Bug 1087629 - Add two new test cases for ICE connection states. r=ekr (374112f2d0)
- Bug 1186551 - [mozlog] add structured action process_start/process_exit. r=jgraham (13ce88dbf7)
- Bug 1154111 - Colorize SKIP in test logs. r=jgraham (85910e0f8b)
- Bug 1191267 - Fix mozlog log buffering command line option, r=chmanchester (2bd6592f9b)
- Bug 1185244 - Improve mach support for running mochitests on Valgrind. r=jgraham, njn. (7f5a830fa0)
- Bug 1219870 - [mozlog] ensure correct suite state when logging suite_start/suite_end via StructuredLogger.log_raw, r=chmanchester (21710387a4)
- Bug 1198257 - Better support for providing a directory name and discovering reftests under that directory, r=jmaher (f6255fc44c)
- Bug 1208220 - Remove test of manifest filename that breaks my workflow. r=jgraham (ae4e45946d)
- Bug 1186888 - [mozlog] Ability to use a pre-existing logger with commandline.setup_logging(), r=jgraham (80dfa2a8a8)
- Bug 1042998 - Use StructuredLog.jsm for mochitest logging, r=chmanchester (8851b1b6f9)
- Bug 1218010 - Shorten the polling interval when waiting for httpd.js startup in mochitest. r=ahal (a1f2c81a8e)
- Bug 1224305 - Add an option to the mochitest harness to provide a copy of the extra chrome manifest it writes. r=ahal (e617971f41)
- Bug 1170342 - Don't disable XInput2 for mochitests on GTK3, off by default now. r=karlt (05d53439da)
- Bug 1145375 - Don't kill the debugger if the user Ctrl-C's as running a mochitest; r=ted (6c310500b8)
- Bug 1199241 - Average runtime data across platforms instead of keeping it distinct, r=jgriffin (cd497f509c)
- Bug 1157852 - Mochitest DevTools test directories run multiple times. r=ahal (415ab41a3a)
- Bug 1186791 (part 1) - Replace nsBaseHashtable::EnumerateRead() calls in storage/ with iterators. r=mak. (84f6f1f566)
- Bug 1186791 (part 2) - Replace nsBaseHashtable::EnumerateRead() calls in storage/ with iterators. r=mak. (9c67504d0c)
- Bug 1186791 (part 3) - Replace nsBaseHashtable::EnumerateRead() calls in storage/ with iterators. r=mak. (02f472c197)
- Bug 1219238 - remove AutoArray from mozStorageSQLFunctions.cpp; r=mak (45e751d2b7)
- Bug 1166931 - JS Warning in MobileIdentityManager.jsm r=ferjm (2022d4cccd)
- var-const (b7800ec532)
- Trivial, no bug: add missing semicolon to nsBlocklistService.js to avoid a strict warning. (ee6b8a7593)
- Bug 1208242 - Part 1: hook up the blocklist service to b2g web extensions r=mossop,ferjm (d0ad653af4)
- Bug 1208242 - Part 3: don't ship things that should not ship r=me (cd75e88080)
- Bug 1009795 - Use toLocalString to format download size instead of the decimalSymbol hook; r=mak (a4b4442d2c)
- Bug 1009795 - Part 2: Revert to the old gDecimalSymbol hack if the Internationalization API is not available; r=mak (465e23f2c3)
- Bug 1116385. r=Mossop (f0a7b7d450)
- let-var (cb5d9d1d07)
- Bug 1210459: Add originAttributes for tests that implement nsILoadContext. r=bholley (ea6be1490a)
- var-let (d7d4533b53)
- Bug 1034724 - Fixed Unicode values of prefs in about:support. r=adw (1c8253ac5b)
- Bug 1153381. Add a D3D11 ANGLE blacklist. r=mstange (9008483ca5)
- add back some WIn XP and 2k3 stuff (896a4a7e9b)
- Bug 1141783 - Correct user message for mismatched drivers. Don't mismatch if the DLLs are missing. r=jrmuizelaar (872d0c3aff)
- missing members version (4771ff5f24)
- bug 1170987 - Fix gfx/2d to build on iOS. r=jrmuizel (1e555cb6b3)
- Bug 1201937 - push transform onto cairo context when evaluating path bounds. r=eihrul (6a4d8d98ec)
- Bug 1165900 - Make MaybeSnapToDevicePixels return a boolean to indicate whether snapping occurred. r=Bas (8f33f6cf7d)
- Bug 1190705 - Add crashtest for canvas 2d. r=Bas (bf3afb2acc)
- Bug 1161277 - verify SkPath is finite before doing ContainsPoint queries. r=jmuizelaar (c56f9ef322)
- Bug 1218900 - Make shell function startTimingMutator() fail with an error rather than asserting when called at the wrong time r=sfink (856e8678ce)
- small type fix (b36cfdf416)
- Bug 1214846 - Make SPSProfiler::enter() report OOM to the context r=terrence (6086f60d17)
- Bug 1218637 - IonMonkey: MIPS64: Add support into vm. r=arai (ae22538418)
- gfx: add back `AddCrashReportAnnotations()` prototype (c13f61cd8a)
517 lines
22 KiB
JavaScript
517 lines
22 KiB
JavaScript
// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
/*
|
|
* To keep the global namespace safe, don't define global variables and
|
|
* functions in this file.
|
|
*
|
|
* This file silently depends on contentAreaUtils.js for
|
|
* getDefaultFileName, getNormalizedLeafName and getDefaultExtension
|
|
*/
|
|
|
|
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
XPCOMUtils.defineLazyModuleGetter(this, "ViewSourceBrowser",
|
|
"resource://gre/modules/ViewSourceBrowser.jsm");
|
|
XPCOMUtils.defineLazyModuleGetter(this, "Deprecated",
|
|
"resource://gre/modules/Deprecated.jsm");
|
|
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
|
|
"resource://gre/modules/PrivateBrowsingUtils.jsm");
|
|
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
|
"resource://gre/modules/Services.jsm");
|
|
|
|
var gViewSourceUtils = {
|
|
|
|
mnsIWebBrowserPersist: Components.interfaces.nsIWebBrowserPersist,
|
|
mnsIWebProgress: Components.interfaces.nsIWebProgress,
|
|
mnsIWebPageDescriptor: Components.interfaces.nsIWebPageDescriptor,
|
|
|
|
/**
|
|
* Opens the view source window.
|
|
*
|
|
* @param aArgsOrURL (required)
|
|
* This is either an Object containing parameters, or a string
|
|
* URL for the page we want to view the source of. In the latter
|
|
* case we will be paying attention to the other parameters, as
|
|
* we will be supporting the old API for this method.
|
|
* If aArgsOrURL is an Object, the other parameters will be ignored.
|
|
* aArgsOrURL as an Object can include the following properties:
|
|
*
|
|
* URL (required):
|
|
* A string URL for the page we'd like to view the source of.
|
|
* browser (optional):
|
|
* The browser containing the document that we would like to view the
|
|
* source of. This is required if outerWindowID is passed.
|
|
* outerWindowID (optional):
|
|
* The outerWindowID of the content window containing the document that
|
|
* we want to view the source of. Pass this if you want to attempt to
|
|
* load the document source out of the network cache.
|
|
* lineNumber (optional):
|
|
* The line number to focus on once the source is loaded.
|
|
*
|
|
* @param aPageDescriptor (deprecated, optional)
|
|
* Accepted for compatibility reasons, but is otherwise ignored.
|
|
* @param aDocument (deprecated, optional)
|
|
* The content document we would like to view the source of. This
|
|
* function will throw if aDocument is a CPOW.
|
|
* @param aLineNumber (deprecated, optional)
|
|
* The line number to focus on once the source is loaded.
|
|
*/
|
|
viewSource: function(aArgsOrURL, aPageDescriptor, aDocument, aLineNumber)
|
|
{
|
|
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
|
|
.getService(Components.interfaces.nsIPrefBranch);
|
|
if (prefs.getBoolPref("view_source.editor.external")) {
|
|
this.openInExternalEditor(aArgsOrURL, aPageDescriptor, aDocument, aLineNumber);
|
|
} else {
|
|
this._openInInternalViewer(aArgsOrURL, aPageDescriptor, aDocument, aLineNumber);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Displays view source in the provided <browser>. This allows for non-window
|
|
* display methods, such as a tab from Firefox.
|
|
*
|
|
* @param aArgs
|
|
* An object with the following properties:
|
|
*
|
|
* URL (required):
|
|
* A string URL for the page we'd like to view the source of.
|
|
* viewSourceBrowser (required):
|
|
* The browser to display the view source in.
|
|
* browser (optional):
|
|
* The browser containing the document that we would like to view the
|
|
* source of. This is required if outerWindowID is passed.
|
|
* outerWindowID (optional):
|
|
* The outerWindowID of the content window containing the document that
|
|
* we want to view the source of. Pass this if you want to attempt to
|
|
* load the document source out of the network cache.
|
|
* lineNumber (optional):
|
|
* The line number to focus on once the source is loaded.
|
|
*/
|
|
viewSourceInBrowser: function(aArgs) {
|
|
Services.telemetry
|
|
.getHistogramById("VIEW_SOURCE_IN_BROWSER_OPENED_BOOLEAN")
|
|
.add(true);
|
|
let viewSourceBrowser = new ViewSourceBrowser(aArgs.viewSourceBrowser);
|
|
viewSourceBrowser.loadViewSource(aArgs);
|
|
},
|
|
|
|
/**
|
|
* Displays view source for a selection from some document in the provided
|
|
* <browser>. This allows for non-window display methods, such as a tab from
|
|
* Firefox.
|
|
*
|
|
* @param aSelection
|
|
* A Selection object for the content of interest.
|
|
* @param aViewSourceInBrowser
|
|
* The browser to display the view source in.
|
|
*/
|
|
viewSourceFromSelectionInBrowser: function(aSelection, aViewSourceInBrowser) {
|
|
let viewSourceBrowser = new ViewSourceBrowser(aViewSourceInBrowser);
|
|
viewSourceBrowser.loadViewSourceFromSelection(aSelection);
|
|
},
|
|
|
|
/**
|
|
* Displays view source for a MathML fragment from some document in the
|
|
* provided <browser>. This allows for non-window display methods, such as a
|
|
* tab from Firefox.
|
|
*
|
|
* @param aNode
|
|
* Some element within the fragment of interest.
|
|
* @param aContext
|
|
* A string denoting the type of fragment. Currently, "mathml" is the
|
|
* only accepted value.
|
|
* @param aViewSourceInBrowser
|
|
* The browser to display the view source in.
|
|
*/
|
|
viewSourceFromFragmentInBrowser: function(aNode, aContext,
|
|
aViewSourceInBrowser) {
|
|
let viewSourceBrowser = new ViewSourceBrowser(aViewSourceInBrowser);
|
|
viewSourceBrowser.loadViewSourceFromFragment(aNode, aContext);
|
|
},
|
|
|
|
// Opens the interval view source viewer
|
|
_openInInternalViewer: function(aArgsOrURL, aPageDescriptor, aDocument, aLineNumber)
|
|
{
|
|
// try to open a view-source window while inheriting the charset (if any)
|
|
var charset = null;
|
|
var isForcedCharset = false;
|
|
if (aDocument) {
|
|
if (Components.utils.isCrossProcessWrapper(aDocument)) {
|
|
throw new Error("View Source cannot accept a CPOW as a document.");
|
|
}
|
|
|
|
charset = "charset=" + aDocument.characterSet;
|
|
try {
|
|
isForcedCharset =
|
|
aDocument.defaultView
|
|
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
|
.getInterface(Components.interfaces.nsIDOMWindowUtils)
|
|
.docCharsetIsForced;
|
|
} catch (ex) {
|
|
}
|
|
}
|
|
Services.telemetry
|
|
.getHistogramById("VIEW_SOURCE_IN_WINDOW_OPENED_BOOLEAN")
|
|
.add(true);
|
|
openDialog("chrome://global/content/viewSource.xul",
|
|
"_blank",
|
|
"all,dialog=no",
|
|
aArgsOrURL, charset, aPageDescriptor, aLineNumber, isForcedCharset);
|
|
},
|
|
|
|
buildEditorArgs: function(aPath, aLineNumber) {
|
|
// Determine the command line arguments to pass to the editor.
|
|
// We currently support a %LINE% placeholder which is set to the passed
|
|
// line number (or to 0 if there's none)
|
|
var editorArgs = [];
|
|
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
|
|
.getService(Components.interfaces.nsIPrefBranch);
|
|
var args = prefs.getCharPref("view_source.editor.args");
|
|
if (args) {
|
|
args = args.replace("%LINE%", aLineNumber || "0");
|
|
// add the arguments to the array (keeping quoted strings intact)
|
|
const argumentRE = /"([^"]+)"|(\S+)/g;
|
|
while (argumentRE.test(args))
|
|
editorArgs.push(RegExp.$1 || RegExp.$2);
|
|
}
|
|
editorArgs.push(aPath);
|
|
return editorArgs;
|
|
},
|
|
|
|
/**
|
|
* Opens an external editor with the view source content.
|
|
*
|
|
* @param aArgsOrURL (required)
|
|
* This is either an Object containing parameters, or a string
|
|
* URL for the page we want to view the source of. In the latter
|
|
* case we will be paying attention to the other parameters, as
|
|
* we will be supporting the old API for this method.
|
|
* If aArgsOrURL is an Object, the other parameters will be ignored.
|
|
* aArgsOrURL as an Object can include the following properties:
|
|
*
|
|
* URL (required):
|
|
* A string URL for the page we'd like to view the source of.
|
|
* browser (optional):
|
|
* The browser containing the document that we would like to view the
|
|
* source of. This is required if outerWindowID is passed.
|
|
* outerWindowID (optional):
|
|
* The outerWindowID of the content window containing the document that
|
|
* we want to view the source of. Pass this if you want to attempt to
|
|
* load the document source out of the network cache.
|
|
* lineNumber (optional):
|
|
* The line number to focus on once the source is loaded.
|
|
*
|
|
* @param aPageDescriptor (deprecated, optional)
|
|
* Accepted for compatibility reasons, but is otherwise ignored.
|
|
* @param aDocument (deprecated, optional)
|
|
* The content document we would like to view the source of. This
|
|
* function will throw if aDocument is a CPOW.
|
|
* @param aLineNumber (deprecated, optional)
|
|
* The line number to focus on once the source is loaded.
|
|
* @param aCallBack
|
|
* A function accepting two arguments:
|
|
* * result (true = success)
|
|
* * data object
|
|
* The function defaults to opening an internal viewer if external
|
|
* viewing fails.
|
|
*/
|
|
openInExternalEditor: function(aArgsOrURL, aPageDescriptor, aDocument,
|
|
aLineNumber, aCallBack) {
|
|
let data;
|
|
if (typeof aArgsOrURL == "string") {
|
|
Deprecated.warning("The arguments you're passing to " +
|
|
"openInExternalEditor are using an out-of-date API.",
|
|
"https://developer.mozilla.org/en-US/Add-ons/" +
|
|
"Code_snippets/View_Source_for_XUL_Applications");
|
|
if (Components.utils.isCrossProcessWrapper(aDocument)) {
|
|
throw new Error("View Source cannot accept a CPOW as a document.");
|
|
}
|
|
data = {
|
|
url: aArgsOrURL,
|
|
pageDescriptor: aPageDescriptor,
|
|
doc: aDocument,
|
|
lineNumber: aLineNumber,
|
|
isPrivate: false,
|
|
};
|
|
if (aDocument) {
|
|
data.isPrivate =
|
|
PrivateBrowsingUtils.isWindowPrivate(aDocument.defaultView);
|
|
}
|
|
} else {
|
|
let { URL, browser, lineNumber } = aArgsOrURL;
|
|
data = {
|
|
url: URL,
|
|
lineNumber,
|
|
isPrivate: false,
|
|
};
|
|
if (browser) {
|
|
data.doc = {
|
|
characterSet: browser.characterSet,
|
|
contentType: browser.documentContentType,
|
|
title: browser.contentTitle,
|
|
};
|
|
data.isPrivate = PrivateBrowsingUtils.isBrowserPrivate(browser);
|
|
}
|
|
}
|
|
|
|
try {
|
|
var editor = this.getExternalViewSourceEditor();
|
|
if (!editor) {
|
|
this.handleCallBack(aCallBack, false, data);
|
|
return;
|
|
}
|
|
|
|
// make a uri
|
|
var ios = Components.classes["@mozilla.org/network/io-service;1"]
|
|
.getService(Components.interfaces.nsIIOService);
|
|
var charset = data.doc ? data.doc.characterSet : null;
|
|
var uri = ios.newURI(data.url, charset, null);
|
|
data.uri = uri;
|
|
|
|
var path;
|
|
var contentType = data.doc ? data.doc.contentType : null;
|
|
if (uri.scheme == "file") {
|
|
// it's a local file; we can open it directly
|
|
path = uri.QueryInterface(Components.interfaces.nsIFileURL).file.path;
|
|
|
|
var editorArgs = this.buildEditorArgs(path, data.lineNumber);
|
|
editor.runw(false, editorArgs, editorArgs.length);
|
|
this.handleCallBack(aCallBack, true, data);
|
|
} else {
|
|
// set up the progress listener with what we know so far
|
|
this.viewSourceProgressListener.contentLoaded = false;
|
|
this.viewSourceProgressListener.editor = editor;
|
|
this.viewSourceProgressListener.callBack = aCallBack;
|
|
this.viewSourceProgressListener.data = data;
|
|
if (!data.pageDescriptor) {
|
|
// without a page descriptor, loadPage has no chance of working. download the file.
|
|
var file = this.getTemporaryFile(uri, data.doc, contentType);
|
|
this.viewSourceProgressListener.file = file;
|
|
|
|
var webBrowserPersist = Components
|
|
.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
|
|
.createInstance(this.mnsIWebBrowserPersist);
|
|
// the default setting is to not decode. we need to decode.
|
|
webBrowserPersist.persistFlags = this.mnsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
|
|
webBrowserPersist.progressListener = this.viewSourceProgressListener;
|
|
let referrerPolicy = Components.interfaces.nsIHttpChannel.REFERRER_POLICY_NO_REFERRER;
|
|
webBrowserPersist.savePrivacyAwareURI(uri, null, null, referrerPolicy, null, null, file, data.isPrivate);
|
|
|
|
let helperService = Components.classes["@mozilla.org/uriloader/external-helper-app-service;1"]
|
|
.getService(Components.interfaces.nsPIExternalAppLauncher);
|
|
if (data.isPrivate) {
|
|
// register the file to be deleted when possible
|
|
helperService.deleteTemporaryPrivateFileWhenPossible(file);
|
|
} else {
|
|
// register the file to be deleted on app exit
|
|
helperService.deleteTemporaryFileOnExit(file);
|
|
}
|
|
} else {
|
|
// we'll use nsIWebPageDescriptor to get the source because it may
|
|
// not have to refetch the file from the server
|
|
// XXXbz this is so broken... This code doesn't set up this docshell
|
|
// at all correctly; if somehow the view-source stuff managed to
|
|
// execute script we'd be in big trouble here, I suspect.
|
|
var webShell = Components.classes["@mozilla.org/docshell;1"].createInstance();
|
|
webShell.QueryInterface(Components.interfaces.nsIBaseWindow).create();
|
|
this.viewSourceProgressListener.webShell = webShell;
|
|
var progress = webShell.QueryInterface(this.mnsIWebProgress);
|
|
progress.addProgressListener(this.viewSourceProgressListener,
|
|
this.mnsIWebProgress.NOTIFY_STATE_DOCUMENT);
|
|
var pageLoader = webShell.QueryInterface(this.mnsIWebPageDescriptor);
|
|
pageLoader.loadPage(data.pageDescriptor, this.mnsIWebPageDescriptor.DISPLAY_AS_SOURCE);
|
|
}
|
|
}
|
|
} catch (ex) {
|
|
// we failed loading it with the external editor.
|
|
Components.utils.reportError(ex);
|
|
this.handleCallBack(aCallBack, false, data);
|
|
return;
|
|
}
|
|
},
|
|
|
|
// Default callback - opens the internal viewer if the external editor failed
|
|
internalViewerFallback: function(result, data)
|
|
{
|
|
if (!result) {
|
|
this._openInInternalViewer(data.url, data.pageDescriptor, data.doc, data.lineNumber);
|
|
}
|
|
},
|
|
|
|
// Calls the callback, keeping in mind undefined or null values.
|
|
handleCallBack: function(aCallBack, result, data)
|
|
{
|
|
Services.telemetry
|
|
.getHistogramById("VIEW_SOURCE_EXTERNAL_RESULT_BOOLEAN")
|
|
.add(result);
|
|
// if callback is undefined, default to the internal viewer
|
|
if (aCallBack === undefined) {
|
|
this.internalViewerFallback(result, data);
|
|
} else if (aCallBack) {
|
|
aCallBack(result, data);
|
|
}
|
|
},
|
|
|
|
// Returns nsIProcess of the external view source editor or null
|
|
getExternalViewSourceEditor: function()
|
|
{
|
|
try {
|
|
let viewSourceAppPath =
|
|
Components.classes["@mozilla.org/preferences-service;1"]
|
|
.getService(Components.interfaces.nsIPrefBranch)
|
|
.getComplexValue("view_source.editor.path",
|
|
Components.interfaces.nsIFile);
|
|
let editor = Components.classes['@mozilla.org/process/util;1']
|
|
.createInstance(Components.interfaces.nsIProcess);
|
|
editor.init(viewSourceAppPath);
|
|
|
|
return editor;
|
|
}
|
|
catch (ex) {
|
|
Components.utils.reportError(ex);
|
|
}
|
|
|
|
return null;
|
|
},
|
|
|
|
viewSourceProgressListener: {
|
|
|
|
mnsIWebProgressListener: Components.interfaces.nsIWebProgressListener,
|
|
|
|
QueryInterface: function(aIID) {
|
|
if (aIID.equals(this.mnsIWebProgressListener) ||
|
|
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
|
|
aIID.equals(Components.interfaces.nsISupports))
|
|
return this;
|
|
throw Components.results.NS_NOINTERFACE;
|
|
},
|
|
|
|
destroy: function() {
|
|
if (this.webShell) {
|
|
this.webShell.QueryInterface(Components.interfaces.nsIBaseWindow).destroy();
|
|
}
|
|
this.webShell = null;
|
|
this.editor = null;
|
|
this.callBack = null;
|
|
this.data = null;
|
|
this.file = null;
|
|
},
|
|
|
|
// This listener is used both for tracking the progress of an HTML parse
|
|
// in one case and for tracking the progress of nsIWebBrowserPersist in
|
|
// another case.
|
|
onStateChange: function(aProgress, aRequest, aFlag, aStatus) {
|
|
// once it's done loading...
|
|
if ((aFlag & this.mnsIWebProgressListener.STATE_STOP) && aStatus == 0) {
|
|
if (!this.webShell) {
|
|
// We aren't waiting for the parser. Instead, we are waiting for
|
|
// an nsIWebBrowserPersist.
|
|
this.onContentLoaded();
|
|
return 0;
|
|
}
|
|
var webNavigation = this.webShell.QueryInterface(Components.interfaces.nsIWebNavigation);
|
|
if (webNavigation.document.readyState == "complete") {
|
|
// This branch is probably never taken. Including it for completeness.
|
|
this.onContentLoaded();
|
|
} else {
|
|
webNavigation.document.addEventListener("DOMContentLoaded",
|
|
this.onContentLoaded.bind(this));
|
|
}
|
|
}
|
|
return 0;
|
|
},
|
|
|
|
onContentLoaded: function() {
|
|
// The progress listener may call this multiple times, so be sure we only
|
|
// run once.
|
|
if (this.contentLoaded) {
|
|
return;
|
|
}
|
|
try {
|
|
if (!this.file) {
|
|
// it's not saved to file yet, it's in the webshell
|
|
|
|
// get a temporary filename using the attributes from the data object that
|
|
// openInExternalEditor gave us
|
|
this.file = gViewSourceUtils.getTemporaryFile(this.data.uri, this.data.doc,
|
|
this.data.doc.contentType);
|
|
|
|
// we have to convert from the source charset.
|
|
var webNavigation = this.webShell.QueryInterface(Components.interfaces.nsIWebNavigation);
|
|
var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
|
|
.createInstance(Components.interfaces.nsIFileOutputStream);
|
|
foStream.init(this.file, 0x02 | 0x08 | 0x20, -1, 0); // write | create | truncate
|
|
var coStream = Components.classes["@mozilla.org/intl/converter-output-stream;1"]
|
|
.createInstance(Components.interfaces.nsIConverterOutputStream);
|
|
coStream.init(foStream, this.data.doc.characterSet, 0, null);
|
|
|
|
// write the source to the file
|
|
coStream.writeString(webNavigation.document.body.textContent);
|
|
|
|
// clean up
|
|
coStream.close();
|
|
foStream.close();
|
|
|
|
let helperService = Components.classes["@mozilla.org/uriloader/external-helper-app-service;1"]
|
|
.getService(Components.interfaces.nsPIExternalAppLauncher);
|
|
if (this.data.isPrivate) {
|
|
// register the file to be deleted when possible
|
|
helperService.deleteTemporaryPrivateFileWhenPossible(this.file);
|
|
} else {
|
|
// register the file to be deleted on app exit
|
|
helperService.deleteTemporaryFileOnExit(this.file);
|
|
}
|
|
}
|
|
|
|
var editorArgs = gViewSourceUtils.buildEditorArgs(this.file.path,
|
|
this.data.lineNumber);
|
|
this.editor.runw(false, editorArgs, editorArgs.length);
|
|
|
|
this.contentLoaded = true;
|
|
gViewSourceUtils.handleCallBack(this.callBack, true, this.data);
|
|
} catch (ex) {
|
|
// we failed loading it with the external editor.
|
|
Components.utils.reportError(ex);
|
|
gViewSourceUtils.handleCallBack(this.callBack, false, this.data);
|
|
} finally {
|
|
this.destroy();
|
|
}
|
|
},
|
|
|
|
onLocationChange: function() {return 0;},
|
|
onProgressChange: function() {return 0;},
|
|
onStatusChange: function() {return 0;},
|
|
onSecurityChange: function() {return 0;},
|
|
|
|
webShell: null,
|
|
editor: null,
|
|
callBack: null,
|
|
data: null,
|
|
file: null
|
|
},
|
|
|
|
// returns an nsIFile for the passed document in the system temp directory
|
|
getTemporaryFile: function(aURI, aDocument, aContentType) {
|
|
// include contentAreaUtils.js in our own context when we first need it
|
|
if (!this._caUtils) {
|
|
var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
|
|
.getService(Components.interfaces.mozIJSSubScriptLoader);
|
|
this._caUtils = {};
|
|
scriptLoader.loadSubScript("chrome://global/content/contentAreaUtils.js", this._caUtils);
|
|
}
|
|
|
|
var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
|
|
.getService(Components.interfaces.nsIProperties);
|
|
var tempFile = fileLocator.get("TmpD", Components.interfaces.nsIFile);
|
|
var fileName = this._caUtils.getDefaultFileName(null, aURI, aDocument, aContentType);
|
|
var extension = this._caUtils.getDefaultExtension(fileName, aURI, aContentType);
|
|
var leafName = this._caUtils.getNormalizedLeafName(fileName, extension);
|
|
tempFile.append(leafName);
|
|
return tempFile;
|
|
}
|
|
}
|