| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com). | 3 * Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com). |
| 4 * Copyright (C) 2009 Joseph Pecoraro | 4 * Copyright (C) 2009 Joseph Pecoraro |
| 5 * Copyright (C) 2011 Google Inc. All rights reserved. | 5 * Copyright (C) 2011 Google Inc. All rights reserved. |
| 6 * | 6 * |
| 7 * Redistribution and use in source and binary forms, with or without | 7 * Redistribution and use in source and binary forms, with or without |
| 8 * modification, are permitted provided that the following conditions | 8 * modification, are permitted provided that the following conditions |
| 9 * are met: | 9 * are met: |
| 10 * | 10 * |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 23 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY | 23 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
| 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 */ | 30 */ |
| 31 | |
| 32 /** | 31 /** |
| 33 * @constructor | 32 * @unrestricted |
| 34 * @extends {WebInspector.VBox} | |
| 35 * @param {!WebInspector.Searchable} searchable | |
| 36 * @param {string=} settingName | |
| 37 */ | 33 */ |
| 38 WebInspector.SearchableView = function(searchable, settingName) | 34 WebInspector.SearchableView = class extends WebInspector.VBox { |
| 39 { | 35 /** |
| 40 WebInspector.VBox.call(this, true); | 36 * @param {!WebInspector.Searchable} searchable |
| 41 this.registerRequiredCSS("ui/searchableView.css"); | 37 * @param {string=} settingName |
| 38 */ |
| 39 constructor(searchable, settingName) { |
| 40 super(true); |
| 41 this.registerRequiredCSS('ui/searchableView.css'); |
| 42 this.element[WebInspector.SearchableView._symbol] = this; | 42 this.element[WebInspector.SearchableView._symbol] = this; |
| 43 | 43 |
| 44 this._searchProvider = searchable; | 44 this._searchProvider = searchable; |
| 45 this._setting = settingName ? WebInspector.settings.createSetting(settingNam
e, {}) : null; | 45 this._setting = settingName ? WebInspector.settings.createSetting(settingNam
e, {}) : null; |
| 46 | 46 |
| 47 this.contentElement.createChild("content"); | 47 this.contentElement.createChild('content'); |
| 48 this._footerElementContainer = this.contentElement.createChild("div", "searc
h-bar hidden"); | 48 this._footerElementContainer = this.contentElement.createChild('div', 'searc
h-bar hidden'); |
| 49 this._footerElementContainer.style.order = 100; | 49 this._footerElementContainer.style.order = 100; |
| 50 | 50 |
| 51 var toolbar = new WebInspector.Toolbar("search-toolbar", this._footerElement
Container); | 51 var toolbar = new WebInspector.Toolbar('search-toolbar', this._footerElement
Container); |
| 52 | 52 |
| 53 if (this._searchProvider.supportsCaseSensitiveSearch()) { | 53 if (this._searchProvider.supportsCaseSensitiveSearch()) { |
| 54 this._caseSensitiveButton = new WebInspector.ToolbarToggle(WebInspector.
UIString("Case sensitive"), ""); | 54 this._caseSensitiveButton = new WebInspector.ToolbarToggle(WebInspector.UI
String('Case sensitive'), ''); |
| 55 this._caseSensitiveButton.setText("Aa"); | 55 this._caseSensitiveButton.setText('Aa'); |
| 56 this._caseSensitiveButton.addEventListener("click", this._toggleCaseSens
itiveSearch, this); | 56 this._caseSensitiveButton.addEventListener('click', this._toggleCaseSensit
iveSearch, this); |
| 57 toolbar.appendToolbarItem(this._caseSensitiveButton); | 57 toolbar.appendToolbarItem(this._caseSensitiveButton); |
| 58 } | 58 } |
| 59 | 59 |
| 60 if (this._searchProvider.supportsRegexSearch()) { | 60 if (this._searchProvider.supportsRegexSearch()) { |
| 61 this._regexButton = new WebInspector.ToolbarToggle(WebInspector.UIString
("Regex"), ""); | 61 this._regexButton = new WebInspector.ToolbarToggle(WebInspector.UIString('
Regex'), ''); |
| 62 this._regexButton.setText(".*"); | 62 this._regexButton.setText('.*'); |
| 63 this._regexButton.addEventListener("click", this._toggleRegexSearch, thi
s); | 63 this._regexButton.addEventListener('click', this._toggleRegexSearch, this)
; |
| 64 toolbar.appendToolbarItem(this._regexButton); | 64 toolbar.appendToolbarItem(this._regexButton); |
| 65 } | 65 } |
| 66 | 66 |
| 67 this._footerElement = this._footerElementContainer.createChild("table", "too
lbar-search"); | 67 this._footerElement = this._footerElementContainer.createChild('table', 'too
lbar-search'); |
| 68 this._footerElement.cellSpacing = 0; | 68 this._footerElement.cellSpacing = 0; |
| 69 | 69 |
| 70 this._firstRowElement = this._footerElement.createChild("tr"); | 70 this._firstRowElement = this._footerElement.createChild('tr'); |
| 71 this._secondRowElement = this._footerElement.createChild("tr", "hidden"); | 71 this._secondRowElement = this._footerElement.createChild('tr', 'hidden'); |
| 72 | 72 |
| 73 // Column 1 | 73 // Column 1 |
| 74 var searchControlElementColumn = this._firstRowElement.createChild("td"); | 74 var searchControlElementColumn = this._firstRowElement.createChild('td'); |
| 75 this._searchControlElement = searchControlElementColumn.createChild("span",
"toolbar-search-control"); | 75 this._searchControlElement = searchControlElementColumn.createChild('span',
'toolbar-search-control'); |
| 76 | 76 |
| 77 this._searchInputElement = WebInspector.HistoryInput.create(); | 77 this._searchInputElement = WebInspector.HistoryInput.create(); |
| 78 this._searchInputElement.classList.add("search-replace"); | 78 this._searchInputElement.classList.add('search-replace'); |
| 79 this._searchControlElement.appendChild(this._searchInputElement); | 79 this._searchControlElement.appendChild(this._searchInputElement); |
| 80 | 80 |
| 81 this._searchInputElement.id = "search-input-field"; | 81 this._searchInputElement.id = 'search-input-field'; |
| 82 this._searchInputElement.placeholder = WebInspector.UIString("Find"); | 82 this._searchInputElement.placeholder = WebInspector.UIString('Find'); |
| 83 | 83 |
| 84 this._matchesElement = this._searchControlElement.createChild("label", "sear
ch-results-matches"); | 84 this._matchesElement = this._searchControlElement.createChild('label', 'sear
ch-results-matches'); |
| 85 this._matchesElement.setAttribute("for", "search-input-field"); | 85 this._matchesElement.setAttribute('for', 'search-input-field'); |
| 86 | 86 |
| 87 this._searchNavigationElement = this._searchControlElement.createChild("div"
, "toolbar-search-navigation-controls"); | 87 this._searchNavigationElement = this._searchControlElement.createChild('div'
, 'toolbar-search-navigation-controls'); |
| 88 | 88 |
| 89 this._searchNavigationPrevElement = this._searchNavigationElement.createChil
d("div", "toolbar-search-navigation toolbar-search-navigation-prev"); | 89 this._searchNavigationPrevElement = |
| 90 this._searchNavigationPrevElement.addEventListener("click", this._onPrevButt
onSearch.bind(this), false); | 90 this._searchNavigationElement.createChild('div', 'toolbar-search-navigat
ion toolbar-search-navigation-prev'); |
| 91 this._searchNavigationPrevElement.title = WebInspector.UIString("Search Prev
ious"); | 91 this._searchNavigationPrevElement.addEventListener('click', this._onPrevButt
onSearch.bind(this), false); |
| 92 | 92 this._searchNavigationPrevElement.title = WebInspector.UIString('Search Prev
ious'); |
| 93 this._searchNavigationNextElement = this._searchNavigationElement.createChil
d("div", "toolbar-search-navigation toolbar-search-navigation-next"); | 93 |
| 94 this._searchNavigationNextElement.addEventListener("click", this._onNextButt
onSearch.bind(this), false); | 94 this._searchNavigationNextElement = |
| 95 this._searchNavigationNextElement.title = WebInspector.UIString("Search Next
"); | 95 this._searchNavigationElement.createChild('div', 'toolbar-search-navigat
ion toolbar-search-navigation-next'); |
| 96 | 96 this._searchNavigationNextElement.addEventListener('click', this._onNextButt
onSearch.bind(this), false); |
| 97 this._searchInputElement.addEventListener("keydown", this._onSearchKeyDown.b
ind(this), true); | 97 this._searchNavigationNextElement.title = WebInspector.UIString('Search Next
'); |
| 98 this._searchInputElement.addEventListener("input", this._onInput.bind(this),
false); | 98 |
| 99 | 99 this._searchInputElement.addEventListener('keydown', this._onSearchKeyDown.b
ind(this), true); |
| 100 this._replaceInputElement = this._secondRowElement.createChild("td").createC
hild("input", "search-replace toolbar-replace-control"); | 100 this._searchInputElement.addEventListener('input', this._onInput.bind(this),
false); |
| 101 this._replaceInputElement.addEventListener("keydown", this._onReplaceKeyDown
.bind(this), true); | 101 |
| 102 this._replaceInputElement.placeholder = WebInspector.UIString("Replace"); | 102 this._replaceInputElement = |
| 103 this._secondRowElement.createChild('td').createChild('input', 'search-re
place toolbar-replace-control'); |
| 104 this._replaceInputElement.addEventListener('keydown', this._onReplaceKeyDown
.bind(this), true); |
| 105 this._replaceInputElement.placeholder = WebInspector.UIString('Replace'); |
| 103 | 106 |
| 104 // Column 2 | 107 // Column 2 |
| 105 this._findButtonElement = this._firstRowElement.createChild("td").createChil
d("button", "search-action-button hidden"); | 108 this._findButtonElement = |
| 106 this._findButtonElement.textContent = WebInspector.UIString("Find"); | 109 this._firstRowElement.createChild('td').createChild('button', 'search-ac
tion-button hidden'); |
| 110 this._findButtonElement.textContent = WebInspector.UIString('Find'); |
| 107 this._findButtonElement.tabIndex = -1; | 111 this._findButtonElement.tabIndex = -1; |
| 108 this._findButtonElement.addEventListener("click", this._onFindClick.bind(thi
s), false); | 112 this._findButtonElement.addEventListener('click', this._onFindClick.bind(thi
s), false); |
| 109 | 113 |
| 110 this._replaceButtonElement = this._secondRowElement.createChild("td").create
Child("button", "search-action-button"); | 114 this._replaceButtonElement = this._secondRowElement.createChild('td').create
Child('button', 'search-action-button'); |
| 111 this._replaceButtonElement.textContent = WebInspector.UIString("Replace"); | 115 this._replaceButtonElement.textContent = WebInspector.UIString('Replace'); |
| 112 this._replaceButtonElement.disabled = true; | 116 this._replaceButtonElement.disabled = true; |
| 113 this._replaceButtonElement.tabIndex = -1; | 117 this._replaceButtonElement.tabIndex = -1; |
| 114 this._replaceButtonElement.addEventListener("click", this._replace.bind(this
), false); | 118 this._replaceButtonElement.addEventListener('click', this._replace.bind(this
), false); |
| 115 | 119 |
| 116 // Column 3 | 120 // Column 3 |
| 117 this._prevButtonElement = this._firstRowElement.createChild("td").createChil
d("button", "search-action-button hidden"); | 121 this._prevButtonElement = |
| 118 this._prevButtonElement.textContent = WebInspector.UIString("Previous"); | 122 this._firstRowElement.createChild('td').createChild('button', 'search-ac
tion-button hidden'); |
| 123 this._prevButtonElement.textContent = WebInspector.UIString('Previous'); |
| 119 this._prevButtonElement.tabIndex = -1; | 124 this._prevButtonElement.tabIndex = -1; |
| 120 this._prevButtonElement.addEventListener("click", this._onPreviousClick.bind
(this), false); | 125 this._prevButtonElement.addEventListener('click', this._onPreviousClick.bind
(this), false); |
| 121 | 126 |
| 122 this._replaceAllButtonElement = this._secondRowElement.createChild("td").cre
ateChild("button", "search-action-button"); | 127 this._replaceAllButtonElement = |
| 123 this._replaceAllButtonElement.textContent = WebInspector.UIString("Replace A
ll"); | 128 this._secondRowElement.createChild('td').createChild('button', 'search-a
ction-button'); |
| 124 this._replaceAllButtonElement.addEventListener("click", this._replaceAll.bin
d(this), false); | 129 this._replaceAllButtonElement.textContent = WebInspector.UIString('Replace A
ll'); |
| 130 this._replaceAllButtonElement.addEventListener('click', this._replaceAll.bin
d(this), false); |
| 125 | 131 |
| 126 // Column 4 | 132 // Column 4 |
| 127 this._replaceElement = this._firstRowElement.createChild("td").createChild("
span"); | 133 this._replaceElement = this._firstRowElement.createChild('td').createChild('
span'); |
| 128 | 134 |
| 129 this._replaceLabelElement = createCheckboxLabel(WebInspector.UIString("Repla
ce")); | 135 this._replaceLabelElement = createCheckboxLabel(WebInspector.UIString('Repla
ce')); |
| 130 this._replaceCheckboxElement = this._replaceLabelElement.checkboxElement; | 136 this._replaceCheckboxElement = this._replaceLabelElement.checkboxElement; |
| 131 this._uniqueId = ++WebInspector.SearchableView._lastUniqueId; | 137 this._uniqueId = ++WebInspector.SearchableView._lastUniqueId; |
| 132 var replaceCheckboxId = "search-replace-trigger" + this._uniqueId; | 138 var replaceCheckboxId = 'search-replace-trigger' + this._uniqueId; |
| 133 this._replaceCheckboxElement.id = replaceCheckboxId; | 139 this._replaceCheckboxElement.id = replaceCheckboxId; |
| 134 this._replaceCheckboxElement.addEventListener("change", this._updateSecondRo
wVisibility.bind(this), false); | 140 this._replaceCheckboxElement.addEventListener('change', this._updateSecondRo
wVisibility.bind(this), false); |
| 135 | 141 |
| 136 this._replaceElement.appendChild(this._replaceLabelElement); | 142 this._replaceElement.appendChild(this._replaceLabelElement); |
| 137 | 143 |
| 138 // Column 5 | 144 // Column 5 |
| 139 var cancelButtonElement = this._firstRowElement.createChild("td").createChil
d("button", "search-action-button"); | 145 var cancelButtonElement = this._firstRowElement.createChild('td').createChil
d('button', 'search-action-button'); |
| 140 cancelButtonElement.textContent = WebInspector.UIString("Cancel"); | 146 cancelButtonElement.textContent = WebInspector.UIString('Cancel'); |
| 141 cancelButtonElement.tabIndex = -1; | 147 cancelButtonElement.tabIndex = -1; |
| 142 cancelButtonElement.addEventListener("click", this.closeSearch.bind(this), f
alse); | 148 cancelButtonElement.addEventListener('click', this.closeSearch.bind(this), f
alse); |
| 143 this._minimalSearchQuerySize = 3; | 149 this._minimalSearchQuerySize = 3; |
| 144 | 150 |
| 145 this._loadSetting(); | 151 this._loadSetting(); |
| 146 }; | 152 } |
| 147 | 153 |
| 148 WebInspector.SearchableView._lastUniqueId = 0; | 154 /** |
| 149 | 155 * @param {?Element} element |
| 150 WebInspector.SearchableView._symbol = Symbol("searchableView"); | 156 * @return {?WebInspector.SearchableView} |
| 151 | 157 */ |
| 152 /** | 158 static fromElement(element) { |
| 153 * @param {?Element} element | |
| 154 * @return {?WebInspector.SearchableView} | |
| 155 */ | |
| 156 WebInspector.SearchableView.fromElement = function(element) | |
| 157 { | |
| 158 var view = null; | 159 var view = null; |
| 159 while (element && !view) { | 160 while (element && !view) { |
| 160 view = element[WebInspector.SearchableView._symbol]; | 161 view = element[WebInspector.SearchableView._symbol]; |
| 161 element = element.parentElementOrShadowHost(); | 162 element = element.parentElementOrShadowHost(); |
| 162 } | 163 } |
| 163 return view; | 164 return view; |
| 165 } |
| 166 |
| 167 _toggleCaseSensitiveSearch() { |
| 168 this._caseSensitiveButton.setToggled(!this._caseSensitiveButton.toggled()); |
| 169 this._saveSetting(); |
| 170 this._performSearch(false, true); |
| 171 } |
| 172 |
| 173 _toggleRegexSearch() { |
| 174 this._regexButton.setToggled(!this._regexButton.toggled()); |
| 175 this._saveSetting(); |
| 176 this._performSearch(false, true); |
| 177 } |
| 178 |
| 179 _saveSetting() { |
| 180 if (!this._setting) |
| 181 return; |
| 182 var settingValue = this._setting.get() || {}; |
| 183 settingValue.caseSensitive = this._caseSensitiveButton.toggled(); |
| 184 settingValue.isRegex = this._regexButton.toggled(); |
| 185 this._setting.set(settingValue); |
| 186 } |
| 187 |
| 188 _loadSetting() { |
| 189 var settingValue = this._setting ? (this._setting.get() || {}) : {}; |
| 190 if (this._searchProvider.supportsCaseSensitiveSearch()) |
| 191 this._caseSensitiveButton.setToggled(!!settingValue.caseSensitive); |
| 192 if (this._searchProvider.supportsRegexSearch()) |
| 193 this._regexButton.setToggled(!!settingValue.isRegex); |
| 194 } |
| 195 |
| 196 /** |
| 197 * @param {number} minimalSearchQuerySize |
| 198 */ |
| 199 setMinimalSearchQuerySize(minimalSearchQuerySize) { |
| 200 this._minimalSearchQuerySize = minimalSearchQuerySize; |
| 201 } |
| 202 |
| 203 /** |
| 204 * @param {string} placeholder |
| 205 */ |
| 206 setPlaceholder(placeholder) { |
| 207 this._searchInputElement.placeholder = placeholder; |
| 208 } |
| 209 |
| 210 /** |
| 211 * @param {boolean} replaceable |
| 212 */ |
| 213 setReplaceable(replaceable) { |
| 214 this._replaceable = replaceable; |
| 215 } |
| 216 |
| 217 /** |
| 218 * @param {number} matches |
| 219 */ |
| 220 updateSearchMatchesCount(matches) { |
| 221 this._searchProvider.currentSearchMatches = matches; |
| 222 this._updateSearchMatchesCountAndCurrentMatchIndex(this._searchProvider.curr
entQuery ? matches : 0, -1); |
| 223 } |
| 224 |
| 225 /** |
| 226 * @param {number} currentMatchIndex |
| 227 */ |
| 228 updateCurrentMatchIndex(currentMatchIndex) { |
| 229 this._updateSearchMatchesCountAndCurrentMatchIndex(this._searchProvider.curr
entSearchMatches, currentMatchIndex); |
| 230 } |
| 231 |
| 232 /** |
| 233 * @return {boolean} |
| 234 */ |
| 235 isSearchVisible() { |
| 236 return this._searchIsVisible; |
| 237 } |
| 238 |
| 239 closeSearch() { |
| 240 this.cancelSearch(); |
| 241 if (this._footerElementContainer.hasFocus()) |
| 242 this.focus(); |
| 243 } |
| 244 |
| 245 _toggleSearchBar(toggled) { |
| 246 this._footerElementContainer.classList.toggle('hidden', !toggled); |
| 247 this.doResize(); |
| 248 } |
| 249 |
| 250 cancelSearch() { |
| 251 if (!this._searchIsVisible) |
| 252 return; |
| 253 this.resetSearch(); |
| 254 delete this._searchIsVisible; |
| 255 this._toggleSearchBar(false); |
| 256 } |
| 257 |
| 258 resetSearch() { |
| 259 this._clearSearch(); |
| 260 this._updateReplaceVisibility(); |
| 261 this._matchesElement.textContent = ''; |
| 262 } |
| 263 |
| 264 refreshSearch() { |
| 265 if (!this._searchIsVisible) |
| 266 return; |
| 267 this.resetSearch(); |
| 268 this._performSearch(false, false); |
| 269 } |
| 270 |
| 271 /** |
| 272 * @return {boolean} |
| 273 */ |
| 274 handleFindNextShortcut() { |
| 275 if (!this._searchIsVisible) |
| 276 return false; |
| 277 this._searchProvider.jumpToNextSearchResult(); |
| 278 return true; |
| 279 } |
| 280 |
| 281 /** |
| 282 * @return {boolean} |
| 283 */ |
| 284 handleFindPreviousShortcut() { |
| 285 if (!this._searchIsVisible) |
| 286 return false; |
| 287 this._searchProvider.jumpToPreviousSearchResult(); |
| 288 return true; |
| 289 } |
| 290 |
| 291 /** |
| 292 * @return {boolean} |
| 293 */ |
| 294 handleFindShortcut() { |
| 295 this.showSearchField(); |
| 296 return true; |
| 297 } |
| 298 |
| 299 /** |
| 300 * @return {boolean} |
| 301 */ |
| 302 handleCancelSearchShortcut() { |
| 303 if (!this._searchIsVisible) |
| 304 return false; |
| 305 this.closeSearch(); |
| 306 return true; |
| 307 } |
| 308 |
| 309 /** |
| 310 * @param {boolean} enabled |
| 311 */ |
| 312 _updateSearchNavigationButtonState(enabled) { |
| 313 this._replaceButtonElement.disabled = !enabled; |
| 314 if (enabled) { |
| 315 this._searchNavigationPrevElement.classList.add('enabled'); |
| 316 this._searchNavigationNextElement.classList.add('enabled'); |
| 317 } else { |
| 318 this._searchNavigationPrevElement.classList.remove('enabled'); |
| 319 this._searchNavigationNextElement.classList.remove('enabled'); |
| 320 } |
| 321 } |
| 322 |
| 323 /** |
| 324 * @param {number} matches |
| 325 * @param {number} currentMatchIndex |
| 326 */ |
| 327 _updateSearchMatchesCountAndCurrentMatchIndex(matches, currentMatchIndex) { |
| 328 if (!this._currentQuery) |
| 329 this._matchesElement.textContent = ''; |
| 330 else if (matches === 0 || currentMatchIndex >= 0) |
| 331 this._matchesElement.textContent = WebInspector.UIString('%d of %d', curre
ntMatchIndex + 1, matches); |
| 332 else if (matches === 1) |
| 333 this._matchesElement.textContent = WebInspector.UIString('1 match'); |
| 334 else |
| 335 this._matchesElement.textContent = WebInspector.UIString('%d matches', mat
ches); |
| 336 this._updateSearchNavigationButtonState(matches > 0); |
| 337 } |
| 338 |
| 339 showSearchField() { |
| 340 if (this._searchIsVisible) |
| 341 this.cancelSearch(); |
| 342 |
| 343 var queryCandidate; |
| 344 if (!this._searchInputElement.hasFocus()) { |
| 345 var selection = this._searchInputElement.getComponentSelection(); |
| 346 if (selection.rangeCount) |
| 347 queryCandidate = selection.toString().replace(/\r?\n.*/, ''); |
| 348 } |
| 349 |
| 350 this._toggleSearchBar(true); |
| 351 this._updateReplaceVisibility(); |
| 352 if (queryCandidate) |
| 353 this._searchInputElement.value = queryCandidate; |
| 354 this._performSearch(false, false); |
| 355 this._searchInputElement.focus(); |
| 356 this._searchInputElement.select(); |
| 357 this._searchIsVisible = true; |
| 358 } |
| 359 |
| 360 _updateReplaceVisibility() { |
| 361 this._replaceElement.classList.toggle('hidden', !this._replaceable); |
| 362 if (!this._replaceable) { |
| 363 this._replaceCheckboxElement.checked = false; |
| 364 this._updateSecondRowVisibility(); |
| 365 } |
| 366 } |
| 367 |
| 368 /** |
| 369 * @param {!Event} event |
| 370 */ |
| 371 _onSearchKeyDown(event) { |
| 372 if (isEscKey(event)) { |
| 373 this.closeSearch(); |
| 374 event.consume(true); |
| 375 return; |
| 376 } |
| 377 if (!isEnterKey(event)) |
| 378 return; |
| 379 |
| 380 if (!this._currentQuery) |
| 381 this._performSearch(true, true, event.shiftKey); |
| 382 else |
| 383 this._jumpToNextSearchResult(event.shiftKey); |
| 384 } |
| 385 |
| 386 /** |
| 387 * @param {!Event} event |
| 388 */ |
| 389 _onReplaceKeyDown(event) { |
| 390 if (isEnterKey(event)) |
| 391 this._replace(); |
| 392 } |
| 393 |
| 394 /** |
| 395 * @param {boolean=} isBackwardSearch |
| 396 */ |
| 397 _jumpToNextSearchResult(isBackwardSearch) { |
| 398 if (!this._currentQuery || !this._searchNavigationPrevElement.classList.cont
ains('enabled')) |
| 399 return; |
| 400 |
| 401 if (isBackwardSearch) |
| 402 this._searchProvider.jumpToPreviousSearchResult(); |
| 403 else |
| 404 this._searchProvider.jumpToNextSearchResult(); |
| 405 } |
| 406 |
| 407 _onNextButtonSearch(event) { |
| 408 if (!this._searchNavigationNextElement.classList.contains('enabled')) |
| 409 return; |
| 410 this._jumpToNextSearchResult(); |
| 411 this._searchInputElement.focus(); |
| 412 } |
| 413 |
| 414 _onPrevButtonSearch(event) { |
| 415 if (!this._searchNavigationPrevElement.classList.contains('enabled')) |
| 416 return; |
| 417 this._jumpToNextSearchResult(true); |
| 418 this._searchInputElement.focus(); |
| 419 } |
| 420 |
| 421 _onFindClick(event) { |
| 422 if (!this._currentQuery) |
| 423 this._performSearch(true, true); |
| 424 else |
| 425 this._jumpToNextSearchResult(); |
| 426 this._searchInputElement.focus(); |
| 427 } |
| 428 |
| 429 _onPreviousClick(event) { |
| 430 if (!this._currentQuery) |
| 431 this._performSearch(true, true, true); |
| 432 else |
| 433 this._jumpToNextSearchResult(true); |
| 434 this._searchInputElement.focus(); |
| 435 } |
| 436 |
| 437 _clearSearch() { |
| 438 delete this._currentQuery; |
| 439 if (!!this._searchProvider.currentQuery) { |
| 440 delete this._searchProvider.currentQuery; |
| 441 this._searchProvider.searchCanceled(); |
| 442 } |
| 443 this._updateSearchMatchesCountAndCurrentMatchIndex(0, -1); |
| 444 } |
| 445 |
| 446 /** |
| 447 * @param {boolean} forceSearch |
| 448 * @param {boolean} shouldJump |
| 449 * @param {boolean=} jumpBackwards |
| 450 */ |
| 451 _performSearch(forceSearch, shouldJump, jumpBackwards) { |
| 452 var query = this._searchInputElement.value; |
| 453 if (!query || (!forceSearch && query.length < this._minimalSearchQuerySize &
& !this._currentQuery)) { |
| 454 this._clearSearch(); |
| 455 return; |
| 456 } |
| 457 |
| 458 this._currentQuery = query; |
| 459 this._searchProvider.currentQuery = query; |
| 460 |
| 461 var searchConfig = this._currentSearchConfig(); |
| 462 this._searchProvider.performSearch(searchConfig, shouldJump, jumpBackwards); |
| 463 } |
| 464 |
| 465 /** |
| 466 * @return {!WebInspector.SearchableView.SearchConfig} |
| 467 */ |
| 468 _currentSearchConfig() { |
| 469 var query = this._searchInputElement.value; |
| 470 var caseSensitive = this._caseSensitiveButton ? this._caseSensitiveButton.to
ggled() : false; |
| 471 var isRegex = this._regexButton ? this._regexButton.toggled() : false; |
| 472 return new WebInspector.SearchableView.SearchConfig(query, caseSensitive, is
Regex); |
| 473 } |
| 474 |
| 475 _updateSecondRowVisibility() { |
| 476 var secondRowVisible = this._replaceCheckboxElement.checked; |
| 477 this._footerElementContainer.classList.toggle('replaceable', secondRowVisibl
e); |
| 478 this._footerElement.classList.toggle('toolbar-search-replace', secondRowVisi
ble); |
| 479 this._secondRowElement.classList.toggle('hidden', !secondRowVisible); |
| 480 this._prevButtonElement.classList.toggle('hidden', !secondRowVisible); |
| 481 this._findButtonElement.classList.toggle('hidden', !secondRowVisible); |
| 482 this._replaceCheckboxElement.tabIndex = secondRowVisible ? -1 : 0; |
| 483 |
| 484 if (secondRowVisible) |
| 485 this._replaceInputElement.focus(); |
| 486 else |
| 487 this._searchInputElement.focus(); |
| 488 this.doResize(); |
| 489 } |
| 490 |
| 491 _replace() { |
| 492 var searchConfig = this._currentSearchConfig(); |
| 493 /** @type {!WebInspector.Replaceable} */ (this._searchProvider) |
| 494 .replaceSelectionWith(searchConfig, this._replaceInputElement.value); |
| 495 delete this._currentQuery; |
| 496 this._performSearch(true, true); |
| 497 } |
| 498 |
| 499 _replaceAll() { |
| 500 var searchConfig = this._currentSearchConfig(); |
| 501 /** @type {!WebInspector.Replaceable} */ (this._searchProvider) |
| 502 .replaceAllWith(searchConfig, this._replaceInputElement.value); |
| 503 } |
| 504 |
| 505 /** |
| 506 * @param {!Event} event |
| 507 */ |
| 508 _onInput(event) { |
| 509 if (this._valueChangedTimeoutId) |
| 510 clearTimeout(this._valueChangedTimeoutId); |
| 511 var timeout = this._searchInputElement.value.length < 3 ? 200 : 0; |
| 512 this._valueChangedTimeoutId = setTimeout(this._onValueChanged.bind(this), ti
meout); |
| 513 } |
| 514 |
| 515 _onValueChanged() { |
| 516 if (!this._searchIsVisible) |
| 517 return; |
| 518 delete this._valueChangedTimeoutId; |
| 519 this._performSearch(false, true); |
| 520 } |
| 164 }; | 521 }; |
| 165 | 522 |
| 166 WebInspector.SearchableView.prototype = { | 523 WebInspector.SearchableView._lastUniqueId = 0; |
| 167 _toggleCaseSensitiveSearch: function() | 524 |
| 168 { | 525 WebInspector.SearchableView._symbol = Symbol('searchableView'); |
| 169 this._caseSensitiveButton.setToggled(!this._caseSensitiveButton.toggled(
)); | 526 |
| 170 this._saveSetting(); | |
| 171 this._performSearch(false, true); | |
| 172 }, | |
| 173 | |
| 174 _toggleRegexSearch: function() | |
| 175 { | |
| 176 this._regexButton.setToggled(!this._regexButton.toggled()); | |
| 177 this._saveSetting(); | |
| 178 this._performSearch(false, true); | |
| 179 }, | |
| 180 | |
| 181 _saveSetting: function() | |
| 182 { | |
| 183 if (!this._setting) | |
| 184 return; | |
| 185 var settingValue = this._setting.get() || {}; | |
| 186 settingValue.caseSensitive = this._caseSensitiveButton.toggled(); | |
| 187 settingValue.isRegex = this._regexButton.toggled(); | |
| 188 this._setting.set(settingValue); | |
| 189 }, | |
| 190 | |
| 191 _loadSetting: function() | |
| 192 { | |
| 193 var settingValue = this._setting ? (this._setting.get() || {}) : {}; | |
| 194 if (this._searchProvider.supportsCaseSensitiveSearch()) | |
| 195 this._caseSensitiveButton.setToggled(!!settingValue.caseSensitive); | |
| 196 if (this._searchProvider.supportsRegexSearch()) | |
| 197 this._regexButton.setToggled(!!settingValue.isRegex); | |
| 198 }, | |
| 199 | |
| 200 /** | |
| 201 * @param {number} minimalSearchQuerySize | |
| 202 */ | |
| 203 setMinimalSearchQuerySize: function(minimalSearchQuerySize) | |
| 204 { | |
| 205 this._minimalSearchQuerySize = minimalSearchQuerySize; | |
| 206 }, | |
| 207 | |
| 208 /** | |
| 209 * @param {string} placeholder | |
| 210 */ | |
| 211 setPlaceholder: function(placeholder) | |
| 212 { | |
| 213 this._searchInputElement.placeholder = placeholder; | |
| 214 }, | |
| 215 | |
| 216 /** | |
| 217 * @param {boolean} replaceable | |
| 218 */ | |
| 219 setReplaceable: function(replaceable) | |
| 220 { | |
| 221 this._replaceable = replaceable; | |
| 222 }, | |
| 223 | |
| 224 /** | |
| 225 * @param {number} matches | |
| 226 */ | |
| 227 updateSearchMatchesCount: function(matches) | |
| 228 { | |
| 229 this._searchProvider.currentSearchMatches = matches; | |
| 230 this._updateSearchMatchesCountAndCurrentMatchIndex(this._searchProvider.
currentQuery ? matches : 0, -1); | |
| 231 }, | |
| 232 | |
| 233 /** | |
| 234 * @param {number} currentMatchIndex | |
| 235 */ | |
| 236 updateCurrentMatchIndex: function(currentMatchIndex) | |
| 237 { | |
| 238 this._updateSearchMatchesCountAndCurrentMatchIndex(this._searchProvider.
currentSearchMatches, currentMatchIndex); | |
| 239 }, | |
| 240 | |
| 241 /** | |
| 242 * @return {boolean} | |
| 243 */ | |
| 244 isSearchVisible: function() | |
| 245 { | |
| 246 return this._searchIsVisible; | |
| 247 }, | |
| 248 | |
| 249 closeSearch: function() | |
| 250 { | |
| 251 this.cancelSearch(); | |
| 252 if (this._footerElementContainer.hasFocus()) | |
| 253 this.focus(); | |
| 254 }, | |
| 255 | |
| 256 _toggleSearchBar: function(toggled) | |
| 257 { | |
| 258 this._footerElementContainer.classList.toggle("hidden", !toggled); | |
| 259 this.doResize(); | |
| 260 }, | |
| 261 | |
| 262 cancelSearch: function() | |
| 263 { | |
| 264 if (!this._searchIsVisible) | |
| 265 return; | |
| 266 this.resetSearch(); | |
| 267 delete this._searchIsVisible; | |
| 268 this._toggleSearchBar(false); | |
| 269 }, | |
| 270 | |
| 271 resetSearch: function() | |
| 272 { | |
| 273 this._clearSearch(); | |
| 274 this._updateReplaceVisibility(); | |
| 275 this._matchesElement.textContent = ""; | |
| 276 }, | |
| 277 | |
| 278 refreshSearch: function() | |
| 279 { | |
| 280 if (!this._searchIsVisible) | |
| 281 return; | |
| 282 this.resetSearch(); | |
| 283 this._performSearch(false, false); | |
| 284 }, | |
| 285 | |
| 286 /** | |
| 287 * @return {boolean} | |
| 288 */ | |
| 289 handleFindNextShortcut: function() | |
| 290 { | |
| 291 if (!this._searchIsVisible) | |
| 292 return false; | |
| 293 this._searchProvider.jumpToNextSearchResult(); | |
| 294 return true; | |
| 295 }, | |
| 296 | |
| 297 /** | |
| 298 * @return {boolean} | |
| 299 */ | |
| 300 handleFindPreviousShortcut: function() | |
| 301 { | |
| 302 if (!this._searchIsVisible) | |
| 303 return false; | |
| 304 this._searchProvider.jumpToPreviousSearchResult(); | |
| 305 return true; | |
| 306 }, | |
| 307 | |
| 308 /** | |
| 309 * @return {boolean} | |
| 310 */ | |
| 311 handleFindShortcut: function() | |
| 312 { | |
| 313 this.showSearchField(); | |
| 314 return true; | |
| 315 }, | |
| 316 | |
| 317 /** | |
| 318 * @return {boolean} | |
| 319 */ | |
| 320 handleCancelSearchShortcut: function() | |
| 321 { | |
| 322 if (!this._searchIsVisible) | |
| 323 return false; | |
| 324 this.closeSearch(); | |
| 325 return true; | |
| 326 }, | |
| 327 | |
| 328 /** | |
| 329 * @param {boolean} enabled | |
| 330 */ | |
| 331 _updateSearchNavigationButtonState: function(enabled) | |
| 332 { | |
| 333 this._replaceButtonElement.disabled = !enabled; | |
| 334 if (enabled) { | |
| 335 this._searchNavigationPrevElement.classList.add("enabled"); | |
| 336 this._searchNavigationNextElement.classList.add("enabled"); | |
| 337 } else { | |
| 338 this._searchNavigationPrevElement.classList.remove("enabled"); | |
| 339 this._searchNavigationNextElement.classList.remove("enabled"); | |
| 340 } | |
| 341 }, | |
| 342 | |
| 343 /** | |
| 344 * @param {number} matches | |
| 345 * @param {number} currentMatchIndex | |
| 346 */ | |
| 347 _updateSearchMatchesCountAndCurrentMatchIndex: function(matches, currentMatc
hIndex) | |
| 348 { | |
| 349 if (!this._currentQuery) | |
| 350 this._matchesElement.textContent = ""; | |
| 351 else if (matches === 0 || currentMatchIndex >= 0) | |
| 352 this._matchesElement.textContent = WebInspector.UIString("%d of %d",
currentMatchIndex + 1, matches); | |
| 353 else if (matches === 1) | |
| 354 this._matchesElement.textContent = WebInspector.UIString("1 match"); | |
| 355 else | |
| 356 this._matchesElement.textContent = WebInspector.UIString("%d matches
", matches); | |
| 357 this._updateSearchNavigationButtonState(matches > 0); | |
| 358 }, | |
| 359 | |
| 360 showSearchField: function() | |
| 361 { | |
| 362 if (this._searchIsVisible) | |
| 363 this.cancelSearch(); | |
| 364 | |
| 365 var queryCandidate; | |
| 366 if (!this._searchInputElement.hasFocus()) { | |
| 367 var selection = this._searchInputElement.getComponentSelection(); | |
| 368 if (selection.rangeCount) | |
| 369 queryCandidate = selection.toString().replace(/\r?\n.*/, ""); | |
| 370 } | |
| 371 | |
| 372 this._toggleSearchBar(true); | |
| 373 this._updateReplaceVisibility(); | |
| 374 if (queryCandidate) | |
| 375 this._searchInputElement.value = queryCandidate; | |
| 376 this._performSearch(false, false); | |
| 377 this._searchInputElement.focus(); | |
| 378 this._searchInputElement.select(); | |
| 379 this._searchIsVisible = true; | |
| 380 }, | |
| 381 | |
| 382 _updateReplaceVisibility: function() | |
| 383 { | |
| 384 this._replaceElement.classList.toggle("hidden", !this._replaceable); | |
| 385 if (!this._replaceable) { | |
| 386 this._replaceCheckboxElement.checked = false; | |
| 387 this._updateSecondRowVisibility(); | |
| 388 } | |
| 389 }, | |
| 390 | |
| 391 /** | |
| 392 * @param {!Event} event | |
| 393 */ | |
| 394 _onSearchKeyDown: function(event) | |
| 395 { | |
| 396 if (isEscKey(event)) { | |
| 397 this.closeSearch(); | |
| 398 event.consume(true); | |
| 399 return; | |
| 400 } | |
| 401 if (!isEnterKey(event)) | |
| 402 return; | |
| 403 | |
| 404 if (!this._currentQuery) | |
| 405 this._performSearch(true, true, event.shiftKey); | |
| 406 else | |
| 407 this._jumpToNextSearchResult(event.shiftKey); | |
| 408 }, | |
| 409 | |
| 410 /** | |
| 411 * @param {!Event} event | |
| 412 */ | |
| 413 _onReplaceKeyDown: function(event) | |
| 414 { | |
| 415 if (isEnterKey(event)) | |
| 416 this._replace(); | |
| 417 }, | |
| 418 | |
| 419 /** | |
| 420 * @param {boolean=} isBackwardSearch | |
| 421 */ | |
| 422 _jumpToNextSearchResult: function(isBackwardSearch) | |
| 423 { | |
| 424 if (!this._currentQuery || !this._searchNavigationPrevElement.classList.
contains("enabled")) | |
| 425 return; | |
| 426 | |
| 427 if (isBackwardSearch) | |
| 428 this._searchProvider.jumpToPreviousSearchResult(); | |
| 429 else | |
| 430 this._searchProvider.jumpToNextSearchResult(); | |
| 431 }, | |
| 432 | |
| 433 _onNextButtonSearch: function(event) | |
| 434 { | |
| 435 if (!this._searchNavigationNextElement.classList.contains("enabled")) | |
| 436 return; | |
| 437 this._jumpToNextSearchResult(); | |
| 438 this._searchInputElement.focus(); | |
| 439 }, | |
| 440 | |
| 441 _onPrevButtonSearch: function(event) | |
| 442 { | |
| 443 if (!this._searchNavigationPrevElement.classList.contains("enabled")) | |
| 444 return; | |
| 445 this._jumpToNextSearchResult(true); | |
| 446 this._searchInputElement.focus(); | |
| 447 }, | |
| 448 | |
| 449 _onFindClick: function(event) | |
| 450 { | |
| 451 if (!this._currentQuery) | |
| 452 this._performSearch(true, true); | |
| 453 else | |
| 454 this._jumpToNextSearchResult(); | |
| 455 this._searchInputElement.focus(); | |
| 456 }, | |
| 457 | |
| 458 _onPreviousClick: function(event) | |
| 459 { | |
| 460 if (!this._currentQuery) | |
| 461 this._performSearch(true, true, true); | |
| 462 else | |
| 463 this._jumpToNextSearchResult(true); | |
| 464 this._searchInputElement.focus(); | |
| 465 }, | |
| 466 | |
| 467 _clearSearch: function() | |
| 468 { | |
| 469 delete this._currentQuery; | |
| 470 if (!!this._searchProvider.currentQuery) { | |
| 471 delete this._searchProvider.currentQuery; | |
| 472 this._searchProvider.searchCanceled(); | |
| 473 } | |
| 474 this._updateSearchMatchesCountAndCurrentMatchIndex(0, -1); | |
| 475 }, | |
| 476 | |
| 477 /** | |
| 478 * @param {boolean} forceSearch | |
| 479 * @param {boolean} shouldJump | |
| 480 * @param {boolean=} jumpBackwards | |
| 481 */ | |
| 482 _performSearch: function(forceSearch, shouldJump, jumpBackwards) | |
| 483 { | |
| 484 var query = this._searchInputElement.value; | |
| 485 if (!query || (!forceSearch && query.length < this._minimalSearchQuerySi
ze && !this._currentQuery)) { | |
| 486 this._clearSearch(); | |
| 487 return; | |
| 488 } | |
| 489 | |
| 490 this._currentQuery = query; | |
| 491 this._searchProvider.currentQuery = query; | |
| 492 | |
| 493 var searchConfig = this._currentSearchConfig(); | |
| 494 this._searchProvider.performSearch(searchConfig, shouldJump, jumpBackwar
ds); | |
| 495 }, | |
| 496 | |
| 497 /** | |
| 498 * @return {!WebInspector.SearchableView.SearchConfig} | |
| 499 */ | |
| 500 _currentSearchConfig: function() | |
| 501 { | |
| 502 var query = this._searchInputElement.value; | |
| 503 var caseSensitive = this._caseSensitiveButton ? this._caseSensitiveButto
n.toggled() : false; | |
| 504 var isRegex = this._regexButton ? this._regexButton.toggled() : false; | |
| 505 return new WebInspector.SearchableView.SearchConfig(query, caseSensitive
, isRegex); | |
| 506 }, | |
| 507 | |
| 508 _updateSecondRowVisibility: function() | |
| 509 { | |
| 510 var secondRowVisible = this._replaceCheckboxElement.checked; | |
| 511 this._footerElementContainer.classList.toggle("replaceable", secondRowVi
sible); | |
| 512 this._footerElement.classList.toggle("toolbar-search-replace", secondRow
Visible); | |
| 513 this._secondRowElement.classList.toggle("hidden", !secondRowVisible); | |
| 514 this._prevButtonElement.classList.toggle("hidden", !secondRowVisible); | |
| 515 this._findButtonElement.classList.toggle("hidden", !secondRowVisible); | |
| 516 this._replaceCheckboxElement.tabIndex = secondRowVisible ? -1 : 0; | |
| 517 | |
| 518 if (secondRowVisible) | |
| 519 this._replaceInputElement.focus(); | |
| 520 else | |
| 521 this._searchInputElement.focus(); | |
| 522 this.doResize(); | |
| 523 }, | |
| 524 | |
| 525 _replace: function() | |
| 526 { | |
| 527 var searchConfig = this._currentSearchConfig(); | |
| 528 /** @type {!WebInspector.Replaceable} */ (this._searchProvider).replaceS
electionWith(searchConfig, this._replaceInputElement.value); | |
| 529 delete this._currentQuery; | |
| 530 this._performSearch(true, true); | |
| 531 }, | |
| 532 | |
| 533 _replaceAll: function() | |
| 534 { | |
| 535 var searchConfig = this._currentSearchConfig(); | |
| 536 /** @type {!WebInspector.Replaceable} */ (this._searchProvider).replaceA
llWith(searchConfig, this._replaceInputElement.value); | |
| 537 }, | |
| 538 | |
| 539 /** | |
| 540 * @param {!Event} event | |
| 541 */ | |
| 542 _onInput: function(event) | |
| 543 { | |
| 544 if (this._valueChangedTimeoutId) | |
| 545 clearTimeout(this._valueChangedTimeoutId); | |
| 546 var timeout = this._searchInputElement.value.length < 3 ? 200 : 0; | |
| 547 this._valueChangedTimeoutId = setTimeout(this._onValueChanged.bind(this)
, timeout); | |
| 548 }, | |
| 549 | |
| 550 _onValueChanged: function() | |
| 551 { | |
| 552 if (!this._searchIsVisible) | |
| 553 return; | |
| 554 delete this._valueChangedTimeoutId; | |
| 555 this._performSearch(false, true); | |
| 556 }, | |
| 557 | |
| 558 __proto__: WebInspector.VBox.prototype | |
| 559 }; | |
| 560 | 527 |
| 561 /** | 528 /** |
| 562 * @interface | 529 * @interface |
| 563 */ | 530 */ |
| 564 WebInspector.Searchable = function() | 531 WebInspector.Searchable = function() {}; |
| 565 { | |
| 566 }; | |
| 567 | 532 |
| 568 WebInspector.Searchable.prototype = { | 533 WebInspector.Searchable.prototype = { |
| 569 searchCanceled: function() { }, | 534 searchCanceled: function() {}, |
| 570 | 535 |
| 571 /** | 536 /** |
| 572 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig | 537 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig |
| 573 * @param {boolean} shouldJump | 538 * @param {boolean} shouldJump |
| 574 * @param {boolean=} jumpBackwards | 539 * @param {boolean=} jumpBackwards |
| 575 */ | 540 */ |
| 576 performSearch: function(searchConfig, shouldJump, jumpBackwards) { }, | 541 performSearch: function(searchConfig, shouldJump, jumpBackwards) {}, |
| 577 | 542 |
| 578 jumpToNextSearchResult: function() { }, | 543 jumpToNextSearchResult: function() {}, |
| 579 | 544 |
| 580 jumpToPreviousSearchResult: function() { }, | 545 jumpToPreviousSearchResult: function() {}, |
| 581 | 546 |
| 582 /** | 547 /** |
| 583 * @return {boolean} | 548 * @return {boolean} |
| 584 */ | 549 */ |
| 585 supportsCaseSensitiveSearch: function() { }, | 550 supportsCaseSensitiveSearch: function() {}, |
| 586 | 551 |
| 587 /** | 552 /** |
| 588 * @return {boolean} | 553 * @return {boolean} |
| 589 */ | 554 */ |
| 590 supportsRegexSearch: function() { } | 555 supportsRegexSearch: function() {} |
| 591 }; | 556 }; |
| 592 | 557 |
| 593 /** | 558 /** |
| 594 * @interface | 559 * @interface |
| 595 */ | 560 */ |
| 596 WebInspector.Replaceable = function() | 561 WebInspector.Replaceable = function() {}; |
| 597 { | 562 |
| 563 WebInspector.Replaceable.prototype = { |
| 564 /** |
| 565 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig |
| 566 * @param {string} replacement |
| 567 */ |
| 568 replaceSelectionWith: function(searchConfig, replacement) {}, |
| 569 |
| 570 /** |
| 571 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig |
| 572 * @param {string} replacement |
| 573 */ |
| 574 replaceAllWith: function(searchConfig, replacement) {} |
| 598 }; | 575 }; |
| 599 | 576 |
| 600 WebInspector.Replaceable.prototype = { | |
| 601 /** | |
| 602 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig | |
| 603 * @param {string} replacement | |
| 604 */ | |
| 605 replaceSelectionWith: function(searchConfig, replacement) { }, | |
| 606 | |
| 607 /** | |
| 608 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig | |
| 609 * @param {string} replacement | |
| 610 */ | |
| 611 replaceAllWith: function(searchConfig, replacement) { } | |
| 612 }; | |
| 613 | |
| 614 /** | 577 /** |
| 615 * @constructor | 578 * @unrestricted |
| 616 * @param {string} query | |
| 617 * @param {boolean} caseSensitive | |
| 618 * @param {boolean} isRegex | |
| 619 */ | 579 */ |
| 620 WebInspector.SearchableView.SearchConfig = function(query, caseSensitive, isRege
x) | 580 WebInspector.SearchableView.SearchConfig = class { |
| 621 { | 581 /** |
| 582 * @param {string} query |
| 583 * @param {boolean} caseSensitive |
| 584 * @param {boolean} isRegex |
| 585 */ |
| 586 constructor(query, caseSensitive, isRegex) { |
| 622 this.query = query; | 587 this.query = query; |
| 623 this.caseSensitive = caseSensitive; | 588 this.caseSensitive = caseSensitive; |
| 624 this.isRegex = isRegex; | 589 this.isRegex = isRegex; |
| 590 } |
| 591 |
| 592 /** |
| 593 * @param {boolean=} global |
| 594 * @return {!RegExp} |
| 595 */ |
| 596 toSearchRegex(global) { |
| 597 var modifiers = this.caseSensitive ? '' : 'i'; |
| 598 if (global) |
| 599 modifiers += 'g'; |
| 600 var query = this.isRegex ? '/' + this.query + '/' : this.query; |
| 601 |
| 602 var regex; |
| 603 |
| 604 // First try creating regex if user knows the / / hint. |
| 605 try { |
| 606 if (/^\/.+\/$/.test(query)) { |
| 607 regex = new RegExp(query.substring(1, query.length - 1), modifiers); |
| 608 regex.__fromRegExpQuery = true; |
| 609 } |
| 610 } catch (e) { |
| 611 // Silent catch. |
| 612 } |
| 613 |
| 614 // Otherwise just do a plain text search. |
| 615 if (!regex) |
| 616 regex = createPlainTextSearchRegex(query, modifiers); |
| 617 |
| 618 return regex; |
| 619 } |
| 625 }; | 620 }; |
| 626 | |
| 627 WebInspector.SearchableView.SearchConfig.prototype = { | |
| 628 /** | |
| 629 * @param {boolean=} global | |
| 630 * @return {!RegExp} | |
| 631 */ | |
| 632 toSearchRegex: function(global) | |
| 633 { | |
| 634 var modifiers = this.caseSensitive ? "" : "i"; | |
| 635 if (global) | |
| 636 modifiers += "g"; | |
| 637 var query = this.isRegex ? "/" + this.query + "/" : this.query; | |
| 638 | |
| 639 var regex; | |
| 640 | |
| 641 // First try creating regex if user knows the / / hint. | |
| 642 try { | |
| 643 if (/^\/.+\/$/.test(query)) { | |
| 644 regex = new RegExp(query.substring(1, query.length - 1), modifie
rs); | |
| 645 regex.__fromRegExpQuery = true; | |
| 646 } | |
| 647 } catch (e) { | |
| 648 // Silent catch. | |
| 649 } | |
| 650 | |
| 651 // Otherwise just do a plain text search. | |
| 652 if (!regex) | |
| 653 regex = createPlainTextSearchRegex(query, modifiers); | |
| 654 | |
| 655 return regex; | |
| 656 } | |
| 657 }; | |
| OLD | NEW |