From 80982c8e6d001944a0f2ee65175325af25159423 Mon Sep 17 00:00:00 2001 From: Keegan Date: Thu, 4 Feb 2016 00:04:08 -0800 Subject: [PATCH] strip out components into separate repo --- .eslintrc | 4 +- dist/clay.js | 481 +++++++++++++++++++++++++++ package.json | 11 +- src/scripts/components/color.js | 107 ------ src/scripts/components/footer.js | 10 - src/scripts/components/heading.js | 11 - src/scripts/components/input.js | 11 - src/scripts/components/select.js | 21 -- src/scripts/components/submit.js | 10 - src/scripts/components/text.js | 10 - src/scripts/components/toggle.js | 10 - src/scripts/config-page.js | 16 +- src/scripts/lib/clay-config.js | 36 +- src/scripts/lib/clay-item.js | 14 +- src/styles/config-page.scss | 6 - src/styles/items/_button.scss | 61 ---- src/styles/items/_color.scss | 91 ----- src/styles/items/_input.scss | 43 --- src/styles/items/_select.scss | 36 -- src/styles/items/_toggle.scss | 51 --- src/templates/components/color.tpl | 15 - src/templates/components/footer.tpl | 6 - src/templates/components/heading.tpl | 3 - src/templates/components/input.tpl | 9 - src/templates/components/select.tpl | 9 - src/templates/components/submit.tpl | 9 - src/templates/components/text.tpl | 3 - src/templates/components/toggle.tpl | 14 - test/fixture.js | 10 +- test/karma-debug.conf.js | 87 +++++ test/spec/lib/clay-config.js | 4 +- 31 files changed, 620 insertions(+), 589 deletions(-) create mode 100644 dist/clay.js delete mode 100644 src/scripts/components/color.js delete mode 100644 src/scripts/components/footer.js delete mode 100644 src/scripts/components/heading.js delete mode 100644 src/scripts/components/input.js delete mode 100644 src/scripts/components/select.js delete mode 100644 src/scripts/components/submit.js delete mode 100644 src/scripts/components/text.js delete mode 100644 src/scripts/components/toggle.js delete mode 100644 src/styles/items/_button.scss delete mode 100644 src/styles/items/_color.scss delete mode 100644 src/styles/items/_input.scss delete mode 100644 src/styles/items/_select.scss delete mode 100644 src/styles/items/_toggle.scss delete mode 100755 src/templates/components/color.tpl delete mode 100755 src/templates/components/footer.tpl delete mode 100755 src/templates/components/heading.tpl delete mode 100755 src/templates/components/input.tpl delete mode 100755 src/templates/components/select.tpl delete mode 100755 src/templates/components/submit.tpl delete mode 100644 src/templates/components/text.tpl delete mode 100755 src/templates/components/toggle.tpl create mode 100644 test/karma-debug.conf.js diff --git a/.eslintrc b/.eslintrc index af72445..aba60f8 100755 --- a/.eslintrc +++ b/.eslintrc @@ -5,9 +5,7 @@ "browser": true }, "globals": { - "Pebble": true, - "$": true, - "t": true + "Pebble": true }, "rules" : { "new-cap": [0], diff --git a/dist/clay.js b/dist/clay.js new file mode 100644 index 0000000..e690350 --- /dev/null +++ b/dist/clay.js @@ -0,0 +1,481 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.clay = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) { + return '{$circularReference:' + seenIndex + '}' + } + seen.push(object) + + function join (elements) { + return indent.slice(1) + elements.join(',' + (indent && '\n') + nextIndent) + (indent ? ' ' : '') + } + + if (Array.isArray(object)) { + return '[' + join(object.map(function (element) { + return walk(element, filter, indent, nextIndent, seen.slice()) + })) + ']' + } + var keys = Object.keys(object) + return keys.length ? '{' + join(keys.map(function (key) { + return (legalKey(key) ? key : JSON.stringify(key)) + ':' + walk(object[key], filter, indent, nextIndent, seen.slice()) + })) + '}' : '{}' + } +} + +var KEYWORD_REGEXP = /^(abstract|boolean|break|byte|case|catch|char|class|const|continue|debugger|default|delete|do|double|else|enum|export|extends|false|final|finally|float|for|function|goto|if|implements|import|in|instanceof|int|interface|long|native|new|null|package|private|protected|public|return|short|static|super|switch|synchronized|this|throw|throws|transient|true|try|typeof|undefined|var|void|volatile|while|with)$/ + +function legalKey (string) { + return /^[a-z_$][0-9a-z_$]*$/gi.test(string) && !KEYWORD_REGEXP.test(string) +} + +// Node.js 0.10 doesn't escape slashes in re.toString() or re.source +// when they were not escaped initially. +// Here we check if the workaround is needed once and for all, +// then apply it only for non-escaped slashes. +var isRegExpEscaped = (new RegExp('/')).source === '\\/' + +function stringifyRegExp (re) { + if (isRegExpEscaped) { + return re.toString() + } + var source = re.source.replace(/\//g, function (found, offset, str) { + if (offset === 0 || str[offset - 1] !== '\\') { + return '\\/' + } + return '/' + }) + var flags = (re.global && 'g' || '') + (re.ignoreCase && 'i' || '') + (re.multiline && 'm' || '') + return '/' + source + '/' + flags +} + +},{}],2:[function(require,module,exports){ +'use strict'; + +module.exports = { + name: 'color', + template: require('../../templates/components/color.tpl'), + style: require('../../styles/clay/components/color.scss'), + manipulator: 'val', + defaults: { + label: '' + }, + initialize: function(minified) { + var HTML = minified.HTML; + var self = this; + + /* eslint-disable comma-spacing, no-multi-spaces, max-len, + standard/array-bracket-even-spacing */ + var layout = self.config.layout || [ + [false , false , '#55FF00', '#AAFF55', false , '#FFFF55', '#FFFFAA', false , false ], + [false , '#AAFFAA', '#55FF55', '#00FF00', '#AAFF00', '#FFFF00', '#FFAA55', '#FFAAAA', false ], + ['#55FFAA', '#00FF55', '#00AA00', '#55AA00', '#AAAA55', '#AAAA00', '#FFAA00', '#FF5500', '#FF5555'], + ['#AAFFFF', '#00FFAA', '#00AA55', '#55AA55', '#005500', '#555500', '#AA5500', '#FF0000', '#FF0055'], + [false , '#55AAAA', '#00AAAA', '#005555', '#FFFFFF', '#000000', '#AA5555', '#AA0000', false ], + ['#55FFFF', '#00FFFF', '#00AAFF', '#0055AA', '#AAAAAA', '#555555', '#550000', '#AA0055', '#FF55AA'], + ['#55AAFF', '#0055FF', '#0000FF', '#0000AA', '#000055', '#550055', '#AA00AA', '#FF00AA', '#FFAAFF'], + [false , '#5555AA', '#5555FF', '#5500FF', '#5500AA', '#AA00FF', '#FF00FF', '#FF55FF', false ], + [false , false , false , '#AAAAFF', '#AA55FF', '#AA55AA', false , false , false ] + ]; + /* eslint-enable */ + + var grid = ''; + var itemWidth = 100 / layout[0].length; + var itemHeight = 100 / layout.length; + var $elem = self.$element; + + for (var i = 0; i < layout.length; i++) { + for (var j = 0; j < layout[i].length; j++) { + + var color = layout[i][j] || 'transparent'; + var selectable = (color !== 'transparent' ? ' selectable' : ''); + + var roundedTL = (i === 0 && j === 0) || i === 0 && !layout[i][j - 1] || + !layout[i][j - 1] && !layout[i - 1][j] ? + ' rounded-tl' : + ''; + + var roundedTR = i === 0 && !layout[i][j + 1] || + !layout[i][j + 1] && !layout[i - 1][j] ? + ' rounded-tr ' : + ''; + + var roundedBL = (i === layout.length - 1 && j === 0) || + i === layout.length - 1 && !layout[i][j - 1] || + !layout[i][j - 1] && !layout[i + 1][j] ? + ' rounded-bl' : + ''; + + var roundedBR = i === layout.length - 1 && !layout[i][j + 1] || + !layout[i][j + 1] && !layout[i + 1][j] ? + ' rounded-br' : + ''; + + grid += '' + + ''; + } + } + + $elem.select('.color-box-container').add(HTML(grid)); + + var $valueDisplay = $elem.select('.value'); + var $picker = $elem.select('.picker-wrap'); + var disabled = self.$manipulatorTarget.get('disabled'); + + $elem.select('label').on('click', function(ev) { + if (!disabled) { + $picker.set('show'); // toggle visibility + } + }); + + self.on('change', function() { + var value = self.get().replace(/^0x/, '').toLowerCase(); + $valueDisplay.set('$background-color', '#' + value); + $elem.select('.color-box').set('-selected'); + $elem.select('.color-box[data-value="0x' + value + '"]').set('+selected'); + }); + + $elem.select('.color-box.selectable').on('touchend', function(ev) { + self.set(ev.target.dataset.value); + $picker.set('-show'); + }); + + self.on('disabled', function() { + disabled = true; + }); + + self.on('enabled', function() { + disabled = false; + }); + + } +}; + +},{"../../styles/clay/components/color.scss":11,"../../templates/components/color.tpl":15}],3:[function(require,module,exports){ +'use strict'; + +module.exports = { + name: 'footer', + template: require('../../templates/components/footer.tpl'), + manipulator: 'html', + defaults: { + attributes: {} + } +}; + +},{"../../templates/components/footer.tpl":16}],4:[function(require,module,exports){ +'use strict'; + +module.exports = { + name: 'heading', + template: require('../../templates/components/heading.tpl'), + manipulator: 'html', + defaults: { + attributes: {}, + size: 4 + } +}; + +},{"../../templates/components/heading.tpl":17}],5:[function(require,module,exports){ +'use strict'; + +module.exports = { + color: require('./color'), + footer: require('./footer'), + heading: require('./heading'), + input: require('./input'), + select: require('./select'), + submit: require('./submit'), + text: require('./text'), + toggle: require('./toggle') +}; + +},{"./color":2,"./footer":3,"./heading":4,"./input":6,"./select":7,"./submit":8,"./text":9,"./toggle":10}],6:[function(require,module,exports){ +'use strict'; + +module.exports = { + name: 'input', + template: require('../../templates/components/input.tpl'), + style: require('../../styles/clay/components/input.scss'), + manipulator: 'val', + defaults: { + label: '', + attributes: {} + } +}; + +},{"../../styles/clay/components/input.scss":12,"../../templates/components/input.tpl":18}],7:[function(require,module,exports){ +'use strict'; + +module.exports = { + name: 'select', + template: require('../../templates/components/select.tpl'), + style: require('../../styles/clay/components/select.scss'), + manipulator: 'val', + defaults: { + label: '', + options: [] + }, + initialize: function() { + var self = this; + + var $value = self.$element.select('.value'); + + self.on('change', function(ev) { + var value = self.$manipulatorTarget.select('option:checked').get('innerHTML'); + $value.set('innerHTML', value); + }); + } +}; + +},{"../../styles/clay/components/select.scss":13,"../../templates/components/select.tpl":19}],8:[function(require,module,exports){ +'use strict'; + +module.exports = { + name: 'submit', + template: require('../../templates/components/submit.tpl'), + manipulator: 'val', + defaults: { + attributes: {} + } +}; + +},{"../../templates/components/submit.tpl":20}],9:[function(require,module,exports){ +'use strict'; + +module.exports = { + name: 'text', + template: require('../../templates/components/text.tpl'), + manipulator: 'html', + defaults: { + attributes: {} + } +}; + +},{"../../templates/components/text.tpl":21}],10:[function(require,module,exports){ +'use strict'; + +module.exports = { + name: 'toggle', + template: require('../../templates/components/toggle.tpl'), + style: require('../../styles/clay/components/toggle.scss'), + manipulator: 'checked', + defaults: { + attributes: {} + } +}; + +},{"../../styles/clay/components/toggle.scss":14,"../../templates/components/toggle.tpl":22}],11:[function(require,module,exports){ +module.exports = ".component-color .value { width: 2.2652rem; height: 1.4rem; border-radius: 0.7rem; box-shadow: #2f2f2f 0 0.1rem 0.1rem; }\n\n.component-color input:disabled ~ .value, .component-color input:disabled ~ .label { opacity: 0.25; }\n\n.component-color .picker-wrap { left: 0; top: 0; top: 0; right: 0; bottom: 0; position: fixed; padding: 1rem; background: rgba(0, 0, 0, 0.7); opacity: 0; -webkit-transition: opacity 70ms ease-in 175ms; transition: opacity 70ms ease-in 175ms; pointer-events: none; z-index: 100; }\n\n.component-color .picker-wrap .picker { padding: 1rem; background: #f2f2f2; border-radius: 0.25rem; }\n\n.component-color .picker-wrap.show { -webkit-transition-delay: 0ms; transition-delay: 0ms; pointer-events: auto; opacity: 1; }\n\n.component-color .color-box-wrap { box-sizing: border-box; position: relative; height: 0; width: 100%; padding: 0 0 100% 0; margin: 0.6em 0 0em; }\n\n.component-color .color-box-wrap .color-box-container { position: absolute; height: 99.97%; width: 100%; left: 0; top: 0; }\n\n.component-color .color-box-wrap .color-box-container .color-box { float: left; cursor: pointer; -webkit-tap-highlight-color: transparent; }\n\n.component-color .color-box-wrap .color-box-container .color-box.rounded-tl { border-top-left-radius: 0.25rem; }\n\n.component-color .color-box-wrap .color-box-container .color-box.rounded-tr { border-top-right-radius: 0.25rem; }\n\n.component-color .color-box-wrap .color-box-container .color-box.rounded-bl { border-bottom-left-radius: 0.25rem; }\n\n.component-color .color-box-wrap .color-box-container .color-box.rounded-br { border-bottom-right-radius: 0.25rem; }\n\n.component-color .color-box-wrap .color-box-container .color-box.selected { -webkit-transform: scale(1.15); transform: scale(1.15); border-radius: 0.25rem; box-shadow: #111 0 0 0.24rem; position: relative; z-index: 100; }\n"; + +},{}],12:[function(require,module,exports){ +module.exports = ".component-input { display: block; }\n\n.component-input .label { padding-bottom: 0.7rem; }\n\n.component-input .input { position: relative; min-width: 100%; margin-top: 0.7rem; margin-left: 0; }\n\n.component-input input { display: block; width: 100%; background: #333333; border-radius: 0.25rem; padding: 0.35rem 0.375rem; border: none; vertical-align: baseline; color: #ffffff; font-size: inherit; }\n\n.component-input input::-webkit-input-placeholder { color: #858585; }\n\n.component-input input::-moz-placeholder { color: #858585; }\n\n.component-input input:-moz-placeholder { color: #858585; }\n\n.component-input input:-ms-input-placeholder { color: #858585; }\n\n.component-input input:focus { border: none; box-shadow: none; }\n\n.component-input input:focus::-webkit-input-placeholder { color: #666666; }\n\n.component-input input:focus::-moz-placeholder { color: #666666; }\n\n.component-input input:focus:-moz-placeholder { color: #666666; }\n\n.component-input input:focus:-ms-input-placeholder { color: #666666; }\n"; + +},{}],13:[function(require,module,exports){ +module.exports = ".component-select { position: relative; }\n\n.component-select .value { position: relative; padding-right: 1.1rem; }\n\n.component-select .value:after { content: \"\"; position: absolute; right: 0; top: 50%; margin-top: -0.1rem; height: 0; width: 0; border-left: 0.425rem solid transparent; border-right: 0.425rem solid transparent; border-top: 0.425rem solid #ececec; }\n\n.component-select select { opacity: 0; position: absolute; display: block; left: 0; right: 0; top: 0; bottom: 0; background: #000; width: 100%; border: none; margin: 0; padding: 0; }\n"; + +},{}],14:[function(require,module,exports){ +module.exports = ".component-toggle input { display: none; }\n\n.component-toggle .graphic { display: inline-block; position: relative; }\n\n.component-toggle .graphic .slide { display: block; border-radius: 1.05rem; height: 1.05rem; width: 2.2652rem; background: #2f2f2f; -webkit-transition: background-color 150ms linear; transition: background-color 150ms linear; }\n\n.component-toggle .graphic .marker { background: #ececec; width: 1.4rem; height: 1.4rem; border-radius: 1.4rem; position: absolute; left: 0; display: block; top: -0.175rem; -webkit-transition: -webkit-transform 150ms linear; transition: -webkit-transform 150ms linear; transition: transform 150ms linear; transition: transform 150ms linear, -webkit-transform 150ms linear; box-shadow: #2f2f2f 0 0.1rem 0.1rem; }\n\n.component-toggle input:checked + .graphic .slide { background: #993d19; }\n\n.component-toggle input:checked + .graphic .marker { background: #ff4700; -webkit-transform: translateX(0.8652rem); transform: translateX(0.8652rem); }\n"; + +},{}],15:[function(require,module,exports){ +module.exports = "
\n \n
\n
\n
\n
\n
\n
\n
\n
\n"; + +},{}],16:[function(require,module,exports){ +module.exports = "\n"; + +},{}],17:[function(require,module,exports){ +module.exports = "
\n \n
\n"; + +},{}],18:[function(require,module,exports){ +module.exports = "\n"; + +},{}],19:[function(require,module,exports){ +module.exports = "\n"; + +},{}],20:[function(require,module,exports){ +module.exports = "
\n \n {{{label}}}\n \n
\n"; + +},{}],21:[function(require,module,exports){ +module.exports = "
\n

