/**
* Input(TODO resize)
* @param {type} $
* @param {type} window
* @param {type} document
* @returns {undefined}
*/
(function($, window, document) {
var CLASS_ICON = $.className('icon');
var CLASS_ICON_CLEAR = $.className('icon-clear');
var CLASS_ICON_SPEECH = $.className('icon-speech');
var CLASS_ICON_SEARCH = $.className('icon-search');
var CLASS_ICON_PASSWORD = $.className('icon-eye');
var CLASS_INPUT_ROW = $.className('input-row');
var CLASS_PLACEHOLDER = $.className('placeholder');
var CLASS_TOOLTIP = $.className('tooltip');
var CLASS_HIDDEN = $.className('hidden');
var CLASS_FOCUSIN = $.className('focusin');
var SELECTOR_ICON_CLOSE = '.' + CLASS_ICON_CLEAR;
var SELECTOR_ICON_SPEECH = '.' + CLASS_ICON_SPEECH;
var SELECTOR_ICON_PASSWORD = '.' + CLASS_ICON_PASSWORD;
var SELECTOR_PLACEHOLDER = '.' + CLASS_PLACEHOLDER;
var SELECTOR_TOOLTIP = '.' + CLASS_TOOLTIP;
var findRow = function(target) {
for (; target && target !== document; target = target.parentNode) {
if (target.classList && target.classList.contains(CLASS_INPUT_ROW)) {
return target;
}
}
return null;
};
var Input = function(element, options) {
this.element = element;
this.options = options || {
actions: 'clear'
};
if (~this.options.actions.indexOf('slider')) { //slider
this.sliderActionClass = CLASS_TOOLTIP + ' ' + CLASS_HIDDEN;
this.sliderActionSelector = SELECTOR_TOOLTIP;
} else { //clear,speech,search
if (~this.options.actions.indexOf('clear')) {
this.clearActionClass = CLASS_ICON + ' ' + CLASS_ICON_CLEAR + ' ' + CLASS_HIDDEN;
this.clearActionSelector = SELECTOR_ICON_CLOSE;
}
if (~this.options.actions.indexOf('speech')) { //only for 5+
this.speechActionClass = CLASS_ICON + ' ' + CLASS_ICON_SPEECH;
this.speechActionSelector = SELECTOR_ICON_SPEECH;
}
if (~this.options.actions.indexOf('search')) {
this.searchActionClass = CLASS_PLACEHOLDER;
this.searchActionSelector = SELECTOR_PLACEHOLDER;
}
if (~this.options.actions.indexOf('password')) {
this.passwordActionClass = CLASS_ICON + ' ' + CLASS_ICON_PASSWORD;
this.passwordActionSelector = SELECTOR_ICON_PASSWORD;
}
}
this.init();
};
Input.prototype.init = function() {
this.initAction();
this.initElementEvent();
};
Input.prototype.initAction = function() {
var self = this;
var row = self.element.parentNode;
if (row) {
if (self.sliderActionClass) {
self.sliderAction = self.createAction(row, self.sliderActionClass, self.sliderActionSelector);
} else {
if (self.searchActionClass) {
self.searchAction = self.createAction(row, self.searchActionClass, self.searchActionSelector);
self.searchAction.addEventListener('tap', function(e) {
$.focus(self.element);
e.stopPropagation();
});
}
if (self.speechActionClass) {
self.speechAction = self.createAction(row, self.speechActionClass, self.speechActionSelector);
self.speechAction.addEventListener('click', $.stopPropagation);
self.speechAction.addEventListener('tap', function(event) {
self.speechActionClick(event);
});
}
if (self.clearActionClass) {
self.clearAction = self.createAction(row, self.clearActionClass, self.clearActionSelector);
self.clearAction.addEventListener('tap', function(event) {
self.clearActionClick(event);
});
}
if (self.passwordActionClass) {
self.passwordAction = self.createAction(row, self.passwordActionClass, self.passwordActionSelector);
self.passwordAction.addEventListener('tap', function(event) {
self.passwordActionClick(event);
});
}
}
}
};
Input.prototype.createAction = function(row, actionClass, actionSelector) {
var action = row.querySelector(actionSelector);
if (!action) {
var action = document.createElement('span');
action.className = actionClass;
if (actionClass === this.searchActionClass) {
action.innerHTML = '' + this.element.getAttribute('placeholder') + '';
this.element.setAttribute('placeholder', '');
if (this.element.value.trim()) {
row.classList.add($.className('active'));
}
}
row.insertBefore(action, this.element.nextSibling);
}
return action;
};
Input.prototype.initElementEvent = function() {
var element = this.element;
if (this.sliderActionClass) {
var tooltip = this.sliderAction;
var timer = null;
var showTip = function() { //每次重新计算是因为控件可能被隐藏,初始化时计算是不正确的
tooltip.classList.remove(CLASS_HIDDEN);
var offsetLeft = element.offsetLeft;
var width = element.offsetWidth - 28;
var tooltipWidth = tooltip.offsetWidth;
var distince = Math.abs(element.max - element.min);
var scaleWidth = (width / distince) * Math.abs(element.value - element.min);
tooltip.style.left = (14 + offsetLeft + scaleWidth - tooltipWidth / 2) + 'px';
tooltip.innerText = element.value;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(function() {
tooltip.classList.add(CLASS_HIDDEN);
}, 1000);
};
element.addEventListener('input', showTip);
element.addEventListener('tap', showTip);
element.addEventListener($.EVENT_MOVE, function(e) {
e.stopPropagation();
});
} else {
if (this.clearActionClass) {
var action = this.clearAction;
if (!action) {
return;
}
$.each(['keyup', 'change', 'input', 'focus', 'cut', 'paste'], function(index, type) {
(function(type) {
element.addEventListener(type, function() {
action.classList[element.value.trim() ? 'remove' : 'add'](CLASS_HIDDEN);
});
})(type);
});
element.addEventListener('blur', function() {
action.classList.add(CLASS_HIDDEN);
});
}
if (this.searchActionClass) {
element.addEventListener('focus', function() {
element.parentNode.classList.add($.className('active'));
});
element.addEventListener('blur', function() {
if (!element.value.trim()) {
element.parentNode.classList.remove($.className('active'));
}
});
}
}
};
Input.prototype.setPlaceholder = function(text) {
if (this.searchActionClass) {
var placeholder = this.element.parentNode.querySelector(SELECTOR_PLACEHOLDER);
placeholder && (placeholder.getElementsByTagName('span')[1].innerText = text);
} else {
this.element.setAttribute('placeholder', text);
}
};
Input.prototype.passwordActionClick = function(event) {
if (this.element.type === 'text') {
this.element.type = 'password';
} else {
this.element.type = 'text';
}
this.passwordAction.classList.toggle($.className('active'));
event.preventDefault();
};
Input.prototype.clearActionClick = function(event) {
var self = this;
self.element.value = '';
$.focus(self.element);
self.clearAction.classList.add(CLASS_HIDDEN);
event.preventDefault();
};
Input.prototype.speechActionClick = function(event) {
if (window.plus) {
var self = this;
var oldValue = self.element.value;
self.element.value = '';
document.body.classList.add(CLASS_FOCUSIN);
plus.speech.startRecognize({
engine: 'iFly'
}, function(s) {
self.element.value += s;
$.focus(self.element);
plus.speech.stopRecognize();
$.trigger(self.element, 'recognized', {
value: self.element.value
});
if (oldValue !== self.element.value) {
$.trigger(self.element, 'change');
$.trigger(self.element, 'input');
}
// document.body.classList.remove(CLASS_FOCUSIN);
}, function(e) {
document.body.classList.remove(CLASS_FOCUSIN);
});
} else {
alert('only for 5+');
}
event.preventDefault();
};
$.fn.input = function(options) {
var inputApis = [];
this.each(function() {
var inputApi = null;
var actions = [];
var row = findRow(this.parentNode);
if (this.type === 'range' && row.classList.contains($.className('input-range'))) {
actions.push('slider');
} else {
var classList = this.classList;
if (classList.contains($.className('input-clear'))) {
actions.push('clear');
}
if (!($.os.android && $.os.stream) && classList.contains($.className('input-speech'))) {
actions.push('speech');
}
if (classList.contains($.className('input-password'))) {
actions.push('password');
}
if (this.type === 'search' && row.classList.contains($.className('search'))) {
actions.push('search');
}
}
var id = this.getAttribute('data-input-' + actions[0]);
if (!id) {
id = ++$.uuid;
inputApi = $.data[id] = new Input(this, {
actions: actions.join(',')
});
for (var i = 0, len = actions.length; i < len; i++) {
this.setAttribute('data-input-' + actions[i], id);
}
} else {
inputApi = $.data[id];
}
inputApis.push(inputApi);
});
return inputApis.length === 1 ? inputApis[0] : inputApis;
};
$.ready(function() {
$($.classSelector('.input-row input')).input();
});
})(mui, window, document);