KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > css > engine > CSSEngine


1 /*
2
3    Copyright 2002-2004 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16
17  */

18 package org.apache.batik.css.engine;
19
20 import java.io.IOException JavaDoc;
21 import java.io.StringReader JavaDoc;
22 import java.net.MalformedURLException JavaDoc;
23 import java.net.URL JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Collections JavaDoc;
26 import java.util.HashSet JavaDoc;
27 import java.util.LinkedList JavaDoc;
28 import java.util.List JavaDoc;
29 import java.util.Set JavaDoc;
30
31 import org.apache.batik.css.engine.sac.CSSConditionFactory;
32 import org.apache.batik.css.engine.sac.CSSSelectorFactory;
33 import org.apache.batik.css.engine.sac.ExtendedSelector;
34 import org.apache.batik.css.engine.value.ComputedValue;
35 import org.apache.batik.css.engine.value.InheritValue;
36 import org.apache.batik.css.engine.value.ShorthandManager;
37 import org.apache.batik.css.engine.value.Value;
38 import org.apache.batik.css.engine.value.ValueManager;
39 import org.apache.batik.css.parser.ExtendedParser;
40 import org.apache.batik.util.CSSConstants;
41 import org.apache.batik.util.ParsedURL;
42 import org.w3c.css.sac.CSSException;
43 import org.w3c.css.sac.DocumentHandler;
44 import org.w3c.css.sac.InputSource;
45 import org.w3c.css.sac.LexicalUnit;
46 import org.w3c.css.sac.SACMediaList;
47 import org.w3c.css.sac.SelectorList;
48 import org.w3c.dom.DOMException JavaDoc;
49 import org.w3c.dom.Document JavaDoc;
50 import org.w3c.dom.Element JavaDoc;
51 import org.w3c.dom.NamedNodeMap JavaDoc;
52 import org.w3c.dom.Node JavaDoc;
53 import org.w3c.dom.events.Event JavaDoc;
54 import org.w3c.dom.events.EventListener JavaDoc;
55 import org.w3c.dom.events.EventTarget JavaDoc;
56 import org.w3c.dom.events.MutationEvent JavaDoc;
57
58 /**
59  * This is the base class for all the CSS engines.
60  *
61  * @author <a HREF="mailto:stephane@hillion.org">Stephane Hillion</a>
62  * @version $Id: CSSEngine.java,v 1.42 2004/12/03 12:20:15 deweese Exp $
63  */

