Chromium Code Reviews| Index: chrome/browser/resources/net_internals/source_filter_parser.js |
| =================================================================== |
| --- chrome/browser/resources/net_internals/source_filter_parser.js (revision 0) |
| +++ chrome/browser/resources/net_internals/source_filter_parser.js (revision 0) |
| @@ -0,0 +1,223 @@ |
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +var SourceFilterParser = (function() { |
| + 'use strict'; |
| + |
| + /** |
| + * Parses |filterText|, extracting a sort method, a list of filters, and a |
| + * copy of |filterText| with all sort parameters removed. |
| + */ |
| + function SourceFilterParser(filterText) { |
| + // Final output will be stored here. |
| + this.filter = null; |
| + this.sort = {}; |
| + this.filterTextWithoutSort = ''; |
| + var filterList = parseFilter_(filterText); |
| + |
| + // Text filters are stored here a strings, and then added as a function on |
|
eroman
2013/04/17 21:38:05
"here a strings" --> "here as strings"
mmenke
2013/04/17 22:34:55
Done. It's always the stuff I do last that has th
|
| + // the end, for performance reason. |
|
eroman
2013/04/17 21:38:05
"for performance reason" --> "for performance reas
mmenke
2013/04/17 22:34:55
Done.
|
| + var textFilters = []; |
| + |
| + // Filter functions are first created individually, and then merged. |
| + var filterFunctions = []; |
| + |
| + for (var i = 0; i < filterList.length; ++i) { |
| + var filterElement = filterList[i].parsed; |
| + var negated = filterList[i].negated; |
| + |
| + var sort = parseSortDirective_(filterElement, negated); |
| + if (sort) { |
| + this.sort = sort; |
| + continue; |
| + } |
| + |
| + this.textWithoutSort += filterList[i].original; |
| + |
| + var filter = parseRestrictDirective_(filterElement, negated); |
| + if (!filter) |
| + filter = parseStringDirective_(filterElement, negated); |
| + if (filter) { |
| + if (negated) { |
| + filter = (function(func, sourceEntry) { |
| + return !func(sourceEntry); |
| + }).bind(null, filter); |
| + } |
| + filterFunctions.push(filter); |
| + continue; |
| + } |
| + textFilters.push({ text: filterElement, negated: negated }); |
| + } |
| + |
| + // Create a single filter for all text filters, so they can share a |
| + // TabePrinter. |
| + filterFunctions.push(textFilter_.bind(null, textFilters)); |
| + |
| + // Create function to go through all the filters. |
| + this.filter = function(sourceEntry) { |
| + for (var i = 0; i < filterFunctions.length; ++i) { |
| + if (!filterFunctions[i](sourceEntry)) |
| + return false; |
| + } |
| + return true; |
| + }; |
| + } |
| + |
| + /** |
| + * Parses a single "sort:" directive, and returns a dictionary containing |
| + * the sort function and direction. Returns null on failure, including |
| + * the case when no such sort function exists. |
| + */ |
| + function parseSortDirective_(filterElement, backwards) { |
| + var match = /^sort:(.*)$/.exec(filterElement); |
| + if (!match) |
| + return null; |
| + return { method: match[1], backwards: backwards }; |
| + } |
| + |
| + /** |
| + * Tries to parses |filterElement| as a single "is:" directive, and returns a |
| + * new filter function. Returns null on failure. |
| + */ |
| + function parseRestrictDirective_(filterElement) { |
| + var match = /^is:(.*)$/.exec(filterElement); |
| + if (!match) |
| + return null; |
| + if (match[1] == 'active') { |
| + return function(sourceEntry) { return !sourceEntry.isInactive(); }; |
| + } |
| + if (match[1] == 'error') { |
| + return function(sourceEntry) { return sourceEntry.isError(); }; |
| + } |
| + return null; |
| + } |
| + |
| + /** |
| + * Tries to parse |filterElement| as a single filter of a type that takes |
| + * arbitrary strings as input, and returns a new filter function on success. |
| + * Returns null on failure. |
| + */ |
| + function parseStringDirective_(filterElement) { |
| + var match = RegExp('^([^:]*):(.*)$').exec(filterElement); |
| + if (!match) |
| + return null; |
| + |
| + // Split parameters around commas and remove empty elements. |
| + var parameters = match[2].split(','); |
| + parameters = parameters.filter(function(string) { |
| + return string.length > 0; |
| + }); |
| + |
| + if (match[1] == 'type') { |
| + return function(sourceEntry) { |
| + var i; |
| + var sourceType = sourceEntry.getSourceTypeString().toLowerCase(); |
| + for (i = 0; i < parameters.length; ++i) { |
| + if (sourceType.search(parameters[i]) != -1) |
| + return true; |
| + } |
| + return false; |
| + }; |
| + } |
| + |
| + if (match[1] == 'id') { |
| + return function(sourceEntry) { |
| + return parameters.indexOf(sourceEntry.getSourceId() + '') != -1; |
| + }; |
| + } |
| + |
| + return null; |
| + } |
| + |
| + /** |
| + * Takes in the text of a filter and returns a list of |
| + * {parsed, original, negated} values that correspond to substrings of the |
| + * filter before and after filtering, and whether or not it started with a |
| + * '-'. Extra whitespace other than a single character after each element is |
| + * ignored. Parsed strings are all lowercase. |
| + */ |
| + function parseFilter_(filterText) { |
| + // Assemble a list of quoted and unquoted strings in the filter. |
| + var filterList = []; |
| + var position = 0; |
| + while (position < filterText.length) { |
| + var inQuote = false; |
| + var filterElement = ''; |
| + var negated = false; |
| + var startPosition = position; |
| + while (position < filterText.length) { |
| + var nextCharacter = filterText[position]; |
| + ++position; |
| + if (nextCharacter == '\\' && |
| + position < filterText.length) { |
| + // If there's a backslash, skip the backslash and add the next |
| + // character to the element. |
| + filterElement += filterText[position]; |
| + ++position; |
| + continue; |
| + } else if (nextCharacter == '"') { |
| + // If there's an unescaped quote character, toggle |inQuote| without |
| + // modifying the element. |
| + inQuote = !inQuote; |
| + } else if (!inQuote && /\s/.test(nextCharacter)) { |
| + // If not in a quote and have a whitespace character, that's the |
| + // end of the element. |
| + break; |
| + } else if (nextCharacter == '-' && startPosition == position - 1) { |
| + // If this is the first character, and it's a '-', this entry is |
| + // negated. |
| + negated = true; |
| + } else { |
| + // Otherwise, add the next character to the element. |
| + filterElement += nextCharacter; |
| + } |
| + } |
| + |
| + if (filterElement.length > 0) { |
| + var filter = { |
| + parsed: filterElement.toLowerCase(), |
| + original: filterText.substring(startPosition, position), |
| + negated: negated, |
| + }; |
| + filterList.push(filter); |
| + } |
| + } |
| + return filterList; |
| + } |
| + |
| + /** |
| + * Takes in a list of text filters and a SourceEntry. Each filter has a |
| + * "text" and "negated" field. Returns true if the SourceEntry matches all |
| + * filters in the (possibly empty) list. |
| + */ |
| + function textFilter_(textFilters, sourceEntry) { |
| + var tablePrinter = null; |
| + for (var i = 0; i < textFilters.length; ++i) { |
| + var text = textFilters[i].text; |
| + var negated = textFilters[i].negated; |
| + var match = false; |
| + // The description is often not contained in one of the log entries. |
| + // The source type almost never is, so check for them directly. |
| + var description = sourceEntry.getDescription().toLowerCase(); |
| + var type = sourceEntry.getSourceTypeString().toLowerCase(); |
| + if (description.indexOf(text) != -1 || type.indexOf(text) != -1) { |
| + match = true; |
| + } else { |
| + if (!tablePrinter) { |
| + tablePrinter = createLogEntryTablePrinter( |
| + sourceEntry.getLogEntries(), |
| + SourceTracker.getInstance().getPrivacyStripping()); |
| + } |
| + match = tablePrinter.search(text); |
| + } |
| + if (negated) |
| + match = !match; |
| + if (!match) |
| + return false; |
| + } |
| + return true; |
| + } |
| + |
| + return SourceFilterParser; |
| +})(); |
| Property changes on: chrome\browser\resources\net_internals\source_filter_parser.js |
| ___________________________________________________________________ |
| Added: svn:mime-type |
| + text/javascript |