mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-07 08:18:41 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
331
toolkit/components/viewsource/ViewSourceBrowser.jsm
Normal file
331
toolkit/components/viewsource/ViewSourceBrowser.jsm
Normal file
|
|
@ -0,0 +1,331 @@
|
|||
// -*- 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/. */
|
||||
|
||||
const { utils: Cu, interfaces: Ci, classes: Cc } = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Deprecated",
|
||||
"resource://gre/modules/Deprecated.jsm");
|
||||
|
||||
const BUNDLE_URL = "chrome://global/locale/viewSource.properties";
|
||||
|
||||
const FRAME_SCRIPT = "chrome://global/content/viewSource-content.js";
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["ViewSourceBrowser"];
|
||||
|
||||
// Keep a set of browsers we've seen before, so we can load our frame script as
|
||||
// needed into any new ones.
|
||||
var gKnownBrowsers = new WeakSet();
|
||||
|
||||
/**
|
||||
* ViewSourceBrowser manages the view source <browser> from the chrome side.
|
||||
* It's companion frame script, viewSource-content.js, needs to be loaded as a
|
||||
* frame script into the browser being managed.
|
||||
*
|
||||
* For a view source window using viewSource.xul, the script viewSource.js in
|
||||
* the window extends an instance of this with more window specific functions.
|
||||
* The page script takes care of loading the companion frame script.
|
||||
*
|
||||
* For a view source tab (or some other non-window case), an instance of this is
|
||||
* created by viewSourceUtils.js to wrap the <browser>. The frame script will
|
||||
* be loaded by this module at construction time.
|
||||
*/
|
||||
this.ViewSourceBrowser = function ViewSourceBrowser(aBrowser) {
|
||||
this._browser = aBrowser;
|
||||
this.init();
|
||||
}
|
||||
|
||||
ViewSourceBrowser.prototype = {
|
||||
/**
|
||||
* The <browser> that will be displaying the view source content.
|
||||
*/
|
||||
get browser() {
|
||||
return this._browser;
|
||||
},
|
||||
|
||||
/**
|
||||
* Holds the value of the last line found via the "Go to line"
|
||||
* command, to pre-populate the prompt the next time it is
|
||||
* opened.
|
||||
*/
|
||||
lastLineFound: null,
|
||||
|
||||
/**
|
||||
* These are the messages that ViewSourceBrowser will listen for
|
||||
* from the frame script it injects. Any message names added here
|
||||
* will automatically have ViewSourceBrowser listen for those messages,
|
||||
* and remove the listeners on teardown.
|
||||
*/
|
||||
messages: [
|
||||
"ViewSource:PromptAndGoToLine",
|
||||
"ViewSource:GoToLine:Success",
|
||||
"ViewSource:GoToLine:Failed",
|
||||
"ViewSource:StoreWrapping",
|
||||
"ViewSource:StoreSyntaxHighlighting",
|
||||
],
|
||||
|
||||
/**
|
||||
* This should be called as soon as the script loads. When this function
|
||||
* executes, we can assume the DOM content has not yet loaded.
|
||||
*/
|
||||
init() {
|
||||
this.messages.forEach((msgName) => {
|
||||
this.mm.addMessageListener(msgName, this);
|
||||
});
|
||||
|
||||
// If we have a known <browser> already, load the frame script here. This
|
||||
// is not true for the window case, as the element does not exist until the
|
||||
// XUL document loads. For that case, the frame script is loaded by
|
||||
// viewSource.js.
|
||||
if (this._browser) {
|
||||
this.loadFrameScript();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* This should be called when the window is closing. This function should
|
||||
* clean up event and message listeners.
|
||||
*/
|
||||
uninit() {
|
||||
this.messages.forEach((msgName) => {
|
||||
this.mm.removeMessageListener(msgName, this);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* For a new browser we've not seen before, load the frame script.
|
||||
*/
|
||||
loadFrameScript() {
|
||||
if (!gKnownBrowsers.has(this.browser)) {
|
||||
gKnownBrowsers.add(this.browser);
|
||||
this.mm.loadFrameScript(FRAME_SCRIPT, false);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Anything added to the messages array will get handled here, and should
|
||||
* get dispatched to a specific function for the message name.
|
||||
*/
|
||||
receiveMessage(message) {
|
||||
let data = message.data;
|
||||
|
||||
switch (message.name) {
|
||||
case "ViewSource:PromptAndGoToLine":
|
||||
this.promptAndGoToLine();
|
||||
break;
|
||||
case "ViewSource:GoToLine:Success":
|
||||
this.onGoToLineSuccess(data.lineNumber);
|
||||
break;
|
||||
case "ViewSource:GoToLine:Failed":
|
||||
this.onGoToLineFailed();
|
||||
break;
|
||||
case "ViewSource:StoreWrapping":
|
||||
this.storeWrapping(data.state);
|
||||
break;
|
||||
case "ViewSource:StoreSyntaxHighlighting":
|
||||
this.storeSyntaxHighlighting(data.state);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Getter for the message manager of the view source browser.
|
||||
*/
|
||||
get mm() {
|
||||
return this.browser.messageManager;
|
||||
},
|
||||
|
||||
/**
|
||||
* Send a message to the view source browser.
|
||||
*/
|
||||
sendAsyncMessage(...args) {
|
||||
this.browser.messageManager.sendAsyncMessage(...args);
|
||||
},
|
||||
|
||||
/**
|
||||
* A getter for the view source string bundle.
|
||||
*/
|
||||
get bundle() {
|
||||
if (this._bundle) {
|
||||
return this._bundle;
|
||||
}
|
||||
return this._bundle = Services.strings.createBundle(BUNDLE_URL);
|
||||
},
|
||||
|
||||
/**
|
||||
* Loads the source for a URL while applying some optional features if
|
||||
* enabled.
|
||||
*
|
||||
* For the viewSource.xul window, this is called by onXULLoaded above.
|
||||
* For view source in a specific browser, this is manually called after
|
||||
* this object is constructed.
|
||||
*
|
||||
* This takes a single object argument containing:
|
||||
*
|
||||
* URL (required):
|
||||
* A string URL for the page we'd like to view the source of.
|
||||
* browser:
|
||||
* The browser containing the document that we would like to view the
|
||||
* source of. This argument is optional if outerWindowID is not passed.
|
||||
* outerWindowID (optional):
|
||||
* The outerWindowID of the content window containing the document that
|
||||
* we want to view the source of. This is the only way of attempting to
|
||||
* load the source out of the network cache.
|
||||
* lineNumber (optional):
|
||||
* The line number to focus on once the source is loaded.
|
||||
*/
|
||||
loadViewSource({ URL, browser, outerWindowID, lineNumber }) {
|
||||
if (!URL) {
|
||||
throw new Error("Must supply a URL when opening view source.");
|
||||
}
|
||||
|
||||
if (browser) {
|
||||
this.browser.relatedBrowser = browser;
|
||||
|
||||
// If we're dealing with a remote browser, then the browser
|
||||
// for view source needs to be remote as well.
|
||||
this.updateBrowserRemoteness(browser.isRemoteBrowser);
|
||||
} else if (outerWindowID) {
|
||||
throw new Error("Must supply the browser if passing the outerWindowID");
|
||||
}
|
||||
|
||||
this.sendAsyncMessage("ViewSource:LoadSource",
|
||||
{ URL, outerWindowID, lineNumber });
|
||||
},
|
||||
|
||||
/**
|
||||
* Loads a view source selection showing the given view-source url and
|
||||
* highlight the selection.
|
||||
*
|
||||
* @param uri view-source uri to show
|
||||
* @param drawSelection true to highlight the selection
|
||||
* @param baseURI base URI of the original document
|
||||
*/
|
||||
loadViewSourceFromSelection(URL, drawSelection, baseURI) {
|
||||
this.sendAsyncMessage("ViewSource:LoadSourceWithSelection",
|
||||
{ URL, drawSelection, baseURI });
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the "remote" attribute of the view source browser. This
|
||||
* will remove the browser from the DOM, and then re-add it in the
|
||||
* same place it was taken from.
|
||||
*
|
||||
* @param shouldBeRemote
|
||||
* True if the browser should be made remote. If the browsers
|
||||
* remoteness already matches this value, this function does
|
||||
* nothing.
|
||||
*/
|
||||
updateBrowserRemoteness(shouldBeRemote) {
|
||||
if (this.browser.isRemoteBrowser != shouldBeRemote) {
|
||||
// In this base case, where we are handed a <browser> someone else is
|
||||
// managing, we don't know for sure that it's safe to toggle remoteness.
|
||||
// For view source in a window, this is overridden to actually do the
|
||||
// flip if needed.
|
||||
throw new Error("View source browser's remoteness mismatch");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Opens the "Go to line" prompt for a user to hop to a particular line
|
||||
* of the source code they're viewing. This will keep prompting until the
|
||||
* user either cancels out of the prompt, or enters a valid line number.
|
||||
*/
|
||||
promptAndGoToLine() {
|
||||
let input = { value: this.lastLineFound };
|
||||
let window = Services.wm.getMostRecentWindow(null);
|
||||
|
||||
let ok = Services.prompt.prompt(
|
||||
window,
|
||||
this.bundle.GetStringFromName("goToLineTitle"),
|
||||
this.bundle.GetStringFromName("goToLineText"),
|
||||
input,
|
||||
null,
|
||||
{value:0});
|
||||
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
let line = parseInt(input.value, 10);
|
||||
|
||||
if (!(line > 0)) {
|
||||
Services.prompt.alert(window,
|
||||
this.bundle.GetStringFromName("invalidInputTitle"),
|
||||
this.bundle.GetStringFromName("invalidInputText"));
|
||||
this.promptAndGoToLine();
|
||||
} else {
|
||||
this.goToLine(line);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Go to a particular line of the source code. This act is asynchronous.
|
||||
*
|
||||
* @param lineNumber
|
||||
* The line number to try to go to to.
|
||||
*/
|
||||
goToLine(lineNumber) {
|
||||
this.sendAsyncMessage("ViewSource:GoToLine", { lineNumber });
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when the frame script reports that a line was successfully gotten
|
||||
* to.
|
||||
*
|
||||
* @param lineNumber
|
||||
* The line number that we successfully got to.
|
||||
*/
|
||||
onGoToLineSuccess(lineNumber) {
|
||||
// We'll pre-populate the "Go to line" prompt with this value the next
|
||||
// time it comes up.
|
||||
this.lastLineFound = lineNumber;
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when the frame script reports that we failed to go to a particular
|
||||
* line. This informs the user that their selection was likely out of range,
|
||||
* and then reprompts the user to try again.
|
||||
*/
|
||||
onGoToLineFailed() {
|
||||
let window = Services.wm.getMostRecentWindow(null);
|
||||
Services.prompt.alert(window,
|
||||
this.bundle.GetStringFromName("outOfRangeTitle"),
|
||||
this.bundle.GetStringFromName("outOfRangeText"));
|
||||
this.promptAndGoToLine();
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the wrapping pref based on the child's current state.
|
||||
* @param state
|
||||
* Whether wrapping is currently enabled in the child.
|
||||
*/
|
||||
storeWrapping(state) {
|
||||
Services.prefs.setBoolPref("view_source.wrap_long_lines", state);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the syntax highlighting pref based on the child's current state.
|
||||
* @param state
|
||||
* Whether syntax highlighting is currently enabled in the child.
|
||||
*/
|
||||
storeSyntaxHighlighting(state) {
|
||||
Services.prefs.setBoolPref("view_source.syntax_highlight", state);
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper to decide if a URI maps to view source content.
|
||||
* @param uri
|
||||
* String containing the URI
|
||||
*/
|
||||
ViewSourceBrowser.isViewSource = function(uri) {
|
||||
return uri.startsWith("view-source:") ||
|
||||
(uri.startsWith("data:") && uri.includes("MathML"));
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue