-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Broke some pages #4
Comments
Another related issue is that when navigating though GitHub, the recent text node fix doesn't work. That's because document.ready is not triggered [1]. We should find a similar callback for pjax. [1] http://stackoverflow.com/questions/8103449/document-ready-not-triggered-with-pjax |
HI. $(function() {
var codeArea = $(".js-file-line-container");
var fileLineContainer='.js-file-line-container';
var lastPage = location.href;
// function wrapTextNodes(el){
// console.log('wrapping',el)
// el.find(".js-file-line").contents().filter(function () {
// return this.nodeType == Node.TEXT_NODE;
// }).each(function () {
// $(this).replaceWith('<span>' + $(this).text() + '</span>');
// });}
function wrapTextNodes(query) {
// Why did all the gawd dam text selection stuff fail, urgggggghh....atleast this worked!
function getTextNodesIn(elem, opt_fnFilter) {
var textNodes = [];
if (elem) {
for (var nodes = elem.childNodes, i = nodes.length; i--;) {
var node = nodes[i],
nodeType = node.nodeType;
if (nodeType == 3) {
if (!opt_fnFilter || opt_fnFilter(node, elem)) {
textNodes.push(node);
}
} else if (nodeType == 1 || nodeType == 9 || nodeType == 11) {
textNodes = textNodes.concat(getTextNodesIn(node, opt_fnFilter));
}
}
}
return textNodes;
}
var el = document.querySelector(query);
if (!el) return;
var results = getTextNodesIn(el);
results.forEach(function(node) {
var span = document.createElement('span');
span.textContent = node.nodeValue;
if (node.parentNode) node.parentNode.replaceChild(span, node);
})
}
wrapTextNodes(fileLineContainer);
// watch for page updating...
var whatToObserve = {
childList: true,
attributes: false,
subtree: true,
attributeOldValue: false /*, attributeFilter: []*/
};
var mutationObserver = new MutationObserver(function(mutationRecords) {
if (location.href != lastPage) {
lastPage = location.href;
wrapTextNodes(fileLineContainer);
}
});
mutationObserver.observe(document.querySelector('.file-navigation .breadcrumb'), whatToObserve);
function restore() {
$(".ghs-highlight").removeClass("ghs-highlight");
$(".ghs-partial-highlight").contents().unwrap();
}
function replaceAll(str, target, replacement) {
return str.split(target).join(replacement);
}
$("body").mouseup(function(e) {
restore();
var codeArea = $(fileLineContainer); // think the page updating killed this, this fixs that
var selection = $.trim(window.getSelection());
if (selection) {
codeArea.find("span:not(:has(*))").each(function() {
if (this != e.target) {
if ($(this).text() == selection) {
$(this).addClass("ghs-highlight");
}
else if ($(this).text().indexOf(selection) > -1) {
$(this).html(function(_, html) {
return replaceAll(html, selection, '<span class="ghs-partial-highlight">' + selection + '</span>');
});
}
}
});
}
});
}); OH, and update the webstore :P |
Look Mah!!! No JQuery!!! (function() {
var fileLineContainer = '.js-file-line-container';
var lastPage = location.href;
var textNodes;
function wrapTextNodes(query) {
// Why did all the gawd dam text selection stuff fail, urgggggghh....atleast this worked! http://cwestblog.com/2014/03/14/javascript-getting-all-text-nodes/
function getTextNodesIn(elem, opt_fnFilter) {
if (elem) {
for (var nodes = elem.childNodes, i = nodes.length; i--;) {
var node = nodes[i],
nodeType = node.nodeType;
if (nodeType == 3) {
if (!opt_fnFilter || opt_fnFilter(node, elem)) {
if (node.nodeValue.trim() != '') textNodes.push(node);
}
} else if (nodeType == 1 || nodeType == 9 || nodeType == 11) {
getTextNodesIn(node, opt_fnFilter)
}
}
}
}
var el = document.querySelector(query);
if (!el) return;
textNodes = [];
getTextNodesIn(el);
textNodes.forEach(function(node, index) {
var span = document.createElement('span');
span.textContent = node.nodeValue;
node.parentNode.replaceChild(span, node);
textNodes[index] = span;
});
}
wrapTextNodes(fileLineContainer);
// watch for page updating...
var whatToObserve = {
childList: true,
attributes: false,
subtree: false,
attributeOldValue: false /*, attributeFilter: []*/
};
var mutationObserver = new MutationObserver(function(mutationRecords) {
if (location.href != lastPage) {
lastPage = location.href;
wrapTextNodes(fileLineContainer);
}
});
mutationObserver.observe(document.querySelector('#js-repo-pjax-container'), whatToObserve);
function restore() {
[].forEach.call(document.querySelectorAll(".ghs-highlight"), function(el) {
el.classList.remove("ghs-highlight");
});
[].forEach.call(document.querySelectorAll(".ghs-partial-highlight"), function(el) {
el.parentNode.replaceChild(el.childNodes[0], el);
});
}
function replaceAll(str, target, replacement) {
return str.split(target).join(replacement);
}
document.body.addEventListener('mouseup', function(e) {
restore();
var selection = window.getSelection().toString().trim();
if (selection) {
textNodes.forEach(function(el) {
if (el != e.target) {
if (el.textContent == selection) {
el.classList.add("ghs-highlight");
} else if (el.textContent.indexOf(selection) > -1) {
el.innerHTML = replaceAll(el.innerHTML, selection, '<span class="ghs-partial-highlight">' + selection + '</span>');
}
}
});
}
});
})(); hehe, couldnt resist, small things should be small....seems to work ;) |
And here it is with the ability to highlight things in the same element and when stuff is highlighted you can use ctrl+Up and ctrl+Down to go through highlights......do what ever you want with it......let me guess, its gonna sit here and rot :P (function() {
var fileLineContainer = '.js-file-line-container';
var lastPage = location.href;
var textNodes = [];
var highlighted = [];
var highlightedIndex;
function wrapTextNodes(query) {
// Why did all the gawd dam text selection stuff fail, urgggggghh....atleast this worked!
function getTextNodesIn(elem, opt_fnFilter) {
if (elem) {
for (var nodes = elem.childNodes, i = nodes.length; i--;) {
var node = nodes[i],
nodeType = node.nodeType;
if (nodeType == 3) {
if (!opt_fnFilter || opt_fnFilter(node, elem)) {
if (node.nodeValue.trim() != '') textNodes.push(node);
}
} else if (nodeType == 1 || nodeType == 9 || nodeType == 11) {
getTextNodesIn(node, opt_fnFilter)
}
}
}
}
var el = document.querySelector(query);
if (!el) return;
textNodes = [];
getTextNodesIn(el);
textNodes.forEach(function(node, index) {
var span = document.createElement('span');
span.textContent = node.nodeValue;
node.parentNode.replaceChild(span, node);
textNodes[index] = span;
});
textNodes.reverse();
}
wrapTextNodes(fileLineContainer);
// watch for page updating...
var whatToObserve = {
childList: true,
attributes: false,
subtree: false,
attributeOldValue: false /*, attributeFilter: []*/
};
var mutationObserver = new MutationObserver(function(mutationRecords) {
if (location.href != lastPage) {
lastPage = location.href;
wrapTextNodes(fileLineContainer);
}
});
mutationObserver.observe(document.querySelector('#js-repo-pjax-container'), whatToObserve);
function restore() {
highlighted.forEach(function(el) {
if (el.classList.contains('ghs-highlight')) el.classList.remove("ghs-highlight");
else {
var parent = el.parentNode;
parent.replaceChild(el.childNodes[0], el);
parent.normalize();
}
})
highlighted = [];
}
function selectElement(el) {
var range = document.createRange();
range.selectNodeContents(el);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
function splitReplace(el, str, selectionIndex) {
var strLength = str.length;
var source = el.textContent;
var pos = -1;
var lastPos = 0;
var result = document.createDocumentFragment();
var selected;
while ((pos = source.indexOf(str, pos + 1)) != -1) {
if (pos > lastPos) result.appendChild(document.createTextNode(source.substring(lastPos, pos)));
var highlight = document.createElement('span');
highlight.textContent = source.substring(pos, pos + strLength);
highlight.classList.add('ghs-partial-highlight');
if (pos === selectionIndex) {
selected = highlight;
highlightedIndex = highlighted.length;
}
result.appendChild(highlight);
highlighted.push(highlight);
lastPos = pos + strLength;
}
result.appendChild(document.createTextNode(source.substring(lastPos)));
el.replaceChild(result, el.childNodes[0]);
if (selected) selectElement(selected);
}
document.body.addEventListener('mousedown', function(e) {
if (e.which != 1 || highlighted.length == 0) return;
restore();
});
document.body.addEventListener('mouseup', function(e) {
if (e.which != 1) return;
var selection = window.getSelection();
var selected = selection.toString().trim();
if (selected) {
textNodes.forEach(function(el) {
if (el.textContent == selected) {
el.classList.add("ghs-highlight");
if (el == e.target) highlightedIndex = highlighted.length;
highlighted.push(el);
} else if (el.textContent.indexOf(selected) > -1) {
if (el != e.target) splitReplace(el, selected);
else splitReplace(el, selected, Math.min(selection.anchorOffset, selection.focusOffset));
};
});
}
});
window.addEventListener('keydown', function(e) {
if (!highlighted.length > 0 || !e.ctrlKey) return;
if (e.keyCode == 38) { // down key
highlightedIndex--;
if (highlightedIndex < 0) highlightedIndex = highlighted.length - 1;
} else if (e.keyCode == 40) { // up key
highlightedIndex++;
if (highlightedIndex >= highlighted.length) highlightedIndex = 0;
} else return;
selectElement(highlighted[highlightedIndex]);
elShow(highlighted[highlightedIndex]);
e.preventDefault()
return false;
});
function elShow(el) {
var rect = el.getBoundingClientRect();
if (rect.bottom >= (window.innerHeight || document.documentElement.clientHeight)) el.scrollIntoView(false);
else if (rect.top <= 0) el.scrollIntoView(true);
}
var css = document.createElement("style");
css.type = "text/css";
css.innerHTML = ".ghs-highlight, .ghs-partial-highlight { border: 1px solid rgba(255, 181, 21, .6); background-color: rgba(255, 181, 21, .3);}";
document.body.appendChild(css);
})(); |
hehehe....I gotta stop and get back to the winamp thing, but..... (function() {
var fileLineContainer = '.js-file-line-container';
var lastPage = location.href;
var textNodes = [];
var highlighted = [];
var highlightedIndex;
function wrapTextNodes(query) {
// Why did all the gawd dam text selection stuff fail, urgggggghh....atleast this worked! http://cwestblog.com/2014/03/14/javascript-getting-all-text-nodes/
function getTextNodesIn(elem, opt_fnFilter) {
if (elem) {
for (var nodes = elem.childNodes, i = nodes.length; i--;) {
var node = nodes[i],
nodeType = node.nodeType;
if (nodeType == 3) {
if (!opt_fnFilter || opt_fnFilter(node, elem)) {
if (node.nodeValue.trim() != '') {
var span = document.createElement('span');
span.textContent = node.nodeValue;
node.parentNode.replaceChild(span, node);
textNodes.push(span);
}
}
} else if (nodeType == 1 || nodeType == 9 || nodeType == 11) {
getTextNodesIn(node, opt_fnFilter)
}
}
}
}
var el = document.querySelector(query);
if (!el) return;
textNodes = [];
getTextNodesIn(el);
textNodes.reverse();
}
wrapTextNodes(fileLineContainer);
// watch for page updating...
var whatToObserve = {
childList: true,
attributes: false,
subtree: false,
attributeOldValue: false /*, attributeFilter: []*/
};
var mutationObserver = new MutationObserver(function(mutationRecords) {
if (location.href != lastPage) {
lastPage = location.href;
wrapTextNodes(fileLineContainer);
}
});
mutationObserver.observe(document.querySelector('#js-repo-pjax-container'), whatToObserve);
function restore() {
highlighted.forEach(function(el) {
if (el.classList.contains('ghs-highlight')) el.classList.remove("ghs-highlight");
else {
var parent = el.parentNode;
parent.replaceChild(el.childNodes[0], el);
parent.normalize();
}
})
highlighted = [];
}
function selectElement(el) {
var range = document.createRange();
range.selectNodeContents(el);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
function splitReplace(el, str, selectionIndex) {
var strLength = str.length;
var source = el.textContent;
var pos = -1;
var lastPos = 0;
var result = document.createDocumentFragment();
var selected;
while ((pos = source.indexOf(str, pos + 1)) != -1) {
if (pos > lastPos) result.appendChild(document.createTextNode(source.substring(lastPos, pos)));
var highlight = document.createElement('span');
highlight.textContent = source.substring(pos, pos + strLength);
highlight.classList.add('ghs-partial-highlight');
if (pos === selectionIndex) {
selected = highlight;
highlightedIndex = highlighted.length;
}
result.appendChild(highlight);
highlighted.push(highlight);
lastPos = pos + strLength;
}
result.appendChild(document.createTextNode(source.substring(lastPos)));
el.replaceChild(result, el.childNodes[0]);
if (selected) selectElement(selected);
}
document.body.addEventListener('mousedown', function(e) {
if (e.which != 1 || highlighted.length == 0) return;
restore();
canvas.style.display = 'none';
});
document.body.addEventListener('mouseup', function(e) {
if (e.which != 1) return;
var selection = window.getSelection();
var selected = selection.toString().trim();
if (selected) {
textNodes.forEach(function(el) {
if (el.textContent == selected) {
el.classList.add("ghs-highlight");
if (el == e.target) highlightedIndex = highlighted.length;
highlighted.push(el);
} else if (el.textContent.indexOf(selected) > -1) {
if (el != e.target) splitReplace(el, selected);
else splitReplace(el, selected, Math.min(selection.anchorOffset, selection.focusOffset));
};
});
updateHighlighter();
}
});
window.addEventListener('keydown', function(e) {
if (!highlighted.length > 0 || !e.ctrlKey) return;
if (e.keyCode == 38) { // down key
highlightedIndex--;
if (highlightedIndex < 0) highlightedIndex = highlighted.length - 1;
} else if (e.keyCode == 40) { // up key
highlightedIndex++;
if (highlightedIndex >= highlighted.length) highlightedIndex = 0;
} else return;
selectElement(highlighted[highlightedIndex]);
elShow(highlighted[highlightedIndex]);
updateHighlighter();
e.preventDefault()
return false;
});
function elShow(el) {
var rect = el.getBoundingClientRect();
if (rect.bottom >= (window.innerHeight || document.documentElement.clientHeight)) el.scrollIntoView(false);
else if (rect.top <= 0) el.scrollIntoView(true);
}
// Do the Highlighter bar on the right
var canvas = document.createElement("canvas");
canvas.setAttribute('id', 'highlighternoconflict');
var canvasUpdating = false;
document.body.appendChild(canvas);
var ctx = canvas.getContext('2d');
function generateHighlighter() {
canvas.style.display = 'block';
canvas.height = document.documentElement.getBoundingClientRect().height;
canvas.width = 20;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "rgba(0,0,0,0.1)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "rgba(255, 181, 21, .3)";
highlighted.forEach(function(el, index) {
if (index == highlightedIndex) ctx.fillStyle = "rgba(0, 0, 255, 0.8)";
else ctx.fillStyle = "rgba(255, 181, 21, .3)";
var box = el.getBoundingClientRect();
ctx.fillRect(0, window.scrollY + box.top, canvas.width, box.height);
})
ctx.fillStyle = "rgba(0,0,0,0.0)";
ctx.strokeStyle = "rgba(0,200,200,0.85)";
ctx.strokeRect(0, window.scrollY, canvas.width, window.innerHeight);
canvasUpdating = false;
}
function updateHighlighter() {
if (highlighted.length && canvasUpdating == false) {
canvasUpdating = true;
window.requestAnimationFrame(generateHighlighter);
}
}
window.addEventListener('scroll', updateHighlighter);
window.addEventListener('resize', updateHighlighter);
// Add the css...with a content script this would be seperate but I put it here for dev purposes..this was made in the Snippets section of the dev tools Sources panel
var css = document.createElement("style");
css.type = "text/css";
css.innerHTML = (function() {
/*
.ghs-highlight, .ghs-partial-highlight {
border: 1px solid rgba(255, 181, 21, .6);
background-color: rgba(255, 181, 21, .3);
}
#highlighternoconflict{
width:20px;
position:fixed;
top:0px;
bottom:0px;
right:0;
height:100%;
display:none;
}
*/
}).toString().split('\n').slice(2, -2).join('\n').trim();
document.body.appendChild(css);
})(); |
@PAEz: thanks for comments! We are currently traveling, will look into it some days later :) |
Cool, would be interested to know what ya think. window.addEventListener('load', function() {
var fileLineContainer = '.js-file-line-container';
var lastPage = location.href;
var textNodes = [];
var highlighted = [];
var highlightedIndex;
function wrapTextNodes(query) {
// Why did all the gawd dam text selection stuff fail, urgggggghh....atleast this worked! http://cwestblog.com/2014/03/14/javascript-getting-all-text-nodes/
function getTextNodesIn(elem, opt_fnFilter) {
if (elem) {
for (var nodes = elem.childNodes, i = nodes.length; i--;) {
var node = nodes[i],
nodeType = node.nodeType;
if (nodeType == 3) {
if (!opt_fnFilter || opt_fnFilter(node, elem)) {
if (node.nodeValue.trim() != '') {
var span = document.createElement('span');
span.textContent = node.nodeValue;
node.parentNode.replaceChild(span, node);
textNodes.push(span);
}
}
} else if (nodeType == 1 || nodeType == 9 || nodeType == 11) {
getTextNodesIn(node, opt_fnFilter)
}
}
}
}
var el = document.querySelector(query);
if (!el) return;
textNodes = [];
getTextNodesIn(el);
textNodes.reverse();
}
wrapTextNodes(fileLineContainer);
// watch for page updating...
var whatToObserve = {
childList: true,
attributes: false,
subtree: false,
attributeOldValue: false /*, attributeFilter: []*/
};
var mutationObserver = new MutationObserver(function(mutationRecords) {
if (location.href != lastPage) {
lastPage = location.href;
wrapTextNodes(fileLineContainer);
}
});
mutationObserver.observe(document.querySelector('#js-repo-pjax-container'), whatToObserve);
function restore() {
highlighted.forEach(function(el) {
if (el.classList.contains('ghs-highlight')) el.classList.remove("ghs-highlight");
else {
var parent = el.parentNode;
parent.replaceChild(el.childNodes[0], el);
parent.normalize();
}
})
highlighted = [];
}
function selectElement(el) {
var range = document.createRange();
range.selectNodeContents(el);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
function splitReplace(el, str, selectionIndex) {
var strLength = str.length;
var source = el.textContent;
var pos = -1;
var lastPos = 0;
var result = document.createDocumentFragment();
var selected;
while ((pos = source.indexOf(str, pos + 1)) != -1) {
if (pos > lastPos) result.appendChild(document.createTextNode(source.substring(lastPos, pos)));
var highlight = document.createElement('span');
highlight.textContent = source.substring(pos, pos + strLength);
highlight.classList.add('ghs-partial-highlight');
if (pos === selectionIndex) {
selected = highlight;
highlightedIndex = highlighted.length;
}
result.appendChild(highlight);
highlighted.push(highlight);
lastPos = pos + strLength;
}
result.appendChild(document.createTextNode(source.substring(lastPos)));
el.replaceChild(result, el.childNodes[0]);
if (selected) selectElement(selected);
}
var canvasDraggin = false;
document.body.addEventListener('mousedown', function(e) {
if (e.target == canvas && e.which===1) {
canvasDraggin = true;
var box=document.documentElement.getBoundingClientRect();
var heightRatio = box.height / window.innerHeight;
var half= window.innerHeight/2 ;
document.body.scrollTop = (e.y * heightRatio)-half;
window.addEventListener('mousemove', canvasDragger);
return;
}
if (e.which != 1 || highlighted.length == 0 || e.target == canvas) return;
restore();
canvas.style.display = 'none';
});
function canvasDragger(e) {
if (!canvasDraggin) return;
var heightRatio = document.documentElement.getBoundingClientRect().height / window.innerHeight;
var half= window.innerHeight/2 ;
document.body.scrollTop = (e.y * heightRatio)-half;
e.preventDefault();
return false;
}
document.body.addEventListener('mouseup', function(e) {
if (e.which != 1) return;
if(canvasDraggin){
canvasDraggin = false;
window.removeEventListener('mousemove', canvasDragger);
return;
}
var selection = window.getSelection();
var selected = selection.toString().trim();
if (selected) {
textNodes.forEach(function(el) {
if (el.textContent == selected) {
el.classList.add("ghs-highlight");
if (el == e.target) highlightedIndex = highlighted.length;
highlighted.push(el);
} else if (el.textContent.indexOf(selected) > -1) {
if (el != e.target) splitReplace(el, selected);
else splitReplace(el, selected, Math.min(selection.anchorOffset, selection.focusOffset));
};
});
updateHighlighter();
}
});
window.addEventListener('keydown', function(e) {
if (!highlighted.length > 0 || !e.ctrlKey) return;
if (e.keyCode == 38) { // down key
highlightedIndex--;
if (highlightedIndex < 0) highlightedIndex = highlighted.length - 1;
} else if (e.keyCode == 40) { // up key
highlightedIndex++;
if (highlightedIndex >= highlighted.length) highlightedIndex = 0;
} else return;
selectElement(highlighted[highlightedIndex]);
elShow(highlighted[highlightedIndex]);
updateHighlighter();
e.preventDefault();
return false;
});
function elShow(el) {
var rect = el.getBoundingClientRect();
if (rect.bottom >= (window.innerHeight || document.documentElement.clientHeight)) el.scrollIntoView(false);
else if (rect.top <= 0) el.scrollIntoView(true);
}
// Do the Highlighter bar on the right
canvas = document.createElement("canvas");
canvas.setAttribute('id', 'highlighternoconflict');
var canvasUpdating = false;
document.body.appendChild(canvas);
var ctx = canvas.getContext('2d');
function generateHighlighter() {
var canvasHeight = window.innerHeight; // Height to make the bar
var heightRatio = canvasHeight / document.documentElement.getBoundingClientRect().height;
canvas.style.display = 'block';
// canvas.height = document.documentElement.getBoundingClientRect().height;
canvas.height = canvasHeight;
canvas.width = 20;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "rgba(0,0,0,0.1)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "rgba(255, 181, 21, .3)";
var lastY = -1,
y = 0;
highlighted.forEach(function(el, index) {
var box = el.getBoundingClientRect();
y = (((window.scrollY + box.top) * heightRatio) + 0.5) | 0;
if (y == lastY && index != highlightedIndex) return;
if (index == highlightedIndex) ctx.fillStyle = "rgba(0, 0, 255, 1)";
else ctx.fillStyle = "rgba(255, 181, 21, 1)";
ctx.fillRect(0, y, canvas.width, (((box.height * heightRatio) + .5) | 0) || 1);
lastY = y;
})
ctx.fillStyle = "rgba(0,0,0,0.0)";
ctx.lineWidth = 1;
ctx.strokeStyle = "rgba(0,200,200,0.85)";
ctx.strokeRect(0, ((window.scrollY * heightRatio) + 0.5) | 0, canvas.width, ((window.innerHeight * heightRatio) + .5) | 0);
canvasUpdating = false;
}
function updateHighlighter() {
if (highlighted.length && canvasUpdating == false) {
canvasUpdating = true;
window.requestAnimationFrame(generateHighlighter);
}
}
window.addEventListener('scroll', updateHighlighter);
window.addEventListener('resize', updateHighlighter);
// Add the css...with a content script this would be seperate but I put it here for dev purposes..this was made in the Snippets section of the dev tools Sources panel
var css = document.createElement("style");
css.type = "text/css";
css.innerHTML = (function() {
/*
.ghs-highlight, .ghs-partial-highlight {
border: 1px solid rgba(255, 181, 21, .6);
background-color: rgba(255, 181, 21, .3);
}
#highlighternoconflict{
width:20px;
position:fixed;
top:0px;
bottom:0px;
right:0;
height:100%;
display:none;
}
*/
}).toString().split('\n').slice(2, -2).join('\n').trim();
document.body.appendChild(css);
}); //)(); |
hehe...one last time.... window.addEventListener('load', function() {
// (function(){
var fileLineContainer = '.js-file-line-container';
var lastPage = location.href;
var textNodes = [];
var highlighted = [];
var highlightedIndex;
function wrapTextNodes(query) {
// Why did all the gawd dam text selection stuff fail, urgggggghh....atleast this worked! http://cwestblog.com/2014/03/14/javascript-getting-all-text-nodes/
function getTextNodesIn(elem, opt_fnFilter) {
if (elem) {
for (var nodes = elem.childNodes, i = nodes.length; i--;) {
var node = nodes[i],
nodeType = node.nodeType;
if (nodeType == 3) {
if (!opt_fnFilter || opt_fnFilter(node, elem)) {
if (node.nodeValue.trim() != '') {
var span = document.createElement('span');
span.textContent = node.nodeValue;
node.parentNode.replaceChild(span, node);
textNodes.push(span);
}
}
} else if (nodeType == 1 || nodeType == 9 || nodeType == 11) {
getTextNodesIn(node, opt_fnFilter)
}
}
}
}
var el = document.querySelector(query);
if (!el) return;
textNodes = [];
getTextNodesIn(el);
textNodes.reverse();
}
wrapTextNodes(fileLineContainer);
// watch for page updating...
var whatToObserve = {
childList: true,
attributes: false,
subtree: false,
attributeOldValue: false /*, attributeFilter: []*/
};
var mutationObserver = new MutationObserver(function(mutationRecords) {
if (location.href != lastPage) {
lastPage = location.href;
wrapTextNodes(fileLineContainer);
}
});
mutationObserver.observe(document.querySelector('#js-repo-pjax-container'), whatToObserve);
function restore() {
highlighted.forEach(function(el) {
if (el.classList.contains('ghs-highlight')) el.classList.remove("ghs-highlight");
else {
var parent = el.parentNode;
parent.replaceChild(el.childNodes[0], el);
parent.normalize();
}
})
highlighted = [];
}
function selectElement(el) {
var range = document.createRange();
range.selectNodeContents(el);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
function splitReplace(el, str, selectionIndex) {
var strLength = str.length;
var source = el.textContent;
var pos = -1;
var lastPos = 0;
var result = document.createDocumentFragment();
var selected;
while ((pos = source.indexOf(str, pos + 1)) != -1) {
if (pos > lastPos) result.appendChild(document.createTextNode(source.substring(lastPos, pos)));
var highlight = document.createElement('span');
highlight.textContent = source.substring(pos, pos + strLength);
highlight.classList.add('ghs-partial-highlight');
if (pos === selectionIndex) {
selected = highlight;
highlightedIndex = highlighted.length;
}
result.appendChild(highlight);
highlighted.push(highlight);
lastPos = pos + strLength;
}
result.appendChild(document.createTextNode(source.substring(lastPos)));
el.replaceChild(result, el.childNodes[0]);
if (selected) selectElement(selected);
}
var canvasDraggin = false;
function barScrollToY(y){
var iHieght = document.documentElement.clientHeight;
var box = document.documentElement.getBoundingClientRect();
var heightRatio = box.height / iHieght;
var half= iHieght/2 ;
window.scrollTo(window.pageXOffset,(y * heightRatio)-half);
}
document.body.addEventListener('mousedown', function(e) {
if (e.target == canvas && e.which===1) {
canvasDraggin = true;
barScrollToY(e.clientY);
window.addEventListener('mousemove', canvasDragger);
return;
}
if (e.which != 1 || highlighted.length == 0) return;
restore();
canvas.style.display = 'none';
});
function canvasDragger(e) {
if (!canvasDraggin) return;
barScrollToY(e.clientY);
e.preventDefault();
return false;
}
document.body.addEventListener('mouseup', function(e) {
if (e.which != 1) return;
if(canvasDraggin){
canvasDraggin = false;
window.removeEventListener('mousemove', canvasDragger);
return;
}
var selection = window.getSelection();
var selected = selection.toString().trim();
if (selected) {
textNodes.forEach(function(el) {
if (el.textContent == selected) {
el.classList.add("ghs-highlight");
if (el == e.target) highlightedIndex = highlighted.length;
highlighted.push(el);
} else if (el.textContent.indexOf(selected) > -1) {
if (el != e.target) splitReplace(el, selected);
else splitReplace(el, selected, Math.min(selection.anchorOffset, selection.focusOffset));
};
});
updateHighlighter();
}
});
window.addEventListener('keydown', function(e) {
if (!highlighted.length > 0 || !e.ctrlKey) return;
if (e.keyCode == 38) { // down key
highlightedIndex--;
if (highlightedIndex < 0) highlightedIndex = highlighted.length - 1;
} else if (e.keyCode == 40) { // up key
highlightedIndex++;
if (highlightedIndex >= highlighted.length) highlightedIndex = 0;
} else return;
selectElement(highlighted[highlightedIndex]);
showElement(highlighted[highlightedIndex]);
updateHighlighter();
e.preventDefault();
return false;
});
function showElement(el) {
var rect = el.getBoundingClientRect();
if (rect.bottom >= document.documentElement.clientHeight) el.scrollIntoView(false);
else if (rect.top <= 0) el.scrollIntoView(true);
}
// Do the Highlighter bar on the right
canvas = document.createElement("canvas");
canvas.setAttribute('id', 'highlighternoconflict');
var canvasUpdating = false;
document.body.appendChild(canvas);
var ctx = canvas.getContext('2d');
function generateHighlighter() {
var canvasHeight = window.document.documentElement.clientHeight; // Height to make the bar
var heightRatio = canvasHeight / document.documentElement.getBoundingClientRect().height;
canvas.style.display = 'block';
// canvas.height = document.documentElement.getBoundingClientRect().height;
canvas.height = canvasHeight;
canvas.width = 20;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "rgba(0,0,0,0.1)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "rgba(255, 181, 21, .3)";
var lastY = -1,
y = 0;
highlighted.forEach(function(el, index) {
var box = el.getBoundingClientRect();
y = (((window.scrollY + box.top) * heightRatio) + 0.5) | 0;
if (y == lastY && index != highlightedIndex) return;
if (index == highlightedIndex) ctx.fillStyle = "rgba(0, 0, 255, 1)";
else ctx.fillStyle = "rgba(255, 181, 21, 1)";
ctx.fillRect(0, y, canvas.width, (((box.height * heightRatio) + .5) | 0) || 1);
lastY = y;
})
ctx.fillStyle = "rgba(0,0,0,0.0)";
ctx.lineWidth = 1;
ctx.strokeStyle = "rgba(0,200,200,0.85)";
ctx.strokeRect(0, ((window.scrollY * heightRatio) + 0.5) | 0, canvas.width, ((canvasHeight * heightRatio) + .5) | 0);
canvasUpdating = false;
}
function updateHighlighter() {
if (highlighted.length && canvasUpdating == false) {
canvasUpdating = true;
window.requestAnimationFrame(generateHighlighter);
}
}
window.addEventListener('scroll', updateHighlighter);
window.addEventListener('resize', updateHighlighter);
// Add the css...with a content script this would be seperate but I put it here for dev purposes..this was made in the Snippets section of the dev tools Sources panel
var css = document.createElement("style");
css.type = "text/css";
css.innerHTML = (function() {
/*
.ghs-highlight, .ghs-partial-highlight {
border: 1px solid rgba(255, 181, 21, .6);
background-color: rgba(255, 181, 21, .3);
}
#highlighternoconflict{
width:20px;
position:fixed;
top:0px;
bottom:0px;
right:0;
height:100%;
display:none;
}
*/
}).toString().split('\n').slice(2, -2).join('\n').trim();
document.body.appendChild(css);
}); //)();
// })(); |
Finally get home. I love all the features you implemented, especially the bar! But I'm a little overwhelmed. Could you split it up and use pull request? One for fixing the bug, one for removing jQuery (I don’t think it’s necessary though—as a half-way js dev I kinda like jQuery), one for add the awesome bar, etc. Thanks! |
Like:
https://github.com/Nuclides/github-highlight-selected/blob/master/Update.plist
Don't click it directly, GitHub uses pjax. Open a new tab and enter the URL.
The text was updated successfully, but these errors were encountered: