michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: 'use strict'; michael@0: michael@0: const { contract } = require('../../util/contract'); michael@0: const { isLocalURL } = require('../../url'); michael@0: const { isNil, isObject, isString } = require('../../lang/type'); michael@0: const { required, either, string, boolean, object } = require('../../deprecated/api-utils'); michael@0: const { merge } = require('../../util/object'); michael@0: const { freeze } = Object; michael@0: michael@0: function isIconSet(icons) { michael@0: return Object.keys(icons). michael@0: every(size => String(size >>> 0) === size && isLocalURL(icons[size])) michael@0: } michael@0: michael@0: let iconSet = { michael@0: is: either(object, string), michael@0: map: v => isObject(v) ? freeze(merge({}, v)) : v, michael@0: ok: v => (isString(v) && isLocalURL(v)) || (isObject(v) && isIconSet(v)), michael@0: msg: 'The option "icon" must be a local URL or an object with ' + michael@0: 'numeric keys / local URL values pair.' michael@0: } michael@0: michael@0: let id = { michael@0: is: string, michael@0: ok: v => /^[a-z-_][a-z0-9-_]*$/i.test(v), michael@0: msg: 'The option "id" must be a valid alphanumeric id (hyphens and ' + michael@0: 'underscores are allowed).' michael@0: }; michael@0: michael@0: let label = { michael@0: is: string, michael@0: ok: v => isNil(v) || v.trim().length > 0, michael@0: msg: 'The option "label" must be a non empty string' michael@0: } michael@0: michael@0: let stateContract = contract({ michael@0: label: label, michael@0: icon: iconSet, michael@0: disabled: boolean michael@0: }); michael@0: michael@0: exports.stateContract = stateContract; michael@0: michael@0: let buttonContract = contract(merge({}, stateContract.rules, { michael@0: id: required(id), michael@0: label: required(label), michael@0: icon: required(iconSet) michael@0: })); michael@0: michael@0: exports.buttonContract = buttonContract; michael@0: michael@0: exports.toggleStateContract = contract(merge({ michael@0: checked: boolean michael@0: }, stateContract.rules)); michael@0: michael@0: exports.toggleButtonContract = contract(merge({ michael@0: checked: boolean michael@0: }, buttonContract.rules)); michael@0: