Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Functions | Variables
scripts.mdnreader Namespace Reference

Classes

class  MDNReader
 

Functions

 _get_browser_compat_data ()
 
 _unify_versions (version_a, version_b)
 
 _is_simple_support_statement (support_statement)
 

Variables

str _COMPAT_KEY = '__compat'
 
str _EXPERIMENTAL_KEY = 'experimental'
 
str _STATUS_KEY = 'status'
 
str _SUPPORT_KEY = 'support'
 
str _VERSION_ADDED_KEY = 'version_added'
 

Function Documentation

◆ _get_browser_compat_data()

scripts.mdnreader._get_browser_compat_data ( )
protected

Definition at line 18 of file mdnreader.py.

18def _get_browser_compat_data():
19 current_dir = os.path.dirname(__file__)
20
21 browser_compat_folder = os.path.abspath(
22 os.path.join(current_dir, '..', '..', '..', 'third_party', 'mdn',
23 'browser-compat-data', 'src'))
24
25 if not os.path.exists(browser_compat_folder):
26 raise RuntimeError('Browser compatibility data not found at %s' %
27 browser_compat_folder)
28
29 browser_compat_data = {}
30
31 INCLUDE_DIRS = [
32 'api',
33 'html',
34 'svg',
35 # TODO(srujzs): add more if needed
36 ]
37
38 # Transform to absolute paths
39 INCLUDE_DIRS = [
40 os.path.join(browser_compat_folder, dir) for dir in INCLUDE_DIRS
41 ]
42
43 def process_json_dict(json_dict):
44 # Returns a tuple of the interface name and the metadata corresponding
45 # to it.
46 if 'api' in json_dict:
47 # Get the interface name
48 api_dict = json_dict['api']
49 interface_name = next(iter(api_dict))
50 return (interface_name, api_dict[interface_name])
51 elif 'html' in json_dict:
52 html_dict = json_dict['html']
53 if 'elements' in html_dict:
54 elements_dict = html_dict['elements']
55 element_name = next(iter(elements_dict))
56 # Convert to WebCore name
57 interface = str('HTML' + element_name + 'Element')
58 return (interface, elements_dict[element_name])
59 elif 'svg' in json_dict:
60 svg_dict = json_dict['svg']
61 if 'elements' in svg_dict:
62 elements_dict = svg_dict['elements']
63 element_name = next(iter(elements_dict))
64 # Convert to WebCore name
65 interface = str('SVG' + element_name + 'Element')
66 return (interface, elements_dict[element_name])
67 return (None, None)
68
69 # Attempts to unify two compatibility infos by taking the union of both, and
70 # for conflicting information, taking the "stricter" of the two versions.
71 # Updates `a` in place to represent the union of `a` and `b`.
72 def _unify_compat(a, b):
73
74 def _has_compat_data(metadata):
75 return _COMPAT_KEY in metadata and _SUPPORT_KEY in metadata[_COMPAT_KEY]
76
77 # Unifies the support statements of both metadata and updates
78 # `support_a` in place. If either metadata do not contain simple support
79 # statements, defaults attribute to not supported.
80 def _unify_support(support_a, support_b):
81 for browser in support_a.keys():
82 if browser in support_b:
83 if _is_simple_support_statement(support_a[browser]) and _is_simple_support_statement(support_b[browser]):
84 support_a[browser][_VERSION_ADDED_KEY] = _unify_versions(
85 support_a[browser][_VERSION_ADDED_KEY],
86 support_b[browser][_VERSION_ADDED_KEY])
87 else:
88 # Only support simple statements for now.
89 support_a[browser] = {_VERSION_ADDED_KEY: None}
90 for browser in support_b.keys():
91 if not browser in support_a:
92 support_a[browser] = support_b[browser]
93
94 if not _has_compat_data(b):
95 return
96 if not _has_compat_data(a):
97 a[_COMPAT_KEY] = b[_COMPAT_KEY]
98 return
99
100 support_a = a[_COMPAT_KEY][_SUPPORT_KEY]
101 support_b = b[_COMPAT_KEY][_SUPPORT_KEY]
102
103 _unify_support(support_a, support_b)
104
105 # Unifies any status info in the two metadata. Modifies `a` in place to
106 # represent the union of both `a` and `b`.
107 def _unify_status(a, b):
108
109 def _has_status(metadata):
110 return _COMPAT_KEY in metadata and _STATUS_KEY in metadata[_COMPAT_KEY]
111
112 # Modifies `status_a` in place to combine "experimental" tags.
113 def _unify_experimental(status_a, status_b):
114 # If either of the statuses report experimental, assume attribute is
115 # experimental.
116 status_a[_EXPERIMENTAL_KEY] = status_a.get(
117 _EXPERIMENTAL_KEY, False) or status_b.get(_EXPERIMENTAL_KEY, False)
118
119 if not _has_status(b):
120 return
121 if not _has_status(a):
122 a[_COMPAT_KEY] = b[_COMPAT_KEY]
123 return
124
125 status_a = a[_COMPAT_KEY][_STATUS_KEY]
126 status_b = b[_COMPAT_KEY][_STATUS_KEY]
127
128 _unify_experimental(status_a, status_b)
129
130 # If there exists multiple definitions of the same interface metadata e.g.
131 # elements, this attempts to unify the compatibilities for the interface as
132 # well as for each attribute.
133 def _unify_metadata(a, b):
134 # Unify the compatibility statement and status of the API or element.
135 _unify_compat(a, b)
136 _unify_status(a, b)
137 # Unify the compatibility statement and status of each attribute.
138 for attr in list(a.keys()):
139 if attr == _COMPAT_KEY:
140 continue
141 if attr in b:
142 _unify_compat(a[attr], b[attr])
143 _unify_status(a[attr], b[attr])
144 for attr in b.keys():
145 if not attr in a:
146 a[attr] = b[attr]
147
148 for (dir_path, dirs, files) in os.walk(browser_compat_folder):
149
150 def should_process_dir(dir_path):
151 if os.path.abspath(dir_path) == browser_compat_folder:
152 return True
153 for dir in INCLUDE_DIRS:
154 if dir_path.startswith(dir):
155 return True
156 return False
157
158 if should_process_dir(dir_path):
159 for name in files:
160 file_name = os.path.join(dir_path, name)
161 (interface_path, ext) = os.path.splitext(file_name)
162 if ext == '.json':
163 with open(file_name) as src:
164 json_dict = json.load(src)
165 interface, metadata = process_json_dict(json_dict)
166 if not interface is None:
167 # Note: interface and member names do not
168 # necessarily have the same capitalization as
169 # WebCore, so we keep them all lowercase for easier
170 # matching later.
171 interface = interface.lower()
172 metadata = {
173 member.lower(): info
174 for member, info in metadata.items()
175 }
176
177 if interface in browser_compat_data:
178 _unify_metadata(browser_compat_data[interface],
179 metadata)
180 else:
181 browser_compat_data[interface] = metadata
182 else:
183 dirs[:] = [] # Do not go underneath
184
185 return browser_compat_data
186
187
188# Given two version values for a given browser, chooses the more strict version.
static float next(float f)

