diff options
Diffstat (limited to '')
-rw-r--r-- | toolkit/actors/ViewSourcePageParent.sys.mjs | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/toolkit/actors/ViewSourcePageParent.sys.mjs b/toolkit/actors/ViewSourcePageParent.sys.mjs new file mode 100644 index 0000000000..cc45b248cc --- /dev/null +++ b/toolkit/actors/ViewSourcePageParent.sys.mjs @@ -0,0 +1,165 @@ +// -*- 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 BUNDLE_URL = "chrome://global/locale/viewSource.properties"; + +/** + * ViewSourcePageParent manages the view source <browser> from the chrome side. + */ +export class ViewSourcePageParent extends JSWindowActorParent { + constructor() { + super(); + + /** + * 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. + */ + this.lastLineFound = null; + } + + /** + * 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; + } + } + + /** + * A getter for the view source string bundle. + */ + get bundle() { + if (this._bundle) { + return this._bundle; + } + return (this._bundle = Services.strings.createBundle(BUNDLE_URL)); + } + + /** + * 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 child 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(); + } + + /** + * @return {boolean} the wrapping state + */ + queryIsWrapping() { + return this.sendQuery("ViewSource:IsWrapping"); + } + + /** + * @return {boolean} the syntax highlighting state + */ + queryIsSyntaxHighlighting() { + return this.sendQuery("ViewSource:IsSyntaxHighlighting"); + } + + /** + * 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); + } +} |