Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(181)

Side by Side Diff: chrome/browser/resources/net_internals/events_view.js

Issue 13725016: about:net-internals: Add support for negative text filters (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Fix Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * EventsView displays a filtered list of all events sharing a source, and 6 * EventsView displays a filtered list of all events sharing a source, and
7 * a details pane for the selected sources. 7 * a details pane for the selected sources.
8 * 8 *
9 * +----------------------++----------------+ 9 * +----------------------++----------------+
10 * | filter box || | 10 * | filter box || |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 var nextSourceRow = this.sourceIdToRowMap_[nextSourceId]; 171 var nextSourceRow = this.sourceIdToRowMap_[nextSourceId];
172 sourceRow.moveBefore(nextSourceRow); 172 sourceRow.moveBefore(nextSourceRow);
173 } 173 }
174 } 174 }
175 }, 175 },
176 176
177 setFilter_: function(filterText) { 177 setFilter_: function(filterText) {
178 var lastComparisonFunction = this.comparisonFunction_; 178 var lastComparisonFunction = this.comparisonFunction_;
179 var lastDoSortBackwards = this.doSortBackwards_; 179 var lastDoSortBackwards = this.doSortBackwards_;
180 180
181 this.pickSortFunction_(filterText); 181 var filterParser = new SourceFilterParser(filterText);
182 this.currentFilter_ = filterParser.filter;
183
184 this.pickSortFunction_(filterParser.sort);
182 185
183 if (lastComparisonFunction != this.comparisonFunction_ || 186 if (lastComparisonFunction != this.comparisonFunction_ ||
184 lastDoSortBackwards != this.doSortBackwards_) { 187 lastDoSortBackwards != this.doSortBackwards_) {
185 this.sort_(); 188 this.sort_();
186 } 189 }
187 190
188 var oldFilter = this.currentFilter_;
189 this.currentFilter_ = createFilter_(filterText);
190
191 // No need to filter again if filters match.
192 if (oldFilter &&
193 JSON.stringify(oldFilter) == JSON.stringify(this.currentFilter_)) {
194 return;
195 }
196
197 // Iterate through all of the rows and see if they match the filter. 191 // Iterate through all of the rows and see if they match the filter.
198 for (var id in this.sourceIdToRowMap_) { 192 for (var id in this.sourceIdToRowMap_) {
199 var entry = this.sourceIdToRowMap_[id]; 193 var entry = this.sourceIdToRowMap_[id];
200 entry.setIsMatchedByFilter(entry.matchesFilter(this.currentFilter_)); 194 entry.setIsMatchedByFilter(this.currentFilter_(entry.getSourceEntry()));
201 } 195 }
202 }, 196 },
203 197
204 /** 198 /**
205 * Parse any "sort:" directives, and update |comparisonFunction_| and 199 * Given a "sort" object with "method" and "backwards" keys, looks up and
206 * |doSortBackwards_| as needed. Note only the last valid sort directive 200 * sets |comparisonFunction_| and |doSortBackwards_|. If the ID does not
207 * is used. 201 * correspond to a sort function, defaults to sorting by ID.
208 */ 202 */
209 pickSortFunction_: function(filterText) { 203 pickSortFunction_: function(sort) {
210 this.comparisonFunction_ = compareSourceId_; 204 this.doSortBackwards_ = sort.backwards;
211 this.doSortBackwards_ = false; 205 this.comparisonFunction_ = COMPARISON_FUNCTION_TABLE[sort.method];
212 206 if (!this.comparisonFunction_) {
213 var filterList = parseFilter_(filterText); 207 this.doSortBackwards_ = false;
214 for (var i = 0; i < filterList.length; ++i) { 208 this.comparisonFunction_ = compareSourceId_;
215 var sort = parseSortDirective_(filterList[i].parsed);
216 if (sort != null) {
217 this.comparisonFunction_ = sort.comparisonFunction;
218 this.doSortBackwards_ = sort.backwards;
219 }
220 } 209 }
221 }, 210 },
222 211
223 /** 212 /**
224 * Repositions |sourceRow|'s in the table using an insertion sort. 213 * Repositions |sourceRow|'s in the table using an insertion sort.
225 * Significantly faster than sorting the entire table again, when only 214 * Significantly faster than sorting the entire table again, when only
226 * one entry has changed. 215 * one entry has changed.
227 */ 216 */
228 insertionSort_: function(sourceRow) { 217 insertionSort_: function(sourceRow) {
229 // SourceRow that should be after |sourceRow|, if it needs 218 // SourceRow that should be after |sourceRow|, if it needs
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 scrollToSourceId: function(sourceId) { 387 scrollToSourceId: function(sourceId) {
399 this.detailsView_.scrollToSourceId(sourceId); 388 this.detailsView_.scrollToSourceId(sourceId);
400 }, 389 },
401 390
402 /** 391 /**
403 * If already using the specified sort method, flips direction. Otherwise, 392 * If already using the specified sort method, flips direction. Otherwise,
404 * removes pre-existing sort parameter before adding the new one. 393 * removes pre-existing sort parameter before adding the new one.
405 */ 394 */
406 toggleSortMethod_: function(sortMethod) { 395 toggleSortMethod_: function(sortMethod) {
407 // Get old filter text and remove old sort directives, if any. 396 // Get old filter text and remove old sort directives, if any.
408 var filterList = parseFilter_(this.getFilterText_()); 397 var filterParser = new SourceFilterParser(this.getFilterText_());
409 var filterText = ''; 398 var filterText = filterParser.filterTextWithoutSort;
410 for (var i = 0; i < filterList.length; ++i) { 399
411 if (parseSortDirective_(filterList[i].parsed) == null) 400 filterText = 'sort:' + sortMethod + ' ' + filterText;
412 filterText += filterList[i].original;
413 }
414 401
415 // If already using specified sortMethod, sort backwards. 402 // If already using specified sortMethod, sort backwards.
416 if (!this.doSortBackwards_ && 403 if (!this.doSortBackwards_ &&
417 COMPARISON_FUNCTION_TABLE[sortMethod] == this.comparisonFunction_) { 404 COMPARISON_FUNCTION_TABLE[sortMethod] == this.comparisonFunction_) {
418 sortMethod = '-' + sortMethod; 405 filterText = '-' + filterText;
419 } 406 }
420 407
421 filterText = 'sort:' + sortMethod + ' ' + filterText;
422 this.setFilterText_(filterText.trim()); 408 this.setFilterText_(filterText.trim());
423 }, 409 },
424 410
425 sortById_: function(event) { 411 sortById_: function(event) {
426 this.toggleSortMethod_('id'); 412 this.toggleSortMethod_('id');
427 }, 413 },
428 414
429 sortBySourceType_: function(event) { 415 sortBySourceType_: function(event) {
430 this.toggleSortMethod_('source'); 416 this.toggleSortMethod_('source');
431 }, 417 },
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 559
574 function compareSourceType_(source1, source2) { 560 function compareSourceType_(source1, source2) {
575 var source1Text = source1.getSourceTypeString(); 561 var source1Text = source1.getSourceTypeString();
576 var source2Text = source2.getSourceTypeString(); 562 var source2Text = source2.getSourceTypeString();
577 var compareResult = source1Text.localeCompare(source2Text); 563 var compareResult = source1Text.localeCompare(source2Text);
578 if (compareResult != 0) 564 if (compareResult != 0)
579 return compareResult; 565 return compareResult;
580 return compareSourceId_(source1, source2); 566 return compareSourceId_(source1, source2);
581 } 567 }
582 568
583 /**
584 * Parses a single "sort:" directive, and returns a dictionary containing
585 * the sort function and direction. Returns null on failure, including
586 * the case when no such sort function exists.
587 */
588
589 function parseSortDirective_(filterElement) {
590 var match = /^sort:(-?)(.*)$/.exec(filterElement);
591 if (!match || !COMPARISON_FUNCTION_TABLE[match[2]])
592 return null;
593 return {
594 comparisonFunction: COMPARISON_FUNCTION_TABLE[match[2]],
595 backwards: (match[1] == '-'),
596 };
597 }
598
599 /**
600 * Parses an "is:" directive, and updates |filter| accordingly.
601 *
602 * Returns true on success, and false if |filterElement| is not an "is:"
603 * directive.
604 */
605 function parseRestrictDirective_(filterElement, filter) {
606 var match = /^is:(-?)(.*)$/.exec(filterElement);
607 if (!match)
608 return false;
609 if (match[2] == 'active') {
610 if (match[1] == '-') {
611 filter.isInactive = true;
612 } else {
613 filter.isActive = true;
614 }
615 return true;
616 }
617 if (match[2] == 'error') {
618 if (match[1] == '-') {
619 filter.isNotError = true;
620 } else {
621 filter.isError = true;
622 }
623 return true;
624 }
625 return false;
626 }
627
628 /**
629 * Parses all directives that take arbitrary strings as input,
630 * and updates |filter| accordingly. Directives of these types
631 * are stored as lists.
632 *
633 * Returns true on success, and false if |filterElement| is not a
634 * recognized directive.
635 */
636 function parseStringDirective_(filterElement, filter) {
637 var directives = ['type', 'id'];
638 for (var i = 0; i < directives.length; ++i) {
639 var directive = directives[i];
640 var match = RegExp('^' + directive + ':(.*)$').exec(filterElement);
641 if (!match)
642 continue;
643
644 // Split parameters around commas and remove empty elements.
645 var parameters = match[1].split(',');
646 parameters = parameters.filter(function(string) {
647 return string.length > 0;
648 });
649
650 // If there's already a matching filter, take the intersection.
651 // This behavior primarily exists for tests. It is not correct
652 // when one of the 'type' filters is a partial match.
653 if (filter[directive]) {
654 parameters = parameters.filter(function(string) {
655 return filter[directive].indexOf(string) != -1;
656 });
657 }
658
659 filter[directive] = parameters;
660 return true;
661 }
662 return false;
663 }
664
665 /**
666 * Takes in the text of a filter and returns a list of {parsed, original}
667 * pairs that correspond to substrings of the filter before and after
668 * filtering. This function is used both to parse filters and to remove
669 * the sort rule from a filter. Extra whitespace other than a single
670 * character after each element is ignored. Parsed strings are all
671 * lowercase.
672 */
673 function parseFilter_(filterText) {
674 filterText = filterText.toLowerCase();
675
676 // Assemble a list of quoted and unquoted strings in the filter.
677 var filterList = [];
678 var position = 0;
679 while (position < filterText.length) {
680 var inQuote = false;
681 var filterElement = '';
682 var startPosition = position;
683 while (position < filterText.length) {
684 var nextCharacter = filterText[position];
685 ++position;
686 if (nextCharacter == '\\' &&
687 position < filterText.length) {
688 // If there's a backslash, skip the backslash and add the next
689 // character to the element.
690 filterElement += filterText[position];
691 ++position;
692 continue;
693 } else if (nextCharacter == '"') {
694 // If there's an unescaped quote character, toggle |inQuote| without
695 // modifying the element.
696 inQuote = !inQuote;
697 } else if (!inQuote && /\s/.test(nextCharacter)) {
698 // If not in a quote and have a whitespace character, that's the
699 // end of the element.
700 break;
701 } else {
702 // Otherwise, add the next character to the element.
703 filterElement += nextCharacter;
704 }
705 }
706
707 if (filterElement.length > 0) {
708 var filter = {
709 parsed: filterElement,
710 original: filterText.substring(startPosition, position),
711 };
712 filterList.push(filter);
713 }
714 }
715 return filterList;
716 }
717
718 /**
719 * Converts |filterText| into an object representing the filter.
720 */
721 function createFilter_(filterText) {
722 var filter = {};
723 var filterList = parseFilter_(filterText);
724
725 for (var i = 0; i < filterList.length; ++i) {
726 if (parseSortDirective_(filterList[i].parsed) ||
727 parseRestrictDirective_(filterList[i].parsed, filter) ||
728 parseStringDirective_(filterList[i].parsed, filter)) {
729 continue;
730 }
731 if (filter.textFilters == undefined)
732 filter.textFilters = [];
733 filter.textFilters.push(filterList[i].parsed);
734 }
735 return filter;
736 }
737
738 return EventsView; 569 return EventsView;
739 })(); 570 })();
OLDNEW
« no previous file with comments | « chrome/browser/resources/net_internals/events_view.html ('k') | chrome/browser/resources/net_internals/index.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698