| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. | |
| 3 * Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com). | |
| 4 * Copyright (C) 2009 Joseph Pecoraro | |
| 5 * Copyright (C) 2011 Google Inc. All rights reserved. | |
| 6 * | |
| 7 * Redistribution and use in source and binary forms, with or without | |
| 8 * modification, are permitted provided that the following conditions | |
| 9 * are met: | |
| 10 * | |
| 11 * 1. Redistributions of source code must retain the above copyright | |
| 12 * notice, this list of conditions and the following disclaimer. | |
| 13 * 2. Redistributions in binary form must reproduce the above copyright | |
| 14 * notice, this list of conditions and the following disclaimer in the | |
| 15 * documentation and/or other materials provided with the distribution. | |
| 16 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of | |
| 17 * its contributors may be used to endorse or promote products derived | |
| 18 * from this software without specific prior written permission. | |
| 19 * | |
| 20 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY | |
| 21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 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 | |
| 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 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 | |
| 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 | |
| 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 */ | |
| 31 | |
| 32 /** | |
| 33 * @constructor | |
| 34 * @extends {WebInspector.VBox} | |
| 35 * @param {!WebInspector.Searchable} searchable | |
| 36 * @param {string=} settingName | |
| 37 */ | |
| 38 WebInspector.SearchableView = function(searchable, settingName) | |
| 39 { | |
| 40 WebInspector.VBox.call(this); | |
| 41 | |
| 42 this._searchProvider = searchable; | |
| 43 this._settingName = settingName; | |
| 44 | |
| 45 this.element.addEventListener("keydown", this._onKeyDown.bind(this), false); | |
| 46 | |
| 47 this._footerElementContainer = this.element.createChild("div", "search-bar s
tatus-bar hidden"); | |
| 48 this._footerElementContainer.style.order = 100; | |
| 49 | |
| 50 this._footerElement = this._footerElementContainer.createChild("table", "too
lbar-search"); | |
| 51 this._footerElement.cellSpacing = 0; | |
| 52 | |
| 53 this._firstRowElement = this._footerElement.createChild("tr"); | |
| 54 this._secondRowElement = this._footerElement.createChild("tr", "hidden"); | |
| 55 | |
| 56 if (this._searchProvider.supportsCaseSensitiveSearch() || this._searchProvid
er.supportsRegexSearch()) { | |
| 57 var searchSettingsPrefixColumn = this._firstRowElement.createChild("td")
; | |
| 58 searchSettingsPrefixColumn.createChild("div", "search-settings-prefix") | |
| 59 this._secondRowElement.createChild("td"); | |
| 60 } | |
| 61 | |
| 62 if (this._searchProvider.supportsCaseSensitiveSearch()) { | |
| 63 var caseSensitiveColumn = this._firstRowElement.createChild("td"); | |
| 64 this._caseSensitiveButton = new WebInspector.StatusBarTextButton(WebInsp
ector.UIString("Case sensitive"), "case-sensitive-search", "Aa", 2); | |
| 65 this._caseSensitiveButton.addEventListener("click", this._toggleCaseSens
itiveSearch, this); | |
| 66 caseSensitiveColumn.appendChild(this._caseSensitiveButton.element); | |
| 67 this._secondRowElement.createChild("td"); | |
| 68 } | |
| 69 | |
| 70 if (this._searchProvider.supportsRegexSearch()) { | |
| 71 var regexColumn = this._firstRowElement.createChild("td"); | |
| 72 this._regexButton = new WebInspector.StatusBarTextButton(WebInspector.UI
String("Regex"), "regex-search", ".*", 2); | |
| 73 this._regexButton.addEventListener("click", this._toggleRegexSearch, thi
s); | |
| 74 regexColumn.appendChild(this._regexButton.element); | |
| 75 this._secondRowElement.createChild("td"); | |
| 76 } | |
| 77 | |
| 78 // Column 1 | |
| 79 var searchControlElementColumn = this._firstRowElement.createChild("td"); | |
| 80 this._searchControlElement = searchControlElementColumn.createChild("span",
"toolbar-search-control"); | |
| 81 this._searchInputElement = this._searchControlElement.createChild("input", "
search-replace"); | |
| 82 this._searchInputElement.id = "search-input-field"; | |
| 83 this._searchInputElement.placeholder = WebInspector.UIString("Find"); | |
| 84 | |
| 85 this._matchesElement = this._searchControlElement.createChild("label", "sear
ch-results-matches"); | |
| 86 this._matchesElement.setAttribute("for", "search-input-field"); | |
| 87 | |
| 88 this._searchNavigationElement = this._searchControlElement.createChild("div"
, "toolbar-search-navigation-controls"); | |
| 89 | |
| 90 this._searchNavigationPrevElement = this._searchNavigationElement.createChil
d("div", "toolbar-search-navigation toolbar-search-navigation-prev"); | |
| 91 this._searchNavigationPrevElement.addEventListener("click", this._onPrevButt
onSearch.bind(this), false); | |
| 92 this._searchNavigationPrevElement.title = WebInspector.UIString("Search Prev
ious"); | |
| 93 | |
| 94 this._searchNavigationNextElement = this._searchNavigationElement.createChil
d("div", "toolbar-search-navigation toolbar-search-navigation-next"); | |
| 95 this._searchNavigationNextElement.addEventListener("click", this._onNextButt
onSearch.bind(this), false); | |
| 96 this._searchNavigationNextElement.title = WebInspector.UIString("Search Next
"); | |
| 97 | |
| 98 this._searchInputElement.addEventListener("mousedown", this._onSearchFieldMa
nualFocus.bind(this), false); // when the search field is manually selected | |
| 99 this._searchInputElement.addEventListener("keydown", this._onSearchKeyDown.b
ind(this), true); | |
| 100 this._searchInputElement.addEventListener("input", this._onInput.bind(this),
false); | |
| 101 | |
| 102 this._replaceInputElement = this._secondRowElement.createChild("td").createC
hild("input", "search-replace toolbar-replace-control"); | |
| 103 this._replaceInputElement.addEventListener("keydown", this._onReplaceKeyDown
.bind(this), true); | |
| 104 this._replaceInputElement.placeholder = WebInspector.UIString("Replace"); | |
| 105 | |
| 106 // Column 2 | |
| 107 this._findButtonElement = this._firstRowElement.createChild("td").createChil
d("button", "search-action-button hidden"); | |
| 108 this._findButtonElement.textContent = WebInspector.UIString("Find"); | |
| 109 this._findButtonElement.tabIndex = -1; | |
| 110 this._findButtonElement.addEventListener("click", this._onFindClick.bind(thi
s), false); | |
| 111 | |
| 112 this._replaceButtonElement = this._secondRowElement.createChild("td").create
Child("button", "search-action-button"); | |
| 113 this._replaceButtonElement.textContent = WebInspector.UIString("Replace"); | |
| 114 this._replaceButtonElement.disabled = true; | |
| 115 this._replaceButtonElement.tabIndex = -1; | |
| 116 this._replaceButtonElement.addEventListener("click", this._replace.bind(this
), false); | |
| 117 | |
| 118 // Column 3 | |
| 119 this._prevButtonElement = this._firstRowElement.createChild("td").createChil
d("button", "search-action-button hidden"); | |
| 120 this._prevButtonElement.textContent = WebInspector.UIString("Previous"); | |
| 121 this._prevButtonElement.tabIndex = -1; | |
| 122 this._prevButtonElement.addEventListener("click", this._onPreviousClick.bind
(this), false); | |
| 123 | |
| 124 this._replaceAllButtonElement = this._secondRowElement.createChild("td").cre
ateChild("button", "search-action-button"); | |
| 125 this._replaceAllButtonElement.textContent = WebInspector.UIString("Replace A
ll"); | |
| 126 this._replaceAllButtonElement.addEventListener("click", this._replaceAll.bin
d(this), false); | |
| 127 | |
| 128 // Column 4 | |
| 129 this._replaceElement = this._firstRowElement.createChild("td").createChild("
span"); | |
| 130 | |
| 131 this._replaceCheckboxElement = this._replaceElement.createChild("input"); | |
| 132 this._replaceCheckboxElement.type = "checkbox"; | |
| 133 this._uniqueId = ++WebInspector.SearchableView._lastUniqueId; | |
| 134 var replaceCheckboxId = "search-replace-trigger" + this._uniqueId; | |
| 135 this._replaceCheckboxElement.id = replaceCheckboxId; | |
| 136 this._replaceCheckboxElement.addEventListener("change", this._updateSecondRo
wVisibility.bind(this), false); | |
| 137 | |
| 138 this._replaceLabelElement = this._replaceElement.createChild("label"); | |
| 139 this._replaceLabelElement.textContent = WebInspector.UIString("Replace"); | |
| 140 this._replaceLabelElement.setAttribute("for", replaceCheckboxId); | |
| 141 | |
| 142 // Column 5 | |
| 143 var cancelButtonElement = this._firstRowElement.createChild("td").createChil
d("button", "search-action-button"); | |
| 144 cancelButtonElement.textContent = WebInspector.UIString("Cancel"); | |
| 145 cancelButtonElement.tabIndex = -1; | |
| 146 cancelButtonElement.addEventListener("click", this.closeSearch.bind(this), f
alse); | |
| 147 this._minimalSearchQuerySize = 3; | |
| 148 | |
| 149 this._registerShortcuts(); | |
| 150 this._loadSetting(); | |
| 151 } | |
| 152 | |
| 153 WebInspector.SearchableView._lastUniqueId = 0; | |
| 154 | |
| 155 /** | |
| 156 * @return {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} | |
| 157 */ | |
| 158 WebInspector.SearchableView.findShortcuts = function() | |
| 159 { | |
| 160 if (WebInspector.SearchableView._findShortcuts) | |
| 161 return WebInspector.SearchableView._findShortcuts; | |
| 162 WebInspector.SearchableView._findShortcuts = [WebInspector.KeyboardShortcut.
makeDescriptor("f", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)]; | |
| 163 if (!WebInspector.isMac()) | |
| 164 WebInspector.SearchableView._findShortcuts.push(WebInspector.KeyboardSho
rtcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F3)); | |
| 165 return WebInspector.SearchableView._findShortcuts; | |
| 166 } | |
| 167 | |
| 168 /** | |
| 169 * @return {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} | |
| 170 */ | |
| 171 WebInspector.SearchableView.cancelSearchShortcuts = function() | |
| 172 { | |
| 173 if (WebInspector.SearchableView._cancelSearchShortcuts) | |
| 174 return WebInspector.SearchableView._cancelSearchShortcuts; | |
| 175 WebInspector.SearchableView._cancelSearchShortcuts = [WebInspector.KeyboardS
hortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Esc)]; | |
| 176 return WebInspector.SearchableView._cancelSearchShortcuts; | |
| 177 } | |
| 178 | |
| 179 /** | |
| 180 * @return {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} | |
| 181 */ | |
| 182 WebInspector.SearchableView.findNextShortcut = function() | |
| 183 { | |
| 184 if (WebInspector.SearchableView._findNextShortcut) | |
| 185 return WebInspector.SearchableView._findNextShortcut; | |
| 186 WebInspector.SearchableView._findNextShortcut = []; | |
| 187 if (WebInspector.isMac()) | |
| 188 WebInspector.SearchableView._findNextShortcut.push(WebInspector.Keyboard
Shortcut.makeDescriptor("g", WebInspector.KeyboardShortcut.Modifiers.Meta)); | |
| 189 return WebInspector.SearchableView._findNextShortcut; | |
| 190 } | |
| 191 | |
| 192 /** | |
| 193 * @return {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} | |
| 194 */ | |
| 195 WebInspector.SearchableView.findPreviousShortcuts = function() | |
| 196 { | |
| 197 if (WebInspector.SearchableView._findPreviousShortcuts) | |
| 198 return WebInspector.SearchableView._findPreviousShortcuts; | |
| 199 WebInspector.SearchableView._findPreviousShortcuts = []; | |
| 200 if (WebInspector.isMac()) | |
| 201 WebInspector.SearchableView._findPreviousShortcuts.push(WebInspector.Key
boardShortcut.makeDescriptor("g", WebInspector.KeyboardShortcut.Modifiers.Meta |
WebInspector.KeyboardShortcut.Modifiers.Shift)); | |
| 202 return WebInspector.SearchableView._findPreviousShortcuts; | |
| 203 } | |
| 204 | |
| 205 WebInspector.SearchableView.prototype = { | |
| 206 _toggleCaseSensitiveSearch: function() | |
| 207 { | |
| 208 this._caseSensitiveButton.toggled = !this._caseSensitiveButton.toggled; | |
| 209 this._saveSetting(); | |
| 210 this._performSearch(false, true); | |
| 211 }, | |
| 212 | |
| 213 _toggleRegexSearch: function() | |
| 214 { | |
| 215 this._regexButton.toggled = !this._regexButton.toggled; | |
| 216 this._saveSetting(); | |
| 217 this._performSearch(false, true); | |
| 218 }, | |
| 219 | |
| 220 /** | |
| 221 * @return {?WebInspector.Setting} | |
| 222 */ | |
| 223 _setting: function() | |
| 224 { | |
| 225 if (!this._settingName) | |
| 226 return null; | |
| 227 if (!WebInspector.settings[this._settingName]) | |
| 228 WebInspector.settings[this._settingName] = WebInspector.settings.cre
ateSetting(this._settingName, {}); | |
| 229 return WebInspector.settings[this._settingName]; | |
| 230 }, | |
| 231 | |
| 232 _saveSetting: function() | |
| 233 { | |
| 234 var setting = this._setting(); | |
| 235 if (!setting) | |
| 236 return; | |
| 237 var settingValue = setting.get() || {}; | |
| 238 settingValue.caseSensitive = this._caseSensitiveButton.toggled; | |
| 239 settingValue.isRegex = this._regexButton.toggled; | |
| 240 setting.set(settingValue); | |
| 241 }, | |
| 242 | |
| 243 _loadSetting: function() | |
| 244 { | |
| 245 var settingValue = this._setting() ? (this._setting().get() || {}) : {}; | |
| 246 if (this._searchProvider.supportsCaseSensitiveSearch()) | |
| 247 this._caseSensitiveButton.toggled = !!settingValue.caseSensitive; | |
| 248 if (this._searchProvider.supportsRegexSearch()) | |
| 249 this._regexButton.toggled = !!settingValue.isRegex; | |
| 250 }, | |
| 251 | |
| 252 /** | |
| 253 * @return {!Element} | |
| 254 */ | |
| 255 defaultFocusedElement: function() | |
| 256 { | |
| 257 var children = this.children(); | |
| 258 for (var i = 0; i < children.length; ++i) { | |
| 259 var element = children[i].defaultFocusedElement(); | |
| 260 if (element) | |
| 261 return element; | |
| 262 } | |
| 263 return WebInspector.View.prototype.defaultFocusedElement.call(this); | |
| 264 }, | |
| 265 | |
| 266 /** | |
| 267 * @param {!Event} event | |
| 268 */ | |
| 269 _onKeyDown: function(event) | |
| 270 { | |
| 271 var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(/**@typ
e {!KeyboardEvent}*/(event)); | |
| 272 var handler = this._shortcuts[shortcutKey]; | |
| 273 if (handler && handler(event)) | |
| 274 event.consume(true); | |
| 275 }, | |
| 276 | |
| 277 _registerShortcuts: function() | |
| 278 { | |
| 279 this._shortcuts = {}; | |
| 280 | |
| 281 /** | |
| 282 * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} shortcuts | |
| 283 * @param {function()} handler | |
| 284 * @this {WebInspector.SearchableView} | |
| 285 */ | |
| 286 function register(shortcuts, handler) | |
| 287 { | |
| 288 for (var i = 0; i < shortcuts.length; ++i) | |
| 289 this._shortcuts[shortcuts[i].key] = handler; | |
| 290 } | |
| 291 | |
| 292 register.call(this, WebInspector.SearchableView.findShortcuts(), this.ha
ndleFindShortcut.bind(this)); | |
| 293 register.call(this, WebInspector.SearchableView.cancelSearchShortcuts(),
this.handleCancelSearchShortcut.bind(this)); | |
| 294 register.call(this, WebInspector.SearchableView.findNextShortcut(), this
.handleFindNextShortcut.bind(this)); | |
| 295 register.call(this, WebInspector.SearchableView.findPreviousShortcuts(),
this.handleFindPreviousShortcut.bind(this)); | |
| 296 }, | |
| 297 | |
| 298 /** | |
| 299 * @param {number} minimalSearchQuerySize | |
| 300 */ | |
| 301 setMinimalSearchQuerySize: function(minimalSearchQuerySize) | |
| 302 { | |
| 303 this._minimalSearchQuerySize = minimalSearchQuerySize; | |
| 304 }, | |
| 305 | |
| 306 /** | |
| 307 * @param {boolean} replaceable | |
| 308 */ | |
| 309 setReplaceable: function(replaceable) | |
| 310 { | |
| 311 this._replaceable = replaceable; | |
| 312 }, | |
| 313 | |
| 314 /** | |
| 315 * @param {number} matches | |
| 316 */ | |
| 317 updateSearchMatchesCount: function(matches) | |
| 318 { | |
| 319 this._searchProvider.currentSearchMatches = matches; | |
| 320 this._updateSearchMatchesCountAndCurrentMatchIndex(this._searchProvider.
currentQuery ? matches : 0, -1); | |
| 321 }, | |
| 322 | |
| 323 /** | |
| 324 * @param {number} currentMatchIndex | |
| 325 */ | |
| 326 updateCurrentMatchIndex: function(currentMatchIndex) | |
| 327 { | |
| 328 this._updateSearchMatchesCountAndCurrentMatchIndex(this._searchProvider.
currentSearchMatches, currentMatchIndex); | |
| 329 }, | |
| 330 | |
| 331 /** | |
| 332 * @return {boolean} | |
| 333 */ | |
| 334 isSearchVisible: function() | |
| 335 { | |
| 336 return this._searchIsVisible; | |
| 337 }, | |
| 338 | |
| 339 closeSearch: function() | |
| 340 { | |
| 341 this.cancelSearch(); | |
| 342 if (WebInspector.currentFocusElement() && WebInspector.currentFocusEleme
nt().isDescendant(this._footerElementContainer)) | |
| 343 this.focus(); | |
| 344 }, | |
| 345 | |
| 346 _toggleSearchBar: function(toggled) | |
| 347 { | |
| 348 this._footerElementContainer.classList.toggle("hidden", !toggled); | |
| 349 this.doResize(); | |
| 350 }, | |
| 351 | |
| 352 cancelSearch: function() | |
| 353 { | |
| 354 if (!this._searchIsVisible) | |
| 355 return; | |
| 356 this.resetSearch(); | |
| 357 delete this._searchIsVisible; | |
| 358 this._toggleSearchBar(false); | |
| 359 }, | |
| 360 | |
| 361 resetSearch: function() | |
| 362 { | |
| 363 this._clearSearch(); | |
| 364 this._updateReplaceVisibility(); | |
| 365 this._matchesElement.textContent = ""; | |
| 366 }, | |
| 367 | |
| 368 refreshSearch: function() | |
| 369 { | |
| 370 if (!this._searchIsVisible) | |
| 371 return; | |
| 372 this.resetSearch(); | |
| 373 this._performSearch(false, false); | |
| 374 }, | |
| 375 | |
| 376 /** | |
| 377 * @return {boolean} | |
| 378 */ | |
| 379 handleFindNextShortcut: function() | |
| 380 { | |
| 381 if (!this._searchIsVisible) | |
| 382 return false; | |
| 383 this._searchProvider.jumpToNextSearchResult(); | |
| 384 return true; | |
| 385 }, | |
| 386 | |
| 387 /** | |
| 388 * @return {boolean} | |
| 389 */ | |
| 390 handleFindPreviousShortcut: function() | |
| 391 { | |
| 392 if (!this._searchIsVisible) | |
| 393 return false; | |
| 394 this._searchProvider.jumpToPreviousSearchResult(); | |
| 395 return true; | |
| 396 }, | |
| 397 | |
| 398 /** | |
| 399 * @return {boolean} | |
| 400 */ | |
| 401 handleFindShortcut: function() | |
| 402 { | |
| 403 this.showSearchField(); | |
| 404 return true; | |
| 405 }, | |
| 406 | |
| 407 /** | |
| 408 * @return {boolean} | |
| 409 */ | |
| 410 handleCancelSearchShortcut: function() | |
| 411 { | |
| 412 if (!this._searchIsVisible) | |
| 413 return false; | |
| 414 this.closeSearch(); | |
| 415 return true; | |
| 416 }, | |
| 417 | |
| 418 /** | |
| 419 * @param {boolean} enabled | |
| 420 */ | |
| 421 _updateSearchNavigationButtonState: function(enabled) | |
| 422 { | |
| 423 this._replaceButtonElement.disabled = !enabled; | |
| 424 if (enabled) { | |
| 425 this._searchNavigationPrevElement.classList.add("enabled"); | |
| 426 this._searchNavigationNextElement.classList.add("enabled"); | |
| 427 } else { | |
| 428 this._searchNavigationPrevElement.classList.remove("enabled"); | |
| 429 this._searchNavigationNextElement.classList.remove("enabled"); | |
| 430 } | |
| 431 }, | |
| 432 | |
| 433 /** | |
| 434 * @param {number} matches | |
| 435 * @param {number} currentMatchIndex | |
| 436 */ | |
| 437 _updateSearchMatchesCountAndCurrentMatchIndex: function(matches, currentMatc
hIndex) | |
| 438 { | |
| 439 if (!this._currentQuery) | |
| 440 this._matchesElement.textContent = ""; | |
| 441 else if (matches === 0 || currentMatchIndex >= 0) | |
| 442 this._matchesElement.textContent = WebInspector.UIString("%d of %d",
currentMatchIndex + 1, matches); | |
| 443 else if (matches === 1) | |
| 444 this._matchesElement.textContent = WebInspector.UIString("1 match"); | |
| 445 else | |
| 446 this._matchesElement.textContent = WebInspector.UIString("%d matches
", matches); | |
| 447 this._updateSearchNavigationButtonState(matches > 0); | |
| 448 }, | |
| 449 | |
| 450 showSearchField: function() | |
| 451 { | |
| 452 if (this._searchIsVisible) | |
| 453 this.cancelSearch(); | |
| 454 | |
| 455 var queryCandidate; | |
| 456 if (WebInspector.currentFocusElement() !== this._searchInputElement) { | |
| 457 var selection = window.getSelection(); | |
| 458 if (selection.rangeCount) | |
| 459 queryCandidate = selection.toString().replace(/\r?\n.*/, ""); | |
| 460 } | |
| 461 | |
| 462 this._toggleSearchBar(true); | |
| 463 this._updateReplaceVisibility(); | |
| 464 if (queryCandidate) | |
| 465 this._searchInputElement.value = queryCandidate; | |
| 466 this._performSearch(false, false); | |
| 467 this._searchInputElement.focus(); | |
| 468 this._searchInputElement.select(); | |
| 469 this._searchIsVisible = true; | |
| 470 }, | |
| 471 | |
| 472 _updateReplaceVisibility: function() | |
| 473 { | |
| 474 this._replaceElement.classList.toggle("hidden", !this._replaceable); | |
| 475 if (!this._replaceable) { | |
| 476 this._replaceCheckboxElement.checked = false; | |
| 477 this._updateSecondRowVisibility(); | |
| 478 } | |
| 479 }, | |
| 480 | |
| 481 /** | |
| 482 * @param {!Event} event | |
| 483 */ | |
| 484 _onSearchFieldManualFocus: function(event) | |
| 485 { | |
| 486 WebInspector.setCurrentFocusElement(event.target); | |
| 487 }, | |
| 488 | |
| 489 /** | |
| 490 * @param {!Event} event | |
| 491 */ | |
| 492 _onSearchKeyDown: function(event) | |
| 493 { | |
| 494 if (!isEnterKey(event)) | |
| 495 return; | |
| 496 | |
| 497 if (!this._currentQuery) | |
| 498 this._performSearch(true, true, event.shiftKey); | |
| 499 else | |
| 500 this._jumpToNextSearchResult(event.shiftKey); | |
| 501 }, | |
| 502 | |
| 503 /** | |
| 504 * @param {!Event} event | |
| 505 */ | |
| 506 _onReplaceKeyDown: function(event) | |
| 507 { | |
| 508 if (isEnterKey(event)) | |
| 509 this._replace(); | |
| 510 }, | |
| 511 | |
| 512 /** | |
| 513 * @param {boolean=} isBackwardSearch | |
| 514 */ | |
| 515 _jumpToNextSearchResult: function(isBackwardSearch) | |
| 516 { | |
| 517 if (!this._currentQuery || !this._searchNavigationPrevElement.classList.
contains("enabled")) | |
| 518 return; | |
| 519 | |
| 520 if (isBackwardSearch) | |
| 521 this._searchProvider.jumpToPreviousSearchResult(); | |
| 522 else | |
| 523 this._searchProvider.jumpToNextSearchResult(); | |
| 524 }, | |
| 525 | |
| 526 _onNextButtonSearch: function(event) | |
| 527 { | |
| 528 if (!this._searchNavigationNextElement.classList.contains("enabled")) | |
| 529 return; | |
| 530 this._jumpToNextSearchResult(); | |
| 531 this._searchInputElement.focus(); | |
| 532 }, | |
| 533 | |
| 534 _onPrevButtonSearch: function(event) | |
| 535 { | |
| 536 if (!this._searchNavigationPrevElement.classList.contains("enabled")) | |
| 537 return; | |
| 538 this._jumpToNextSearchResult(true); | |
| 539 this._searchInputElement.focus(); | |
| 540 }, | |
| 541 | |
| 542 _onFindClick: function(event) | |
| 543 { | |
| 544 if (!this._currentQuery) | |
| 545 this._performSearch(true, true); | |
| 546 else | |
| 547 this._jumpToNextSearchResult(); | |
| 548 this._searchInputElement.focus(); | |
| 549 }, | |
| 550 | |
| 551 _onPreviousClick: function(event) | |
| 552 { | |
| 553 if (!this._currentQuery) | |
| 554 this._performSearch(true, true, true); | |
| 555 else | |
| 556 this._jumpToNextSearchResult(true); | |
| 557 this._searchInputElement.focus(); | |
| 558 }, | |
| 559 | |
| 560 _clearSearch: function() | |
| 561 { | |
| 562 delete this._currentQuery; | |
| 563 if (!!this._searchProvider.currentQuery) { | |
| 564 delete this._searchProvider.currentQuery; | |
| 565 this._searchProvider.searchCanceled(); | |
| 566 } | |
| 567 this._updateSearchMatchesCountAndCurrentMatchIndex(0, -1); | |
| 568 }, | |
| 569 | |
| 570 /** | |
| 571 * @param {boolean} forceSearch | |
| 572 * @param {boolean} shouldJump | |
| 573 * @param {boolean=} jumpBackwards | |
| 574 */ | |
| 575 _performSearch: function(forceSearch, shouldJump, jumpBackwards) | |
| 576 { | |
| 577 var query = this._searchInputElement.value; | |
| 578 if (!query || (!forceSearch && query.length < this._minimalSearchQuerySi
ze && !this._currentQuery)) { | |
| 579 this._clearSearch(); | |
| 580 return; | |
| 581 } | |
| 582 | |
| 583 this._currentQuery = query; | |
| 584 this._searchProvider.currentQuery = query; | |
| 585 | |
| 586 var searchConfig = this._currentSearchConfig(); | |
| 587 this._searchProvider.performSearch(searchConfig, shouldJump, jumpBackwar
ds); | |
| 588 }, | |
| 589 | |
| 590 /** | |
| 591 * @return {!WebInspector.SearchableView.SearchConfig} | |
| 592 */ | |
| 593 _currentSearchConfig: function() | |
| 594 { | |
| 595 var query = this._searchInputElement.value; | |
| 596 var caseSensitive = this._caseSensitiveButton ? this._caseSensitiveButto
n.toggled : false; | |
| 597 var isRegex = this._regexButton ? this._regexButton.toggled : false; | |
| 598 return new WebInspector.SearchableView.SearchConfig(query, caseSensitive
, isRegex); | |
| 599 }, | |
| 600 | |
| 601 _updateSecondRowVisibility: function() | |
| 602 { | |
| 603 var secondRowVisible = this._replaceCheckboxElement.checked; | |
| 604 this._footerElementContainer.classList.toggle("replaceable", secondRowVi
sible); | |
| 605 this._footerElement.classList.toggle("toolbar-search-replace", secondRow
Visible); | |
| 606 this._secondRowElement.classList.toggle("hidden", !secondRowVisible); | |
| 607 this._prevButtonElement.classList.toggle("hidden", !secondRowVisible); | |
| 608 this._findButtonElement.classList.toggle("hidden", !secondRowVisible); | |
| 609 this._replaceCheckboxElement.tabIndex = secondRowVisible ? -1 : 0; | |
| 610 | |
| 611 if (secondRowVisible) | |
| 612 this._replaceInputElement.focus(); | |
| 613 else | |
| 614 this._searchInputElement.focus(); | |
| 615 this.doResize(); | |
| 616 }, | |
| 617 | |
| 618 _replace: function() | |
| 619 { | |
| 620 var searchConfig = this._currentSearchConfig(); | |
| 621 /** @type {!WebInspector.Replaceable} */ (this._searchProvider).replaceS
electionWith(searchConfig, this._replaceInputElement.value); | |
| 622 delete this._currentQuery; | |
| 623 this._performSearch(true, true); | |
| 624 }, | |
| 625 | |
| 626 _replaceAll: function() | |
| 627 { | |
| 628 var searchConfig = this._currentSearchConfig(); | |
| 629 /** @type {!WebInspector.Replaceable} */ (this._searchProvider).replaceA
llWith(searchConfig, this._replaceInputElement.value); | |
| 630 }, | |
| 631 | |
| 632 _onInput: function(event) | |
| 633 { | |
| 634 this._onValueChanged(); | |
| 635 }, | |
| 636 | |
| 637 _onValueChanged: function() | |
| 638 { | |
| 639 this._performSearch(false, true); | |
| 640 }, | |
| 641 | |
| 642 __proto__: WebInspector.VBox.prototype | |
| 643 } | |
| 644 | |
| 645 /** | |
| 646 * @interface | |
| 647 */ | |
| 648 WebInspector.Searchable = function() | |
| 649 { | |
| 650 } | |
| 651 | |
| 652 WebInspector.Searchable.prototype = { | |
| 653 searchCanceled: function() { }, | |
| 654 | |
| 655 /** | |
| 656 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig | |
| 657 * @param {boolean} shouldJump | |
| 658 * @param {boolean=} jumpBackwards | |
| 659 */ | |
| 660 performSearch: function(searchConfig, shouldJump, jumpBackwards) { }, | |
| 661 | |
| 662 jumpToNextSearchResult: function() { }, | |
| 663 | |
| 664 jumpToPreviousSearchResult: function() { }, | |
| 665 | |
| 666 /** | |
| 667 * @return {boolean} | |
| 668 */ | |
| 669 supportsCaseSensitiveSearch: function() { }, | |
| 670 | |
| 671 /** | |
| 672 * @return {boolean} | |
| 673 */ | |
| 674 supportsRegexSearch: function() { } | |
| 675 } | |
| 676 | |
| 677 /** | |
| 678 * @interface | |
| 679 */ | |
| 680 WebInspector.Replaceable = function() | |
| 681 { | |
| 682 } | |
| 683 | |
| 684 WebInspector.Replaceable.prototype = { | |
| 685 /** | |
| 686 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig | |
| 687 * @param {string} replacement | |
| 688 */ | |
| 689 replaceSelectionWith: function(searchConfig, replacement) { }, | |
| 690 | |
| 691 /** | |
| 692 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig | |
| 693 * @param {string} replacement | |
| 694 */ | |
| 695 replaceAllWith: function(searchConfig, replacement) { } | |
| 696 } | |
| 697 | |
| 698 /** | |
| 699 * @constructor | |
| 700 * @param {string} query | |
| 701 * @param {boolean} caseSensitive | |
| 702 * @param {boolean} isRegex | |
| 703 */ | |
| 704 WebInspector.SearchableView.SearchConfig = function(query, caseSensitive, isRege
x) | |
| 705 { | |
| 706 this.query = query; | |
| 707 this.caseSensitive = caseSensitive; | |
| 708 this.isRegex = isRegex; | |
| 709 } | |
| OLD | NEW |