Created
April 7, 2016 11:48
-
-
Save lexmihaylov/cfe23bb074fd650cea52533af768f123 to your computer and use it in GitHub Desktop.
Word processor for selection highlighter meant to be used with GoogleChrome's speechSynthesis engine.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
'use strict'; | |
/** | |
* List of all punctuation marks that are allowed in the sanitized text | |
* Note: this can be extended in the future | |
* @type {String} | |
* @const | |
*/ | |
var AllowedPunctuatio = ":!\\?\\.,'`<>\\+\\-=/\\\\"; | |
/** | |
* a list of punctuation marks that should be highligted seperately if | |
* there is no sentence event | |
* @type {String} | |
* @const | |
*/ | |
var ReadablePunctuation = ":!\\?\\.,<>\\+\\-=/\\\\"; | |
AllowedPunctuatio = ":!\\?\\.,'`<>\\+\\-=/\\\\"; | |
ReadablePunctuation = "<>=/\\\\"; | |
/** | |
* regexp to strip unreadable symbols | |
* @type {RegExp} | |
* @const | |
*/ | |
var SymbolStrip = new RegExp('[^'+AllowedPunctuatio+'\\w]', 'gi'); | |
/** | |
* regexp for finding begin index | |
* @type {RegExp} | |
* @const | |
*/ | |
var BeginIndexRegEx = new RegExp('[\\w'+ReadablePunctuation+']', 'gi'); | |
/** | |
* regexp for finding end index | |
* @type {RegExp} | |
* @const | |
*/ | |
var EndIndexRegEx = new RegExp('[\\s'+ReadablePunctuation+']', 'gi'); | |
function sanitize(text) { | |
text = text.replace(/\u2013/g, '-'); | |
text = text.replace(/\u2014/g, '-'); | |
text = text.replace(/\u2019/g, '\''); | |
text = text.replace(/\u2018/g, '\''); | |
text = text.replace(/\n/g, ' '); | |
text = text.replace(/\r/g, ' '); | |
text = text.replace(/\t/g, ' '); | |
// strip unreadable symbols | |
text = text.replace(SymbolStrip, function(match, position) { | |
return Array(match.length + 1).join(' '); | |
}.bind(this)); | |
return text; | |
} | |
function getTextNodesIn(elem) { | |
var textNodes = []; | |
if (elem) { | |
for (var nodes = elem.childNodes, i = 0; i < nodes.length; i++) { | |
var node = nodes[i], nodeType = node.nodeType; | |
if (nodeType == 3) { | |
textNodes.push(node); | |
} else if (nodeType == 1 || nodeType == 9 || nodeType == 11) { | |
textNodes = textNodes.concat(getTextNodesIn(node)); | |
} | |
} | |
} | |
return textNodes; | |
} | |
function processItem(node, selections) { | |
var index = 0; | |
var str = sanitize(node.data); | |
var start; | |
var end; | |
var endReached = false; | |
if($(node).closest('.mjx-chtml').length > 0) { | |
return; | |
} | |
if($(node).closest('script').length > 0) { | |
return; | |
} | |
while(true) { | |
start = str.slice(index).search(BeginIndexRegEx); | |
if(start == -1) { | |
break; | |
} | |
start += index; | |
if((new RegExp('['+ReadablePunctuation+']', 'gi')).test(str[start])) { | |
end = start + 1; | |
} else { | |
end = str.slice(start).search(EndIndexRegEx); | |
if(end == -1) { | |
end = str.length; | |
endReached = true; | |
} else { | |
end += start; | |
} | |
} | |
var range = document.createRange(); | |
range.setStart(node, start); | |
range.setEnd(node, end); | |
selections.push({ | |
node: node, | |
range: range | |
}); | |
if(endReached) { | |
break; | |
} | |
index = end; | |
} | |
} | |
function process(textNodes) { | |
var selections = []; | |
var item; | |
for(var i = 0; i < textNodes.length; i++) { | |
item = textNodes[i]; | |
processItem(item, selections); | |
} | |
return selections; | |
} | |
var nodes = getTextNodesIn($('.text').get(0)); | |
var selections = process(nodes); | |
for(var i = 0; i < selections.length; i++) { | |
(function(item, i) { | |
setTimeout(function() { | |
document.getSelection().removeAllRanges(); | |
var range = item.range; | |
document.getSelection().addRange(range); | |
}, i*500) | |
}(selections[i], i)) | |
} | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment