| 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 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 | 32 |
| 33 from webkitpy.common.host import Host | 33 from webkitpy.common.host import Host |
| 34 from webkitpy.common.webkit_finder import WebKitFinder | 34 from webkitpy.common.webkit_finder import WebKitFinder |
| 35 from HTMLParser import HTMLParser | 35 from HTMLParser import HTMLParser |
| 36 | 36 |
| 37 | 37 |
| 38 _log = logging.getLogger(__name__) | 38 _log = logging.getLogger(__name__) |
| 39 | 39 |
| 40 | 40 |
| 41 def convert_for_webkit(new_path, filename, reference_support_info, host=Host()): | 41 def convert_for_webkit(new_path, filename, reference_support_info, host=Host()): |
| 42 """ Converts a file's |contents| so it will function correctly in its |new_p
ath| in Webkit. | 42 """Converts a file's contents so the Blink layout test runner can run it. |
| 43 | 43 |
| 44 Returns the list of modified properties and the modified text if the file wa
s modified, None otherwise.""" | 44 Returns: |
| 45 A pair: the list of modified properties, and the modified text if the file
was modified, None otherwise. |
| 46 """ |
| 45 contents = host.filesystem.read_binary_file(filename) | 47 contents = host.filesystem.read_binary_file(filename) |
| 46 converter = _W3CTestConverter(new_path, filename, reference_support_info, ho
st) | 48 converter = _W3CTestConverter(new_path, filename, reference_support_info, ho
st) |
| 47 if filename.endswith('.css'): | 49 if filename.endswith('.css'): |
| 48 return converter.add_webkit_prefix_to_unprefixed_properties(contents.dec
ode('utf-8')) | 50 return converter.add_webkit_prefix_to_unprefixed_properties(contents.dec
ode('utf-8')) |
| 49 else: | 51 else: |
| 50 converter.feed(contents.decode('utf-8')) | 52 converter.feed(contents.decode('utf-8')) |
| 51 converter.close() | 53 converter.close() |
| 52 return converter.output() | 54 return converter.output() |
| 53 | 55 |
| 54 | 56 |
| 55 class _W3CTestConverter(HTMLParser): | 57 class _W3CTestConverter(HTMLParser): |
| 58 """A HTMLParser subclass which converts a HTML file as it is parsed. |
| 59 |
| 60 After the feed() method is called, the converted document will be stored |
| 61 in converted_data, and can be retrieved with the output() method. |
| 62 """ |
| 56 | 63 |
| 57 def __init__(self, new_path, filename, reference_support_info, host=Host()): | 64 def __init__(self, new_path, filename, reference_support_info, host=Host()): |
| 58 HTMLParser.__init__(self) | 65 HTMLParser.__init__(self) |
| 59 | 66 |
| 60 self._host = host | 67 self._host = host |
| 61 self._filesystem = self._host.filesystem | 68 self._filesystem = self._host.filesystem |
| 62 self._webkit_root = WebKitFinder(self._filesystem).webkit_base() | 69 self._webkit_root = WebKitFinder(self._filesystem).webkit_base() |
| 63 | 70 |
| 64 self.converted_data = [] | 71 self.converted_data = [] |
| 65 self.converted_properties = [] | 72 self.converted_properties = [] |
| 66 self.in_style_tag = False | 73 self.in_style_tag = False |
| 67 self.style_data = [] | 74 self.style_data = [] |
| 68 self.filename = filename | 75 self.filename = filename |
| 69 self.reference_support_info = reference_support_info | 76 self.reference_support_info = reference_support_info |
| 70 | 77 |
| 71 resources_path = self.path_from_webkit_root('LayoutTests', 'resources') | 78 resources_path = self.path_from_webkit_root('LayoutTests', 'resources') |
| 72 resources_relpath = self._filesystem.relpath(resources_path, new_path) | 79 resources_relpath = self._filesystem.relpath(resources_path, new_path) |
| 73 self.resources_relpath = resources_relpath | 80 self.resources_relpath = resources_relpath |
| 74 | 81 |
| 75 # These settings might vary between WebKit and Blink | 82 # These settings might vary between WebKit and Blink. |
| 76 self._css_property_file = self.path_from_webkit_root('Source', 'core', '
css', 'CSSProperties.in') | 83 self._css_property_file = self.path_from_webkit_root('Source', 'core', '
css', 'CSSProperties.in') |
| 77 self.prefixed_properties = self.read_webkit_prefixed_css_property_list() | 84 self.prefixed_properties = self.read_webkit_prefixed_css_property_list() |
| 78 prop_regex = '([\s{]|^)(' + "|".join( | 85 prop_regex = '([\s{]|^)(' + "|".join( |
| 79 prop.replace('-webkit-', '') for prop in self.prefixed_properties) +
')(\s+:|:)' | 86 prop.replace('-webkit-', '') for prop in self.prefixed_properties) +
')(\s+:|:)' |
| 80 self.prop_re = re.compile(prop_regex) | 87 self.prop_re = re.compile(prop_regex) |
| 81 | 88 |
| 82 def output(self): | 89 def output(self): |
| 83 return (self.converted_properties, ''.join(self.converted_data)) | 90 return (self.converted_properties, ''.join(self.converted_data)) |
| 84 | 91 |
| 85 def path_from_webkit_root(self, *comps): | 92 def path_from_webkit_root(self, *comps): |
| 86 return self._filesystem.abspath(self._filesystem.join(self._webkit_root,
*comps)) | 93 return self._filesystem.abspath(self._filesystem.join(self._webkit_root,
*comps)) |
| 87 | 94 |
| 88 def read_webkit_prefixed_css_property_list(self): | 95 def read_webkit_prefixed_css_property_list(self): |
| 89 prefixed_properties = [] | 96 prefixed_properties = [] |
| 90 unprefixed_properties = set() | 97 unprefixed_properties = set() |
| 91 | 98 |
| 92 contents = self._filesystem.read_text_file(self._css_property_file) | 99 contents = self._filesystem.read_text_file(self._css_property_file) |
| 93 for line in contents.splitlines(): | 100 for line in contents.splitlines(): |
| 94 if re.match('^(#|//|$)', line): | 101 if re.match('^(#|//|$)', line): |
| 95 # skip comments and preprocessor directives | 102 # skip comments and preprocessor directives. |
| 96 continue | 103 continue |
| 97 prop = line.split()[0] | 104 prop = line.split()[0] |
| 98 # Find properties starting with the -webkit- prefix. | 105 # Find properties starting with the -webkit- prefix. |
| 99 match = re.match('-webkit-([\w|-]*)', prop) | 106 match = re.match('-webkit-([\w|-]*)', prop) |
| 100 if match: | 107 if match: |
| 101 prefixed_properties.append(match.group(1)) | 108 prefixed_properties.append(match.group(1)) |
| 102 else: | 109 else: |
| 103 unprefixed_properties.add(prop.strip()) | 110 unprefixed_properties.add(prop.strip()) |
| 104 | 111 |
| 105 # Ignore any prefixed properties for which an unprefixed version is supp
orted | 112 # Ignore any prefixed properties for which an unprefixed version is supp
orted. |
| 106 return [prop for prop in prefixed_properties if prop not in unprefixed_p
roperties] | 113 return [prop for prop in prefixed_properties if prop not in unprefixed_p
roperties] |
| 107 | 114 |
| 108 def add_webkit_prefix_to_unprefixed_properties(self, text): | 115 def add_webkit_prefix_to_unprefixed_properties(self, text): |
| 109 """ Searches |text| for instances of properties requiring the -webkit- p
refix and adds the prefix to them. | 116 """Searches |text| for instances of properties requiring the -webkit- pr
efix and adds the prefix to them. |
| 110 | 117 |
| 111 Returns the list of converted properties and the modified text.""" | 118 Returns the list of converted properties and the modified text. |
| 112 | 119 """ |
| 113 converted_properties = set() | 120 converted_properties = set() |
| 114 text_chunks = [] | 121 text_chunks = [] |
| 115 cur_pos = 0 | 122 cur_pos = 0 |
| 116 for m in self.prop_re.finditer(text): | 123 for m in self.prop_re.finditer(text): |
| 117 text_chunks.extend([text[cur_pos:m.start()], m.group(1), '-webkit-',
m.group(2), m.group(3)]) | 124 text_chunks.extend([text[cur_pos:m.start()], m.group(1), '-webkit-',
m.group(2), m.group(3)]) |
| 118 converted_properties.add(m.group(2)) | 125 converted_properties.add(m.group(2)) |
| 119 cur_pos = m.end() | 126 cur_pos = m.end() |
| 120 text_chunks.append(text[cur_pos:]) | 127 text_chunks.append(text[cur_pos:]) |
| 121 | 128 |
| 122 for prop in converted_properties: | 129 for prop in converted_properties: |
| 123 _log.info(' converting %s', prop) | 130 _log.info(' converting %s', prop) |
| 124 | 131 |
| 125 # FIXME: Handle the JS versions of these properties and GetComputedStyle
, too. | 132 # FIXME: Handle the JS versions of these properties and GetComputedStyle
, too. |
| 126 return (converted_properties, ''.join(text_chunks)) | 133 return (converted_properties, ''.join(text_chunks)) |
| 127 | 134 |
| 128 def convert_reference_relpaths(self, text): | 135 def convert_reference_relpaths(self, text): |
| 129 """ Searches |text| for instances of files in reference_support_info and
updates the relative path to be correct for the new ref file location""" | 136 """Converts reference file paths found in the given text. |
| 130 | 137 |
| 138 Searches |text| for instances of files in |self.reference_support_info|
and |
| 139 updates the relative path to be correct for the new ref file location. |
| 140 """ |
| 131 converted = text | 141 converted = text |
| 132 for path in self.reference_support_info['files']: | 142 for path in self.reference_support_info['files']: |
| 133 if path in text: | 143 if path in text: |
| 134 # FIXME: This doesn't handle an edge case where simply removing
the relative path doesn't work. | 144 # FIXME: This doesn't handle an edge case where simply removing
the relative path doesn't work. |
| 135 # See crbug.com/421584 for details. | 145 # See crbug.com/421584 for details. |
| 136 new_path = re.sub(self.reference_support_info['reference_relpath
'], '', path, 1) | 146 new_path = re.sub(self.reference_support_info['reference_relpath
'], '', path, 1) |
| 137 converted = re.sub(path, new_path, text) | 147 converted = re.sub(path, new_path, text) |
| 138 | 148 |
| 139 return converted | 149 return converted |
| 140 | 150 |
| 141 def convert_style_data(self, data): | 151 def convert_style_data(self, data): |
| 142 converted = self.add_webkit_prefix_to_unprefixed_properties(data) | 152 converted = self.add_webkit_prefix_to_unprefixed_properties(data) |
| 143 if converted[0]: | 153 if converted[0]: |
| 144 self.converted_properties.extend(list(converted[0])) | 154 self.converted_properties.extend(list(converted[0])) |
| 145 | 155 |
| 146 if self.reference_support_info is None or self.reference_support_info ==
{}: | 156 if self.reference_support_info is None or self.reference_support_info ==
{}: |
| 147 return converted[1] | 157 return converted[1] |
| 148 | 158 |
| 149 return self.convert_reference_relpaths(converted[1]) | 159 return self.convert_reference_relpaths(converted[1]) |
| 150 | 160 |
| 151 def convert_attributes_if_needed(self, tag, attrs): | 161 def convert_attributes_if_needed(self, tag, attrs): |
| 162 """Converts attributes in a start tag in HTML. |
| 163 |
| 164 The converted tag text is appended to |self.converted_data|. |
| 165 """ |
| 152 converted = self.get_starttag_text() | 166 converted = self.get_starttag_text() |
| 153 for attr_name, attr_value in attrs: | 167 for attr_name, attr_value in attrs: |
| 154 if attr_name == 'style': | 168 if attr_name == 'style': |
| 155 new_style = self.convert_style_data(attr_value) | 169 new_style = self.convert_style_data(attr_value) |
| 156 converted = re.sub(re.escape(attr_value), new_style, converted) | 170 converted = re.sub(re.escape(attr_value), new_style, converted) |
| 157 if attr_name == 'class' and 'instructions' in attr_value: | 171 if attr_name == 'class' and 'instructions' in attr_value: |
| 158 # Always hide instructions, they're for manual testers. | 172 # Always hide instructions, they're for manual testers. |
| 159 converted = re.sub(' style=".*?"', '', converted) | 173 converted = re.sub(' style=".*?"', '', converted) |
| 160 converted = re.sub('\>', ' style="display:none">', converted) | 174 converted = re.sub('\>', ' style="display:none">', converted) |
| 161 | 175 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 self.converted_data.extend(['&#', name, ';']) | 210 self.converted_data.extend(['&#', name, ';']) |
| 197 | 211 |
| 198 def handle_comment(self, data): | 212 def handle_comment(self, data): |
| 199 self.converted_data.extend(['<!-- ', data, ' -->']) | 213 self.converted_data.extend(['<!-- ', data, ' -->']) |
| 200 | 214 |
| 201 def handle_decl(self, decl): | 215 def handle_decl(self, decl): |
| 202 self.converted_data.extend(['<!', decl, '>']) | 216 self.converted_data.extend(['<!', decl, '>']) |
| 203 | 217 |
| 204 def handle_pi(self, data): | 218 def handle_pi(self, data): |
| 205 self.converted_data.extend(['<?', data, '>']) | 219 self.converted_data.extend(['<?', data, '>']) |
| OLD | NEW |