15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011 Google Inc.  All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Joseph Pecoraro
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1.  Redistributions of source code must retain the above copyright
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     notice, this list of conditions and the following disclaimer.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2.  Redistributions in binary form must reproduce the above copyright
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     notice, this list of conditions and the following disclaimer in the
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     documentation and/or other materials provided with the distribution.
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     its contributors may be used to endorse or promote products derived
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     from this software without specific prior written permission.
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.DOMPresentationUtils = {}
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.DOMPresentationUtils.decorateNodeLabel = function(node, parentElement)
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    var title = node.nodeNameInCorrectCase();
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    var nameElement = document.createElement("span");
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    nameElement.textContent = title;
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    parentElement.appendChild(nameElement);
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    var idAttribute = node.getAttribute("id");
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (idAttribute) {
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var idElement = document.createElement("span");
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        parentElement.appendChild(idElement);
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var part = "#" + idAttribute;
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        title += part;
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        idElement.appendChild(document.createTextNode(part));
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Mark the name as extra, since the ID is more important.
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        nameElement.className = "extra";
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    var classAttribute = node.getAttribute("class");
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (classAttribute) {
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var classes = classAttribute.split(/\s+/);
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var foundClasses = {};
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (classes.length) {
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var classesElement = document.createElement("span");
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            classesElement.className = "extra";
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            parentElement.appendChild(classesElement);
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (var i = 0; i < classes.length; ++i) {
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                var className = classes[i];
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (className && !(className in foundClasses)) {
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    var part = "." + className;
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    title += part;
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    classesElement.appendChild(document.createTextNode(part));
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    foundClasses[className] = true;
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    parentElement.title = title;
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
79926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/**
80926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * @param {Element} container
81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * @param {string} nodeTitle
82926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) */
83926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)WebInspector.DOMPresentationUtils.createSpansForNodeTitle = function(container, nodeTitle)
84926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
85926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    var match = nodeTitle.match(/([^#.]+)(#[^.]+)?(\..*)?/);
86926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    container.createChild("span", "webkit-html-tag-name").textContent = match[1];
87926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (match[2])
88926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        container.createChild("span", "webkit-html-attribute-value").textContent = match[2];
89926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (match[3])
90926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        container.createChild("span", "webkit-html-attribute-name").textContent = match[3];
91926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
92926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.DOMPresentationUtils.linkifyNodeReference = function(node)
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    var link = document.createElement("span");
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    link.className = "node-link";
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    WebInspector.DOMPresentationUtils.decorateNodeLabel(node, link);
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    link.addEventListener("click", WebInspector.domAgent.inspectElement.bind(WebInspector.domAgent, node.id), false);
100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    link.addEventListener("mouseover", WebInspector.domAgent.highlightDOMNode.bind(WebInspector.domAgent, node.id, "", undefined), false);
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    link.addEventListener("mouseout", WebInspector.domAgent.hideDOMNodeHighlight.bind(WebInspector.domAgent), false);
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return link;
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.DOMPresentationUtils.linkifyNodeById = function(nodeId)
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    var node = WebInspector.domAgent.nodeForId(nodeId);
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node)
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return document.createTextNode(WebInspector.UIString("<node>"));
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return WebInspector.DOMPresentationUtils.linkifyNodeReference(node);
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/**
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {string} imageURL
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {boolean} showDimensions
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {function(Element=)} userCallback
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {Object=} precomputedDimensions
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.DOMPresentationUtils.buildImagePreviewContents = function(imageURL, showDimensions, userCallback, precomputedDimensions)
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    var resource = WebInspector.resourceTreeModel.resourceForURL(imageURL);
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!resource) {
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        userCallback();
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    var imageElement = document.createElement("img");
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    imageElement.addEventListener("load", buildContent, false);
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    imageElement.addEventListener("error", errorCallback, false);
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    resource.populateImageSource(imageElement);
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function errorCallback()
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Drop the event parameter when invoking userCallback.
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        userCallback();
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function buildContent()
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var container = document.createElement("table");
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        container.className = "image-preview-container";
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var naturalWidth = precomputedDimensions ? precomputedDimensions.naturalWidth : imageElement.naturalWidth;
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var naturalHeight = precomputedDimensions ? precomputedDimensions.naturalHeight : imageElement.naturalHeight;
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var offsetWidth = precomputedDimensions ? precomputedDimensions.offsetWidth : naturalWidth;
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var offsetHeight = precomputedDimensions ? precomputedDimensions.offsetHeight : naturalHeight;
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var description;
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (showDimensions) {
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (offsetHeight === naturalHeight && offsetWidth === naturalWidth)
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                description = WebInspector.UIString("%d \xd7 %d pixels", offsetWidth, offsetHeight);
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            else
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                description = WebInspector.UIString("%d \xd7 %d pixels (Natural: %d \xd7 %d pixels)", offsetWidth, offsetHeight, naturalWidth, naturalHeight);
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        container.createChild("tr").createChild("td", "image-container").appendChild(imageElement);
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (description)
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            container.createChild("tr").createChild("td").createChild("span", "description").textContent = description;
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        userCallback(container);
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
161