/* 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/. */
* @param String id (non standard) * Needed so tests can confirm the XUL implementation is working
*/ function Menu({ id = null } = {}) { this.menuitems = []; this.id = id;
/** * Add an item to the end of the Menu * * @param {MenuItem} menuItem
*/
Menu.prototype.append = function (menuItem) { this.menuitems.push(menuItem);
};
/** * Remove all items from the Menu
*/
Menu.prototype.clear = function () { this.menuitems = [];
};
/** * Add an item to a specified position in the menu * * @param {int} _pos * @param {MenuItem} _menuItem
*/
Menu.prototype.insert = function (_pos, _menuItem) { throw Error("Not implemented");
};
/** * Show the Menu next to the provided target. Anchor point is bottom-left. * * @param {Element} target * The element to use as anchor.
*/
Menu.prototype.popupAtTarget = function (target) { const rect = target.getBoundingClientRect(); const doc = target.ownerDocument; const defaultView = doc.defaultView; const x = rect.left + defaultView.mozInnerScreenX; const y = rect.bottom + defaultView.mozInnerScreenY;
this.popup(x, y, doc);
};
/** * Hide an existing menu, if there's any. * * @param {Document} doc * The document that should own the context menu.
*/
Menu.prototype.hide = function (doc) { const win = doc.defaultView;
doc = DevToolsUtils.getTopWindow(win).document; const popup = doc.querySelector('popupset menupopup[menu-api="true"]'); if (!popup) { return;
}
popup.hidePopup();
};
/** * Show the Menu at a specified location on the screen * * Missing features: * - browserWindow - BrowserWindow (optional) - Default is null. * - positioningItem Number - (optional) OS X * * @param {int} screenX * @param {int} screenY * @param {Document} doc * The document that should own the context menu.
*/
Menu.prototype.popup = function (screenX, screenY, doc) { // See bug 1285229, on Windows, opening the same popup multiple times in a // row ends up duplicating the popup. The newly inserted popup doesn't // dismiss the old one. So remove any previously displayed popup before // opening a new one. this.hide(doc);
// The context-menu will be created in the topmost window to preserve keyboard // navigation (see Bug 1543940). // Keep a reference on the window owning the menu to hide the popup on unload. const win = doc.defaultView; const topWin = DevToolsUtils.getTopWindow(win);
// Convert coordinates from win's CSS coordinate space to topWin's const winToTopWinCssScale = win.devicePixelRatio / topWin.devicePixelRatio;
screenX = screenX * winToTopWinCssScale;
screenY = screenY * winToTopWinCssScale;
doc = topWin.document;
let popupset = doc.querySelector("popupset"); if (!popupset) {
popupset = doc.createXULElement("popupset");
doc.documentElement.appendChild(popupset);
}
if (this.id) {
popup.id = this.id;
} this._createMenuItems(popup);
// The context menu will be created in the topmost chrome window. Hide it manually when // the owner document is unloaded. const onWindowUnload = () => popup.hidePopup();
win.addEventListener("unload", onWindowUnload);
// Remove the menu from the DOM once it's hidden.
popup.addEventListener("popuphidden", e => { if (e.target === popup) {
win.removeEventListener("unload", onWindowUnload);
popup.remove(); this.emit("close");
}
});
popup.addEventListener("popupshown", e => { if (e.target === popup) { this.emit("open");
}
});
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.