64 public abstract class CSSEngine {
65
66     /**
67      * List of StyleMap objects, one for each @font-face rule
68      * encountered by this CSSEngine.
69      */

70     protected List JavaDoc fontFaces = new LinkedList JavaDoc();
71
72     /**
73      * Get's the StyleMaps generated by @font-face rules
74      * encountered by this CSSEngine thus far.
75      */

76     public List JavaDoc getFontFaces() { return fontFaces; }
77
78     CSSEngineUserAgent userAgent = null;
79
80     /**
81      * Returns the next stylable parent of the given element.
82      */

83     public static CSSStylableElement getParentCSSStylableElement(Element JavaDoc elt) {
84         Element JavaDoc e = getParentElement(elt);
85         while (e != null) {
86             if (e instanceof CSSStylableElement) {
87                 return (CSSStylableElement)e;
88             }
89             e = getParentElement(e);
90         }
91         return null;
92     }
93
94     /**
95      * Returns the next parent element of the given element, from the
96      * CSS point of view.
97      */

98     public static Element JavaDoc getParentElement(Element JavaDoc elt) {
99         Node JavaDoc n = elt.getParentNode();
100         while (n != null) {
101             n = getLogicalParentNode(n);
102             if (n.getNodeType() == Node.ELEMENT_NODE) {
103                 return (Element JavaDoc)n;
104             }
105             n = n.getParentNode();
106         }
107         return null;
108     }
109
110     /**
111      * Returns the logical parent of a node, given its physical parent.
112      */

113     public static Node JavaDoc getLogicalParentNode(Node JavaDoc parent) {
114         Node JavaDoc node = parent;
115         if (node != null) {
116             if (node instanceof CSSImportedElementRoot) {
117                 return ((CSSImportedElementRoot)node).getCSSParentElement();
118             } else {
119                 return node;
120             }
121         }
122         return null;
123     }
124
125     /**
126      * Returns the imported child of the given node, if any.
127      */

128     public static CSSImportedElementRoot getImportedChild(Node JavaDoc node) {
129         if (node instanceof CSSImportNode) {
130             CSSImportNode inode = (CSSImportNode)node;
131             CSSImportedElementRoot r = inode.getCSSImportedElementRoot();
132             return r;
133         }
134         return null;
135     }
136
137     /**
138      * The CSS context.
139      */

140     protected CSSContext cssContext;
141     
142     /**
143      * The associated document.
144      */

145     protected Document JavaDoc document;
146
147     /**
148      * The document URI.
149      */

150     protected URL JavaDoc documentURI;
151
152     /**
153      * The property/int mappings.
154      */

155     protected StringIntMap indexes;
156
157     /**
158      * The shorthand-property/int mappings.
159      */

160     protected StringIntMap shorthandIndexes;
161
162     /**
163      * The value managers.
164      */

165     protected ValueManager[] valueManagers;
166
167     /**
168      * The shorthand managers.
169      */

170     protected ShorthandManager[] shorthandManagers;
171
172     /**
173      * The CSS parser.
174      */

175     protected ExtendedParser parser;
176
177     /**
178      * The pseudo-element names.
179      */

180     protected String JavaDoc[] pseudoElementNames;
181
182     /**
183      * The font-size property index.
184      */

185     protected int fontSizeIndex = -1;
186
187     /**
188      * The line-height property index.
189      */

190     protected int lineHeightIndex = -1;
191
192     /**
193      * The color property index.
194      */

195     protected int colorIndex = -1;
196
197     /**
198      * The user-agent style-sheet.
199      */

200     protected StyleSheet userAgentStyleSheet;
201
202     /**
203      * The user style-sheet.
204      */

205     protected StyleSheet userStyleSheet;
206
207     /**
208      * The media to use to cascade properties.
209      */

210     protected SACMediaList media;
211
212     /**
213      * The DOM nodes which contains StyleSheets.
214      */

215     protected List JavaDoc styleSheetNodes;
216
217     /**
218      * The style attribute namespace URI.
219      */

220     protected String JavaDoc styleNamespaceURI;
221
222     /**
223      * The style attribute local name.
224      */

225     protected String JavaDoc styleLocalName;
226     
227     /**
228      * The class attribute namespace URI.
229      */

230     protected String JavaDoc classNamespaceURI;
231
232     /**
233      * The class attribute local name.
234      */

235     protected String JavaDoc classLocalName;
236     
237     /**
238      * The non CSS presentational hints.
239      */

240     protected Set JavaDoc nonCSSPresentationalHints;
241
242     /**
243      * The non CSS presentational hints namespace URI.
244      */

245     protected String JavaDoc nonCSSPresentationalHintsNamespaceURI;
246
247     /**
248      * The style declaration document handler.
249      */

250     protected StyleDeclarationDocumentHandler styleDeclarationDocumentHandler =
251         new StyleDeclarationDocumentHandler();
252
253     /**
254      * The style declaration update handler.
255      */

256     protected StyleDeclarationUpdateHandler styleDeclarationUpdateHandler;
257
258     /**
259      * The style sheet document handler.
260      */

261     protected StyleSheetDocumentHandler styleSheetDocumentHandler =
262         new StyleSheetDocumentHandler();
263
264     /**
265      * The style declaration document handler used to build a
266      * StyleDeclaration object.
267      */

268     protected StyleDeclarationBuilder styleDeclarationBuilder =
269         new StyleDeclarationBuilder();
270
271     /**
272      * The current element.
273      */

274     protected CSSStylableElement element;
275
276     /**
277      * The current base URI.
278      */

279     protected URL JavaDoc cssBaseURI;
280
281     /**
282      * The alternate stylesheet title.
283      */

284     protected String JavaDoc alternateStyleSheet;
285
286     /**
287      * The DOMAttrModified event listener.
288      */

289     protected EventListener JavaDoc domAttrModifiedListener;
290
291     /**
292      * The DOMNodeInserted event listener.
293      */

294     protected EventListener JavaDoc domNodeInsertedListener;
295
296     /**
297      * The DOMNodeRemoved event listener.
298      */

299     protected EventListener JavaDoc domNodeRemovedListener;
300
301     /**
302      * The DOMSubtreeModified event listener.
303      */

304     protected EventListener JavaDoc domSubtreeModifiedListener;
305
306     /**
307      * The DOMCharacterDataModified event listener.
308      */

309     protected EventListener JavaDoc domCharacterDataModifiedListener;
310
311     /**
312      * Whether a style sheet as been removed from the document.
313      */

314     protected boolean styleSheetRemoved;
315
316     /**
317      * The right sibling of the last removed node.
318      */

319     protected Node JavaDoc removedStylableElementSibling;
320
321     /**
322      * The listeners.
323      */

324     protected List JavaDoc listeners = Collections.synchronizedList(new LinkedList JavaDoc());
325
326     /**
327      * The attributes found in stylesheets selectors.
328      */

329     protected Set JavaDoc selectorAttributes;
330
331     /**
332      * Used to fire a change event for all the properties.
333      */

334     protected final int[] ALL_PROPERTIES;
335
336     /**
337      * The CSS condition factory.
338      */

339     protected CSSConditionFactory cssConditionFactory;
340
341     /**
342      * Creates a new CSSEngine.
343      * @param doc The associated document.
344      * @param uri The document URI.
345      * @param p The CSS parser.
346      * @param vm The property value managers.
347      * @param sm The shorthand properties managers.
348      * @param pe The pseudo-element names supported by the associated
349      * XML dialect. Must be null if no support for pseudo-
350      * elements is required.
351      * @param sns The namespace URI of the style attribute.
352      * @param sln The local name of the style attribute.
353      * @param cns The namespace URI of the class attribute.
354      * @param cln The local name of the class attribute.
355      * @param hints Whether the CSS engine should support non CSS
356      * presentational hints.
357      * @param hintsNS The hints namespace URI.
358      * @param ctx The CSS context.
359      */

360     protected CSSEngine(Document JavaDoc doc,
361                         URL JavaDoc uri,
362                         ExtendedParser p,
363                         ValueManager[] vm,
364                         ShorthandManager[] sm,
365                         String JavaDoc[] pe,
366                         String JavaDoc sns,
367                         String JavaDoc sln,
368                         String JavaDoc cns,
369                         String JavaDoc cln,
370                         boolean hints,
371                         String JavaDoc hintsNS,
372                         CSSContext ctx) {
373         document = doc;
374         documentURI = uri;
375         parser = p;
376         pseudoElementNames = pe;
377         styleNamespaceURI = sns;
378         styleLocalName = sln;
379         classNamespaceURI = cns;
380         classLocalName = cln;
381         cssContext = ctx;
382
383         cssConditionFactory = new CSSConditionFactory(cns, cln, null, "id");
384
385         int len = vm.length;
386         indexes = new StringIntMap(len);
387         valueManagers = vm;
388
389         for (int i = len - 1; i >= 0; --i) {
390             String JavaDoc pn = vm[i].getPropertyName();
391             indexes.put(pn, i);
392             if (fontSizeIndex == -1 &&
393                 pn.equals(CSSConstants.CSS_FONT_SIZE_PROPERTY)) {
394                 fontSizeIndex = i;
395             }
396             if (lineHeightIndex == -1 &&
397                 pn.equals(CSSConstants.CSS_LINE_HEIGHT_PROPERTY)) {
398                 lineHeightIndex = i;
399             }
400             if (colorIndex == -1 &&
401                 pn.equals(CSSConstants.CSS_COLOR_PROPERTY)) {
402                 colorIndex = i;
403             }
404         }
405
406         len = sm.length;
407         shorthandIndexes = new StringIntMap(len);
408         shorthandManagers = sm;
409         for (int i = len - 1; i >= 0; --i) {
410             shorthandIndexes.put(sm[i].getPropertyName(), i);
411         }
412
413         if (hints) {
414             nonCSSPresentationalHints = new HashSet JavaDoc(vm.length+sm.length);
415             nonCSSPresentationalHintsNamespaceURI = hintsNS;
416             len = vm.length;
417             for (int i = 0; i < len; i++) {
418                 String JavaDoc pn = vm[i].getPropertyName();
419                 nonCSSPresentationalHints.add(pn);
420             }
421             len = sm.length;
422             for (int i = 0; i < len; i++) {
423                 String JavaDoc pn = sm[i].getPropertyName();
424                 nonCSSPresentationalHints.add(pn);
425             }
426         }
427
428         if (cssContext.isDynamic() &&
429             (document instanceof EventTarget JavaDoc)) {
430             // Attach the mutation events listeners.
431
EventTarget JavaDoc et = (EventTarget JavaDoc)document;
432             domAttrModifiedListener = new DOMAttrModifiedListener();
433             et.addEventListener("DOMAttrModified",
434                                 domAttrModifiedListener,
435                                 false);
436             domNodeInsertedListener = new DOMNodeInsertedListener();
437             et.addEventListener("DOMNodeInserted",
438                                 domNodeInsertedListener,
439                                 false);
440             domNodeRemovedListener = new DOMNodeRemovedListener();
441             et.addEventListener("DOMNodeRemoved",
442                                 domNodeRemovedListener,
443                                 false);
444             domSubtreeModifiedListener = new DOMSubtreeModifiedListener();
445             et.addEventListener("DOMSubtreeModified",
446                                 domSubtreeModifiedListener,
447                                 false);
448             domCharacterDataModifiedListener =
449                 new DOMCharacterDataModifiedListener();
450             et.addEventListener("DOMCharacterDataModified",
451                                 domCharacterDataModifiedListener,
452                                 false);
453             styleDeclarationUpdateHandler =
454                 new StyleDeclarationUpdateHandler();
455         }
456
457         ALL_PROPERTIES = new int[getNumberOfProperties()];
458         for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
459             ALL_PROPERTIES[i] = i;
460         }
461     }
462
463     /**
464      * Disposes the CSSEngine and all the attached resources.
465      */

