
    BPchU              
       ,   d Z ddlZddlmZ ddlmZmZmZmZ ddl	m
Z
 ddlmZ ddlmZmZmZ dd	lmZ erdd
lmZ  G d de          Z G d deeeeeef         f                   Z G d de          Z G d de          Z G d de          ZdS )z0
Functions for handling styles and embedded css
    N)OrderedDict)MutableMappingUnionIterableTYPE_CHECKING   )IBaseElement)Color)BaseStyleValueall_propertiesShorthandValueConditionalRule)SvgDocumentElementc                   T     e Zd ZdZd
 fd	Zd Zd Z fdZ fdZ fdZ	d	 Z
 xZS )Classesz<A list of classes applied to an element (used in css and js)Nc                     d | _         t          |t                    r|                                }t	                                          |pd           || _         d S )N )callback
isinstancestrsplitsuper__init__)selfclassesr   	__class__s      ./usr/share/inkscape/extensions/inkex/styles.pyr   zClasses.__init__*   sP    gs## 	&mmooGB'''     c                 ,    d                     |           S )N joinr   s    r   __str__zClasses.__str__1   s    xx~~r   c                 B    | j         |                      |            d S d S Nr   r$   s    r   	_callbackzClasses._callback4   *    =$MM$ %$r   c                 t    t                                          ||           |                                  d S r'   )r   __setitem__r)   )r   indexvaluer   s      r   r,   zClasses.__setitem__8   s3    E5)))r   c                     t          |          }|| vr7t                                          |           |                                  d S d S r'   )r   r   appendr)   r   r.   r   s     r   r0   zClasses.append<   sM    E

GGNN5!!!NN r   c                     t          |          }|| v r7t                                          |           |                                  d S d S r'   )r   r   remover)   r1   s     r   r3   zClasses.removeB   sJ    E

D==GGNN5!!!NN =r   c                 |    t          |          }|| v r|                     |          S |                     |          S )z$If exists, remove it, if not, add it)r   r3   r0   )r   r.   s     r   togglezClasses.toggleH   s:    E

D==;;u%%%{{5!!!r   NN)__name__
__module____qualname____doc__r   r%   r)   r,   r0   r3   r5   __classcell__r   s   @r   r   r   '   s        FF! ! ! ! ! !                   " " " " " " "r   r   c                   z    e Zd ZdZdZdZdZ	 ddddZ	 d- fd
	Ze	d.de
dee         fd            Ze	d.de
fd            Zd Zd/dZd Zd Zd Zd Zd Z fdZd Zd Zd Z fdZ fdZd Zd.dZ fdZd. fd 	Zd! Z  fd"Z!d0 fd$	Z" fd%Z#d1d'Z$d1d(Z%d) Z&d* Z'e(d+             Z)e(d,             Z* xZ+S )2Stylea  A list of style directives

    .. versionchanged:: 1.2
        The Style API now allows for access to parsed / processed styles via the
        :func:`call` method.

    .. automethod:: __call__
    .. automethod:: __getitem__
    .. automethod:: __setitem__
    )strokefill
stop-colorzflood-colorzlighting-color)stroke-opacityfill-opacityopacitystop-opacityzstroke-widthrC   rB   rE   )r@   r?   rA   Nc                    || _         d | _        pd |                                D             t          t                    r|                               t          t                    r0t          t                    sfdt                    D             t                      
                               || _        d S )Nc                 D    g | ]\  }}|                     d d          |fS )_-)replace).0kvs      r   