◆ _is_simple_support_statement()

scripts.mdnreader._is_simple_support_statement (   support_statement)
protected

Definition at line 239 of file mdnreader.py.

239def _is_simple_support_statement(support_statement):
240 if isinstance(support_statement, list): # array_support_statement
241 # TODO(srujzs): Parse this list to determine compatibility. Will
242 # likely require parsing for 'version_removed' keys. Notes about
243 # which browser version enabled this attribute for which
244 # platform also complicates things. For now, we assume it's not
245 # compatible.
246 return False
247 if len(support_statement.keys()) > 1:
248 # If it's anything more complicated than 'version_added', like
249 # 'notes' that specify platform versions, we assume it's not
250 # compatible.
251 return False
252 return True
253
254

◆ _unify_versions()

scripts.mdnreader._unify_versions (   version_a,
  version_b 
)
protected

Definition at line 189 of file mdnreader.py.

189def _unify_versions(version_a, version_b):
190 # Given two valid version strings, compares parts of the version string
191 # iteratively.
192 def _greater_version(version_a, version_b):
193 version_a_split = list(map(int, version_a.split('.')))
194 version_b_split = list(map(int, version_b.split('.')))
195 for i in range(min(len(version_a_split), len(version_b_split))):
196 if version_a_split[i] > version_b_split[i]:
197 return version_a
198 elif version_a_split[i] < version_b_split[i]:
199 return version_b
200 return version_a if len(version_a_split) > len(
201 version_b_split) else version_b
202
203 # Validate that we can handle the given version.
204 def _validate_version(version):
205 if not version:
206 return False
207 if version is True:
208 return True
209 if isinstance(version, str):
210 pattern = re.compile('^([0-9]+\.)*[0-9]+$')
211 if not pattern.match(version):
212 # It's possible for version strings to look like '<35'. We don't
213 # attempt to parse the conditional logic, and just default to
214 # potentially incompatible.
215 return None
216 return version
217 else:
218 raise ValueError(
219 'Type of version_a was not handled correctly! type(version) = '
220 + str(type(version)))
221
222 version_a = _validate_version(version_a)
223 version_b = _validate_version(version_b)
224 # If one version reports not supported, default to not supported.
225 if not version_a or not version_b:
226 return False
227 # If one version reports always supported, the other version can only be
228 # more strict.
229 if version_a is True:
230 return version_b
231 if version_b is True:
232 return version_a
233
234 return _greater_version(version_a, version_b)
235
236
237# At this time, we only handle simple support statements due to the complexity
238# and variability around support statements with multiple elements.
static float min(float r, float g, float b)
Definition hsl.cpp:48

Variable Documentation

◆ _COMPAT_KEY

str scripts.mdnreader._COMPAT_KEY = '__compat'
protected

Definition at line 11 of file mdnreader.py.

◆ _EXPERIMENTAL_KEY

str scripts.mdnreader._EXPERIMENTAL_KEY = 'experimental'
protected

Definition at line 12 of file mdnreader.py.

◆ _STATUS_KEY

str scripts.mdnreader._STATUS_KEY = 'status'
protected

Definition at line 13 of file mdnreader.py.

◆ _SUPPORT_KEY

str scripts.mdnreader._SUPPORT_KEY = 'support'
protected

Definition at line 14 of file mdnreader.py.

◆ _VERSION_ADDED_KEY

str scripts.mdnreader._VERSION_ADDED_KEY = 'version_added'
protected

Definition at line 15 of file mdnreader.py.