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

Side by Side Diff: extensions/browser/manifest_highlighter.cc

Issue 22938005: Add ErrorConsole UI for Extension Install Warnings (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@dc_ec_install_warnings
Patch Set: More robust highlighting + testing Created 7 years, 4 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
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <stack>
6
7 #include "extensions/browser/manifest_highlighter.h"
8
9 namespace extensions {
10
11 ManifestHighlighter::ManifestHighlighter(const std::string& manifest,
12 const std::string& key,
13 const std::string& specific)
14 : manifest_(manifest),
15 start_(manifest_.find('{') + 1),
16 end_(manifest_.rfind('}')) {
17 Parse(key, specific);
18 }
19
20 ManifestHighlighter::~ManifestHighlighter() {
21 }
22
23 std::string ManifestHighlighter::GetBeforeFeature() const {
24 return manifest_.substr(0, start_);
25 }
26
27 std::string ManifestHighlighter::GetFeature() const {
28 return manifest_.substr(start_, end_ - start_);
29 }
30
31 std::string ManifestHighlighter::GetAfterFeature() const {
32 return manifest_.substr(end_);
33 }
34
35 void ManifestHighlighter::Parse(const std::string& key,
36 const std::string& specific) {
37 // First, try to find the bounds of the full key.
38 if (FindBounds(key, true) /* enforce at top level */ ) {
39 // If we succeed, and we have a specific location, find the bounds of the
40 // specific.
41 if (!specific.empty())
42 FindBounds(specific, false /* don't enforce at top level */ );
43
44 // We may have found trailing whitespace. Don't use base::TrimWhitespace,
45 // because we want to keep any whitespace we find - just not highlight it.
46 size_t trim = manifest_.find_last_not_of(" \t\n\r", end_ - 1);
47 if (trim < end_ && trim > start_)
48 end_ = trim + 1;
49 } else {
50 // If we fail, then we set start to end so that the highlighted portion is
51 // empty.
52 start_ = end_;
53 }
54 }
55
56 bool ManifestHighlighter::FindBounds(const std::string& feature,
57 bool enforce_at_top_level) {
58 char c = '\0';
59 while (start_ < end_) {
60 c = manifest_[start_];
61 if (c == '"') {
62 // The feature may be quoted.
63 size_t quote_end = manifest_.find('"', start_ + 1);
64 if (manifest_.substr(start_ + 1, quote_end - 1 - start_) == feature) {
65 FindBoundsHelper(feature, quote_end + 1);
66 return true;
67 } else {
68 // If it's not the feature, then we can skip the quoted section.
69 start_ = quote_end + 1;
70 }
71 } else if (manifest_.substr(start_, feature.size()) == feature) {
72 FindBoundsHelper(feature, start_ + feature.size() + 1);
73 return true;
74 } else if (enforce_at_top_level && (c == '{' || c == '[')) {
75 // If we don't have to be at the top level, then we can skip any chunks
76 // we find.
77 ChunkIncrement(&start_);
78 } else {
79 CommentSafeIncrement(&start_);
80 }
81 }
82 return false;
83 }
84
85 void ManifestHighlighter::FindBoundsHelper(const std::string& feature,
Yoyo Zhou 2013/08/19 20:39:46 You could also call this FindBoundsEnd
Devlin 2013/08/19 21:42:39 Done.
86 size_t local_start) {
87 char c = '\0';
88 while (local_start < end_) {
89 c = manifest_[local_start];
90 // We're done when we find a terminating character (i.e., either a comma or
91 // an ending bracket.
92 if (c == ',' || c == '}' || c == ']') {
93 end_ = local_start;
94 return;
95 }
96 // We can skip any chunks we find, since we are looking for the end of the
97 // current feature, and don't want to go any deeper.
98 if (c == '"' || c == '{' || c == '[')
99 ChunkIncrement(&local_start);
100 else
101 CommentSafeIncrement(&local_start);
102 }
103 }
104
105 void ManifestHighlighter::ChunkIncrement(size_t* index) {
106 char c = manifest_[*index];
107 std::stack<char> stack;
108 do {
109 if (c == '"')
Yoyo Zhou 2013/08/19 20:39:46 This is unfortunate, but we can also have \" insid
Devlin 2013/08/19 21:42:39 Escaped chars now handled. Commented "s aren't re
110 *index = manifest_.find('"', *index + 1);
111 else if (c == '[')
112 stack.push(']');
113 else if (c == '{')
114 stack.push('}');
115 else if (!stack.empty() && c == stack.top())
116 stack.pop();
117 CommentSafeIncrement(index);
118 c = manifest_[*index];
119 } while (!stack.empty() && *index < end_);
120 }
121
122 void ManifestHighlighter::CommentSafeIncrement(size_t* index) {
123 size_t i = *index;
124 if (manifest_[i] == '/' && i + 1 < manifest_.size()) {
125 // Eat a single-line comment.
126 if (manifest_[i + 1] == '/') {
127 i += 2; // Eat the '//'.
128 while (i < manifest_.size() &&
129 manifest_[i] != '\n' && manifest_[i] != '\r') {
130 ++i;
131 }
132 } else if (manifest_[i + 1] == '*') { // Eat a multi-line comment.
133 i += 3; // Advance to the first possible comment end.
134 while (i < manifest_.size() &&
135 !(manifest_[i - 1] == '*' && manifest_[i] == '/')) {
136 ++i;
137 }
138 }
139 }
140 *index = i + 1;
141 }
142
143 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/manifest_highlighter.h ('k') | extensions/browser/manifest_highlighter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698