7575import urllib .parse
7676import xml .dom
7777import itertools
78+ import functools
7879
7980from . import errorhandler
8081from . import css
@@ -197,10 +198,6 @@ def setSerializer(serializer):
197198
198199def _style_declarations (base ):
199200 "recursive generator to find all CSSStyleDeclarations"
200- if isinstance (base , css .CSSStyleDeclaration ):
201- # base is a style already
202- yield base
203- return
204201 for rule in getattr (base , 'cssRules' , ()):
205202 yield from _style_declarations (rule )
206203 if hasattr (base , 'style' ):
@@ -223,41 +220,65 @@ def getUrls(sheet):
223220 other = (
224221 value .uri
225222 for style in _style_declarations (sheet )
223+ for value in _uri_values (style )
224+ )
225+
226+ return itertools .chain (imports , other )
227+
228+
229+ def _uri_values (style ):
230+ return (
231+ value
226232 for prop in style .getProperties (all = True )
227233 for value in prop .propertyValue
228234 if value .type == 'URI'
229235 )
230236
231- return itertools .chain (imports , other )
232237
238+ _flatten = itertools .chain .from_iterable
233239
234- def replaceUrls (sheetOrStyle , replacer , ignoreImportRules = False ):
240+
241+ @functools .singledispatch
242+ def replaceUrls (sheet , replacer , ignoreImportRules = False ):
235243 """Replace all URLs in :class:`cssutils.css.CSSImportRule` or
236- :class:`cssutils.css.CSSValue` objects of given `sheetOrStyle `.
244+ :class:`cssutils.css.CSSValue` objects of given `sheet `.
237245
238- :param sheetOrStyle:
239- a :class:`cssutils.css.CSSStyleSheet` or a
240- :class:`cssutils.css.CSSStyleDeclaration` which is changed in place
246+ :param sheet:
247+ a :class:`cssutils.css.CSSStyleSheet` to be modified in place.
241248 :param replacer:
242249 a function which is called with a single argument `url` which
243250 is the current value of each url() excluding ``url(``, ``)`` and
244251 surrounding (single or double) quotes.
245252 :param ignoreImportRules:
246253 if ``True`` does not call `replacer` with URLs from @import rules.
247254 """
248- if not ignoreImportRules and not isinstance (sheetOrStyle , css .CSSStyleDeclaration ):
249- imports = (rule for rule in sheetOrStyle if rule .type == rule .IMPORT_RULE )
250- for rule in imports :
251- rule .href = replacer (rule .href )
252-
253- values = (
254- value
255- for style in _style_declarations (sheetOrStyle )
256- for prop in style .getProperties (all = True )
257- for value in prop .propertyValue
258- if value .type == 'URI'
255+ imports = (
256+ rule
257+ for rule in sheet
258+ if rule .type == rule .IMPORT_RULE and not ignoreImportRules
259259 )
260- for value in values :
260+ for rule in imports :
261+ rule .href = replacer (rule .href )
262+
263+ for value in _flatten (map (_uri_values , _style_declarations (sheet ))):
264+ value .uri = replacer (value .uri )
265+
266+
267+ @replaceUrls .register (css .CSSStyleDeclaration )
268+ def _ (style , replacer , ignoreImportRules = False ):
269+ """Replace all URLs in :class:`cssutils.css.CSSImportRule` or
270+ :class:`cssutils.css.CSSValue` objects of given `style`.
271+
272+ :param style:
273+ a :class:`cssutils.css.CSSStyleDeclaration` to be modified in place.
274+ :param replacer:
275+ a function which is called with a single argument `url` which
276+ is the current value of each url() excluding ``url(``, ``)`` and
277+ surrounding (single or double) quotes.
278+ :param ignoreImportRules:
279+ not applicable, ignored.
280+ """
281+ for value in _uri_values (style ):
261282 value .uri = replacer (value .uri )
262283
263284
0 commit comments