You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-commits@xmlgraphics.apache.org by ca...@apache.org on 2005/09/13 15:31:09 UTC
svn commit: r280553 [6/9] - in /xmlgraphics/batik/trunk: ./
resources/org/apache/batik/apps/svgbrowser/resources/
sources/org/apache/batik/bridge/ sources/org/apache/batik/bridge/svg12/
sources/org/apache/batik/css/engine/ sources/org/apache/batik/dom/...
Added: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/XPathSubsetContentSelector.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/XPathSubsetContentSelector.java?rev=280553&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/XPathSubsetContentSelector.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/XPathSubsetContentSelector.java Tue Sep 13 06:29:29 2005
@@ -0,0 +1,513 @@
+/*
+
+ Copyright 2005 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+package org.apache.batik.bridge.svg12;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import org.apache.batik.dom.svg12.XBLOMContentElement;
+import org.apache.batik.parser.AbstractScanner;
+import org.apache.batik.parser.ParseException;
+import org.apache.batik.xml.XMLUtilities;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * A class to handle the XPath subset syntax for XBL content elements.
+ *
+ * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
+ * @version $Id$
+ */
+public class XPathSubsetContentSelector extends AbstractContentSelector {
+
+ protected static final int SELECTOR_INVALID = -1;
+ protected static final int SELECTOR_ANY = 0;
+ protected static final int SELECTOR_QNAME = 1;
+ protected static final int SELECTOR_ID = 2;
+
+ /**
+ * The type of XPath subset expression.
+ */
+ protected int selectorType;
+
+ /**
+ * The QName prefix used for selection.
+ */
+ protected String prefix;
+
+ /**
+ * The local name or ID used for selection.
+ */
+ protected String localName;
+
+ /**
+ * The index for selection. 0 means select all elements that match.
+ */
+ protected int index;
+
+ /**
+ * The selected nodes.
+ */
+ protected SelectedNodes selectedContent;
+
+ /**
+ * Creates a new XPathSubsetContentSelector object.
+ */
+ public XPathSubsetContentSelector(ContentManager cm,
+ XBLOMContentElement content,
+ Element bound,
+ String selector) {
+ super(cm, content, bound);
+ parseSelector(selector);
+ }
+
+ /**
+ * Parses the selector string.
+ */
+ protected void parseSelector(String selector) {
+ selectorType = SELECTOR_INVALID;
+ Scanner scanner = new Scanner(selector);
+ int token = scanner.next();
+ if (token == Scanner.NAME) {
+ String name1 = scanner.getStringValue();
+ token = scanner.next();
+ if (token == Scanner.EOF) {
+ selectorType = SELECTOR_QNAME;
+ prefix = null;
+ localName = name1;
+ index = 0;
+ return;
+ } else if (token == Scanner.COLON) {
+ token = scanner.next();
+ if (token == Scanner.NAME) {
+ String name2 = scanner.getStringValue();
+ token = scanner.next();
+ if (token == Scanner.EOF) {
+ selectorType = SELECTOR_QNAME;
+ prefix = name1;
+ localName = name2;
+ index = 0;
+ return;
+ } else if (token == Scanner.LEFT_SQUARE_BRACKET) {
+ token = scanner.next();
+ if (token == Scanner.NUMBER) {
+ int number = Integer.parseInt(scanner.getStringValue());
+ token = scanner.next();
+ if (token == Scanner.RIGHT_SQUARE_BRACKET) {
+ token = scanner.next();
+ if (token == Scanner.EOF) {
+ selectorType = SELECTOR_QNAME;
+ prefix = name1;
+ localName = name2;
+ index = number;
+ return;
+ }
+ }
+ }
+ }
+ } else if (token == Scanner.LEFT_SQUARE_BRACKET) {
+ token = scanner.next();
+ if (token == Scanner.NUMBER) {
+ int number = Integer.parseInt(scanner.getStringValue());
+ token = scanner.next();
+ if (token == Scanner.RIGHT_SQUARE_BRACKET) {
+ token = scanner.next();
+ if (token == Scanner.EOF) {
+ selectorType = SELECTOR_QNAME;
+ prefix = null;
+ localName = name1;
+ index = number;
+ return;
+ }
+ }
+ }
+ } else if (token == Scanner.LEFT_PARENTHESIS) {
+ if (name1.equals("id")) {
+ token = scanner.next();
+ if (token == Scanner.STRING) {
+ String id = scanner.getStringValue();
+ token = scanner.next();
+ if (token == Scanner.RIGHT_PARENTHESIS) {
+ token = scanner.next();
+ if (token == Scanner.EOF) {
+ selectorType = SELECTOR_ID;
+ localName = id;
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+ } else if (token == Scanner.ASTERISK) {
+ token = scanner.next();
+ if (token == Scanner.EOF) {
+ selectorType = SELECTOR_ANY;
+ return;
+ } else if (token == Scanner.LEFT_SQUARE_BRACKET) {
+ token = scanner.next();
+ if (token == Scanner.NUMBER) {
+ int number = Integer.parseInt(scanner.getStringValue());
+ token = scanner.next();
+ if (token == Scanner.RIGHT_SQUARE_BRACKET) {
+ token = scanner.next();
+ if (token == Scanner.EOF) {
+ selectorType = SELECTOR_ANY;
+ index = number;
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns a list of nodes that were matched by the given selector
+ * string.
+ */
+ public NodeList getSelectedContent() {
+ if (selectedContent == null) {
+ selectedContent = new SelectedNodes();
+ }
+ return selectedContent;
+ }
+
+ /**
+ * Forces this selector to update its selected nodes list.
+ * Returns true if the selected node list needed updating.
+ * This assumes that the previous content elements in this
+ * shadow tree (in document order) have up-to-date selectedContent
+ * lists.
+ */
+ boolean update() {
+ if (selectedContent == null) {
+ selectedContent = new SelectedNodes();
+ return true;
+ }
+ return selectedContent.update();
+ }
+
+ /**
+ * Implementation of NodeList that contains the nodes that matched
+ * this selector.
+ */
+ protected class SelectedNodes implements NodeList {
+
+ /**
+ * The selected nodes.
+ */
+ protected ArrayList nodes = new ArrayList(10);
+
+ /**
+ * Creates a new SelectedNodes object.
+ */
+ public SelectedNodes() {
+ update();
+ }
+
+ protected boolean update() {
+ ArrayList oldNodes = (ArrayList) nodes.clone();
+ nodes.clear();
+ int nth = 0;
+ for (Node n = boundElement.getFirstChild(); n != null; n = n.getNextSibling()) {
+ if (n.getNodeType() != Node.ELEMENT_NODE) {
+ continue;
+ }
+ Element e = (Element) n;
+ boolean matched = selectorType == SELECTOR_ANY;
+ switch (selectorType) {
+ case SELECTOR_ID:
+ matched = e.getAttributeNS(null, "id").equals(localName);
+ break;
+ case SELECTOR_QNAME:
+ if (prefix == null) {
+ matched = e.getNamespaceURI() == null;
+ } else {
+ String ns = contentElement.lookupNamespaceURI(prefix);
+ if (ns == null) {
+ // XXX throw invalid prefix exception
+ } else {
+ matched = e.getNamespaceURI().equals(ns);
+ }
+ }
+ matched = matched && localName.equals(e.getLocalName());
+ break;
+ }
+ if (selectorType == SELECTOR_ANY
+ || selectorType == SELECTOR_QNAME) {
+ matched = matched && (index == 0 || ++nth == index);
+ }
+ if (matched && !isSelected(n)) {
+ nodes.add(e);
+ }
+ }
+ int nodesSize = nodes.size();
+ if (oldNodes.size() != nodesSize) {
+ return true;
+ }
+ for (int i = 0; i < nodesSize; i++) {
+ if (oldNodes.get(i) != nodes.get(i)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * <b>DOM</b>: Implements {@link org.w3c.dom.NodeList#item(int)}.
+ */
+ public Node item(int index) {
+ if (index < 0 || index >= nodes.size()) {
+ return null;
+ }
+ return (Node) nodes.get(index);
+ }
+
+ /**
+ * <b>DOM</b>: Implements {@link org.w3c.dom.NodeList#getLength()}.
+ * @return {@link #children}.
+ */
+ public int getLength() {
+ return nodes.size();
+ }
+ }
+
+ /**
+ * A scanner for XPath subset selectors.
+ */
+ protected static class Scanner extends AbstractScanner {
+
+ public static final int EOF = 0;
+ public static final int NAME = 1;
+ public static final int COLON = 2;
+ public static final int LEFT_SQUARE_BRACKET = 3;
+ public static final int RIGHT_SQUARE_BRACKET = 4;
+ public static final int LEFT_PARENTHESIS = 5;
+ public static final int RIGHT_PARENTHESIS = 6;
+ public static final int STRING = 7;
+ public static final int NUMBER = 8;
+ public static final int ASTERISK = 9;
+
+ /**
+ * Creates a new Scanner object.
+ */
+ public Scanner(String s) {
+ super(s);
+ }
+
+ /**
+ * Returns the end gap of the current lexical unit.
+ */
+ protected int endGap() {
+ return (current == -1) ? 0 : 1;
+ }
+
+// public int next() {
+// int i = super.next();
+// System.err.print("\t\t");
+// switch (i) {
+// case EOF:
+// System.err.println("EOF");
+// break;
+// case NAME:
+// System.err.println("NAME " + getStringValue());
+// break;
+// case COLON:
+// System.err.println("COLON");
+// break;
+// case LEFT_SQUARE_BRACKET:
+// System.err.println("LEFT_SQUARE_BRACKET");
+// break;
+// case RIGHT_SQUARE_BRACKET:
+// System.err.println("RIGHT_SQUARE_BRACKET");
+// break;
+// case LEFT_PARENTHESIS:
+// System.err.println("LEFT_PARENTHESIS");
+// break;
+// case RIGHT_PARENTHESIS:
+// System.err.println("RIGHT_PARENTHESIS");
+// break;
+// case STRING:
+// System.err.println("STRING \"" + getStringValue() + "\"");
+// break;
+// case NUMBER:
+// System.err.println("NUMBER " + getStringValue());
+// break;
+// case ASTERISK:
+// System.err.println("ASTERISK");
+// break;
+// default:
+// System.err.println("?");
+// }
+// return i;
+// }
+
+ /**
+ * Returns the next token.
+ */
+ protected void nextToken() throws ParseException {
+ try {
+ switch (current) {
+ case -1:
+ type = EOF;
+ return;
+ case ':':
+ nextChar();
+ type = COLON;
+ return;
+ case '[':
+ nextChar();
+ type = LEFT_SQUARE_BRACKET;
+ return;
+ case ']':
+ nextChar();
+ type = RIGHT_SQUARE_BRACKET;
+ return;
+ case '(':
+ nextChar();
+ type = LEFT_PARENTHESIS;
+ return;
+ case ')':
+ nextChar();
+ type = RIGHT_PARENTHESIS;
+ return;
+ case '*':
+ nextChar();
+ type = ASTERISK;
+ return;
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ case '\f':
+ do {
+ nextChar();
+ } while (XMLUtilities.isXMLSpace((char) current));
+ nextToken();
+ return;
+ case '\'':
+ type = string1();
+ return;
+ case '"':
+ type = string2();
+ return;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ type = number();
+ return;
+ default:
+ if (XMLUtilities.isXMLNameFirstCharacter((char) current)) {
+ do {
+ nextChar();
+ } while (current != -1
+ && current != ':'
+ && XMLUtilities.isXMLNameCharacter((char) current));
+ type = NAME;
+ return;
+ }
+ nextChar();
+ throw new ParseException("identifier.character",
+ reader.getLine(),
+ reader.getColumn());
+ }
+ } catch (IOException e) {
+ throw new ParseException(e);
+ }
+ }
+
+ /**
+ * Scans a single quoted string.
+ */
+ protected int string1() throws IOException {
+ start = position;
+ loop: for (;;) {
+ switch (nextChar()) {
+ case -1:
+ throw new ParseException("eof",
+ reader.getLine(),
+ reader.getColumn());
+ case '\'':
+ break loop;
+ }
+ }
+ nextChar();
+ return STRING;
+ }
+
+ /**
+ * Scans a double quoted string.
+ */
+ protected int string2() throws IOException {
+ start = position;
+ loop: for (;;) {
+ switch (nextChar()) {
+ case -1:
+ throw new ParseException("eof",
+ reader.getLine(),
+ reader.getColumn());
+ case '"':
+ break loop;
+ }
+ }
+ nextChar();
+ return STRING;
+ }
+
+ /**
+ * Scans a number.
+ */
+ protected int number() throws IOException {
+ loop: for (;;) {
+ switch (nextChar()) {
+ case '.':
+ switch (nextChar()) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ return dotNumber();
+ }
+ throw new ParseException("character",
+ reader.getLine(),
+ reader.getColumn());
+ default:
+ break loop;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ }
+ }
+ return NUMBER;
+ }
+
+ /**
+ * Scans the decimal part of a number.
+ */
+ protected int dotNumber() throws IOException {
+ loop: for (;;) {
+ switch (nextChar()) {
+ default:
+ break loop;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ }
+ }
+ return NUMBER;
+ }
+ }
+}
Propchange: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/XPathSubsetContentSelector.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSEngine.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSEngine.java?rev=280553&r1=280552&r2=280553&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSEngine.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSEngine.java Tue Sep 13 06:29:29 2005
@@ -1,6 +1,6 @@
/*
- Copyright 2002-2004 The Apache Software Foundation
+ Copyright 2002-2005 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -45,6 +45,7 @@
import org.w3c.css.sac.LexicalUnit;
import org.w3c.css.sac.SACMediaList;
import org.w3c.css.sac.SelectorList;
+import org.w3c.dom.Attr;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -64,75 +65,63 @@
public abstract class CSSEngine {
/**
- * List of StyleMap objects, one for each @font-face rule
- * encountered by this CSSEngine.
+ * Returns the CSS parent node of the given node.
*/
- protected List fontFaces = new LinkedList();
+ public static Node getCSSParentNode(Node n) {
+ if (n instanceof CSSNavigableNode) {
+ return ((CSSNavigableNode) n).getCSSParentNode();
+ }
+ return n.getParentNode();
+ }
/**
- * Get's the StyleMaps generated by @font-face rules
- * encountered by this CSSEngine thus far.
+ * Returns the CSS first child node of the given node.
*/
- public List getFontFaces() { return fontFaces; }
-
- CSSEngineUserAgent userAgent = null;
+ protected static Node getCSSFirstChild(Node n) {
+ if (n instanceof CSSNavigableNode) {
+ return ((CSSNavigableNode) n).getCSSFirstChild();
+ }
+ return n.getFirstChild();
+ }
/**
- * Returns the next stylable parent of the given element.
+ * Returns the CSS next sibling node of the given node.
*/
- public static CSSStylableElement getParentCSSStylableElement(Element elt) {
- Element e = getParentElement(elt);
- while (e != null) {
- if (e instanceof CSSStylableElement) {
- return (CSSStylableElement)e;
- }
- e = getParentElement(e);
+ protected static Node getCSSNextSibling(Node n) {
+ if (n instanceof CSSNavigableNode) {
+ return ((CSSNavigableNode) n).getCSSNextSibling();
}
- return null;
+ return n.getNextSibling();
}
/**
- * Returns the next parent element of the given element, from the
- * CSS point of view.
+ * Returns the CSS previous sibling node of the given node.
*/
- public static Element getParentElement(Element elt) {
- Node n = elt.getParentNode();
- while (n != null) {
- n = getLogicalParentNode(n);
- if (n.getNodeType() == Node.ELEMENT_NODE) {
- return (Element)n;
- }
- n = n.getParentNode();
+ protected static Node getCSSPreviousSibling(Node n) {
+ if (n instanceof CSSNavigableNode) {
+ return ((CSSNavigableNode) n).getCSSPreviousSibling();
}
- return null;
+ return n.getPreviousSibling();
}
/**
- * Returns the logical parent of a node, given its physical parent.
+ * Returns the next stylable parent of the given element.
*/
- public static Node getLogicalParentNode(Node parent) {
- Node node = parent;
- if (node != null) {
- if (node instanceof CSSImportedElementRoot) {
- return ((CSSImportedElementRoot)node).getCSSParentElement();
- } else {
- return node;
+ public static CSSStylableElement getParentCSSStylableElement(Element elt) {
+ Node n = getCSSParentNode(elt);
+ while (n != null) {
+ if (n instanceof CSSStylableElement) {
+ return (CSSStylableElement) n;
}
+ n = getCSSParentNode(n);
}
return null;
}
/**
- * Returns the imported child of the given node, if any.
+ * The user agent used for showing error messages.
*/
- public static CSSImportedElementRoot getImportedChild(Node node) {
- if (node instanceof CSSImportNode) {
- CSSImportNode inode = (CSSImportNode)node;
- CSSImportedElementRoot r = inode.getCSSImportedElementRoot();
- return r;
- }
- return null;
- }
+ protected CSSEngineUserAgent userAgent;
/**
* The CSS context.
@@ -150,6 +139,11 @@
protected URL documentURI;
/**
+ * Whether the document is a CSSNavigableDocument.
+ */
+ protected boolean isCSSNavigableDocument;
+
+ /**
* The property/int mappings.
*/
protected StringIntMap indexes;
@@ -215,6 +209,12 @@
protected List styleSheetNodes;
/**
+ * List of StyleMap objects, one for each @font-face rule
+ * encountered by this CSSEngine.
+ */
+ protected List fontFaces = new LinkedList();
+
+ /**
* The style attribute namespace URI.
*/
protected String styleNamespaceURI;
@@ -284,6 +284,11 @@
protected String alternateStyleSheet;
/**
+ * Listener for CSSNavigableDocument events.
+ */
+ protected CSSNavigableDocumentHandler cssNavigableDocumentListener;
+
+ /**
* The DOMAttrModified event listener.
*/
protected EventListener domAttrModifiedListener;
@@ -380,6 +385,8 @@
classLocalName = cln;
cssContext = ctx;
+ isCSSNavigableDocument = doc instanceof CSSNavigableDocument;
+
cssConditionFactory = new CSSConditionFactory(cns, cln, null, "id");
int len = vm.length;
@@ -425,38 +432,76 @@
}
}
- if (cssContext.isDynamic() &&
- (document instanceof EventTarget)) {
+ if (cssContext.isDynamic() && document instanceof EventTarget) {
// Attach the mutation events listeners.
- EventTarget et = (EventTarget)document;
+ addEventListeners((EventTarget) document);
+ styleDeclarationUpdateHandler =
+ new StyleDeclarationUpdateHandler();
+ }
+
+ ALL_PROPERTIES = new int[getNumberOfProperties()];
+ for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
+ ALL_PROPERTIES[i] = i;
+ }
+ }
+
+ /**
+ * Adds event listeners to the document to track CSS changes.
+ */
+ protected void addEventListeners(EventTarget doc) {
+ if (isCSSNavigableDocument) {
+ cssNavigableDocumentListener = new CSSNavigableDocumentHandler();
+ CSSNavigableDocument cnd = (CSSNavigableDocument) doc;
+ cnd.addCSSNavigableDocumentListener(cssNavigableDocumentListener);
+ } else {
domAttrModifiedListener = new DOMAttrModifiedListener();
- et.addEventListener("DOMAttrModified",
- domAttrModifiedListener,
- false);
+ doc.addEventListener("DOMAttrModified",
+ domAttrModifiedListener,
+ false);
domNodeInsertedListener = new DOMNodeInsertedListener();
- et.addEventListener("DOMNodeInserted",
- domNodeInsertedListener,
- false);
+ doc.addEventListener("DOMNodeInserted",
+ domNodeInsertedListener,
+ false);
domNodeRemovedListener = new DOMNodeRemovedListener();
- et.addEventListener("DOMNodeRemoved",
- domNodeRemovedListener,
- false);
+ doc.addEventListener("DOMNodeRemoved",
+ domNodeRemovedListener,
+ false);
domSubtreeModifiedListener = new DOMSubtreeModifiedListener();
- et.addEventListener("DOMSubtreeModified",
- domSubtreeModifiedListener,
- false);
+ doc.addEventListener("DOMSubtreeModified",
+ domSubtreeModifiedListener,
+ false);
domCharacterDataModifiedListener =
new DOMCharacterDataModifiedListener();
- et.addEventListener("DOMCharacterDataModified",
- domCharacterDataModifiedListener,
- false);
- styleDeclarationUpdateHandler =
- new StyleDeclarationUpdateHandler();
+ doc.addEventListener("DOMCharacterDataModified",
+ domCharacterDataModifiedListener,
+ false);
}
+ }
- ALL_PROPERTIES = new int[getNumberOfProperties()];
- for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
- ALL_PROPERTIES[i] = i;
+ /**
+ * Removes the event listeners from the document.
+ */
+ protected void removeEventListeners(EventTarget doc) {
+ if (isCSSNavigableDocument) {
+ CSSNavigableDocument cnd = (CSSNavigableDocument) doc;
+ cnd.removeCSSNavigableDocumentListener
+ (cssNavigableDocumentListener);
+ } else {
+ doc.removeEventListener("DOMAttrModified",
+ domAttrModifiedListener,
+ false);
+ doc.removeEventListener("DOMNodeInserted",
+ domNodeInsertedListener,
+ false);
+ doc.removeEventListener("DOMNodeRemoved",
+ domNodeRemovedListener,
+ false);
+ doc.removeEventListener("DOMSubtreeModified",
+ domSubtreeModifiedListener,
+ false);
+ doc.removeEventListener("DOMCharacterDataModified",
+ domCharacterDataModifiedListener,
+ false);
}
}
@@ -468,39 +513,23 @@
disposeStyleMaps(document.getDocumentElement());
if (document instanceof EventTarget) {
// Detach the mutation events listeners.
- EventTarget et = (EventTarget)document;
- et.removeEventListener("DOMAttrModified",
- domAttrModifiedListener,
- false);
- et.removeEventListener("DOMNodeInserted",
- domNodeInsertedListener,
- false);
- et.removeEventListener("DOMNodeRemoved",
- domNodeRemovedListener,
- false);
- et.removeEventListener("DOMSubtreeModified",
- domSubtreeModifiedListener,
- false);
- et.removeEventListener("DOMCharacterDataModified",
- domCharacterDataModifiedListener,
- false);
+ removeEventListeners((EventTarget) document);
}
}
- private void disposeStyleMaps(Node node) {
+ /**
+ * Removes the style maps from each CSSStylableElement in the document.
+ */
+ protected void disposeStyleMaps(Node node) {
if (node instanceof CSSStylableElement) {
((CSSStylableElement)node).setComputedStyleMap(null, null);
}
- for (Node n = node.getFirstChild();
+ for (Node n = getCSSFirstChild(node);
n != null;
- n = n.getNextSibling()) {
+ n = getCSSNextSibling(n)) {
if (n.getNodeType() == Node.ELEMENT_NODE) {
disposeStyleMaps(n);
}
- Node c = getImportedChild(n);
- if (c != null) {
- disposeStyleMaps(c);
- }
}
}
@@ -597,6 +626,14 @@
}
/**
+ * Gets the StyleMaps generated by @font-face rules
+ * encountered by this CSSEngine thus far.
+ */
+ public List getFontFaces() {
+ return fontFaces;
+ }
+
+ /**
* Sets the media to use to compute the styles.
*/
public void setMedia(String str) {
@@ -643,9 +680,9 @@
}
}
- for (Node dn = dest.getFirstChild(), sn = src.getFirstChild();
+ for (Node dn = getCSSFirstChild(dest), sn = getCSSFirstChild(src);
dn != null;
- dn = dn.getNextSibling(), sn = sn.getNextSibling()) {
+ dn = getCSSNextSibling(dn), sn = getCSSNextSibling(sn)) {
if (sn.getNodeType() == Node.ELEMENT_NODE) {
importCascadedStyleMaps((Element)sn, srceng, (Element)dn);
}
@@ -689,28 +726,28 @@
element = elt;
try {
// Apply the non-CSS presentational hints to the result.
- ShorthandManager.PropertyHandler ph =
- new ShorthandManager.PropertyHandler() {
- public void property(String pname, LexicalUnit lu,
- boolean important) {
- int idx = getPropertyIndex(pname);
- if (idx != -1) {
- ValueManager vm = valueManagers[idx];
- Value v = vm.createValue(lu, CSSEngine.this);
- putAuthorProperty(result, idx, v, important,
- StyleMap.NON_CSS_ORIGIN);
- return;
+ if (nonCSSPresentationalHints != null) {
+ ShorthandManager.PropertyHandler ph =
+ new ShorthandManager.PropertyHandler() {
+ public void property(String pname, LexicalUnit lu,
+ boolean important) {
+ int idx = getPropertyIndex(pname);
+ if (idx != -1) {
+ ValueManager vm = valueManagers[idx];
+ Value v = vm.createValue(lu, CSSEngine.this);
+ putAuthorProperty(result, idx, v, important,
+ StyleMap.NON_CSS_ORIGIN);
+ return;
+ }
+ idx = getShorthandIndex(pname);
+ if (idx == -1)
+ return; // Unknown property...
+ // Shorthand value
+ shorthandManagers[idx].setValues
+ (CSSEngine.this, this, lu, important);
}
- idx = getShorthandIndex(pname);
- if (idx == -1)
- return; // Unknown property...
- // Shorthand value
- shorthandManagers[idx].setValues
- (CSSEngine.this, this, lu, important);
- }
- };
+ };
- if (nonCSSPresentationalHints != null) {
NamedNodeMap attrs = elt.getAttributes();
int len = attrs.getLength();
for (int i = 0; i < len; i++) {
@@ -738,7 +775,8 @@
}
// Apply the document style-sheets to the result.
- List snodes = getStyleSheetNodes();
+ CSSEngine eng = cssContext.getCSSEngineForElement(elt);
+ List snodes = eng.getStyleSheetNodes();
int slen = snodes.size();
if (slen > 0) {
List rules = new ArrayList();
@@ -872,9 +910,9 @@
if (n instanceof CSSStyleSheetNode) {
styleSheetNodes.add(n);
}
- for (Node nd = n.getFirstChild();
+ for (Node nd = getCSSFirstChild(n);
nd != null;
- nd = nd.getNextSibling()) {
+ nd = getCSSNextSibling(nd)) {
findStyleSheetNodes(nd);
}
}
@@ -1155,7 +1193,7 @@
URL uri) throws DOMException {
try {
parseStyleSheet(ss, new InputSource(new StringReader(rules)), uri);
- } catch (Exception e) {
+ } catch (Exception e) {
// e.printStackTrace();
String m = e.getMessage();
if (m == null) m = "";
@@ -1775,25 +1813,25 @@
*/
protected void inlineStyleAttributeUpdated(CSSStylableElement elt,
StyleMap style,
- MutationEvent evt) {
+ short attrChange,
+ String prevValue,
+ String newValue) {
boolean[] updated = styleDeclarationUpdateHandler.updatedProperties;
for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
updated[i] = false;
}
- switch (evt.getAttrChange()) {
+ switch (attrChange) {
case MutationEvent.ADDITION:
case MutationEvent.MODIFICATION:
- String decl = evt.getNewValue();
- // System.err.println("Inline Style Update: '" + decl + "'");
- if (decl.length() > 0) {
+ if (newValue.length() > 0) {
element = elt;
try {
parser.setSelectorFactory(CSSSelectorFactory.INSTANCE);
parser.setConditionFactory(cssConditionFactory);
styleDeclarationUpdateHandler.styleMap = style;
parser.setDocumentHandler(styleDeclarationUpdateHandler);
- parser.parseStyleDeclaration(decl);
+ parser.parseStyleDeclaration(newValue);
styleDeclarationUpdateHandler.styleMap = null;
} catch (Exception e) {
String m = e.getMessage();
@@ -1802,7 +1840,7 @@
documentURI.toString());
String s = Messages.formatMessage
("style.syntax.error.at",
- new Object[] { u, styleLocalName, decl, m });
+ new Object[] { u, styleLocalName, newValue, m });
DOMException de = new DOMException(DOMException.SYNTAX_ERR, s);
if (userAgent == null) throw de;
userAgent.displayError(de);
@@ -1816,8 +1854,7 @@
case MutationEvent.REMOVAL:
boolean removed = false;
- if (evt.getPrevValue() != null &&
- evt.getPrevValue().length() > 0) {
+ if (prevValue != null && prevValue.length() > 0) {
// Check if the style map has cascaded styles which
// come from the inline style attribute.
for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
@@ -1923,8 +1960,9 @@
int count =0;
if (!recascade) {
for (int i=0; i<diffs.length; i++) {
- if (diffs[i])
+ if (diffs[i]) {
count++;
+ }
}
} else {
StyleMap newStyle = getCascadedStyleMap(elt, null);
@@ -2058,22 +2096,13 @@
}
}
- CSSImportedElementRoot ier = getImportedChild(node);
- if (ier != null) {
- Element e = (Element)ier.getFirstChild();
- // Don't recascade trees that have been imported.
- // If you do it will use the stylesheets from this
- // document instead of the original document. Also
- // currently there isn't any supported way to modify
- // the content imported from the other document so
- // the cascade can't change.
- CSSEngine subEng = cssContext.getCSSEngineForElement(e);
- subEng.invalidateProperties(e, inherited, null, recascade);
- }
- for (Node n = node.getFirstChild();
+ for (Node n = getCSSFirstChild(node);
n != null;
- n = n.getNextSibling()) {
- invalidateProperties(n, inherited, null, recascade);
+ n = getCSSNextSibling(n)) {
+ if (n.getNodeType() == Node.ELEMENT_NODE) {
+ CSSEngine eng = cssContext.getCSSEngineForElement((Element) n);
+ invalidateProperties(n, inherited, null, recascade);
+ }
}
}
@@ -2127,8 +2156,8 @@
protected void nonCSSPresentationalHintUpdated(CSSStylableElement elt,
StyleMap style,
String property,
- MutationEvent evt) {
- // System.err.println("update: " + property);
+ short attrChange,
+ String newValue) {
int idx = getPropertyIndex(property);
if (style.isImportant(idx)) {
@@ -2144,13 +2173,13 @@
return;
}
- switch (evt.getAttrChange()) {
+ switch (attrChange) {
case MutationEvent.ADDITION:
case MutationEvent.MODIFICATION:
element = elt;
try {
LexicalUnit lu;
- lu = parser.parsePropertyValue(evt.getNewValue());
+ lu = parser.parsePropertyValue(newValue);
ValueManager vm = valueManagers[idx];
Value v = vm.createValue(lu, CSSEngine.this);
style.putMask(idx, (short)0);
@@ -2163,7 +2192,7 @@
documentURI.toString());
String s = Messages.formatMessage
("property.syntax.error.at",
- new Object[] { u, property, evt.getNewValue(), m });
+ new Object[] { u, property, newValue, m });
DOMException de = new DOMException(DOMException.SYNTAX_ERR, s);
if (userAgent == null) throw de;
userAgent.displayError(de);
@@ -2218,6 +2247,162 @@
}
/**
+ * Handles an attribute change in the document.
+ */
+ protected void handleAttrModified(Element e,
+ Attr attr,
+ short attrChange,
+ String prevValue,
+ String newValue) {
+ if (!(e instanceof CSSStylableElement)) {
+ // Not a stylable element.
+ return;
+ }
+
+ if (newValue.equals(prevValue)) {
+ return; // no change really...
+ }
+
+ String attrNS = attr.getNamespaceURI();
+ String name = ((attrNS == null) ?
+ attr.getNodeName() :
+ attr.getLocalName());
+
+ CSSStylableElement elt = (CSSStylableElement)e;
+ StyleMap style = elt.getComputedStyleMap(null);
+ if (style != null) {
+ if ((attrNS == styleNamespaceURI) ||
+ ((attrNS != null) && attrNS.equals(styleNamespaceURI))) {
+ if (name.equals(styleLocalName)) {
+ // The style declaration attribute has been modified.
+ inlineStyleAttributeUpdated
+ (elt, style, attrChange, prevValue, newValue);
+ return;
+ }
+ }
+
+ if (nonCSSPresentationalHints != null) {
+ if ((attrNS == nonCSSPresentationalHintsNamespaceURI) ||
+ ((attrNS != null) &&
+ attrNS.equals(nonCSSPresentationalHintsNamespaceURI))) {
+ if (nonCSSPresentationalHints.contains(name)) {
+ // The 'name' attribute which represents a non CSS
+ // presentational hint has been modified.
+ nonCSSPresentationalHintUpdated
+ (elt, style, name, attrChange, newValue);
+ return;
+ }
+ }
+ }
+ }
+
+ if (selectorAttributes != null &&
+ selectorAttributes.contains(name)) {
+ // An attribute has been modified, invalidate all the
+ // properties to correctly match attribute selectors.
+ invalidateProperties(elt, null, null, true);
+ for (Node n = getCSSNextSibling(elt);
+ n != null;
+ n = getCSSNextSibling(n)) {
+ invalidateProperties(n, null, null, true);
+ }
+ }
+ }
+
+ /**
+ * To handle mutations of a CSSNavigableDocument.
+ */
+ protected class CSSNavigableDocumentHandler
+ implements CSSNavigableDocumentListener {
+
+ /**
+ * A node has been inserted into the CSSNavigableDocument tree.
+ */
+ public void nodeInserted(Node newNode) {
+ if (newNode instanceof CSSStyleSheetNode) {
+ styleSheetNodes = null;
+ // Invalidate all the CSSStylableElements in the document.
+ invalidateProperties(document.getDocumentElement(),
+ null, null, true);
+ } else if (newNode instanceof CSSStylableElement) {
+ // Invalidate the CSSStylableElement siblings, to
+ // correctly match the adjacent selectors and
+ // first-child pseudo-class.
+ for (Node n = getCSSNextSibling(newNode);
+ n != null;
+ n = getCSSNextSibling(n)) {
+ invalidateProperties(n, null, null, true);
+ }
+ }
+ }
+
+ /**
+ * A node is about to be removed from the CSSNavigableDocument tree.
+ */
+ public void nodeToBeRemoved(Node oldNode) {
+ if (oldNode instanceof CSSStyleSheetNode) {
+ // Wait for the DOMSubtreeModified to do the invalidations
+ // because at this time the node is in the tree.
+ styleSheetRemoved = true;
+ } else if (oldNode instanceof CSSStylableElement) {
+ // Wait for the DOMSubtreeModified to do the invalidations
+ // because at this time the node is in the tree.
+ removedStylableElementSibling = getCSSNextSibling(oldNode);
+ }
+ // Clears the computed styles in the removed tree.
+ disposeStyleMaps(oldNode);
+ }
+
+ /**
+ * A subtree of the CSSNavigableDocument tree has been modified
+ * in some way.
+ */
+ public void subtreeModified(Node rootOfModifications) {
+ if (styleSheetRemoved) {
+ styleSheetRemoved = false;
+ styleSheetNodes = null;
+
+ // Invalidate all the CSSStylableElements in the document.
+ invalidateProperties(document.getDocumentElement(),
+ null, null, true);
+ } else if (removedStylableElementSibling != null) {
+ // Invalidate the CSSStylableElement siblings, to
+ // correctly match the adjacent selectors and
+ // first-child pseudo-class.
+ for (Node n = removedStylableElementSibling;
+ n != null;
+ n = getCSSNextSibling(n)) {
+ invalidateProperties(n, null, null, true);
+ }
+ removedStylableElementSibling = null;
+ }
+ }
+
+ /**
+ * Character data in the CSSNavigableDocument tree has been modified.
+ */
+ public void characterDataModified(Node text) {
+ if (getCSSParentNode(text) instanceof CSSStyleSheetNode) {
+ styleSheetNodes = null;
+ // Invalidate all the CSSStylableElements in the document.
+ invalidateProperties(document.getDocumentElement(),
+ null, null, true);
+ }
+ }
+
+ /**
+ * An attribute has changed in the CSSNavigableDocument.
+ */
+ public void attrModified(Element e,
+ Attr attr,
+ short attrChange,
+ String prevValue,
+ String newValue) {
+ handleAttrModified(e, attr, attrChange, prevValue, newValue);
+ }
+ }
+
+ /**
* To handle the insertion of a CSSStyleSheetNode in the
* associated document.
*/
@@ -2313,60 +2498,12 @@
*/
protected class DOMAttrModifiedListener implements EventListener {
public void handleEvent(Event evt) {
- EventTarget et = evt.getTarget();
- if (!(et instanceof CSSStylableElement)) {
- // Not a stylable element.
- return;
- }
-
- MutationEvent mevt = (MutationEvent)evt;
- if (mevt.getNewValue().equals(mevt.getPrevValue()))
- return; // no change really...
-
- Node attr = mevt.getRelatedNode();
- String attrNS = attr.getNamespaceURI();
- String name = ((attrNS == null) ?
- attr.getNodeName() :
- attr.getLocalName());
-
- CSSStylableElement elt = (CSSStylableElement)et;
- StyleMap style = elt.getComputedStyleMap(null);
- if (style != null) {
- if ((attrNS == styleNamespaceURI) ||
- ((attrNS != null) && attrNS.equals(styleNamespaceURI))) {
- if (name.equals(styleLocalName)) {
- // The style declaration attribute has been modified.
- inlineStyleAttributeUpdated(elt, style, mevt);
- return;
- }
- }
-
- if (nonCSSPresentationalHints != null) {
- if ((attrNS == nonCSSPresentationalHintsNamespaceURI) ||
- ((attrNS != null) &&
- attrNS.equals(nonCSSPresentationalHintsNamespaceURI))) {
- if (nonCSSPresentationalHints.contains(name)) {
- // The 'name' attribute which represents a non CSS
- // presentational hint has been modified.
- nonCSSPresentationalHintUpdated(elt, style, name,
- mevt);
- return;
- }
- }
- }
- }
-
- if (selectorAttributes != null &&
- selectorAttributes.contains(name)) {
- // An attribute has been modified, invalidate all the
- // properties to correctly match attribute selectors.
- invalidateProperties(elt, null, null, true);
- for (Node n = elt.getNextSibling();
- n != null;
- n = n.getNextSibling()) {
- invalidateProperties(n, null, null, true);
- }
- }
+ MutationEvent mevt = (MutationEvent) evt;
+ handleAttrModified((Element) evt.getTarget(),
+ (Attr) mevt.getRelatedNode(),
+ mevt.getAttrChange(),
+ mevt.getPrevValue(),
+ mevt.getNewValue());
}
}
}
Added: xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSNavigableDocument.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSNavigableDocument.java?rev=280553&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSNavigableDocument.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSNavigableDocument.java Tue Sep 13 06:29:29 2005
@@ -0,0 +1,39 @@
+/*
+
+ Copyright 2005 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+package org.apache.batik.css.engine;
+
+/**
+ * An interface for documents that have CSSNavigableNodes.
+ *
+ * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
+ * @version $Id$
+ */
+public interface CSSNavigableDocument {
+
+ /**
+ * Adds an event listener for mutations on the
+ * CSSNavigableDocument tree.
+ */
+ void addCSSNavigableDocumentListener(CSSNavigableDocumentListener l);
+
+ /**
+ * Removes an event listener for mutations on the
+ * CSSNavigableDocument tree.
+ */
+ void removeCSSNavigableDocumentListener(CSSNavigableDocumentListener l);
+}
Propchange: xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSNavigableDocument.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSNavigableDocumentListener.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSNavigableDocumentListener.java?rev=280553&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSNavigableDocumentListener.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSNavigableDocumentListener.java Tue Sep 13 06:29:29 2005
@@ -0,0 +1,60 @@
+/*
+
+ Copyright 2005 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+package org.apache.batik.css.engine;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * An interface for listeners of CSSNavigableDocument events. The
+ * events parallel the DOM events, but apply to the CSS view of
+ * the tree rather than the actual DOM tree.
+ *
+ * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
+ * @version $Id$
+ */
+public interface CSSNavigableDocumentListener {
+
+ /**
+ * A node has been inserted into the CSSNavigableDocument tree.
+ */
+ void nodeInserted(Node newNode);
+
+ /**
+ * A node is about to be removed from the CSSNavigableDocument tree.
+ */
+ void nodeToBeRemoved(Node oldNode);
+
+ /**
+ * A subtree of the CSSNavigableDocument tree has been modified
+ * in some way.
+ */
+ void subtreeModified(Node rootOfModifications);
+
+ /**
+ * Character data in the CSSNavigableDocument tree has been modified.
+ */
+ void characterDataModified(Node text);
+
+ /**
+ * An attribute has changed in the CSSNavigableDocument.
+ */
+ void attrModified(Element e, Attr attr, short attrChange,
+ String prevValue, String newValue);
+}
Propchange: xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSNavigableDocumentListener.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSNavigableNode.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSNavigableNode.java?rev=280553&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSNavigableNode.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSNavigableNode.java Tue Sep 13 06:29:29 2005
@@ -0,0 +1,62 @@
+/*
+
+ Copyright 2005 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+package org.apache.batik.css.engine;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * An interface for DOM classes that can be navigated for CSS selector
+ * matching and cascade computation.
+ *
+ * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
+ * @version $Id$
+ */
+public interface CSSNavigableNode {
+
+ /**
+ * Returns the CSS parent node of this node.
+ */
+ Node getCSSParentNode();
+
+ /**
+ * Returns the CSS previous sibling node of this node.
+ */
+ Node getCSSPreviousSibling();
+
+ /**
+ * Returns the CSS next sibling node of this node.
+ */
+ Node getCSSNextSibling();
+
+ /**
+ * Returns the CSS first child node of this node.
+ */
+ Node getCSSFirstChild();
+
+ /**
+ * Returns the CSS last child of this node.
+ */
+ Node getCSSLastChild();
+
+ /**
+ * Returns whether this node is the root of a (conceptual) hidden tree
+ * that selectors will not work across.
+ */
+ boolean isHiddenFromSelectors();
+}
Propchange: xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSNavigableNode.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/SVG12CSSEngine.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/SVG12CSSEngine.java?rev=280553&r1=280552&r2=280553&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/SVG12CSSEngine.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/SVG12CSSEngine.java Tue Sep 13 06:29:29 2005
@@ -1,6 +1,6 @@
/*
- Copyright 2002-2003 The Apache Software Foundation
+ Copyright 2002-2003,2005 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -41,7 +41,7 @@
public class SVG12CSSEngine extends SVGCSSEngine {
/**
- * Creates a new SVGCSSEngine.
+ * Creates a new SVG12CSSEngine.
* @param doc The associated document.
* @param uri The document URI.
* @param p The CSS parser to use.
@@ -59,7 +59,7 @@
}
/**
- * Creates a new SVGCSSEngine.
+ * Creates a new SVG12CSSEngine.
* @param doc The associated document.
* @param uri The document URI.
* @param p The CSS parser to use.
Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/dom/AbstractDOMImplementation.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/dom/AbstractDOMImplementation.java?rev=280553&r1=280552&r2=280553&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/dom/AbstractDOMImplementation.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/dom/AbstractDOMImplementation.java Tue Sep 13 06:29:29 2005
@@ -1,6 +1,6 @@
/*
- Copyright 2000-2003 The Apache Software Foundation
+ Copyright 2000-2003,2005 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -20,7 +20,9 @@
import java.io.Serializable;
import org.apache.batik.dom.events.DocumentEventSupport;
+import org.apache.batik.dom.events.EventSupport;
import org.apache.batik.dom.util.HashTable;
+
import org.w3c.dom.DOMImplementation;
/**
@@ -118,5 +120,12 @@
*/
public DocumentEventSupport createDocumentEventSupport() {
return new DocumentEventSupport();
+ }
+
+ /**
+ * Creates an EventSupport object for a given node.
+ */
+ public EventSupport createEventSupport(AbstractNode n) {
+ return new EventSupport(n);
}
}
Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/dom/AbstractDocument.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/dom/AbstractDocument.java?rev=280553&r1=280552&r2=280553&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/dom/AbstractDocument.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/dom/AbstractDocument.java Tue Sep 13 06:29:29 2005
@@ -1,6 +1,6 @@
/*
- Copyright 2000-2003 The Apache Software Foundation
+ Copyright 2000-2003,2005 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -35,13 +35,22 @@
import org.apache.batik.dom.events.EventSupport;
import org.apache.batik.dom.traversal.TraversalSupport;
import org.apache.batik.dom.util.DOMUtilities;
+import org.apache.batik.dom.xbl.GenericXBLManager;
+import org.apache.batik.dom.xbl.XBLManager;
import org.apache.batik.i18n.Localizable;
import org.apache.batik.i18n.LocalizableSupport;
import org.apache.batik.util.CleanerThread;
import org.apache.batik.util.DOMConstants;
import org.apache.batik.util.SoftDoublyIndexedTable;
import org.apache.batik.util.XMLConstants;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+
import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.DOMError;
import org.w3c.dom.DOMErrorHandler;
@@ -49,26 +58,19 @@
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.DOMLocator;
import org.w3c.dom.DOMStringList;
-import org.w3c.dom.Document;
-import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.Text;
-import org.w3c.dom.UserDataHandler;
import org.w3c.dom.events.DocumentEvent;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.MutationNameEvent;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
import org.w3c.dom.traversal.DocumentTraversal;
import org.w3c.dom.traversal.NodeFilter;
import org.w3c.dom.traversal.NodeIterator;
import org.w3c.dom.traversal.TreeWalker;
-
-import org.apache.xml.utils.PrefixResolver;
-import org.apache.xpath.XPath;
-import org.apache.xpath.XPathContext;
-import org.apache.xpath.objects.XObject;
-import org.w3c.dom.NodeList;
+import org.w3c.dom.UserDataHandler;
import org.w3c.dom.xpath.XPathEvaluator;
import org.w3c.dom.xpath.XPathException;
import org.w3c.dom.xpath.XPathExpression;
@@ -168,6 +170,11 @@
protected DocumentConfiguration domConfig;
/**
+ * The XBL manager for this document.
+ */
+ protected XBLManager xblManager = new GenericXBLManager();
+
+ /**
* The elementsById lists.
* This is keyed on 'id'. the entry is either
* a IdSoftReference to the element or a List of
@@ -1078,7 +1085,9 @@
if (es1 != null) {
EventSupport es2 = e.getEventSupport();
if (es2 == null) {
- es2 = new EventSupport(e);
+ AbstractDOMImplementation di
+ = (AbstractDOMImplementation) implementation;
+ es2 = di.createEventSupport(e);
setEventsEnabled(true);
e.eventSupport = es2;
}
@@ -1699,6 +1708,28 @@
}
/**
+ * Sets the XBLManager used for this document.
+ */
+ public void setXBLManager(XBLManager m) {
+ boolean wasProcessing = xblManager.isProcessing();
+ xblManager.stopProcessing();
+ if (m == null) {
+ m = new GenericXBLManager();
+ }
+ xblManager = m;
+ if (wasProcessing) {
+ xblManager.startProcessing();
+ }
+ }
+
+ /**
+ * Returns the XBLManager used for this document.
+ */
+ public XBLManager getXBLManager() {
+ return xblManager;
+ }
+
+ /**
* DOMError implementation.
*/
protected class DocumentError implements DOMError {
@@ -2556,6 +2587,111 @@
public String lookupNamespaceURI(String prefix) {
return ((AbstractNode) contextNode).lookupNamespaceURI(prefix);
}
+ }
+
+ // NodeXBL //////////////////////////////////////////////////////////////
+
+ /**
+ * Get the parent of this node in the fully flattened tree.
+ */
+ public Node getXblParentNode() {
+ return xblManager.getXblParentNode(this);
+ }
+
+ /**
+ * Get the list of child nodes of this node in the fully flattened tree.
+ */
+ public NodeList getXblChildNodes() {
+ return xblManager.getXblChildNodes(this);
+ }
+
+ /**
+ * Get the list of child nodes of this node in the fully flattened tree
+ * that are within the same shadow scope.
+ */
+ public NodeList getXblScopedChildNodes() {
+ return xblManager.getXblScopedChildNodes(this);
+ }
+
+ /**
+ * Get the first child node of this node in the fully flattened tree.
+ */
+ public Node getXblFirstChild() {
+ return xblManager.getXblFirstChild(this);
+ }
+
+ /**
+ * Get the last child node of this node in the fully flattened tree.
+ */
+ public Node getXblLastChild() {
+ return xblManager.getXblLastChild(this);
+ }
+
+ /**
+ * Get the node which directly precedes the current node in the
+ * xblParentNode's xblChildNodes list.
+ */
+ public Node getXblPreviousSibling() {
+ return xblManager.getXblPreviousSibling(this);
+ }
+
+ /**
+ * Get the node which directly follows the current node in the
+ * xblParentNode's xblChildNodes list.
+ */
+ public Node getXblNextSibling() {
+ return xblManager.getXblNextSibling(this);
+ }
+
+ /**
+ * Get the first element child of this node in the fully flattened tree.
+ */
+ public Element getXblFirstElementChild() {
+ return xblManager.getXblFirstElementChild(this);
+ }
+
+ /**
+ * Get the last element child of this node in the fully flattened tree.
+ */
+ public Element getXblLastElementChild() {
+ return xblManager.getXblLastElementChild(this);
+ }
+
+ /**
+ * Get the first element that precedes the current node in the
+ * xblParentNode's xblChildNodes list.
+ */
+ public Element getXblPreviousElementSibling() {
+ return xblManager.getXblPreviousElementSibling(this);
+ }
+
+ /**
+ * Get the first element that follows the current node in the
+ * xblParentNode's xblChildNodes list.
+ */
+ public Element getXblNextElementSibling() {
+ return xblManager.getXblNextElementSibling(this);
+ }
+
+ /**
+ * Get the bound element whose shadow tree this current node resides in.
+ */
+ public Element getXblBoundElement() {
+ return xblManager.getXblBoundElement(this);
+ }
+
+ /**
+ * Get the shadow tree of this node.
+ */
+ public Element getXblShadowTree() {
+ return xblManager.getXblShadowTree(this);
+ }
+
+ /**
+ * Get the xbl:definition elements currently binding this element.
+ */
+ public NodeList getXblDefinitions() {
+ return xblManager.getXblDefinitions(this);
}
// Serializable /////////////////////////////////////////////////
Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/dom/AbstractElement.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/dom/AbstractElement.java?rev=280553&r1=280552&r2=280553&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/dom/AbstractElement.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/dom/AbstractElement.java Tue Sep 13 06:29:29 2005
@@ -19,7 +19,10 @@
import java.io.Serializable;
+import org.apache.batik.dom.events.DOMMutationEvent;
import org.apache.batik.dom.util.DOMUtilities;
+import org.apache.batik.util.XMLConstants;
+
import org.w3c.dom.Attr;
import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
@@ -610,15 +613,17 @@
AbstractDocument doc = getCurrentDocument();
if (doc.getEventsEnabled() && !oldv.equals(newv)) {
DocumentEvent de = (DocumentEvent)doc;
- MutationEvent ev = (MutationEvent)de.createEvent("MutationEvents");
- ev.initMutationEvent("DOMAttrModified",
- true, // canBubbleArg
- false, // cancelableArg
- node, // relatedNodeArg
- oldv, // prevValueArg
- newv, // newValueArg
- name, // attrNameArg
- change); // attrChange
+ DOMMutationEvent ev
+ = (DOMMutationEvent) de.createEvent("MutationEvents");
+ ev.initMutationEventNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
+ "DOMAttrModified",
+ true, // canBubbleArg
+ false, // cancelableArg
+ node, // relatedNodeArg
+ oldv, // prevValueArg
+ newv, // newValueArg
+ name, // attrNameArg
+ change); // attrChange
dispatchEvent(ev);
}
}
Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/dom/AbstractNode.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/dom/AbstractNode.java?rev=280553&r1=280552&r2=280553&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/dom/AbstractNode.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/dom/AbstractNode.java Tue Sep 13 06:29:29 2005
@@ -1,6 +1,6 @@
/*
- Copyright 2000-2003 The Apache Software Foundation
+ Copyright 2000-2003,2005 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -23,10 +23,13 @@
import java.util.Iterator;
import java.util.Map;
+import org.apache.batik.dom.events.DOMMutationEvent;
import org.apache.batik.dom.events.EventSupport;
import org.apache.batik.dom.events.NodeEventTarget;
import org.apache.batik.dom.util.DOMUtilities;
import org.apache.batik.dom.util.XMLSupport;
+import org.apache.batik.dom.xbl.NodeXBL;
+import org.apache.batik.dom.xbl.XBLManagerData;
import org.apache.batik.util.ParsedURL;
import org.apache.batik.util.XMLConstants;
import org.w3c.dom.Attr;
@@ -37,7 +40,6 @@
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
-import org.w3c.dom.TypeInfo;
import org.w3c.dom.UserDataHandler;
import org.w3c.dom.events.DocumentEvent;
import org.w3c.dom.events.Event;
@@ -53,12 +55,14 @@
*/
public abstract class AbstractNode
implements ExtendedNode,
+ NodeXBL,
+ XBLManagerData,
Serializable {
/**
* An empty instance of NodeList.
*/
- protected final static NodeList EMPTY_NODE_LIST = new NodeList() {
+ public final static NodeList EMPTY_NODE_LIST = new NodeList() {
public Node item(int i) { return null; }
public int getLength() { return 0; }
};
@@ -84,6 +88,11 @@
protected HashMap userDataHandlers;
/**
+ * The XBL manager data.
+ */
+ protected Object managerData;
+
+ /**
* Sets the name of this node.
* Do nothing.
*/
@@ -447,6 +456,10 @@
return getCascadedXMLBase(this);
}
+ public static String getBaseURI(Node n) {
+ return ((AbstractNode) n).getBaseURI();
+ }
+
// DocumentPosition constants from DOM Level 3 Core org.w3c.dom.Node
// interface.
@@ -739,6 +752,9 @@
Node attr = nnm.item(i);
String attrPrefix = attr.getPrefix();
String localName = attr.getLocalName();
+ if (localName == null) {
+ localName = attr.getNodeName();
+ }
if (XMLConstants.XMLNS_PREFIX.equals(attrPrefix)
&& compareStrings(localName, prefix)
|| XMLConstants.XMLNS_PREFIX.equals(localName)
@@ -913,9 +929,7 @@
EventListener listener,
boolean useCapture) {
if (eventSupport == null) {
- eventSupport = new EventSupport(this);
- AbstractDocument doc = getCurrentDocument();
- doc.setEventsEnabled(true);
+ initializeEventSupport();
}
eventSupport.addEventListener(type, listener, useCapture);
}
@@ -931,15 +945,13 @@
boolean useCapture,
Object evtGroup) {
if (eventSupport == null) {
- eventSupport = new EventSupport(this);
- AbstractDocument doc = getCurrentDocument();
- doc.setEventsEnabled(true);
+ initializeEventSupport();
}
eventSupport.addEventListenerNS(namespaceURI,
type,
- evtGroup,
listener,
- useCapture);
+ useCapture,
+ evtGroup);
}
/**
@@ -965,10 +977,10 @@
EventListener listener,
boolean useCapture) {
if (eventSupport != null) {
- eventSupport.removeEventListener(namespaceURI,
- type,
- listener,
- useCapture);
+ eventSupport.removeEventListenerNS(namespaceURI,
+ type,
+ listener,
+ useCapture);
}
}
@@ -977,7 +989,7 @@
* org.apache.batik.dom.events.NodeEventTarget#getParentNodeEventTarget()}.
*/
public NodeEventTarget getParentNodeEventTarget() {
- return (NodeEventTarget)getParentNode();
+ return (NodeEventTarget) getXblParentNode();
}
/**
@@ -986,9 +998,7 @@
*/
public boolean dispatchEvent(Event evt) throws EventException {
if (eventSupport == null) {
- eventSupport = new EventSupport(this);
- AbstractDocument doc = getCurrentDocument();
- doc.setEventsEnabled(true);
+ initializeEventSupport();
}
return eventSupport.dispatchEvent(this, evt);
}
@@ -1020,21 +1030,37 @@
}
/**
+ * Initializes the event support instance for this node if it has not
+ * been already, and returns it.
+ */
+ public EventSupport initializeEventSupport() {
+ if (eventSupport == null) {
+ AbstractDocument doc = getCurrentDocument();
+ AbstractDOMImplementation di
+ = (AbstractDOMImplementation) doc.getImplementation();
+ eventSupport = di.createEventSupport(this);
+ doc.setEventsEnabled(true);
+ }
+ return eventSupport;
+ }
+
+ /**
* Recursively fires a DOMNodeInsertedIntoDocument event.
*/
public void fireDOMNodeInsertedIntoDocumentEvent() {
AbstractDocument doc = getCurrentDocument();
if (doc.getEventsEnabled()) {
DocumentEvent de = (DocumentEvent)doc;
- MutationEvent ev = (MutationEvent)de.createEvent("MutationEvents");
- ev.initMutationEvent("DOMNodeInsertedIntoDocument",
- true, // canBubbleArg
- false, // cancelableArg
- null, // relatedNodeArg
- null, // prevValueArg
- null, // newValueArg
- null, // attrNameArg
- MutationEvent.ADDITION);
+ DOMMutationEvent ev = (DOMMutationEvent)de.createEvent("MutationEvents");
+ ev.initMutationEventNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
+ "DOMNodeInsertedIntoDocument",
+ true, // canBubbleArg
+ false, // cancelableArg
+ null, // relatedNodeArg
+ null, // prevValueArg
+ null, // newValueArg
+ null, // attrNameArg
+ MutationEvent.ADDITION);
dispatchEvent(ev);
}
}
@@ -1046,15 +1072,17 @@
AbstractDocument doc = getCurrentDocument();
if (doc.getEventsEnabled()) {
DocumentEvent de = (DocumentEvent)doc;
- MutationEvent ev = (MutationEvent)de.createEvent("MutationEvents");
- ev.initMutationEvent("DOMNodeRemovedFromDocument",
- true, // canBubbleArg
- false, // cancelableArg
- null, // relatedNodeArg
- null, // prevValueArg
- null, // newValueArg
- null, // attrNameArg
- MutationEvent.REMOVAL);
+ DOMMutationEvent ev
+ = (DOMMutationEvent) de.createEvent("MutationEvents");
+ ev.initMutationEventNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
+ "DOMNodeRemovedFromDocument",
+ true, // canBubbleArg
+ false, // cancelableArg
+ null, // relatedNodeArg
+ null, // prevValueArg
+ null, // newValueArg
+ null, // attrNameArg
+ MutationEvent.REMOVAL);
dispatchEvent(ev);
}
}
@@ -1067,15 +1095,17 @@
AbstractDocument doc = getCurrentDocument();
if (doc.getEventsEnabled()) {
DocumentEvent de = (DocumentEvent)doc;
- MutationEvent ev = (MutationEvent)de.createEvent("MutationEvents");
- ev.initMutationEvent("DOMCharacterDataModified",
- true, // canBubbleArg
- false, // cancelableArg
- null, // relatedNodeArg
- oldv, // prevValueArg
- newv, // newValueArg
- null, // attrNameArg
- MutationEvent.MODIFICATION);
+ DOMMutationEvent ev
+ = (DOMMutationEvent) de.createEvent("MutationEvents");
+ ev.initMutationEventNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
+ "DOMCharacterDataModified",
+ true, // canBubbleArg
+ false, // cancelableArg
+ null, // relatedNodeArg
+ oldv, // prevValueArg
+ newv, // newValueArg
+ null, // attrNameArg
+ MutationEvent.MODIFICATION);
dispatchEvent(ev);
}
}
@@ -1142,10 +1172,124 @@
getNodeName() });
}
+ // NodeXBL //////////////////////////////////////////////////////////////
+
/**
- * Gets the base URI of the given node.
+ * Get the parent of this node in the fully flattened tree.
*/
- public static String getBaseURI(Node n) {
- return ((AbstractNode) n).getBaseURI();
+ public Node getXblParentNode() {
+ return ownerDocument.getXBLManager().getXblParentNode(this);
+ }
+
+ /**
+ * Get the list of child nodes of this node in the fully flattened tree.
+ */
+ public NodeList getXblChildNodes() {
+ return ownerDocument.getXBLManager().getXblChildNodes(this);
+ }
+
+ /**
+ * Get the list of child nodes of this node in the fully flattened tree
+ * that are within the same shadow scope.
+ */
+ public NodeList getXblScopedChildNodes() {
+ return ownerDocument.getXBLManager().getXblScopedChildNodes(this);
+ }
+
+ /**
+ * Get the first child node of this node in the fully flattened tree.
+ */
+ public Node getXblFirstChild() {
+ return ownerDocument.getXBLManager().getXblFirstChild(this);
+ }
+
+ /**
+ * Get the last child node of this node in the fully flattened tree.
+ */
+ public Node getXblLastChild() {
+ return ownerDocument.getXBLManager().getXblLastChild(this);
+ }
+
+ /**
+ * Get the node which directly precedes the current node in the
+ * xblParentNode's xblChildNodes list.
+ */
+ public Node getXblPreviousSibling() {
+ return ownerDocument.getXBLManager().getXblPreviousSibling(this);
+ }
+
+ /**
+ * Get the node which directly follows the current node in the
+ * xblParentNode's xblChildNodes list.
+ */
+ public Node getXblNextSibling() {
+ return ownerDocument.getXBLManager().getXblNextSibling(this);
+ }
+
+ /**
+ * Get the first element child of this node in the fully flattened tree.
+ */
+ public Element getXblFirstElementChild() {
+ return ownerDocument.getXBLManager().getXblFirstElementChild(this);
+ }
+
+ /**
+ * Get the last element child of this node in the fully flattened tree.
+ */
+ public Element getXblLastElementChild() {
+ return ownerDocument.getXBLManager().getXblLastElementChild(this);
+ }
+
+ /**
+ * Get the first element that precedes the current node in the
+ * xblParentNode's xblChildNodes list.
+ */
+ public Element getXblPreviousElementSibling() {
+ return ownerDocument.getXBLManager().getXblPreviousElementSibling(this);
+ }
+
+ /**
+ * Get the first element that follows the current node in the
+ * xblParentNode's xblChildNodes list.
+ */
+ public Element getXblNextElementSibling() {
+ return ownerDocument.getXBLManager().getXblNextElementSibling(this);
+ }
+
+ /**
+ * Get the bound element whose shadow tree this current node resides in.
+ */
+ public Element getXblBoundElement() {
+ return ownerDocument.getXBLManager().getXblBoundElement(this);
+ }
+
+ /**
+ * Get the shadow tree of this node.
+ */
+ public Element getXblShadowTree() {
+ return ownerDocument.getXBLManager().getXblShadowTree(this);
+ }
+
+ /**
+ * Get the xbl:definition elements currently binding this element.
+ */
+ public NodeList getXblDefinitions() {
+ return ownerDocument.getXBLManager().getXblDefinitions(this);
+ }
+
+ // XBLManagerData ////////////////////////////////////////////////////////
+
+ /**
+ * Returns the XBL manager associated data for this node.
+ */
+ public Object getManagerData() {
+ return managerData;
+ }
+
+ /**
+ * Sets the XBL manager associated data for this node.
+ */
+ public void setManagerData(Object data) {
+ managerData = data;
}
}