OLD | NEW |
---|---|
1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 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 """Process Chrome resources (HTML/CSS/JS) to handle <include> and <if> tags.""" | 5 """Process Chrome resources (HTML/CSS/JS) to handle <include> and <if> tags.""" |
6 | 6 |
7 from collections import defaultdict | 7 from collections import defaultdict |
8 import re | 8 import re |
9 import os | 9 import os |
10 | 10 |
11 | 11 |
12 class LineNumber(object): | 12 class LineNumber(object): |
13 """A simple wrapper to hold line information (e.g. file.js:32). | 13 """A simple wrapper to hold line information (e.g. file.js:32). |
14 | 14 |
15 Args: | 15 Args: |
16 source_file: A file path. | 16 source_file: A file path. |
17 line_number: The line in |file|. | 17 line_number: The line in |file|. |
18 """ | 18 """ |
19 def __init__(self, source_file, line_number): | 19 def __init__(self, source_file, line_number): |
20 self.file = source_file | 20 self.file = source_file |
21 self.line_number = int(line_number) | 21 self.line_number = int(line_number) |
22 | 22 |
23 | 23 |
24 class FileCache(object): | 24 class FileCache(object): |
rothwell
2014/12/18 22:30:48
It doesn't look like this needs to be a class, it
Dan Beam
2015/02/25 03:36:49
what would I do with _cache? make it a global? I
| |
25 """An in-memory cache to speed up reading the same files over and over. | 25 """An in-memory cache to speed up reading the same files over and over. |
26 | 26 |
27 Usage: | 27 Usage: |
28 FileCache.read(path_to_file) | 28 FileCache.read(path_to_file) |
29 """ | 29 """ |
30 | 30 |
31 _cache = defaultdict(str) | 31 _cache = defaultdict(str) |
32 | 32 |
33 @classmethod | 33 @classmethod |
34 def read(self, source_file): | 34 def read(self, source_file): |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
68 source_file: A file to process. | 68 source_file: A file to process. |
69 | 69 |
70 Attributes: | 70 Attributes: |
71 contents: Expanded contents after inlining <include>s and stripping <if>s. | 71 contents: Expanded contents after inlining <include>s and stripping <if>s. |
72 included_files: A list of files that were inlined via <include>. | 72 included_files: A list of files that were inlined via <include>. |
73 """ | 73 """ |
74 | 74 |
75 _IF_TAGS_REG = "</?if[^>]*?>" | 75 _IF_TAGS_REG = "</?if[^>]*?>" |
76 _INCLUDE_REG = "<include[^>]+src=['\"]([^>]*)['\"]>" | 76 _INCLUDE_REG = "<include[^>]+src=['\"]([^>]*)['\"]>" |
77 | 77 |
78 def __init__(self, source_file): | 78 def __init__(self, source_file): |
rothwell
2014/12/18 22:30:48
docstring - e.g. what is a source_file, a filename
Dan Beam
2015/02/25 03:36:49
Done.
| |
79 self._included_files = set() | 79 self._included_files = set() |
80 self._index = 0 | 80 self._index = 0 |
81 self._lines = self._get_file(source_file) | 81 self._lines = self._get_file(source_file) |
82 | 82 |
83 while self._index < len(self._lines): | 83 while self._index < len(self._lines): |
rothwell
2014/12/18 22:30:48
I think you want to be using enumerate here, or do
| |
84 current_line = self._lines[self._index] | 84 current_line = self._lines[self._index] |
85 match = re.search(self._INCLUDE_REG, current_line[2]) | 85 match = re.search(self._INCLUDE_REG, current_line[2]) |
86 if match: | 86 if match: |
87 file_dir = os.path.dirname(current_line[0]) | 87 file_dir = os.path.dirname(current_line[0]) |
88 file_name = os.path.abspath(os.path.join(file_dir, match.group(1))) | 88 file_name = os.path.abspath(os.path.join(file_dir, match.group(1))) |
89 if file_name not in self._included_files: | 89 if file_name not in self._included_files: |
90 self._include_file(file_name) | 90 self._include_file(file_name) |
91 continue # Stay on the same line. | 91 continue # Stay on the same line. |
Dan Beam
2015/02/25 03:36:49
^ this is why I can't use enumerate(), because a l
| |
92 else: | 92 else: |
93 # Found a duplicate <include>. Ignore and insert a blank line to | 93 # Found a duplicate <include>. Ignore and insert a blank line to |
94 # preserve line numbers. | 94 # preserve line numbers. |
95 self._lines[self._index] = self._lines[self._index][:2] + ("",) | 95 self._lines[self._index] = self._lines[self._index][:2] + ("",) |
96 self._index += 1 | 96 self._index += 1 |
97 | 97 |
98 for i, line in enumerate(self._lines): | 98 for i, line in enumerate(self._lines): |
99 self._lines[i] = line[:2] + (re.sub(self._IF_TAGS_REG, "", line[2]),) | 99 self._lines[i] = line[:2] + (re.sub(self._IF_TAGS_REG, "", line[2]),) |
100 | 100 |
101 self.contents = "\n".join(l[2] for l in self._lines) | 101 self.contents = "\n".join(l[2] for l in self._lines) |
(...skipping 11 matching lines...) Expand all Loading... | |
113 def get_file_from_line(self, line_number): | 113 def get_file_from_line(self, line_number): |
114 """Get the original file and line number for an expanded file's line number. | 114 """Get the original file and line number for an expanded file's line number. |
115 | 115 |
116 Args: | 116 Args: |
117 line_number: A processed file's line number. | 117 line_number: A processed file's line number. |
118 """ | 118 """ |
119 line_number = int(line_number) - 1 | 119 line_number = int(line_number) - 1 |
120 return LineNumber(self._lines[line_number][0], self._lines[line_number][1]) | 120 return LineNumber(self._lines[line_number][0], self._lines[line_number][1]) |
121 | 121 |
122 @property | 122 @property |
123 def included_files(self): | 123 def included_files(self): |
rothwell
2014/12/18 22:30:48
if you're trying to obscure access to the underlyi
Dan Beam
2015/02/25 03:36:49
Done. (pydoc doesn't show these properties for me
| |
124 """A list of files that were inlined via <include>.""" | 124 """A list of files that were inlined via <include>.""" |
125 return self._included_files | 125 return self._included_files |
OLD | NEW |