\n
\n"; + +},{}],22:[function(require,module,exports){ +module.exports = "\n"; + +},{}],23:[function(require,module,exports){ +module.exports = "
"; + +},{}],"pebble-clay":[function(require,module,exports){ +'use strict'; + +var configPageHtml = require('./tmp/config-page.html'); +var toSource = require('tosource'); +var standardComponents = require('./src/scripts/components'); + +/** + * @param {string} input + * @returns {string} + */ +function encodeDataUri(input) { + if (window.btoa) { + return 'data:text/html;base64,' + encodeURIComponent(window.btoa(input)); + } + + // iOS doesn't have a window so we need to polyfil window.btoa + // extracted from https://github.com/inexorabletash/polyfill + var B64_ALPHABET = + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + input = String(input); + var position = 0; + var out = []; + var o1; + var o2; + var o3; + var e1; + var e2; + var e3; + var e4; + + if (/[^\x00-\xFF]/.test(input)) { throw Error('InvalidCharacterError'); } + + while (position < input.length) { + o1 = input.charCodeAt(position++); + o2 = input.charCodeAt(position++); + o3 = input.charCodeAt(position++); + + // 111111 112222 222233 333333 + e1 = o1 >> 2; + e2 = ((o1 & 0x3) << 4) | (o2 >> 4); + e3 = ((o2 & 0xf) << 2) | (o3 >> 6); + e4 = o3 & 0x3f; + + if (position === input.length + 2) { + e3 = 64; + e4 = 64; + } else if (position === input.length + 1) { + e4 = 64; + } + + out.push(B64_ALPHABET.charAt(e1), + B64_ALPHABET.charAt(e2), + B64_ALPHABET.charAt(e3), + B64_ALPHABET.charAt(e4)); + } + + return 'data:text/html;base64,' + encodeURIComponent(out.join('')); +} + +/** + * @param {Array} config - the Clay config + * @param {function} [customFn] - custom code to run from the config page. + * Will run with api as context + * @constructor + */ +function Clay(config, customFn) { + var self = this; + + self.config = config; + self.customFn = customFn || function() {}; + self.components = []; + + /** + * @private + * @param {Clay~ConfigItem|Array} item + * @return {void} + */ + function _registerStandardComponents(item) { + if (Array.isArray(item)) { + item.forEach(function(item) { + _registerStandardComponents(item); + }); + } else if (item.type === 'section') { + _registerStandardComponents(item.items); + } else if (standardComponents[item.type]) { + self.registerComponent(standardComponents[item.type]); + } + } + + _registerStandardComponents(self.config); +} + +Clay.prototype.registerComponent = function(component) { + this.components.push(component); +}; + +/** + * Generate the Data URI used by the config Page with settings injected + * @param {string} returnTo - used while developing on desktop. + * @return {string} + */ +Clay.prototype.generateUrl = function(returnTo) { + var settings; + try { + settings = JSON.parse(localStorage.getItem('clay-settings')) || {}; + } catch (e) { + console.error(e); + settings = {}; + } + + // Show config page + return encodeDataUri(configPageHtml + .replace('$$CUSTOM_FN$$', toSource(this.customFn)) + .replace('$$RETURN_TO$$', returnTo || 'pebblejs://close#') + .replace('$$CONFIG$$', toSource(this.config)) + .replace('$$SETTINGS$$', toSource(settings)) + .replace('$$COMPONENTS$$', toSource(this.components)) + ); +}; + +/** + * Parse the response from the webviewclosed event data + * @param {string} response + * @returns {{}} + */ +Clay.prototype.getSettings = function(response) { + // Decode and parse config data as JSON + var settings = JSON.parse(decodeURIComponent(response)); + // @todo get defaults in here + if (!settings) return {}; + + localStorage.setItem('clay-settings', JSON.stringify(settings)); + return settings; +}; + +module.exports = Clay; + +},{"./src/scripts/components":5,"./tmp/config-page.html":23,"tosource":1}]},{},["pebble-clay"])("pebble-clay") +}); \ No newline at end of file diff --git a/package.json b/package.json index 7c445dc..193ae62 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pebble-clay", - "version": "1.0.0", + "version": "0.1.0", "description": "Pebble Config Framework", "main": "dist/clay.js", "directories": { @@ -8,14 +8,14 @@ }, "scripts": { "test-travis": "./node_modules/.bin/karma start ./test/karma.conf.js --single-run --browsers chromeTravisCI && ./node_modules/.bin/eslint ./", - "test-debug": "export DEBUG=true; ./node_modules/.bin/karma start ./test/karma.conf.js --no-single-run", + "test-debug": "DEBUG=true && ./node_modules/.bin/karma start ./test/karma.conf.js --no-single-run", "test": "./node_modules/.bin/karma start ./test/karma.conf.js --single-run", "lint": "./node_modules/.bin/eslint ./", "build": "gulp" }, "repository": { "type": "git", - "url": "git+https://github.com/keegan-lillo/pebble-clay.git" + "url": "git+https://github.com/pebble/clay.git" }, "keywords": [ "Pebble", @@ -24,10 +24,11 @@ "author": "Keegan Lillo", "license": "GPL", "bugs": { - "url": "https://github.com/keegan-lillo/pebble-clay/issues" + "url": "https://github.com/pebble/clay/issues" }, - "homepage": "https://github.com/keegan-lillo/pebble-clay#readme", + "homepage": "https://github.com/pebble/clay#readme", "devDependencies": { + "pebble-clay-components": "git+https://github.com/pebble/clay-components.git#master", "browserify": "^13.0.0", "browserify-istanbul": "^0.2.1", "chai": "^3.4.1", diff --git a/src/scripts/components/color.js b/src/scripts/components/color.js deleted file mode 100644 index b728ff4..0000000 --- a/src/scripts/components/color.js +++ /dev/null @@ -1,107 +0,0 @@ -'use strict'; - -var HTML = require('../vendor/minified/minified').HTML; - -module.exports = { - name: 'color', - template: require('../../templates/components/color.tpl'), - manipulator: require('../lib/manipulators').val, - defaults: { - label: '' - }, - initialize: function() { - var self = this; - - /* eslint-disable comma-spacing, no-multi-spaces, max-len, - standard/array-bracket-even-spacing */ - var layout = self.config.layout || [ - [false , false , '#55FF00', '#AAFF55', false , '#FFFF55', '#FFFFAA', false , false ], - [false , '#AAFFAA', '#55FF55', '#00FF00', '#AAFF00', '#FFFF00', '#FFAA55', '#FFAAAA', false ], - ['#55FFAA', '#00FF55', '#00AA00', '#55AA00', '#AAAA55', '#AAAA00', '#FFAA00', '#FF5500', '#FF5555'], - ['#AAFFFF', '#00FFAA', '#00AA55', '#55AA55', '#005500', '#555500', '#AA5500', '#FF0000', '#FF0055'], - [false , '#55AAAA', '#00AAAA', '#005555', '#FFFFFF', '#000000', '#AA5555', '#AA0000', false ], - ['#55FFFF', '#00FFFF', '#00AAFF', '#0055AA', '#AAAAAA', '#555555', '#550000', '#AA0055', '#FF55AA'], - ['#55AAFF', '#0055FF', '#0000FF', '#0000AA', '#000055', '#550055', '#AA00AA', '#FF00AA', '#FFAAFF'], - [false , '#5555AA', '#5555FF', '#5500FF', '#5500AA', '#AA00FF', '#FF00FF', '#FF55FF', false ], - [false , false , false , '#AAAAFF', '#AA55FF', '#AA55AA', false , false , false ] - ]; - /* eslint-enable */ - - var grid = ''; - var itemWidth = 100 / layout[0].length; - var itemHeight = 100 / layout.length; - var $elem = self.$element; - - for (var i = 0; i < layout.length; i++) { - for (var j = 0; j < layout[i].length; j++) { - - var color = layout[i][j] || 'transparent'; - var selectable = (color !== 'transparent' ? ' selectable' : ''); - - var roundedTL = (i === 0 && j === 0) || i === 0 && !layout[i][j - 1] || - !layout[i][j - 1] && !layout[i - 1][j] ? - ' rounded-tl' : - ''; - - var roundedTR = i === 0 && !layout[i][j + 1] || - !layout[i][j + 1] && !layout[i - 1][j] ? - ' rounded-tr ' : - ''; - - var roundedBL = (i === layout.length - 1 && j === 0) || - i === layout.length - 1 && !layout[i][j - 1] || - !layout[i][j - 1] && !layout[i + 1][j] ? - ' rounded-bl' : - ''; - - var roundedBR = i === layout.length - 1 && !layout[i][j + 1] || - !layout[i][j + 1] && !layout[i + 1][j] ? - ' rounded-br' : - ''; - - grid += '' + - ''; - } - } - - $elem.select('.color-box-container').add(HTML(grid)); - - var $valueDisplay = $elem.select('.value'); - var $picker = $elem.select('.picker-wrap'); - var disabled = self.$manipulatorTarget.get('disabled'); - - $elem.on('click', function(ev) { - if (!disabled) { - $picker.set('show'); - } - }); - - self.on('change', function() { - var value = self.get().replace(/^0x/, '').toLowerCase(); - $valueDisplay.set('$background-color', '#' + value); - $elem.select('.color-box').set('-selected'); - $elem.select('.color-box[data-value="0x' + value + '"]').set('+selected'); - }); - - $elem.select('.color-box.selectable').on('click', function(ev) { - self.set(ev.target.dataset.value); - $picker.set('-show'); - }); - - self.on('disabled', function() { - disabled = true; - }); - - self.on('enabled', function() { - disabled = false; - }); - - } -}; diff --git a/src/scripts/components/footer.js b/src/scripts/components/footer.js deleted file mode 100644 index 6c761a1..0000000 --- a/src/scripts/components/footer.js +++ /dev/null @@ -1,10 +0,0 @@ -'use strict'; - -module.exports = { - name: 'footer', - template: require('../../templates/components/footer.tpl'), - manipulator: require('../lib/manipulators').html, - defaults: { - attributes: {} - } -}; diff --git a/src/scripts/components/heading.js b/src/scripts/components/heading.js deleted file mode 100644 index 0ad0058..0000000 --- a/src/scripts/components/heading.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; - -module.exports = { - name: 'heading', - template: require('../../templates/components/heading.tpl'), - manipulator: require('../lib/manipulators').html, - defaults: { - attributes: {}, - size: 4 - } -}; diff --git a/src/scripts/components/input.js b/src/scripts/components/input.js deleted file mode 100644 index 1495102..0000000 --- a/src/scripts/components/input.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; - -module.exports = { - name: 'input', - template: require('../../templates/components/input.tpl'), - manipulator: require('../lib/manipulators').val, - defaults: { - label: '', - attributes: {} - } -}; diff --git a/src/scripts/components/select.js b/src/scripts/components/select.js deleted file mode 100644 index 9716970..0000000 --- a/src/scripts/components/select.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict'; - -module.exports = { - name: 'select', - template: require('../../templates/components/select.tpl'), - manipulator: require('../lib/manipulators').val, - defaults: { - label: '', - options: [] - }, - initialize: function() { - var self = this; - - var $value = self.$element.select('.value'); - - self.on('change', function(ev) { - var value = self.$manipulatorTarget.select('option:checked').get('innerHTML'); - $value.set('innerHTML', value); - }); - } -}; diff --git a/src/scripts/components/submit.js b/src/scripts/components/submit.js deleted file mode 100644 index 5c856cf..0000000 --- a/src/scripts/components/submit.js +++ /dev/null @@ -1,10 +0,0 @@ -'use strict'; - -module.exports = { - name: 'submit', - template: require('../../templates/components/submit.tpl'), - manipulator: require('../lib/manipulators').val, - defaults: { - attributes: {} - } -}; diff --git a/src/scripts/components/text.js b/src/scripts/components/text.js deleted file mode 100644 index c35a7cd..0000000 --- a/src/scripts/components/text.js +++ /dev/null @@ -1,10 +0,0 @@ -'use strict'; - -module.exports = { - name: 'text', - template: require('../../templates/components/text.tpl'), - manipulator: require('../lib/manipulators').html, - defaults: { - attributes: {} - } -}; diff --git a/src/scripts/components/toggle.js b/src/scripts/components/toggle.js deleted file mode 100644 index c3c3bd3..0000000 --- a/src/scripts/components/toggle.js +++ /dev/null @@ -1,10 +0,0 @@ -'use strict'; - -module.exports = { - name: 'toggle', - template: require('../../templates/components/toggle.tpl'), - manipulator: require('../lib/manipulators').checked, - defaults: { - attributes: {} - } -}; diff --git a/src/scripts/config-page.js b/src/scripts/config-page.js index 0d5ddc2..a7152f7 100755 --- a/src/scripts/config-page.js +++ b/src/scripts/config-page.js @@ -15,14 +15,14 @@ var clayConfig = new ClayConfig(settings, config, $mainForm); clayConfig.on(clayConfig.EVENTS.BEFORE_BUILD, function() { // register components here - this.registerComponent(require('./components/heading')); - this.registerComponent(require('./components/text')); - this.registerComponent(require('./components/footer')); - this.registerComponent(require('./components/input')); - this.registerComponent(require('./components/color')); - this.registerComponent(require('./components/select')); - this.registerComponent(require('./components/toggle')); - this.registerComponent(require('./components/submit')); + this.registerComponent(require('pebble-clay-components/dist/components/heading')); + this.registerComponent(require('pebble-clay-components/dist/components/text')); + this.registerComponent(require('pebble-clay-components/dist/components/footer')); + this.registerComponent(require('pebble-clay-components/dist/components/input')); + this.registerComponent(require('pebble-clay-components/dist/components/color')); + this.registerComponent(require('pebble-clay-components/dist/components/select')); + this.registerComponent(require('pebble-clay-components/dist/components/toggle')); + this.registerComponent(require('pebble-clay-components/dist/components/submit')); }); clayConfig.on(clayConfig.EVENTS.AFTER_BUILD, function() { diff --git a/src/scripts/lib/clay-config.js b/src/scripts/lib/clay-config.js index 02e9260..7badb62 100644 --- a/src/scripts/lib/clay-config.js +++ b/src/scripts/lib/clay-config.js @@ -19,6 +19,7 @@ var ClayItem = require('./clay-item'); var utils = require('../lib/utils'); var ClayEvents = require('./clay-events'); var componentStore = require('./component-registry'); +var manipulators = require('./manipulators'); /** * @extends ClayEvents @@ -154,20 +155,8 @@ function ClayConfig(settings, config, $rootContainer) { return _settings; }; - /** - * Register a component to Clay. This must be called prior to .build(); - * @param {{}} component - the clay component to register - * @param {string} component.name - the name of the component - * @param {string} component.template - HTML template to use for the component - * @param {{}} component.manipulator - methods to attach to the component - * @param {function} component.manipulator.set - set manipulator method - * @param {function} component.manipulator.get - get manipulator method - * @param {{}} component.defaults - template defaults - * @param {function} [component.initialize] - method to scaffold the component - */ - self.registerComponent = function(component) { - componentStore[component.name] = component; - }; + // @todo maybe don't do this and force the static method + self.registerComponent = ClayConfig.registerComponent; /** * Build the config page. This must be run before any of the get methods can be run @@ -189,4 +178,23 @@ function ClayConfig(settings, config, $rootContainer) { } +/** + * Register a component to Clay. This must be called prior to .build(); + * @param {{}} component - the clay component to register + * @param {string} component.name - the name of the component + * @param {string} component.template - HTML template to use for the component + * @param {string|{}} component.manipulator - methods to attach to the component + * @param {function} component.manipulator.set - set manipulator method + * @param {function} component.manipulator.get - get manipulator method + * @param {{}} component.defaults - template defaults + * @param {function} [component.initialize] - method to scaffold the component + */ +ClayConfig.registerComponent = function(component) { + var _component = _.copyObj(component); + if (typeof _component.manipulator === 'string') { + _component.manipulator = manipulators[component.manipulator]; + } + componentStore[_component.name] = _component; +}; + module.exports = ClayConfig; diff --git a/src/scripts/lib/clay-item.js b/src/scripts/lib/clay-item.js index fdd2ac8..268f1d5 100644 --- a/src/scripts/lib/clay-item.js +++ b/src/scripts/lib/clay-item.js @@ -14,14 +14,14 @@ var ClayEvents = require('./clay-events'); function ClayItem(config) { var self = this; - var _itemType = componentRegistry[config.type]; + var _component = componentRegistry[config.type]; - if (!_itemType) { + if (!_component) { throw new Error('the component: ' + config.type + ' is not registered. ' + 'Make sure to register it with ClayConfig.registerComponent()'); } - var _templateData = _.extend({}, _itemType.defaults, config); + var _templateData = _.extend({}, _component.defaults, config); /** @type {string|null} */ self.id = config.id || null; @@ -33,7 +33,7 @@ function ClayItem(config) { self.config = config; /** @type {M} */ - self.$element = HTML(_.formatHtml(_itemType.template, _templateData)); + self.$element = HTML(_.formatHtml(_component.template, _templateData)); /** @type {M} */ self.$manipulatorTarget = self.$element.select('[data-manipulator-target]'); @@ -48,8 +48,8 @@ function ClayItem(config) { * @returns {ClayItem} */ self.initialize = function() { - if (typeof _itemType.initialize === 'function') { - _itemType.initialize.apply(self, arguments); + if (typeof _component.initialize === 'function') { + _component.initialize.apply(self, arguments); } return self; }; @@ -58,7 +58,7 @@ function ClayItem(config) { ClayEvents.call(self, self.$manipulatorTarget); // attach the manipulator methods to the clayItem - _.eachObj(_itemType.manipulator, function(methodName, method) { + _.eachObj(_component.manipulator, function(methodName, method) { self[methodName] = method.bind(self); }); diff --git a/src/styles/config-page.scss b/src/styles/config-page.scss index cc984dd..a3f2046 100755 --- a/src/styles/config-page.scss +++ b/src/styles/config-page.scss @@ -3,9 +3,3 @@ @import "partials/reset"; @import "fonts"; @import "base"; - -@import "items/color"; -@import "items/toggle"; -@import "items/input"; -@import "items/select"; -@import "items/button"; diff --git a/src/styles/items/_button.scss b/src/styles/items/_button.scss deleted file mode 100644 index a789ef6..0000000 --- a/src/styles/items/_button.scss +++ /dev/null @@ -1,61 +0,0 @@ -@import "../partials/vars"; - -.item-button { -} - - -button, -.button { - @include font-pfdin(medium); - text-transform: uppercase; - background-color: $color-gray-4; - border-radius: $border-radius; - font-size: 1rem; - line-height: 1; - border: none; - display: block; - - color: $color-white; - min-width: 12rem; - text-align: center; - margin: 0 auto; - -webkit-tap-highlight-color: rgba(0,0,0,0); - - padding: $button-padding; - - .platform-ios & { - padding: $button-padding-ios; - } - - &:disabled { - background-color: $color-gray-3; - color: $color-gray-8; - } - - &:not(:disabled):active { - background-color: $color-gray-8; - } - - &.orange, &[type="submit"] { - background-color: $color-orange; - - &:disabled { - background-color: $color-orange-dark; - color: $color-gray-3; - } - - &:not(:disabled):active { - background-color: $color-red; - } - } - - &.light-grey { - background-color: $color-gray-5; - } - -} - -a.button { - text-decoration: none; - color: $color-white; -} diff --git a/src/styles/items/_color.scss b/src/styles/items/_color.scss deleted file mode 100644 index 3213800..0000000 --- a/src/styles/items/_color.scss +++ /dev/null @@ -1,91 +0,0 @@ -@import "../partials/vars"; - -.item-color { - - .value { - width: $small-component-width; - height: $base-height; - border-radius: $base-height / 2; - box-shadow: $box-shadow-small-components; - } - - input:disabled ~ .value, - input:disabled ~ .label { - opacity: 0.25; - } - - .picker-wrap { - left: 0; - top: 0; - top: 0; - right: 0; - bottom: 0; - position: fixed; - padding: 1rem; - background: rgba(0,0,0,0.7); - opacity: 0; - transition: opacity 70ms ease-in 175ms; - pointer-events: none; - z-index: 100; - - .picker { - padding: 1rem; - background: $color-gray-11; - border-radius: $border-radius; - } - - &.show { - transition-delay: 0ms; - pointer-events: auto; - opacity: 1; - } - } - - .color-box-wrap { - box-sizing: border-box; - position: relative; - height: 0; - width: 100%; - padding: 0 0 100% 0; // overridden with inline style - margin: 0.6em 0 0em; - - .color-box-container { - position: absolute; - height: 99.97%; - width: 100%; - left: 0; - top: 0; - - .color-box { - float:left; - cursor: pointer; - -webkit-tap-highlight-color: rgba(0,0,0,0); - - &.rounded-tl { - border-top-left-radius: $border-radius; - } - - &.rounded-tr { - border-top-right-radius: $border-radius; - } - - &.rounded-bl { - border-bottom-left-radius: $border-radius; - } - - &.rounded-br { - border-bottom-right-radius: $border-radius; - } - - &.selected { - transform: scale(1.15); - border-radius: $border-radius; - box-shadow: #111 0 0 0.24rem; - position: relative; - z-index: 100; - } - } - - } - } -} diff --git a/src/styles/items/_input.scss b/src/styles/items/_input.scss deleted file mode 100644 index ae1f455..0000000 --- a/src/styles/items/_input.scss +++ /dev/null @@ -1,43 +0,0 @@ -@import "../partials/vars"; -@import "../partials/mixins"; - - -.item-input { - - display: block; - - .label { - padding-bottom: $item-spacing-v; - } - - .input { - position: relative; - min-width: 100%; - margin-top: $item-spacing-v; - margin-left: 0; - } - - input { - display:block; - width: 100%; - background: $color-gray-2; - border-radius: $border-radius; - padding: $item-spacing-v / 2 $item-spacing-h / 2; - border: none; - vertical-align: baseline; - color: $color-white; - font-size: inherit; - - @include placeholder { - color: $color-gray-8; - } - - &:focus { - @include placeholder { - color: $color-gray-6; - } - border: none; - box-shadow: none ; - } - } -} diff --git a/src/styles/items/_select.scss b/src/styles/items/_select.scss deleted file mode 100644 index 5a8697b..0000000 --- a/src/styles/items/_select.scss +++ /dev/null @@ -1,36 +0,0 @@ -@import "../vendor/bourbon/bourbon"; -@import "../partials/vars"; - -.item-select { - position: relative; - - .value { - $triangle-size: 0.85rem; - position: relative; - padding-right: $triangle-size + 0.25rem; - - &:after { - content: ""; - position: absolute; - right: 0; - top: 50%; - margin-top: -0.1rem; - @include triangle($triangle-size, $color-gray-10, down); - } - } - - select { - opacity: 0; - position: absolute; - display: block; - left: 0; - right: 0; - top: 0; - bottom: 0; - background: #000; - width: 100%; - border: none; - margin:0; - padding:0; - } -} diff --git a/src/styles/items/_toggle.scss b/src/styles/items/_toggle.scss deleted file mode 100644 index 144ed60..0000000 --- a/src/styles/items/_toggle.scss +++ /dev/null @@ -1,51 +0,0 @@ -@import "../partials/vars"; - -.item-toggle { - - $slide-height: $base-height * 0.75; - $slide-width: $small-component-width; - $marker-diameter: $base-height; - - input { - display: none; // @todo make sure this doesnt mess up interactivity on iOS - } - - .graphic { - display: inline-block; - position: relative; - - .slide { - display:block; - border-radius: $slide-height; - height: $slide-height; - width: $slide-width; - background: $color-gray-1; - transition: background-color 150ms linear; - } - - .marker { - background: $color-gray-10; - width: $marker-diameter; - height: $marker-diameter; - border-radius: $marker-diameter; - position: absolute; - left: 0; - display: block; - top: ($marker-diameter - $slide-height) / 2 * -1; - transition: transform 150ms linear; - box-shadow: $box-shadow-small-components; - } - } - - input:checked + .graphic { - .slide { - background: $color-orange-dark; - } - - .marker { - background: $color-orange; - transform: translateX($slide-width - $marker-diameter); - } - } - -} diff --git a/src/templates/components/color.tpl b/src/templates/components/color.tpl deleted file mode 100755 index b5692b8..0000000 --- a/src/templates/components/color.tpl +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/src/templates/components/footer.tpl b/src/templates/components/footer.tpl deleted file mode 100755 index 3724a0d..0000000 --- a/src/templates/components/footer.tpl +++ /dev/null @@ -1,6 +0,0 @@ - diff --git a/src/templates/components/heading.tpl b/src/templates/components/heading.tpl deleted file mode 100755 index 932cdc1..0000000 --- a/src/templates/components/heading.tpl +++ /dev/null @@ -1,3 +0,0 @@ -
- -
diff --git a/src/templates/components/input.tpl b/src/templates/components/input.tpl deleted file mode 100755 index 42b2eca..0000000 --- a/src/templates/components/input.tpl +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/src/templates/components/select.tpl b/src/templates/components/select.tpl deleted file mode 100755 index f6c17aa..0000000 --- a/src/templates/components/select.tpl +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/src/templates/components/submit.tpl b/src/templates/components/submit.tpl deleted file mode 100755 index 004695d..0000000 --- a/src/templates/components/submit.tpl +++ /dev/null @@ -1,9 +0,0 @@ -
- -
diff --git a/src/templates/components/text.tpl b/src/templates/components/text.tpl deleted file mode 100644 index de4a843..0000000 --- a/src/templates/components/text.tpl +++ /dev/null @@ -1,3 +0,0 @@ -
-

-
diff --git a/src/templates/components/toggle.tpl b/src/templates/components/toggle.tpl deleted file mode 100755 index a223472..0000000 --- a/src/templates/components/toggle.tpl +++ /dev/null @@ -1,14 +0,0 @@ - diff --git a/test/fixture.js b/test/fixture.js index 65c9362..5de3a27 100644 --- a/test/fixture.js +++ b/test/fixture.js @@ -10,11 +10,11 @@ var idCounter = 0; var componentRegistry = require('../src/scripts/lib/component-registry'); // add some components to the registry to test -componentRegistry.text = require('../src/scripts/components/text'); -componentRegistry.input = require('../src/scripts/components/input'); -componentRegistry.toggle = require('../src/scripts/components/toggle'); -componentRegistry.footer = require('../src/scripts/components/footer'); -componentRegistry.select = require('../src/scripts/components/select'); +ClayConfig.registerComponent(require('pebble-clay-components/dist/components/text')); +ClayConfig.registerComponent(require('pebble-clay-components/dist/components/input')); +ClayConfig.registerComponent(require('pebble-clay-components/dist/components/toggle')); +ClayConfig.registerComponent(require('pebble-clay-components/dist/components/footer')); +ClayConfig.registerComponent(require('pebble-clay-components/dist/components/select')); /** * @param {string|{}} config diff --git a/test/karma-debug.conf.js b/test/karma-debug.conf.js new file mode 100644 index 0000000..52fd02e --- /dev/null +++ b/test/karma-debug.conf.js @@ -0,0 +1,87 @@ +'use strict'; + +// Karma configuration +// Generated on Mon Jan 25 2016 15:19:28 GMT-0800 (PST) + +module.exports = function(config) { + config.set({ + + // base path that will be used to resolve all patterns (eg. files, exclude) + basePath: '..', + + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ['browserify', 'mocha'], + + browserify: { + debug: true, + plugin: [ + [ + 'sourcemapify', + { root: '/Users/keegan/eclipse_workspace/pebble-clay' } + ] + ], + transform: [ + [ + 'stringify', + { extensions: ['.html', '.tpl'] } + ], + 'deamdify' + ] + }, + + // list of files / patterns to load in the browser + files: [ + 'test/spec/**/*.js' + ], + + // list of files to exclude + exclude: [], + + // preprocess matching files before serving them to the browser + // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor + preprocessors: { + 'test/spec/**/*.js': ['browserify'] + }, + + // Which plugins to enable + plugins: [ + 'karma-chrome-launcher', + 'karma-mocha', + 'karma-mocha-reporter', + 'karma-browserify' + ], + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + reporters: ['progress', 'mocha'], + + // web server port + port: 9877, + + // enable / disable colors in the output (reporters and logs) + colors: true, + + // level of logging + // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN + // || config.LOG_INFO || config.LOG_DEBUG + logLevel: config.LOG_INFO, + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: true, + + // start these browsers + // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher + browsers: ['Chrome'], + + // Continuous Integration mode + // if true, Karma captures browsers, runs the tests and exits + singleRun: true, + + // Concurrency level + // how many browser should be started simultaneous + concurrency: Infinity + }); +}; + diff --git a/test/spec/lib/clay-config.js b/test/spec/lib/clay-config.js index daa33e7..8ae5433 100644 --- a/test/spec/lib/clay-config.js +++ b/test/spec/lib/clay-config.js @@ -2,7 +2,7 @@ var assert = require('chai').assert; var sinon = require('sinon'); -var textComponent = require('../../../src/scripts/components/text'); +var textComponent = require('pebble-clay-components/dist/components/text'); var componentRegistry = require('../../../src/scripts/lib/component-registry'); var checkReadOnly = require('../../test-utils').checkReadOnly; var fixtures = require('../../fixture'); @@ -128,6 +128,8 @@ describe('ClayConfig', function() { clayConfig.build(); }); + + // @todo test for validation }); describe('.build()', function() {