| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 | 2 |
| 3 # Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. | 3 # Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. |
| 4 # | 4 # |
| 5 # Redistribution and use in source and binary forms, with or without | 5 # Redistribution and use in source and binary forms, with or without |
| 6 # modification, are permitted provided that the following conditions | 6 # modification, are permitted provided that the following conditions |
| 7 # are met: | 7 # are met: |
| 8 # | 8 # |
| 9 # 1. Redistributions of source code must retain the above | 9 # 1. Redistributions of source code must retain the above |
| 10 # copyright notice, this list of conditions and the following | 10 # copyright notice, this list of conditions and the following |
| 11 # disclaimer. | 11 # disclaimer. |
| 12 # 2. Redistributions in binary form must reproduce the above | 12 # 2. Redistributions in binary form must reproduce the above |
| 13 # copyright notice, this list of conditions and the following | 13 # copyright notice, this list of conditions and the following |
| 14 # disclaimer in the documentation and/or other materials | 14 # disclaimer in the documentation and/or other materials |
| 15 # provided with the distribution. | 15 # provided with the distribution. |
| 16 # | 16 # |
| 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY | 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY |
| 18 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 18 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 19 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 19 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 20 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE | 20 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE |
| 21 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, | 21 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, |
| 22 # OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 22 # OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 23 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 23 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 24 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 24 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR | 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR |
| 26 # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | 26 # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF |
| 27 # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 27 # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 28 # SUCH DAMAGE. | 28 # SUCH DAMAGE. |
| 29 | 29 |
| 30 import itertools |
| 30 import logging | 31 import logging |
| 31 import re | 32 import re |
| 32 | 33 |
| 33 from webkitpy.common.host import Host | 34 from webkitpy.common.host import Host |
| 34 from webkitpy.common.webkit_finder import WebKitFinder | 35 from webkitpy.common.webkit_finder import WebKitFinder |
| 35 from HTMLParser import HTMLParser | 36 from HTMLParser import HTMLParser |
| 36 | 37 |
| 37 | 38 |
| 38 _log = logging.getLogger(__name__) | 39 _log = logging.getLogger(__name__) |
| 39 | 40 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 67 self.filename = filename | 68 self.filename = filename |
| 68 self.reference_support_info = reference_support_info | 69 self.reference_support_info = reference_support_info |
| 69 | 70 |
| 70 resources_path = self.path_from_webkit_root('LayoutTests', 'resources') | 71 resources_path = self.path_from_webkit_root('LayoutTests', 'resources') |
| 71 resources_relpath = self._filesystem.relpath(resources_path, new_path) | 72 resources_relpath = self._filesystem.relpath(resources_path, new_path) |
| 72 self.resources_relpath = resources_relpath | 73 self.resources_relpath = resources_relpath |
| 73 | 74 |
| 74 # These settings might vary between WebKit and Blink | 75 # These settings might vary between WebKit and Blink |
| 75 self._css_property_file = self.path_from_webkit_root('Source', 'core', '
css', 'CSSProperties.in') | 76 self._css_property_file = self.path_from_webkit_root('Source', 'core', '
css', 'CSSProperties.in') |
| 76 | 77 |
| 78 # prefixed_properties is a list of properties where we will add "-webkit
-" on the front of each name. |
| 79 # prefixed_values is a map of properties where we we will prefix each va
lue. |
| 80 # Property name can be also prefixed if included in the prefixed_propert
ies. |
| 81 # renamed_properties and renamed_values is a map where simply adding a p
refix isn't good enough. |
| 82 # TODO(kojii): other than prefixed_properties need to hard-code here, cl
ean this up when we unprefix. |
| 77 self.prefixed_properties = self.read_webkit_prefixed_css_property_list() | 83 self.prefixed_properties = self.read_webkit_prefixed_css_property_list() |
| 84 self.prefixed_values = { |
| 85 'unicode-bidi': ['isolate', 'isolate-override', 'plaintext'] |
| 86 } |
| 87 self.renamed_properties = { |
| 88 'text-combine-upright': '-webkit-text-combine' |
| 89 } |
| 90 self.renamed_values = { |
| 91 'text-combine-upright': {'all': 'horizontal'} |
| 92 } |
| 78 | 93 |
| 79 self.prefixed_properties = self.read_webkit_prefixed_css_property_list() | 94 prop_regex = '([\s{]|^)(' + "|".join(itertools.chain( |
| 80 prop_regex = '([\s{]|^)(' + "|".join(prop.replace('-webkit-', '') for pr
op in self.prefixed_properties) + ')(\s+:|:)' | 95 self.renamed_properties.iterkeys(), |
| 96 self.renamed_values.iterkeys(), |
| 97 self.prefixed_values.iterkeys(), |
| 98 (prop.replace('-webkit-', '') for prop in self.prefixed_properties))
) + ')(\s+:|:[^;]*)' |
| 81 self.prop_re = re.compile(prop_regex) | 99 self.prop_re = re.compile(prop_regex) |
| 82 | 100 |
| 83 def output(self): | 101 def output(self): |
| 84 return (self.converted_properties, ''.join(self.converted_data)) | 102 return (self.converted_properties, ''.join(self.converted_data)) |
| 85 | 103 |
| 86 def path_from_webkit_root(self, *comps): | 104 def path_from_webkit_root(self, *comps): |
| 87 return self._filesystem.abspath(self._filesystem.join(self._webkit_root,
*comps)) | 105 return self._filesystem.abspath(self._filesystem.join(self._webkit_root,
*comps)) |
| 88 | 106 |
| 89 def read_webkit_prefixed_css_property_list(self): | 107 def read_webkit_prefixed_css_property_list(self): |
| 90 prefixed_properties = [] | 108 prefixed_properties = [] |
| 91 unprefixed_properties = set() | 109 unprefixed_properties = set() |
| 92 | 110 |
| 93 contents = self._filesystem.read_text_file(self._css_property_file) | 111 contents = self._filesystem.read_text_file(self._css_property_file) |
| 94 for line in contents.splitlines(): | 112 for line in contents.splitlines(): |
| 95 if re.match('^(#|//|$)', line): | 113 if re.match('^(#|//|$)', line): |
| 96 # skip comments and preprocessor directives | 114 # skip comments and preprocessor directives |
| 97 continue | 115 continue |
| 98 prop = line.split()[0] | 116 prop = line.split()[0] |
| 99 # Find properties starting with the -webkit- prefix. | 117 # Find properties starting with the -webkit- prefix. |
| 100 match = re.match('-webkit-([\w|-]*)', prop) | 118 match = re.match('-webkit-([\w|-]*)', prop) |
| 101 if match: | 119 if match: |
| 102 prefixed_properties.append(match.group(1)) | 120 prefixed_properties.append(match.group(1)) |
| 103 else: | 121 else: |
| 104 unprefixed_properties.add(prop.strip()) | 122 unprefixed_properties.add(prop.strip()) |
| 105 | 123 |
| 124 # SVG writing-mode exists, but CSS writing-mode is still prefixed. |
| 125 # They are two separate properties, so we need to pick one unless we cal
culates which elements it applies to. |
| 126 # Using file type can mitigate the issue, but we still can't support HTM
L/SVG mixed files at this moment. |
| 127 # TODO(kojii): Clean this up when we unprefix writing-mode. |
| 128 unprefixed_properties.discard('writing-mode') |
| 129 |
| 106 # Ignore any prefixed properties for which an unprefixed version is supp
orted | 130 # Ignore any prefixed properties for which an unprefixed version is supp
orted |
| 107 return [prop for prop in prefixed_properties if prop not in unprefixed_p
roperties] | 131 return [prop for prop in prefixed_properties if prop not in unprefixed_p
roperties] |
| 108 | 132 |
| 109 def add_webkit_prefix_to_unprefixed_properties(self, text): | 133 def add_webkit_prefix_to_unprefixed_properties(self, text): |
| 110 """ Searches |text| for instances of properties requiring the -webkit- p
refix and adds the prefix to them. | 134 """ Searches |text| for instances of properties requiring the -webkit- p
refix and adds the prefix to them. |
| 111 | 135 |
| 112 Returns the list of converted properties and the modified text.""" | 136 Returns the list of converted properties and the modified text.""" |
| 113 | 137 |
| 114 converted_properties = set() | 138 converted_properties = set() |
| 115 text_chunks = [] | 139 text_chunks = [] |
| 116 cur_pos = 0 | 140 cur_pos = 0 |
| 117 for m in self.prop_re.finditer(text): | 141 for m in self.prop_re.finditer(text): |
| 118 text_chunks.extend([text[cur_pos:m.start()], m.group(1), '-webkit-',
m.group(2), m.group(3)]) | 142 text_chunks.extend([text[cur_pos:m.start()], m.group(1)]) |
| 119 converted_properties.add(m.group(2)) | 143 property = m.group(2) |
| 144 oldProperty = self.renamed_properties.get(property) |
| 145 if oldProperty: |
| 146 text_chunks.append(oldProperty) |
| 147 elif property in self.prefixed_properties: |
| 148 text_chunks.extend(['-webkit-', property]) |
| 149 else: |
| 150 text_chunks.append(property) |
| 151 text_chunks.append(self.add_webkit_prefix_to_unprefixed_value(proper
ty, m.group(3))) |
| 152 converted_properties.add(property) |
| 120 cur_pos = m.end() | 153 cur_pos = m.end() |
| 121 text_chunks.append(text[cur_pos:]) | 154 text_chunks.append(text[cur_pos:]) |
| 122 | 155 |
| 123 for prop in converted_properties: | 156 for prop in converted_properties: |
| 124 _log.info(' converting %s', prop) | 157 _log.info(' converting %s', prop) |
| 125 | 158 |
| 126 # FIXME: Handle the JS versions of these properties and GetComputedStyle
, too. | 159 # FIXME: Handle the JS versions of these properties and GetComputedStyle
, too. |
| 127 return (converted_properties, ''.join(text_chunks)) | 160 return (converted_properties, ''.join(text_chunks)) |
| 128 | 161 |
| 162 def add_webkit_prefix_to_unprefixed_value(self, property, text): |
| 163 renamed_values = self.renamed_values.get(property) |
| 164 if renamed_values: |
| 165 text = re.sub("|".join(renamed_values.iterkeys()), lambda m: renamed
_values[m.group(0)], text) |
| 166 prefixed_values = self.prefixed_values.get(property) |
| 167 if prefixed_values: |
| 168 text = re.sub("|".join(prefixed_values), lambda m: '-webkit-' + m.gr
oup(0), text) |
| 169 return text |
| 170 |
| 129 def convert_reference_relpaths(self, text): | 171 def convert_reference_relpaths(self, text): |
| 130 """ Searches |text| for instances of files in reference_support_info and
updates the relative path to be correct for the new ref file location""" | 172 """ Searches |text| for instances of files in reference_support_info and
updates the relative path to be correct for the new ref file location""" |
| 131 | 173 |
| 132 converted = text | 174 converted = text |
| 133 for path in self.reference_support_info['files']: | 175 for path in self.reference_support_info['files']: |
| 134 if text.find(path) != -1: | 176 if text.find(path) != -1: |
| 135 # FIXME: This doesn't handle an edge case where simply removing
the relative path doesn't work. | 177 # FIXME: This doesn't handle an edge case where simply removing
the relative path doesn't work. |
| 136 # See crbug.com/421584 for details. | 178 # See crbug.com/421584 for details. |
| 137 new_path = re.sub(self.reference_support_info['reference_relpath
'], '', path, 1) | 179 new_path = re.sub(self.reference_support_info['reference_relpath
'], '', path, 1) |
| 138 converted = re.sub(path, new_path, text) | 180 converted = re.sub(path, new_path, text) |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 self.converted_data.extend(['&#', name, ';']) | 254 self.converted_data.extend(['&#', name, ';']) |
| 213 | 255 |
| 214 def handle_comment(self, data): | 256 def handle_comment(self, data): |
| 215 self.converted_data.extend(['<!-- ', data, ' -->']) | 257 self.converted_data.extend(['<!-- ', data, ' -->']) |
| 216 | 258 |
| 217 def handle_decl(self, decl): | 259 def handle_decl(self, decl): |
| 218 self.converted_data.extend(['<!', decl, '>']) | 260 self.converted_data.extend(['<!', decl, '>']) |
| 219 | 261 |
| 220 def handle_pi(self, data): | 262 def handle_pi(self, data): |
| 221 self.converted_data.extend(['<?', data, '>']) | 263 self.converted_data.extend(['<?', data, '>']) |
| OLD | NEW |