Mercurial > code > home > repos > homeauto
diff service/pilight/static/input-number/input-number.js @ 945:752e620f1293
add input-rgb polymer element
Ignore-this: 2ba2ef39af2ef4f6c14036c5ac188e97
darcs-hash:20140712183250-312f9-dbe5a232f2d861b3088e314e2cd53ff70ce839d3
author | drewp <drewp@bigasterisk.com> |
---|---|
date | Sat, 12 Jul 2014 11:32:50 -0700 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/pilight/static/input-number/input-number.js Sat Jul 12 11:32:50 2014 -0700 @@ -0,0 +1,229 @@ +(function() { + + var style = document.createElement('style'); + style.type = 'text/css'; + var css = 'body.ew-resize, body.ew-resize * {cursor: ew-resize; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;}\n'; + style.appendChild(document.createTextNode(css)); + document.getElementsByTagName('head')[0].appendChild(style); + + var validKeys = [46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 189, 190, 37, 38, 39, 40, 8, 9]; + + var oldValue, selection, range, rect; + + var delta = 0; + var deltaStep = 5; + var x = 0; + var y = 0; + var xOld = 0; + + Polymer({ + + __doc__: { + element: 'input-number', + description: 'Input element for numeric data type.', + status: 'alpha', + url: 'https://github.com/arodic/input-number/', + demo: 'http://arodic.github.com/input-number/', + attributes: [ + { name: 'value', type: 'number', description: 'Input value.' }, + { name: 'min', type: 'number', description: 'Minimum value.' }, + { name: 'max', type: 'number', description: 'Maximum value.' }, + { name: 'step', type: 'number', description: 'Value increment when dragging in powers of 10.' }, + { name: 'toDeg', type: 'boolean', description: 'Converts displayed value to degrees.' }, + { name: 'editable', type: 'boolean', description: 'Determines if the input can be edited.' } + ], + properties: [], + methods: [], + events: [ + { + name: 'input-changed', + description: 'Fires when value attribute is changed.' + } + ] + }, + + value: 0, + min: -Infinity, + max: Infinity, + step: -3, + toDeg: false, + editable: true, + displayValue: 0, + ready: function() { + this.setAttribute('tabindex', 0); + this.setAttribute('contenteditable', true); + this.setAttribute('spellcheck', false); + this.addEventListener('keydown', this.onKeydown.bind(this)); + this.addEventListener('focus', this.onFocus.bind(this)); + this.addEventListener('blur', this.onBlur.bind(this)); + + // TODO: make better on mobile + this.$.blocker.addEventListener('dblclick', this.onFocus.bind(this)); + this.$.blocker.addEventListener('contextmenu', this.onFocus.bind(this)); + this.$.blocker.addEventListener('mousedown', this.onStartDrag.bind(this)); + this.$.blocker.addEventListener('touchstart', this.onStartDrag.bind(this)); + + this.addEventListener('keydown', this.onKeydown.bind(this)); + this.addEventListener('mouseover', this.updateBlocker.bind(this)); + + }, + domReady: function() { + this.stepChanged(); + this.displayValueChanged(); + this.updateBlocker(); + }, + onStartDrag: function(event) { + // event.stopPropagation(); + event.preventDefault(); + event = event.changedTouches ? event.changedTouches[0] : event; + + document.body.classList.add('ew-resize'); + xOld = event.clientX; + delta = 0; + document.activeElement.blur(); + this._onDrag = this.onDrag.bind(this); + this._onEndDrag = this.onEndDrag.bind(this); + document.addEventListener('mousemove', this._onDrag, false); + document.addEventListener('mouseup', this._onEndDrag, false); + this.addEventListener('touchmove', this._onDrag, false); + this.addEventListener('touchend', this._onEndDrag, false); + this.addEventListener('touchcancel', this._onEndDrag, false); + this.addEventListener('touchleave', this._onEndDrag, false); + }, + onEndDrag: function(event) { + // event.stopPropagation(); + event = event.changedTouches ? event.changedTouches[0] : event; + + document.body.classList.remove('ew-resize'); + document.removeEventListener('mousemove', this._onDrag, false); + document.removeEventListener('mouseup', this._onEndDrag, false); + this.removeEventListener('touchmove', this._onDrag, false); + this.removeEventListener('touchend', this._onEndDrag, false); + this.removeEventListener('touchcancel', this._onEndDrag, false); + this.removeEventListener('touchleave', this._onEndDrag, false); + }, + onDrag: function(event) { + // event.stopPropagation(); + // TODO: add acceleration + if (!this.editable) return; + if (event.type == 'mousemove' && event.which === 0) { + this._onEndDrag(event); + return; + } + + oldValue = this.value; + + event = event.changedTouches ? event.changedTouches[0] : event; + + x = event.clientX; + y = event.clientY; + delta += x - xOld; + xOld = event.clientX; + + while (Math.abs(delta) > deltaStep) { + if (delta > deltaStep) { + if (this.toDeg) this.value += Math.pow(10, this.step) / 180 * Math.PI; + else this.value += Math.pow(10, this.step); + delta -= deltaStep; + } + if (delta < -deltaStep) { + if (this.toDeg) this.value -= Math.pow(10, this.step) / 180 * Math.PI; + else this.value -= Math.pow(10, this.step); + delta += deltaStep; + } + } + this.value = Math.max(this.value, this.min); + this.value = Math.min(this.value, this.max); + if (this.value != oldValue) this.fire('input-changed', { input: this, oldValue: oldValue, newValue: this.value, delta: this.value - oldValue }); + }, + + onKeydown: function(event) { + // TODO: number keyboard on mobile + event.stopPropagation(); + if(event.which == 13) { + selection = window.getSelection(); + selection.removeAllRanges(); + this.blur(); + return; + } + + oldValue = this.value; + + if (!this.editable || validKeys.indexOf(event.which) == -1) { + event.preventDefault(); + return; + } + setTimeout(function(){ + this.updateValue(); + this.fire('input-changed', { input: this, oldValue: oldValue, newValue: this.value, delta: this.value - oldValue }); + }.bind(this), 1); + + }, + onFocus: function(event) { + event.preventDefault(); + selection = window.getSelection(); + selection.removeAllRanges(); + range = document.createRange(); + this.textContent = this.displayValue; + range.selectNodeContents(this); + selection.addRange(range); + this.focused = true; + }, + onBlur: function() { + this.updateValue(); + selection = window.getSelection(); + selection.removeAllRanges(); + this.focused = false; + this.updateValue(); + this.valueChanged(); + this._match = this.displayValue.toString().match(this.regEx); + this.textContent = this._match ? parseFloat(this._match[1]) : this.displayValue; + }, + updateValue: function() { + if (!isNaN(this.textContent) && (this.textContent.slice(-1) != '.')) { + if (this.toDeg) + this.value = parseFloat(this.textContent) / 180 * Math.PI; + else + this.value = parseFloat(this.textContent); + } + }, + updateBlocker: function() { + rect = this.getBoundingClientRect(); + this.$.blocker.style.width = rect.width + 'px'; + this.$.blocker.style.height = rect.height + 'px'; + }, + valueChanged: function() { + if (this.value < this.min) this.min = this.value; + if (this.value > this.max) this.max = this.value; + + if (!this.focused) { + if (this.toDeg) + this.displayValue = this.value / Math.PI * 180; + else + this.displayValue = this.value; + } + }, + displayValueChanged: function() { + this._match = this.displayValue.toString().match(this.regEx); + this.textContent = this._match ? parseFloat(this._match[1]) : this.displayValue; + this.updateBlocker(); + }, + toDegChanged: function() { + this.valueChanged(); + }, + minChanged: function() { + this.value = Math.max(this.value, this.min); + }, + maxChanged: function() { + this.value = Math.min(this.value, this.max); + }, + stepChanged: function() { + if (this.step < 0) { + this.regEx = new RegExp("(^-?\\d+\\.\\d{" + Math.abs(this.step) + "})(\\d)"); + } else { + this.regEx = new RegExp("(^-?\\d+\\.\\d{" + 1 + "})(\\d)"); + } + } + }); + +})();