466     public void dispose() {
467         setCSSEngineUserAgent(null);
468         disposeStyleMaps(document.getDocumentElement());
469         if (document instanceof EventTarget JavaDoc) {
470             // Detach the mutation events listeners.
471
EventTarget JavaDoc et = (EventTarget JavaDoc)document;
472             et.removeEventListener("DOMAttrModified",
473                                    domAttrModifiedListener,
474                                    false);
475             et.removeEventListener("DOMNodeInserted",
476                                    domNodeInsertedListener,
477                                    false);
478             et.removeEventListener("DOMNodeRemoved",
479                                    domNodeRemovedListener,
480                                    false);
481             et.removeEventListener("DOMSubtreeModified",
482                                    domSubtreeModifiedListener,
483                                    false);
484             et.removeEventListener("DOMCharacterDataModified",
485                                    domCharacterDataModifiedListener,
486                                    false);
487         }
488     }
489
490     private void disposeStyleMaps(Node JavaDoc node) {
491         if (node instanceof CSSStylableElement) {
492             ((CSSStylableElement)node).setComputedStyleMap(null, null);
493         }
494         for (Node JavaDoc n = node.getFirstChild();
495              n != null;
496              n = n.getNextSibling()) {
497             if (n.getNodeType() == Node.ELEMENT_NODE) {
498                 disposeStyleMaps(n);
499             }
500             Node JavaDoc c = getImportedChild(n);
501             if (c != null) {
502                 disposeStyleMaps(c);
503             }
504         }
505     }
506
507     /**
508      * Returns the CSS context.
509      */

