зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1691755 - Move view-source context menu items to nsContextMenu r=Gijs
Differential Revision: https://phabricator.services.mozilla.com/D104956
This commit is contained in:
Родитель
90f209f9d1
Коммит
b97e032178
|
@ -34,6 +34,15 @@
|
|||
</menugroup>
|
||||
<menuseparator id="context-sep-navigation"/>
|
||||
<menuseparator id="page-menu-separator"/>
|
||||
<menuitem id="context-viewsource-goToLine"
|
||||
oncommand="gViewSourceUtils.getPageActor(gContextMenu.browser).promptAndGoToLine()"/>
|
||||
<menuitem id="context-viewsource-wrapLongLines"
|
||||
type="checkbox"
|
||||
oncommand="gViewSourceUtils.getPageActor(gContextMenu.browser).sendAsyncMessage('ViewSource:ToggleWrapping');"/>
|
||||
<menuitem id="context-viewsource-highlightSyntax"
|
||||
type="checkbox"
|
||||
oncommand="gViewSourceUtils.getPageActor(gContextMenu.browser).sendAsyncMessage('ViewSource:ToggleSyntaxHighlighting');"/>
|
||||
<menuseparator id="context-sep-viewsource-commands"/>
|
||||
<menuitem id="spell-no-suggestions"
|
||||
disabled="true"
|
||||
label="&spellNoSuggestions.label;"/>
|
||||
|
|
|
@ -333,6 +333,7 @@ class nsContextMenu {
|
|||
this.initClickToPlayItems();
|
||||
this.initPasswordManagerItems();
|
||||
this.initSyncItems();
|
||||
this.initViewSourceItems();
|
||||
}
|
||||
|
||||
initPageMenuSeparator() {
|
||||
|
@ -1061,6 +1062,40 @@ class nsContextMenu {
|
|||
gSync.updateContentContextMenu(this);
|
||||
}
|
||||
|
||||
initViewSourceItems() {
|
||||
const getString = name => {
|
||||
const { bundle } = gViewSourceUtils.getPageActor(this.browser);
|
||||
return bundle.GetStringFromName(name);
|
||||
};
|
||||
const showViewSourceItem = (id, check, accesskey) => {
|
||||
const fullId = `context-viewsource-${id}`;
|
||||
this.showItem(fullId, onViewSource);
|
||||
if (!onViewSource) {
|
||||
return;
|
||||
}
|
||||
check().then(checked => this.setItemAttr(fullId, "checked", checked));
|
||||
this.setItemAttr(fullId, "label", getString(`context_${id}_label`));
|
||||
if (accesskey) {
|
||||
this.setItemAttr(
|
||||
fullId,
|
||||
"accesskey",
|
||||
getString(`context_${id}_accesskey`)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const onViewSource = this.browser.currentURI.schemeIs("view-source");
|
||||
|
||||
showViewSourceItem("goToLine", async () => false, true);
|
||||
showViewSourceItem("wrapLongLines", () =>
|
||||
gViewSourceUtils.getPageActor(this.browser).queryIsWrapping()
|
||||
);
|
||||
showViewSourceItem("highlightSyntax", () =>
|
||||
gViewSourceUtils.getPageActor(this.browser).queryIsSyntaxHighlighting()
|
||||
);
|
||||
this.showItem("context-sep-viewsource-commands", onViewSource);
|
||||
}
|
||||
|
||||
openPasswordManager() {
|
||||
LoginHelper.openPasswordManager(window, {
|
||||
entryPoint: "contextmenu",
|
||||
|
|
|
@ -13,7 +13,6 @@ var EXPORTED_SYMBOLS = ["ViewSourcePageChild"];
|
|||
|
||||
XPCOMUtils.defineLazyGlobalGetters(this, ["NodeFilter"]);
|
||||
|
||||
const NS_XHTML = "http://www.w3.org/1999/xhtml";
|
||||
const BUNDLE_URL = "chrome://global/locale/viewSource.properties";
|
||||
|
||||
// These are markers used to delimit the selection during processing. They
|
||||
|
@ -36,37 +35,6 @@ let gNeedsDrawSelection = false;
|
|||
*/
|
||||
let gInitialLineNumber = -1;
|
||||
|
||||
/**
|
||||
* In-page context menu items that are injected after page load.
|
||||
*/
|
||||
let gContextMenuItems = [
|
||||
{
|
||||
id: "goToLine",
|
||||
accesskey: true,
|
||||
handler(actor) {
|
||||
actor.sendAsyncMessage("ViewSource:PromptAndGoToLine");
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "wrapLongLines",
|
||||
get checked() {
|
||||
return Services.prefs.getBoolPref("view_source.wrap_long_lines");
|
||||
},
|
||||
handler(actor) {
|
||||
actor.toggleWrapping();
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "highlightSyntax",
|
||||
get checked() {
|
||||
return Services.prefs.getBoolPref("view_source.syntax_highlight");
|
||||
},
|
||||
handler(actor) {
|
||||
actor.toggleSyntaxHighlighting();
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
class ViewSourcePageChild extends JSWindowActorChild {
|
||||
constructor() {
|
||||
super();
|
||||
|
@ -85,9 +53,22 @@ class ViewSourcePageChild extends JSWindowActorChild {
|
|||
}
|
||||
|
||||
receiveMessage(msg) {
|
||||
if (msg.name == "ViewSource:GoToLine") {
|
||||
this.goToLine(msg.data.lineNumber);
|
||||
switch (msg.name) {
|
||||
case "ViewSource:GoToLine":
|
||||
this.goToLine(msg.data.lineNumber);
|
||||
break;
|
||||
case "ViewSource:IsWrapping":
|
||||
return this.isWrapping;
|
||||
case "ViewSource:IsSyntaxHighlighting":
|
||||
return this.isSyntaxHighlighting;
|
||||
case "ViewSource:ToggleWrapping":
|
||||
this.toggleWrapping();
|
||||
break;
|
||||
case "ViewSource:ToggleSyntaxHighlighting":
|
||||
this.toggleSyntaxHighlighting();
|
||||
break;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -128,20 +109,9 @@ class ViewSourcePageChild extends JSWindowActorChild {
|
|||
* This handler is for click events from:
|
||||
* * error page content, which can show up if the user attempts to view the
|
||||
* source of an attack page.
|
||||
* * in-page context menu actions
|
||||
*/
|
||||
onClick(event) {
|
||||
let target = event.originalTarget;
|
||||
// Check for content menu actions
|
||||
if (target.id) {
|
||||
gContextMenuItems.forEach(itemSpec => {
|
||||
if (itemSpec.id !== target.id) {
|
||||
return;
|
||||
}
|
||||
itemSpec.handler(this);
|
||||
event.stopPropagation();
|
||||
});
|
||||
}
|
||||
|
||||
// Don't trust synthetic events
|
||||
if (!event.isTrusted || event.target.localName != "button") {
|
||||
|
@ -181,10 +151,6 @@ class ViewSourcePageChild extends JSWindowActorChild {
|
|||
this.goToLine(gInitialLineNumber);
|
||||
gInitialLineNumber = -1;
|
||||
}
|
||||
|
||||
if (this.document.body) {
|
||||
this.injectContextMenu();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -380,6 +346,20 @@ class ViewSourcePageChild extends JSWindowActorChild {
|
|||
return found || "range" in result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {boolean} whether the "wrap" class exists on the document body.
|
||||
*/
|
||||
get isWrapping() {
|
||||
return this.document.body.classList.contains("wrap");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {boolean} whether the "highlight" class exists on the document body.
|
||||
*/
|
||||
get isSyntaxHighlighting() {
|
||||
return this.document.body.classList.contains("highlight");
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the "wrap" class on the document body, which sets whether
|
||||
* or not long lines are wrapped. Notifies parent to update the pref.
|
||||
|
@ -500,56 +480,4 @@ class ViewSourcePageChild extends JSWindowActorChild {
|
|||
findInst.findBackwards = findBackwards;
|
||||
findInst.searchString = searchString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add context menu items for view source specific actions.
|
||||
*/
|
||||
injectContextMenu() {
|
||||
let doc = this.document;
|
||||
|
||||
let menu = doc.createElementNS(NS_XHTML, "menu");
|
||||
menu.setAttribute("type", "context");
|
||||
menu.setAttribute("id", "actions");
|
||||
doc.body.appendChild(menu);
|
||||
doc.body.setAttribute("contextmenu", "actions");
|
||||
|
||||
gContextMenuItems.forEach(itemSpec => {
|
||||
let item = doc.createElementNS(NS_XHTML, "menuitem");
|
||||
item.setAttribute("id", itemSpec.id);
|
||||
let labelName = `context_${itemSpec.id}_label`;
|
||||
let label = this.bundle.GetStringFromName(labelName);
|
||||
item.setAttribute("label", label);
|
||||
if ("checked" in itemSpec) {
|
||||
item.setAttribute("type", "checkbox");
|
||||
}
|
||||
if (itemSpec.accesskey) {
|
||||
let accesskeyName = `context_${itemSpec.id}_accesskey`;
|
||||
item.setAttribute(
|
||||
"accesskey",
|
||||
this.bundle.GetStringFromName(accesskeyName)
|
||||
);
|
||||
}
|
||||
menu.appendChild(item);
|
||||
});
|
||||
|
||||
this.updateContextMenu();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update state of checkbox-style context menu items.
|
||||
*/
|
||||
updateContextMenu() {
|
||||
let doc = this.document;
|
||||
gContextMenuItems.forEach(itemSpec => {
|
||||
if (!("checked" in itemSpec)) {
|
||||
return;
|
||||
}
|
||||
let item = doc.getElementById(itemSpec.id);
|
||||
if (itemSpec.checked) {
|
||||
item.setAttribute("checked", true);
|
||||
} else {
|
||||
item.removeAttribute("checked");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,6 +139,20 @@ class ViewSourcePageParent extends JSWindowActorParent {
|
|||
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
|
||||
|
|
|
@ -30,6 +30,14 @@ var gViewSourceUtils = {
|
|||
return aBrowsingContext.currentWindowGlobal.getActor("ViewSource");
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the ViewSourcePage actor.
|
||||
* @param object An object with `browsingContext` field
|
||||
*/
|
||||
getPageActor({ browsingContext }) {
|
||||
return browsingContext.currentWindowGlobal.getActor("ViewSourcePage");
|
||||
},
|
||||
|
||||
/**
|
||||
* Opens the view source window.
|
||||
*
|
||||
|
|
Загрузка…
Ссылка в новой задаче