<listcomp>z"Style.__init__.<locals>.<listcomp>r   s/    JJJtq!199S#..2JJJr   c                 $    g | ]}||         fS r   r   )rK   namestyles     r   rN   z"Style.__init__.<locals>.<listcomp>w   s"    CCCTdE$K(CCCr   )elementr   itemsr   r   
_parse_strdictr   sortedr   r   )r   rQ   r   rR   kwr   s    `   r   r   zStyle.__init__m   s    JJJrxxzzJJJeS!! 	+OOE**EeT"" 	D:e[+I+I 	DCCCCVE]]CCCE r   rQ   returnc              #      K   |                      d          D ]4}d|v r.t          j        ||                                          }||V  5dS )a  Create a dictionary from the value of a CSS rule (such as an inline style or
        from an embedded style sheet), including its !important state, parsing the value
        if possible.

        Args:
            style: the content of a CSS rule to parse
            element: the element this style is working on (can be the root SVG, is used
                for parsing gradients etc.)

        Yields:
            :class:`~inkex.properties.BaseStyleValue`: the parsed attribute
        ;:)declarationN)r   r   factory_errorhandledstrip)rQ   rR   r\   results       r   rT   zStyle._parse_str}   sr       !;;s++ 	! 	!Kk!!'<):):)<)<   % LLL	! 	!r   c                 $    t          | |          S )zParse a style passed as stringrR   )r>   )rQ   rR   s     r   	parse_strzStyle.parse_str   s     UG,,,,r   c                 *    |                                  S )z2Format an inline style attribute from a dictionary)to_strr$   s    r   r%   zStyle.__str__   s    {{}}r   rZ   c                 F     |                      fd D                       S )z*Convert to string using a custom delimiterc                 D    g | ]}                     |          j        S r   )	get_storer\   )rK   keyr   s     r   rN   z Style.to_str.<locals>.<listcomp>   s(    IIIS,,8IIIr   r"   )r   seps   ` r   rd   zStyle.to_str   s*    xxIIIIDIIIJJJr   c                 r    |                                  }|                    t          |                     |S )z6Add two styles together to get a third, composing them)copyupdater>   r   otherrets      r   __add__zStyle.__add__   s,    iikk

5<<   
r   c                 0    |                      |           | S )z;Add style to this style, the same as ``style.update(dict)``)rl   r   rn   s     r   __iadd__zStyle.__iadd__   s    Er   c                 X    |                                  }|                    |           |S )zRemove keys and return copy)rk   __isub__rm   s      r   __sub__zStyle.__sub__   s&    iikkU
r   c                 <    |D ]}|                      |d           | S )zCRemove keys from this style, list of keys or other style dictionaryN)popr   rn   rh   s      r   ru   zStyle.__isub__   s-     	  	 CHHS$r   c                 .    |                      |           S r'   )__eq__rr   s     r   __ne__zStyle.__ne__   s    ;;u%%%%r   c                     t          i | j                  }t                                                      D ]
\  }}|||<   |S )z:Create a copy of the style.

        .. versionadded:: 1.2ra   )r>   rR   r   rS   )r   ro   rh   r.   r   s       r   rk   z
Style.copy   sH     B---''--// 	 	JCCHH
r   c                 f   t          |t                    st          |          }t          |t                    rY|                                D ]D}|                     |          r|                    |          r|                    |          | |<   E| j        |                     |            dS dS )z5Update, while respecting ``!important`` declarations.N)r   r>   keysget_importancerg   r   ry   s      r   rl   zStyle.update   s    %'' 	!%LLEeU## 	5zz|| 5 5++C00 59M9Mc9R9R 5 % 4 4DI=$MM$ %$r   c                    |                                  }|                                 t          |t                    s|S |                                D ]}d}|t
          v r[t
          |         d         rH||vrd}nA|                     |          |                    |          k    r|                    |          }||v r||         dk    rd}|r||         ||<   |S )af  Creates a new Style containing all parent styles with importance "!important"
        and current styles with importance "!important"

        .. versionadded:: 1.2

        Args:
            parent: the parent style that will be merged into this one (will not be
                altered)

        Returns:
            Style: the merged Style object
        F   Tinherit)rk   apply_shorthandsr   r>   r   r   r   )r   parentro   rh   applys        r   add_inheritedzStyle.add_inherited   s     iikk65)) 	J;;== 	' 	'CEn$$)<Q)?$ c>> EE((--1F1Fs1K1KKK"11#66Eczzc#h)33 '!#;C
r   c                     t          |                                           D ],}t          |t                    r|                    |            -dS )z#Apply all shorthands in this style.N)listvaluesr   r   apply_shorthand)r   rR   s     r   r   zStyle.apply_shorthands   sR    DKKMM** 	. 	.G'>22 .''---	. 	.r   c                     t                                          |           | j        |                     |            d S d S r'   )r   __delitem__r   r   rh   r   s     r   r   zStyle.__delitem__   sC    C   =$MM$ %$r   c                 L   t          |t                    r|1t          j        ||          }|                    | j                  }n||j        k    rt          d          t                                          ||           | j	        | 	                    |            dS dS )a  Sets a style value.

        .. versionchanged:: 1.2
            ``value`` can now also be non-string objects such as a Gradient.

        Args:
            key (str): the attribute name
            value (Any):

                - a :class:`BaseStyleValue`
                - a string with the value
                - any other object. The :class:`~inkex.properties.BaseStyleValue`
                  subclass of the provided key will attempt to create a string out of
                  the passed value.
        Raises:
            ValueError: when ``value`` is a :class:`~inkex.properties.BaseStyleValue`
                for a different attribute than `key`
            Error: Other exceptions may be raised when converting non-string objects.N	attr_namer.   zYou're trying to save a value into a style attribute, but the
                provided key is different from the attribute name given in the value)
