diff options
Diffstat (limited to 'addon-sdk/source/lib/sdk/ui/button')
-rw-r--r-- | addon-sdk/source/lib/sdk/ui/button/action.js | 114 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/ui/button/contract.js | 73 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/ui/button/toggle.js | 127 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/ui/button/view.js | 243 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/ui/button/view/events.js | 18 |
5 files changed, 0 insertions, 575 deletions
diff --git a/addon-sdk/source/lib/sdk/ui/button/action.js b/addon-sdk/source/lib/sdk/ui/button/action.js deleted file mode 100644 index dfb092d0c..000000000 --- a/addon-sdk/source/lib/sdk/ui/button/action.js +++ /dev/null @@ -1,114 +0,0 @@ -/* 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/. */ -'use strict'; - -module.metadata = { - 'stability': 'experimental', - 'engines': { - 'Firefox': '> 28' - } -}; - -const { Class } = require('../../core/heritage'); -const { merge } = require('../../util/object'); -const { Disposable } = require('../../core/disposable'); -const { on, off, emit, setListeners } = require('../../event/core'); -const { EventTarget } = require('../../event/target'); -const { getNodeView } = require('../../view/core'); - -const view = require('./view'); -const { buttonContract, stateContract } = require('./contract'); -const { properties, render, state, register, unregister, - getDerivedStateFor } = require('../state'); -const { events: stateEvents } = require('../state/events'); -const { events: viewEvents } = require('./view/events'); -const events = require('../../event/utils'); - -const { getActiveTab } = require('../../tabs/utils'); - -const { id: addonID } = require('../../self'); -const { identify } = require('../id'); - -const buttons = new Map(); - -const toWidgetId = id => - ('action-button--' + addonID.toLowerCase()+ '-' + id). - replace(/[^a-z0-9_-]/g, ''); - -const ActionButton = Class({ - extends: EventTarget, - implements: [ - properties(stateContract), - state(stateContract), - Disposable - ], - setup: function setup(options) { - let state = merge({ - disabled: false - }, buttonContract(options)); - - let id = toWidgetId(options.id); - - register(this, state); - - // Setup listeners. - setListeners(this, options); - - buttons.set(id, this); - - view.create(merge({}, state, { id: id })); - }, - - dispose: function dispose() { - let id = toWidgetId(this.id); - buttons.delete(id); - - off(this); - - view.dispose(id); - - unregister(this); - }, - - get id() { - return this.state().id; - }, - - click: function click() { view.click(toWidgetId(this.id)) } -}); -exports.ActionButton = ActionButton; - -identify.define(ActionButton, ({id}) => toWidgetId(id)); - -getNodeView.define(ActionButton, button => - view.nodeFor(toWidgetId(button.id)) -); - -var actionButtonStateEvents = events.filter(stateEvents, - e => e.target instanceof ActionButton); - -var actionButtonViewEvents = events.filter(viewEvents, - e => buttons.has(e.target)); - -var clickEvents = events.filter(actionButtonViewEvents, e => e.type === 'click'); -var updateEvents = events.filter(actionButtonViewEvents, e => e.type === 'update'); - -on(clickEvents, 'data', ({target: id, window}) => { - let button = buttons.get(id); - let state = getDerivedStateFor(button, getActiveTab(window)); - - emit(button, 'click', state); -}); - -on(updateEvents, 'data', ({target: id, window}) => { - render(buttons.get(id), window); -}); - -on(actionButtonStateEvents, 'data', ({target, window, state}) => { - let id = toWidgetId(target.id); - view.setIcon(id, window, state.icon); - view.setLabel(id, window, state.label); - view.setDisabled(id, window, state.disabled); - view.setBadge(id, window, state.badge, state.badgeColor); -}); diff --git a/addon-sdk/source/lib/sdk/ui/button/contract.js b/addon-sdk/source/lib/sdk/ui/button/contract.js deleted file mode 100644 index ce6e33d95..000000000 --- a/addon-sdk/source/lib/sdk/ui/button/contract.js +++ /dev/null @@ -1,73 +0,0 @@ -/* 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/. */ -'use strict'; - -const { contract } = require('../../util/contract'); -const { isLocalURL } = require('../../url'); -const { isNil, isObject, isString } = require('../../lang/type'); -const { required, either, string, boolean, object, number } = require('../../deprecated/api-utils'); -const { merge } = require('../../util/object'); -const { freeze } = Object; - -const isIconSet = (icons) => - Object.keys(icons). - every(size => String(size >>> 0) === size && isLocalURL(icons[size])); - -var iconSet = { - is: either(object, string), - map: v => isObject(v) ? freeze(merge({}, v)) : v, - ok: v => (isString(v) && isLocalURL(v)) || (isObject(v) && isIconSet(v)), - msg: 'The option "icon" must be a local URL or an object with ' + - 'numeric keys / local URL values pair.' -} - -var id = { - is: string, - ok: v => /^[a-z-_][a-z0-9-_]*$/i.test(v), - msg: 'The option "id" must be a valid alphanumeric id (hyphens and ' + - 'underscores are allowed).' -}; - -var label = { - is: string, - ok: v => isNil(v) || v.trim().length > 0, - msg: 'The option "label" must be a non empty string' -} - -var badge = { - is: either(string, number), - msg: 'The option "badge" must be a string or a number' -} - -var badgeColor = { - is: string, - msg: 'The option "badgeColor" must be a string' -} - -var stateContract = contract({ - label: label, - icon: iconSet, - disabled: boolean, - badge: badge, - badgeColor: badgeColor -}); - -exports.stateContract = stateContract; - -var buttonContract = contract(merge({}, stateContract.rules, { - id: required(id), - label: required(label), - icon: required(iconSet) -})); - -exports.buttonContract = buttonContract; - -exports.toggleStateContract = contract(merge({ - checked: boolean -}, stateContract.rules)); - -exports.toggleButtonContract = contract(merge({ - checked: boolean -}, buttonContract.rules)); - diff --git a/addon-sdk/source/lib/sdk/ui/button/toggle.js b/addon-sdk/source/lib/sdk/ui/button/toggle.js deleted file mode 100644 index a226b3212..000000000 --- a/addon-sdk/source/lib/sdk/ui/button/toggle.js +++ /dev/null @@ -1,127 +0,0 @@ -/* 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/. */ -'use strict'; - -module.metadata = { - 'stability': 'experimental', - 'engines': { - 'Firefox': '> 28' - } -}; - -const { Class } = require('../../core/heritage'); -const { merge } = require('../../util/object'); -const { Disposable } = require('../../core/disposable'); -const { on, off, emit, setListeners } = require('../../event/core'); -const { EventTarget } = require('../../event/target'); -const { getNodeView } = require('../../view/core'); - -const view = require('./view'); -const { toggleButtonContract, toggleStateContract } = require('./contract'); -const { properties, render, state, register, unregister, - setStateFor, getStateFor, getDerivedStateFor } = require('../state'); -const { events: stateEvents } = require('../state/events'); -const { events: viewEvents } = require('./view/events'); -const events = require('../../event/utils'); - -const { getActiveTab } = require('../../tabs/utils'); - -const { id: addonID } = require('../../self'); -const { identify } = require('../id'); - -const buttons = new Map(); - -const toWidgetId = id => - ('toggle-button--' + addonID.toLowerCase()+ '-' + id). - replace(/[^a-z0-9_-]/g, ''); - -const ToggleButton = Class({ - extends: EventTarget, - implements: [ - properties(toggleStateContract), - state(toggleStateContract), - Disposable - ], - setup: function setup(options) { - let state = merge({ - disabled: false, - checked: false - }, toggleButtonContract(options)); - - let id = toWidgetId(options.id); - - register(this, state); - - // Setup listeners. - setListeners(this, options); - - buttons.set(id, this); - - view.create(merge({ type: 'checkbox' }, state, { id: id })); - }, - - dispose: function dispose() { - let id = toWidgetId(this.id); - buttons.delete(id); - - off(this); - - view.dispose(id); - - unregister(this); - }, - - get id() { - return this.state().id; - }, - - click: function click() { - return view.click(toWidgetId(this.id)); - } -}); -exports.ToggleButton = ToggleButton; - -identify.define(ToggleButton, ({id}) => toWidgetId(id)); - -getNodeView.define(ToggleButton, button => - view.nodeFor(toWidgetId(button.id)) -); - -var toggleButtonStateEvents = events.filter(stateEvents, - e => e.target instanceof ToggleButton); - -var toggleButtonViewEvents = events.filter(viewEvents, - e => buttons.has(e.target)); - -var clickEvents = events.filter(toggleButtonViewEvents, e => e.type === 'click'); -var updateEvents = events.filter(toggleButtonViewEvents, e => e.type === 'update'); - -on(toggleButtonStateEvents, 'data', ({target, window, state}) => { - let id = toWidgetId(target.id); - - view.setIcon(id, window, state.icon); - view.setLabel(id, window, state.label); - view.setDisabled(id, window, state.disabled); - view.setChecked(id, window, state.checked); - view.setBadge(id, window, state.badge, state.badgeColor); -}); - -on(clickEvents, 'data', ({target: id, window, checked }) => { - let button = buttons.get(id); - let windowState = getStateFor(button, window); - - let newWindowState = merge({}, windowState, { checked: checked }); - - setStateFor(button, window, newWindowState); - - let state = getDerivedStateFor(button, getActiveTab(window)); - - emit(button, 'click', state); - - emit(button, 'change', state); -}); - -on(updateEvents, 'data', ({target: id, window}) => { - render(buttons.get(id), window); -}); diff --git a/addon-sdk/source/lib/sdk/ui/button/view.js b/addon-sdk/source/lib/sdk/ui/button/view.js deleted file mode 100644 index 63b7aea31..000000000 --- a/addon-sdk/source/lib/sdk/ui/button/view.js +++ /dev/null @@ -1,243 +0,0 @@ -/* 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/. */ -'use strict'; - -module.metadata = { - 'stability': 'experimental', - 'engines': { - 'Firefox': '> 28' - } -}; - -const { Cu } = require('chrome'); -const { on, off, emit } = require('../../event/core'); - -const { data } = require('sdk/self'); - -const { isObject, isNil } = require('../../lang/type'); - -const { getMostRecentBrowserWindow } = require('../../window/utils'); -const { ignoreWindow } = require('../../private-browsing/utils'); -const { CustomizableUI } = Cu.import('resource:///modules/CustomizableUI.jsm', {}); -const { AREA_PANEL, AREA_NAVBAR } = CustomizableUI; - -const { events: viewEvents } = require('./view/events'); - -const XUL_NS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'; - -const views = new Map(); -const customizedWindows = new WeakMap(); - -const buttonListener = { - onCustomizeStart: window => { - for (let [id, view] of views) { - setIcon(id, window, view.icon); - setLabel(id, window, view.label); - } - - customizedWindows.set(window, true); - }, - onCustomizeEnd: window => { - customizedWindows.delete(window); - - for (let [id, ] of views) { - let placement = CustomizableUI.getPlacementOfWidget(id); - - if (placement) - emit(viewEvents, 'data', { type: 'update', target: id, window: window }); - } - }, - onWidgetAfterDOMChange: (node, nextNode, container) => { - let { id } = node; - let view = views.get(id); - let window = node.ownerDocument.defaultView; - - if (view) { - emit(viewEvents, 'data', { type: 'update', target: id, window: window }); - } - } -}; - -CustomizableUI.addListener(buttonListener); - -require('../../system/unload').when( _ => - CustomizableUI.removeListener(buttonListener) -); - -function getNode(id, window) { - return !views.has(id) || ignoreWindow(window) - ? null - : CustomizableUI.getWidget(id).forWindow(window).node -}; - -function isInToolbar(id) { - let placement = CustomizableUI.getPlacementOfWidget(id); - - return placement && CustomizableUI.getAreaType(placement.area) === 'toolbar'; -} - - -function getImage(icon, isInToolbar, pixelRatio) { - let targetSize = (isInToolbar ? 18 : 32) * pixelRatio; - let bestSize = 0; - let image = icon; - - if (isObject(icon)) { - for (let size of Object.keys(icon)) { - size = +size; - let offset = targetSize - size; - - if (offset === 0) { - bestSize = size; - break; - } - - let delta = Math.abs(offset) - Math.abs(targetSize - bestSize); - - if (delta < 0) - bestSize = size; - } - - image = icon[bestSize]; - } - - if (image.indexOf('./') === 0) - return data.url(image.substr(2)); - - return image; -} - -function nodeFor(id, window=getMostRecentBrowserWindow()) { - return customizedWindows.has(window) ? null : getNode(id, window); -}; -exports.nodeFor = nodeFor; - -function create(options) { - let { id, label, icon, type, badge } = options; - - if (views.has(id)) - throw new Error('The ID "' + id + '" seems already used.'); - - CustomizableUI.createWidget({ - id: id, - type: 'custom', - removable: true, - defaultArea: AREA_NAVBAR, - allowedAreas: [ AREA_PANEL, AREA_NAVBAR ], - - onBuild: function(document) { - let window = document.defaultView; - - let node = document.createElementNS(XUL_NS, 'toolbarbutton'); - - let image = getImage(icon, true, window.devicePixelRatio); - - if (ignoreWindow(window)) - node.style.display = 'none'; - - node.setAttribute('id', this.id); - node.setAttribute('class', 'toolbarbutton-1 chromeclass-toolbar-additional badged-button'); - node.setAttribute('type', type); - node.setAttribute('label', label); - node.setAttribute('tooltiptext', label); - node.setAttribute('image', image); - node.setAttribute('constrain-size', 'true'); - - views.set(id, { - area: this.currentArea, - icon: icon, - label: label - }); - - node.addEventListener('command', function(event) { - if (views.has(id)) { - emit(viewEvents, 'data', { - type: 'click', - target: id, - window: event.view, - checked: node.checked - }); - } - }); - - return node; - } - }); -}; -exports.create = create; - -function dispose(id) { - if (!views.has(id)) return; - - views.delete(id); - CustomizableUI.destroyWidget(id); -} -exports.dispose = dispose; - -function setIcon(id, window, icon) { - let node = getNode(id, window); - - if (node) { - icon = customizedWindows.has(window) ? views.get(id).icon : icon; - let image = getImage(icon, isInToolbar(id), window.devicePixelRatio); - - node.setAttribute('image', image); - } -} -exports.setIcon = setIcon; - -function setLabel(id, window, label) { - let node = nodeFor(id, window); - - if (node) { - node.setAttribute('label', label); - node.setAttribute('tooltiptext', label); - } -} -exports.setLabel = setLabel; - -function setDisabled(id, window, disabled) { - let node = nodeFor(id, window); - - if (node) - node.disabled = disabled; -} -exports.setDisabled = setDisabled; - -function setChecked(id, window, checked) { - let node = nodeFor(id, window); - - if (node) - node.checked = checked; -} -exports.setChecked = setChecked; - -function setBadge(id, window, badge, color) { - let node = nodeFor(id, window); - - if (node) { - // `Array.from` is needed to handle unicode symbol properly: - // '𝐀𝐁'.length is 4 where Array.from('𝐀𝐁').length is 2 - let text = isNil(badge) - ? '' - : Array.from(String(badge)).slice(0, 4).join(''); - - node.setAttribute('badge', text); - - let badgeNode = node.ownerDocument.getAnonymousElementByAttribute(node, - 'class', 'toolbarbutton-badge'); - - if (badgeNode) - badgeNode.style.backgroundColor = isNil(color) ? '' : color; - } -} -exports.setBadge = setBadge; - -function click(id) { - let node = nodeFor(id); - - if (node) - node.click(); -} -exports.click = click; diff --git a/addon-sdk/source/lib/sdk/ui/button/view/events.js b/addon-sdk/source/lib/sdk/ui/button/view/events.js deleted file mode 100644 index 98909656a..000000000 --- a/addon-sdk/source/lib/sdk/ui/button/view/events.js +++ /dev/null @@ -1,18 +0,0 @@ -/* 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/. */ - -'use strict'; - -module.metadata = { - 'stability': 'experimental', - 'engines': { - 'Firefox': '*', - 'SeaMonkey': '*', - 'Thunderbird': '*' - } -}; - -var channel = {}; - -exports.events = channel; |