|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 'use strict'; |
|
5 |
|
6 const { contract } = require('../../util/contract'); |
|
7 const { isLocalURL } = require('../../url'); |
|
8 const { isNil, isObject, isString } = require('../../lang/type'); |
|
9 const { required, either, string, boolean, object } = require('../../deprecated/api-utils'); |
|
10 const { merge } = require('../../util/object'); |
|
11 const { freeze } = Object; |
|
12 |
|
13 function isIconSet(icons) { |
|
14 return Object.keys(icons). |
|
15 every(size => String(size >>> 0) === size && isLocalURL(icons[size])) |
|
16 } |
|
17 |
|
18 let iconSet = { |
|
19 is: either(object, string), |
|
20 map: v => isObject(v) ? freeze(merge({}, v)) : v, |
|
21 ok: v => (isString(v) && isLocalURL(v)) || (isObject(v) && isIconSet(v)), |
|
22 msg: 'The option "icon" must be a local URL or an object with ' + |
|
23 'numeric keys / local URL values pair.' |
|
24 } |
|
25 |
|
26 let id = { |
|
27 is: string, |
|
28 ok: v => /^[a-z-_][a-z0-9-_]*$/i.test(v), |
|
29 msg: 'The option "id" must be a valid alphanumeric id (hyphens and ' + |
|
30 'underscores are allowed).' |
|
31 }; |
|
32 |
|
33 let label = { |
|
34 is: string, |
|
35 ok: v => isNil(v) || v.trim().length > 0, |
|
36 msg: 'The option "label" must be a non empty string' |
|
37 } |
|
38 |
|
39 let stateContract = contract({ |
|
40 label: label, |
|
41 icon: iconSet, |
|
42 disabled: boolean |
|
43 }); |
|
44 |
|
45 exports.stateContract = stateContract; |
|
46 |
|
47 let buttonContract = contract(merge({}, stateContract.rules, { |
|
48 id: required(id), |
|
49 label: required(label), |
|
50 icon: required(iconSet) |
|
51 })); |
|
52 |
|
53 exports.buttonContract = buttonContract; |
|
54 |
|
55 exports.toggleStateContract = contract(merge({ |
|
56 checked: boolean |
|
57 }, stateContract.rules)); |
|
58 |
|
59 exports.toggleButtonContract = contract(merge({ |
|
60 checked: boolean |
|
61 }, buttonContract.rules)); |
|
62 |