r   r   factoryparse_valuerR   r   
ValueErrorr   r,   r   )r   rh   r.   rH   r   s       r   r,   zStyle.__setitem__   s    & %00 		EM"*SFFFE!!$,//AAEO##X   	C'''=$MM$ %$r   c                 6    |                      |          j        S )zReturns the unparsed value of the element (minus a possible ``!important``)

        .. versionchanged:: 1.2
            ``!important`` is removed from the value.
        )rg   r.   )r   rh   s     r   __getitem__zStyle.__getitem__  s     ~~c""((r   c                 8    || v r|                      |          S |S r'   )r   )r   rh   defaults      r   getz	Style.get&  s$    $;;##C(((r   c                 F    t                                          |          S )a  Gets the :class:`~inkex.properties.BaseStyleValue` of this key, since the
        other interfaces - :func:`__getitem__` and :func:`__call__` - return the
        original and parsed value, respectively.

        .. versionadded:: 1.2

        Args:
            key (str): the attribute name

        Returns:
            BaseStyleValue: the BaseStyleValue struct of this attribute
        )r   r   r   s     r   rg   zStyle.get_store+  s     ww""3'''r   c                    | }t                                                      D ]?}t          |t                    r(|                                 }|                                 @||v r/|                    |                              |p| j                  S |t          v r;t          j        |t          |         d                   }|                                S t          d          )zReturn the parsed value of a style. Optionally, an element can be passed
        that will be used to find gradient definitions ect.

        .. versionadded:: 1.2r   r   zUnknown attribute)r   r   r   r   rk   r   rg   r   rR   r   r   r   KeyError)r   rh   rR   rk   r.   defvaluer   s         r   __call__zStyle.__call__:  s     WW^^%% 	( 	(E%00 (yy{{%%'''$;;>>#&&2273JdlKKK.  %-^C%8%;  H $$&& *+++r   c                 H   t          |t                    st          |          }|                                 |                                k    rdS t          |           t          |          z  D ]1}|                     |          |                    |          k    r dS 2dS )NFT)r   r>   r   setrg   )r   rn   args      r   r{   zStyle.__eq__Q  s    %'' 	!%LLE99;;%**,,&&5t99s5zz) 	 	C~~c""eooc&:&:::uu ;tr   c              #   n   K   t                                                      D ]\  }}||j        fV  dS )z8The styles's parsed items

        .. versionadded:: 1.2N)r   rS   r.   )r   rh   r.   r   s      r   rS   zStyle.items[  sH        ''--// 	# 	#JCu{"""""	# 	#r   Fc                 \    || v r&t                                          |          j        S |S )zgReturns whether the declaration with ``key`` is marked as ``!important``

        .. versionadded:: 1.2)r   r   	important)r   rh   r   r   s      r   r   zStyle.get_importanceb  s.     $;;77&&s++55r   c                     || v r'|t                                          |          _        nt                      | j        |                     |            dS dS )z^Sets the ``!important`` state of a declaration with key ``key``

        .. versionadded:: 1.2N)r   r   r   r   r   )r   rh   
