Skip to content

Instantly share code, notes, and snippets.

@borisdiakur
Last active April 27, 2023 03:47
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save borisdiakur/9f9d751b4c9cf5acafa2 to your computer and use it in GitHub Desktop.
Save borisdiakur/9f9d751b4c9cf5acafa2 to your computer and use it in GitHub Desktop.
Bookmarklet for case-sensitive search in Google Chrome (and other browsers which do not ship this feature). You can find install instruction below the code.
(function () {
'use strict';
var body = document.body,
html = document.documentElement;
var docHeight = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
var findingColor = 'limegreen';
var text = window.prompt('Search:', '');
var spans = document.getElementsByClassName('diakur-case-sensitive-serarch-finding');
var gutter = document.getElementsByClassName('diakur-case-sensitive-serarch-gutter')[0];
(function clearEverything() {
for (var i = spans.length; i--;) {
for (var j = spans[i].childNodes.length; j--;) {
spans[i].parentNode.replaceChild(spans[i].childNodes[j], spans[i]);
spans[i] = null;
}
}
if (gutter) {
body.removeChild(gutter); gutter = null;
}
})();
if (text === null || text.length === 0) { return; }
gutter = document.createElement('span');
gutter.style.backgroundColor = 'rgba(105,105,105,0.75)';
gutter.style.position = 'fixed';
gutter.style.right = 0;
gutter.style.top = 0;
gutter.style.width = '12px';
gutter.style.height = '100%';
gutter.style.zIndex = 1e6;
gutter.setAttribute('class', 'diakur-case-sensitive-serarch-gutter');
body.appendChild(gutter);
function getTopPos(el) {
for (var topPos = 0; el !== null;) {
topPos += el.offsetTop;
el = el.offsetParent;
}
return topPos;
}
function searchWithinNode(node, te, len) {
var pos, skip, spannode, middlebit, endbit, middleclone;
skip = 0;
if (node.nodeType === 3) {
pos = node.data.indexOf(te);
if (pos >= 0) {
spannode = document.createElement('span');
spannode.setAttribute('data-title', node.data);
spannode.setAttribute('class', 'diakur-case-sensitive-serarch-finding');
spannode.style.backgroundColor = findingColor;
middlebit = node.splitText(pos);
endbit = middlebit.splitText(len);
middleclone = middlebit.cloneNode(true);
spannode.appendChild(middleclone);
middlebit.parentNode.replaceChild(spannode, middlebit);
spannode.setAttribute('data-top', getTopPos(spannode));
skip = 1;
}
} else if (node.nodeType === 1 && node.childNodes && node.tagName.toLowerCase() !== 'script' && node.tagName.toLowerCase() !== 'style') {
for (var child = 0; child < node.childNodes.length; ++child) {
child = child + searchWithinNode(node.childNodes[child], te, len);
}
}
return skip;
}
searchWithinNode(document.body, text, text.length);
spans = document.getElementsByClassName('diakur-case-sensitive-serarch-finding');
var scrollToFinding = function () {
window.scroll(0, this.getAttribute('data-top'));
};
for (var i = spans.length; i--;) {
var finding = document.createElement('a');
var top = getTopPos(spans[i]);
finding.style.width = '100%';
finding.style.height = '5px';
finding.style.backgroundColor = findingColor;
finding.style.cursor = 'pointer';
finding.style.position = 'absolute';
finding.style.left = 0;
finding.style.top = top / docHeight * 100 + '%';
finding.setAttribute('title', spans[i].getAttribute('data-title'));
finding.setAttribute('data-top', top);
finding.addEventListener('click', scrollToFinding, false);
gutter.appendChild(finding);
}
if (spans[0]) {
spans[0].scrollIntoView();
} else {
body.removeChild(gutter); gutter = null;
}
})();
@borisdiakur
Copy link
Author

Install Instruction for Google Chrome

  • In Chrome, click Bookmarks → Bookmark Manager.
  • You should see a new tab with the bookmarks and folders listed.
  • Select the folder on the left where you want to store the bookmarklet (I chose “Other Bookmarks”).
  • Click the “Organize” link, then “Add Page” in the drop down.
  • You should see two input fields. Type the name of the bookmark you would like (i.e., “search”) in the first field.
  • In the second field type javascript: and paste the javascript code above right behind it. The result should start with javascript:(func.
  • Finally you might want to add a keyboard shortcut to trigger a search via the bookmarklet. How you do this depends on your OS (on OS X I use BetterTouchTool).

@ElectricRCAircraftGuy
Copy link

Use this tool to remove line breaks and paragraph breaks: https://www.textfixer.com/tools/remove-line-breaks.php.

Is there any way to go to the next or previous word found?

@ElectricRCAircraftGuy
Copy link

ElectricRCAircraftGuy commented Mar 27, 2020

Bug: you can only do the search once per page refresh. Each time you attempt the search again without first refreshing the page, it deletes the last result found. Repeating this process again and again will eventually delete all the previous searches, then once they are all deleted it will do a new search, and the process repeats.

Please convert this from a gist to a project, and start maintaining it. Or, perhaps, I will take this on and do it--but I don't know any Javascript. :(

Update: I started a project and took some notes on how I will begin:
ElectricRCAircraftGuy/Chrome-Case-Sensitive-Find#1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment