Beispiel #1
0
def get_selectors(document, selectors):
    view = {}
    for selector in selectors:
        val = selectors.get(selector)
        cssselector = CSSSelector(selector)
        matching = cssselector.evaluate(document)
        # print(selector, info)
        for element in matching:
            info = val
            if callable(val):
                info = val(selector, element)
            if element not in view:
                view[element] = {}
                if info:
                    view[element].update(info)
            else:
                # head = view[element].get('start', '')
                # tail = view[element].get('end', '')
                if info:
                    view[element].update(info)
    return view
Beispiel #2
0
def getView(document,
            css,
            media='all',
            name=None,
            styleCallback=lambda element: None):
    """
    document
        a DOM document, currently an lxml HTML document
    css
        a CSS StyleSheet string
    media: optional
        TODO: view for which media it should be
    name: optional
        TODO: names of sheets only
    styleCallback: optional
        should return css.CSSStyleDeclaration of inline styles, for html
        a style declaration for ``element@style``. Gets one parameter 
        ``element`` which is the relevant DOMElement
    
    returns style view
        a dict of {DOMElement: css.CSSStyleDeclaration} for html
    """
    sheet = cssutils.parseString(css)

    view = {}
    specificities = {}  # needed temporarily

    # TODO: filter rules simpler?, add @media
    rules = (rule for rule in sheet if rule.type == rule.STYLE_RULE)
    for rule in rules:
        for selector in rule.selectorList:
            log(0, 'SELECTOR', selector.selectorText)
            # TODO: make this a callback to be able to use other stuff than lxml
            cssselector = CSSSelector(selector.selectorText)
            matching = cssselector.evaluate(document)
            for element in matching:
                #if element.tag in ('div',):
                # add styles for all matching DOM elements
                log(1, 'ELEMENT', id(element), element.text)

                if element not in view:
                    # add initial empty style declatation
                    view[element] = cssutils.css.CSSStyleDeclaration()
                    specificities[element] = {}

                    # and add inline @style if present
                    inlinestyle = styleCallback(element)
                    if inlinestyle:
                        for p in inlinestyle:
                            # set inline style specificity
                            view[element].setProperty(p)
                            specificities[element][p.name] = (1, 0, 0, 0)

                for p in rule.style:
                    # update style declaration
                    if p not in view[element]:
                        # setProperty needs a new Property object and
                        # MUST NOT reuse the existing Property
                        # which would be the same for all elements!
                        # see Issue #23
                        view[element].setProperty(p.name, p.value, p.priority)
                        specificities[element][p.name] = selector.specificity
                        log(2, view[element].getProperty('color'))

                    else:
                        log(2, view[element].getProperty('color'))
                        sameprio = (
                            p.priority == view[element].getPropertyPriority(
                                p.name))
                        if not sameprio and bool(p.priority) or (
                                sameprio and selector.specificity >=
                                specificities[element][p.name]):
                            # later, more specific or higher prio
                            view[element].setProperty(p.name, p.value,
                                                      p.priority)

    #pprint(view)
    return view
Beispiel #3
0
    document = etree.HTML(html)
    e = etree.Element('pre', {'class': 'cssutils'})
    e.text = css
    document.find('body').append(e)

    sheet = cssutils.parseString(css)

    view = {}
    specificities = {}  # temporarily needed
    # TODO: filter rules simpler?, add @media
    rules = (rule for rule in sheet.cssRules if rule.type == rule.STYLE_RULE)

    for rule in rules:
        for selector in rule.selectorList:
            cssselector = CSSSelector(selector.selectorText)
            elements = cssselector.evaluate(document)
            for element in elements:
                # add styles for all matching DOM elements
                if element not in view:
                    # add initial
                    view[element] = cssutils.css.CSSStyleDeclaration()
                    specificities[element] = {}

                for p in rule.style:
                    # update styles
                    if p not in view[element]:
                        view[element].setProperty(p)
                        specificities[element][p.name] = selector.specificity
                    else:
                        sameprio = (
                            p.priority == view[element].getPropertyPriority(
Beispiel #4
0
def getView(document, css):
    """
	document
		a DOM document, currently an lxml HTML document
	css
		a CSS StyleSheet string
	
	returns style view
		a dict of {DOMElement: css.CSSStyleDeclaration} for html
	"""
    from lxml.cssselect import CSSSelector
    sheet = cssutils.parseString(css)

    view = {}
    specificities = {}  # needed temporarily

    # TODO: filter rules simpler?, add @media
    rules = (rule for rule in sheet if rule.type == rule.STYLE_RULE)
    for rule in rules:
        for selector in rule.selectorList:
            #log(0, 'SELECTOR', selector.selectorText)
            # TODO: make this a callback to be able to use other stuff than lxml
            try:
                cssselector = CSSSelector(selector.selectorText)
            except:
                continue
            matching = cssselector.evaluate(document)

            for element in matching:
                #if element.tag in ('div',):
                # add styles for all matching DOM elements
                #log(1, 'ELEMENT', id(element), element.text)

                if element not in view:
                    # add initial empty style declatation
                    view[element] = cssutils.css.CSSStyleDeclaration(
                    )  # @UndefinedVariable
                    specificities[element] = {}

                for p in rule.style:
                    # update style declaration
                    if p not in view[element]:
                        # setProperty needs a new Property object and
                        # MUST NOT reuse the existing Property
                        # which would be the same for all elements!
                        # see Issue #23
                        view[element].setProperty(p.name, p.value, p.priority)
                        specificities[element][p.name] = selector.specificity
                        #log(2, view[element].getProperty('color'))

                    else:
                        #log(2, view[element].getProperty('color'))
                        sameprio = (
                            p.priority == view[element].getPropertyPriority(
                                p.name))
                        if not sameprio and bool(p.priority) or (
                                sameprio and selector.specificity >=
                                specificities[element][p.name]):
                            # later, more specific or higher prio
                            view[element].setProperty(p.name, p.value,
                                                      p.priority)

    return view
Beispiel #5
0
def get_view(document, sheet, name=None, style_callback=lambda element: None):
    """
    document
        a DOM document, currently an lxml HTML document
    sheet
        a CSS StyleSheet
    name: optional
        TODO: names of sheets only
    style_callback: optional
        should return css.CSSStyleDeclaration of inline styles, for html
        a style declaration for ``element@style``. Gets one parameter
        ``element`` which is the relevant DOMElement

    returns style view
        a dict of {DOMElement: css.CSSStyleDeclaration} for html
    """

    view = {}
    specificities = {}  # needed temporarily

    # TODO: filter rules simpler?, add @media
    rules = (rule for rule in sheet if rule.type == rule.STYLE_RULE)
    for rule in rules:
        for selector in rule.selectorList:
            # TODO: make this a callback to be able to use other stuff than lxml
            try:
                cssselector = CSSSelector(selector.selectorText)
            except ExpressionError:
                continue
            matching = cssselector.evaluate(document)

            for element in matching:
                # if element.tag in ('div',):
                # add styles for all matching DOM elements

                if element not in view:
                    # add initial empty style declatation
                    view[element] = cssutils.css.CSSStyleDeclaration()
                    specificities[element] = {}

                for p in rule.style:
                    # update style declaration
                    if p not in view[element]:
                        # setProperty needs a new Property object and
                        # MUST NOT reuse the existing Property
                        # which would be the same for all elements!
                        # see Issue #23
                        view[element].setProperty(p.name, p.value, p.priority)
                        specificities[element][p.name] = selector.specificity

                    else:
                        sameprio = (
                            p.priority == view[element].getPropertyPriority(
                                p.name))
                        if not sameprio and bool(p.priority) or (
                                sameprio and selector.specificity >=
                                specificities[element][p.name]):
                            # later, more specific or higher prio
                            view[element].setProperty(p.name, p.value,
                                                      p.priority)
    return view
Beispiel #6
0
    def getView(self, document, sheet, media='all', name=None, styleCallback=None):
        """
        document
            a DOM document, currently an lxml HTML document
        sheet
            a CSS StyleSheet object, currently cssutils sheet
        media: optional
            TODO: view for which media it should be
        name: optional
            TODO: names of sheets only
        styleCallback: optional
            should return css.CSSStyleDeclaration of inline styles, for html
            a style declaration for ``element@style``. Gets one parameter
            ``element`` which is the relevant DOMElement

        returns style view
            a dict of {DOMElement: css.CSSStyleDeclaration} for html
        """

        styleCallback = styleCallback or self.styleattribute

        _unmergable_rules = CSSStyleSheet()

        view = {}
        specificities = {}  # needed temporarily

        # TODO: filter rules simpler?, add @media
        rules = (rule for rule in sheet if rule.type == rule.STYLE_RULE)
        for rule in rules:
            for selector in rule.selectorList:
                self.log(0, 'SELECTOR', selector.selectorText)
                # TODO: make this a callback to be able to use other stuff than lxml
                try:
                    cssselector = CSSSelector(selector.selectorText)
                except (ExpressionError, NotImplementedError) as e:
                    _unmergable_rules.add(CSSStyleRule(selectorText=selector.selectorText,
                                                       style=rule.style))
                    continue

                matching = cssselector.evaluate(document)

                for element in matching:

                        if element.tag in self.NONVISUAL_TAGS:
                            continue

                        # add styles for all matching DOM elements
                        self.log(1, 'ELEMENT', id(element), element.text)

                        if element not in view:
                            # add initial empty style declatation
                            view[element] = CSSStyleDeclaration()
                            specificities[element] = {}

                            # and add inline @style if present
                            inlinestyle = styleCallback(element)
                            if inlinestyle:
                                for p in inlinestyle:
                                    # set inline style specificity
                                    view[element].setProperty(p)
                                    specificities[element][p.name] = (1, 0, 0, 0)

                        for p in rule.style:
                            # update style declaration
                            if p not in view[element]:
                                # setProperty needs a new Property object and
                                # MUST NOT reuse the existing Property
                                # which would be the same for all elements!
                                # see Issue #23
                                view[element].setProperty(p.name, p.value, p.priority)
                                specificities[element][p.name] = selector.specificity
                                self.log(2, view[element].getProperty('color'))

                            else:
                                self.log(2, view[element].getProperty('color'))
                                sameprio = (p.priority ==
                                            view[element].getPropertyPriority(p.name))
                                if not sameprio and bool(p.priority) or (
                                   sameprio and selector.specificity >=
                                        specificities[element][p.name]):
                                    # later, more specific or higher prio
                                    view[element].setProperty(p.name, p.value, p.priority)

        _unmergable_css = _unmergable_rules.cssText
        if _unmergable_css:
            e = etree.Element('style')
            # print __name__, _unmergable_css.__repr__()
            e.text = to_unicode(_unmergable_css, 'utf-8')
            body = document.find('body') or document
            body.insert(0, e)  # add <style> right into body

        return view
Beispiel #7
0
    document = etree.HTML(html)
    e = etree.Element('pre', {'class': 'cssutils'})
    e.text = css
    document.find('body').append(e)

    sheet = cssutils.parseString(css)

    view = {}
    specificities = {} # temporarily needed
    # TODO: filter rules simpler?, add @media
    rules = (rule for rule in sheet.cssRules if rule.type == rule.STYLE_RULE)

    for rule in rules:
        for selector in rule.selectorList:
            cssselector = CSSSelector(selector.selectorText)
            elements = cssselector.evaluate(document)
            for element in elements:
                # add styles for all matching DOM elements
                if element not in view:
                    # add initial
                    view[element] = cssutils.css.CSSStyleDeclaration()
                    specificities[element] = {}

                for p in rule.style:
                    # update styles
                    if p not in view[element]:
                        view[element].setProperty(p)
                        specificities[element][p.name] = selector.specificity
                    else:
                        sameprio = (p.priority ==
                                    view[element].getPropertyPriority(p.name))
Beispiel #8
0
def getView(document, css):
	"""
	document
		a DOM document, currently an lxml HTML document
	css
		a CSS StyleSheet string
	
	returns style view
		a dict of {DOMElement: css.CSSStyleDeclaration} for html
	"""
	from lxml.cssselect import CSSSelector
	sheet = cssutils.parseString(css)
	
	view = {}
	specificities = {} # needed temporarily 

	# TODO: filter rules simpler?, add @media
	rules = (rule for rule in sheet if rule.type == rule.STYLE_RULE)	
	for rule in rules:
		for selector in rule.selectorList:
			#log(0, 'SELECTOR', selector.selectorText)
			# TODO: make this a callback to be able to use other stuff than lxml
			try:
				cssselector = CSSSelector(selector.selectorText)
			except:
				continue
			matching = cssselector.evaluate(document)
			
			for element in matching:
				#if element.tag in ('div',):
					# add styles for all matching DOM elements
					#log(1, 'ELEMENT', id(element), element.text)
					
					if element not in view:	
						# add initial empty style declatation
						view[element] = cssutils.css.CSSStyleDeclaration() # @UndefinedVariable
						specificities[element] = {}					
															
					for p in rule.style:
						# update style declaration
						if p not in view[element]:
							# setProperty needs a new Property object and
							# MUST NOT reuse the existing Property
							# which would be the same for all elements!
							# see Issue #23
							view[element].setProperty(p.name, p.value, p.priority)
							specificities[element][p.name] = selector.specificity
							#log(2, view[element].getProperty('color'))
							
						else:
							#log(2, view[element].getProperty('color'))
							sameprio = (p.priority == 
										view[element].getPropertyPriority(p.name))
							if not sameprio and bool(p.priority) or (
							   sameprio and selector.specificity >= 
											specificities[element][p.name]):
								# later, more specific or higher prio 
								view[element].setProperty(p.name, p.value, p.priority)
					

	return view
def getView(document, css, media='all', name=None, 
            styleCallback=lambda element: None):
    """
    document
        a DOM document, currently an lxml HTML document
    css
        a CSS StyleSheet string
    media: optional
        TODO: view for which media it should be
    name: optional
        TODO: names of sheets only
    styleCallback: optional
        should return css.CSSStyleDeclaration of inline styles, for html
        a style declaration for ``element@style``. Gets one parameter 
        ``element`` which is the relevant DOMElement
    
    returns style view
        a dict of {DOMElement: css.CSSStyleDeclaration} for html
    """
    sheet = cssutils.parseString(css)
    
    view = {}
    specificities = {} # needed temporarily 

    # TODO: filter rules simpler?, add @media
    rules = (rule for rule in sheet if rule.type == rule.STYLE_RULE)    
    for rule in rules:
        for selector in rule.selectorList:
            log(0, 'SELECTOR', selector.selectorText)
            # TODO: make this a callback to be able to use other stuff than lxml
            cssselector = CSSSelector(selector.selectorText)
            matching = cssselector.evaluate(document)
            for element in matching:
                #if element.tag in ('div',):
                    # add styles for all matching DOM elements
                    log(1, 'ELEMENT', id(element), element.text)
                    
                    if element not in view:    
                        # add initial empty style declatation
                        view[element] = cssutils.css.CSSStyleDeclaration()
                        specificities[element] = {}                    
                        
                        # and add inline @style if present
                        inlinestyle = styleCallback(element)
                        if inlinestyle:
                            for p in inlinestyle:
                                # set inline style specificity
                                view[element].setProperty(p)
                                specificities[element][p.name] = (1,0,0,0)
                                                            
                    for p in rule.style:
                        # update style declaration
                        if p not in view[element]:
                            # setProperty needs a new Property object and
                            # MUST NOT reuse the existing Property
                            # which would be the same for all elements!
                            # see Issue #23
                            view[element].setProperty(p.name, p.value, p.priority)
                            specificities[element][p.name] = selector.specificity
                            log(2, view[element].getProperty('color'))
                            
                        else:
                            log(2, view[element].getProperty('color'))
                            sameprio = (p.priority == 
                                        view[element].getPropertyPriority(p.name))
                            if not sameprio and bool(p.priority) or (
                               sameprio and selector.specificity >= 
                                            specificities[element][p.name]):
                                # later, more specific or higher prio 
                                view[element].setProperty(p.name, p.value, p.priority)
                    
                   
    #pprint(view)
    return view