Skip to content

Commit

Permalink
Bug 1794385 - Move unified-extensions-item custom element to its own …
Browse files Browse the repository at this point in the history
…file. r=Gijs

Differential Revision: https://phabricator.services.mozilla.com/D162288
  • Loading branch information
willdurand committed Nov 17, 2022
1 parent 2e6c5ff commit fdf5b0d
Show file tree
Hide file tree
Showing 6 changed files with 219 additions and 201 deletions.
200 changes: 0 additions & 200 deletions browser/base/content/browser-addons.js
Original file line number Diff line number Diff line change
Expand Up @@ -1200,206 +1200,6 @@ var BrowserAddonUI = {
},
};

/**
* The `unified-extensions-item` custom element is used to manage an extension
* in the list of extensions, which is displayed when users click the unified
* extensions (toolbar) button.
*
* This custom element must be initialized with `setAddon()`:
*
* ```
* let item = document.createElement("unified-extensions-item");
* item.setAddon(addon);
* document.body.appendChild(item);
* ```
*/
customElements.define(
"unified-extensions-item",
class extends HTMLElement {
/**
* Set the add-on for this item. The item will be populated based on the
* add-on when it is rendered into the DOM.
*
* @param {AddonWrapper} addon The add-on to use.
*/
setAddon(addon) {
this.addon = addon;
}

connectedCallback() {
if (this._openMenuButton) {
return;
}

const template = document.getElementById(
"unified-extensions-item-template"
);
this.appendChild(template.content.cloneNode(true));

this._actionButton = this.querySelector(
".unified-extensions-item-action"
);
this._openMenuButton = this.querySelector(
".unified-extensions-item-open-menu"
);

this._openMenuButton.addEventListener("blur", this);
this._openMenuButton.addEventListener("focus", this);

this.addEventListener("command", this);
this.addEventListener("mouseout", this);
this.addEventListener("mouseover", this);

this.render();
}

handleEvent(event) {
const { target } = event;

switch (event.type) {
case "command":
if (target === this._openMenuButton) {
const popup = target.ownerDocument.getElementById(
"unified-extensions-context-menu"
);
popup.openPopup(
target,
"after_end",
0,
0,
true /* isContextMenu */,
false /* attributesOverride */,
event
);
} else if (target === this._actionButton) {
const extension = WebExtensionPolicy.getByID(this.addon.id)
?.extension;
if (!extension) {
return;
}

const win = event.target.ownerGlobal;
const tab = win.gBrowser.selectedTab;

extension.tabManager.addActiveTabPermission(tab);
extension.tabManager.activateScripts(tab);
}
break;

case "blur":
case "mouseout":
if (target === this._openMenuButton) {
this.removeAttribute("secondary-button-hovered");
} else if (target === this._actionButton) {
this._updateStateMessage();
}
break;

case "focus":
case "mouseover":
if (target === this._openMenuButton) {
this.setAttribute("secondary-button-hovered", true);
} else if (target === this._actionButton) {
this._updateStateMessage({ hover: true });
}
break;
}
}

async _updateStateMessage({ hover = false } = {}) {
const policy = WebExtensionPolicy.getByID(this.addon.id);

const messages = lazy.OriginControls.getStateMessageIDs(
policy,
this.ownerGlobal.gBrowser.currentURI
);
if (!messages) {
return;
}

const messageElement = this.querySelector(
".unified-extensions-item-message-default"
);

// We only want to adjust the height of an item in the panel when we
// first draw it, and not on hover (even if the hover message is longer,
// which shouldn't happen in practice but even if it was, we don't want
// to change the height on hover).
let adjustMinHeight = false;
if (hover && messages.onHover) {
this.ownerDocument.l10n.setAttributes(messageElement, messages.onHover);
} else if (messages.default) {
this.ownerDocument.l10n.setAttributes(messageElement, messages.default);
adjustMinHeight = true;
}

await document.l10n.translateElements([messageElement]);

if (adjustMinHeight) {
const contentsElement = this.querySelector(
".unified-extensions-item-contents"
);
const { height } = getComputedStyle(contentsElement);
contentsElement.style.minHeight = height;
}
}

_hasAction() {
const policy = WebExtensionPolicy.getByID(this.addon.id);
const state = lazy.OriginControls.getState(
policy,
this.ownerGlobal.gBrowser.currentURI
);

return state && state.whenClicked && !state.hasAccess;
}

render() {
if (!this.addon) {
throw new Error(
"unified-extensions-item requires an add-on, forgot to call setAddon()?"
);
}

this.setAttribute("extension-id", this.addon.id);

// Note that the data-extensionid attribute is used by context menu handlers
// to identify the extension being manipulated by the context menu.
this._actionButton.dataset.extensionid = this.addon.id;

let policy = WebExtensionPolicy.getByID(this.addon.id);
this.toggleAttribute(
"attention",
lazy.OriginControls.getAttention(policy, this.ownerGlobal)
);

this.querySelector(
".unified-extensions-item-name"
).textContent = this.addon.name;

const iconURL = AddonManager.getPreferredIconURL(this.addon, 32, window);
if (iconURL) {
this.querySelector(".unified-extensions-item-icon").setAttribute(
"src",
iconURL
);
}

this._actionButton.disabled = !this._hasAction();

// Note that the data-extensionid attribute is used by context menu handlers
// to identify the extension being manipulated by the context menu.
this._openMenuButton.dataset.extensionid = this.addon.id;
this._openMenuButton.setAttribute(
"data-l10n-args",
JSON.stringify({ extensionName: this.addon.name })
);

this._updateStateMessage();
}
}
);

// We must declare `gUnifiedExtensions` using `var` below to avoid a
// "redeclaration" syntax error.
var gUnifiedExtensions = {
Expand Down
Loading

0 comments on commit fdf5b0d

Please sign in to comment.