Bug 1439021 - restore 'view source' by forking M-C code. r=me (fork-onky)

This commit is contained in:
Jorg K 2018-02-26 16:10:00 +01:00
Родитель b828ecb025
Коммит 21adc223e0
8 изменённых файлов: 1217 добавлений и 2 удалений

Просмотреть файл

@ -0,0 +1,7 @@
/* 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/. */
toolbar[printpreview="true"] {
-moz-binding: url("chrome://global/content/printPreviewBindings.xml#printpreviewtoolbar");
}

866
common/src/viewSource.js Normal file
Просмотреть файл

@ -0,0 +1,866 @@
// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
/* import-globals-from ../../../content/globalOverlay.js */
/* import-globals-from ../../printing/content/printUtils.js */
/* import-globals-from ../../../content/viewZoomOverlay.js */
/* import-globals-from ../../../content/contentAreaUtils.js */
/* 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/. */
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/ViewSourceBrowser.jsm");
ChromeUtils.defineModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
ChromeUtils.defineModuleGetter(this, "CharsetMenu",
"resource://gre/modules/CharsetMenu.jsm");
ChromeUtils.defineModuleGetter(this, "Deprecated",
"resource://gre/modules/Deprecated.jsm");
/* global gBrowser, gViewSourceBundle, gContextMenu */
[
["gBrowser", "content"],
["gViewSourceBundle", "viewSourceBundle"],
["gContextMenu", "viewSourceContextMenu"]
].forEach(function([name, id]) {
Object.defineProperty(window, name, {
configurable: true,
enumerable: true,
get() {
var element = document.getElementById(id);
if (!element)
return null;
delete window[name];
return window[name] = element;
},
});
});
/**
* ViewSourceChrome is the primary interface for interacting with
* the view source browser from a self-contained window. It extends
* ViewSourceBrowser with additional things needed inside the special window.
*
* It initializes itself on script load.
*/
function ViewSourceChrome() {
ViewSourceBrowser.call(this);
}
ViewSourceChrome.prototype = {
__proto__: ViewSourceBrowser.prototype,
/**
* The <browser> that will be displaying the view source content.
*/
get browser() {
return gBrowser;
},
/**
* The context menu, when opened from the content process, sends
* up a chunk of serialized data describing the items that the
* context menu is being opened on. This allows us to avoid using
* CPOWs.
*/
contextMenuData: {},
/**
* These are the messages that ViewSourceChrome will listen for
* from the frame script it injects. Any message names added here
* will automatically have ViewSourceChrome listen for those messages,
* and remove the listeners on teardown.
*/
messages: ViewSourceBrowser.prototype.messages.concat([
"ViewSource:SourceLoaded",
"ViewSource:SourceUnloaded",
"ViewSource:Close",
"ViewSource:OpenURL",
"ViewSource:ContextMenuOpening",
]),
/**
* This called via ViewSourceBrowser's constructor. 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.mm.loadFrameScript("chrome://global/content/viewSource-content.js", true);
this.shouldWrap = Services.prefs.getBoolPref("view_source.wrap_long_lines");
this.shouldHighlight =
Services.prefs.getBoolPref("view_source.syntax_highlight");
addEventListener("load", this);
addEventListener("unload", this);
addEventListener("AppCommand", this, true);
addEventListener("MozSwipeGesture", this, true);
ViewSourceBrowser.prototype.init.call(this);
},
/**
* This should be called when the window is closing. This function should
* clean up event and message listeners.
*/
uninit() {
ViewSourceBrowser.prototype.uninit.call(this);
// "load" event listener is removed in its handler, to
// ensure we only fire it once.
removeEventListener("unload", this);
removeEventListener("AppCommand", this, true);
removeEventListener("MozSwipeGesture", this, true);
gContextMenu.removeEventListener("popupshowing", this);
gContextMenu.removeEventListener("popuphidden", this);
Services.els.removeSystemEventListener(this.browser, "dragover", this,
true);
Services.els.removeSystemEventListener(this.browser, "drop", this, true);
},
/**
* 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) {
// Begin messages from super class
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;
// End messages from super class
case "ViewSource:SourceLoaded":
this.onSourceLoaded();
break;
case "ViewSource:SourceUnloaded":
this.onSourceUnloaded();
break;
case "ViewSource:Close":
this.close();
break;
case "ViewSource:OpenURL":
this.openURL(data.URL);
break;
case "ViewSource:ContextMenuOpening":
this.onContextMenuOpening(data.isLink, data.isEmail, data.href);
if (this.browser.isRemoteBrowser) {
this.openContextMenu(data.screenX, data.screenY);
}
break;
}
},
/**
* Any events should get handled here, and should get dispatched to
* a specific function for the event type.
*/
handleEvent(event) {
switch (event.type) {
case "unload":
this.uninit();
break;
case "load":
this.onXULLoaded();
break;
case "AppCommand":
this.onAppCommand(event);
break;
case "MozSwipeGesture":
this.onSwipeGesture(event);
break;
case "popupshowing":
this.onContextMenuShowing(event);
break;
case "popuphidden":
this.onContextMenuHidden(event);
break;
case "dragover":
this.onDragOver(event);
break;
case "drop":
this.onDrop(event);
break;
}
},
/**
* Getter that returns whether or not the view source browser
* has history enabled on it.
*/
get historyEnabled() {
return !this.browser.hasAttribute("disablehistory");
},
/**
* Getter for the message manager used to communicate with the view source
* browser.
*
* In this window version of view source, we use the window message manager
* for loading scripts and listening for messages so that if we switch
* remoteness of the browser (which we might do if we're attempting to load
* the document source out of the network cache), we automatically re-load
* the frame script.
*/
get mm() {
return window.messageManager;
},
/**
* Getter for the nsIWebNavigation of the view source browser.
*/
get webNav() {
return this.browser.webNavigation;
},
/**
* Send the browser forward in its history.
*/
goForward() {
this.browser.goForward();
},
/**
* Send the browser backward in its history.
*/
goBack() {
this.browser.goBack();
},
/**
* This should be called once when the DOM has finished loading. Here we
* set the state of various menu items, and add event listeners to
* DOM nodes.
*
* This is also the place where we handle any arguments that have been
* passed to viewSource.xul.
*
* Modern consumers should pass a single object argument to viewSource.xul:
*
* 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.
*
* The deprecated API has the opener pass in a number of arguments:
*
* arg[0] - URL string.
* arg[1] - Charset value string in the form 'charset=xxx'.
* arg[2] - Page descriptor from nsIWebPageDescriptor used to load content
* from the cache.
* arg[3] - Line number to go to.
* arg[4] - Boolean for whether charset was forced by the user
*/
onXULLoaded() {
// This handler should only ever run the first time the XUL is loaded.
removeEventListener("load", this);
let wrapMenuItem = document.getElementById("menu_wrapLongLines");
if (this.shouldWrap) {
wrapMenuItem.setAttribute("checked", "true");
}
let highlightMenuItem = document.getElementById("menu_highlightSyntax");
if (this.shouldHighlight) {
highlightMenuItem.setAttribute("checked", "true");
}
gContextMenu.addEventListener("popupshowing", this);
gContextMenu.addEventListener("popuphidden", this);
Services.els.addSystemEventListener(this.browser, "dragover", this, true);
Services.els.addSystemEventListener(this.browser, "drop", this, true);
if (!this.historyEnabled) {
// Disable the BACK and FORWARD commands and hide the related menu items.
let viewSourceNavigation = document.getElementById("viewSourceNavigation");
if (viewSourceNavigation) {
viewSourceNavigation.setAttribute("disabled", "true");
viewSourceNavigation.setAttribute("hidden", "true");
}
}
// We require the first argument to do any loading of source.
// otherwise, we're done.
if (!window.arguments[0]) {
return undefined;
}
if (typeof window.arguments[0] == "string") {
// We're using the deprecated API
return this._loadViewSourceDeprecated(window.arguments);
}
// We're using the modern API, which allows us to view the
// source of documents from out of process browsers.
let args = window.arguments[0];
// viewPartialSource.js will take care of loading the content in partial mode.
if (!args.partial) {
this.loadViewSource(args);
}
return undefined;
},
/**
* This is the deprecated API for viewSource.xul, for old-timer consumers.
* This API might eventually go away.
*/
_loadViewSourceDeprecated(aArguments) {
Deprecated.warning("The arguments you're passing to viewSource.xul " +
"are using an out-of-date API.",
"https://developer.mozilla.org/en-US/Add-ons/Code_snippets/View_Source_for_XUL_Applications");
// Parse the 'arguments' supplied with the dialog.
// arg[0] - URL string.
// arg[1] - Charset value in the form 'charset=xxx'.
// arg[2] - Page descriptor used to load content from the cache.
// arg[3] - Line number to go to.
// arg[4] - Whether charset was forced by the user
if (aArguments[2]) {
let pageDescriptor = aArguments[2];
if (Cu.isCrossProcessWrapper(pageDescriptor)) {
throw new Error("Cannot pass a CPOW as the page descriptor to viewSource.xul.");
}
}
if (this.browser.isRemoteBrowser) {
throw new Error("Deprecated view source API should not use a remote browser.");
}
let forcedCharSet;
if (aArguments[4] && aArguments[1].startsWith("charset=")) {
forcedCharSet = aArguments[1].split("=")[1];
}
this.sendAsyncMessage("ViewSource:LoadSourceDeprecated", {
URL: aArguments[0],
lineNumber: aArguments[3],
forcedCharSet,
}, {
pageDescriptor: aArguments[2],
});
},
/**
* Handler for the AppCommand event.
*
* @param event
* The AppCommand event being handled.
*/
onAppCommand(event) {
event.stopPropagation();
switch (event.command) {
case "Back":
this.goBack();
break;
case "Forward":
this.goForward();
break;
}
},
/**
* Handler for the MozSwipeGesture event.
*
* @param event
* The MozSwipeGesture event being handled.
*/
onSwipeGesture(event) {
event.stopPropagation();
switch (event.direction) {
case SimpleGestureEvent.DIRECTION_LEFT:
this.goBack();
break;
case SimpleGestureEvent.DIRECTION_RIGHT:
this.goForward();
break;
case SimpleGestureEvent.DIRECTION_UP:
goDoCommand("cmd_scrollTop");
break;
case SimpleGestureEvent.DIRECTION_DOWN:
goDoCommand("cmd_scrollBottom");
break;
}
},
/**
* Called as soon as the frame script reports that some source
* code has been loaded in the browser.
*/
onSourceLoaded() {
document.getElementById("cmd_goToLine").removeAttribute("disabled");
if (this.historyEnabled) {
this.updateCommands();
}
this.browser.focus();
},
/**
* Called as soon as the frame script reports that some source
* code has been unloaded from the browser.
*/
onSourceUnloaded() {
// Disable "go to line" while reloading due to e.g. change of charset
// or toggling of syntax highlighting.
document.getElementById("cmd_goToLine").setAttribute("disabled", "true");
},
/**
* Called by clicks on a menu populated by CharsetMenu.jsm to
* change the selected character set.
*
* @param event
* The click event on a character set menuitem.
*/
onSetCharacterSet(event) {
if (event.target.hasAttribute("charset")) {
let charset = event.target.getAttribute("charset");
// If we don't have history enabled, we have to do a reload in order to
// show the character set change. See bug 136322.
this.sendAsyncMessage("ViewSource:SetCharacterSet", {
charset,
doPageLoad: this.historyEnabled,
});
if (!this.historyEnabled) {
this.browser
.reloadWithFlags(Ci.nsIWebNavigation.LOAD_FLAGS_CHARSET_CHANGE);
}
}
},
/**
* Called from the frame script when the context menu is about to
* open. This tells ViewSourceChrome things about the item that
* the context menu is being opened on. This should be called before
* the popupshowing event handler fires.
*/
onContextMenuOpening(isLink, isEmail, href) {
this.contextMenuData = { isLink, isEmail, href, isOpen: true };
},
/**
* Event handler for the popupshowing event on the context menu.
* This handler is responsible for setting the state on various
* menu items in the context menu, and reads values that were sent
* up from the frame script and stashed into this.contextMenuData.
*
* @param event
* The popupshowing event for the context menu.
*/
onContextMenuShowing(event) {
let copyLinkMenuItem = document.getElementById("context-copyLink");
copyLinkMenuItem.hidden = !this.contextMenuData.isLink;
let copyEmailMenuItem = document.getElementById("context-copyEmail");
copyEmailMenuItem.hidden = !this.contextMenuData.isEmail;
},
/**
* Called when the user chooses the "Copy Link" or "Copy Email"
* menu items in the context menu. Copies the relevant selection
* into the system clipboard.
*/
onContextMenuCopyLinkOrEmail() {
// It doesn't make any sense to call this if the context menu
// isn't open...
if (!this.contextMenuData.isOpen) {
return;
}
let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"]
.getService(Ci.nsIClipboardHelper);
clipboard.copyString(this.contextMenuData.href);
},
/**
* Called when the context menu closes, and invalidates any data
* that the frame script might have sent up about what the context
* menu was opened on.
*/
onContextMenuHidden(event) {
this.contextMenuData = {
isOpen: false,
};
},
/**
* Called when the user drags something over the content browser.
*/
onDragOver(event) {
// For drags that appear to be internal text (for example, tab drags),
// set the dropEffect to 'none'. This prevents the drop even if some
// other listener cancelled the event.
let types = event.dataTransfer.types;
if (types.includes("text/x-moz-text-internal") && !types.includes("text/plain")) {
event.dataTransfer.dropEffect = "none";
event.stopPropagation();
event.preventDefault();
}
if (Services.droppedLinkHandler.canDropLink(event, false)) {
event.preventDefault();
}
},
/**
* Called twhen the user drops something onto the content browser.
*/
onDrop(event) {
if (event.defaultPrevented)
return;
let name = { };
let uri;
try {
// Pass true to prevent the dropping of javascript:/data: URIs
uri = Services.droppedLinkHandler.dropLink(event, name, true);
} catch (e) {
return;
}
if (uri) {
this.loadURL(uri);
}
},
/**
* For remote browsers, the contextmenu event is received in the
* content process, and a message is sent up from the frame script
* to ViewSourceChrome, but then it stops. The event does not bubble
* up to the point that the popup is opened in the parent process.
* ViewSourceChrome is responsible for opening up the context menu in
* that case. This is called when we receive the contextmenu message
* from the child, and we know that the browser is currently remote.
*
* @param screenX
* The screenX coordinate to open the popup at.
* @param screenY
* The screenY coordinate to open the popup at.
*/
openContextMenu(screenX, screenY) {
gContextMenu.openPopupAtScreen(screenX, screenY, true);
},
/**
* Loads the source of a URL. This will probably end up hitting the
* network.
*
* @param URL
* A URL string to be opened in the view source browser.
*/
loadURL(URL) {
this.sendAsyncMessage("ViewSource:LoadSource", { URL });
},
/**
* Updates any commands that are dependant on command broadcasters.
*/
updateCommands() {
let backBroadcaster = document.getElementById("Browser:Back");
let forwardBroadcaster = document.getElementById("Browser:Forward");
if (this.webNav.canGoBack) {
backBroadcaster.removeAttribute("disabled");
} else {
backBroadcaster.setAttribute("disabled", "true");
}
if (this.webNav.canGoForward) {
forwardBroadcaster.removeAttribute("disabled");
} else {
forwardBroadcaster.setAttribute("disabled", "true");
}
},
/**
* Reloads the browser, bypassing the network cache.
*/
reload() {
this.browser.reloadWithFlags(Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY |
Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE);
},
/**
* Closes the view source window.
*/
close() {
window.close();
},
/**
* Called when the user clicks on the "Wrap Long Lines" menu item.
*/
toggleWrapping() {
this.shouldWrap = !this.shouldWrap;
this.sendAsyncMessage("ViewSource:ToggleWrapping");
},
/**
* Called when the user clicks on the "Syntax Highlighting" menu item.
*/
toggleSyntaxHighlighting() {
this.shouldHighlight = !this.shouldHighlight;
this.sendAsyncMessage("ViewSource:ToggleSyntaxHighlighting");
},
/**
* 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.
* @param remoteType
* The type of remote browser process.
*/
updateBrowserRemoteness(shouldBeRemote, remoteType) {
if (this.browser.isRemoteBrowser == shouldBeRemote &&
this.browser.remoteType == remoteType) {
return;
}
let parentNode = this.browser.parentNode;
let nextSibling = this.browser.nextSibling;
// Removing and re-adding the browser from and to the DOM strips its XBL
// properties. Save and restore sameProcessAsFrameLoader. Note that when we
// restore sameProcessAsFrameLoader, there won't yet be a binding or
// setter. This works in conjunction with the hack in <xul:browser>'s
// constructor to re-get the weak reference to it.
let sameProcessAsFrameLoader = this.browser.sameProcessAsFrameLoader;
this.browser.remove();
if (shouldBeRemote) {
this.browser.setAttribute("remote", "true");
this.browser.setAttribute("remoteType", remoteType);
} else {
this.browser.removeAttribute("remote");
this.browser.removeAttribute("remoteType");
}
this.browser.sameProcessAsFrameLoader = sameProcessAsFrameLoader;
// If nextSibling was null, this will put the browser at
// the end of the list.
parentNode.insertBefore(this.browser, nextSibling);
if (shouldBeRemote) {
// We're going to send a message down to the remote browser
// to load the source content - however, in order for the
// contentWindowAsCPOW and contentDocumentAsCPOW values on
// the remote browser to be set, we must set up the
// RemoteWebProgress, which is lazily loaded. We only need
// contentWindowAsCPOW for the printing support, and this
// should go away once bug 1146454 is fixed, since we can
// then just pass the outerWindowID of the this.browser to
// PrintUtils.
this.browser.webProgress;
}
},
};
var viewSourceChrome = new ViewSourceChrome();
/**
* PrintUtils uses this to make Print Preview work.
*/
var PrintPreviewListener = {
_ppBrowser: null,
getPrintPreviewBrowser() {
if (!this._ppBrowser) {
this._ppBrowser = document.createElement("browser");
this._ppBrowser.setAttribute("flex", "1");
this._ppBrowser.setAttribute("type", "content");
}
if (gBrowser.isRemoteBrowser) {
this._ppBrowser.setAttribute("remote", "true");
} else {
this._ppBrowser.removeAttribute("remote");
}
let findBar = document.getElementById("FindToolbar");
document.getElementById("appcontent")
.insertBefore(this._ppBrowser, findBar);
return this._ppBrowser;
},
getSourceBrowser() {
return gBrowser;
},
getNavToolbox() {
return document.getElementById("appcontent");
},
onEnter() {
let toolbox = document.getElementById("viewSource-toolbox");
toolbox.hidden = true;
gBrowser.collapsed = true;
},
onExit() {
this._ppBrowser.remove();
gBrowser.collapsed = false;
document.getElementById("viewSource-toolbox").hidden = false;
},
activateBrowser(browser) {
browser.docShellIsActive = true;
},
};
// viewZoomOverlay.js uses this
function getBrowser() {
return gBrowser;
}
Object.defineProperty(this, "gPageLoader", {
configurable: true,
enumerable: true,
get() {
var webnav = viewSourceChrome.webNav;
if (!webnav)
return null;
delete this.gPageLoader;
this.gPageLoader = (webnav instanceof Ci.nsIWebPageDescriptor) ? webnav
: null;
return this.gPageLoader;
},
});
// Strips the |view-source:| for internalSave()
function ViewSourceSavePage() {
internalSave(gBrowser.currentURI.spec.replace(/^view-source:/i, ""),
null, null, null, null, null, "SaveLinkTitle",
null, null, gBrowser.contentDocumentAsCPOW, null,
gPageLoader);
}
// Below are old deprecated functions and variables left behind for
// compatibility reasons. These will be removed soon via bug 1159293.
Object.defineProperty(this, "gLastLineFound", {
configurable: true,
enumerable: true,
get() {
Deprecated.warning("gLastLineFound is deprecated - please use " +
"viewSourceChrome.lastLineFound instead.",
"https://developer.mozilla.org/en-US/Add-ons/Code_snippets/View_Source_for_XUL_Applications");
return viewSourceChrome.lastLineFound;
},
});
function onLoadViewSource() {
Deprecated.warning("onLoadViewSource() is deprecated - please use " +
"viewSourceChrome.onXULLoaded() instead.",
"https://developer.mozilla.org/en-US/Add-ons/Code_snippets/View_Source_for_XUL_Applications");
viewSourceChrome.onXULLoaded();
}
function isHistoryEnabled() {
Deprecated.warning("isHistoryEnabled() is deprecated - please use " +
"viewSourceChrome.historyEnabled instead.",
"https://developer.mozilla.org/en-US/Add-ons/Code_snippets/View_Source_for_XUL_Applications");
return viewSourceChrome.historyEnabled;
}
function ViewSourceClose() {
Deprecated.warning("ViewSourceClose() is deprecated - please use " +
"viewSourceChrome.close() instead.",
"https://developer.mozilla.org/en-US/Add-ons/Code_snippets/View_Source_for_XUL_Applications");
viewSourceChrome.close();
}
function ViewSourceReload() {
Deprecated.warning("ViewSourceReload() is deprecated - please use " +
"viewSourceChrome.reload() instead.",
"https://developer.mozilla.org/en-US/Add-ons/Code_snippets/View_Source_for_XUL_Applications");
viewSourceChrome.reload();
}
function getWebNavigation() {
Deprecated.warning("getWebNavigation() is deprecated - please use " +
"viewSourceChrome.webNav instead.",
"https://developer.mozilla.org/en-US/Add-ons/Code_snippets/View_Source_for_XUL_Applications");
// The original implementation returned null if anything threw during
// the getting of the webNavigation.
try {
return viewSourceChrome.webNav;
} catch (e) {
return null;
}
}
function viewSource(url) {
Deprecated.warning("viewSource() is deprecated - please use " +
"viewSourceChrome.loadURL() instead.",
"https://developer.mozilla.org/en-US/Add-ons/Code_snippets/View_Source_for_XUL_Applications");
viewSourceChrome.loadURL(url);
}
function ViewSourceGoToLine() {
Deprecated.warning("ViewSourceGoToLine() is deprecated - please use " +
"viewSourceChrome.promptAndGoToLine() instead.",
"https://developer.mozilla.org/en-US/Add-ons/Code_snippets/View_Source_for_XUL_Applications");
viewSourceChrome.promptAndGoToLine();
}
function goToLine(line) {
Deprecated.warning("goToLine() is deprecated - please use " +
"viewSourceChrome.goToLine() instead.",
"https://developer.mozilla.org/en-US/Add-ons/Code_snippets/View_Source_for_XUL_Applications");
viewSourceChrome.goToLine(line);
}
function BrowserForward(aEvent) {
Deprecated.warning("BrowserForward() is deprecated - please use " +
"viewSourceChrome.goForward() instead.",
"https://developer.mozilla.org/en-US/Add-ons/Code_snippets/View_Source_for_XUL_Applications");
viewSourceChrome.goForward();
}
function BrowserBack(aEvent) {
Deprecated.warning("BrowserBack() is deprecated - please use " +
"viewSourceChrome.goBack() instead.",
"https://developer.mozilla.org/en-US/Add-ons/Code_snippets/View_Source_for_XUL_Applications");
viewSourceChrome.goBack();
}
function UpdateBackForwardCommands() {
Deprecated.warning("UpdateBackForwardCommands() is deprecated - please use " +
"viewSourceChrome.updateCommands() instead.",
"https://developer.mozilla.org/en-US/Add-ons/Code_snippets/View_Source_for_XUL_Applications");
viewSourceChrome.updateCommands();
}

