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