source: webkit/trunk/Source/WebCore/xml/XMLViewer.js

Last change on this file was 162269, checked in by [email protected], 11 years ago

XMLTreeViewer shouldn't use the view source mode
https://bugs.webkit.org/show_bug.cgi?id=127229

Reviewed by Andreas Kling.

Add the relevant styles from view-source.css to XMLViewer.css.

  • xml/XMLTreeViewer.cpp:

(WebCore::XMLTreeViewer::transformDocumentToTreeView):

  • xml/XMLViewer.css:

(body):
(.comment):
(.tag):
(.attribute-name):
(.attribute-value):

  • xml/XMLViewer.js:

(createComment):
(createTag):
(createAttribute):

  • Property svn:eol-style set to LF
File size: 13.4 KB
Line 
1/*
2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * Copyright (C) 2013 Apple Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
18 * “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
21 * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30var nodeParentPairs = [];
31var sourceXML;
32
33// Script entry point.
34
35function prepareWebKitXMLViewer(noStyleMessage)
36{
37 var html = createHTMLElement('html');
38 var head = createHTMLElement('head');
39 html.appendChild(head);
40 var style = createHTMLElement('style');
41 style.id = 'xml-viewer-style';
42 head.appendChild(style);
43 var body = createHTMLElement('body');
44 html.appendChild(body);
45 sourceXML = createHTMLElement('div');
46
47 var child;
48 while (child = document.firstChild) {
49 document.removeChild(child);
50 if (child.nodeType != Node.DOCUMENT_TYPE_NODE)
51 sourceXML.appendChild(child);
52 }
53 document.appendChild(html);
54
55 var header = createHTMLElement('div');
56 body.appendChild(header);
57 header.classList.add('header');
58 var headerSpan = createHTMLElement('span');
59 header.appendChild(headerSpan);
60 headerSpan.textContent = noStyleMessage;
61 header.appendChild(createHTMLElement('br'));
62
63 var tree = createHTMLElement('div');
64 body.appendChild(tree);
65 tree.classList.add('pretty-print');
66 tree.id = 'tree';
67 window.onload = sourceXMLLoaded;
68}
69
70function sourceXMLLoaded()
71{
72 var root = document.getElementById('tree');
73
74 for (var child = sourceXML.firstChild; child; child = child.nextSibling)
75 nodeParentPairs.push({parentElement: root, node: child});
76
77 for (var i = 0; i < nodeParentPairs.length; i++)
78 processNode(nodeParentPairs[i].parentElement, nodeParentPairs[i].node);
79
80 drawArrows();
81 initButtons();
82
83 if (typeof(onAfterWebkitXMLViewerLoaded) == 'function')
84 onAfterWebkitXMLViewerLoaded();
85}
86
87// Tree processing.
88
89function processNode(parentElement, node)
90{
91 if (!processNode.processorsMap) {
92 processNode.processorsMap = {};
93 processNode.processorsMap[Node.PROCESSING_INSTRUCTION_NODE] = processProcessingInstruction;
94 processNode.processorsMap[Node.ELEMENT_NODE] = processElement;
95 processNode.processorsMap[Node.COMMENT_NODE] = processComment;
96 processNode.processorsMap[Node.TEXT_NODE] = processText;
97 processNode.processorsMap[Node.CDATA_SECTION_NODE] = processCDATA;
98 }
99 if (processNode.processorsMap[node.nodeType])
100 processNode.processorsMap[node.nodeType].call(this, parentElement, node);
101}
102
103function processElement(parentElement, node)
104{
105 if (!node.firstChild)
106 processEmptyElement(parentElement, node);
107 else {
108 var child = node.firstChild;
109 if (child.nodeType == Node.TEXT_NODE && isShort(child.nodeValue) && !child.nextSibling)
110 processShortTextOnlyElement(parentElement, node);
111 else
112 processComplexElement(parentElement, node);
113 }
114}
115
116function processEmptyElement(parentElement, node)
117{
118 var line = createLine();
119 line.appendChild(createTag(node, false, true));
120 parentElement.appendChild(line);
121}
122
123function processShortTextOnlyElement(parentElement, node)
124{
125 var line = createLine();
126 line.appendChild(createTag(node, false, false));
127 for (var child = node.firstChild; child; child = child.nextSibling)
128 line.appendChild(createText(child.nodeValue));
129 line.appendChild(createTag(node, true, false));
130 parentElement.appendChild(line);
131}
132
133function processComplexElement(parentElement, node)
134{
135 var collapsible = createCollapsible();
136
137 collapsible.expanded.start.appendChild(createTag(node, false, false));
138 for (var child = node.firstChild; child; child = child.nextSibling)
139 nodeParentPairs.push({parentElement: collapsible.expanded.content, node: child});
140 collapsible.expanded.end.appendChild(createTag(node, true, false));
141
142 collapsible.collapsed.content.appendChild(createTag(node, false, false));
143 collapsible.collapsed.content.appendChild(createText('...'));
144 collapsible.collapsed.content.appendChild(createTag(node, true, false));
145 parentElement.appendChild(collapsible);
146}
147
148function processComment(parentElement, node)
149{
150 if (isShort(node.nodeValue)) {
151 var line = createLine();
152 line.appendChild(createComment('<!-- ' + node.nodeValue + ' -->'));
153 parentElement.appendChild(line);
154 } else {
155 var collapsible = createCollapsible();
156
157 collapsible.expanded.start.appendChild(createComment('<!--'));
158 collapsible.expanded.content.appendChild(createComment(node.nodeValue));
159 collapsible.expanded.end.appendChild(createComment('-->'));
160
161 collapsible.collapsed.content.appendChild(createComment('<!--'));
162 collapsible.collapsed.content.appendChild(createComment('...'));
163 collapsible.collapsed.content.appendChild(createComment('-->'));
164 parentElement.appendChild(collapsible);
165 }
166}
167
168function processCDATA(parentElement, node)
169{
170 if (isShort(node.nodeValue)) {
171 var line = createLine();
172 line.appendChild(createText('<![CDATA[ ' + node.nodeValue + ' ]]>'));
173 parentElement.appendChild(line);
174 } else {
175 var collapsible = createCollapsible();
176
177 collapsible.expanded.start.appendChild(createText('<![CDATA['));
178 collapsible.expanded.content.appendChild(createText(node.nodeValue));
179 collapsible.expanded.end.appendChild(createText(']]>'));
180
181 collapsible.collapsed.content.appendChild(createText('<![CDATA['));
182 collapsible.collapsed.content.appendChild(createText('...'));
183 collapsible.collapsed.content.appendChild(createText(']]>'));
184 parentElement.appendChild(collapsible);
185 }
186}
187
188function processProcessingInstruction(parentElement, node)
189{
190 if (isShort(node.nodeValue)) {
191 var line = createLine();
192 line.appendChild(createComment('<?' + node.nodeName + ' ' + node.nodeValue + '?>'));
193 parentElement.appendChild(line);
194 } else {
195 var collapsible = createCollapsible();
196
197 collapsible.expanded.start.appendChild(createComment('<?' + node.nodeName));
198 collapsible.expanded.content.appendChild(createComment(node.nodeValue));
199 collapsible.expanded.end.appendChild(createComment('?>'));
200
201 collapsible.collapsed.content.appendChild(createComment('<?' + node.nodeName));
202 collapsible.collapsed.content.appendChild(createComment('...'));
203 collapsible.collapsed.content.appendChild(createComment('?>'));
204 parentElement.appendChild(collapsible);
205 }
206}
207
208function processText(parentElement, node)
209{
210 parentElement.appendChild(createText(node.nodeValue));
211}
212
213// Processing utils.
214
215function trim(value)
216{
217 return value.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
218}
219
220function isShort(value)
221{
222 return trim(value).length <= 50;
223}
224
225// Tree rendering.
226
227function createHTMLElement(elementName)
228{
229 return document.createElementNS('http://www.w3.org/1999/xhtml', elementName)
230}
231
232function createCollapsible()
233{
234 var collapsible = createHTMLElement('div');
235 collapsible.classList.add('collapsible');
236 collapsible.expanded = createHTMLElement('div');
237 collapsible.expanded.classList.add('expanded');
238 collapsible.appendChild(collapsible.expanded);
239
240 collapsible.expanded.start = createLine();
241 collapsible.expanded.start.appendChild(createCollapseButton());
242 collapsible.expanded.appendChild(collapsible.expanded.start);
243
244 collapsible.expanded.content = createHTMLElement('div');
245 collapsible.expanded.content.classList.add('collapsible-content');
246 collapsible.expanded.appendChild(collapsible.expanded.content);
247
248 collapsible.expanded.end = createLine();
249 collapsible.expanded.appendChild(collapsible.expanded.end);
250
251 collapsible.collapsed = createHTMLElement('div');
252 collapsible.collapsed.classList.add('collapsed');
253 collapsible.collapsed.classList.add('hidden');
254 collapsible.appendChild(collapsible.collapsed);
255 collapsible.collapsed.content = createLine();
256 collapsible.collapsed.content.appendChild(createExpandButton());
257 collapsible.collapsed.appendChild(collapsible.collapsed.content);
258
259 return collapsible;
260}
261
262function createButton()
263{
264 var button = createHTMLElement('span');
265 button.classList.add('button');
266 return button;
267}
268
269function createCollapseButton(str)
270{
271 var button = createButton();
272 button.classList.add('collapse-button');
273 return button;
274}
275
276function createExpandButton(str)
277{
278 var button = createButton();
279 button.classList.add('expand-button');
280 return button;
281}
282
283function createComment(commentString)
284{
285 var comment = createHTMLElement('span');
286 comment.classList.add('comment');
287 comment.textContent = commentString;
288 return comment;
289}
290
291function createText(value)
292{
293 var text = createHTMLElement('span');
294 text.textContent = trim(value);
295 text.classList.add('text');
296 return text;
297}
298
299function createLine()
300{
301 var line = createHTMLElement('div');
302 line.classList.add('line');
303 return line;
304}
305
306function createTag(node, isClosing, isEmpty)
307{
308 var tag = createHTMLElement('span');
309 tag.classList.add('tag');
310
311 var stringBeforeAttrs = '<';
312 if (isClosing)
313 stringBeforeAttrs += '/';
314 stringBeforeAttrs += node.nodeName;
315 var textBeforeAttrs = document.createTextNode(stringBeforeAttrs);
316 tag.appendChild(textBeforeAttrs);
317
318 if (!isClosing) {
319 for (var i = 0; i < node.attributes.length; i++)
320 tag.appendChild(createAttribute(node.attributes[i]));
321 }
322
323 var stringAfterAttrs = '';
324 if (isEmpty)
325 stringAfterAttrs += '/';
326 stringAfterAttrs += '>';
327 var textAfterAttrs = document.createTextNode(stringAfterAttrs);
328 tag.appendChild(textAfterAttrs);
329
330 return tag;
331}
332
333function createAttribute(attributeNode)
334{
335 var attribute = createHTMLElement('span');
336
337 var attributeName = createHTMLElement('span');
338 attributeName.classList.add('attribute-name');
339 attributeName.textContent = attributeNode.name;
340
341 var textBefore = document.createTextNode(' ');
342 var textBetween = document.createTextNode('="');
343
344 var attributeValue = createHTMLElement('span');
345 attributeValue.classList.add('attribute-value');
346 attributeValue.textContent = attributeNode.value;
347
348 var textAfter = document.createTextNode('"');
349
350 attribute.appendChild(textBefore);
351 attribute.appendChild(attributeName);
352 attribute.appendChild(textBetween);
353 attribute.appendChild(attributeValue);
354 attribute.appendChild(textAfter);
355 return attribute;
356}
357
358// Tree behaviour.
359
360function drawArrows()
361{
362 var ctx = document.getCSSCanvasContext("2d", "arrowRight", 10, 11);
363
364 ctx.fillStyle = "rgb(90,90,90)";
365 ctx.beginPath();
366 ctx.moveTo(0, 0);
367 ctx.lineTo(0, 8);
368 ctx.lineTo(7, 4);
369 ctx.lineTo(0, 0);
370 ctx.fill();
371 ctx.closePath();
372
373 var ctx = document.getCSSCanvasContext("2d", "arrowDown", 10, 10);
374
375 ctx.fillStyle = "rgb(90,90,90)";
376 ctx.beginPath();
377 ctx.moveTo(0, 0);
378 ctx.lineTo(8, 0);
379 ctx.lineTo(4, 7);
380 ctx.lineTo(0, 0);
381 ctx.fill();
382 ctx.closePath();
383}
384
385function expandFunction(sectionId)
386{
387 return function() {
388 document.querySelector('#' + sectionId + ' > .expanded').className = 'expanded';
389 document.querySelector('#' + sectionId + ' > .collapsed').className = 'collapsed hidden';
390 };
391}
392
393function collapseFunction(sectionId)
394{
395 return function() {
396 document.querySelector('#' + sectionId + ' > .expanded').className = 'expanded hidden';
397 document.querySelector('#' + sectionId + ' > .collapsed').className = 'collapsed';
398 };
399}
400
401function initButtons()
402{
403 var sections = document.querySelectorAll('.collapsible');
404 for (var i = 0; i < sections.length; i++) {
405 var sectionId = 'collapsible' + i;
406 sections[i].id = sectionId;
407
408 var expandedPart = sections[i].querySelector('#' + sectionId + ' > .expanded');
409 var collapseButton = expandedPart.querySelector('.collapse-button');
410 collapseButton.onclick = collapseFunction(sectionId);
411 collapseButton.onmousedown = handleButtonMouseDown;
412
413 var collapsedPart = sections[i].querySelector('#' + sectionId + ' > .collapsed');
414 var expandButton = collapsedPart.querySelector('.expand-button');
415 expandButton.onclick = expandFunction(sectionId);
416 expandButton.onmousedown = handleButtonMouseDown;
417 }
418}
419
420function handleButtonMouseDown(e)
421{
422 // To prevent selection on double click
423 e.preventDefault();
424}
Note: See TracBrowser for help on using the repository browser.