修订版 | 0579eecf8e202f0e0ab0e14dbcd7079ec8740418 (tree) |
---|---|
时间 | 2017-09-25 04:27:16 |
作者 | umorigu <umorigu@gmai...> |
Commiter | umorigu |
Color search text in body
@@ -136,7 +136,7 @@ window.addEventListener && window.addEventListener('DOMContentLoaded', function( | ||
136 | 136 | results.forEach(function(val, index) { |
137 | 137 | var fragment = document.createDocumentFragment(); |
138 | 138 | var li = document.createElement('li'); |
139 | - var href = val.url; | |
139 | + var href = val.url + '#q=' + encodeSearchTextForHash(searchText); | |
140 | 140 | var decoratedName = findAndDecorateText(val.name, searchRegex); |
141 | 141 | if (! decoratedName) { |
142 | 142 | decoratedName = escapeHTML(val.name); |
@@ -148,7 +148,7 @@ window.addEventListener && window.addEventListener('DOMContentLoaded', function( | ||
148 | 148 | } else { |
149 | 149 | updatedAt = val.updated_at; |
150 | 150 | } |
151 | - var liHtml = '<a href="' + href + '">' + decoratedName + '</a> ' + | |
151 | + var liHtml = '<a href="' + escapeHTML(href) + '">' + decoratedName + '</a> ' + | |
152 | 152 | getPassage(now, updatedAt); |
153 | 153 | li.innerHTML = liHtml; |
154 | 154 | fragment.appendChild(li); |
@@ -210,6 +210,7 @@ window.addEventListener && window.addEventListener('DOMContentLoaded', function( | ||
210 | 210 | kanaMap = map; |
211 | 211 | } |
212 | 212 | function textToRegex(searchText) { |
213 | + if (!searchText) return null; | |
213 | 214 | var regEscape = /[\\^$.*+?()[\]{}|]/g; |
214 | 215 | // 1:Symbol 2:Katakana 3:Hiragana |
215 | 216 | var regRep = /([\\^$.*+?()[\]{}|])|([\u30a1-\u30f6])|([\u3041-\u3096])/g; |
@@ -336,29 +337,6 @@ window.addEventListener && window.addEventListener('DOMContentLoaded', function( | ||
336 | 337 | return blocks; |
337 | 338 | //return foundLines.join('\n'); |
338 | 339 | } |
339 | - function findAndDecorateText(text, searchRegex) { | |
340 | - var isReplaced = false; | |
341 | - var lastIndex = 0; | |
342 | - var m; | |
343 | - var decorated = ''; | |
344 | - searchRegex.lastIndex = 0; | |
345 | - while ((m = searchRegex.exec(text)) !== null) { | |
346 | - isReplaced = true; | |
347 | - var pre = text.substring(lastIndex, m.index); | |
348 | - decorated += escapeHTML(pre); | |
349 | - for (var i = 1; i < m.length; i++) { | |
350 | - if (m[i]) { | |
351 | - decorated += '<strong class="word' + (i - 1) + '">' + escapeHTML(m[i]) + '</strong>' | |
352 | - } | |
353 | - } | |
354 | - lastIndex = searchRegex.lastIndex; | |
355 | - } | |
356 | - if (isReplaced) { | |
357 | - decorated += escapeHTML(text.substr(lastIndex)); | |
358 | - return decorated; | |
359 | - } | |
360 | - return null; | |
361 | - } | |
362 | 340 | function getSummary(bodyText, searchRegex) { |
363 | 341 | return getTargetLines(bodyText, searchRegex); |
364 | 342 | } |
@@ -453,7 +431,7 @@ window.addEventListener && window.addEventListener('DOMContentLoaded', function( | ||
453 | 431 | var loc = document.location; |
454 | 432 | var url = loc.protocol + '//' + loc.host + loc.pathname + |
455 | 433 | '?cmd=search2' + |
456 | - '&q=' + encodeSearthText(q) + | |
434 | + '&q=' + encodeSearchText(q) + | |
457 | 435 | (base ? '&base=' + encodeURIComponent(base) : ''); |
458 | 436 | e.preventDefault(); |
459 | 437 | setTimeout(function() { |
@@ -485,13 +463,84 @@ window.addEventListener && window.addEventListener('DOMContentLoaded', function( | ||
485 | 463 | } |
486 | 464 | } |
487 | 465 | }); |
488 | - function encodeSearthText(q) { | |
489 | - var sp = q.split(/\s+/); | |
490 | - for (var i = 0; i < sp.length; i++) { | |
491 | - sp[i] = encodeURIComponent(sp[i]); | |
466 | + } | |
467 | + function encodeSearchText(q) { | |
468 | + var sp = q.split(/\s+/); | |
469 | + for (var i = 0; i < sp.length; i++) { | |
470 | + sp[i] = encodeURIComponent(sp[i]); | |
471 | + } | |
472 | + return sp.join('+'); | |
473 | + } | |
474 | + function encodeSearchTextForHash(q) { | |
475 | + var sp = q.split(/\s+/); | |
476 | + return sp.join('+'); | |
477 | + } | |
478 | + function findAndDecorateText(text, searchRegex) { | |
479 | + var isReplaced = false; | |
480 | + var lastIndex = 0; | |
481 | + var m; | |
482 | + var decorated = ''; | |
483 | + searchRegex.lastIndex = 0; | |
484 | + while ((m = searchRegex.exec(text)) !== null) { | |
485 | + isReplaced = true; | |
486 | + var pre = text.substring(lastIndex, m.index); | |
487 | + decorated += escapeHTML(pre); | |
488 | + for (var i = 1; i < m.length; i++) { | |
489 | + if (m[i]) { | |
490 | + decorated += '<strong class="word' + (i - 1) + '">' + escapeHTML(m[i]) + '</strong>' | |
491 | + } | |
492 | + } | |
493 | + lastIndex = searchRegex.lastIndex; | |
494 | + } | |
495 | + if (isReplaced) { | |
496 | + decorated += escapeHTML(text.substr(lastIndex)); | |
497 | + return decorated; | |
498 | + } | |
499 | + return null; | |
500 | + } | |
501 | + function getSearchTextInLocationHash() { | |
502 | + // TODO Cross browser | |
503 | + var hash = location.hash; | |
504 | + var q = ''; | |
505 | + if (hash.substr(0, 3) === '#q=') { | |
506 | + q = hash.substr(3).replace(/\+/g, ' '); | |
507 | + } | |
508 | + return q; | |
509 | + } | |
510 | + function colorSearchTextInBody() { | |
511 | + var searchText = getSearchTextInLocationHash(); | |
512 | + if (!searchText) return; | |
513 | + var searchRegex = textToRegex(removeSearchOperators(searchText)); | |
514 | + var headReText = '([\\s\\b]|^)'; | |
515 | + var tailReText = '\\b'; | |
516 | + var ignoreTags = ['INPUT', 'TEXTAREA', 'BUTTON', | |
517 | + 'SCRIPT', 'FRAME', 'IFRAME']; | |
518 | + function colorSearchText(element, searchRegex) { | |
519 | + var decorated = findAndDecorateText(element.nodeValue, searchRegex); | |
520 | + if (decorated) { | |
521 | + var span = document.createElement('span'); | |
522 | + span.innerHTML = decorated; | |
523 | + element.parentNode.replaceChild(span, element); | |
524 | + } | |
525 | + } | |
526 | + function walkElement(element) { | |
527 | + var e = element.firstChild; | |
528 | + while (e) { | |
529 | + if (e.nodeType == 3 && e.nodeValue && | |
530 | + e.nodeValue.length >= 2 && /\S/.test(e.nodeValue)) { | |
531 | + var next = e.nextSibling; | |
532 | + colorSearchText(e, searchRegex); | |
533 | + e = next; | |
534 | + } else { | |
535 | + if (e.nodeType == 1 && ignoreTags.indexOf(e.tagName) == -1) { | |
536 | + walkElement(e); | |
537 | + } | |
538 | + e = e.nextSibling; | |
539 | + } | |
492 | 540 | } |
493 | - return sp.join('+'); | |
494 | 541 | } |
542 | + var target = document.getElementById('body'); | |
543 | + walkElement(target); | |
495 | 544 | } |
496 | 545 | function isEnabledFetchFunctions() { |
497 | 546 | if (window.fetch && document.querySelector) { |
@@ -508,6 +557,7 @@ window.addEventListener && window.addEventListener('DOMContentLoaded', function( | ||
508 | 557 | if (props.json_enabled) return true; |
509 | 558 | return false; |
510 | 559 | } |
560 | + colorSearchTextInBody(); | |
511 | 561 | if (! isEnabledFetchFunctions()) return; |
512 | 562 | if (! isEnableServerFunctions()) return; |
513 | 563 | replaceSearchWithSearch2(); |