importancer   s      r   set_importancezStyle.set_importancej  s]     $;;1;EGG$$..**=$MM$ %$r   r@   c                     t          |                     |d                    }|                    |                     |dz   d                    S )z-Get the color AND opacity as one Color objectnonez-opacityg      ?)r
   r   to_rgba)r   rP   colors      r   	get_colorzStyle.get_coloru  sB    dhhtV,,--}}TXXdZ&7==>>>r   c                     t          |          }|j        dk    rA|t          j        v r3|j        | t          j        |         <   |                                | |<   dS || |<   dS )zXSets the given color AND opacity as rgba to the fill or stroke style
        properties.rgbaN)r
   spacer>   associated_propsalphato_rgb)r   r   rP   s      r   	set_colorzStyle.set_colorz  s_     e;&  TU-C%C%C16D'-.DJJJDJJJr   c                 `    |                                  D ]\  }}|d| dk    r	d| d| |<   dS )z8Find urls in this style and replace them with the new idzurl(#)N)rS   )r   old_idnew_idrP   r.   s        r   update_urlszStyle.update_urls  sS    !ZZ\\ 	/ 	/MT5)))))).V...T
	/ 	/r   c                     ddl m} ddlm} | j         |t          |                     | _        |j         |t          |                    |_         || j        |j                                      |          S )z:Interpolate all properties.

        .. versionadded:: 1.1r   )StyleInterpolatorr   )PathElementN)rQ   )tweenr   inkex.elementsr   rR   r   interpolate)r   rn   fractionr   r   s        r   r   zStyle.interpolate  s    
 	-,,,,,......<&;SYY777DL= 'Kc%jj999EM  u}==II(SSSr   c                    t          |j        j                            |                                                    }|                    |                                dg           |                    |j        t          d          ddfg           t          |d           }|d         d         
                                }|dd         D ]\  }}|                    |           ||_        |S )a  Returns the cascaded style of an element (all rules that apply the element
        itself), based on the stylesheets, the presentation attributes and the inline
        style using the respective specificity of the style

        see https://www.w3.org/TR/CSS22/cascade.html#cascading-order

        .. versionadded:: 1.2

        Args:
            element (BaseElement): the element that the cascaded style will be
                computed for

        Returns:
            Style: the cascaded style
        )r   r   r   infr   c                     | d         S )Nr   r   )items    r   <lambda>z&Style.cascaded_style.<locals>.<lambda>  s
    a r   )rh   r   N)r   rootstylesheetslookup_specificityget_idr0   presentation_stylerQ   floatrV   rk   rl   rR   )clsrR   stylesr_   rQ   rH   s         r   cascaded_stylezStyle.cascaded_style  s    " gl.AA'..BRBRSSTT 	w1133Y?@@@ 	w}uU||Q&:;<<< $8$89991""$$qrr
 	! 	!HE1MM%     r   c                     t                               |          }|                                }|Bt          |t                    r-t                               ||                                          }||_        |S )as  Returns the specified style of an element, i.e. the cascaded style +
        inheritance, see https://www.w3.org/TR/CSS22/cascade.html#specified-value

        .. versionadded:: 1.2

        Args:
            element (BaseElement): the element that the specified style will be computed
                for

        Returns:
            Style: the specified style
        )r>   r   	getparentr   r	   r   specified_stylerR   )r   rR   cascadedr   s       r   r   zStyle.specified_style  sk    " ''00""$$*V\"B"B**8V5K5K5M5MNNH"r   )NNNr'   )rZ   )F)r@   ),r7   r8   r9   r:   color_propsopacity_props