229
common/src/viewSource.xul Normal file
Просмотреть файл

@ -0,0 +1,229 @@
<?xml version="1.0"?>
# -*- Mode: HTML -*-
# 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/.
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://messenger/content/viewSource.css" type="text/css"?>
<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
<!DOCTYPE window [
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
%brandDTD;
<!ENTITY % sourceDTD SYSTEM "chrome://messenger/locale/viewSource.dtd" >
%sourceDTD;
]>
<window id="viewSource"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
contenttitlesetting="true"
title="&mainWindow.title;"
titlemodifier="&mainWindow.titlemodifier;"
titlepreface="&mainWindow.preface;"
titlemenuseparator ="&mainWindow.titlemodifierseparator;"
windowtype="navigator:view-source"
width="640" height="480"
screenX="10" screenY="10"
persist="screenX screenY width height sizemode">
<script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
<script type="application/javascript" src="chrome://global/content/printUtils.js"/>
<script type="application/javascript" src="chrome://messenger/content/viewSource.js"/>
<script type="application/javascript" src="chrome://global/content/viewZoomOverlay.js"/>
<script type="application/javascript" src="chrome://global/content/contentAreaUtils.js"/>
<stringbundle id="viewSourceBundle" src="chrome://messenger/locale/viewSource.properties"/>
<command id="cmd_savePage" oncommand="ViewSourceSavePage();"/>
<command id="cmd_print" oncommand="PrintUtils.printWindow(gBrowser.outerWindowID, gBrowser);"/>
<command id="cmd_printpreview" oncommand="PrintUtils.printPreview(PrintPreviewListener);"/>
<command id="cmd_pagesetup" oncommand="PrintUtils.showPageSetup();"/>
<command id="cmd_close" oncommand="window.close();"/>
<commandset id="editMenuCommands"/>
<command id="cmd_find"
oncommand="document.getElementById('FindToolbar').onFindCommand();"/>
<command id="cmd_findAgain"
oncommand="document.getElementById('FindToolbar').onFindAgainCommand(false);"/>
<command id="cmd_findPrevious"
oncommand="document.getElementById('FindToolbar').onFindAgainCommand(true);"/>
#ifdef XP_MACOSX
<command id="cmd_findSelection"
oncommand="document.getElementById('FindToolbar').onFindSelectionCommand();"/>
#endif
<command id="cmd_reload" oncommand="viewSourceChrome.reload();"/>
<command id="cmd_goToLine" oncommand="viewSourceChrome.promptAndGoToLine();" disabled="true"/>
<command id="cmd_highlightSyntax" oncommand="viewSourceChrome.toggleSyntaxHighlighting();"/>
<command id="cmd_wrapLongLines" oncommand="viewSourceChrome.toggleWrapping();"/>
<command id="cmd_textZoomReduce" oncommand="ZoomManager.reduce();"/>
<command id="cmd_textZoomEnlarge" oncommand="ZoomManager.enlarge();"/>
<command id="cmd_textZoomReset" oncommand="ZoomManager.reset();"/>
<command id="Browser:Back" oncommand="viewSourceChrome.goBack()" observes="viewSourceNavigation"/>
<command id="Browser:Forward" oncommand="viewSourceChrome.goForward()" observes="viewSourceNavigation"/>
<broadcaster id="viewSourceNavigation"/>
<keyset id="editMenuKeys"/>
<keyset id="viewSourceKeys">
<key id="key_savePage" key="&savePageCmd.commandkey;" modifiers="accel" command="cmd_savePage"/>
<key id="key_print" key="&printCmd.commandkey;" modifiers="accel" command="cmd_print"/>
<key id="key_close" key="&closeCmd.commandkey;" modifiers="accel" command="cmd_close"/>
<key id="key_goToLine" key="&goToLineCmd.commandkey;" command="cmd_goToLine" modifiers="accel"/>
<key id="key_textZoomEnlarge" key="&textEnlarge.commandkey;" command="cmd_textZoomEnlarge" modifiers="accel"/>
<key id="key_textZoomEnlarge2" key="&textEnlarge.commandkey2;" command="cmd_textZoomEnlarge" modifiers="accel"/>
<key id="key_textZoomEnlarge3" key="&textEnlarge.commandkey3;" command="cmd_textZoomEnlarge" modifiers="accel"/>
<key id="key_textZoomReduce" key="&textReduce.commandkey;" command="cmd_textZoomReduce" modifiers="accel"/>
<key id="key_textZoomReduce2" key="&textReduce.commandkey2;" command="cmd_textZoomReduce" modifiers="accel"/>
<key id="key_textZoomReset" key="&textReset.commandkey;" command="cmd_textZoomReset" modifiers="accel"/>
<key id="key_textZoomReset2" key="&textReset.commandkey2;" command="cmd_textZoomReset" modifiers="accel"/>
<key id="key_reload" key="&reloadCmd.commandkey;" command="cmd_reload" modifiers="accel"/>
<key key="&reloadCmd.commandkey;" command="cmd_reload" modifiers="accel,shift"/>
<key keycode="VK_F5" command="cmd_reload"/>
<key keycode="VK_F5" command="cmd_reload" modifiers="accel"/>
<key id="key_find" key="&findOnCmd.commandkey;" command="cmd_find" modifiers="accel"/>
<key id="key_findAgain" key="&findAgainCmd.commandkey;" command="cmd_findAgain" modifiers="accel"/>
<key id="key_findPrevious" key="&findAgainCmd.commandkey;" command="cmd_findPrevious" modifiers="accel,shift"/>
#ifdef XP_MACOSX
<key id="key_findSelection" key="&findSelectionCmd.commandkey;" command="cmd_findSelection" modifiers="accel"/>
#endif
<key keycode="&findAgainCmd.commandkey2;" command="cmd_findAgain"/>
<key keycode="&findAgainCmd.commandkey2;" command="cmd_findPrevious" modifiers="shift"/>
<key keycode="VK_BACK" command="Browser:Back"/>
<key keycode="VK_BACK" command="Browser:Forward" modifiers="shift"/>
#ifndef XP_MACOSX
<key id="goBackKb" keycode="VK_LEFT" command="Browser:Back" modifiers="alt"/>
<key id="goForwardKb" keycode="VK_RIGHT" command="Browser:Forward" modifiers="alt"/>
#else
<key id="goBackKb" keycode="VK_LEFT" command="Browser:Back" modifiers="accel" />
<key id="goForwardKb" keycode="VK_RIGHT" command="Browser:Forward" modifiers="accel" />
#endif
#ifdef XP_UNIX
<key id="goBackKb2" key="&goBackCmd.commandKey;" command="Browser:Back" modifiers="accel"/>
<key id="goForwardKb2" key="&goForwardCmd.commandKey;" command="Browser:Forward" modifiers="accel"/>
#endif
</keyset>
<tooltip id="aHTMLTooltip" page="true"/>
<menupopup id="viewSourceContextMenu">
<menuitem id="context-back"
label="&backCmd.label;"
accesskey="&backCmd.accesskey;"
command="Browser:Back"
observes="viewSourceNavigation"/>
<menuitem id="context-forward"
label="&forwardCmd.label;"
accesskey="&forwardCmd.accesskey;"
command="Browser:Forward"
observes="viewSourceNavigation"/>
<menuseparator observes="viewSourceNavigation"/>
<menuitem id="cMenu_findAgain"/>
<menuseparator/>
<menuitem id="cMenu_copy"/>
<menuitem id="context-copyLink"
label="&copyLinkCmd.label;"
accesskey="&copyLinkCmd.accesskey;"
oncommand="viewSourceChrome.onContextMenuCopyLinkOrEmail();"/>
<menuitem id="context-copyEmail"
label="&copyEmailCmd.label;"
accesskey="&copyEmailCmd.accesskey;"
oncommand="viewSourceChrome.onContextMenuCopyLinkOrEmail();"/>
<menuseparator/>
<menuitem id="cMenu_selectAll"/>
</menupopup>
<!-- Menu -->
<toolbox id="viewSource-toolbox">
<menubar id="viewSource-main-menubar">
<menu id="menu_file" label="&fileMenu.label;" accesskey="&fileMenu.accesskey;">
<menupopup id="menu_FilePopup">
<menuitem key="key_savePage" command="cmd_savePage" id="menu_savePage"
label="&savePageCmd.label;" accesskey="&savePageCmd.accesskey;"/>
<menuitem command="cmd_pagesetup" id="menu_pageSetup"
label="&pageSetupCmd.label;" accesskey="&pageSetupCmd.accesskey;"/>
#ifndef XP_MACOSX
<menuitem command="cmd_printpreview" id="menu_printPreview"
label="&printPreviewCmd.label;" accesskey="&printPreviewCmd.accesskey;"/>
#endif
<menuitem key="key_print" command="cmd_print" id="menu_print"
label="&printCmd.label;" accesskey="&printCmd.accesskey;"/>
<menuseparator/>
<menuitem key="key_close" command="cmd_close" id="menu_close"
label="&closeCmd.label;" accesskey="&closeCmd.accesskey;"/>
</menupopup>
</menu>
<menu id="menu_edit">
<menupopup id="editmenu-popup">
<menuitem id="menu_undo"/>
<menuitem id="menu_redo"/>
<menuseparator/>
<menuitem id="menu_cut"/>
<menuitem id="menu_copy"/>
<menuitem id="menu_paste"/>
<menuitem id="menu_delete"/>
<menuseparator/>
<menuitem id="menu_selectAll"/>
<menuseparator/>
<menuitem id="menu_find"/>
<menuitem id="menu_findAgain"/>
<menuseparator/>
<menuitem id="menu_goToLine" key="key_goToLine" command="cmd_goToLine"
label="&goToLineCmd.label;" accesskey="&goToLineCmd.accesskey;"/>
</menupopup>
</menu>
<menu id="menu_view" label="&viewMenu.label;" accesskey="&viewMenu.accesskey;">
<menupopup id="viewmenu-popup">
<menuitem id="menu_reload" command="cmd_reload" accesskey="&reloadCmd.accesskey;"
label="&reloadCmd.label;" key="key_reload"/>
<menuseparator />
<menu id="viewTextZoomMenu" label="&menu_textSize.label;" accesskey="&menu_textSize.accesskey;">
<menupopup>
<menuitem id="menu_textEnlarge" command="cmd_textZoomEnlarge"
label="&menu_textEnlarge.label;" accesskey="&menu_textEnlarge.accesskey;"
key="key_textZoomEnlarge"/>
<menuitem id="menu_textReduce" command="cmd_textZoomReduce"
label="&menu_textReduce.label;" accesskey="&menu_textReduce.accesskey;"
key="key_textZoomReduce"/>
<menuseparator/>
<menuitem id="menu_textReset" command="cmd_textZoomReset"
label="&menu_textReset.label;" accesskey="&menu_textReset.accesskey;"
key="key_textZoomReset"/>
</menupopup>
</menu>
<!-- Charset Menu -->
<menu id="charsetMenu"
label="&charsetMenu2.label;"
accesskey="&charsetMenu2.accesskey;"
oncommand="viewSourceChrome.onSetCharacterSet(event);"
onpopupshowing="CharsetMenu.build(event.target);
CharsetMenu.update(event.target, content.document.characterSet);">
<menupopup/>
</menu>
<menuseparator/>
<menuitem id="menu_wrapLongLines" type="checkbox" command="cmd_wrapLongLines"
label="&menu_wrapLongLines.title;" accesskey="&menu_wrapLongLines.accesskey;"/>
<menuitem type="checkbox" id="menu_highlightSyntax" command="cmd_highlightSyntax"
label="&menu_highlightSyntax.label;" accesskey="&menu_highlightSyntax.accesskey;"/>
</menupopup>
</menu>
</menubar>
</toolbox>
<vbox id="appcontent" flex="1">
<browser id="content" type="content" name="content" src="about:blank" flex="1"
primary="true"
context="viewSourceContextMenu" showcaret="true" tooltip="aHTMLTooltip" />
<findbar id="FindToolbar" browserid="content"/>
</vbox>
</window>

