1a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// found in the LICENSE file.
4a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
5a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch/**
6a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * @constructor
7a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * @implements {WebInspector.ProjectSearchConfig}
8a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * @param {string} query
9a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * @param {boolean} ignoreCase
10a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * @param {boolean} isRegex
11a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch */
12a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben MurdochWebInspector.SearchConfig = function(query, ignoreCase, isRegex)
13a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch{
14a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    this._query = query;
15a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    this._ignoreCase = ignoreCase;
16a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    this._isRegex = isRegex;
17a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    this._parse();
18a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch}
19a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
20f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu/** @typedef {!{regex: !RegExp, isNegative: boolean}} */
21f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo LiuWebInspector.SearchConfig.RegexQuery;
22f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
23a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch/**
24a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * @param {{query: string, ignoreCase: boolean, isRegex: boolean}} object
255d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) * @return {!WebInspector.SearchConfig}
26a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch */
27a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben MurdochWebInspector.SearchConfig.fromPlainObject = function(object)
28a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch{
29a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    return new WebInspector.SearchConfig(object.query, object.ignoreCase, object.isRegex);
30a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch}
31a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
32a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben MurdochWebInspector.SearchConfig.prototype = {
33a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    /**
34a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch     * @return {string}
35a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch     */
36a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    query: function()
37a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
38a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return this._query;
39a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    },
40a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
41a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    /**
42a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch     * @return {boolean}
43a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch     */
44a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    ignoreCase: function()
45a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
46a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return this._ignoreCase;
47a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    },
48a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
49a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    /**
50a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch     * @return {boolean}
51a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch     */
52a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    isRegex: function()
53a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
54a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return this._isRegex;
55a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    },
56a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
57a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    /**
58a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch     * @return {{query: string, ignoreCase: boolean, isRegex: boolean}}
59a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch     */
60a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    toPlainObject: function()
61a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
62a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return { query: this.query(), ignoreCase: this.ignoreCase(), isRegex: this.isRegex() };
63a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    },
64a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
65a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    _parse: function()
66a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
67f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        var filePattern = "(?:-)?file:(([^\\\\ ]|\\\\.)+)"; // After file: prefix: any symbol except space and backslash or any symbol escaped with a backslash.
68a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        var quotedPattern = "\"(([^\\\\\"]|\\\\.)+)\""; // Inside double quotes: any symbol except double quote and backslash or any symbol escaped with a backslash.
69a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        var unquotedPattern = "(([^\\\\ ]|\\\\.)+)"; // any symbol except space and backslash or any symbol escaped with a backslash.
70a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
71a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        var pattern = "(" + filePattern + ")|(" + quotedPattern + ")|(" + unquotedPattern + ")";
72a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        var regexp = new RegExp(pattern, "g");
73a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        var queryParts = this._query.match(regexp) || [];
74a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
75a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        /**
76f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu         * @type {!Array.<!WebInspector.SearchConfig.QueryTerm>}
77a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch         */
78a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        this._fileQueries = [];
79a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
80a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        /**
81a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch         * @type {!Array.<string>}
82a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch         */
83a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        this._queries = [];
84a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
85a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        for (var i = 0; i < queryParts.length; ++i) {
86a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            var queryPart = queryParts[i];
87a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            if (!queryPart)
88a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                continue;
89f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            var fileQuery = this._parseFileQuery(queryPart);
90f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            if (fileQuery) {
91f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu                this._fileQueries.push(fileQuery);
92f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu                /** @type {!Array.<!WebInspector.SearchConfig.RegexQuery>} */
93f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu                this._fileRegexQueries = this._fileRegexQueries || [];
94f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu                this._fileRegexQueries.push({ regex: new RegExp(fileQuery.text, this.ignoreCase ? "i" : ""), isNegative: fileQuery.isNegative });
95a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                continue;
96a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            }
97a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            if (queryPart.startsWith("\"")) {
98a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                if (!queryPart.endsWith("\""))
99a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                    continue;
100a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                this._queries.push(this._parseQuotedQuery(queryPart));
101a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                continue;
102a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            }
103a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            this._queries.push(this._parseUnquotedQuery(queryPart));
104a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        }
105a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    },
106a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
107a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    /**
108a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch     * @param {string} filePath
109a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch     * @return {boolean}
110a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch     */
111a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    filePathMatchesFileQuery: function(filePath)
112a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
113f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        if (!this._fileRegexQueries)
114f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            return true;
115f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        for (var i = 0; i < this._fileRegexQueries.length; ++i) {
116f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            if (!!filePath.match(this._fileRegexQueries[i].regex) === this._fileRegexQueries[i].isNegative)
117a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                return false;
118a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        }
119a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return true;
120a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    },
121a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
122a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    /**
123a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch     * @return {!Array.<string>}
124a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch     */
125a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    queries: function()
126a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
127a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return this._queries;
128a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    },
129a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
130a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    _parseUnquotedQuery: function(query)
131a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
132a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return query.replace(/\\(.)/g, "$1");
133a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    },
134a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
135a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    _parseQuotedQuery: function(query)
136a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
137a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return query.substring(1, query.length - 1).replace(/\\(.)/g, "$1");
138a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    },
139a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
140f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    /**
141f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu     * @param {string} query
142f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu     * @return {?WebInspector.SearchConfig.QueryTerm}
143f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu     */
144a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    _parseFileQuery: function(query)
145a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
146f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        var match = query.match(/^(-)?file:/);
147f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        if (!match)
148f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            return null;
149f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        var isNegative = !!match[1];
150f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        query = query.substr(match[0].length);
151a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        var result = "";
152a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        for (var i = 0; i < query.length; ++i) {
153a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            var char = query[i];
154a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            if (char === "*") {
155a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                result += ".*";
156a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            } else if (char === "\\") {
157a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                ++i;
158a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                var nextChar = query[i];
159a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                if (nextChar === " ")
160a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                    result += " ";
161a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            } else {
162a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                if (String.regexSpecialCharacters().indexOf(query.charAt(i)) !== -1)
163a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                    result += "\\";
164a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                result += query.charAt(i);
165a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            }
166a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        }
167f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        return new WebInspector.SearchConfig.QueryTerm(result, isNegative);
168a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
169a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch}
170f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
171f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu/**
172f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu * @constructor
173f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu * @param {string} text
174f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu * @param {boolean} isNegative
175f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu */
176f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo LiuWebInspector.SearchConfig.QueryTerm = function(text, isNegative)
177f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{
178f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    this.text = text;
179f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    this.isNegative = isNegative;
180f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu}
181