unit_propsr   r   staticmethodr   r   r   rT   rb   r%   rd   rp   rs   rv   ru   r|   rk   rl   r   r   r   r,   r   r   rg   r   r{   rS   r   r   r   r   r   r   classmethodr   r   r;   r<   s   @r   r>   r>   P   s       	 	 TKQMJ
 "$ 

! ! ! ! ! !  ! !# !0H ! ! ! \!* - - - - - \-  K K K K    
    & & &              D. . .         
         B) ) )   
( ( ( ( (, , , , , ,.  # # # # #     	  	  	  	  	 ? ? ? ?
   / / /T T T     [ D   [    r   r>   c                   4     e Zd ZdZd fd	ZddZddZ xZS )StyleSheetsa   
    Special mechanism which contains all the stylesheets for an svg document
    while also caching lookups for specific elements.

    This caching is needed because data can't be attached to elements as they are
    re-created on the fly by lxml so lookups have to be centralised.
    Nc                 V    t                                                       || _        d S r'   )r   r   svg)r   r   r   s     r   r   zStyleSheets.__init__  s$    r   c              #   b   K   || j         }| D ] }|                    ||          D ]}|V  !dS )z3
        Find all styles for this element.
        Nr   )r   lookupr   
element_idr   sheetrQ   s        r   r   zStyleSheets.lookup  s\       ;(C 	 	Ejc::  	 	r   c              #   b   K   || j         }| D ] }|                    ||          D ]}|V  !dS )zz
        Find all styles for this element and return the specificity of the match.

        .. versionadded:: 1.2
        Nr   )r   r   r   s        r   r   zStyleSheets.lookup_specificity  s_       ;(C 	 	E11*#1FF  	 	r   r'   )r7   r8   r9   r:   r   r   r   r;   r<   s   @r   r   r     so              
 
 
 
       r   r   c                   n     e Zd ZdZ ej        d          Zd fd	Zd ZddZ	d Z
 fdZd	 Zd
 Z xZS )
StyleSheetz
    A style sheet, usually the CDATA contents of a style tag, but also
    a css file used with a css. Will yield multiple Style() classes.
    z(\/\/.*?\n)|(\/\*.*?\*\/)|@.*;Nc                     t                                                       d | _        | j                            d|pd          }|                    d          D ]}|r|                     |           || _        d S )N })r   r   r   comment_stripsubr   r0   )r   contentr   blockr   s       r   r   zStyleSheet.__init__  s}    $((gm==]]3'' 	# 	#E #E""" r   c                 L    dd                     d | D                       z   dz   S )N
c                 ,    g | ]}t          |          S r   r   )rK   rQ   s     r   rN   z&StyleSheet.__str__.<locals>.<listcomp>  s     > > >U > > >r   r"   r$   s    r   r%   zStyleSheet.__str__  s-    dii > > > > >???$FFr   c                 B    | j         |                      |            d S d S r'   r(   )r   rQ   s     r   r)   zStyleSheet._callback  r*   r   c                 t    |                      t          |t          |          | j                             dS )z0Append a rule and style combo to this stylesheetrulesrQ   r   N)r0   ConditionalStyler   r)   )r   rulerQ   s      r   addzStyleSheet.add  s<    4s5zzDNSSS	
 	
 	
 	
 	
r   c                    t          |t                    rd|vrdS |                    d                              dd          \  }}|                                                    d          rdS t          ||                                | j                  }t                                          |           |                                  dS )z*Make sure callback is called when updating{Nr   r   @r   )	r   r   r^   r   
startswithr   r)   r   r0   )r   rn   r   rQ   r   s       r   r0   zStyleSheet.append  s    eS!! 	% ;;s++11#q99LE5{{}}'',, $5;;==4>  E 	ur   c              #      K   | D ]J}|                     |                                          D ] }|                    dd          |k    r|V  !KdS )z:Lookup the element_id against all the styles in this sheetidN)xpathto_xpathr   )r   r   r   rQ   elems        r   r   zStyleSheet.lookup,  sl       	  	 E		%.."2"233    88D$'':55KKK 	  	 r   c              #      K   | D ]t}t          |                                |                                          D ]=\  }}|                    |          D ]"}|                    dd          |k    r||fV  #>udS )a  Lookup the element_id against all the styles in this sheet
        and return the specificity of the match

        Args:
            element_id (str): the id of the element that styles are being queried for
            svg (SvgDocumentElement): The document that contains both element and the
                styles

        Yields:
            Tuple[ConditionalStyle, Tuple[int, int, int]]: all matched styles and the
            specificity of the match
        r   N)zip	to_xpathsget_specificitiesr   r   )r   r   r   rQ   r   specr   s          r   r   zStyleSheet.lookup_specificity3  s        	, 	,E!%//"3"3U5L5L5N5NOO , ,
