1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/addon-sdk/source/lib/sdk/ui/button/toggle.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,122 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 +'use strict'; 1.8 + 1.9 +module.metadata = { 1.10 + 'stability': 'experimental', 1.11 + 'engines': { 1.12 + 'Firefox': '> 28' 1.13 + } 1.14 +}; 1.15 + 1.16 +const { Class } = require('../../core/heritage'); 1.17 +const { merge } = require('../../util/object'); 1.18 +const { Disposable } = require('../../core/disposable'); 1.19 +const { on, off, emit, setListeners } = require('../../event/core'); 1.20 +const { EventTarget } = require('../../event/target'); 1.21 +const { getNodeView } = require('../../view/core'); 1.22 + 1.23 +const view = require('./view'); 1.24 +const { toggleButtonContract, toggleStateContract } = require('./contract'); 1.25 +const { properties, render, state, register, unregister, 1.26 + setStateFor, getStateFor, getDerivedStateFor } = require('../state'); 1.27 +const { events: stateEvents } = require('../state/events'); 1.28 +const { events: viewEvents } = require('./view/events'); 1.29 +const events = require('../../event/utils'); 1.30 + 1.31 +const { getActiveTab } = require('../../tabs/utils'); 1.32 + 1.33 +const { id: addonID } = require('../../self'); 1.34 +const { identify } = require('../id'); 1.35 + 1.36 +const buttons = new Map(); 1.37 + 1.38 +const toWidgetId = id => 1.39 + ('toggle-button--' + addonID.toLowerCase()+ '-' + id). 1.40 + replace(/[^a-z0-9_-]/g, ''); 1.41 + 1.42 +const ToggleButton = Class({ 1.43 + extends: EventTarget, 1.44 + implements: [ 1.45 + properties(toggleStateContract), 1.46 + state(toggleStateContract), 1.47 + Disposable 1.48 + ], 1.49 + setup: function setup(options) { 1.50 + let state = merge({ 1.51 + disabled: false, 1.52 + checked: false 1.53 + }, toggleButtonContract(options)); 1.54 + 1.55 + let id = toWidgetId(options.id); 1.56 + 1.57 + register(this, state); 1.58 + 1.59 + // Setup listeners. 1.60 + setListeners(this, options); 1.61 + 1.62 + buttons.set(id, this); 1.63 + 1.64 + view.create(merge({ type: 'checkbox' }, state, { id: id })); 1.65 + }, 1.66 + 1.67 + dispose: function dispose() { 1.68 + let id = toWidgetId(this.id); 1.69 + buttons.delete(id); 1.70 + 1.71 + off(this); 1.72 + 1.73 + view.dispose(id); 1.74 + 1.75 + unregister(this); 1.76 + }, 1.77 + 1.78 + get id() this.state().id, 1.79 + 1.80 + click: function click() view.click(toWidgetId(this.id)) 1.81 +}); 1.82 +exports.ToggleButton = ToggleButton; 1.83 + 1.84 +identify.define(ToggleButton, ({id}) => toWidgetId(id)); 1.85 + 1.86 +getNodeView.define(ToggleButton, button => 1.87 + view.nodeFor(toWidgetId(button.id)) 1.88 +); 1.89 + 1.90 +let toggleButtonStateEvents = events.filter(stateEvents, 1.91 + e => e.target instanceof ToggleButton); 1.92 + 1.93 +let toggleButtonViewEvents = events.filter(viewEvents, 1.94 + e => buttons.has(e.target)); 1.95 + 1.96 +let clickEvents = events.filter(toggleButtonViewEvents, e => e.type === 'click'); 1.97 +let updateEvents = events.filter(toggleButtonViewEvents, e => e.type === 'update'); 1.98 + 1.99 +on(toggleButtonStateEvents, 'data', ({target, window, state}) => { 1.100 + let id = toWidgetId(target.id); 1.101 + 1.102 + view.setIcon(id, window, state.icon); 1.103 + view.setLabel(id, window, state.label); 1.104 + view.setDisabled(id, window, state.disabled); 1.105 + view.setChecked(id, window, state.checked); 1.106 +}); 1.107 + 1.108 +on(clickEvents, 'data', ({target: id, window, checked }) => { 1.109 + let button = buttons.get(id); 1.110 + let windowState = getStateFor(button, window); 1.111 + 1.112 + let newWindowState = merge({}, windowState, { checked: checked }); 1.113 + 1.114 + setStateFor(button, window, newWindowState); 1.115 + 1.116 + let state = getDerivedStateFor(button, getActiveTab(window)); 1.117 + 1.118 + emit(button, 'click', state); 1.119 + 1.120 + emit(button, 'change', state); 1.121 +}); 1.122 + 1.123 +on(updateEvents, 'data', ({target: id, window}) => { 1.124 + render(buttons.get(id), window); 1.125 +});