1/*
2 * Copyright (C) 2011 Google Inc.  All rights reserved.
3 * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
4 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
5 * Copyright (C) 2009 Joseph Pecoraro
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1.  Redistributions of source code must retain the above copyright
12 *     notice, this list of conditions and the following disclaimer.
13 * 2.  Redistributions in binary form must reproduce the above copyright
14 *     notice, this list of conditions and the following disclaimer in the
15 *     documentation and/or other materials provided with the distribution.
16 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
17 *     its contributors may be used to endorse or promote products derived
18 *     from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32WebInspector.DOMPresentationUtils = {}
33
34WebInspector.DOMPresentationUtils.decorateNodeLabel = function(node, parentElement)
35{
36    var title = node.nodeNameInCorrectCase();
37
38    var nameElement = document.createElement("span");
39    nameElement.textContent = title;
40    parentElement.appendChild(nameElement);
41
42    var idAttribute = node.getAttribute("id");
43    if (idAttribute) {
44        var idElement = document.createElement("span");
45        parentElement.appendChild(idElement);
46
47        var part = "#" + idAttribute;
48        title += part;
49        idElement.appendChild(document.createTextNode(part));
50
51        // Mark the name as extra, since the ID is more important.
52        nameElement.className = "extra";
53    }
54
55    var classAttribute = node.getAttribute("class");
56    if (classAttribute) {
57        var classes = classAttribute.split(/\s+/);
58        var foundClasses = {};
59
60        if (classes.length) {
61            var classesElement = document.createElement("span");
62            classesElement.className = "extra";
63            parentElement.appendChild(classesElement);
64
65            for (var i = 0; i < classes.length; ++i) {
66                var className = classes[i];
67                if (className && !(className in foundClasses)) {
68                    var part = "." + className;
69                    title += part;
70                    classesElement.appendChild(document.createTextNode(part));
71                    foundClasses[className] = true;
72                }
73            }
74        }
75    }
76    parentElement.title = title;
77}
78
79/**
80 * @param {Element} container
81 * @param {string} nodeTitle
82 */
83WebInspector.DOMPresentationUtils.createSpansForNodeTitle = function(container, nodeTitle)
84{
85    var match = nodeTitle.match(/([^#.]+)(#[^.]+)?(\..*)?/);
86    container.createChild("span", "webkit-html-tag-name").textContent = match[1];
87    if (match[2])
88        container.createChild("span", "webkit-html-attribute-value").textContent = match[2];
89    if (match[3])
90        container.createChild("span", "webkit-html-attribute-name").textContent = match[3];
91}
92
93WebInspector.DOMPresentationUtils.linkifyNodeReference = function(node)
94{
95    var link = document.createElement("span");
96    link.className = "node-link";
97    WebInspector.DOMPresentationUtils.decorateNodeLabel(node, link);
98
99    link.addEventListener("click", WebInspector.domAgent.inspectElement.bind(WebInspector.domAgent, node.id), false);
100    link.addEventListener("mouseover", WebInspector.domAgent.highlightDOMNode.bind(WebInspector.domAgent, node.id, "", undefined), false);
101    link.addEventListener("mouseout", WebInspector.domAgent.hideDOMNodeHighlight.bind(WebInspector.domAgent), false);
102
103    return link;
104}
105
106WebInspector.DOMPresentationUtils.linkifyNodeById = function(nodeId)
107{
108    var node = WebInspector.domAgent.nodeForId(nodeId);
109    if (!node)
110        return document.createTextNode(WebInspector.UIString("<node>"));
111    return WebInspector.DOMPresentationUtils.linkifyNodeReference(node);
112}
113
114/**
115 * @param {string} imageURL
116 * @param {boolean} showDimensions
117 * @param {function(Element=)} userCallback
118 * @param {Object=} precomputedDimensions
119 */
120WebInspector.DOMPresentationUtils.buildImagePreviewContents = function(imageURL, showDimensions, userCallback, precomputedDimensions)
121{
122    var resource = WebInspector.resourceTreeModel.resourceForURL(imageURL);
123    if (!resource) {
124        userCallback();
125        return;
126    }
127
128    var imageElement = document.createElement("img");
129    imageElement.addEventListener("load", buildContent, false);
130    imageElement.addEventListener("error", errorCallback, false);
131    resource.populateImageSource(imageElement);
132
133    function errorCallback()
134    {
135        // Drop the event parameter when invoking userCallback.
136        userCallback();
137    }
138
139    function buildContent()
140    {
141        var container = document.createElement("table");
142        container.className = "image-preview-container";
143        var naturalWidth = precomputedDimensions ? precomputedDimensions.naturalWidth : imageElement.naturalWidth;
144        var naturalHeight = precomputedDimensions ? precomputedDimensions.naturalHeight : imageElement.naturalHeight;
145        var offsetWidth = precomputedDimensions ? precomputedDimensions.offsetWidth : naturalWidth;
146        var offsetHeight = precomputedDimensions ? precomputedDimensions.offsetHeight : naturalHeight;
147        var description;
148        if (showDimensions) {
149            if (offsetHeight === naturalHeight && offsetWidth === naturalWidth)
150                description = WebInspector.UIString("%d \xd7 %d pixels", offsetWidth, offsetHeight);
151            else
152                description = WebInspector.UIString("%d \xd7 %d pixels (Natural: %d \xd7 %d pixels)", offsetWidth, offsetHeight, naturalWidth, naturalHeight);
153        }
154
155        container.createChild("tr").createChild("td", "image-container").appendChild(imageElement);
156        if (description)
157            container.createChild("tr").createChild("td").createChild("span", "description").textContent = description;
158        userCallback(container);
159    }
160}
161