~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/xml/XMLViewer.js

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

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