• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3# found in the LICENSE file.
4
5import os
6import re
7
8from py_vulcanize import js_utils
9from py_vulcanize import module
10from py_vulcanize import parse_html_deps
11from py_vulcanize import style_sheet
12
13
14def IsHTMLResourceTheModuleGivenConflictingResourceNames(
15    js_resource, html_resource):  # pylint: disable=unused-argument
16  return 'polymer-element' in html_resource.contents
17
18
19class HTMLModule(module.Module):
20
21  @property
22  def _module_dir_name(self):
23    return os.path.dirname(self.resource.absolute_path)
24
25  def Parse(self, excluded_scripts):
26    try:
27      parser_results = parse_html_deps.HTMLModuleParser().Parse(self.contents)
28    except Exception as ex:
29      raise Exception('While parsing %s: %s' % (self.name, str(ex)))
30
31    self.dependency_metadata = Parse(self.loader,
32                                     self.name,
33                                     self._module_dir_name,
34                                     self.IsThirdPartyComponent(),
35                                     parser_results,
36                                     excluded_scripts)
37    self._parser_results = parser_results
38    self.scripts = parser_results.scripts
39
40  def Load(self, excluded_scripts):
41    super(HTMLModule, self).Load(excluded_scripts=excluded_scripts)
42
43    reachable_names = set([m.name
44                           for m in self.all_dependent_modules_recursive])
45    if 'tr.exportTo' in self.contents:
46      if 'tracing.base.base' not in reachable_names:
47        raise Exception('%s: Does not have a dependency on base' %
48                        os.path.relpath(self.resource.absolute_path))
49
50    for script in self.scripts:
51      if script.is_external:
52        if excluded_scripts and any(re.match(pattern, script.src) for
53            pattern in excluded_scripts):
54          continue
55
56        resource = _HRefToResource(self.loader, self.name, self._module_dir_name,
57                                   script.src,
58                                   tag_for_err_msg='<script src="%s">' % script.src)
59        path = resource.unix_style_relative_path
60        raw_script = self.loader.LoadRawScript(path)
61        self.dependent_raw_scripts.append(raw_script)
62        script.loaded_raw_script = raw_script
63
64  def GetTVCMDepsModuleType(self):
65    return 'py_vulcanize.HTML_MODULE_TYPE'
66
67  def AppendHTMLContentsToFile(self, f, ctl, minify=False):
68    super(HTMLModule, self).AppendHTMLContentsToFile(f, ctl)
69
70    ctl.current_module = self
71    try:
72      for piece in self._parser_results.YieldHTMLInPieces(ctl, minify=minify):
73        f.write(piece)
74    finally:
75      ctl.current_module = None
76
77  def HRefToResource(self, href, tag_for_err_msg):
78    return _HRefToResource(self.loader, self.name, self._module_dir_name,
79                           href, tag_for_err_msg)
80
81  def AppendDirectlyDependentFilenamesTo(
82      self, dependent_filenames, include_raw_scripts=True):
83    super(HTMLModule, self).AppendDirectlyDependentFilenamesTo(
84        dependent_filenames, include_raw_scripts)
85    for contents in self._parser_results.inline_stylesheets:
86      module_dirname = os.path.dirname(self.resource.absolute_path)
87      ss = style_sheet.ParsedStyleSheet(
88          self.loader, module_dirname, contents)
89      ss.AppendDirectlyDependentFilenamesTo(dependent_filenames)
90
91def _HRefToResource(
92    loader, module_name, module_dir_name, href, tag_for_err_msg):
93  if href[0] == '/':
94    resource = loader.FindResourceGivenRelativePath(
95        os.path.normpath(href[1:]))
96  else:
97    abspath = os.path.normpath(os.path.join(module_dir_name,
98                                            os.path.normpath(href)))
99    resource = loader.FindResourceGivenAbsolutePath(abspath)
100
101  if not resource:
102    raise module.DepsException(
103        'In %s, the %s cannot be loaded because '
104        'it is not in the search path' % (module_name, tag_for_err_msg))
105  try:
106    resource.contents
107  except:
108    raise module.DepsException('In %s, %s points at a nonexistent file ' % (
109        module_name, tag_for_err_msg))
110  return resource
111
112
113def Parse(loader, module_name, module_dir_name, is_component, parser_results,
114          exclude_scripts=None):
115  res = module.ModuleDependencyMetadata()
116  if is_component:
117    return res
118
119  # External script references.
120  for href in parser_results.scripts_external:
121    if exclude_scripts and any(re.match(pattern, href) for
122        pattern in exclude_scripts):
123      continue
124
125    resource = _HRefToResource(loader, module_name, module_dir_name,
126                               href,
127                               tag_for_err_msg='<script src="%s">' % href)
128    res.dependent_raw_script_relative_paths.append(
129        resource.unix_style_relative_path)
130
131  # External imports. Mostly the same as <script>, but we know its a module.
132  for href in parser_results.imports:
133    if exclude_scripts and any(re.match(pattern, href) for
134        pattern in exclude_scripts):
135      continue
136
137    if not href.endswith('.html'):
138      raise Exception(
139          'In %s, the <link rel="import" href="%s"> must point at a '
140          'file with an html suffix' % (module_name, href))
141
142    resource = _HRefToResource(
143        loader, module_name, module_dir_name, href,
144        tag_for_err_msg='<link rel="import" href="%s">' % href)
145    res.dependent_module_names.append(resource.name)
146
147  # Style sheets.
148  for href in parser_results.stylesheets:
149    resource = _HRefToResource(
150        loader, module_name, module_dir_name, href,
151        tag_for_err_msg='<link rel="stylesheet" href="%s">' % href)
152    res.style_sheet_names.append(resource.name)
153
154  return res
155