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.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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.
34 * @extends {WebInspector.VBox}
35 * @param {!WebInspector.Searchable} searchable
36 * @param {string=} settingName
38 WebInspector
.SearchableView = function(searchable
, settingName
)
40 WebInspector
.VBox
.call(this, true);
41 this.registerRequiredCSS("ui/searchableView.css");
43 this._searchProvider
= searchable
;
44 this._setting
= settingName
? WebInspector
.settings
.createSetting(settingName
, {}) : null;
46 this.element
.addEventListener("keydown", this._onKeyDown
.bind(this), false);
48 this.contentElement
.createChild("content");
49 this._footerElementContainer
= this.contentElement
.createChild("div", "search-bar hidden");
50 this._footerElementContainer
.style
.order
= 100;
52 var toolbar
= new WebInspector
.Toolbar(this._footerElementContainer
);
54 if (this._searchProvider
.supportsCaseSensitiveSearch()) {
55 this._caseSensitiveButton
= new WebInspector
.ToolbarTextButton(WebInspector
.UIString("Case sensitive"), "case-sensitive-search-toolbar-item", "Aa", 2);
56 this._caseSensitiveButton
.addEventListener("click", this._toggleCaseSensitiveSearch
, this);
57 toolbar
.appendToolbarItem(this._caseSensitiveButton
);
60 if (this._searchProvider
.supportsRegexSearch()) {
61 this._regexButton
= new WebInspector
.ToolbarTextButton(WebInspector
.UIString("Regex"), "regex-search-toolbar-item", ".*", 2);
62 this._regexButton
.addEventListener("click", this._toggleRegexSearch
, this);
63 toolbar
.appendToolbarItem(this._regexButton
);
66 this._footerElement
= this._footerElementContainer
.createChild("table", "toolbar-search");
67 this._footerElement
.cellSpacing
= 0;
69 this._firstRowElement
= this._footerElement
.createChild("tr");
70 this._secondRowElement
= this._footerElement
.createChild("tr", "hidden");
73 var searchControlElementColumn
= this._firstRowElement
.createChild("td");
74 this._searchControlElement
= searchControlElementColumn
.createChild("span", "toolbar-search-control");
76 this._searchInputElement
= WebInspector
.HistoryInput
.create();
77 this._searchInputElement
.classList
.add("search-replace");
78 this._searchControlElement
.appendChild(this._searchInputElement
);
80 this._searchInputElement
.id
= "search-input-field";
81 this._searchInputElement
.placeholder
= WebInspector
.UIString("Find");
83 this._matchesElement
= this._searchControlElement
.createChild("label", "search-results-matches");
84 this._matchesElement
.setAttribute("for", "search-input-field");
86 this._searchNavigationElement
= this._searchControlElement
.createChild("div", "toolbar-search-navigation-controls");
88 this._searchNavigationPrevElement
= this._searchNavigationElement
.createChild("div", "toolbar-search-navigation toolbar-search-navigation-prev");
89 this._searchNavigationPrevElement
.addEventListener("click", this._onPrevButtonSearch
.bind(this), false);
90 this._searchNavigationPrevElement
.title
= WebInspector
.UIString("Search Previous");
92 this._searchNavigationNextElement
= this._searchNavigationElement
.createChild("div", "toolbar-search-navigation toolbar-search-navigation-next");
93 this._searchNavigationNextElement
.addEventListener("click", this._onNextButtonSearch
.bind(this), false);
94 this._searchNavigationNextElement
.title
= WebInspector
.UIString("Search Next");
96 this._searchInputElement
.addEventListener("mousedown", this._onSearchFieldManualFocus
.bind(this), false); // when the search field is manually selected
97 this._searchInputElement
.addEventListener("keydown", this._onSearchKeyDown
.bind(this), true);
98 this._searchInputElement
.addEventListener("input", this._onInput
.bind(this), false);
100 this._replaceInputElement
= this._secondRowElement
.createChild("td").createChild("input", "search-replace toolbar-replace-control");
101 this._replaceInputElement
.addEventListener("keydown", this._onReplaceKeyDown
.bind(this), true);
102 this._replaceInputElement
.placeholder
= WebInspector
.UIString("Replace");
105 this._findButtonElement
= this._firstRowElement
.createChild("td").createChild("button", "search-action-button hidden");
106 this._findButtonElement
.textContent
= WebInspector
.UIString("Find");
107 this._findButtonElement
.tabIndex
= -1;
108 this._findButtonElement
.addEventListener("click", this._onFindClick
.bind(this), false);
110 this._replaceButtonElement
= this._secondRowElement
.createChild("td").createChild("button", "search-action-button");
111 this._replaceButtonElement
.textContent
= WebInspector
.UIString("Replace");
112 this._replaceButtonElement
.disabled
= true;
113 this._replaceButtonElement
.tabIndex
= -1;
114 this._replaceButtonElement
.addEventListener("click", this._replace
.bind(this), false);
117 this._prevButtonElement
= this._firstRowElement
.createChild("td").createChild("button", "search-action-button hidden");
118 this._prevButtonElement
.textContent
= WebInspector
.UIString("Previous");
119 this._prevButtonElement
.tabIndex
= -1;
120 this._prevButtonElement
.addEventListener("click", this._onPreviousClick
.bind(this), false);
122 this._replaceAllButtonElement
= this._secondRowElement
.createChild("td").createChild("button", "search-action-button");
123 this._replaceAllButtonElement
.textContent
= WebInspector
.UIString("Replace All");
124 this._replaceAllButtonElement
.addEventListener("click", this._replaceAll
.bind(this), false);
127 this._replaceElement
= this._firstRowElement
.createChild("td").createChild("span");
129 this._replaceLabelElement
= createCheckboxLabel(WebInspector
.UIString("Replace"));
130 this._replaceCheckboxElement
= this._replaceLabelElement
.checkboxElement
;
131 this._uniqueId
= ++WebInspector
.SearchableView
._lastUniqueId
;
132 var replaceCheckboxId
= "search-replace-trigger" + this._uniqueId
;
133 this._replaceCheckboxElement
.id
= replaceCheckboxId
;
134 this._replaceCheckboxElement
.addEventListener("change", this._updateSecondRowVisibility
.bind(this), false);
136 this._replaceElement
.appendChild(this._replaceLabelElement
);
139 var cancelButtonElement
= this._firstRowElement
.createChild("td").createChild("button", "search-action-button");
140 cancelButtonElement
.textContent
= WebInspector
.UIString("Cancel");
141 cancelButtonElement
.tabIndex
= -1;
142 cancelButtonElement
.addEventListener("click", this.closeSearch
.bind(this), false);
143 this._minimalSearchQuerySize
= 3;
145 this._registerShortcuts();
149 WebInspector
.SearchableView
._lastUniqueId
= 0;
152 * @return {!Array.<!WebInspector.KeyboardShortcut.Descriptor>}
154 WebInspector
.SearchableView
.findShortcuts = function()
156 if (WebInspector
.SearchableView
._findShortcuts
)
157 return WebInspector
.SearchableView
._findShortcuts
;
158 WebInspector
.SearchableView
._findShortcuts
= [WebInspector
.KeyboardShortcut
.makeDescriptor("f", WebInspector
.KeyboardShortcut
.Modifiers
.CtrlOrMeta
)];
159 if (!WebInspector
.isMac())
160 WebInspector
.SearchableView
._findShortcuts
.push(WebInspector
.KeyboardShortcut
.makeDescriptor(WebInspector
.KeyboardShortcut
.Keys
.F3
));
161 return WebInspector
.SearchableView
._findShortcuts
;
165 * @return {!Array.<!WebInspector.KeyboardShortcut.Descriptor>}
167 WebInspector
.SearchableView
.cancelSearchShortcuts = function()
169 if (WebInspector
.SearchableView
._cancelSearchShortcuts
)
170 return WebInspector
.SearchableView
._cancelSearchShortcuts
;
171 WebInspector
.SearchableView
._cancelSearchShortcuts
= [WebInspector
.KeyboardShortcut
.makeDescriptor(WebInspector
.KeyboardShortcut
.Keys
.Esc
)];
172 return WebInspector
.SearchableView
._cancelSearchShortcuts
;
176 * @return {!Array.<!WebInspector.KeyboardShortcut.Descriptor>}
178 WebInspector
.SearchableView
.findNextShortcut = function()
180 if (WebInspector
.SearchableView
._findNextShortcut
)
181 return WebInspector
.SearchableView
._findNextShortcut
;
182 WebInspector
.SearchableView
._findNextShortcut
= [];
183 if (WebInspector
.isMac())
184 WebInspector
.SearchableView
._findNextShortcut
.push(WebInspector
.KeyboardShortcut
.makeDescriptor("g", WebInspector
.KeyboardShortcut
.Modifiers
.Meta
));
185 return WebInspector
.SearchableView
._findNextShortcut
;
189 * @return {!Array.<!WebInspector.KeyboardShortcut.Descriptor>}
191 WebInspector
.SearchableView
.findPreviousShortcuts = function()
193 if (WebInspector
.SearchableView
._findPreviousShortcuts
)
194 return WebInspector
.SearchableView
._findPreviousShortcuts
;
195 WebInspector
.SearchableView
._findPreviousShortcuts
= [];
196 if (WebInspector
.isMac())
197 WebInspector
.SearchableView
._findPreviousShortcuts
.push(WebInspector
.KeyboardShortcut
.makeDescriptor("g", WebInspector
.KeyboardShortcut
.Modifiers
.Meta
| WebInspector
.KeyboardShortcut
.Modifiers
.Shift
));
198 return WebInspector
.SearchableView
._findPreviousShortcuts
;
201 WebInspector
.SearchableView
.prototype = {
202 _toggleCaseSensitiveSearch: function()
204 this._caseSensitiveButton
.setToggled(!this._caseSensitiveButton
.toggled());
206 this._performSearch(false, true);
209 _toggleRegexSearch: function()
211 this._regexButton
.setToggled(!this._regexButton
.toggled());
213 this._performSearch(false, true);
216 _saveSetting: function()
220 var settingValue
= this._setting
.get() || {};
221 settingValue
.caseSensitive
= this._caseSensitiveButton
.toggled();
222 settingValue
.isRegex
= this._regexButton
.toggled();
223 this._setting
.set(settingValue
);
226 _loadSetting: function()
228 var settingValue
= this._setting
? (this._setting
.get() || {}) : {};
229 if (this._searchProvider
.supportsCaseSensitiveSearch())
230 this._caseSensitiveButton
.setToggled(!!settingValue
.caseSensitive
);
231 if (this._searchProvider
.supportsRegexSearch())
232 this._regexButton
.setToggled(!!settingValue
.isRegex
);
239 defaultFocusedElement: function()
241 var children
= this.children();
242 for (var i
= 0; i
< children
.length
; ++i
) {
243 var element
= children
[i
].defaultFocusedElement();
247 return WebInspector
.Widget
.prototype.defaultFocusedElement
.call(this);
251 * @param {!Event} event
253 _onKeyDown: function(event
)
255 var shortcutKey
= WebInspector
.KeyboardShortcut
.makeKeyFromEvent(/**@type {!KeyboardEvent}*/(event
));
256 var handler
= this._shortcuts
[shortcutKey
];
257 if (handler
&& handler(event
))
261 _registerShortcuts: function()
263 this._shortcuts
= {};
266 * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} shortcuts
267 * @param {function()} handler
268 * @this {WebInspector.SearchableView}
270 function register(shortcuts
, handler
)
272 for (var i
= 0; i
< shortcuts
.length
; ++i
)
273 this._shortcuts
[shortcuts
[i
].key
] = handler
;
276 register
.call(this, WebInspector
.SearchableView
.findShortcuts(), this.handleFindShortcut
.bind(this));
277 register
.call(this, WebInspector
.SearchableView
.cancelSearchShortcuts(), this.handleCancelSearchShortcut
.bind(this));
278 register
.call(this, WebInspector
.SearchableView
.findNextShortcut(), this.handleFindNextShortcut
.bind(this));
279 register
.call(this, WebInspector
.SearchableView
.findPreviousShortcuts(), this.handleFindPreviousShortcut
.bind(this));
283 * @param {number} minimalSearchQuerySize
285 setMinimalSearchQuerySize: function(minimalSearchQuerySize
)
287 this._minimalSearchQuerySize
= minimalSearchQuerySize
;
291 * @param {string} placeholder
293 setPlaceholder: function(placeholder
)
295 this._searchInputElement
.placeholder
= placeholder
;
299 * @param {boolean} replaceable
301 setReplaceable: function(replaceable
)
303 this._replaceable
= replaceable
;
307 * @param {number} matches
309 updateSearchMatchesCount: function(matches
)
311 this._searchProvider
.currentSearchMatches
= matches
;
312 this._updateSearchMatchesCountAndCurrentMatchIndex(this._searchProvider
.currentQuery
? matches
: 0, -1);
316 * @param {number} currentMatchIndex
318 updateCurrentMatchIndex: function(currentMatchIndex
)
320 this._updateSearchMatchesCountAndCurrentMatchIndex(this._searchProvider
.currentSearchMatches
, currentMatchIndex
);
326 isSearchVisible: function()
328 return this._searchIsVisible
;
331 closeSearch: function()
334 if (WebInspector
.currentFocusElement() && WebInspector
.currentFocusElement().isDescendant(this._footerElementContainer
))
338 _toggleSearchBar: function(toggled
)
340 this._footerElementContainer
.classList
.toggle("hidden", !toggled
);
344 cancelSearch: function()
346 if (!this._searchIsVisible
)
349 delete this._searchIsVisible
;
350 this._toggleSearchBar(false);
353 resetSearch: function()
356 this._updateReplaceVisibility();
357 this._matchesElement
.textContent
= "";
360 refreshSearch: function()
362 if (!this._searchIsVisible
)
365 this._performSearch(false, false);
371 handleFindNextShortcut: function()
373 if (!this._searchIsVisible
)
375 this._searchProvider
.jumpToNextSearchResult();
382 handleFindPreviousShortcut: function()
384 if (!this._searchIsVisible
)
386 this._searchProvider
.jumpToPreviousSearchResult();
393 handleFindShortcut: function()
395 this.showSearchField();
402 handleCancelSearchShortcut: function()
404 if (!this._searchIsVisible
)
411 * @param {boolean} enabled
413 _updateSearchNavigationButtonState: function(enabled
)
415 this._replaceButtonElement
.disabled
= !enabled
;
417 this._searchNavigationPrevElement
.classList
.add("enabled");
418 this._searchNavigationNextElement
.classList
.add("enabled");
420 this._searchNavigationPrevElement
.classList
.remove("enabled");
421 this._searchNavigationNextElement
.classList
.remove("enabled");
426 * @param {number} matches
427 * @param {number} currentMatchIndex
429 _updateSearchMatchesCountAndCurrentMatchIndex: function(matches
, currentMatchIndex
)
431 if (!this._currentQuery
)
432 this._matchesElement
.textContent
= "";
433 else if (matches
=== 0 || currentMatchIndex
>= 0)
434 this._matchesElement
.textContent
= WebInspector
.UIString("%d of %d", currentMatchIndex
+ 1, matches
);
435 else if (matches
=== 1)
436 this._matchesElement
.textContent
= WebInspector
.UIString("1 match");
438 this._matchesElement
.textContent
= WebInspector
.UIString("%d matches", matches
);
439 this._updateSearchNavigationButtonState(matches
> 0);
442 showSearchField: function()
444 if (this._searchIsVisible
)
448 if (WebInspector
.currentFocusElement() !== this._searchInputElement
) {
449 var selection
= this._searchInputElement
.getComponentSelection();
450 if (selection
.rangeCount
)
451 queryCandidate
= selection
.toString().replace(/\r?\n.*/, "");
454 this._toggleSearchBar(true);
455 this._updateReplaceVisibility();
457 this._searchInputElement
.value
= queryCandidate
;
458 this._performSearch(false, false);
459 this._searchInputElement
.focus();
460 this._searchInputElement
.select();
461 this._searchIsVisible
= true;
464 _updateReplaceVisibility: function()
466 this._replaceElement
.classList
.toggle("hidden", !this._replaceable
);
467 if (!this._replaceable
) {
468 this._replaceCheckboxElement
.checked
= false;
469 this._updateSecondRowVisibility();
474 * @param {!Event} event
476 _onSearchFieldManualFocus: function(event
)
478 WebInspector
.setCurrentFocusElement(/** @type {?Node} */ (event
.target
));
482 * @param {!Event} event
484 _onSearchKeyDown: function(event
)
486 if (!isEnterKey(event
))
489 if (!this._currentQuery
)
490 this._performSearch(true, true, event
.shiftKey
);
492 this._jumpToNextSearchResult(event
.shiftKey
);
496 * @param {!Event} event
498 _onReplaceKeyDown: function(event
)
500 if (isEnterKey(event
))
505 * @param {boolean=} isBackwardSearch
507 _jumpToNextSearchResult: function(isBackwardSearch
)
509 if (!this._currentQuery
|| !this._searchNavigationPrevElement
.classList
.contains("enabled"))
512 if (isBackwardSearch
)
513 this._searchProvider
.jumpToPreviousSearchResult();
515 this._searchProvider
.jumpToNextSearchResult();
518 _onNextButtonSearch: function(event
)
520 if (!this._searchNavigationNextElement
.classList
.contains("enabled"))
522 this._jumpToNextSearchResult();
523 this._searchInputElement
.focus();
526 _onPrevButtonSearch: function(event
)
528 if (!this._searchNavigationPrevElement
.classList
.contains("enabled"))
530 this._jumpToNextSearchResult(true);
531 this._searchInputElement
.focus();
534 _onFindClick: function(event
)
536 if (!this._currentQuery
)
537 this._performSearch(true, true);
539 this._jumpToNextSearchResult();
540 this._searchInputElement
.focus();
543 _onPreviousClick: function(event
)
545 if (!this._currentQuery
)
546 this._performSearch(true, true, true);
548 this._jumpToNextSearchResult(true);
549 this._searchInputElement
.focus();
552 _clearSearch: function()
554 delete this._currentQuery
;
555 if (!!this._searchProvider
.currentQuery
) {
556 delete this._searchProvider
.currentQuery
;
557 this._searchProvider
.searchCanceled();
559 this._updateSearchMatchesCountAndCurrentMatchIndex(0, -1);
563 * @param {boolean} forceSearch
564 * @param {boolean} shouldJump
565 * @param {boolean=} jumpBackwards
567 _performSearch: function(forceSearch
, shouldJump
, jumpBackwards
)
569 var query
= this._searchInputElement
.value
;
570 if (!query
|| (!forceSearch
&& query
.length
< this._minimalSearchQuerySize
&& !this._currentQuery
)) {
575 this._currentQuery
= query
;
576 this._searchProvider
.currentQuery
= query
;
578 var searchConfig
= this._currentSearchConfig();
579 this._searchProvider
.performSearch(searchConfig
, shouldJump
, jumpBackwards
);
583 * @return {!WebInspector.SearchableView.SearchConfig}
585 _currentSearchConfig: function()
587 var query
= this._searchInputElement
.value
;
588 var caseSensitive
= this._caseSensitiveButton
? this._caseSensitiveButton
.toggled() : false;
589 var isRegex
= this._regexButton
? this._regexButton
.toggled() : false;
590 return new WebInspector
.SearchableView
.SearchConfig(query
, caseSensitive
, isRegex
);
593 _updateSecondRowVisibility: function()
595 var secondRowVisible
= this._replaceCheckboxElement
.checked
;
596 this._footerElementContainer
.classList
.toggle("replaceable", secondRowVisible
);
597 this._footerElement
.classList
.toggle("toolbar-search-replace", secondRowVisible
);
598 this._secondRowElement
.classList
.toggle("hidden", !secondRowVisible
);
599 this._prevButtonElement
.classList
.toggle("hidden", !secondRowVisible
);
600 this._findButtonElement
.classList
.toggle("hidden", !secondRowVisible
);
601 this._replaceCheckboxElement
.tabIndex
= secondRowVisible
? -1 : 0;
603 if (secondRowVisible
)
604 this._replaceInputElement
.focus();
606 this._searchInputElement
.focus();
612 var searchConfig
= this._currentSearchConfig();
613 /** @type {!WebInspector.Replaceable} */ (this._searchProvider
).replaceSelectionWith(searchConfig
, this._replaceInputElement
.value
);
614 delete this._currentQuery
;
615 this._performSearch(true, true);
618 _replaceAll: function()
620 var searchConfig
= this._currentSearchConfig();
621 /** @type {!WebInspector.Replaceable} */ (this._searchProvider
).replaceAllWith(searchConfig
, this._replaceInputElement
.value
);
625 * @param {!Event} event
627 _onInput: function(event
)
629 if (this._valueChangedTimeoutId
)
630 clearTimeout(this._valueChangedTimeoutId
);
631 var timeout
= this._searchInputElement
.value
.length
< 3 ? 200 : 0;
632 this._valueChangedTimeoutId
= setTimeout(this._onValueChanged
.bind(this), timeout
);
635 _onValueChanged: function()
637 delete this._valueChangedTimeoutId
;
638 this._performSearch(false, true);
641 __proto__
: WebInspector
.VBox
.prototype
647 WebInspector
.Searchable = function()
651 WebInspector
.Searchable
.prototype = {
652 searchCanceled: function() { },
655 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig
656 * @param {boolean} shouldJump
657 * @param {boolean=} jumpBackwards
659 performSearch: function(searchConfig
, shouldJump
, jumpBackwards
) { },
661 jumpToNextSearchResult: function() { },
663 jumpToPreviousSearchResult: function() { },
668 supportsCaseSensitiveSearch: function() { },
673 supportsRegexSearch: function() { }
679 WebInspector
.Replaceable = function()
683 WebInspector
.Replaceable
.prototype = {
685 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig
686 * @param {string} replacement
688 replaceSelectionWith: function(searchConfig
, replacement
) { },
691 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig
692 * @param {string} replacement
694 replaceAllWith: function(searchConfig
, replacement
) { }
699 * @param {string} query
700 * @param {boolean} caseSensitive
701 * @param {boolean} isRegex
703 WebInspector
.SearchableView
.SearchConfig = function(query
, caseSensitive
, isRegex
)
706 this.caseSensitive
= caseSensitive
;
707 this.isRegex
= isRegex
;
710 WebInspector
.SearchableView
.SearchConfig
.prototype = {
712 * @param {boolean=} global
715 toSearchRegex: function(global
)
717 var modifiers
= this.caseSensitive
? "" : "i";
720 var query
= this.isRegex
? "/" + this.query
+ "/" : this.query
;
724 // First try creating regex if user knows the / / hint.
726 if (/^\/.+\/$/.test(query
)) {
727 regex
= new RegExp(query
.substring(1, query
.length
- 1), modifiers
);
728 regex
.__fromRegExpQuery
= true;
734 // Otherwise just do a plain text search.
736 regex
= createPlainTextSearchRegex(query
, modifiers
);