diff options
| author | Jez Ng | 2012-01-15 23:04:21 +0800 |
|---|---|---|
| committer | Jez Ng | 2012-01-25 23:47:49 -0500 |
| commit | 2134a4c14abcfcbae0a75ba31f29d5651f057db2 (patch) | |
| tree | ce92c8baa10450577c1840206e0ffb93ab47bab6 /vimiumFrontend.js | |
| parent | 5d13995b56b3fbbc6c574236568992dea29d1379 (diff) | |
| download | vimium-2134a4c14abcfcbae0a75ba31f29d5651f057db2.tar.bz2 | |
Finish initial implementation of regex find.
Diffstat (limited to 'vimiumFrontend.js')
| -rw-r--r-- | vimiumFrontend.js | 101 |
1 files changed, 72 insertions, 29 deletions
diff --git a/vimiumFrontend.js b/vimiumFrontend.js index a22cbd8f..28ab7659 100644 --- a/vimiumFrontend.js +++ b/vimiumFrontend.js @@ -8,8 +8,7 @@ var getCurrentUrlHandlers = []; // function(url) var insertModeLock = null; var findMode = false; -var findModeMatchIndex = 0; -var findModeQuery = ""; +var findModeQuery = { rawQuery: "" }; var findModeQueryHasResults = false; var isShowingHelpDialog = false; var handlerStack = []; @@ -601,60 +600,87 @@ function exitInsertMode(target) { function isInsertMode() { return insertModeLock !== null; } +// should be called whenever rawQuery is modified. +function updateFindModeQuery() { + // the query can be treated differently (e.g. as a plain string versus regex depending on the presence of + // escape sequences. '\' is the escape character and needs to be escaped itself to be used as a normal + // character. here we grep for the relevant escape sequences. + findModeQuery.parsedQuery = findModeQuery.rawQuery.replace(/\\./g, function(match) { + switch (match) { + case "\\r": + findModeQuery.isRegex = true; + return ''; + case "\\\\": + return "\\"; + default: + return match; + } + }); + + // if we are dealing with a regex, grep for all matches in the text, and then call window.find() on them + // sequentially so the browser handles the scrolling / text selection. + if (findModeQuery.isRegex) { + var pattern = new RegExp(findModeQuery.parsedQuery, "gi"); + // innerText will not return the text of hidden elements, and strip out tags while preserving newlines + var text = document.body.innerText; + findModeQuery.regexMatches = text.match(pattern); + findModeQuery.activeRegexIndex = 0; + } +} + function handleKeyCharForFindMode(keyChar) { - findModeQuery = findModeQuery + keyChar; + findModeQuery.rawQuery += keyChar; + updateFindModeQuery(); performFindInPlace(); showFindModeHUDForQuery(); } function handleDeleteForFindMode() { - if (findModeQuery.length == 0) { + if (findModeQuery.rawQuery.length == 0) { exitFindMode(); performFindInPlace(); } else { - findModeQuery = findModeQuery.substring(0, findModeQuery.length - 1); + findModeQuery.rawQuery = findModeQuery.rawQuery.substring(0, findModeQuery.rawQuery.length - 1); + updateFindModeQuery(); performFindInPlace(); showFindModeHUDForQuery(); } } function handleEnterForFindMode() { - performFindInPlace(); exitFindMode(); + performFindInPlace(); } function performFindInPlace() { var cachedScrollX = window.scrollX; var cachedScrollY = window.scrollY; + if (findModeQuery.isRegex) { + if (findModeQuery.regexMatches === null) { + findModeQueryHasResults = false; + return; + } + else + var query = findModeQuery.regexMatches[0]; + } + else + var query = findModeQuery.parsedQuery; + // Search backwards first to "free up" the current word as eligible for the real forward search. This allows // us to search in place without jumping around between matches as the query grows. - window.find(findModeQuery, false, true, true, false, true, false); + window.find(query, false, true, true, false, true, false); // We need to restore the scroll position because we might've lost the right position by searching // backwards. window.scrollTo(cachedScrollX, cachedScrollY); - executeFind(); + findModeQueryHasResults = executeFind(query); } -function executeFind(backwards) { - var pattern = new RegExp(findModeQuery, "g"); - var text = document.body.textContent; - var result = text.match(pattern); - if ( ! findMode ) - if (backwards) - if (findModeMatchIndex > 0) - findModeMatchIndex -= 1; - else - findModeMatchIndex = result.length - 1; - else - if (findModeMatchIndex < result.length - 1) - findModeMatchIndex += 1; - else - findModeMatchIndex = 0; - findModeQueryHasResults = window.find(result[findModeMatchIndex], false, backwards, true, false, true, false); +function executeFind(query, backwards) { + return window.find(query, false, backwards, true, false, true, false); } function focusFoundLink() { @@ -666,7 +692,24 @@ function focusFoundLink() { } function findAndFocus(backwards) { - executeFind(backwards); + if (!findModeQueryHasResults) + return; + + if (findModeQuery.isRegex) { + if (!backwards) { + if (++findModeQuery.activeRegexIndex == findModeQuery.regexMatches.length) + findModeQuery.activeRegexIndex = 0; + } + else { + if (--findModeQuery.activeRegexIndex == -1) + findModeQuery.activeRegexIndex = findModeQuery.regexMatches.length - 1; + } + var query = findModeQuery.regexMatches[findModeQuery.activeRegexIndex]; + } + else + var query = findModeQuery.parsedQuery; + + executeFind(query, backwards); focusFoundLink(); } @@ -723,10 +766,10 @@ function goNext() { } function showFindModeHUDForQuery() { - if (findModeQueryHasResults || findModeQuery.length == 0) - HUD.show("/" + insertSpaces(findModeQuery)); + if (findModeQueryHasResults || findModeQuery.rawQuery.length == 0) + HUD.show("/" + insertSpaces(findModeQuery.rawQuery)); else - HUD.show("/" + insertSpaces(findModeQuery + " (No Matches)")); + HUD.show("/" + insertSpaces(findModeQuery.rawQuery + " (No Matches)")); } /* @@ -746,7 +789,7 @@ function insertSpaces(query) { } function enterFindMode() { - findModeQuery = ""; + findModeQuery = { rawQuery: "" }; findMode = true; HUD.show("/"); } |
