def bubble(self, node: Node): props = [] others = [] def filter_props(block): for node in block.nodes: node = self.visit(node) if node.node_name == "property": props.append(node) elif node.node_name == "block": filter_props(node) else: others.append(node) filter_props(node.block) if props: selector = Selector([Literal("&")]) selector.lineno = node.lineno selector.column = node.column selector.filename = node.filename selector.value = "&" group = Group(lineno=self.parser.lineno, column=self.parser.column) group.lineno = node.lineno group.column = node.column group.filename = node.filename block = Block(node.block, group) block.lineno = node.lineno block.column = node.column block.filename = node.filename for prop in props: block.append(prop) group.append(selector) group.block = block node.block.nodes = [] node.block.append(group) for other in others: node.block.append(other) group = self.closest_group(node.block) if group: node.group = group.clone() node.bubbled = True
def import_file(self, node: Import, file, literal, lineno=1, column=1): log.debug(f"importing {file}; {self.import_stack}") # handling 'require' if node.once: if self.require_history.get(file, False): return null self.require_history[file] = True if literal and not self.include_css: return node # avoid overflows from reimporting the same file if file in self.import_stack: raise ImportError("import loop has been found") with open(file, "r") as f: source = f.read() # shortcut for empty files if not source.strip(): return null # expose imports node.path = file node.dirname = Path(file).parent # store modified time node.mtime = os.stat(file).st_mtime self.paths.append(str(node.dirname)) if "_imports" in self.options: self.options["_imports"].append(node.clone()) # parse the file self.import_stack.append(file) filename_node.current_filename = file if literal: re.sub("\n\n?", "\n", source) literal = Literal(source, lineno=self.parser.lineno, column=self.parser.column) literal.lineno = 1 literal.column = 1 if not self.resolve_url: return literal # create block block = Block(None, None, lineno=lineno, column=column) block.filename = file # parse merged = {} merged.update(self.options) merged.update({"root": block}) parser = Parser(source, merged) try: block = parser.parse() except Exception: line = parser.lexer.lineno column = parser.lexer.column if literal and self.include_css and self.resolve_url: self.warn(f"ParseError: {file}:{line}:{column}. " f"This file is included as-is") return literal else: raise ParseError( "Issue when parsing an imported file", filename=file, lineno=line, column=column, input=source, ) # evaluate imported 'root' block = block.clone(self.get_current_block()) block.parent = self.get_current_block() block.scope = False ret = self.visit(block) self.import_stack.pop() if not self.resolve_url: # or not self.resolve_url no_check: self.paths.pop() return ret