From 32dc8bff9e9f308970533207943ea192c4264af8 Mon Sep 17 00:00:00 2001 From: Dmitry Filatov Date: Wed, 5 Feb 2014 15:32:13 +0400 Subject: [PATCH] input: get rid of polling (close #287) --- .../input/__control/input__control.bemhtml | 2 +- .../input/__control/input__control.bh.js | 2 +- .../input/_has-clear/input_has-clear.bemhtml | 5 +- .../input/_has-clear/input_has-clear.bh.js | 7 +- .../input/_has-clear/input_has-clear.js | 5 +- .../input/_polling/input_polling.bemhtml | 3 + .../input/_polling/input_polling.bh.js | 9 +++ .../input/_polling/input_polling.deps.js | 3 + common.blocks/input/_polling/input_polling.js | 50 +++++++++++++ common.blocks/input/input.js | 9 ++- desktop.blocks/input/input.deps.js | 4 +- desktop.blocks/input/input.js | 72 +++++-------------- touch.blocks/input/input.js | 14 ---- 13 files changed, 104 insertions(+), 81 deletions(-) create mode 100644 common.blocks/input/_polling/input_polling.bemhtml create mode 100644 common.blocks/input/_polling/input_polling.bh.js create mode 100644 common.blocks/input/_polling/input_polling.deps.js create mode 100644 common.blocks/input/_polling/input_polling.js delete mode 100644 touch.blocks/input/input.js diff --git a/common.blocks/input/__control/input__control.bemhtml b/common.blocks/input/__control/input__control.bemhtml index 794599a48..49e5c03b8 100644 --- a/common.blocks/input/__control/input__control.bemhtml +++ b/common.blocks/input/__control/input__control.bemhtml @@ -13,7 +13,7 @@ block('input').elem('control')( placeholder : input.placeholder }; - input.autocomplete === false && (attrs.autocomplete = 'off'); + input.autocomplete !== true && (attrs.autocomplete = 'off'); this.mods.disabled && (attrs.disabled = 'disabled'); return attrs; diff --git a/common.blocks/input/__control/input__control.bh.js b/common.blocks/input/__control/input__control.bh.js index 08edd68ef..9e40d6700 100644 --- a/common.blocks/input/__control/input__control.bh.js +++ b/common.blocks/input/__control/input__control.bh.js @@ -13,7 +13,7 @@ module.exports = function(bh) { placeholder : input.placeholder }; - input.autocomplete === false && (attrs.autocomplete = 'off'); + input.autocomplete !== true && (attrs.autocomplete = 'off'); json.blockMods.disabled && (attrs.disabled = 'disabled'); ctx.attrs(attrs); diff --git a/common.blocks/input/_has-clear/input_has-clear.bemhtml b/common.blocks/input/_has-clear/input_has-clear.bemhtml index a0bad53b8..7dc2af5a0 100644 --- a/common.blocks/input/_has-clear/input_has-clear.bemhtml +++ b/common.blocks/input/_has-clear/input_has-clear.bemhtml @@ -1,4 +1,7 @@ block('input').mod('has-clear', true).elem('box') .content()(function() { - return [this.ctx.content, { elem : 'clear' }]; + return [ + this.ctx.content, + { elem : 'clear', mods : { visible : !!this._input.val } } + ]; }); diff --git a/common.blocks/input/_has-clear/input_has-clear.bh.js b/common.blocks/input/_has-clear/input_has-clear.bh.js index 15d3f2fc1..b045bad42 100644 --- a/common.blocks/input/_has-clear/input_has-clear.bh.js +++ b/common.blocks/input/_has-clear/input_has-clear.bh.js @@ -1,7 +1,12 @@ module.exports = function(bh) { bh.match('input_has-clear__box', function(ctx) { - ctx.content([ctx.content(), { elem : 'clear' }], true); + ctx.content( + [ + ctx.content(), + { elem : 'clear', mods : { visible : !!ctx.tParam('_input').val } } + ], + true); }); }; diff --git a/common.blocks/input/_has-clear/input_has-clear.js b/common.blocks/input/_has-clear/input_has-clear.js index 65ac124fa..04ba347b9 100644 --- a/common.blocks/input/_has-clear/input_has-clear.js +++ b/common.blocks/input/_has-clear/input_has-clear.js @@ -5,10 +5,7 @@ provide(Input.decl({ modName : 'has-clear', modVal : true }, { 'js' : { 'inited' : function() { this.__base.apply(this, arguments); - - this - .on('change', this._updateClear) - ._updateClear(); + this.on('change', this._updateClear); } } }, diff --git a/common.blocks/input/_polling/input_polling.bemhtml b/common.blocks/input/_polling/input_polling.bemhtml new file mode 100644 index 000000000..24be8ba11 --- /dev/null +++ b/common.blocks/input/_polling/input_polling.bemhtml @@ -0,0 +1,3 @@ +block('input').mod('polling', true).js()(function() { + return this.extend(applyNext(), { live : false }); +}); diff --git a/common.blocks/input/_polling/input_polling.bh.js b/common.blocks/input/_polling/input_polling.bh.js new file mode 100644 index 000000000..251556a1b --- /dev/null +++ b/common.blocks/input/_polling/input_polling.bh.js @@ -0,0 +1,9 @@ +module.exports = function(bh) { + + bh.match('input_polling', function(ctx) { + ctx + .applyBase() + .extend(ctx.js(), { live : false }); + }); + +}; diff --git a/common.blocks/input/_polling/input_polling.deps.js b/common.blocks/input/_polling/input_polling.deps.js new file mode 100644 index 000000000..b35d25267 --- /dev/null +++ b/common.blocks/input/_polling/input_polling.deps.js @@ -0,0 +1,3 @@ +({ + shouldDeps : ['idle', 'tick'] +}) \ No newline at end of file diff --git a/common.blocks/input/_polling/input_polling.js b/common.blocks/input/_polling/input_polling.js new file mode 100644 index 000000000..5e5332595 --- /dev/null +++ b/common.blocks/input/_polling/input_polling.js @@ -0,0 +1,50 @@ +modules.define('input', ['tick', 'idle'], function(provide, tick, idle, Input) { + +var instances = [], + boundToTick, + bindToTick = function() { + boundToTick = true; + tick + .on('tick', update) + .start(); + idle + .on({ + idle : function() { + tick.un('tick', update); + }, + wakeup : function() { + tick.on('tick', update); + } + }) + .start(); + }, + update = function() { + var instance, i = 0; + while(instance = instances[i++]) { + instance.setVal(instance.elem('control').val()); + } + }; + +provide(Input.decl({ modName : 'polling', modVal : true }, { + onSetMod : { + 'js' : { + 'inited' : function() { + this.__base.apply(this, arguments); + + boundToTick || bindToTick(); + + this._instanceIndex = instances.push(this) - 1; + }, + + '' : function() { + this.__base.apply(this, arguments); + + instances.splice(this._instanceIndex, 1); + var i = this._instanceIndex, instance; + while(instance = instances[i++]) --instance._instanceIndex; + } + } + } +})); + +}); \ No newline at end of file diff --git a/common.blocks/input/input.js b/common.blocks/input/input.js index 527a5167b..f29355a26 100644 --- a/common.blocks/input/input.js +++ b/common.blocks/input/input.js @@ -48,11 +48,16 @@ provide(BEMDOM.decl({ block : this.name, baseBlock : Control }, /** @lends input } return this; + }, + + _tryToUpdateVal : function() { + this.setVal(this.elem('control').val()); } }, { live : function() { - this.__base.apply(this, arguments); - return false; + return this + .liveBindTo('control', 'input', this.prototype._tryToUpdateVal) + .__base(); } })); diff --git a/desktop.blocks/input/input.deps.js b/desktop.blocks/input/input.deps.js index 9ab96d7e1..f38bbf014 100644 --- a/desktop.blocks/input/input.deps.js +++ b/desktop.blocks/input/input.deps.js @@ -1,7 +1,7 @@ [{ - shouldDeps : ['tick', 'idle'] + shouldDeps : ['ua'] }, { tech : 'spec.js', shouldDeps : { tech : 'js', block : 'dom' } -}] +}] \ No newline at end of file diff --git a/desktop.blocks/input/input.js b/desktop.blocks/input/input.js index 364b1ffc5..65a6199d8 100644 --- a/desktop.blocks/input/input.js +++ b/desktop.blocks/input/input.js @@ -1,69 +1,31 @@ -modules.define('input', ['tick', 'idle'], function(provide, tick, idle, Input) { +modules.define('input', ['ua'], function(provide, ua, Input) { -var instances = [], - boundToTick, - bindToTick = function() { - boundToTick = true; - tick - .on('tick', update) - .start(); - idle - .on({ - idle : function() { - tick.un('tick', update); - }, - wakeup : function() { - tick.on('tick', update); - } - }) - .start(); - }, - update = function() { - var instance, i = 0; - while(instance = instances[i++]) { - instance.setVal(instance.elem('control').val()); - } - }; - -provide(Input.decl({ - onSetMod : { - 'js' : { - 'inited' : function() { - this.__base.apply(this, arguments); - - boundToTick || bindToTick(); - - // сохраняем индекс в массиве инстансов чтобы потом быстро из него удалять - this._instanceIndex = instances.push(this) - 1; - }, - - '' : function() { - this.__base.apply(this, arguments); - - // удаляем из общего массива instances - instances.splice(this._instanceIndex, 1); - // понижаем _instanceIndex всем тем кто был добавлен в instances после нас - var i = this._instanceIndex, instance; - while(instance = instances[i++]) --instance._instanceIndex; - } - } - }, +if(!ua.msie || ua.version >= 10) { + provide(Input); + return; +} +provide(Input.decl('input', { /** - * Нормализация установки фокуса для IE - * @private - * @override + * Normalizes focus for IE */ _focus : function() { var input = this.elem('control')[0]; - if(input.createTextRange && !input.selectionStart) { + if(!input.selectionStart) { var range = input.createTextRange(); range.move('character', input.value.length); range.select(); - } else { - input.focus(); } } +}, { + live : function() { + this.liveBindTo('keyup cut paste', function() { + // nextTick because when `cut` and `paste` events callbacks are executed, real value is not changed + this.nextTick(this._tryToUpdateVal); + }); + + return this.__base(); + } })); }); diff --git a/touch.blocks/input/input.js b/touch.blocks/input/input.js deleted file mode 100644 index 19e5381b3..000000000 --- a/touch.blocks/input/input.js +++ /dev/null @@ -1,14 +0,0 @@ -modules.define('input', function(provide, Input) { - -provide(Input.decl({ - _onInputChanged : function() { - this.setVal(this.elem('control').val()); - } -}, { - live : function() { - this.liveBindTo('control', 'input', this.prototype._onInputChanged); - return this.__base.apply(this, arguments); - } -})); - -});