510     public CSSContext getCSSContext() {
511         return cssContext;
512     }
513
514     /**
515      * Returns the document associated with this engine.
516      */

517     public Document JavaDoc getDocument() {
518         return document;
519     }
520
521     /**
522      * Returns the font-size property index.
523      */

524     public int getFontSizeIndex() {
525         return fontSizeIndex;
526     }
527
528     /**
529      * Returns the line-height property index.
530      */

531     public int getLineHeightIndex() {
532         return lineHeightIndex;
533     }
534
535     /**
536      * Returns the color property index.
537      */

538     public int getColorIndex() {
539         return colorIndex;
540     }
541
542     /**
543      * Returns the number of properties.
544      */

545     public int getNumberOfProperties() {
546         return valueManagers.length;
547     }
548
549     /**
550      * Returns the property index, or -1.
551      */

552     public int getPropertyIndex(String JavaDoc name) {
553         return indexes.get(name);
554     }
555
556     /**
557      * Returns the shorthand property index, or -1.
558      */

559     public int getShorthandIndex(String JavaDoc name) {
560         return shorthandIndexes.get(name);
561     }
562
563     /**
564      * Returns the name of the property at the given index.
565      */

566     public String JavaDoc getPropertyName(int idx) {
567         return valueManagers[idx].getPropertyName();
568     }
569
570     public void setCSSEngineUserAgent(CSSEngineUserAgent userAgent) {
571         this.userAgent = userAgent;
572     }
573
574     public CSSEngineUserAgent getCSSEngineUserAgent() {
575         return userAgent;
576     }
577
578     /**
579      * Sets the user agent style-sheet.
580      */