dIIdOO , ,Dxxd++z99$dm+++,,	, 	,r   r6   r'   )r7   r8   r9   r:   recompiler   r   r%   r)   r   r0   r   r   r;   r<   s   @r   r   r     s         
 BJ@AAM	! 	! 	! 	! 	! 	!G G G       
 
 
         , , , , , , ,r   r   c                   <     e Zd ZdZd	 fd	Zd Zd Zd Zd Z xZ	S )
r   z
    Just like a Style object, but includes one or more
    conditional rules which places this style in a stylesheet
    rather than being an attribute style.
    *Nc                      t                      j        d||d| d |                    d          D             | _        d S )N)rQ   r   c                 ,    g | ]}t          |          S r   r   rK   r   s     r   rN   z-ConditionalStyle.__init__.<locals>.<listcomp>P  s     IIIod++IIIr   ,r   )r   r   r   r   )r   r   rQ   r   kwargsr   s        r   r   zConditionalStyle.__init__N  sL    BuxBB6BBBIIC8H8HIII


r   c                     |                      d          }d                    d | j        D                       }|r| d| dS | dS )z+Return this style as a css entry with classz;
  z,
c              3   4   K   | ]}t          |          V  d S r'   r   r
  s     r   	<genexpr>z+ConditionalStyle.__str__.<locals>.<genexpr>U  s(      <<3t99<<<<<<r   z {
  z;
}z {})rd   r#   r   )r   r   r   s      r   r%   zConditionalStyle.__str__R  s`    ++g&&

<<<<<<< 	322G2222r   c                 P    d                     |                                           S )zConvert all rules to an xpath|)r#   r  r$   s    r   r   zConditionalStyle.to_xpathZ  s      xx(()))r   c                 $    d | j         D             S )z[Gets a list of xpaths for all rules of this ConditionalStyle

        .. versionadded:: 1.2c                 6    g | ]}|                                 S r   )r   r
  s     r   rN   z.ConditionalStyle.to_xpaths.<locals>.<listcomp>f  s     777D777r   )r   r$   s    r   r  zConditionalStyle.to_xpathsb  s     87DJ7777r   c              #   J   K   | j         D ]}|                                V  dS )zhGets an iterator of the specificity of all rules in this ConditionalStyle

        .. versionadded:: 1.2N)r   get_specificity)r   r   s     r   r  z"ConditionalStyle.get_specificitiesh  s>       J 	) 	)D&&((((((	) 	)r   )r  NN)
r7   r8   r9   r:   r   r%   r   r  r  r;   r<   s   @r   r   r   G  s         J J J J J J  * * *8 8 8) ) ) ) ) ) )r   r   )r:   r  collectionsr   typingr   r   r   r   interfaces.IElementr	   colorsr
   
propertiesr   r   r   cssr   elements._svgr   r   r   r   r>   r   r   r   r   r   r   <module>r     s  *  
			 # # # # # # A A A A A A A A A A A A - - - - - -       F F F F F F F F F F             2111111&" &" &" &" &"d &" &" &"RC C C C CKU33F-G(GH C C CL% % % % %$ % % %PF, F, F, F, F, F, F, F,R&) &) &) &) &)u &) &) &) &) &)r   