/home/ivoiecob/email.hirewise-va.com/modules/MailWebclient/js/koBindingSearchHighlighter.js
'use strict';
var
_ = require('underscore'),
$ = require('jquery'),
ko = require('knockout')
;
function getCaretOffset(oElement)
{
var
oSel = null,
oRange = {},
oPreSelectionRange = {},
iStart = 0
;
if (window.getSelection && document.createRange)
{
oSel = window.getSelection();
if (oSel.rangeCount > 0)
{
oRange = oSel.getRangeAt(0);
oPreSelectionRange = oRange.cloneRange();
oPreSelectionRange.selectNodeContents(oElement);
oPreSelectionRange.setEnd(oRange.startContainer, oRange.startOffset);
iStart = oPreSelectionRange.toString().length;
if ($(oElement).html().length < iStart)
{
iStart = 0;
}
}
}
else if (document.selection && document.body.createTextRange)
{
oRange = document.selection.createRange();
oPreSelectionRange = document.body.createTextRange();
oPreSelectionRange.moveToElementText(oElement);
if (typeof(oPreSelectionRange.setEndPoint) === 'function')
{
oPreSelectionRange.setEndPoint('EndToStart', oRange);
}
iStart = oPreSelectionRange.text.length;
}
return iStart;
}
function setCursor(oElement, iCaretPos)
{
var
range,
selection,
textRange
;
if (!oElement)
{
return false;
}
else if(document.createRange)
{
range = document.createRange();
range.selectNodeContents(oElement);
range.setStart(oElement, iCaretPos);
range.setEnd(oElement, iCaretPos);
selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
}
else if(oElement.createTextRange)
{
textRange = oElement.createTextRange();
textRange.collapse(true);
textRange.moveEnd(iCaretPos);
textRange.moveStart(iCaretPos);
textRange.select();
return true;
}
else if(oElement.setSelectionRange)
{
oElement.setSelectionRange(iCaretPos, iCaretPos);
return true;
}
return false;
}
ko.bindingHandlers.highlighter = {
'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) {
var
jqEl = $(oElement),
oOptions = fValueAccessor(),
oValueObserver = oOptions.valueObserver ? oOptions.valueObserver : null,
oHighlighterValueObserver = oOptions.highlighterValueObserver ? oOptions.highlighterValueObserver : null,
oHighlightTrigger = oOptions.highlightTrigger ? oOptions.highlightTrigger : null,
aHighlightWords = ['from:', 'to:', 'subject:', 'text:', 'email:', 'has:', 'date:', 'text:', 'body:', 'folders:'],
rPattern = (function () {
var sPatt = '';
$.each(aHighlightWords, function(i, oEl) {
sPatt = (!i) ? (sPatt + '\\b' + oEl) : (sPatt + '|\\b' + oEl);
});
return new RegExp('(' + sPatt + ')', 'g');
}()),
fClear = function (sStr) {
return sStr.replace(/\xC2\xA0/g, ' ').replace(/\xA0/g, ' ').replace(/[\s]+/g, ' ');
},
iPrevKeyCode = -1,
sUserLanguage = window.navigator.language || window.navigator.userLanguage,
aTabooLang = ['zh', 'zh-TW', 'zh-CN', 'zh-HK', 'zh-SG', 'zh-MO', 'ja', 'ja-JP', 'ko', 'ko-KR', 'vi', 'vi-VN', 'th', 'th-TH'],// , 'ru', 'ru-RU'
bHighlight = !_.include(aTabooLang, sUserLanguage)
;
$(oElement)
.on('keydown', function (oEvent) {
return oEvent.keyCode !== Enums.Key.Enter;
})
.on('keyup', function (oEvent) {
var
aMoveKeys = [Enums.Key.Left, Enums.Key.Right, Enums.Key.Home, Enums.Key.End],
bMoveKeys = -1 !== $.inArray(oEvent.keyCode, aMoveKeys)
;
if (!(
oEvent.keyCode === Enums.Key.Shift ||
oEvent.keyCode === Enums.Key.Alt ||
oEvent.keyCode === Enums.Key.Ctrl ||
// for international english -------------------------
oEvent.keyCode === Enums.Key.Dash ||
oEvent.keyCode === Enums.Key.Apostrophe ||
oEvent.keyCode === Enums.Key.Six && oEvent.shiftKey ||
// ---------------------------------------------------
bMoveKeys ||
((oEvent.ctrlKey || iPrevKeyCode === Enums.Key.Ctrl) && oEvent.keyCode === Enums.Key.a)
))
{
oValueObserver(fClear(jqEl.text()));
highlight(false);
}
iPrevKeyCode = oEvent.keyCode;
return true;
})
.on('paste', function (oEvent) {
if (document.queryCommandSupported('insertText'))
{
// cancel paste
oEvent.preventDefault();
// get text representation of clipboard
var sText = '';
if (oEvent.clipboardData || oEvent.originalEvent.clipboardData)
{
sText = (oEvent.originalEvent || oEvent).clipboardData.getData('text/plain');
}
else if (window.clipboardData)
{
sText = window.clipboardData.getData('Text');
}
// insert text manually
document.execCommand('insertText', false, sText);
// insertText command doesn't work in IE
// paste command causes looping in IE
// so there is no clearing text in IE for now
}
setTimeout(function () {
oValueObserver(fClear(jqEl.text()));
highlight(false);
}, 0);
});
// highlight on init
setTimeout(function () {
highlight(true);
}, 0);
function highlight(bNotRestoreSel) {
if(bHighlight)
{
var
iCaretPos = 0,
sContent = jqEl.text(),
aContent = sContent.split(rPattern),
aDividedContent = [],
sReplaceWith = '<span class="search_highlight"' + '>$&</span>'
;
_.each(aContent, function (sEl) {
var aEl = sEl.split('');
if (_.any(aHighlightWords, function (oAnyEl) {return oAnyEl === sEl;}))
{
_.each(aEl, function (sElem) {
aDividedContent.push($(sElem.replace(/(.)/, sReplaceWith)));
});
}
else
{
_.each(aEl, function(sElem) {
if(sElem === ' ')
{
// space fix for firefox
aDividedContent.push(document.createTextNode('\u00A0'));
}
else
{
aDividedContent.push(document.createTextNode(sElem));
}
});
}
});
if (!jqEl.is(':focus'))
{
// Don't set focus if the field wasn't focused before.
// It may affect on viewing messages in the list using the up and down buttons.
jqEl.empty().append(aDividedContent);
}
else
{
iCaretPos = getCaretOffset(oElement);
jqEl.empty().append(aDividedContent);
setCursor(oElement, iCaretPos);
}
}
}
oHighlightTrigger.notifySubscribers();
oHighlightTrigger.subscribe(function (bNotRestoreSel) {
setTimeout(function () {
highlight(!!bNotRestoreSel);
}, 0);
}, this);
oHighlighterValueObserver.subscribe(function () {
var
sElemText = jqEl.text(),
sValue = oValueObserver()
;
if (sElemText.replace('\u00A0', ' ') !== sValue.replace('\u00A0', ' '))
{
jqEl.text(sValue);
}
}, this);
}
};