581     public void setUserAgentStyleSheet(StyleSheet ss) {
582         userAgentStyleSheet = ss;
583     }
584
585     /**
586      * Sets the user style-sheet.
587      */

588     public void setUserStyleSheet(StyleSheet ss) {
589         userStyleSheet = ss;
590     }
591
592     /**
593      * Returns the ValueManagers.
594      */

595     public ValueManager[] getValueManagers() {
596         return valueManagers;
597     }
598
599     /**
600      * Sets the media to use to compute the styles.
601      */

602     public void setMedia(String JavaDoc str) {
603         try {
604             media = parser.parseMedia(str);
605         } catch (Exception JavaDoc e) {
606             String JavaDoc m = e.getMessage();
607             if (m == null) m = "";
608             String JavaDoc s =Messages.formatMessage
609                 ("media.error", new Object JavaDoc[] { str, m });
610             throw new DOMException JavaDoc(DOMException.SYNTAX_ERR, s);
611         }
612     }
613
614     /**
615      * Sets the alternate style-sheet title.
616      */

617     public void setAlternateStyleSheet(String JavaDoc str) {
618         alternateStyleSheet = str;
619     }
620
621     /**
622      * Recursively imports the cascaded style from a source element
623      * to an element of the current document.
624      */

625     public void importCascadedStyleMaps(Element JavaDoc src,
626                                         CSSEngine srceng,
627                                         Element JavaDoc dest) {
628         if (src instanceof CSSStylableElement) {
629             CSSStylableElement csrc = (CSSStylableElement)src;
630             CSSStylableElement cdest = (CSSStylableElement)dest;
631
632             StyleMap sm = srceng.getCascadedStyleMap(csrc, null);
633             sm.setFixedCascadedStyle(true);
634             cdest.setComputedStyleMap(null, sm);
635
636             if (pseudoElementNames != null) {
637                 int len = pseudoElementNames.length;
638                 for (int i = 0; i < len; i++) {
639                     String JavaDoc pe = pseudoElementNames[i];
640                     sm = srceng.getCascadedStyleMap(csrc, pe);
641                     cdest.setComputedStyleMap(pe, sm);
642                 }
643             }
644         }
645
646         for (Node JavaDoc dn = dest.getFirstChild(), sn = src.getFirstChild();
647              dn != null;
648              dn = dn.getNextSibling(), sn = sn.getNextSibling()) {
649             if (sn.getNodeType() == Node.ELEMENT_NODE) {
650                 importCascadedStyleMaps((Element JavaDoc)sn, srceng, (Element JavaDoc)dn);
651             }
652         }
653     }
654
655     /**
656      * Returns the current base-url.
657      */

658     public URL JavaDoc getCSSBaseURI() {
659         if (cssBaseURI == null) {
660             cssBaseURI = element.getCSSBase();
661         }
662         return cssBaseURI;
663     }
664
665     /**
666      * Returns the cascaded style of the given element/pseudo-element.
667      * @param elt The stylable element.
668      * @param pseudo Optional pseudo-element string (null if none).
669      */

