1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.vectomatic.svg.samples.client.xpath;
19
20 import java.util.ArrayList;
21 import java.util.HashMap;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Map;
25
26 import org.vectomatic.dom.svg.impl.Attr;
27 import org.vectomatic.dom.svg.impl.NamedNodeMap;
28 import org.vectomatic.dom.svg.ui.SVGImage;
29 import org.vectomatic.dom.svg.ui.SVGResource;
30 import org.vectomatic.dom.svg.ui.SVGResource.Validated;
31 import org.vectomatic.dom.svg.utils.DOMHelper;
32 import org.vectomatic.dom.svg.utils.SVGConstants;
33 import org.vectomatic.dom.svg.utils.SVGPrefixResolver;
34 import org.vectomatic.svg.samples.client.Main;
35 import org.vectomatic.svg.samples.client.Main.MainBundle;
36 import org.vectomatic.svg.samples.client.SampleBase;
37
38 import com.google.gwt.core.client.GWT;
39 import com.google.gwt.dom.client.Document;
40 import com.google.gwt.dom.client.Element;
41 import com.google.gwt.dom.client.Node;
42 import com.google.gwt.dom.client.NodeList;
43 import com.google.gwt.dom.client.PreElement;
44 import com.google.gwt.dom.client.SpanElement;
45 import com.google.gwt.dom.client.Text;
46 import com.google.gwt.event.dom.client.ClickEvent;
47 import com.google.gwt.event.dom.client.KeyUpEvent;
48 import com.google.gwt.resources.client.ClientBundle;
49 import com.google.gwt.resources.client.CssResource;
50 import com.google.gwt.uibinder.client.UiBinder;
51 import com.google.gwt.uibinder.client.UiField;
52 import com.google.gwt.uibinder.client.UiHandler;
53 import com.google.gwt.user.client.ui.Button;
54 import com.google.gwt.user.client.ui.CheckBox;
55 import com.google.gwt.user.client.ui.HTML;
56 import com.google.gwt.user.client.ui.Label;
57 import com.google.gwt.user.client.ui.TabLayoutPanel;
58 import com.google.gwt.user.client.ui.TextBox;
59
60
61
62
63
64 public class XPathSample extends SampleBase {
65 interface XmlCssResource extends CssResource {
66 public String element();
67 public String attribute();
68 public String text();
69 public String comment();
70 public String markup();
71 public String selected();
72 public String root();
73 }
74 interface XPathBundle extends ClientBundle {
75 public static XPathBundle INSTANCE = GWT.create(XPathBundle.class);
76 @Source("xml.css")
77 public XmlCssResource css();
78 @Validated(validated=false)
79 @Source("pizza_pepperoni_bw.svg")
80 public SVGResource pizza();
81 }
82
83 interface XPathSampleBinder extends UiBinder<TabLayoutPanel, XPathSample> {
84 }
85 private static XPathSampleBinder binder = GWT.create(XPathSampleBinder.class);
86
87 @UiField(provided=true)
88 public static XPathBundle xpathBundle = XPathBundle.INSTANCE;
89 @UiField(provided=true)
90 public static MainBundle mainBundle = Main.mainBundle;
91
92
93
94 @UiField
95 TextBox xpathBox;
96
97
98
99 @UiField
100 Button evaluateButton;
101
102
103
104
105 @UiField
106 CheckBox evaluateCheckBox;
107
108
109
110 @UiField
111 Label errorLabel;
112
113
114
115 @UiField
116 SVGImage svgImage;
117
118
119
120 @UiField
121 HTML xmlContainer;
122
123
124
125
126 private Document doc = Document.get();
127
128
129
130 private XmlCssResource css = xpathBundle.css();
131
132
133
134 private Map<Node, SpanElement> nodeToSpan = new HashMap<Node, SpanElement>();
135
136
137
138
139 private List<Element> xpathSpans;
140
141
142
143 private List<Element> svgElements;
144
145
146
147 private SVGPrefixResolver resolver;
148
149 @Override
150 public TabLayoutPanel getPanel() {
151 if (tabPanel == null) {
152 tabPanel = binder.createAndBindUi(this);
153 tabPanel.setTabText(0, "XPath");
154 createCodeTabs("XPathSample");
155
156 css.ensureInjected();
157 xpathSpans = new ArrayList<Element>();
158 svgElements = new ArrayList<Element>();
159 PreElement pre = doc.createPreElement();
160 visit(svgImage.getElement(), pre);
161 pre.addClassName(css.root());
162 xmlContainer.getElement().appendChild(pre);
163 resolver = new SVGPrefixResolver() {
164 {
165 prefixToUri.put("i", "http://ns.adobe.com/AdobeIllustrator/10.0/");
166 prefixToUri.put("cc", "http://web.resource.org/cc/");
167 prefixToUri.put("dc", "http://purl.org/dc/elements/1.1/");
168 prefixToUri.put("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
169 }
170 };
171 evaluate();
172 }
173 return tabPanel;
174 }
175
176 @UiHandler("evaluateButton")
177 public void evaluate(ClickEvent event) {
178 evaluate();
179 }
180
181 @UiHandler("evaluateCheckBox")
182 public void checkbox(ClickEvent event) {
183 evaluateButton.setEnabled(!evaluateCheckBox.getValue());
184 }
185
186 @UiHandler("xpathBox")
187 public void keyUp(KeyUpEvent event) {
188 if (evaluateCheckBox.getValue()) {
189 evaluate();
190 }
191 }
192
193 public void evaluate() {
194 String error = "";
195 try {
196 for (Element span : xpathSpans) {
197 span.removeClassName(css.selected());
198 }
199 xpathSpans.clear();
200 for (Element svgElement : svgElements) {
201 svgElement.setAttribute(SVGConstants.SVG_FILL_ATTRIBUTE, "#FFFFFF");
202 }
203 svgElements.clear();
204
205 String expr = xpathBox.getText();
206 GWT.log(expr);
207 Iterator<Node> iterator = DOMHelper.evaluateNodeListXPath(svgImage.getElement(), expr, resolver);
208 while (iterator.hasNext()) {
209 Node node = iterator.next();
210 if (node.getNodeType() == Node.ELEMENT_NODE) {
211 svgElements.add(node.<Element>cast());
212 }
213 Element span = nodeToSpan.get(node);
214 xpathSpans.add(span);
215 }
216 for (Element span : xpathSpans) {
217 span.addClassName(css.selected());
218 }
219 for (Element svgElement : svgElements) {
220 svgElement.setAttribute(SVGConstants.SVG_FILL_ATTRIBUTE, "green");
221 }
222 } catch(Throwable t) {
223 error = t.getMessage();
224 }
225 errorLabel.setText(error);
226 }
227
228 private SpanElement createMarkup(String markup) {
229 SpanElement markupSpan = doc.createSpanElement();
230 markupSpan.addClassName(css.markup());
231 markupSpan.appendChild(doc.createTextNode(markup));
232 return markupSpan;
233 }
234
235 private void visit(Node node, Element parentSpan) {
236 SpanElement span = doc.createSpanElement();
237 nodeToSpan.put(node, span);
238
239 parentSpan.appendChild(span);
240 NodeList<Node> childNodes = node.getChildNodes();
241 switch(node.getNodeType()) {
242 case Node.ELEMENT_NODE:
243 {
244 Element element = node.<Element>cast();
245 span.addClassName(css.element());
246
247
248 span.appendChild(createMarkup("<"));
249 String tagName = element.getTagName();
250 int index = tagName.indexOf(":");
251 if (index != -1) {
252 span.appendChild(doc.createTextNode(tagName.substring(0, index)));
253 span.appendChild(createMarkup(":"));
254 span.appendChild(doc.createTextNode(tagName.substring(index + 1)));
255 } else {
256 span.appendChild(doc.createTextNode(tagName));
257 }
258
259
260 NamedNodeMap<Attr> attributes = DOMHelper.getAttributes(element);
261 for (int i = 0, length = attributes.getLength(); i < length; i++) {
262 span.appendChild(doc.createTextNode(" "));
263
264 SpanElement attrSpan = doc.createSpanElement();
265 attrSpan.addClassName(css.attribute());
266 span.appendChild(attrSpan);
267 Attr attr = attributes.item(i);
268 nodeToSpan.put(attr, attrSpan);
269
270 String attrName = attr.getName();
271 index = attrName.indexOf(":");
272 if (index != -1) {
273 attrSpan.appendChild(doc.createTextNode(attrName.substring(0, index)));
274 attrSpan.appendChild(createMarkup(":"));
275 attrSpan.appendChild(doc.createTextNode(attrName.substring(index + 1)));
276 } else {
277 attrSpan.appendChild(doc.createTextNode(attrName));
278 }
279 attrSpan.appendChild(createMarkup("=\""));
280 attrSpan.appendChild(doc.createTextNode(attr.getValue()));
281 attrSpan.appendChild(createMarkup("\""));
282 }
283 span.appendChild(createMarkup(childNodes.getLength() > 0 ? ">" : "/>"));
284 }
285 break;
286 case Node.TEXT_NODE:
287 {
288
289 Text text = node.<Text>cast();
290 span.addClassName(css.text());
291 span.appendChild(doc.createTextNode(text.getData()));
292 }
293 break;
294 }
295
296 for (int i = 0, count = node.getChildCount(); i < count; i++) {
297 visit(childNodes.getItem(i), span);
298 }
299
300 if (childNodes.getLength() > 0 && node.getNodeType() == Node.ELEMENT_NODE) {
301 Element element = node.<Element>cast();
302 span.addClassName(css.element());
303
304
305 span.appendChild(createMarkup("</"));
306 String tagName = element.getTagName();
307 int index = tagName.indexOf(":");
308 if (index != -1) {
309 span.appendChild(doc.createTextNode(tagName.substring(0, index)));
310 span.appendChild(createMarkup(":"));
311 span.appendChild(doc.createTextNode(tagName.substring(index + 1)));
312 } else {
313 span.appendChild(doc.createTextNode(tagName));
314 }
315 span.appendChild(createMarkup(">"));
316 }
317 }
318
319 }