Просмотреть файл

@ -508,7 +508,7 @@ function ViewPageSource(messages)
// Strip out the message-display parameter to ensure that attached emails
// display the message source, not the processed HTML.
url = url.replace(/type=application\/x-message-display&/, "");
window.openDialog("chrome://global/content/viewSource.xul",
window.openDialog("chrome://messenger/content/viewSource.xul",
"_blank", "all,dialog=no",
{URL: url, browser: browser,
outerWindowID: browser.outerWindowID});

Просмотреть файл

@ -5,7 +5,7 @@ messenger.jar:
% content messenger %content/messenger/
% override chrome://global/content/nsDragAndDrop.js chrome://messenger/content/nsDragAndDrop.js
% override chrome://messagebody/skin/messageBody.css chrome://messenger/skin/messageBody.css
% overlay chrome://global/content/viewSource.xul chrome://messenger/content/viewSourceOverlay.xul
% overlay chrome://messenger/content/viewSource.xul chrome://messenger/content/viewSourceOverlay.xul
% overlay chrome://global/content/config.xul chrome://messenger/content/configEditorOverlay.xul
% overlay chrome://editor/content/EdSpellCheck.xul chrome://messenger/content/EdSpellCheckOverlay.xul
% overlay about:addons chrome://messenger/content/extensionsOverlay.xul
@ -40,6 +40,9 @@ messenger.jar:
content/messenger/customizeToolbar.css (../../common/src/customizeToolbar.css)
content/messenger/customizeToolbar.js (../../common/src/customizeToolbar.js)
* content/messenger/customizeToolbar.xul (../../common/src/customizeToolbar.xul)
content/messenger/viewSource.css (../../common/src/viewSource.css)
content/messenger/viewSource.js (../../common/src/viewSource.js)
* content/messenger/viewSource.xul (../../common/src/viewSource.xul)
* content/messenger/datetimepicker.xml (../../common/bindings/datetimepicker.xml)
content/messenger/generalBindings.xml (../../common/bindings/generalBindings.xml)
* content/messenger/toolbar.xml (../../common/bindings/toolbar.xml)

Просмотреть файл

@ -0,0 +1,91 @@
<!-- 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/. -->
<!-- extracted from content/viewSource.xul -->
<!-- LOCALIZATION NOTE (mainWindow.title) : DONT_TRANSLATE -->
<!ENTITY mainWindow.title "&brandFullName;">
<!-- LOCALIZATION NOTE (mainWindow.titlemodifier) : DONT_TRANSLATE -->
<!ENTITY mainWindow.titlemodifier "&brandFullName;">
<!-- LOCALIZATION NOTE (mainWindow.titlemodifierseparator) : DONT_TRANSLATE -->
<!ENTITY mainWindow.titlemodifierseparator " - ">
<!ENTITY mainWindow.preface "Source of: ">
<!ENTITY fileMenu.label "File">
<!ENTITY fileMenu.accesskey "F">
<!ENTITY savePageCmd.label "Save Page As…">
<!ENTITY savePageCmd.accesskey "A">
<!ENTITY savePageCmd.commandkey "S">
<!ENTITY pageSetupCmd.label "Page Setup…">
<!ENTITY pageSetupCmd.accesskey "u">
<!ENTITY printPreviewCmd.label "Print Preview">
<!ENTITY printPreviewCmd.accesskey "v">
<!ENTITY printCmd.label "Print…">
<!ENTITY printCmd.accesskey "P">
<!ENTITY printCmd.commandkey "P">
<!ENTITY closeCmd.label "Close">
<!ENTITY closeCmd.accesskey "C">
<!ENTITY closeCmd.commandkey "W">
<!-- LOCALIZATION NOTE :
textEnlarge.commandkey3, textReduce.commandkey2 and
textReset.commandkey2 are alternative acceleration keys for zoom.
If shift key is needed with your locale popular keyboard for them,
you can use these alternative items. Otherwise, their values should be empty. -->
<!ENTITY textEnlarge.commandkey "+">
<!ENTITY textEnlarge.commandkey2 "=">
<!ENTITY textEnlarge.commandkey3 "">
<!ENTITY textReduce.commandkey "-">
<!ENTITY textReduce.commandkey2 "">
<!ENTITY textReset.commandkey "0">
<!ENTITY textReset.commandkey2 "">
<!ENTITY goToLineCmd.label "Go to Line…">
<!ENTITY goToLineCmd.accesskey "G">
<!ENTITY goToLineCmd.commandkey "l">
<!ENTITY viewMenu.label "View">
<!ENTITY viewMenu.accesskey "V">
<!ENTITY reloadCmd.label "Reload">
<!ENTITY reloadCmd.accesskey "R">
<!ENTITY reloadCmd.commandkey "r">
<!ENTITY menu_wrapLongLines.title "Wrap Long Lines">
<!ENTITY menu_wrapLongLines.accesskey "W">
<!ENTITY menu_highlightSyntax.label "Syntax Highlighting">
<!ENTITY menu_highlightSyntax.accesskey "H">
<!ENTITY menu_textSize.label "Text Size">
<!ENTITY menu_textSize.accesskey "Z">
<!ENTITY menu_textEnlarge.label "Increase">
<!ENTITY menu_textEnlarge.accesskey "I">
<!ENTITY menu_textReduce.label "Decrease">
<!ENTITY menu_textReduce.accesskey "D">
<!ENTITY menu_textReset.label "Normal">
<!ENTITY menu_textReset.accesskey "N">
<!ENTITY findOnCmd.label "Find in This Page…">
<!ENTITY findOnCmd.accesskey "F">
<!ENTITY findOnCmd.commandkey "f">
<!ENTITY findAgainCmd.label "Find Again">
<!ENTITY findAgainCmd.accesskey "g">
<!ENTITY findAgainCmd.commandkey "g">
<!ENTITY findAgainCmd.commandkey2 "VK_F3">
<!ENTITY findSelectionCmd.commandkey "e">
<!ENTITY backCmd.label "Back">
<!ENTITY backCmd.accesskey "B">
<!ENTITY forwardCmd.label "Forward">
<!ENTITY forwardCmd.accesskey "F">
<!ENTITY goBackCmd.commandKey "[">
<!ENTITY goForwardCmd.commandKey "]">
<!ENTITY copyLinkCmd.label "Copy Link Location">
<!ENTITY copyLinkCmd.accesskey "L">
<!ENTITY copyEmailCmd.label "Copy Email Address">
<!ENTITY copyEmailCmd.accesskey "E">
<!-- Copied from charsetMenu.dtd -->
<!ENTITY charsetMenu2.label "Text Encoding">
<!ENTITY charsetMenu2.accesskey "c">

Просмотреть файл

@ -0,0 +1,17 @@
# 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/.
goToLineTitle = Go to line
goToLineText = Enter line number
invalidInputTitle = Invalid input
invalidInputText = The line number entered is invalid.
outOfRangeTitle = Line not found
outOfRangeText = The specified line was not found.
viewSelectionSourceTitle = DOM Source of Selection
viewMathMLSourceTitle = DOM Source of MathML
context_goToLine_label = Go to Line…
context_goToLine_accesskey = L
context_wrapLongLines_label = Wrap Long Lines
context_highlightSyntax_label = Syntax Highlighting

Просмотреть файл

@ -24,6 +24,8 @@
locale/@AB_CD@/messenger/charsetTitles.properties (%chrome/messenger/charsetTitles.properties)
locale/@AB_CD@/messenger/customizeToolbar.dtd (%chrome/messenger/customizeToolbar.dtd)
locale/@AB_CD@/messenger/customizeToolbar.properties (%chrome/messenger/customizeToolbar.properties)
locale/@AB_CD@/messenger/viewSource.dtd (%chrome/messenger/viewSource.dtd)
locale/@AB_CD@/messenger/viewSource.properties (%chrome/messenger/viewSource.properties)
locale/@AB_CD@/messenger/datetimepicker.dtd (%chrome/messenger/datetimepicker.dtd)
locale/@AB_CD@/messenger/systemIntegrationDialog.dtd (%chrome/messenger/systemIntegrationDialog.dtd)
locale/@AB_CD@/messenger/virtualFolderProperties.dtd (%chrome/messenger/virtualFolderProperties.dtd)