修訂 | d1aa1006226fb78e431c27a2749be183096edcc4 (tree) |
---|---|
時間 | 2017-09-18 07:03:03 |
作者 | umorigu <umorigu@gmai...> |
Commiter | umorigu |
BugTrack/2433 Cancelable Search with search2 plugin
@@ -9,6 +9,9 @@ | ||
9 | 9 | define('PLUGIN_SEARCH2_MAX_LENGTH', 80); |
10 | 10 | define('PLUGIN_SEARCH2_MAX_BASE', 16); // #search(1,2,3,...,15,16) |
11 | 11 | |
12 | +define('PLUGIN_SEARCH2_RESULT_RECORD_LIMIT', 500); | |
13 | +define('PLUGIN_SEARCH2_RESULT_RECORD_LIMIT_START', 100); | |
14 | + | |
12 | 15 | // Show a search box on a page |
13 | 16 | function plugin_search2_convert() |
14 | 17 | { |
@@ -22,6 +25,8 @@ function plugin_search2_action() | ||
22 | 25 | |
23 | 26 | $action = isset($vars['action']) ? $vars['action'] : ''; |
24 | 27 | $base = isset($vars['base']) ? $vars['base'] : ''; |
28 | + $start_s = isset($vars['start']) ? $vars['start'] : ''; | |
29 | + $start_index = pkwk_ctype_digit($start_s) ? intval($start_s) : 0; | |
25 | 30 | $bases = array(); |
26 | 31 | if ($base !== '') { |
27 | 32 | $bases[] = $base; |
@@ -38,17 +43,19 @@ function plugin_search2_action() | ||
38 | 43 | } |
39 | 44 | } else if ($action === 'query') { |
40 | 45 | $text = isset($vars['q']) ? $vars['q'] : ''; |
41 | - plugin_search2_do_search($text, $base); | |
46 | + plugin_search2_do_search($text, $base, $start_index); | |
42 | 47 | exit; |
43 | 48 | } |
44 | 49 | } |
45 | 50 | |
46 | -function plugin_search2_do_search($query_text, $base) | |
51 | +function plugin_search2_do_search($query_text, $base, $start_index) | |
47 | 52 | { |
48 | 53 | global $whatsnew, $non_list, $search_non_list; |
49 | 54 | global $_msg_andresult, $_msg_orresult, $_msg_notfoundresult; |
50 | 55 | global $search_auth; |
51 | 56 | |
57 | + $result_record_limit = $start_index === 0 ? | |
58 | + PLUGIN_SEARCH2_RESULT_RECORD_LIMIT_START : PLUGIN_SEARCH2_RESULT_RECORD_LIMIT; | |
52 | 59 | $type = 'AND'; |
53 | 60 | $word = $query_text; |
54 | 61 | $retval = array(); |
@@ -73,9 +80,14 @@ function plugin_search2_do_search($query_text, $base) | ||
73 | 80 | $page_names = array_keys($pages); |
74 | 81 | |
75 | 82 | $found_pages = array(); |
83 | + $readable_page_index = -1; | |
84 | + $scan_page_index = -1; | |
85 | + $saved_scan_start_index = -1; | |
86 | + $last_read_page_name = null; | |
76 | 87 | foreach ($page_names as $page) { |
77 | 88 | $b_match = FALSE; |
78 | 89 | $pagename_only = false; |
90 | + $scan_page_index++; | |
79 | 91 | if (! is_page_readable($page)) { |
80 | 92 | if ($search_auth) { |
81 | 93 | // $search_auth - 1: User can know page names that contain search text if the page is readable |
@@ -84,6 +96,14 @@ function plugin_search2_do_search($query_text, $base) | ||
84 | 96 | // $search_auth - 0: All users can know page names that conntain search text |
85 | 97 | $pagename_only = true; |
86 | 98 | } |
99 | + $readable_page_index++; | |
100 | + if ($readable_page_index < $start_index) { | |
101 | + // Skip: It's not time to read | |
102 | + continue; | |
103 | + } | |
104 | + if ($saved_scan_start_index === -1) { | |
105 | + $saved_scan_start_index = $scan_page_index; | |
106 | + } | |
87 | 107 | // Search for page name and contents |
88 | 108 | $raw_lines = get_source($page, TRUE, FALSE); |
89 | 109 | $lines = remove_author_lines($raw_lines); |
@@ -104,20 +124,37 @@ function plugin_search2_do_search($query_text, $base) | ||
104 | 124 | $found_pages[] = array('name' => (string)$page, |
105 | 125 | 'url' => get_page_uri($page), 'body' => (string)$body); |
106 | 126 | } |
107 | - continue; | |
127 | + } | |
128 | + $last_read_page_name = $page; | |
129 | + if ($start_index + $result_record_limit <= $readable_page_index + 1) { | |
130 | + // Read page limit | |
131 | + break; | |
108 | 132 | } |
109 | 133 | } |
110 | 134 | $s_word = htmlsc($word); |
135 | + /* | |
111 | 136 | if (empty($found_pages)) { |
112 | 137 | $message = str_replace('$1', $s_word, $_msg_notfoundresult); |
113 | 138 | $result_obj = array('message' => $message, 'results' => array()); |
114 | 139 | print(json_encode($result_obj, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); |
115 | 140 | return; |
116 | 141 | } |
142 | + */ | |
117 | 143 | $message = str_replace('$1', $s_word, str_replace('$2', count($found_pages), |
118 | 144 | str_replace('$3', count($page_names), $b_type_and ? $_msg_andresult : $_msg_orresult))); |
119 | - | |
120 | - $result_obj = array('message' => $message, 'results' => $found_pages); | |
145 | + $search_done = (boolean)($scan_page_index + 1 === count($page_names)); | |
146 | + $result_obj = array( | |
147 | + 'message' => $message, | |
148 | + 'q' => $word, | |
149 | + 'start_index' => $start_index, | |
150 | + 'limit' => $result_record_limit, | |
151 | + 'read_page_count' => $readable_page_index - $start_index + 1, | |
152 | + 'scan_page_count' => $scan_page_index - $saved_scan_start_index + 1, | |
153 | + 'page_count' => count($page_names), | |
154 | + 'last_read_page_name' => $last_read_page_name, | |
155 | + 'next_start_index' => $readable_page_index + 1, | |
156 | + 'search_done' => $search_done, | |
157 | + 'results' => $found_pages); | |
121 | 158 | print(json_encode($result_obj, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); |
122 | 159 | } |
123 | 160 |
@@ -157,6 +194,8 @@ EOD; | ||
157 | 194 | EOD; |
158 | 195 | $base_option = '<div class="small">' . $base_msg . '</div>'; |
159 | 196 | } |
197 | + $_search2_result_notfound = htmlsc($_msg_notfoundresult); | |
198 | + $_search2_result_found = htmlsc($_msg_andresult); | |
160 | 199 | $result_page_panel =<<<EOD |
161 | 200 | <div id="_plugin_search2_search_status"></div> |
162 | 201 | <div id="_plugin_search2_message"></div> |
@@ -10,6 +10,7 @@ window.addEventListener && window.addEventListener('DOMContentLoaded', function( | ||
10 | 10 | var aroundLines = 2; |
11 | 11 | var maxResultLines = 20; |
12 | 12 | var minBlockLines = 5; |
13 | + var searchWaitMilliseconds = 100; | |
13 | 14 | function escapeHTML (s) { |
14 | 15 | if(typeof s !== 'string') { |
15 | 16 | s = '' + s; |
@@ -23,11 +24,12 @@ window.addEventListener && window.addEventListener('DOMContentLoaded', function( | ||
23 | 24 | }[m]; |
24 | 25 | }); |
25 | 26 | } |
26 | - function doSearch(text) { | |
27 | + function doSearch(searchText, session, startIndex) { | |
27 | 28 | var url = './?cmd=search2&action=query'; |
28 | - if (text) { | |
29 | - url += '&q=' + encodeURIComponent(text); | |
29 | + if (searchText) { | |
30 | + url += '&q=' + encodeURIComponent(searchText); | |
30 | 31 | } |
32 | + url += '&start=' + startIndex; | |
31 | 33 | fetch (url |
32 | 34 | ).then(function(response){ |
33 | 35 | if (response.ok) { |
@@ -37,16 +39,32 @@ window.addEventListener && window.addEventListener('DOMContentLoaded', function( | ||
37 | 39 | + response.statusText + ' on ' + url); |
38 | 40 | } |
39 | 41 | }).then(function(obj) { |
40 | - showResult(obj, text); | |
42 | + showResult(obj, session, searchText); | |
41 | 43 | })['catch'](function(err){ |
42 | 44 | console.log(err); |
43 | 45 | console.log('Error! Please check JavaScript console' + '\n' + JSON.stringify(err) + '|' + err); |
44 | 46 | }); |
45 | 47 | } |
46 | - function showResult(obj, searchText) { | |
48 | + function getMessageTemplate(idText, defaultText) { | |
49 | + var messageHolder = document.querySelector('#' + idText); | |
50 | + var messageTemplate = (messageHolder && messageHolder.value) || defaultText; | |
51 | + return messageTemplate; | |
52 | + } | |
53 | + function showResult(obj, session, searchText) { | |
54 | + var searchRegex = textToRegex(searchText); | |
47 | 55 | var ul = document.querySelector('#result-list'); |
48 | 56 | if (!ul) return; |
49 | - ul.innerHTML = ''; | |
57 | + if (obj.start_index === 0) { | |
58 | + ul.innerHTML = ''; | |
59 | + } | |
60 | + if (! session.scan_page_count) session.scan_page_count = 0; | |
61 | + if (! session.read_page_count) session.read_page_count = 0; | |
62 | + if (! session.hit_page_count) session.hit_page_count = 0; | |
63 | + session.scan_page_count += obj.scan_page_count; | |
64 | + session.read_page_count += obj.read_page_count; | |
65 | + session.hit_page_count += obj.results.length; | |
66 | + session.page_count = obj.page_count; | |
67 | + | |
50 | 68 | var msg = obj.message; |
51 | 69 | var notFoundMessageTemplate = getMessageTemplate('_plugin_search2_msg_result_notfound', |
52 | 70 | 'No page which contains $1 has been found.'); |
@@ -77,9 +95,6 @@ window.addEventListener && window.addEventListener('DOMContentLoaded', function( | ||
77 | 95 | setSearchStatus(msg + progress); |
78 | 96 | } |
79 | 97 | var results = obj.results; |
80 | - document.querySelector('#_plugin_search2_message').innerHTML = msg; | |
81 | - setSearchStatus(''); | |
82 | - var searchRegex = textToRegex(searchText); | |
83 | 98 | results.forEach(function(val, index) { |
84 | 99 | var fragment = document.createDocumentFragment(); |
85 | 100 | var li = document.createElement('li'); |
@@ -98,6 +113,11 @@ window.addEventListener && window.addEventListener('DOMContentLoaded', function( | ||
98 | 113 | } |
99 | 114 | ul.appendChild(fragment); |
100 | 115 | }); |
116 | + if (!obj.search_done && obj.next_start_index) { | |
117 | + setTimeout(function(){ | |
118 | + doSearch(searchText, session, obj.next_start_index); | |
119 | + }, searchWaitMilliseconds); | |
120 | + } | |
101 | 121 | } |
102 | 122 | function textToRegex(searchText) { |
103 | 123 | var regEscape = /[\\^$.*+?()[\]{}|]/g; |