670     public StyleMap getCascadedStyleMap(CSSStylableElement elt,
671                                         String JavaDoc pseudo) {
672         int props = getNumberOfProperties();
673         final StyleMap result = new StyleMap(props);
674
675         // Apply the user-agent style-sheet to the result.
676
if (userAgentStyleSheet != null) {
677             List JavaDoc rules = new ArrayList JavaDoc();
678             addMatchingRules(rules, userAgentStyleSheet, elt, pseudo);
679             addRules(elt, pseudo, result, rules, StyleMap.USER_AGENT_ORIGIN);
680         }
681
682         // Apply the user properties style-sheet to the result.
683
if (userStyleSheet != null) {
684             List JavaDoc rules = new ArrayList JavaDoc();
685             addMatchingRules(rules, userStyleSheet, elt, pseudo);
686             addRules(elt, pseudo, result, rules, StyleMap.USER_ORIGIN);
687         }
688
689         element = elt;
690         try {
691             // Apply the non-CSS presentational hints to the result.
692
ShorthandManager.PropertyHandler ph =
693                 new ShorthandManager.PropertyHandler() {
694                     public void property(String JavaDoc pname, LexicalUnit lu,
695                                          boolean important) {
696                         int idx = getPropertyIndex(pname);
697                         if (idx != -1) {
698                             ValueManager vm = valueManagers[idx];
699                             Value v = vm.createValue(lu, CSSEngine.this);
700                             putAuthorProperty(result, idx, v, important,
701                                               StyleMap.NON_CSS_ORIGIN);
702                             return;
703                         }
704                         idx = getShorthandIndex(pname);
705                         if (idx == -1)
706                             return; // Unknown property...
707
// Shorthand value
708
shorthandManagers[idx].setValues
709                             (CSSEngine.this, this, lu, important);
710                     }
711                 };
712
713             if (nonCSSPresentationalHints != null) {
714                 NamedNodeMap JavaDoc attrs = elt.getAttributes();
715                 int len = attrs.getLength();
716                 for (int i = 0; i < len; i++) {
717                     Node JavaDoc attr = attrs.item(i);
718                     String JavaDoc an = attr.getNodeName();
719                     if (nonCSSPresentationalHints.contains(an)) {
720                         try {
721                             LexicalUnit lu;
722                             lu = parser.parsePropertyValue(attr.getNodeValue());
723                             ph.property(an, lu, false);
724                         } catch (Exception JavaDoc e) {
725                             String JavaDoc m = e.getMessage();
726                             if (m == null) m = "";
727                             String JavaDoc u = ((documentURI == null)?"<unknown>":
728                                         documentURI.toString());
729                             String JavaDoc s = Messages.formatMessage
730                                 ("property.syntax.error.at",
731                                  new Object JavaDoc[] { u, an, attr.getNodeValue(),m});
732                             DOMException JavaDoc de = new DOMException JavaDoc(DOMException.SYNTAX_ERR, s);
733                             if (userAgent == null) throw de;
734                             userAgent.displayError(de);
735                         }
736                     }
737                 }
738             }
739
740             // Apply the document style-sheets to the result.
741
List JavaDoc snodes = getStyleSheetNodes();
742             int slen = snodes.size();
743             if (slen > 0) {
744                 List JavaDoc rules = new ArrayList JavaDoc();
745                 for (int i = 0; i < slen; i++) {
746                     CSSStyleSheetNode ssn = (CSSStyleSheetNode)snodes.get(i);
747                     StyleSheet ss = ssn.getCSSStyleSheet();
748                     if (ss != null &&
749                         (!ss.isAlternate() ||
750                          ss.getTitle() == null ||
751                          ss.getTitle().equals(alternateStyleSheet)) &&
752                         mediaMatch(ss.getMedia())) {
753                         addMatchingRules(rules, ss, elt, pseudo);
754                     }
755                 }
756                 addRules(elt, pseudo, result, rules, StyleMap.AUTHOR_ORIGIN);
757             }
758
759             // Apply the inline style to the result.
760
if (styleLocalName != null) {
761                 String JavaDoc style = elt.getAttributeNS(styleNamespaceURI,
762                                                   styleLocalName);
763                 if (style.length() > 0) {
764                     try {
765                         parser.setSelectorFactory(CSSSelectorFactory.INSTANCE);
766                         parser.setConditionFactory(cssConditionFactory);
767                         styleDeclarationDocumentHandler.styleMap = result;
768                         parser.setDocumentHandler
769                             (styleDeclarationDocumentHandler);
770                         parser.parseStyleDeclaration(style);
771                         styleDeclarationDocumentHandler.styleMap = null;
772                     } catch (Exception JavaDoc e) {
773                &