adds support for all browsers
diff --git a/weinre.build/build.xml b/weinre.build/build.xml
index 6917c0b..5324454 100644
--- a/weinre.build/build.xml
+++ b/weinre.build/build.xml
@@ -430,6 +430,11 @@
             <fileset dir="${VENDOR}/webkit/WebCore/inspector/front-end"/>
         </copy>
 
+        <!-- Replaces webkit-specific 'const' keyword in inspector files with 'var' to support non-webkit browsers -->
+        <replaceregexp match="const " replace="var " flags="g" byline="true">
+            <fileset dir="${WEB}/client" includes="**/*.js"/>
+        </replaceregexp>
+
         <exec executable="python" failonerror="true" failifexecutionfails="true">
             <arg file="scripts/build-client-html.py"/>
             <arg file="${WEB}"/>
diff --git a/weinre.build/scripts/build-client-html.py b/weinre.build/scripts/build-client-html.py
index 7e1660c..6561c10 100644
--- a/weinre.build/scripts/build-client-html.py
+++ b/weinre.build/scripts/build-client-html.py
@@ -62,7 +62,7 @@
                 '<meta http-equiv="X-UA-Compatible" content="chrome=1">\n'
                 '<link rel="shortcut icon" href="../images/weinre-icon-64x64.png">\n',
                 '<title>weinre</title>\n',
-                '<script type="text/javascript" src="weinre/check-for-webkit.js"></script>\n',
+                '<script type="text/javascript" src="weinre/browser-support-check.js"></script>\n',
                 '<script type="text/javascript" src="weinre/hacks.js"></script>\n',
                 '<script type="text/javascript" src="../modjewel.js"></script>\n',
                 '<script type="text/javascript">modjewel.require("modjewel").warnOnRecursiveRequire(true)</script>\n',
diff --git a/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/AuditLauncherView.js b/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/AuditLauncherView.js
new file mode 100644
index 0000000..e7ab735
--- /dev/null
+++ b/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/AuditLauncherView.js
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.AuditLauncherView = function(runnerCallback)
+{
+    WebInspector.View.call(this);
+    this._runnerCallback = runnerCallback;
+    this._categoryIdPrefix = "audit-category-item-";
+    this._auditRunning = false;
+
+    this.element.addStyleClass("audit-launcher-view");
+
+    this._contentElement = document.createElement("div");
+    this._contentElement.className = "audit-launcher-view-content";
+    this.element.appendChild(this._contentElement);
+    this._boundCategoryClickListener = this._categoryClicked.bind(this);
+
+    this._resetResourceCount();
+
+    this._sortedCategories = [];
+
+    this._headerElement = document.createElement("h1");
+    this._headerElement.className = "no-audits";
+    this._headerElement.textContent = WebInspector.UIString("No audits to run");
+    this._contentElement.appendChild(this._headerElement);
+
+    WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceStarted, this._onResourceStarted, this);
+    WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceFinished, this._onResourceFinished, this);
+}
+
+WebInspector.AuditLauncherView.prototype = {
+    _resetResourceCount: function()
+    {
+        this._loadedResources = 0;
+        this._totalResources = 0;
+    },
+
+    _onResourceStarted: function(event)
+    {
+        var resource = event.data;
+        // Ignore long-living WebSockets for the sake of progress indicator, as we won't be waiting them anyway.
+        if (resource.type === WebInspector.Resource.Type.WebSocket)
+            return;
+        ++this._totalResources;
+        this._updateResourceProgress();
+    },
+
+    _onResourceFinished: function(event)
+    {
+        var resource = event.data;
+        // See resorceStarted for details.
+        if (resource.type === WebInspector.Resource.Type.WebSocket)
+            return;
+        ++this._loadedResources;
+        this._updateResourceProgress();
+    },
+
+    addCategory: function(category)
+    {
+        if (!this._sortedCategories.length)
+            this._createLauncherUI();
+
+        var categoryElement = this._createCategoryElement(category.displayName, category.id);
+        category._checkboxElement = categoryElement.firstChild;
+        if (this._selectAllCheckboxElement.checked) {
+            category._checkboxElement.checked = true;
+            ++this._currentCategoriesCount;
+        }
+
+        function compareCategories(a, b)
+        {
+            var aTitle = a.displayName || "";
+            var bTitle = b.displayName || "";
+            return aTitle.localeCompare(bTitle);
+        }
+        var insertBefore = insertionIndexForObjectInListSortedByFunction(category, this._sortedCategories, compareCategories);
+        this._categoriesElement.insertBefore(categoryElement, this._categoriesElement.children[insertBefore] || null);
+        this._sortedCategories.splice(insertBefore, 0, category);
+        this._updateButton();
+    },
+
+    _setAuditRunning: function(auditRunning)
+    {
+        if (this._auditRunning === auditRunning)
+            return;
+        this._auditRunning = auditRunning;
+        this._updateButton();
+        this._updateResourceProgress();
+    },
+
+    _launchButtonClicked: function(event)
+    {
+        var catIds = [];
+        var childNodes = this._categoriesElement.childNodes;
+        for (var category = 0; category < this._sortedCategories.length; ++category) {
+            if (this._sortedCategories[category]._checkboxElement.checked)
+                catIds.push(this._sortedCategories[category].id);
+        }
+
+        this._setAuditRunning(true);
+        this._runnerCallback(catIds, this._auditPresentStateElement.checked, this._setAuditRunning.bind(this, false));
+    },
+
+    _selectAllClicked: function(checkCategories)
+    {
+        var childNodes = this._categoriesElement.childNodes;
+        for (var i = 0, length = childNodes.length; i < length; ++i)
+            childNodes[i].firstChild.checked = checkCategories;
+        this._currentCategoriesCount = checkCategories ? this._sortedCategories.length : 0;
+        this._updateButton();
+    },
+
+    _categoryClicked: function(event)
+    {
+        this._currentCategoriesCount += event.target.checked ? 1 : -1;
+        this._selectAllCheckboxElement.checked = this._currentCategoriesCount === this._sortedCategories.length;
+        this._updateButton();
+    },
+
+    _createCategoryElement: function(title, id)
+    {
+        var labelElement = document.createElement("label");
+        labelElement.id = this._categoryIdPrefix + id;
+
+        var element = document.createElement("input");
+        element.type = "checkbox";
+        if (id !== "")
+            element.addEventListener("click", this._boundCategoryClickListener, false);
+        labelElement.appendChild(element);
+        labelElement.appendChild(document.createTextNode(title));
+
+        return labelElement;
+    },
+
+    _createLauncherUI: function()
+    {
+        this._headerElement = document.createElement("h1");
+        this._headerElement.textContent = WebInspector.UIString("Select audits to run");
+
+        for (var child = 0; child < this._contentElement.children.length; ++child)
+            this._contentElement.removeChild(this._contentElement.children[child]);
+
+        this._contentElement.appendChild(this._headerElement);
+
+        function handleSelectAllClick(event)
+        {
+            this._selectAllClicked(event.target.checked);
+        }
+        var categoryElement = this._createCategoryElement(WebInspector.UIString("Select All"), "");
+        categoryElement.id = "audit-launcher-selectall";
+        this._selectAllCheckboxElement = categoryElement.firstChild;
+        this._selectAllCheckboxElement.checked = true;
+        this._selectAllCheckboxElement.addEventListener("click", handleSelectAllClick.bind(this), false);
+        this._contentElement.appendChild(categoryElement);
+
+        this._categoriesElement = document.createElement("div");
+        this._categoriesElement.className = "audit-categories-container";
+        this._contentElement.appendChild(this._categoriesElement);
+
+        this._currentCategoriesCount = 0;
+
+        var flexibleSpaceElement = document.createElement("div");
+        flexibleSpaceElement.className = "flexible-space";
+        this._contentElement.appendChild(flexibleSpaceElement);
+
+        this._buttonContainerElement = document.createElement("div");
+        this._buttonContainerElement.className = "button-container";
+
+        var labelElement = document.createElement("label");
+        this._auditPresentStateElement = document.createElement("input");
+        this._auditPresentStateElement.name = "audit-mode";
+        this._auditPresentStateElement.type = "radio";
+        this._auditPresentStateElement.checked = true;
+        this._auditPresentStateLabelElement = document.createTextNode(WebInspector.UIString("Audit Present State"));
+        labelElement.appendChild(this._auditPresentStateElement);
+        labelElement.appendChild(this._auditPresentStateLabelElement);
+        this._buttonContainerElement.appendChild(labelElement);
+
+        labelElement = document.createElement("label");
+        this.auditReloadedStateElement = document.createElement("input");
+        this.auditReloadedStateElement.name = "audit-mode";
+        this.auditReloadedStateElement.type = "radio";
+        labelElement.appendChild(this.auditReloadedStateElement);
+        labelElement.appendChild(document.createTextNode("Reload Page and Audit on Load"));
+        this._buttonContainerElement.appendChild(labelElement);
+
+        this._launchButton = document.createElement("button");
+        this._launchButton.type = "button";
+        this._launchButton.textContent = WebInspector.UIString("Run");
+        this._launchButton.addEventListener("click", this._launchButtonClicked.bind(this), false);
+        this._buttonContainerElement.appendChild(this._launchButton);
+
+        this._resourceProgressContainer = document.createElement("span");
+        this._resourceProgressContainer.className = "resource-progress";
+        var resourceProgressImage = document.createElement("img");
+        this._resourceProgressContainer.appendChild(resourceProgressImage);
+        this._resourceProgressTextElement = document.createElement("span");
+        this._resourceProgressContainer.appendChild(this._resourceProgressTextElement);
+        this._buttonContainerElement.appendChild(this._resourceProgressContainer);
+
+        this._contentElement.appendChild(this._buttonContainerElement);
+
+        this._selectAllClicked(this._selectAllCheckboxElement.checked);
+        this._updateButton();
+        this._updateResourceProgress();
+    },
+
+    _updateResourceProgress: function()
+    {
+        if (!this._resourceProgressContainer)
+            return;
+
+        if (!this._auditRunning) {
+            this._resetResourceCount();
+            this._resourceProgressContainer.addStyleClass("hidden");
+        } else
+            this._resourceProgressContainer.removeStyleClass("hidden");
+        this._resourceProgressTextElement.textContent = WebInspector.UIString("Loading (%d of %d)", this._loadedResources, this._totalResources);
+    },
+
+    _updateButton: function()
+    {
+        this._launchButton.disabled = !this._currentCategoriesCount || this._auditRunning;
+    }
+}
+
+WebInspector.AuditLauncherView.prototype.__proto__ = WebInspector.View.prototype;
diff --git a/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/ConsoleView.js b/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/ConsoleView.js
new file mode 100644
index 0000000..42fd799
--- /dev/null
+++ b/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/ConsoleView.js
@@ -0,0 +1,1156 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
+ * Copyright (C) 2009 Joseph Pecoraro
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+const ExpressionStopCharacters = " =:[({;,!+-*/&|^<>";
+
+WebInspector.ConsoleView = function(drawer)
+{
+    WebInspector.View.call(this, document.getElementById("console-view"));
+
+    this.messages = [];
+    this.drawer = drawer;
+
+    this.clearButton = document.getElementById("clear-console-status-bar-item");
+    this.clearButton.title = WebInspector.UIString("Clear console log.");
+    this.clearButton.addEventListener("click", this._clearButtonClicked.bind(this), false);
+
+    this.messagesElement = document.getElementById("console-messages");
+    this.messagesElement.addEventListener("selectstart", this._messagesSelectStart.bind(this), false);
+    this.messagesElement.addEventListener("click", this._messagesClicked.bind(this), true);
+
+    this.promptElement = document.getElementById("console-prompt");
+    this.promptElement.setAttribute("contenteditable", "true");
+    this.promptElement.className = "source-code";
+    this.promptElement.addEventListener("keydown", this._promptKeyDown.bind(this), true);
+    this.prompt = new WebInspector.TextPrompt(this.promptElement, this.completions.bind(this), ExpressionStopCharacters + ".");
+    this.prompt.history = WebInspector.settings.consoleHistory;
+
+    this.topGroup = new WebInspector.ConsoleGroup(null);
+    this.messagesElement.insertBefore(this.topGroup.element, this.promptElement);
+    this.currentGroup = this.topGroup;
+
+    this.toggleConsoleButton = document.getElementById("console-status-bar-item");
+    this.toggleConsoleButton.title = WebInspector.UIString("Show console.");
+    this.toggleConsoleButton.addEventListener("click", this._toggleConsoleButtonClicked.bind(this), false);
+
+    // Will hold the list of filter elements
+    this.filterBarElement = document.getElementById("console-filter");
+
+    function createDividerElement() {
+        var dividerElement = document.createElement("div");
+        dividerElement.addStyleClass("scope-bar-divider");
+        this.filterBarElement.appendChild(dividerElement);
+    }
+
+    var updateFilterHandler = this._updateFilter.bind(this);
+    function createFilterElement(category, label) {
+        var categoryElement = document.createElement("li");
+        categoryElement.category = category;
+        categoryElement.className = category;
+        categoryElement.addEventListener("click", updateFilterHandler, false);
+        categoryElement.textContent = label;
+
+        this.filterBarElement.appendChild(categoryElement);
+
+        return categoryElement;
+    }
+
+    this.allElement = createFilterElement.call(this, "all", WebInspector.UIString("All"));
+    createDividerElement.call(this);
+    this.errorElement = createFilterElement.call(this, "errors", WebInspector.UIString("Errors"));
+    this.warningElement = createFilterElement.call(this, "warnings", WebInspector.UIString("Warnings"));
+    this.logElement = createFilterElement.call(this, "logs", WebInspector.UIString("Logs"));
+
+    this.filter(this.allElement, false);
+    this._registerShortcuts();
+
+    this.messagesElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), false);
+
+    this._customFormatters = {
+        "object": this._formatobject,
+        "array":  this._formatarray,
+        "node":   this._formatnode,
+        "string": this._formatstring
+    };
+
+    this._registerConsoleDomainDispatcher();
+}
+
+WebInspector.ConsoleView.prototype = {
+    _registerConsoleDomainDispatcher: function() {
+        var console = this;
+        var dispatcher = {
+            addConsoleMessage: function(payload)
+            {
+                var consoleMessage = new WebInspector.ConsoleMessage(
+                    payload.source,
+                    payload.type,
+                    payload.level,
+                    payload.line,
+                    payload.url,
+                    payload.repeatCount,
+                    payload.message,
+                    payload.parameters,
+                    payload.stackTrace,
+                    payload.requestId);
+                console.addMessage(consoleMessage);
+            },
+
+            updateConsoleMessageExpiredCount: function(count)
+            {
+                var message = String.sprintf(WebInspector.UIString("%d console messages are not shown."), count);
+                console.addMessage(WebInspector.ConsoleMessage.createTextMessage(message, WebInspector.ConsoleMessage.MessageLevel.Warning));
+            },
+
+            updateConsoleMessageRepeatCount: function(count)
+            {
+                var msg = console.previousMessage;
+                var prevRepeatCount = msg.totalRepeatCount;
+
+                if (!console.commandSincePreviousMessage) {
+                    msg.repeatDelta = count - prevRepeatCount;
+                    msg.repeatCount = msg.repeatCount + msg.repeatDelta;
+                    msg.totalRepeatCount = count;
+                    msg._updateRepeatCount();
+                    console._incrementErrorWarningCount(msg);
+                } else {
+                    var msgCopy = new WebInspector.ConsoleMessage(msg.source, msg.type, msg.level, msg.line, msg.url, count - prevRepeatCount, msg._messageText, msg._parameters, msg._stackTrace, msg._requestId);
+                    msgCopy.totalRepeatCount = count;
+                    msgCopy._formatMessage();
+                    console.addMessage(msgCopy);
+                }
+            },
+
+            consoleMessagesCleared: function()
+            {
+                console.clearMessages();
+            },
+        }
+        InspectorBackend.registerDomainDispatcher("Console", dispatcher);
+    },
+
+    _updateFilter: function(e)
+    {
+        var isMac = WebInspector.isMac();
+        var selectMultiple = false;
+        if (isMac && e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey)
+            selectMultiple = true;
+        if (!isMac && e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey)
+            selectMultiple = true;
+
+        this.filter(e.target, selectMultiple);
+    },
+
+    filter: function(target, selectMultiple)
+    {
+        function unselectAll()
+        {
+            this.allElement.removeStyleClass("selected");
+            this.errorElement.removeStyleClass("selected");
+            this.warningElement.removeStyleClass("selected");
+            this.logElement.removeStyleClass("selected");
+
+            this.messagesElement.removeStyleClass("filter-all");
+            this.messagesElement.removeStyleClass("filter-errors");
+            this.messagesElement.removeStyleClass("filter-warnings");
+            this.messagesElement.removeStyleClass("filter-logs");
+        }
+
+        var targetFilterClass = "filter-" + target.category;
+
+        if (target.category === "all") {
+            if (target.hasStyleClass("selected")) {
+                // We can't unselect all, so we break early here
+                return;
+            }
+
+            unselectAll.call(this);
+        } else {
+            // Something other than all is being selected, so we want to unselect all
+            if (this.allElement.hasStyleClass("selected")) {
+                this.allElement.removeStyleClass("selected");
+                this.messagesElement.removeStyleClass("filter-all");
+            }
+        }
+
+        if (!selectMultiple) {
+            // If multiple selection is off, we want to unselect everything else
+            // and just select ourselves.
+            unselectAll.call(this);
+
+            target.addStyleClass("selected");
+            this.messagesElement.addStyleClass(targetFilterClass);
+
+            return;
+        }
+
+        if (target.hasStyleClass("selected")) {
+            // If selectMultiple is turned on, and we were selected, we just
+            // want to unselect ourselves.
+            target.removeStyleClass("selected");
+            this.messagesElement.removeStyleClass(targetFilterClass);
+        } else {
+            // If selectMultiple is turned on, and we weren't selected, we just
+            // want to select ourselves.
+            target.addStyleClass("selected");
+            this.messagesElement.addStyleClass(targetFilterClass);
+        }
+    },
+
+    _toggleConsoleButtonClicked: function()
+    {
+        this.drawer.visibleView = this;
+    },
+
+    attach: function(mainElement, statusBarElement)
+    {
+        mainElement.appendChild(this.element);
+        statusBarElement.appendChild(this.clearButton);
+        statusBarElement.appendChild(this.filterBarElement);
+    },
+
+    show: function()
+    {
+        this.toggleConsoleButton.addStyleClass("toggled-on");
+        this.toggleConsoleButton.title = WebInspector.UIString("Hide console.");
+        if (!this.prompt.isCaretInsidePrompt())
+            this.prompt.moveCaretToEndOfPrompt();
+    },
+
+    afterShow: function()
+    {
+        WebInspector.currentFocusElement = this.promptElement;
+    },
+
+    hide: function()
+    {
+        this.toggleConsoleButton.removeStyleClass("toggled-on");
+        this.toggleConsoleButton.title = WebInspector.UIString("Show console.");
+    },
+
+    _scheduleScrollIntoView: function()
+    {
+        if (this._scrollIntoViewTimer)
+            return;
+
+        function scrollIntoView()
+        {
+            this.promptElement.scrollIntoView(true);
+            delete this._scrollIntoViewTimer;
+        }
+        this._scrollIntoViewTimer = setTimeout(scrollIntoView.bind(this), 20);
+    },
+
+    addMessage: function(msg)
+    {
+        var shouldScrollToLastMessage = this.messagesElement.isScrolledToBottom();
+
+        if (msg instanceof WebInspector.ConsoleMessage && !(msg instanceof WebInspector.ConsoleCommandResult)) {
+            this._incrementErrorWarningCount(msg);
+            WebInspector.resourceTreeModel.addConsoleMessage(msg);
+            WebInspector.panels.scripts.addConsoleMessage(msg);
+            this.commandSincePreviousMessage = false;
+            this.previousMessage = msg;
+        } else if (msg instanceof WebInspector.ConsoleCommand) {
+            if (this.previousMessage) {
+                this.commandSincePreviousMessage = true;
+            }
+        }
+
+        this.messages.push(msg);
+
+        if (msg.type === WebInspector.ConsoleMessage.MessageType.EndGroup) {
+            var parentGroup = this.currentGroup.parentGroup
+            if (parentGroup)
+                this.currentGroup = parentGroup;
+        } else {
+            if (msg.type === WebInspector.ConsoleMessage.MessageType.StartGroup || msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) {
+                var group = new WebInspector.ConsoleGroup(this.currentGroup);
+                this.currentGroup.messagesElement.appendChild(group.element);
+                this.currentGroup = group;
+            }
+
+            this.currentGroup.addMessage(msg);
+        }
+
+        if (shouldScrollToLastMessage)
+            this._scheduleScrollIntoView();
+    },
+
+    _incrementErrorWarningCount: function(msg)
+    {
+        switch (msg.level) {
+            case WebInspector.ConsoleMessage.MessageLevel.Warning:
+                WebInspector.warnings += msg.repeatDelta;
+                break;
+            case WebInspector.ConsoleMessage.MessageLevel.Error:
+                WebInspector.errors += msg.repeatDelta;
+                break;
+        }
+    },
+
+    requestClearMessages: function()
+    {
+        InspectorBackend.clearConsoleMessages();
+    },
+
+    clearMessages: function()
+    {
+        WebInspector.resourceTreeModel.clearConsoleMessages();
+        WebInspector.panels.scripts.clearConsoleMessages();
+
+        this.messages = [];
+
+        this.currentGroup = this.topGroup;
+        this.topGroup.messagesElement.removeChildren();
+
+        WebInspector.errors = 0;
+        WebInspector.warnings = 0;
+
+        delete this.commandSincePreviousMessage;
+        delete this.previousMessage;
+    },
+
+    completions: function(wordRange, bestMatchOnly, completionsReadyCallback)
+    {
+        // Pass less stop characters to rangeOfWord so the range will be a more complete expression.
+        var expressionRange = wordRange.startContainer.rangeOfWord(wordRange.startOffset, ExpressionStopCharacters, this.promptElement, "backward");
+        var expressionString = expressionRange.toString();
+        var lastIndex = expressionString.length - 1;
+
+        var dotNotation = (expressionString[lastIndex] === ".");
+        var bracketNotation = (expressionString[lastIndex] === "[");
+
+        if (dotNotation || bracketNotation)
+            expressionString = expressionString.substr(0, lastIndex);
+
+        var prefix = wordRange.toString();
+        if (!expressionString && !prefix)
+            return;
+
+        var reportCompletions = this._reportCompletions.bind(this, bestMatchOnly, completionsReadyCallback, dotNotation, bracketNotation, prefix);
+        // Collect comma separated object properties for the completion.
+
+        var includeCommandLineAPI = (!dotNotation && !bracketNotation);
+        var injectedScriptAccess;
+        if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused)
+            InspectorBackend.getCompletionsOnCallFrame(WebInspector.panels.scripts.selectedCallFrameId(), expressionString, includeCommandLineAPI, reportCompletions);
+        else
+            InspectorBackend.getCompletions(expressionString, includeCommandLineAPI, reportCompletions);
+    },
+
+    _reportCompletions: function(bestMatchOnly, completionsReadyCallback, dotNotation, bracketNotation, prefix, result, isException) {
+        if (isException)
+            return;
+
+        if (bracketNotation) {
+            if (prefix.length && prefix[0] === "'")
+                var quoteUsed = "'";
+            else
+                var quoteUsed = "\"";
+        }
+
+        var results = [];
+        var properties = Object.keys(result).sort();
+
+        for (var i = 0; i < properties.length; ++i) {
+            var property = properties[i];
+
+            if (dotNotation && !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(property))
+                continue;
+
+            if (bracketNotation) {
+                if (!/^[0-9]+$/.test(property))
+                    property = quoteUsed + property.escapeCharacters(quoteUsed + "\\") + quoteUsed;
+                property += "]";
+            }
+
+            if (property.length < prefix.length)
+                continue;
+            if (property.indexOf(prefix) !== 0)
+                continue;
+
+            results.push(property);
+            if (bestMatchOnly)
+                break;
+        }
+        completionsReadyCallback(results);
+    },
+
+    _clearButtonClicked: function()
+    {
+        this.requestClearMessages();
+    },
+
+    _handleContextMenuEvent: function(event)
+    {
+        if (!window.getSelection().isCollapsed) {
+            // If there is a selection, we want to show our normal context menu
+            // (with Copy, etc.), and not Clear Console.
+            return;
+        }
+
+        var itemAction = function () {
+            WebInspector.settings.monitoringXHREnabled = !WebInspector.settings.monitoringXHREnabled;
+            InspectorBackend.setMonitoringXHREnabled(WebInspector.settings.monitoringXHREnabled);
+        }.bind(this);
+        var contextMenu = new WebInspector.ContextMenu();
+        contextMenu.appendCheckboxItem(WebInspector.UIString("XMLHttpRequest logging"), itemAction, WebInspector.settings.monitoringXHREnabled)
+        contextMenu.appendItem(WebInspector.UIString("Clear Console"), this.requestClearMessages.bind(this));
+        contextMenu.show(event);
+    },
+
+    _messagesSelectStart: function(event)
+    {
+        if (this._selectionTimeout)
+            clearTimeout(this._selectionTimeout);
+
+        this.prompt.clearAutoComplete();
+
+        function moveBackIfOutside()
+        {
+            delete this._selectionTimeout;
+            if (!this.prompt.isCaretInsidePrompt() && window.getSelection().isCollapsed)
+                this.prompt.moveCaretToEndOfPrompt();
+            this.prompt.autoCompleteSoon();
+        }
+
+        this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100);
+    },
+
+    _messagesClicked: function(event)
+    {
+        var link = event.target.enclosingNodeOrSelfWithNodeName("a");
+        if (!link || !link.representedNode)
+            return;
+
+        WebInspector.updateFocusedNode(link.representedNode.id);
+        event.stopPropagation();
+        event.preventDefault();
+    },
+
+    _registerShortcuts: function()
+    {
+        this._shortcuts = {};
+
+        var shortcut = WebInspector.KeyboardShortcut;
+        var shortcutK = shortcut.makeDescriptor("k", WebInspector.KeyboardShortcut.Modifiers.Meta);
+        // This case requires a separate bound function as its isMacOnly property should not be shared among different shortcut handlers.
+        this._shortcuts[shortcutK.key] = this.requestClearMessages.bind(this);
+        this._shortcuts[shortcutK.key].isMacOnly = true;
+
+        var clearConsoleHandler = this.requestClearMessages.bind(this);
+        var shortcutL = shortcut.makeDescriptor("l", WebInspector.KeyboardShortcut.Modifiers.Ctrl);
+        this._shortcuts[shortcutL.key] = clearConsoleHandler;
+
+        var section = WebInspector.shortcutsHelp.section(WebInspector.UIString("Console"));
+        var keys = WebInspector.isMac() ? [ shortcutK.name, shortcutL.name ] : [ shortcutL.name ];
+        section.addAlternateKeys(keys, WebInspector.UIString("Clear Console"));
+
+        keys = [
+            shortcut.shortcutToString(shortcut.Keys.Tab),
+            shortcut.shortcutToString(shortcut.Keys.Tab, shortcut.Modifiers.Shift)
+        ];
+        section.addRelatedKeys(keys, WebInspector.UIString("Next/previous suggestion"));
+        section.addKey(shortcut.shortcutToString(shortcut.Keys.Right), WebInspector.UIString("Accept suggestion"));
+        keys = [
+            shortcut.shortcutToString(shortcut.Keys.Down),
+            shortcut.shortcutToString(shortcut.Keys.Up)
+        ];
+        section.addRelatedKeys(keys, WebInspector.UIString("Next/previous line"));
+        keys = [
+            shortcut.shortcutToString("N", shortcut.Modifiers.Alt),
+            shortcut.shortcutToString("P", shortcut.Modifiers.Alt)
+        ];
+        if (WebInspector.isMac())
+            section.addRelatedKeys(keys, WebInspector.UIString("Next/previous command"));
+        section.addKey(shortcut.shortcutToString(shortcut.Keys.Enter), WebInspector.UIString("Execute command"));
+    },
+
+    _promptKeyDown: function(event)
+    {
+        if (isEnterKey(event)) {
+            this._enterKeyPressed(event);
+            return;
+        }
+
+        var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
+        var handler = this._shortcuts[shortcut];
+        if (handler) {
+            if (!this._shortcuts[shortcut].isMacOnly || WebInspector.isMac()) {
+                handler();
+                event.preventDefault();
+                return;
+            }
+        }
+    },
+
+    evalInInspectedWindow: function(expression, objectGroup, includeCommandLineAPI, callback)
+    {
+        if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused) {
+            WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, objectGroup, includeCommandLineAPI, callback);
+            return;
+        }
+
+        if (!expression) {
+            // There is no expression, so the completion should happen against global properties.
+            expression = "this";
+        }
+
+        function evalCallback(result)
+        {
+            callback(WebInspector.RemoteObject.fromPayload(result));
+        }
+        InspectorBackend.evaluate(expression, objectGroup, includeCommandLineAPI, evalCallback);
+    },
+
+    _enterKeyPressed: function(event)
+    {
+        if (event.altKey || event.ctrlKey || event.shiftKey)
+            return;
+
+        event.preventDefault();
+        event.stopPropagation();
+
+        this.prompt.clearAutoComplete(true);
+
+        var str = this.prompt.text;
+        if (!str.length)
+            return;
+
+        var commandMessage = new WebInspector.ConsoleCommand(str);
+        this.addMessage(commandMessage);
+
+        var self = this;
+        function printResult(result)
+        {
+            self.prompt.history.push(str);
+            self.prompt.historyOffset = 0;
+            self.prompt.text = "";
+
+            WebInspector.settings.consoleHistory = self.prompt.history.slice(-30);
+
+            self.addMessage(new WebInspector.ConsoleCommandResult(result, commandMessage));
+        }
+        this.evalInInspectedWindow(str, "console", true, printResult);
+    },
+
+    _format: function(output, forceObjectFormat)
+    {
+        var isProxy = (output != null && typeof output === "object");
+        var type = (forceObjectFormat ? "object" : WebInspector.RemoteObject.type(output));
+
+        var formatter = this._customFormatters[type];
+        if (!formatter || !isProxy) {
+            formatter = this._formatvalue;
+            output = output.description;
+        }
+
+        var span = document.createElement("span");
+        span.className = "console-formatted-" + type + " source-code";
+        formatter.call(this, output, span);
+        return span;
+    },
+
+    _formatvalue: function(val, elem)
+    {
+        elem.appendChild(document.createTextNode(val));
+    },
+
+    _formatobject: function(obj, elem)
+    {
+        elem.appendChild(new WebInspector.ObjectPropertiesSection(obj, obj.description, null, true).element);
+    },
+
+    _formatnode: function(object, elem)
+    {
+        function printNode(nodeId)
+        {
+            if (!nodeId) {
+                // Sometimes DOM is loaded after the sync message is being formatted, so we get no
+                // nodeId here. So we fall back to object formatting here.
+                this._formatobject(object, elem);
+                return;
+            }
+            var treeOutline = new WebInspector.ElementsTreeOutline();
+            treeOutline.showInElementsPanelEnabled = true;
+            treeOutline.rootDOMNode = WebInspector.domAgent.nodeForId(nodeId);
+            treeOutline.element.addStyleClass("outline-disclosure");
+            if (!treeOutline.children[0].hasChildren)
+                treeOutline.element.addStyleClass("single-node");
+            elem.appendChild(treeOutline.element);
+        }
+        object.pushNodeToFrontend(printNode.bind(this));
+    },
+
+    _formatarray: function(arr, elem)
+    {
+        arr.getOwnProperties(false, this._printArray.bind(this, elem));
+    },
+
+    _formatstring: function(output, elem)
+    {
+        var span = document.createElement("span");
+        span.className = "console-formatted-string source-code";
+        span.appendChild(WebInspector.linkifyStringAsFragment(output.description));
+
+        // Make black quotes.
+        elem.removeStyleClass("console-formatted-string");
+        elem.appendChild(document.createTextNode("\""));
+        elem.appendChild(span);
+        elem.appendChild(document.createTextNode("\""));
+    },
+
+    _printArray: function(elem, properties)
+    {
+        if (!properties)
+            return;
+
+        var elements = [];
+        for (var i = 0; i < properties.length; ++i) {
+            var name = properties[i].name;
+            if (name == parseInt(name))
+                elements[name] = this._formatAsArrayEntry(properties[i].value);
+        }
+
+        elem.appendChild(document.createTextNode("["));
+        for (var i = 0; i < elements.length; ++i) {
+            var element = elements[i];
+            if (element)
+                elem.appendChild(element);
+            else
+                elem.appendChild(document.createTextNode("undefined"))
+            if (i < elements.length - 1)
+                elem.appendChild(document.createTextNode(", "));
+        }
+        elem.appendChild(document.createTextNode("]"));
+    },
+
+    _formatAsArrayEntry: function(output)
+    {
+        // Prevent infinite expansion of cross-referencing arrays.
+        return this._format(output, WebInspector.RemoteObject.type(output) === "array");
+    }
+}
+
+WebInspector.ConsoleView.prototype.__proto__ = WebInspector.View.prototype;
+
+WebInspector.ConsoleMessage = function(source, type, level, line, url, repeatCount, message, parameters, stackTrace, requestId)
+{
+    this.source = source;
+    this.type = type;
+    this.level = level;
+    this.line = line;
+    this.url = url;
+    this.repeatCount = repeatCount;
+    this.repeatDelta = repeatCount;
+    this.totalRepeatCount = repeatCount;
+    this._messageText = message;
+    this._parameters = parameters;
+    this._stackTrace = stackTrace;
+    this._requestId = requestId;
+
+    if (stackTrace && stackTrace.length) {
+        var topCallFrame = stackTrace[0];
+        if (!this.url)
+            this.url = topCallFrame.scriptName;
+        if (!this.line)
+            this.line = topCallFrame.lineNumber;
+    }
+
+    this._formatMessage();
+}
+
+WebInspector.ConsoleMessage.createTextMessage = function(text, level)
+{
+    level = level || WebInspector.ConsoleMessage.MessageLevel.Log;
+    return new WebInspector.ConsoleMessage(WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageType.Log, level, 0, null, 1, null, [text], null);
+}
+
+WebInspector.ConsoleMessage.prototype = {
+    _formatMessage: function()
+    {
+        var stackTrace = this._stackTrace;
+        var messageText;
+        switch (this.type) {
+            case WebInspector.ConsoleMessage.MessageType.Trace:
+                messageText = document.createTextNode("console.trace()");
+                break;
+            case WebInspector.ConsoleMessage.MessageType.UncaughtException:
+                messageText = document.createTextNode(this._messageText);
+                break;
+            case WebInspector.ConsoleMessage.MessageType.NetworkError:
+                var resource = this._requestId && WebInspector.networkResourceById(this._requestId);
+                if (resource) {
+                    stackTrace = resource.stackTrace;
+
+                    messageText = document.createElement("span");
+                    messageText.appendChild(document.createTextNode(resource.requestMethod + " "));
+                    messageText.appendChild(WebInspector.linkifyURLAsNode(resource.url));
+                    if (resource.failed)
+                        messageText.appendChild(document.createTextNode(" " + resource.localizedFailDescription));
+                    else
+                        messageText.appendChild(document.createTextNode(" " + resource.statusCode + " (" + resource.statusText + ")"));
+                } else
+                    messageText = this._format([this._messageText]);
+                break;
+            case WebInspector.ConsoleMessage.MessageType.Assert:
+                var args = [WebInspector.UIString("Assertion failed:")];
+                if (this._parameters)
+                    args = args.concat(this._parameters);
+                messageText = this._format(args);
+                break;
+            case WebInspector.ConsoleMessage.MessageType.Object:
+                var obj = this._parameters ? this._parameters[0] : undefined;
+                var args = ["%O", obj];
+                messageText = this._format(args);
+                break;
+            default:
+                var args = this._parameters || [this._messageText];
+                messageText = this._format(args);
+                break;
+        }
+
+        this._formattedMessage = document.createElement("span");
+        this._formattedMessage.className = "console-message-text source-code";
+
+        if (this.url && this.url !== "undefined") {
+            var urlElement = WebInspector.linkifyResourceAsNode(this.url, "scripts", this.line, "console-message-url");
+            this._formattedMessage.appendChild(urlElement);
+        }
+
+        this._formattedMessage.appendChild(messageText);
+
+        if (this._stackTrace) {
+            switch (this.type) {
+                case WebInspector.ConsoleMessage.MessageType.Trace:
+                case WebInspector.ConsoleMessage.MessageType.UncaughtException:
+                case WebInspector.ConsoleMessage.MessageType.NetworkError:
+                case WebInspector.ConsoleMessage.MessageType.Assert: {
+                    var ol = document.createElement("ol");
+                    ol.className = "outline-disclosure";
+                    var treeOutline = new TreeOutline(ol);
+
+                    var content = this._formattedMessage;
+                    var root = new TreeElement(content, null, true);
+                    content.treeElementForTest = root;
+                    treeOutline.appendChild(root);
+                    if (this.type === WebInspector.ConsoleMessage.MessageType.Trace)
+                        root.expand();
+
+                    this._populateStackTraceTreeElement(root);
+                    this._formattedMessage = ol;
+                }
+            }
+        }
+
+        // This is used for inline message bubbles in SourceFrames, or other plain-text representations.
+        this.message = this._formattedMessage.textContent;
+    },
+
+    isErrorOrWarning: function()
+    {
+        return (this.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this.level === WebInspector.ConsoleMessage.MessageLevel.Error);
+    },
+
+    _format: function(parameters)
+    {
+        // This node is used like a Builder. Values are continually appended onto it.
+        var formattedResult = document.createElement("span");
+        if (!parameters.length)
+            return formattedResult;
+
+        // Formatting code below assumes that parameters are all wrappers whereas frontend console
+        // API allows passing arbitrary values as messages (strings, numbers, etc.). Wrap them here.
+        for (var i = 0; i < parameters.length; ++i) {
+            if (typeof parameters[i] === "object")
+                parameters[i] = WebInspector.RemoteObject.fromPayload(parameters[i]);
+            else
+                parameters[i] = WebInspector.RemoteObject.fromPrimitiveValue(parameters[i]);
+        }
+
+        // There can be string log and string eval result. We distinguish between them based on message type.
+        var shouldFormatMessage = WebInspector.RemoteObject.type(parameters[0]) === "string" && this.type !== WebInspector.ConsoleMessage.MessageType.Result;
+
+        // Multiple parameters with the first being a format string. Save unused substitutions.
+        if (shouldFormatMessage) {
+            // Multiple parameters with the first being a format string. Save unused substitutions.
+            var result = this._formatWithSubstitutionString(parameters, formattedResult);
+            parameters = result.unusedSubstitutions;
+            if (parameters.length)
+                formattedResult.appendChild(document.createTextNode(" "));
+        }
+
+        // Single parameter, or unused substitutions from above.
+        for (var i = 0; i < parameters.length; ++i) {
+            // Inline strings when formatting.
+            if (shouldFormatMessage && parameters[i].type === "string")
+                formattedResult.appendChild(document.createTextNode(parameters[i].description));
+            else
+                formattedResult.appendChild(WebInspector.console._format(parameters[i]));
+            if (i < parameters.length - 1)
+                formattedResult.appendChild(document.createTextNode(" "));
+        }
+        return formattedResult;
+    },
+
+    _formatWithSubstitutionString: function(parameters, formattedResult)
+    {
+        var formatters = {}
+        for (var i in String.standardFormatters)
+            formatters[i] = String.standardFormatters[i];
+
+        function consoleFormatWrapper(force)
+        {
+            return function(obj) {
+                return WebInspector.console._format(obj, force);
+            };
+        }
+
+        // Firebug uses %o for formatting objects.
+        formatters.o = consoleFormatWrapper();
+        // Firebug allows both %i and %d for formatting integers.
+        formatters.i = formatters.d;
+        // Support %O to force object formatting, instead of the type-based %o formatting.
+        formatters.O = consoleFormatWrapper(true);
+
+        function append(a, b)
+        {
+            if (!(b instanceof Node))
+                a.appendChild(WebInspector.linkifyStringAsFragment(b.toString()));
+            else
+                a.appendChild(b);
+            return a;
+        }
+
+        // String.format does treat formattedResult like a Builder, result is an object.
+        return String.format(parameters[0].description, parameters.slice(1), formatters, formattedResult, append);
+    },
+
+    toMessageElement: function()
+    {
+        if (this._element)
+            return this._element;
+
+        var element = document.createElement("div");
+        element.message = this;
+        element.className = "console-message";
+
+        this._element = element;
+
+        switch (this.level) {
+            case WebInspector.ConsoleMessage.MessageLevel.Tip:
+                element.addStyleClass("console-tip-level");
+                break;
+            case WebInspector.ConsoleMessage.MessageLevel.Log:
+                element.addStyleClass("console-log-level");
+                break;
+            case WebInspector.ConsoleMessage.MessageLevel.Debug:
+                element.addStyleClass("console-debug-level");
+                break;
+            case WebInspector.ConsoleMessage.MessageLevel.Warning:
+                element.addStyleClass("console-warning-level");
+                break;
+            case WebInspector.ConsoleMessage.MessageLevel.Error:
+                element.addStyleClass("console-error-level");
+                break;
+        }
+
+        if (this.type === WebInspector.ConsoleMessage.MessageType.StartGroup || this.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed)
+            element.addStyleClass("console-group-title");
+
+        if (this.elementsTreeOutline) {
+            element.addStyleClass("outline-disclosure");
+            element.appendChild(this.elementsTreeOutline.element);
+            return element;
+        }
+
+        element.appendChild(this._formattedMessage);
+
+        if (this.repeatCount > 1)
+            this._updateRepeatCount();
+
+        return element;
+    },
+
+    _populateStackTraceTreeElement: function(parentTreeElement)
+    {
+        for (var i = 0; i < this._stackTrace.length; i++) {
+            var frame = this._stackTrace[i];
+
+            var content = document.createElement("div");
+            var messageTextElement = document.createElement("span");
+            messageTextElement.className = "console-message-text source-code";
+            var functionName = frame.functionName || WebInspector.UIString("(anonymous function)");
+            messageTextElement.appendChild(document.createTextNode(functionName));
+            content.appendChild(messageTextElement);
+
+            var urlElement = WebInspector.linkifyResourceAsNode(frame.scriptName, "scripts", frame.lineNumber, "console-message-url");
+            content.appendChild(urlElement);
+
+            var treeElement = new TreeElement(content);
+            parentTreeElement.appendChild(treeElement);
+        }
+    },
+
+    _updateRepeatCount: function() {
+        if (!this.repeatCountElement) {
+            this.repeatCountElement = document.createElement("span");
+            this.repeatCountElement.className = "bubble";
+
+            this._element.insertBefore(this.repeatCountElement, this._element.firstChild);
+            this._element.addStyleClass("repeated-message");
+        }
+        this.repeatCountElement.textContent = this.repeatCount;
+    },
+
+    toString: function()
+    {
+        var sourceString;
+        switch (this.source) {
+            case WebInspector.ConsoleMessage.MessageSource.HTML:
+                sourceString = "HTML";
+                break;
+            case WebInspector.ConsoleMessage.MessageSource.WML:
+                sourceString = "WML";
+                break;
+            case WebInspector.ConsoleMessage.MessageSource.XML:
+                sourceString = "XML";
+                break;
+            case WebInspector.ConsoleMessage.MessageSource.JS:
+                sourceString = "JS";
+                break;
+            case WebInspector.ConsoleMessage.MessageSource.CSS:
+                sourceString = "CSS";
+                break;
+            case WebInspector.ConsoleMessage.MessageSource.Other:
+                sourceString = "Other";
+                break;
+        }
+
+        var typeString;
+        switch (this.type) {
+            case WebInspector.ConsoleMessage.MessageType.Log:
+            case WebInspector.ConsoleMessage.MessageType.UncaughtException:
+            case WebInspector.ConsoleMessage.MessageType.NetworkError:
+                typeString = "Log";
+                break;
+            case WebInspector.ConsoleMessage.MessageType.Object:
+                typeString = "Object";
+                break;
+            case WebInspector.ConsoleMessage.MessageType.Trace:
+                typeString = "Trace";
+                break;
+            case WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed:
+            case WebInspector.ConsoleMessage.MessageType.StartGroup:
+                typeString = "Start Group";
+                break;
+            case WebInspector.ConsoleMessage.MessageType.EndGroup:
+                typeString = "End Group";
+                break;
+            case WebInspector.ConsoleMessage.MessageType.Assert:
+                typeString = "Assert";
+                break;
+            case WebInspector.ConsoleMessage.MessageType.Result:
+                typeString = "Result";
+                break;
+        }
+
+        var levelString;
+        switch (this.level) {
+            case WebInspector.ConsoleMessage.MessageLevel.Tip:
+                levelString = "Tip";
+                break;
+            case WebInspector.ConsoleMessage.MessageLevel.Log:
+                levelString = "Log";
+                break;
+            case WebInspector.ConsoleMessage.MessageLevel.Warning:
+                levelString = "Warning";
+                break;
+            case WebInspector.ConsoleMessage.MessageLevel.Debug:
+                levelString = "Debug";
+                break;
+            case WebInspector.ConsoleMessage.MessageLevel.Error:
+                levelString = "Error";
+                break;
+        }
+
+        return sourceString + " " + typeString + " " + levelString + ": " + this._formattedMessage.textContent + "\n" + this.url + " line " + this.line;
+    },
+
+    isEqual: function(msg)
+    {
+        if (!msg)
+            return false;
+
+        if (this._stackTrace) {
+            if (!msg._stackTrace)
+                return false;
+            var l = this._stackTrace;
+            var r = msg._stackTrace;
+            for (var i = 0; i < l.length; i++) {
+                if (l[i].scriptName !== r[i].scriptName ||
+                    l[i].functionName !== r[i].functionName ||
+                    l[i].lineNumber !== r[i].lineNumber ||
+                    l[i].column !== r[i].column)
+                    return false;
+            }
+        }
+
+        return (this.source === msg.source)
+            && (this.type === msg.type)
+            && (this.level === msg.level)
+            && (this.line === msg.line)
+            && (this.url === msg.url)
+            && (this.message === msg.message)
+            && (this._requestId === msg._requestId);
+    }
+}
+
+// Note: Keep these constants in sync with the ones in Console.h
+WebInspector.ConsoleMessage.MessageSource = {
+    HTML: 0,
+    WML: 1,
+    XML: 2,
+    JS: 3,
+    CSS: 4,
+    Other: 5
+}
+
+WebInspector.ConsoleMessage.MessageType = {
+    Log: 0,
+    Object: 1,
+    Trace: 2,
+    StartGroup: 3,
+    StartGroupCollapsed: 4,
+    EndGroup: 5,
+    Assert: 6,
+    UncaughtException: 7,
+    NetworkError:8,
+    Result: 9
+}
+
+WebInspector.ConsoleMessage.MessageLevel = {
+    Tip: 0,
+    Log: 1,
+    Warning: 2,
+    Error: 3,
+    Debug: 4
+}
+
+WebInspector.ConsoleCommand = function(command)
+{
+    this.command = command;
+}
+
+WebInspector.ConsoleCommand.prototype = {
+    toMessageElement: function()
+    {
+        var element = document.createElement("div");
+        element.command = this;
+        element.className = "console-user-command";
+
+        var commandTextElement = document.createElement("span");
+        commandTextElement.className = "console-message-text source-code";
+        commandTextElement.textContent = this.command;
+        element.appendChild(commandTextElement);
+
+        return element;
+    }
+}
+
+WebInspector.ConsoleCommandResult = function(result, originatingCommand)
+{
+    var level = (result.isError() ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log);
+    this.originatingCommand = originatingCommand;
+    WebInspector.ConsoleMessage.call(this, WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageType.Result, level, -1, null, 1, null, [result]);
+}
+
+WebInspector.ConsoleCommandResult.prototype = {
+    toMessageElement: function()
+    {
+        var element = WebInspector.ConsoleMessage.prototype.toMessageElement.call(this);
+        element.addStyleClass("console-user-command-result");
+        return element;
+    }
+}
+
+WebInspector.ConsoleCommandResult.prototype.__proto__ = WebInspector.ConsoleMessage.prototype;
+
+WebInspector.ConsoleGroup = function(parentGroup)
+{
+    this.parentGroup = parentGroup;
+
+    var element = document.createElement("div");
+    element.className = "console-group";
+    element.group = this;
+    this.element = element;
+
+    var messagesElement = document.createElement("div");
+    messagesElement.className = "console-group-messages";
+    element.appendChild(messagesElement);
+    this.messagesElement = messagesElement;
+}
+
+WebInspector.ConsoleGroup.prototype = {
+    addMessage: function(msg)
+    {
+        var element = msg.toMessageElement();
+
+        if (msg.type === WebInspector.ConsoleMessage.MessageType.StartGroup || msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) {
+            this.messagesElement.parentNode.insertBefore(element, this.messagesElement);
+            element.addEventListener("click", this._titleClicked.bind(this), false);
+            var groupElement = element.enclosingNodeOrSelfWithClass("console-group");
+            if (groupElement && msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed)
+                groupElement.addStyleClass("collapsed");
+        } else
+            this.messagesElement.appendChild(element);
+
+        if (element.previousSibling && msg.originatingCommand && element.previousSibling.command === msg.originatingCommand)
+            element.previousSibling.addStyleClass("console-adjacent-user-command-result");
+    },
+
+    _titleClicked: function(event)
+    {
+        var groupTitleElement = event.target.enclosingNodeOrSelfWithClass("console-group-title");
+        if (groupTitleElement) {
+            var groupElement = groupTitleElement.enclosingNodeOrSelfWithClass("console-group");
+            if (groupElement)
+                if (groupElement.hasStyleClass("collapsed"))
+                    groupElement.removeStyleClass("collapsed");
+                else
+                    groupElement.addStyleClass("collapsed");
+            groupTitleElement.scrollIntoViewIfNeeded(true);
+        }
+
+        event.stopPropagation();
+        event.preventDefault();
+    }
+}
+
diff --git a/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/ElementsTreeOutline.js b/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/ElementsTreeOutline.js
new file mode 100644
index 0000000..dab33a6
--- /dev/null
+++ b/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/ElementsTreeOutline.js
@@ -0,0 +1,1444 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * Copyright (C) 2009 Joseph Pecoraro
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.ElementsTreeOutline = function() {
+    this.element = document.createElement("ol");
+    this.element.addEventListener("mousedown", this._onmousedown.bind(this), false);
+    this.element.addEventListener("mousemove", this._onmousemove.bind(this), false);
+    this.element.addEventListener("mouseout", this._onmouseout.bind(this), false);
+
+    TreeOutline.call(this, this.element);
+
+    this.includeRootDOMNode = true;
+    this.selectEnabled = false;
+    this.showInElementsPanelEnabled = false;
+    this.rootDOMNode = null;
+    this.focusedDOMNode = null;
+
+    this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
+}
+
+WebInspector.ElementsTreeOutline.prototype = {
+    get rootDOMNode()
+    {
+        return this._rootDOMNode;
+    },
+
+    set rootDOMNode(x)
+    {
+        if (this._rootDOMNode === x)
+            return;
+
+        this._rootDOMNode = x;
+
+        this._isXMLMimeType = !!(WebInspector.mainResource && WebInspector.mainResource.mimeType && WebInspector.mainResource.mimeType.match(/x(?:ht)?ml/i));
+
+        this.update();
+    },
+
+    get isXMLMimeType()
+    {
+        return this._isXMLMimeType;
+    },
+
+    nodeNameToCorrectCase: function(nodeName)
+    {
+        return this.isXMLMimeType ? nodeName : nodeName.toLowerCase();
+    },
+
+    get focusedDOMNode()
+    {
+        return this._focusedDOMNode;
+    },
+
+    set focusedDOMNode(x)
+    {
+        if (this._focusedDOMNode === x) {
+            this.revealAndSelectNode(x);
+            return;
+        }
+
+        this._focusedDOMNode = x;
+
+        this.revealAndSelectNode(x);
+
+        // The revealAndSelectNode() method might find a different element if there is inlined text,
+        // and the select() call would change the focusedDOMNode and reenter this setter. So to
+        // avoid calling focusedNodeChanged() twice, first check if _focusedDOMNode is the same
+        // node as the one passed in.
+        if (this._focusedDOMNode === x)
+            this.focusedNodeChanged();
+    },
+
+    get editing()
+    {
+        return this._editing;
+    },
+
+    update: function()
+    {
+        var selectedNode = this.selectedTreeElement ? this.selectedTreeElement.representedObject : null;
+
+        this.removeChildren();
+
+        if (!this.rootDOMNode)
+            return;
+
+        var treeElement;
+        if (this.includeRootDOMNode) {
+            treeElement = new WebInspector.ElementsTreeElement(this.rootDOMNode);
+            treeElement.selectable = this.selectEnabled;
+            this.appendChild(treeElement);
+        } else {
+            // FIXME: this could use findTreeElement to reuse a tree element if it already exists
+            var node = this.rootDOMNode.firstChild;
+            while (node) {
+                treeElement = new WebInspector.ElementsTreeElement(node);
+                treeElement.selectable = this.selectEnabled;
+                this.appendChild(treeElement);
+                node = node.nextSibling;
+            }
+        }
+
+        if (selectedNode)
+            this.revealAndSelectNode(selectedNode);
+    },
+
+    updateSelection: function()
+    {
+        if (!this.selectedTreeElement)
+            return;
+        var element = this.treeOutline.selectedTreeElement;
+        element.updateSelection();
+    },
+
+    focusedNodeChanged: function(forceUpdate) {},
+
+    findTreeElement: function(node)
+    {
+        var treeElement = TreeOutline.prototype.findTreeElement.call(this, node, isAncestorNode, parentNode);
+        if (!treeElement && node.nodeType === Node.TEXT_NODE) {
+            // The text node might have been inlined if it was short, so try to find the parent element.
+            treeElement = TreeOutline.prototype.findTreeElement.call(this, node.parentNode, isAncestorNode, parentNode);
+        }
+
+        return treeElement;
+    },
+
+    createTreeElementFor: function(node)
+    {
+        var treeElement = this.findTreeElement(node);
+        if (treeElement)
+            return treeElement;
+        if (!node.parentNode)
+            return null;
+
+        var treeElement = this.createTreeElementFor(node.parentNode);
+        if (treeElement && treeElement.showChild(node.index))
+            return treeElement.children[node.index];
+
+        return null;
+    },
+
+    set suppressRevealAndSelect(x)
+    {
+        if (this._suppressRevealAndSelect === x)
+            return;
+        this._suppressRevealAndSelect = x;
+    },
+
+    revealAndSelectNode: function(node)
+    {
+        if (!node || this._suppressRevealAndSelect)
+            return;
+
+        var treeElement = this.createTreeElementFor(node);
+        if (!treeElement)
+            return;
+
+        treeElement.reveal();
+        treeElement.select();
+    },
+
+    _treeElementFromEvent: function(event)
+    {
+        var root = this.element;
+
+        // We choose this X coordinate based on the knowledge that our list
+        // items extend nearly to the right edge of the outer <ol>.
+        var x = root.totalOffsetLeft + root.offsetWidth - 20;
+
+        var y = event.pageY;
+
+        // Our list items have 1-pixel cracks between them vertically. We avoid
+        // the cracks by checking slightly above and slightly below the mouse
+        // and seeing if we hit the same element each time.
+        var elementUnderMouse = this.treeElementFromPoint(x, y);
+        var elementAboveMouse = this.treeElementFromPoint(x, y - 2);
+        var element;
+        if (elementUnderMouse === elementAboveMouse)
+            element = elementUnderMouse;
+        else
+            element = this.treeElementFromPoint(x, y + 2);
+
+        return element;
+    },
+
+    _onmousedown: function(event)
+    {
+        var element = this._treeElementFromEvent(event);
+
+        if (!element || element.isEventWithinDisclosureTriangle(event))
+            return;
+
+        element.select();
+    },
+
+    _onmousemove: function(event)
+    {
+        var element = this._treeElementFromEvent(event);
+        if (element && this._previousHoveredElement === element)
+            return;
+
+        if (this._previousHoveredElement) {
+            this._previousHoveredElement.hovered = false;
+            delete this._previousHoveredElement;
+        }
+
+        if (element) {
+            element.hovered = true;
+            this._previousHoveredElement = element;
+
+            // Lazily compute tag-specific tooltips.
+            if (element.representedObject && !element.tooltip)
+                element._createTooltipForNode();
+        }
+
+        WebInspector.highlightDOMNode(element ? element.representedObject.id : 0);
+    },
+
+    _onmouseout: function(event)
+    {
+        var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY);
+        if (nodeUnderMouse && nodeUnderMouse.isDescendant(this.element))
+            return;
+
+        if (this._previousHoveredElement) {
+            this._previousHoveredElement.hovered = false;
+            delete this._previousHoveredElement;
+        }
+
+        WebInspector.highlightDOMNode(0);
+    },
+
+    _contextMenuEventFired: function(event)
+    {
+        var listItem = event.target.enclosingNodeOrSelfWithNodeName("LI");
+        if (!listItem || !listItem.treeElement)
+            return;
+
+        var contextMenu = new WebInspector.ContextMenu();
+        if (this.showInElementsPanelEnabled) {
+            function focusElement()
+            {
+                WebInspector.panels.elements.switchToAndFocus(listItem.treeElement.representedObject);
+            }
+            contextMenu.appendItem(WebInspector.UIString("Reveal in Elements Panel"), focusElement.bind(this));
+        } else {
+            var href = event.target.enclosingNodeOrSelfWithClass("webkit-html-resource-link") || event.target.enclosingNodeOrSelfWithClass("webkit-html-external-link");
+            var tag = event.target.enclosingNodeOrSelfWithClass("webkit-html-tag");
+            var textNode = event.target.enclosingNodeOrSelfWithClass("webkit-html-text-node");
+            var needSeparator;
+            if (href)
+                needSeparator = WebInspector.panels.elements.populateHrefContextMenu(contextMenu, event, href);
+            if (tag && listItem.treeElement._populateTagContextMenu) {
+                if (needSeparator)
+                    contextMenu.appendSeparator();
+                listItem.treeElement._populateTagContextMenu(contextMenu, event);
+            } else if (textNode && listItem.treeElement._populateTextContextMenu) {
+                if (needSeparator)
+                    contextMenu.appendSeparator();
+                listItem.treeElement._populateTextContextMenu(contextMenu, textNode);
+            }
+        }
+        contextMenu.show(event);
+    }
+}
+
+WebInspector.ElementsTreeOutline.prototype.__proto__ = TreeOutline.prototype;
+
+WebInspector.ElementsTreeElement = function(node, elementCloseTag)
+{
+    this._elementCloseTag = elementCloseTag;
+    var hasChildrenOverride = !elementCloseTag && node.hasChildNodes() && !this._showInlineText(node);
+
+    // The title will be updated in onattach.
+    TreeElement.call(this, "", node, hasChildrenOverride);
+
+    if (this.representedObject.nodeType == Node.ELEMENT_NODE && !elementCloseTag)
+        this._canAddAttributes = true;
+    this._searchQuery = null;
+    this._expandedChildrenLimit = WebInspector.ElementsTreeElement.InitialChildrenLimit;
+}
+
+WebInspector.ElementsTreeElement.InitialChildrenLimit = 500;
+
+// A union of HTML4 and HTML5-Draft elements that explicitly
+// or implicitly (for HTML5) forbid the closing tag.
+// FIXME: Revise once HTML5 Final is published.
+WebInspector.ElementsTreeElement.ForbiddenClosingTagElements = [
+    "area", "base", "basefont", "br", "canvas", "col", "command", "embed", "frame",
+    "hr", "img", "input", "isindex", "keygen", "link", "meta", "param", "source"
+].keySet();
+
+// These tags we do not allow editing their tag name.
+WebInspector.ElementsTreeElement.EditTagBlacklist = [
+    "html", "head", "body"
+].keySet();
+
+WebInspector.ElementsTreeElement.prototype = {
+    highlightSearchResults: function(searchQuery)
+    {
+        if (this._searchQuery === searchQuery)
+            return;
+
+        this._searchQuery = searchQuery;
+        this.updateTitle();
+    },
+
+    get hovered()
+    {
+        return this._hovered;
+    },
+
+    set hovered(x)
+    {
+        if (this._hovered === x)
+            return;
+
+        this._hovered = x;
+
+        if (this.listItemElement) {
+            if (x) {
+                this.updateSelection();
+                this.listItemElement.addStyleClass("hovered");
+            } else {
+                this.listItemElement.removeStyleClass("hovered");
+            }
+        }
+    },
+
+    get expandedChildrenLimit()
+    {
+        return this._expandedChildrenLimit;
+    },
+
+    set expandedChildrenLimit(x)
+    {
+        if (this._expandedChildrenLimit === x)
+            return;
+
+        this._expandedChildrenLimit = x;
+        if (this.treeOutline && !this._updateChildrenInProgress)
+            this._updateChildren(true);
+    },
+
+    get expandedChildCount()
+    {
+        var count = this.children.length;
+        if (count && this.children[count - 1]._elementCloseTag)
+            count--;
+        if (count && this.children[count - 1].expandAllButton)
+            count--;
+        return count;
+    },
+
+    showChild: function(index)
+    {
+        if (this._elementCloseTag)
+            return;
+
+        if (index >= this.expandedChildrenLimit) {
+            this._expandedChildrenLimit = index + 1;
+            this._updateChildren(true);
+        }
+
+        // Whether index-th child is visible in the children tree
+        return this.expandedChildCount > index;
+    },
+
+    _createTooltipForNode: function()
+    {
+        var node = this.representedObject;
+        if (!node.nodeName || node.nodeName.toLowerCase() !== "img")
+            return;
+
+        function setTooltip(properties)
+        {
+            if (!properties)
+                return;
+
+            if (properties.offsetHeight === properties.naturalHeight && properties.offsetWidth === properties.naturalWidth)
+                this.tooltip = WebInspector.UIString("%d × %d pixels", properties.offsetWidth, properties.offsetHeight);
+            else
+                this.tooltip = WebInspector.UIString("%d × %d pixels (Natural: %d × %d pixels)", properties.offsetWidth, properties.offsetHeight, properties.naturalWidth, properties.naturalHeight);
+        }
+        InspectorBackend.getNodeProperties(node.id, ["naturalHeight", "naturalWidth", "offsetHeight", "offsetWidth"], setTooltip.bind(this));
+    },
+
+    updateSelection: function()
+    {
+        var listItemElement = this.listItemElement;
+        if (!listItemElement)
+            return;
+
+        if (document.body.offsetWidth <= 0) {
+            // The stylesheet hasn't loaded yet or the window is closed,
+            // so we can't calculate what is need. Return early.
+            return;
+        }
+
+        if (!this.selectionElement) {
+            this.selectionElement = document.createElement("div");
+            this.selectionElement.className = "selection selected";
+            listItemElement.insertBefore(this.selectionElement, listItemElement.firstChild);
+        }
+
+        this.selectionElement.style.height = listItemElement.offsetHeight + "px";
+    },
+
+    onattach: function()
+    {
+        if (this._hovered) {
+            this.updateSelection();
+            this.listItemElement.addStyleClass("hovered");
+        }
+
+        this.updateTitle();
+
+        this._preventFollowingLinksOnDoubleClick();
+    },
+
+    _preventFollowingLinksOnDoubleClick: function()
+    {
+        var links = this.listItemElement.querySelectorAll("li > .webkit-html-tag > .webkit-html-attribute > .webkit-html-external-link, li > .webkit-html-tag > .webkit-html-attribute > .webkit-html-resource-link");
+        if (!links)
+            return;
+
+        for (var i = 0; i < links.length; ++i)
+            links[i].preventFollowOnDoubleClick = true;
+    },
+
+    onpopulate: function()
+    {
+        if (this.children.length || this._showInlineText(this.representedObject) || this._elementCloseTag)
+            return;
+
+        this.updateChildren();
+    },
+
+    updateChildren: function(fullRefresh)
+    {
+        if (this._elementCloseTag)
+            return;
+
+        WebInspector.domAgent.getChildNodesAsync(this.representedObject, this._updateChildren.bind(this, fullRefresh));
+    },
+
+    insertChildElement: function(child, index, closingTag)
+    {
+        var newElement = new WebInspector.ElementsTreeElement(child, closingTag);
+        newElement.selectable = this.treeOutline.selectEnabled;
+        this.insertChild(newElement, index);
+        return newElement;
+    },
+
+    moveChild: function(child, targetIndex)
+    {
+        var wasSelected = child.selected;
+        this.removeChild(child);
+        this.insertChild(child, targetIndex);
+        if (wasSelected)
+            child.select();
+    },
+
+    _updateChildren: function(fullRefresh)
+    {
+        if (this._updateChildrenInProgress)
+            return;
+
+        this._updateChildrenInProgress = true;
+        var focusedNode = this.treeOutline.focusedDOMNode;
+        var originalScrollTop;
+        if (fullRefresh) {
+            var treeOutlineContainerElement = this.treeOutline.element.parentNode;
+            originalScrollTop = treeOutlineContainerElement.scrollTop;
+            var selectedTreeElement = this.treeOutline.selectedTreeElement;
+            if (selectedTreeElement && selectedTreeElement.hasAncestor(this))
+                this.select();
+            this.removeChildren();
+        }
+
+        var treeElement = this;
+        var treeChildIndex = 0;
+        var elementToSelect;
+
+        function updateChildrenOfNode(node)
+        {
+            var treeOutline = treeElement.treeOutline;
+            var child = node.firstChild;
+            while (child) {
+                var currentTreeElement = treeElement.children[treeChildIndex];
+                if (!currentTreeElement || currentTreeElement.representedObject !== child) {
+                    // Find any existing element that is later in the children list.
+                    var existingTreeElement = null;
+                    for (var i = (treeChildIndex + 1), size = treeElement.expandedChildCount; i < size; ++i) {
+                        if (treeElement.children[i].representedObject === child) {
+                            existingTreeElement = treeElement.children[i];
+                            break;
+                        }
+                    }
+
+                    if (existingTreeElement && existingTreeElement.parent === treeElement) {
+                        // If an existing element was found and it has the same parent, just move it.
+                        treeElement.moveChild(existingTreeElement, treeChildIndex);
+                    } else {
+                        // No existing element found, insert a new element.
+                        if (treeChildIndex < treeElement.expandedChildrenLimit) {
+                            var newElement = treeElement.insertChildElement(child, treeChildIndex);
+                            if (child === focusedNode)
+                                elementToSelect = newElement;
+                            if (treeElement.expandedChildCount > treeElement.expandedChildrenLimit)
+                                treeElement.expandedChildrenLimit++;
+                        }
+                    }
+                }
+
+                child = child.nextSibling;
+                ++treeChildIndex;
+            }
+        }
+
+        // Remove any tree elements that no longer have this node (or this node's contentDocument) as their parent.
+        for (var i = (this.children.length - 1); i >= 0; --i) {
+            var currentChild = this.children[i];
+            var currentNode = currentChild.representedObject;
+            var currentParentNode = currentNode.parentNode;
+
+            if (currentParentNode === this.representedObject)
+                continue;
+
+            var selectedTreeElement = this.treeOutline.selectedTreeElement;
+            if (selectedTreeElement && (selectedTreeElement === currentChild || selectedTreeElement.hasAncestor(currentChild)))
+                this.select();
+
+            this.removeChildAtIndex(i);
+        }
+
+        updateChildrenOfNode(this.representedObject);
+        this.adjustCollapsedRange(false);
+
+        var lastChild = this.children[this.children.length - 1];
+        if (this.representedObject.nodeType == Node.ELEMENT_NODE && (!lastChild || !lastChild._elementCloseTag))
+            this.insertChildElement(this.representedObject, this.children.length, true);
+
+        // We want to restore the original selection and tree scroll position after a full refresh, if possible.
+        if (fullRefresh && elementToSelect) {
+            elementToSelect.select();
+            if (treeOutlineContainerElement && originalScrollTop <= treeOutlineContainerElement.scrollHeight)
+                treeOutlineContainerElement.scrollTop = originalScrollTop;
+        }
+
+        delete this._updateChildrenInProgress;
+    },
+
+    adjustCollapsedRange: function()
+    {
+        // Ensure precondition: only the tree elements for node children are found in the tree
+        // (not the Expand All button or the closing tag).
+        if (this.expandAllButtonElement && this.expandAllButtonElement.__treeElement.parent)
+            this.removeChild(this.expandAllButtonElement.__treeElement);
+
+        const node = this.representedObject;
+        if (!node.children)
+            return;
+        const childNodeCount = node.children.length;
+
+        // In case some nodes from the expanded range were removed, pull some nodes from the collapsed range into the expanded range at the bottom.
+        for (var i = this.expandedChildCount, limit = Math.min(this.expandedChildrenLimit, childNodeCount); i < limit; ++i)
+            this.insertChildElement(node.children[i], i);
+
+        const expandedChildCount = this.expandedChildCount;
+        if (childNodeCount > this.expandedChildCount) {
+            var targetButtonIndex = expandedChildCount;
+            if (!this.expandAllButtonElement) {
+                var item = new TreeElement(null, null, false);
+                item.titleHTML = "<button class=\"show-all-nodes\" value=\"\" />";
+                item.selectable = false;
+                item.expandAllButton = true;
+                this.insertChild(item, targetButtonIndex);
+                this.expandAllButtonElement = item.listItemElement.firstChild;
+                this.expandAllButtonElement.__treeElement = item;
+                this.expandAllButtonElement.addEventListener("click", this.handleLoadAllChildren.bind(this), false);
+            } else if (!this.expandAllButtonElement.__treeElement.parent)
+                this.insertChild(this.expandAllButtonElement.__treeElement, targetButtonIndex);
+            this.expandAllButtonElement.textContent = WebInspector.UIString("Show All Nodes (%d More)", childNodeCount - expandedChildCount);
+        } else if (this.expandAllButtonElement)
+            delete this.expandAllButtonElement;
+    },
+
+    handleLoadAllChildren: function()
+    {
+        this.expandedChildrenLimit = Math.max(this.representedObject._childNodeCount, this.expandedChildrenLimit + WebInspector.ElementsTreeElement.InitialChildrenLimit);
+    },
+
+    onexpand: function()
+    {
+        if (this._elementCloseTag)
+            return;
+
+        this.updateTitle();
+        this.treeOutline.updateSelection();
+    },
+
+    oncollapse: function()
+    {
+        if (this._elementCloseTag)
+            return;
+
+        this.updateTitle();
+        this.treeOutline.updateSelection();
+    },
+
+    onreveal: function()
+    {
+        if (this.listItemElement)
+            this.listItemElement.scrollIntoViewIfNeeded(false);
+    },
+
+    onselect: function(treeElement, selectedByUser)
+    {
+        this.treeOutline.suppressRevealAndSelect = true;
+        this.treeOutline.focusedDOMNode = this.representedObject;
+        if (selectedByUser)
+            WebInspector.highlightDOMNode(this.representedObject.id);
+        this.updateSelection();
+        this.treeOutline.suppressRevealAndSelect = false;
+    },
+
+    ondelete: function()
+    {
+        var startTagTreeElement = this.treeOutline.findTreeElement(this.representedObject);
+        startTagTreeElement ? startTagTreeElement.remove() : this.remove();
+        return true;
+    },
+
+    onenter: function()
+    {
+        // On Enter or Return start editing the first attribute
+        // or create a new attribute on the selected element.
+        if (this.treeOutline.editing)
+            return false;
+
+        this._startEditing();
+
+        // prevent a newline from being immediately inserted
+        return true;
+    },
+
+    selectOnMouseDown: function(event)
+    {
+        TreeElement.prototype.selectOnMouseDown.call(this, event);
+
+        if (this._editing)
+            return;
+
+        if (this.treeOutline.showInElementsPanelEnabled) {
+            WebInspector.showPanel("elements");
+            WebInspector.panels.elements.focusedDOMNode = this.representedObject;
+        }
+
+        // Prevent selecting the nearest word on double click.
+        if (event.detail >= 2)
+            event.preventDefault();
+    },
+
+    ondblclick: function(event)
+    {
+        if (this._editing || this._elementCloseTag)
+            return;
+
+        if (this._startEditingTarget(event.target))
+            return;
+
+        if (this.hasChildren && !this.expanded)
+            this.expand();
+    },
+
+    _insertInLastAttributePosition: function(tag, node)
+    {
+        if (tag.getElementsByClassName("webkit-html-attribute").length > 0)
+            tag.insertBefore(node, tag.lastChild);
+        else {
+            var nodeName = tag.textContent.match(/^<(.*?)>$/)[1];
+            tag.textContent = '';
+            tag.appendChild(document.createTextNode('<'+nodeName));
+            tag.appendChild(node);
+            tag.appendChild(document.createTextNode('>'));
+        }
+
+        this.updateSelection();
+    },
+
+    _startEditingTarget: function(eventTarget)
+    {
+        if (this.treeOutline.focusedDOMNode != this.representedObject)
+            return;
+
+        if (this.representedObject.nodeType != Node.ELEMENT_NODE && this.representedObject.nodeType != Node.TEXT_NODE)
+            return false;
+
+        var textNode = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-text-node");
+        if (textNode)
+            return this._startEditingTextNode(textNode);
+
+        var attribute = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-attribute");
+        if (attribute)
+            return this._startEditingAttribute(attribute, eventTarget);
+
+        var tagName = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-tag-name");
+        if (tagName)
+            return this._startEditingTagName(tagName);
+
+        var newAttribute = eventTarget.enclosingNodeOrSelfWithClass("add-attribute");
+        if (newAttribute)
+            return this._addNewAttribute();
+
+        return false;
+    },
+
+    _populateTagContextMenu: function(contextMenu, event)
+    {
+        var attribute = event.target.enclosingNodeOrSelfWithClass("webkit-html-attribute");
+        var newAttribute = event.target.enclosingNodeOrSelfWithClass("add-attribute");
+
+        // Add attribute-related actions.
+        contextMenu.appendItem(WebInspector.UIString("Add Attribute"), this._addNewAttribute.bind(this));
+        if (attribute && !newAttribute)
+            contextMenu.appendItem(WebInspector.UIString("Edit Attribute"), this._startEditingAttribute.bind(this, attribute, event.target));
+        contextMenu.appendSeparator();
+
+        // Add free-form node-related actions.
+        contextMenu.appendItem(WebInspector.UIString("Edit as HTML"), this._editAsHTML.bind(this));
+        contextMenu.appendItem(WebInspector.UIString("Copy as HTML"), this._copyHTML.bind(this));
+        contextMenu.appendItem(WebInspector.UIString("Delete Node"), this.remove.bind(this));
+
+        if (Preferences.nativeInstrumentationEnabled) {
+            // Add debbuging-related actions
+            contextMenu.appendSeparator();
+
+            function handlerFunction(nodeId, breakType)
+            {
+                WebInspector.breakpointManager.createDOMBreakpoint(nodeId, breakType);
+                WebInspector.panels.elements.sidebarPanes.domBreakpoints.expand();
+            }
+            var node = this.representedObject;
+            for (var key in WebInspector.DOMBreakpointTypes) {
+                var type = WebInspector.DOMBreakpointTypes[key];
+                var label = WebInspector.domBreakpointTypeContextMenuLabel(type);
+                var breakpoint = node.breakpoints[type];
+                if (!breakpoint)
+                    var handler = handlerFunction.bind(this, node.id, type);
+                else
+                    var handler = breakpoint.remove.bind(breakpoint);
+                contextMenu.appendCheckboxItem(label, handler, !!breakpoint);
+            }
+        }
+    },
+
+    _populateTextContextMenu: function(contextMenu, textNode)
+    {
+        contextMenu.appendItem(WebInspector.UIString("Edit Text"), this._startEditingTextNode.bind(this, textNode));
+    },
+
+    _startEditing: function()
+    {
+        if (this.treeOutline.focusedDOMNode !== this.representedObject)
+            return;
+
+        var listItem = this._listItemNode;
+
+        if (this._canAddAttributes) {
+            var attribute = listItem.getElementsByClassName("webkit-html-attribute")[0];
+            if (attribute)
+                return this._startEditingAttribute(attribute, attribute.getElementsByClassName("webkit-html-attribute-value")[0]);
+
+            return this._addNewAttribute();
+        }
+
+        if (this.representedObject.nodeType === Node.TEXT_NODE) {
+            var textNode = listItem.getElementsByClassName("webkit-html-text-node")[0];
+            if (textNode)
+                return this._startEditingTextNode(textNode);
+            return;
+        }
+    },
+
+    _addNewAttribute: function()
+    {
+        // Cannot just convert the textual html into an element without
+        // a parent node. Use a temporary span container for the HTML.
+        var container = document.createElement("span");
+        container.innerHTML = this._attributeHTML(" ", "");
+        var attr = container.firstChild;
+        attr.style.marginLeft = "2px"; // overrides the .editing margin rule
+        attr.style.marginRight = "2px"; // overrides the .editing margin rule
+
+        var tag = this.listItemElement.getElementsByClassName("webkit-html-tag")[0];
+        this._insertInLastAttributePosition(tag, attr);
+        return this._startEditingAttribute(attr, attr);
+    },
+
+    _triggerEditAttribute: function(attributeName)
+    {
+        var attributeElements = this.listItemElement.getElementsByClassName("webkit-html-attribute-name");
+        for (var i = 0, len = attributeElements.length; i < len; ++i) {
+            if (attributeElements[i].textContent === attributeName) {
+                for (var elem = attributeElements[i].nextSibling; elem; elem = elem.nextSibling) {
+                    if (elem.nodeType !== Node.ELEMENT_NODE)
+                        continue;
+
+                    if (elem.hasStyleClass("webkit-html-attribute-value"))
+                        return this._startEditingAttribute(elem.parentNode, elem);
+                }
+            }
+        }
+    },
+
+    _startEditingAttribute: function(attribute, elementForSelection)
+    {
+        if (WebInspector.isBeingEdited(attribute))
+            return true;
+
+        var attributeNameElement = attribute.getElementsByClassName("webkit-html-attribute-name")[0];
+        if (!attributeNameElement)
+            return false;
+
+        var attributeName = attributeNameElement.innerText;
+
+        function removeZeroWidthSpaceRecursive(node)
+        {
+            if (node.nodeType === Node.TEXT_NODE) {
+                node.nodeValue = node.nodeValue.replace(/\u200B/g, "");
+                return;
+            }
+
+            if (node.nodeType !== Node.ELEMENT_NODE)
+                return;
+
+            for (var child = node.firstChild; child; child = child.nextSibling)
+                removeZeroWidthSpaceRecursive(child);
+        }
+
+        // Remove zero-width spaces that were added by nodeTitleInfo.
+        removeZeroWidthSpaceRecursive(attribute);
+
+        this._editing = WebInspector.startEditing(attribute, {
+            context: attributeName,
+            commitHandler: this._attributeEditingCommitted.bind(this),
+            cancelHandler: this._editingCancelled.bind(this)
+        });
+        window.getSelection().setBaseAndExtent(elementForSelection, 0, elementForSelection, 1);
+
+        return true;
+    },
+
+    _startEditingTextNode: function(textNode)
+    {
+        if (WebInspector.isBeingEdited(textNode))
+            return true;
+
+        this._editing = WebInspector.startEditing(textNode, {
+            context: null,
+            commitHandler: this._textNodeEditingCommitted.bind(this),
+            cancelHandler: this._editingCancelled.bind(this)
+        });
+        window.getSelection().setBaseAndExtent(textNode, 0, textNode, 1);
+
+        return true;
+    },
+
+    _startEditingTagName: function(tagNameElement)
+    {
+        if (!tagNameElement) {
+            tagNameElement = this.listItemElement.getElementsByClassName("webkit-html-tag-name")[0];
+            if (!tagNameElement)
+                return false;
+        }
+
+        var tagName = tagNameElement.textContent;
+        if (WebInspector.ElementsTreeElement.EditTagBlacklist[tagName.toLowerCase()])
+            return false;
+
+        if (WebInspector.isBeingEdited(tagNameElement))
+            return true;
+
+        var closingTagElement = this._distinctClosingTagElement();
+
+        function keyupListener(event)
+        {
+            if (closingTagElement)
+                closingTagElement.textContent = "</" + tagNameElement.textContent + ">";
+        }
+
+        function editingComitted(element, newTagName)
+        {
+            tagNameElement.removeEventListener('keyup', keyupListener, false);
+            this._tagNameEditingCommitted.apply(this, arguments);
+        }
+
+        function editingCancelled()
+        {
+            tagNameElement.removeEventListener('keyup', keyupListener, false);
+            this._editingCancelled.apply(this, arguments);
+        }
+
+        tagNameElement.addEventListener('keyup', keyupListener, false);
+
+        this._editing = WebInspector.startEditing(tagNameElement, {
+            context: tagName,
+            commitHandler: editingComitted.bind(this),
+            cancelHandler: editingCancelled.bind(this)
+        });
+        window.getSelection().setBaseAndExtent(tagNameElement, 0, tagNameElement, 1);
+        return true;
+    },
+
+    _startEditingAsHTML: function(commitCallback, initialValue)
+    {
+        if (this._htmlEditElement && WebInspector.isBeingEdited(this._htmlEditElement))
+            return true;
+
+        this._htmlEditElement = document.createElement("div");
+        this._htmlEditElement.className = "source-code elements-tree-editor";
+        this._htmlEditElement.textContent = initialValue;
+
+        // Hide header items.
+        var child = this.listItemElement.firstChild;
+        while (child) {
+            child.style.display = "none";
+            child = child.nextSibling;
+        }
+        // Hide children item.
+        if (this._childrenListNode)
+            this._childrenListNode.style.display = "none";
+        // Append editor.
+        this.listItemElement.appendChild(this._htmlEditElement);
+
+        this.updateSelection();
+
+        function commit()
+        {
+            commitCallback(this._htmlEditElement.textContent);
+            dispose.call(this);
+        }
+
+        function dispose()
+        {
+            delete this._editing;
+
+            // Remove editor.
+            this.listItemElement.removeChild(this._htmlEditElement);
+            delete this._htmlEditElement;
+            // Unhide children item.
+            if (this._childrenListNode)
+                this._childrenListNode.style.removeProperty("display");
+            // Unhide header items.
+            var child = this.listItemElement.firstChild;
+            while (child) {
+                child.style.removeProperty("display");
+                child = child.nextSibling;
+            }
+
+            this.updateSelection();
+        }
+
+        this._editing = WebInspector.startEditing(this._htmlEditElement, {
+            context: null,
+            commitHandler: commit.bind(this),
+            cancelHandler: dispose.bind(this),
+            multiline: true
+        });
+    },
+
+    _attributeEditingCommitted: function(element, newText, oldText, attributeName, moveDirection)
+    {
+        delete this._editing;
+
+        // Before we do anything, determine where we should move
+        // next based on the current element's settings
+        var moveToAttribute, moveToTagName, moveToNewAttribute;
+        if (moveDirection) {
+            var found = false;
+
+            // Search for the attribute's position, and then decide where to move to.
+            var attributes = this.representedObject.attributes;
+            for (var i = 0; i < attributes.length; ++i) {
+                if (attributes[i].name === attributeName) {
+                    found = true;
+                    if (moveDirection === "backward") {
+                        if (i === 0)
+                            moveToTagName = true;
+                        else
+                            moveToAttribute = attributes[i - 1].name;
+                    } else if (moveDirection === "forward") {
+                        if (i === attributes.length - 1)
+                            moveToNewAttribute = true;
+                        else
+                            moveToAttribute = attributes[i + 1].name;
+                    }
+                }
+            }
+
+            // Moving From the "New Attribute" position.
+            if (!found) {
+                if (moveDirection === "backward" && attributes.length > 0)
+                    moveToAttribute = attributes[attributes.length - 1].name;
+                else if (moveDirection === "forward") {
+                    if (!/^\s*$/.test(newText))
+                        moveToNewAttribute = true;
+                    else
+                        moveToTagName = true;
+                }
+            }
+        }
+
+        function moveToNextAttributeIfNeeded()
+        {
+            // Cleanup empty new attribute sections.
+            if (element.textContent.trim().length === 0)
+                element.parentNode.removeChild(element);
+
+            // Make the move.
+            if (moveToAttribute)
+                this._triggerEditAttribute(moveToAttribute);
+            else if (moveToNewAttribute)
+                this._addNewAttribute();
+            else if (moveToTagName)
+                this._startEditingTagName();
+        }
+
+        function regenerateStyledAttribute(name, value)
+        {
+            var previous = element.previousSibling;
+            if (!previous || previous.nodeType !== Node.TEXT_NODE)
+                element.parentNode.insertBefore(document.createTextNode(" "), element);
+
+            // outerHTML should not be used to replace node content in IE, updated with replaceChild usage
+			element.innerHTML = this._attributeHTML(name, value);
+			element.parentNode.replaceChild(element.firstChild, element);
+            //element.outerHTML = this._attributeHTML(name, value);
+        }
+
+        var parseContainerElement = document.createElement("span");
+        parseContainerElement.innerHTML = "<span " + newText + "></span>";
+        var parseElement = parseContainerElement.firstChild;
+
+        if (!parseElement) {
+            this._editingCancelled(element, attributeName);
+            moveToNextAttributeIfNeeded.call(this);
+            return;
+        }
+
+        if (!parseElement.hasAttributes()) {
+            this.representedObject.removeAttribute(attributeName);
+            this.treeOutline.focusedNodeChanged(true);
+            moveToNextAttributeIfNeeded.call(this);
+            return;
+        }
+
+        var foundOriginalAttribute = false;
+        for (var i = 0; i < parseElement.attributes.length; ++i) {
+            var attr = parseElement.attributes[i];
+            foundOriginalAttribute = foundOriginalAttribute || attr.name === attributeName;
+            try {
+                this.representedObject.setAttribute(attr.name, attr.value);
+                regenerateStyledAttribute.call(this, attr.name, attr.value);
+            } catch(e) {} // ignore invalid attribute (innerHTML doesn't throw errors, but this can)
+        }
+
+        if (!foundOriginalAttribute)
+            this.representedObject.removeAttribute(attributeName);
+
+        this.treeOutline.focusedNodeChanged(true);
+
+        moveToNextAttributeIfNeeded.call(this);
+    },
+
+    _tagNameEditingCommitted: function(element, newText, oldText, tagName, moveDirection)
+    {
+        delete this._editing;
+        var self = this;
+
+        function cancel()
+        {
+            var closingTagElement = self._distinctClosingTagElement();
+            if (closingTagElement)
+                closingTagElement.textContent = "</" + tagName + ">";
+
+            self._editingCancelled(element, tagName);
+            moveToNextAttributeIfNeeded.call(self);
+        }
+
+        function moveToNextAttributeIfNeeded()
+        {
+            if (moveDirection !== "forward") {
+                this._addNewAttribute();
+                return;
+            }
+
+            var attributes = this.representedObject.attributes;
+            if (attributes.length > 0)
+                this._triggerEditAttribute(attributes[0].name);
+            else
+                this._addNewAttribute();
+        }
+
+        newText = newText.trim();
+        if (newText === oldText) {
+            cancel();
+            return;
+        }
+
+        var treeOutline = this.treeOutline;
+        var wasExpanded = this.expanded;
+
+        function changeTagNameCallback(nodeId)
+        {
+            if (!nodeId) {
+                cancel();
+                return;
+            }
+
+            // Select it and expand if necessary. We force tree update so that it processes dom events and is up to date.
+            WebInspector.panels.elements.updateModifiedNodes();
+
+            WebInspector.updateFocusedNode(nodeId);
+            var newTreeItem = treeOutline.findTreeElement(WebInspector.domAgent.nodeForId(nodeId));
+            if (wasExpanded)
+                newTreeItem.expand();
+
+            moveToNextAttributeIfNeeded.call(newTreeItem);
+        }
+
+        InspectorBackend.changeTagName(this.representedObject.id, newText, changeTagNameCallback);
+    },
+
+    _textNodeEditingCommitted: function(element, newText)
+    {
+        delete this._editing;
+
+        var textNode;
+        if (this.representedObject.nodeType === Node.ELEMENT_NODE) {
+            // We only show text nodes inline in elements if the element only
+            // has a single child, and that child is a text node.
+            textNode = this.representedObject.firstChild;
+        } else if (this.representedObject.nodeType == Node.TEXT_NODE)
+            textNode = this.representedObject;
+
+        textNode.nodeValue = newText;
+    },
+
+    _editingCancelled: function(element, context)
+    {
+        delete this._editing;
+
+        // Need to restore attributes structure.
+        this.updateTitle();
+    },
+
+    _distinctClosingTagElement: function()
+    {
+        // FIXME: Improve the Tree Element / Outline Abstraction to prevent crawling the DOM
+
+        // For an expanded element, it will be the last element with class "close"
+        // in the child element list.
+        if (this.expanded) {
+            var closers = this._childrenListNode.querySelectorAll(".close");
+            return closers[closers.length-1];
+        }
+
+        // Remaining cases are single line non-expanded elements with a closing
+        // tag, or HTML elements without a closing tag (such as <br>). Return
+        // null in the case where there isn't a closing tag.
+        var tags = this.listItemElement.getElementsByClassName("webkit-html-tag");
+        return (tags.length === 1 ? null : tags[tags.length-1]);
+    },
+
+    updateTitle: function()
+    {
+        // If we are editing, return early to prevent canceling the edit.
+        // After editing is committed updateTitle will be called.
+        if (this._editing)
+            return;
+
+        this.titleHTML = "<span class=\"highlight\">" + this._nodeTitleInfo(WebInspector.linkifyURL).titleHTML + "</span>";
+        delete this.selectionElement;
+        this.updateSelection();
+        this._preventFollowingLinksOnDoubleClick();
+        this._highlightSearchResults();
+    },
+
+    _attributeHTML: function(name, value, node, linkify)
+    {
+        var hasText = (value.length > 0);
+        var html = "<span class=\"webkit-html-attribute\"><span class=\"webkit-html-attribute-name\">" + name.escapeHTML() + "</span>";
+
+        if (hasText)
+            html += "=&#8203;\"";
+
+        if (linkify && (name === "src" || name === "href")) {
+            var rewrittenHref = WebInspector.resourceURLForRelatedNode(node, value);
+            value = value.replace(/([\/;:\)\]\}])/g, "$1\u200B");
+            html += linkify(rewrittenHref, value, "webkit-html-attribute-value", node.nodeName.toLowerCase() === "a");
+        } else {
+            value = value.escapeHTML().replace(/([\/;:\)\]\}])/g, "$1&#8203;");
+            html += "<span class=\"webkit-html-attribute-value\">" + value + "</span>";
+        }
+
+        if (hasText)
+            html += "\"";
+
+        html += "</span>";
+        return html;
+    },
+
+    _tagHTML: function(tagName, isClosingTag, isDistinctTreeElement, linkify)
+    {
+        var node = this.representedObject;
+        var result = "<span class=\"webkit-html-tag" + (isClosingTag && isDistinctTreeElement ? " close" : "")  + "\">&lt;";
+        result += "<span " + (isClosingTag ? "" : "class=\"webkit-html-tag-name\"") + ">" + (isClosingTag ? "/" : "") + tagName + "</span>";
+        if (!isClosingTag && node.hasAttributes()) {
+            for (var i = 0; i < node.attributes.length; ++i) {
+                var attr = node.attributes[i];
+                result += " " + this._attributeHTML(attr.name, attr.value, node, linkify);
+            }
+        }
+        result += "&gt;</span>&#8203;";
+
+        return result;
+    },
+
+    _nodeTitleInfo: function(linkify)
+    {
+        var node = this.representedObject;
+        var info = {titleHTML: "", hasChildren: this.hasChildren};
+
+        switch (node.nodeType) {
+            case Node.DOCUMENT_NODE:
+                info.titleHTML = "Document";
+                break;
+
+            case Node.DOCUMENT_FRAGMENT_NODE:
+                info.titleHTML = "Document Fragment";
+                break;
+
+            case Node.ATTRIBUTE_NODE:
+                var value = node.value || "\u200B"; // Zero width space to force showing an empty value.
+                info.titleHTML = this._attributeHTML(node.name, value);
+                break;
+
+            case Node.ELEMENT_NODE:
+                var tagName = this.treeOutline.nodeNameToCorrectCase(node.nodeName).escapeHTML();
+                if (this._elementCloseTag) {
+                    info.titleHTML = this._tagHTML(tagName, true, true);
+                    info.hasChildren = false;
+                    break;
+                }
+
+                var titleHTML = this._tagHTML(tagName, false, false, linkify);
+
+                var textChild = onlyTextChild.call(node);
+                var showInlineText = textChild && textChild.textContent.length < Preferences.maxInlineTextChildLength;
+
+                if (!this.expanded && (!showInlineText && (this.treeOutline.isXMLMimeType || !WebInspector.ElementsTreeElement.ForbiddenClosingTagElements[tagName]))) {
+                    if (this.hasChildren)
+                        titleHTML += "<span class=\"webkit-html-text-node\">&#8230;</span>&#8203;";
+                    titleHTML += this._tagHTML(tagName, true, false);
+                }
+
+                // If this element only has a single child that is a text node,
+                // just show that text and the closing tag inline rather than
+                // create a subtree for them
+                if (showInlineText) {
+                    titleHTML += "<span class=\"webkit-html-text-node\">" + textChild.nodeValue.escapeHTML() + "</span>&#8203;" + this._tagHTML(tagName, true, false);
+                    info.hasChildren = false;
+                }
+                info.titleHTML = titleHTML;
+                break;
+
+            case Node.TEXT_NODE:
+                if (isNodeWhitespace.call(node))
+                    info.titleHTML = "(whitespace)";
+                else {
+                    if (node.parentNode && node.parentNode.nodeName.toLowerCase() === "script") {
+                        var newNode = document.createElement("span");
+                        newNode.textContent = node.textContent;
+
+                        var javascriptSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/javascript");
+                        javascriptSyntaxHighlighter.syntaxHighlightNode(newNode);
+
+                        info.titleHTML = "<span class=\"webkit-html-text-node webkit-html-js-node\">" + newNode.innerHTML.replace(/^[\n\r]*/, "").replace(/\s*$/, "") + "</span>";
+                    } else if (node.parentNode && node.parentNode.nodeName.toLowerCase() === "style") {
+                        var newNode = document.createElement("span");
+                        newNode.textContent = node.textContent;
+
+                        var cssSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/css");
+                        cssSyntaxHighlighter.syntaxHighlightNode(newNode);
+
+                        info.titleHTML = "<span class=\"webkit-html-text-node webkit-html-css-node\">" + newNode.innerHTML.replace(/^[\n\r]*/, "").replace(/\s*$/, "") + "</span>";
+                    } else
+                        info.titleHTML = "\"<span class=\"webkit-html-text-node\">" + node.nodeValue.escapeHTML() + "</span>\"";
+                }
+                break;
+
+            case Node.COMMENT_NODE:
+                info.titleHTML = "<span class=\"webkit-html-comment\">&lt;!--" + node.nodeValue.escapeHTML() + "--&gt;</span>";
+                break;
+
+            case Node.DOCUMENT_TYPE_NODE:
+                var titleHTML = "<span class=\"webkit-html-doctype\">&lt;!DOCTYPE " + node.nodeName;
+                if (node.publicId) {
+                    titleHTML += " PUBLIC \"" + node.publicId + "\"";
+                    if (node.systemId)
+                        titleHTML += " \"" + node.systemId + "\"";
+                } else if (node.systemId)
+                    titleHTML += " SYSTEM \"" + node.systemId + "\"";
+                if (node.internalSubset)
+                    titleHTML += " [" + node.internalSubset + "]";
+                titleHTML += "&gt;</span>";
+                info.titleHTML = titleHTML;
+                break;
+
+            case Node.CDATA_SECTION_NODE:
+                info.titleHTML = "<span class=\"webkit-html-text-node\">&lt;![CDATA[" + node.nodeValue.escapeHTML() + "]]&gt;</span>";
+                break;
+            default:
+                info.titleHTML = this.treeOutline.nodeNameToCorrectCase(node.nodeName).collapseWhitespace().escapeHTML();
+        }
+
+        return info;
+    },
+
+    _showInlineText: function(node)
+    {
+        if (node.nodeType === Node.ELEMENT_NODE) {
+            var textChild = onlyTextChild.call(node);
+            if (textChild && textChild.textContent.length < Preferences.maxInlineTextChildLength)
+                return true;
+        }
+        return false;
+    },
+
+    remove: function()
+    {
+        var parentElement = this.parent;
+        if (!parentElement)
+            return;
+
+        var self = this;
+        function removeNodeCallback(removedNodeId)
+        {
+            // -1 is an error code, which means removing the node from the DOM failed,
+            // so we shouldn't remove it from the tree.
+            if (removedNodeId === -1)
+                return;
+
+            parentElement.removeChild(self);
+            parentElement.adjustCollapsedRange(true);
+        }
+
+        InspectorBackend.removeNode(this.representedObject.id, removeNodeCallback);
+    },
+
+    _editAsHTML: function()
+    {
+        var treeOutline = this.treeOutline;
+        var node = this.representedObject;
+        var wasExpanded = this.expanded;
+
+        function selectNode(nodeId)
+        {
+            if (!nodeId)
+                return;
+
+            // Select it and expand if necessary. We force tree update so that it processes dom events and is up to date.
+            WebInspector.panels.elements.updateModifiedNodes();
+
+            WebInspector.updateFocusedNode(nodeId);
+            if (wasExpanded) {
+                var newTreeItem = treeOutline.findTreeElement(WebInspector.domAgent.nodeForId(nodeId));
+                if (newTreeItem)
+                    newTreeItem.expand();
+            }
+        }
+
+        function commitChange(value)
+        {
+            InspectorBackend.setOuterHTML(node.id, value, selectNode);
+        }
+
+        InspectorBackend.getOuterHTML(node.id, this._startEditingAsHTML.bind(this, commitChange));
+    },
+
+    _copyHTML: function()
+    {
+        InspectorBackend.copyNode(this.representedObject.id);
+    },
+
+    _highlightSearchResults: function()
+    {
+        if (!this._searchQuery)
+            return;
+        var text = this.listItemElement.textContent;
+        var regexObject = createSearchRegex(this._searchQuery);
+
+        var offset = 0;
+        var match = regexObject.exec(text);
+        while (match) {
+            highlightSearchResult(this.listItemElement, offset + match.index, match[0].length);
+            offset += match.index + 1;
+            text = text.substring(match.index + 1);
+            match = regexObject.exec(text);
+        }
+    }
+}
+
+WebInspector.ElementsTreeElement.prototype.__proto__ = TreeElement.prototype;
diff --git a/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/Settings.js b/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/Settings.js
new file mode 100644
index 0000000..f20078a
--- /dev/null
+++ b/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/Settings.js
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+var Preferences = {
+    canEditScriptSource: false,
+    maxInlineTextChildLength: 80,
+    minConsoleHeight: 75,
+    minSidebarWidth: 100,
+    minElementsSidebarWidth: 200,
+    minScriptsSidebarWidth: 200,
+    styleRulesExpandedState: {},
+    showMissingLocalizedStrings: false,
+    samplingCPUProfiler: false,
+    showColorNicknames: true,
+    debuggerAlwaysEnabled: false,
+    profilerAlwaysEnabled: false,
+    onlineDetectionEnabled: true,
+    nativeInstrumentationEnabled: false,
+    resourceExportEnabled: false,
+    useDataURLForResourceImageIcons: true,
+    showTimingTab: false,
+    showCookiesTab: false,
+    debugMode: false,
+    heapProfilerPresent: false,
+    detailedHeapProfiles: false
+}
+
+WebInspector.Settings = function()
+{
+    this.installApplicationSetting("colorFormat", "hex");
+    this.installApplicationSetting("consoleHistory", []);
+    this.installApplicationSetting("debuggerEnabled", false);
+    this.installApplicationSetting("profilerEnabled", false);
+    this.installApplicationSetting("eventListenersFilter", "all");
+    this.installApplicationSetting("lastActivePanel", "elements");
+    this.installApplicationSetting("lastViewedScriptFile", "application");
+    this.installApplicationSetting("monitoringXHREnabled", false);
+    this.installApplicationSetting("pauseOnExceptionState", WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions);
+    this.installApplicationSetting("resourcesLargeRows", true);
+    this.installApplicationSetting("resourcesSortOptions", {timeOption: "responseTime", sizeOption: "transferSize"});
+    this.installApplicationSetting("resourceViewTab", "content");
+    this.installApplicationSetting("showInheritedComputedStyleProperties", false);
+    this.installApplicationSetting("showUserAgentStyles", true);
+    this.installApplicationSetting("watchExpressions", []);
+    this.installApplicationSetting("breakpoints", []);
+
+    this.installProjectSetting("nativeBreakpoints", []);
+}
+
+WebInspector.Settings.Events = {
+    ProjectChanged: "project-changed"
+}
+
+WebInspector.Settings.prototype = {
+    installApplicationSetting: function(key, defaultValue)
+    {
+        if (key in this)
+            return;
+
+        Object.defineProperty(this, key,{
+            get : this._get.bind(this, key, defaultValue),
+            set : this._set.bind(this, key)});
+    },
+
+    installProjectSetting: function(key, defaultValue)
+    {
+        Object.defineProperty(this, key,{
+            get : this._getProjectSetting.bind(this, key, defaultValue),
+            set : this._setProjectSetting.bind(this, key)});
+
+    },
+
+    inspectedURLChanged: function(url)
+    {
+        var fragmentIndex = url.indexOf("#");
+        if (fragmentIndex !== -1)
+            url = url.substring(0, fragmentIndex);
+        this._projectId = url;
+        this.dispatchEventToListeners(WebInspector.Settings.Events.ProjectChanged);
+    },
+
+    get projectId()
+    {
+        return this._projectId;
+    },
+
+    findSettingForAllProjects: function(key)
+    {
+        var result = {};
+        var regexp = "^" + key + ":(.*)";
+        for (var i = 0; i < window.localStorage.length; ++i) {
+            var fullKey =  window.localStorage.key(i);
+            var match = fullKey.match(regexp);
+            if (!match)
+                continue;
+            try {
+                result[match[1]] = JSON.parse(window.localStorage[fullKey]);
+            } catch(e) {
+                window.localStorage.removeItem(fullKey);
+            }
+        }
+        return result;
+    },
+
+    _get: function(key, defaultValue)
+    {
+        if (key in window.localStorage) {
+            try {
+                return JSON.parse(window.localStorage[key]);
+            } catch(e) {
+                window.localStorage.removeItem(key);
+            }
+        }
+        return defaultValue;
+    },
+
+    _set: function(key, value)
+    {
+        window.localStorage[key] = JSON.stringify(value);
+    },
+
+    _getProjectSetting: function(key, defaultValue)
+    {
+        return this._get(this._formatProjectKey(key), defaultValue);
+    },
+
+    _setProjectSetting: function(key, value)
+    {
+        return this._set(this._formatProjectKey(key), value);
+    },
+
+    _formatProjectKey: function(key)
+    {
+        return key + ":" + this._projectId;
+    }
+}
+
+WebInspector.Settings.prototype.__proto__ = WebInspector.Object.prototype;
diff --git a/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/StylesSidebarPane.js b/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/StylesSidebarPane.js
new file mode 100644
index 0000000..211b059
--- /dev/null
+++ b/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/StylesSidebarPane.js
@@ -0,0 +1,1979 @@
+/*
+ * Copyright (C) 2007 Apple Inc.  All rights reserved.
+ * Copyright (C) 2009 Joseph Pecoraro
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.StylesSidebarPane = function(computedStylePane)
+{
+    WebInspector.SidebarPane.call(this, WebInspector.UIString("Styles"));
+
+    this.settingsSelectElement = document.createElement("select");
+
+    var option = document.createElement("option");
+    option.value = "original";
+    option.action = this._changeColorFormat.bind(this);
+    option.label = WebInspector.UIString("As Authored");
+    this.settingsSelectElement.appendChild(option);
+
+    var option = document.createElement("option");
+    option.value = "hex";
+    option.action = this._changeColorFormat.bind(this);
+    option.label = WebInspector.UIString("Hex Colors");
+    this.settingsSelectElement.appendChild(option);
+
+    option = document.createElement("option");
+    option.value = "rgb";
+    option.action = this._changeColorFormat.bind(this);
+    option.label = WebInspector.UIString("RGB Colors");
+    this.settingsSelectElement.appendChild(option);
+
+    option = document.createElement("option");
+    option.value = "hsl";
+    option.action = this._changeColorFormat.bind(this);
+    option.label = WebInspector.UIString("HSL Colors");
+    this.settingsSelectElement.appendChild(option);
+
+    this.settingsSelectElement.appendChild(document.createElement("hr"));
+
+    option = document.createElement("option");
+    option.action = this._createNewRule.bind(this);
+    option.label = WebInspector.UIString("New Style Rule");
+    this.settingsSelectElement.appendChild(option);
+
+    this.settingsSelectElement.addEventListener("click", function(event) { event.stopPropagation() }, false);
+    this.settingsSelectElement.addEventListener("change", this._changeSetting.bind(this), false);
+    var format = WebInspector.settings.colorFormat;
+    if (format === "original")
+        this.settingsSelectElement[0].selected = true;
+    else if (format === "hex")
+        this.settingsSelectElement[1].selected = true;
+    else if (format === "rgb")
+        this.settingsSelectElement[2].selected = true;
+    else if (format === "hsl")
+        this.settingsSelectElement[3].selected = true;
+
+    this.titleElement.appendChild(this.settingsSelectElement);
+    this._computedStylePane = computedStylePane;
+    this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
+}
+
+WebInspector.StylesSidebarPane.StyleValueDelimiters = " \t\n\"':;,/()";
+
+// Taken from http://www.w3.org/TR/CSS21/propidx.html.
+WebInspector.StylesSidebarPane.InheritedProperties = [
+    "azimuth", "border-collapse", "border-spacing", "caption-side", "color", "cursor", "direction", "elevation",
+    "empty-cells", "font-family", "font-size", "font-style", "font-variant", "font-weight", "font", "letter-spacing",
+    "line-height", "list-style-image", "list-style-position", "list-style-type", "list-style", "orphans", "pitch-range",
+    "pitch", "quotes", "richness", "speak-header", "speak-numeral", "speak-punctuation", "speak", "speech-rate", "stress",
+    "text-align", "text-indent", "text-transform", "text-shadow", "visibility", "voice-family", "volume", "white-space", "widows", "word-spacing"
+].keySet();
+
+// Keep in sync with RenderStyleConstants.h PseudoId enum. Array below contains pseudo id names for corresponding enum indexes.
+// First item is empty due to its artificial NOPSEUDO nature in the enum.
+// FIXME: find a way of generating this mapping or getting it from combination of RenderStyleConstants and CSSSelector.cpp at
+// runtime.
+WebInspector.StylesSidebarPane.PseudoIdNames = [
+    "", "first-line", "first-letter", "before", "after", "selection", "", "-webkit-scrollbar", "-webkit-file-upload-button",
+    "-webkit-input-placeholder", "-webkit-slider-thumb", "-webkit-search-cancel-button", "-webkit-search-decoration",
+    "-webkit-search-results-decoration", "-webkit-search-results-button", "-webkit-media-controls-panel",
+    "-webkit-media-controls-play-button", "-webkit-media-controls-mute-button", "-webkit-media-controls-timeline",
+    "-webkit-media-controls-timeline-container", "-webkit-media-controls-volume-slider",
+    "-webkit-media-controls-volume-slider-container", "-webkit-media-controls-current-time-display",
+    "-webkit-media-controls-time-remaining-display", "-webkit-media-controls-seek-back-button", "-webkit-media-controls-seek-forward-button",
+    "-webkit-media-controls-fullscreen-button", "-webkit-media-controls-rewind-button", "-webkit-media-controls-return-to-realtime-button",
+    "-webkit-media-controls-toggle-closed-captions-button", "-webkit-media-controls-status-display", "-webkit-scrollbar-thumb",
+    "-webkit-scrollbar-button", "-webkit-scrollbar-track", "-webkit-scrollbar-track-piece", "-webkit-scrollbar-corner",
+    "-webkit-resizer", "-webkit-input-list-button", "-webkit-inner-spin-button", "-webkit-outer-spin-button"
+];
+
+WebInspector.StylesSidebarPane.prototype = {
+    _contextMenuEventFired: function(event)
+    {
+        var href = event.target.enclosingNodeOrSelfWithClass("webkit-html-resource-link") || event.target.enclosingNodeOrSelfWithClass("webkit-html-external-link");
+        if (href) {
+            var contextMenu = new WebInspector.ContextMenu();
+            var filled = WebInspector.panels.elements.populateHrefContextMenu(contextMenu, event, href);
+            if (filled)
+                contextMenu.show(event);
+        }
+    },
+
+    update: function(node, editedSection, forceUpdate)
+    {
+        var refresh = false;
+
+        if (forceUpdate)
+            delete this.node;
+
+        if (!forceUpdate && (!node || node === this.node))
+            refresh = true;
+
+        if (node && node.nodeType === Node.TEXT_NODE && node.parentNode)
+            node = node.parentNode;
+
+        if (node && node.nodeType !== Node.ELEMENT_NODE)
+            node = null;
+
+        if (node)
+            this.node = node;
+        else
+            node = this.node;
+
+        if (!node) {
+            this.bodyElement.removeChildren();
+            this._computedStylePane.bodyElement.removeChildren();
+            this.sections = {};
+            return;
+        }
+
+        function stylesCallback(styles)
+        {
+            if (styles)
+                this._rebuildUpdate(node, styles);
+        }
+
+        function computedStyleCallback(computedStyle)
+        {
+            if (computedStyle)
+                this._refreshUpdate(node, computedStyle, editedSection);
+        }
+
+        if (refresh)
+            WebInspector.cssModel.getComputedStyleAsync(node.id, computedStyleCallback.bind(this));
+        else
+            WebInspector.cssModel.getStylesAsync(node.id, stylesCallback.bind(this));
+    },
+
+    _refreshUpdate: function(node, computedStyle, editedSection)
+    {
+        for (var pseudoId in this.sections) {
+            var styleRules = this._refreshStyleRules(this.sections[pseudoId], computedStyle);
+            var usedProperties = {};
+            var disabledComputedProperties = {};
+            this._markUsedProperties(styleRules, usedProperties, disabledComputedProperties);
+            this._refreshSectionsForStyleRules(styleRules, usedProperties, disabledComputedProperties, editedSection);
+        }
+        // Trace the computed style.
+        this.sections[0][0].rebuildComputedTrace(this.sections[0]);
+    },
+
+    _rebuildUpdate: function(node, styles)
+    {
+        this.bodyElement.removeChildren();
+        this._computedStylePane.bodyElement.removeChildren();
+
+        var styleRules = this._rebuildStyleRules(node, styles);
+        var usedProperties = {};
+        var disabledComputedProperties = {};
+        this._markUsedProperties(styleRules, usedProperties, disabledComputedProperties);
+        this.sections[0] = this._rebuildSectionsForStyleRules(styleRules, usedProperties, disabledComputedProperties, 0);
+        var anchorElement = this.sections[0].inheritedPropertiesSeparatorElement;
+        // Trace the computed style.
+        this.sections[0][0].rebuildComputedTrace(this.sections[0]);
+
+        for (var i = 0; i < styles.pseudoElements.length; ++i) {
+            var pseudoElementCSSRules = styles.pseudoElements[i];
+
+            styleRules = [];
+            var pseudoId = pseudoElementCSSRules.pseudoId;
+
+            var entry = { isStyleSeparator: true, pseudoId: pseudoId };
+            styleRules.push(entry);
+
+            // Add rules in reverse order to match the cascade order.
+            for (var j = pseudoElementCSSRules.rules.length - 1; j >= 0; --j) {
+                var rule = pseudoElementCSSRules.rules[j];
+                styleRules.push({ style: rule.style, selectorText: rule.selectorText, sourceURL: rule.sourceURL, rule: rule, editable: !!(rule.style && rule.style.id) });
+            }
+            usedProperties = {};
+            disabledComputedProperties = {};
+            this._markUsedProperties(styleRules, usedProperties, disabledComputedProperties);
+            this.sections[pseudoId] = this._rebuildSectionsForStyleRules(styleRules, usedProperties, disabledComputedProperties, pseudoId, anchorElement);
+        }
+    },
+
+    _refreshStyleRules: function(sections, computedStyle)
+    {
+        var nodeComputedStyle = computedStyle;
+        var styleRules = [];
+        for (var i = 0; sections && i < sections.length; ++i) {
+            var section = sections[i];
+            if (section instanceof WebInspector.BlankStylePropertiesSection)
+                continue;
+            if (section.computedStyle)
+                section.styleRule.style = nodeComputedStyle;
+            var styleRule = { section: section, style: section.styleRule.style, computedStyle: section.computedStyle, rule: section.rule, editable: !!(section.styleRule.style && section.styleRule.style.id) };
+            styleRules.push(styleRule);
+        }
+        return styleRules;
+    },
+
+    _rebuildStyleRules: function(node, styles)
+    {
+        var nodeComputedStyle = styles.computedStyle;
+        this.sections = {};
+
+        var styleRules = [];
+
+        styleRules.push({ computedStyle: true, selectorText: "", style: nodeComputedStyle, editable: false });
+
+        var styleAttributes = {};
+        for (var name in styles.styleAttributes) {
+            var attrStyle = { style: styles.styleAttributes[name], editable: false };
+            attrStyle.selectorText = WebInspector.panels.elements.treeOutline.nodeNameToCorrectCase(node.nodeName) + "[" + name;
+            if (node.getAttribute(name))
+                attrStyle.selectorText += "=" + node.getAttribute(name);
+            attrStyle.selectorText += "]";
+            styleRules.push(attrStyle);
+        }
+
+        // Show element's Style Attributes
+        if (styles.inlineStyle && node.nodeType === Node.ELEMENT_NODE) {
+            var inlineStyle = { selectorText: "element.style", style: styles.inlineStyle, isAttribute: true };
+            styleRules.push(inlineStyle);
+        }
+
+        // Add rules in reverse order to match the cascade order.
+        if (styles.matchedCSSRules.length)
+            styleRules.push({ isStyleSeparator: true, text: WebInspector.UIString("Matched CSS Rules") });
+        for (var i = styles.matchedCSSRules.length - 1; i >= 0; --i) {
+            var rule = styles.matchedCSSRules[i];
+            styleRules.push({ style: rule.style, selectorText: rule.selectorText, sourceURL: rule.sourceURL, rule: rule, editable: !!(rule.style && rule.style.id) });
+        }
+
+        // Walk the node structure and identify styles with inherited properties.
+        var parentNode = node.parentNode;
+        function insertInheritedNodeSeparator(node)
+        {
+            var entry = {};
+            entry.isStyleSeparator = true;
+            entry.node = node;
+            styleRules.push(entry);
+        }
+
+        for (var parentOrdinal = 0; parentOrdinal < styles.inherited.length; ++parentOrdinal) {
+            var parentStyles = styles.inherited[parentOrdinal];
+            var separatorInserted = false;
+            if (parentStyles.inlineStyle) {
+                if (this._containsInherited(parentStyles.inlineStyle)) {
+                    var inlineStyle = { selectorText: WebInspector.UIString("Style Attribute"), style: parentStyles.inlineStyle, isAttribute: true, isInherited: true };
+                    if (!separatorInserted) {
+                        insertInheritedNodeSeparator(parentNode);
+                        separatorInserted = true;
+                    }
+                    styleRules.push(inlineStyle);
+                }
+            }
+
+            for (var i = parentStyles.matchedCSSRules.length - 1; i >= 0; --i) {
+                var rulePayload = parentStyles.matchedCSSRules[i];
+                if (!this._containsInherited(rulePayload.style))
+                    continue;
+                var rule = rulePayload;
+                if (!separatorInserted) {
+                    insertInheritedNodeSeparator(parentNode);
+                    separatorInserted = true;
+                }
+                styleRules.push({ style: rule.style, selectorText: rule.selectorText, sourceURL: rule.sourceURL, rule: rule, isInherited: true, editable: !!(rule.style && rule.style.id) });
+            }
+            parentNode = parentNode.parentNode;
+        }
+        return styleRules;
+    },
+
+    _markUsedProperties: function(styleRules, usedProperties, disabledComputedProperties)
+    {
+        var priorityUsed = false;
+
+        // Walk the style rules and make a list of all used and overloaded properties.
+        for (var i = 0; i < styleRules.length; ++i) {
+            var styleRule = styleRules[i];
+            if (styleRule.computedStyle || styleRule.isStyleSeparator)
+                continue;
+            if (styleRule.section && styleRule.section.noAffect)
+                continue;
+
+            styleRule.usedProperties = {};
+
+            var style = styleRule.style;
+            var allProperties = style.allProperties;
+            for (var j = 0; j < allProperties.length; ++j) {
+                var property = allProperties[j];
+                if (!property.isLive)
+                    continue;
+                var name = property.name;
+
+                if (!priorityUsed && property.priority.length)
+                    priorityUsed = true;
+
+                // If the property name is already used by another rule then this rule's
+                // property is overloaded, so don't add it to the rule's usedProperties.
+                if (!(name in usedProperties))
+                    styleRule.usedProperties[name] = true;
+
+                if (name === "font") {
+                    // The font property is not reported as a shorthand. Report finding the individual
+                    // properties so they are visible in computed style.
+                    // FIXME: remove this when http://bugs.webkit.org/show_bug.cgi?id=15598 is fixed.
+                    styleRule.usedProperties["font-family"] = true;
+                    styleRule.usedProperties["font-size"] = true;
+                    styleRule.usedProperties["font-style"] = true;
+                    styleRule.usedProperties["font-variant"] = true;
+                    styleRule.usedProperties["font-weight"] = true;
+                    styleRule.usedProperties["line-height"] = true;
+                }
+            }
+
+            // Add all the properties found in this style to the used properties list.
+            // Do this here so only future rules are affect by properties used in this rule.
+            for (var name in styleRules[i].usedProperties)
+                usedProperties[name] = true;
+        }
+
+        if (priorityUsed) {
+            // Walk the properties again and account for !important.
+            var foundPriorityProperties = [];
+
+            // Walk in reverse to match the order !important overrides.
+            for (var i = (styleRules.length - 1); i >= 0; --i) {
+                if (styleRules[i].computedStyle || styleRules[i].isStyleSeparator)
+                    continue;
+
+                var style = styleRules[i].style;
+                var allProperties = style.allProperties;
+                for (var j = 0; j < allProperties.length; ++j) {
+                    var property = allProperties[j];
+                    if (!property.isLive)
+                        continue;
+                    var name = property.name;
+                    if (property.priority.length) {
+                        if (!(name in foundPriorityProperties))
+                            styleRules[i].usedProperties[name] = true;
+                        else
+                            delete styleRules[i].usedProperties[name];
+                        foundPriorityProperties[name] = true;
+                    } else if (name in foundPriorityProperties)
+                        delete styleRules[i].usedProperties[name];
+                }
+            }
+        }
+    },
+
+    _refreshSectionsForStyleRules: function(styleRules, usedProperties, disabledComputedProperties, editedSection)
+    {
+        // Walk the style rules and update the sections with new overloaded and used properties.
+        for (var i = 0; i < styleRules.length; ++i) {
+            var styleRule = styleRules[i];
+            var section = styleRule.section;
+            if (styleRule.computedStyle) {
+                section._disabledComputedProperties = disabledComputedProperties;
+                section._usedProperties = usedProperties;
+                section.update();
+            } else {
+                section._usedProperties = styleRule.usedProperties;
+                section.update(section === editedSection);
+            }
+        }
+    },
+
+    _rebuildSectionsForStyleRules: function(styleRules, usedProperties, disabledComputedProperties, pseudoId, anchorElement)
+    {
+        anchorElement = anchorElement || null;
+        // Make a property section for each style rule.
+        var sections = [];
+        var lastWasSeparator = true;
+        for (var i = 0; i < styleRules.length; ++i) {
+            var styleRule = styleRules[i];
+            if (styleRule.isStyleSeparator) {
+                var separatorElement = document.createElement("div");
+                separatorElement.className = "styles-sidebar-separator";
+                if (styleRule.node) {
+                    var link = WebInspector.panels.elements.linkifyNodeReference(styleRule.node);
+                    separatorElement.appendChild(document.createTextNode(WebInspector.UIString("Inherited from") + " "));
+                    separatorElement.appendChild(link);
+                    if (!sections.inheritedPropertiesSeparatorElement)
+                        sections.inheritedPropertiesSeparatorElement = separatorElement;
+                } else if ("pseudoId" in styleRule) {
+                    var pseudoName = WebInspector.StylesSidebarPane.PseudoIdNames[styleRule.pseudoId];
+                    if (pseudoName)
+                        separatorElement.textContent = WebInspector.UIString("Pseudo ::%s element", pseudoName);
+                    else
+                        separatorElement.textContent = WebInspector.UIString("Pseudo element");
+                } else
+                    separatorElement.textContent = styleRule.text;
+                this.bodyElement.insertBefore(separatorElement, anchorElement);
+                lastWasSeparator = true;
+                continue;
+            }
+            var computedStyle = styleRule.computedStyle;
+
+            // Default editable to true if it was omitted.
+            var editable = styleRule.editable;
+            if (typeof editable === "undefined")
+                editable = true;
+
+            if (computedStyle)
+                var section = new WebInspector.ComputedStylePropertiesSection(styleRule, usedProperties, disabledComputedProperties, styleRules);
+            else
+                var section = new WebInspector.StylePropertiesSection(styleRule, editable, styleRule.isInherited, lastWasSeparator);
+            section.pane = this;
+            section.expanded = true;
+
+            if (computedStyle) {
+                this._computedStylePane.bodyElement.appendChild(section.element);
+                lastWasSeparator = true;
+            } else {
+                this.bodyElement.insertBefore(section.element, anchorElement);
+                lastWasSeparator = false;
+            }
+            sections.push(section);
+        }
+        return sections;
+    },
+
+    _containsInherited: function(style)
+    {
+        var properties = style.allProperties;
+        for (var i = 0; i < properties.length; ++i) {
+            var property = properties[i];
+            // Does this style contain non-overridden inherited property?
+            if (property.isLive && property.name in WebInspector.StylesSidebarPane.InheritedProperties)
+                return true;
+        }
+        return false;
+    },
+
+    _changeSetting: function(event)
+    {
+        var options = this.settingsSelectElement.options;
+        var selectedOption = options[this.settingsSelectElement.selectedIndex];
+        selectedOption.action(event);
+
+        // Select the correct color format setting again, since it needs to be selected.
+        var selectedIndex = 0;
+        for (var i = 0; i < options.length; ++i) {
+            if (options[i].value === WebInspector.settings.colorFormat) {
+                selectedIndex = i;
+                break;
+            }
+        }
+
+        this.settingsSelectElement.selectedIndex = selectedIndex;
+    },
+
+    _changeColorFormat: function(event)
+    {
+        var selectedOption = this.settingsSelectElement[this.settingsSelectElement.selectedIndex];
+        WebInspector.settings.colorFormat = selectedOption.value;
+
+        for (var pseudoId in this.sections) {
+            var sections = this.sections[pseudoId];
+            for (var i = 0; i < sections.length; ++i)
+                sections[i].update(true);
+        }
+    },
+
+    _createNewRule: function(event)
+    {
+        this.addBlankSection().startEditingSelector();
+    },
+
+    addBlankSection: function()
+    {
+        var blankSection = new WebInspector.BlankStylePropertiesSection(appropriateSelectorForNode(this.node, true));
+        blankSection.pane = this;
+
+        var elementStyleSection = this.sections[0][1];
+        this.bodyElement.insertBefore(blankSection.element, elementStyleSection.element.nextSibling);
+
+        this.sections[0].splice(2, 0, blankSection);
+
+        return blankSection;
+    },
+
+    removeSection: function(section)
+    {
+        for (var pseudoId in this.sections) {
+            var sections = this.sections[pseudoId];
+            var index = sections.indexOf(section);
+            if (index === -1)
+                continue;
+            sections.splice(index, 1);
+            if (section.element.parentNode)
+                section.element.parentNode.removeChild(section.element);
+        }
+    },
+
+    registerShortcuts: function()
+    {
+        var section = WebInspector.shortcutsHelp.section(WebInspector.UIString("Styles Pane"));
+        var shortcut = WebInspector.KeyboardShortcut;
+        var keys = [
+            shortcut.shortcutToString(shortcut.Keys.Tab),
+            shortcut.shortcutToString(shortcut.Keys.Tab, shortcut.Modifiers.Shift)
+        ];
+        section.addRelatedKeys(keys, WebInspector.UIString("Next/previous property"));
+        keys = [
+            shortcut.shortcutToString(shortcut.Keys.Up),
+            shortcut.shortcutToString(shortcut.Keys.Down)
+        ];
+        section.addRelatedKeys(keys, WebInspector.UIString("Increment/decrement value"));
+        keys = [
+            shortcut.shortcutToString(shortcut.Keys.Up, shortcut.Modifiers.Shift),
+            shortcut.shortcutToString(shortcut.Keys.Down, shortcut.Modifiers.Shift)
+        ];
+        section.addRelatedKeys(keys, WebInspector.UIString("Increment/decrement by %f", 10));
+        keys = [
+            shortcut.shortcutToString(shortcut.Keys.PageUp),
+            shortcut.shortcutToString(shortcut.Keys.PageDown)
+        ];
+        section.addRelatedKeys(keys, WebInspector.UIString("Increment/decrement by %f", 10));
+        keys = [
+            shortcut.shortcutToString(shortcut.Keys.PageUp, shortcut.Modifiers.Shift),
+            shortcut.shortcutToString(shortcut.Keys.PageDown, shortcut.Modifiers.Shift)
+        ];
+        section.addRelatedKeys(keys, WebInspector.UIString("Increment/decrement by %f", 100));
+        keys = [
+            shortcut.shortcutToString(shortcut.Keys.PageUp, shortcut.Modifiers.Alt),
+            shortcut.shortcutToString(shortcut.Keys.PageDown, shortcut.Modifiers.Alt)
+        ];
+        section.addRelatedKeys(keys, WebInspector.UIString("Increment/decrement by %f", 0.1));
+    }
+}
+
+WebInspector.StylesSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
+
+WebInspector.ComputedStyleSidebarPane = function()
+{
+    WebInspector.SidebarPane.call(this, WebInspector.UIString("Computed Style"));
+    var showInheritedCheckbox = new WebInspector.Checkbox(WebInspector.UIString("Show inherited"), "sidebar-pane-subtitle");
+    this.titleElement.appendChild(showInheritedCheckbox.element);
+
+    if (WebInspector.settings.showInheritedComputedStyleProperties) {
+        this.bodyElement.addStyleClass("show-inherited");
+        showInheritedCheckbox.checked = true;
+    }
+
+    function showInheritedToggleFunction(event)
+    {
+        WebInspector.settings.showInheritedComputedStyleProperties = showInheritedCheckbox.checked;
+        if (WebInspector.settings.showInheritedComputedStyleProperties)
+            this.bodyElement.addStyleClass("show-inherited");
+        else
+            this.bodyElement.removeStyleClass("show-inherited");
+    }
+
+    showInheritedCheckbox.addEventListener(showInheritedToggleFunction.bind(this));
+}
+
+WebInspector.ComputedStyleSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
+
+WebInspector.StylePropertiesSection = function(styleRule, editable, isInherited, isFirstSection)
+{
+    WebInspector.PropertiesSection.call(this, "");
+    this.element.className = "styles-section monospace" + (isFirstSection ? " first-styles-section" : "");
+
+    this._selectorElement = document.createElement("span");
+    this._selectorElement.textContent = styleRule.selectorText;
+    this.titleElement.appendChild(this._selectorElement);
+    if (Preferences.debugMode)
+        this._selectorElement.addEventListener("click", this._debugShowStyle.bind(this), false);
+
+    var openBrace = document.createElement("span");
+    openBrace.textContent = " {";
+    this.titleElement.appendChild(openBrace);
+
+    var closeBrace = document.createElement("div");
+    closeBrace.textContent = "}";
+    this.element.appendChild(closeBrace);
+
+    this._selectorElement.addEventListener("dblclick", this._handleSelectorDoubleClick.bind(this), false);
+    this.element.addEventListener("dblclick", this._handleEmptySpaceDoubleClick.bind(this), false);
+
+    this.styleRule = styleRule;
+    this.rule = this.styleRule.rule;
+    this.editable = editable;
+    this.isInherited = isInherited;
+
+    // Prevent editing the user agent and user rules.
+    var isUserAgent = this.rule && this.rule.isUserAgent;
+    var isUser = this.rule && this.rule.isUser;
+    var isViaInspector = this.rule && this.rule.isViaInspector;
+
+    if (isUserAgent || isUser)
+        this.editable = false;
+
+    this._usedProperties = styleRule.usedProperties;
+
+    if (this.rule)
+        this.titleElement.addStyleClass("styles-selector");
+
+    function linkifyUncopyable(url, line)
+    {
+        var link = WebInspector.linkifyResourceAsNode(url, "resources", line + 1);
+        link.setAttribute("data-uncopyable", link.textContent);
+        link.textContent = "";
+        return link;
+    }
+
+    var subtitle = "";
+    if (this.styleRule.sourceURL)
+        this.subtitleElement.appendChild(linkifyUncopyable(this.styleRule.sourceURL, this.rule.sourceLine));
+    else if (isUserAgent)
+        subtitle = WebInspector.UIString("user agent stylesheet");
+    else if (isUser)
+        subtitle = WebInspector.UIString("user stylesheet");
+    else if (isViaInspector)
+        subtitle = WebInspector.UIString("via inspector");
+    else if (this.rule && this.rule.sourceURL)
+        this.subtitleElement.appendChild(linkifyUncopyable(this.rule.sourceURL, this.rule.sourceLine));
+
+    if (isInherited)
+        this.element.addStyleClass("show-inherited"); // This one is related to inherited rules, not compted style.
+    if (subtitle)
+        this.subtitle = subtitle;
+
+    this.identifier = styleRule.selectorText;
+    if (this.subtitle)
+        this.identifier += ":" + this.subtitle;
+
+    if (!this.editable)
+        this.element.addStyleClass("read-only");
+}
+
+WebInspector.StylePropertiesSection.prototype = {
+    collapse: function(dontRememberState)
+    {
+        // Overriding with empty body.
+    },
+
+    isPropertyInherited: function(propertyName)
+    {
+        if (this.isInherited) {
+            // While rendering inherited stylesheet, reverse meaning of this property.
+            // Render truly inherited properties with black, i.e. return them as non-inherited.
+            return !(propertyName in WebInspector.StylesSidebarPane.InheritedProperties);
+        }
+        return false;
+    },
+
+    isPropertyOverloaded: function(propertyName, shorthand)
+    {
+        if (!this._usedProperties || this.noAffect)
+            return false;
+
+        if (this.isInherited && !(propertyName in WebInspector.StylesSidebarPane.InheritedProperties)) {
+            // In the inherited sections, only show overrides for the potentially inherited properties.
+            return false;
+        }
+
+        var used = (propertyName in this._usedProperties);
+        if (used || !shorthand)
+            return !used;
+
+        // Find out if any of the individual longhand properties of the shorthand
+        // are used, if none are then the shorthand is overloaded too.
+        var longhandProperties = this.styleRule.style.getLonghandProperties(propertyName);
+        for (var j = 0; j < longhandProperties.length; ++j) {
+            var individualProperty = longhandProperties[j];
+            if (individualProperty.name in this._usedProperties)
+                return false;
+        }
+
+        return true;
+    },
+
+    nextEditableSibling: function()
+    {
+        var curSection = this;
+        do {
+            curSection = curSection.nextSibling;
+        } while (curSection && !curSection.editable);
+
+        return curSection;
+    },
+
+    previousEditableSibling: function()
+    {
+        var curSection = this;
+        do {
+            curSection = curSection.previousSibling;
+        } while (curSection && !curSection.editable);
+
+        return curSection;
+    },
+
+    update: function(full)
+    {
+        if (full) {
+            this.propertiesTreeOutline.removeChildren();
+            this.populated = false;
+        } else {
+            var child = this.propertiesTreeOutline.children[0];
+            while (child) {
+                child.overloaded = this.isPropertyOverloaded(child.name, child.shorthand);
+                child = child.traverseNextTreeElement(false, null, true);
+            }
+        }
+        this.afterUpdate();
+    },
+
+    afterUpdate: function()
+    {
+        if (this._afterUpdate) {
+            this._afterUpdate(this);
+            delete this._afterUpdate;
+        }
+    },
+
+    onpopulate: function()
+    {
+        var style = this.styleRule.style;
+
+        var handledProperties = {};
+        var shorthandNames = {};
+
+        this.uniqueProperties = [];
+        var allProperties = style.allProperties;
+        for (var i = 0; i < allProperties.length; ++i)
+            this.uniqueProperties.push(allProperties[i]);
+
+        // Collect all shorthand names.
+        for (var i = 0; i < this.uniqueProperties.length; ++i) {
+            var property = this.uniqueProperties[i];
+            if (property.disabled)
+                continue;
+            if (property.shorthand)
+                shorthandNames[property.shorthand] = true;
+        }
+
+        // Collect all shorthand names.
+        for (var i = 0; i < this.uniqueProperties.length; ++i) {
+            var property = this.uniqueProperties[i];
+            var disabled = property.disabled;
+            if (!disabled && this.disabledComputedProperties && !(property.name in this.usedProperties) && property.name in this.disabledComputedProperties)
+                disabled = true;
+
+            var shorthand = !disabled ? property.shorthand : null;
+
+            if (shorthand && shorthand in handledProperties)
+                continue;
+
+            if (shorthand) {
+                property = style.getLiveProperty(shorthand);
+                if (!property)
+                    property = new WebInspector.CSSProperty(style, style.allProperties.length, shorthand, style.getShorthandValue(shorthand), style.getShorthandPriority(shorthand), "style", true, true, "");
+            }
+
+            var isShorthand = !!(property.isLive && (shorthand || shorthandNames[property.name]));
+            var inherited = this.isPropertyInherited(property.name);
+            var overloaded = this.isPropertyOverloaded(property.name, isShorthand);
+
+            var item = new WebInspector.StylePropertyTreeElement(this.styleRule, style, property, isShorthand, inherited, overloaded);
+            this.propertiesTreeOutline.appendChild(item);
+            handledProperties[property.name] = property;
+        }
+    },
+
+    findTreeElementWithName: function(name)
+    {
+        var treeElement = this.propertiesTreeOutline.children[0];
+        while (treeElement) {
+            if (treeElement.name === name)
+                return treeElement;
+            treeElement = treeElement.traverseNextTreeElement(true, null, true);
+        }
+        return null;
+    },
+
+    addNewBlankProperty: function(optionalIndex)
+    {
+        var style = this.styleRule.style;
+        var property = style.newBlankProperty();
+        var item = new WebInspector.StylePropertyTreeElement(this.styleRule, style, property, false, false, false);
+        this.propertiesTreeOutline.appendChild(item);
+        item.listItemElement.textContent = "";
+        item._newProperty = true;
+        item.updateTitle();
+        return item;
+    },
+
+    _debugShowStyle: function(anchor)
+    {
+        var boundHandler;
+        function removeStyleBox(element, event)
+        {
+            if (event.target === element) {
+                event.stopPropagation();
+                return;
+            }
+            document.body.removeChild(element);
+            document.getElementById("main").removeEventListener("mousedown", boundHandler, true);
+        }
+
+        if (!event.shiftKey)
+            return;
+
+        var container = document.createElement("div");
+        var element = document.createElement("span");
+        container.appendChild(element);
+        element.style.background = "yellow";
+        element.style.display = "inline-block";
+        container.style.cssText = "z-index: 2000000; position: absolute; top: 50px; left: 50px; white-space: pre; overflow: auto; background: white; font-family: monospace; font-size: 12px; border: 1px solid black; opacity: 0.85; -webkit-user-select: text; padding: 2px;";
+        container.style.width = (document.body.offsetWidth - 100) + "px";
+        container.style.height = (document.body.offsetHeight - 100) + "px";
+        document.body.appendChild(container);
+        if (this.rule)
+            element.textContent = this.rule.selectorText + " {" + ((this.styleRule.style.cssText !== undefined) ? this.styleRule.style.cssText : "<no cssText>") + "}";
+        else
+            element.textContent = this.styleRule.style.cssText;
+        boundHandler = removeStyleBox.bind(null, container);
+        document.getElementById("main").addEventListener("mousedown", boundHandler, true);
+    },
+
+    _handleEmptySpaceDoubleClick: function(event)
+    {
+        if (event.target.hasStyleClass("header")) {
+            event.stopPropagation();
+            return;
+        }
+        this.expand();
+        this.addNewBlankProperty().startEditing();
+    },
+
+    _handleSelectorClick: function(event)
+    {
+        event.stopPropagation();
+    },
+
+    _handleSelectorDoubleClick: function(event)
+    {
+        this._startEditingOnMouseEvent();
+        event.stopPropagation();
+    },
+
+    _startEditingOnMouseEvent: function()
+    {
+        if (!this.editable)
+            return;
+
+        if (!this.rule && this.propertiesTreeOutline.children.length === 0) {
+            this.expand();
+            this.addNewBlankProperty().startEditing();
+            return;
+        }
+
+        if (!this.rule)
+            return;
+
+        this.startEditingSelector();
+    },
+
+    startEditingSelector: function()
+    {
+        var element = this._selectorElement;
+        if (WebInspector.isBeingEdited(element))
+            return;
+
+        WebInspector.startEditing(this._selectorElement, {
+            context: null,
+            commitHandler: this.editingSelectorCommitted.bind(this),
+            cancelHandler: this.editingSelectorCancelled.bind(this)
+        });
+        window.getSelection().setBaseAndExtent(element, 0, element, 1);
+    },
+
+    editingSelectorCommitted: function(element, newContent, oldContent, context, moveDirection)
+    {
+        function moveToNextIfNeeded() {
+            if (!moveDirection)
+                return;
+
+            if (moveDirection === "forward") {
+                this.expand();
+                if (this.propertiesTreeOutline.children.length === 0)
+                    this.addNewBlankProperty().startEditing();
+                else {
+                    var item = this.propertiesTreeOutline.children[0]
+                    item.startEditing(item.nameElement);
+                }
+            } else {
+                var previousSection = this.previousEditableSibling();
+                if (!previousSection)
+                    return;
+
+                previousSection.expand();
+                previousSection.addNewBlankProperty().startEditing();
+            }
+        }
+
+        if (newContent === oldContent)
+            return moveToNextIfNeeded.call(this);
+
+        var self = this;
+
+        function successCallback(newRule, doesAffectSelectedNode)
+        {
+            if (!doesAffectSelectedNode) {
+                self.noAffect = true;
+                self.element.addStyleClass("no-affect");
+            } else {
+                delete self.noAffect;
+                self.element.removeStyleClass("no-affect");
+            }
+
+            self.rule = newRule;
+            self.styleRule = { section: self, style: newRule.style, selectorText: newRule.selectorText, sourceURL: newRule.sourceURL, rule: newRule };
+
+            var oldIdentifier = this.identifier;
+            self.identifier = newRule.selectorText + ":" + self.subtitleElement.textContent;
+
+            self.pane.update();
+
+            WebInspector.panels.elements.renameSelector(oldIdentifier, this.identifier, oldContent, newContent);
+
+            moveToNextIfNeeded.call(self);
+        }
+
+        var focusedNode = WebInspector.panels.elements.focusedDOMNode;
+        WebInspector.cssModel.setRuleSelector(this.rule.id, focusedNode ? focusedNode.id : 0, newContent, successCallback, moveToNextIfNeeded.bind(this));
+    },
+
+    editingSelectorCancelled: function()
+    {
+        // Do nothing, this is overridden by BlankStylePropertiesSection.
+    }
+}
+
+WebInspector.StylePropertiesSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype;
+
+WebInspector.ComputedStylePropertiesSection = function(styleRule, usedProperties, disabledComputedProperties)
+{
+    WebInspector.PropertiesSection.call(this, "");
+    this.headerElement.addStyleClass("hidden");
+    this.element.className = "styles-section monospace first-styles-section read-only computed-style";
+    this.styleRule = styleRule;
+    this._usedProperties = usedProperties;
+    this._disabledComputedProperties = disabledComputedProperties;
+    this._alwaysShowComputedProperties = { "display": true, "height": true, "width": true };
+    this.computedStyle = true;
+    this._propertyTreeElements = {};
+    this._expandedPropertyNames = {};
+}
+
+WebInspector.ComputedStylePropertiesSection.prototype = {
+    collapse: function(dontRememberState)
+    {
+        // Overriding with empty body.
+    },
+
+    _isPropertyInherited: function(propertyName)
+    {
+        return !(propertyName in this._usedProperties) && !(propertyName in this._alwaysShowComputedProperties) && !(propertyName in this._disabledComputedProperties);
+    },
+
+    update: function()
+    {
+        this._expandedPropertyNames = {};
+        for (var name in this._propertyTreeElements) {
+            if (this._propertyTreeElements[name].expanded)
+                this._expandedPropertyNames[name] = true;
+        }
+        this._propertyTreeElements = {};
+        this.propertiesTreeOutline.removeChildren();
+        this.populated = false;
+    },
+
+    onpopulate: function()
+    {
+        function sorter(a, b)
+        {
+            return a.name.localeCompare(b.name);
+        }
+
+        var style = this.styleRule.style;
+        var uniqueProperties = [];
+        var allProperties = style.allProperties;
+        for (var i = 0; i < allProperties.length; ++i)
+            uniqueProperties.push(allProperties[i]);
+        uniqueProperties.sort(sorter);
+
+        this._propertyTreeElements = {};
+        for (var i = 0; i < uniqueProperties.length; ++i) {
+            var property = uniqueProperties[i];
+            var inherited = this._isPropertyInherited(property.name);
+            var item = new WebInspector.StylePropertyTreeElement(this.styleRule, style, property, false, inherited, false);
+            this.propertiesTreeOutline.appendChild(item);
+            this._propertyTreeElements[property.name] = item;
+        }
+    },
+
+    rebuildComputedTrace: function(sections)
+    {
+        for (var i = 0; i < sections.length; ++i) {
+            var section = sections[i];
+            if (section.computedStyle || section instanceof WebInspector.BlankStylePropertiesSection)
+                continue;
+
+            for (var j = 0; j < section.uniqueProperties.length; ++j) {
+                var property = section.uniqueProperties[j];
+                if (property.disabled)
+                    continue;
+                if (section.isInherited && !(property.name in WebInspector.StylesSidebarPane.InheritedProperties))
+                    continue;
+
+                var treeElement = this._propertyTreeElements[property.name];
+                if (treeElement) {
+                    var selectorText = section.styleRule.selectorText;
+                    var value = property.value;
+                    var title = "<span style='color: gray'>" + selectorText + "</span> - " + value;
+                    var subtitle = " <span style='float:right'>" + section.subtitleElement.innerHTML + "</span>";
+                    var childElement = new TreeElement(null, null, false);
+                    childElement.titleHTML = title + subtitle;
+                    treeElement.appendChild(childElement);
+                    if (section.isPropertyOverloaded(property.name))
+                        childElement.listItemElement.addStyleClass("overloaded");
+                }
+            }
+        }
+
+        // Restore expanded state after update.
+        for (var name in this._expandedPropertyNames) {
+            if (name in this._propertyTreeElements)
+                this._propertyTreeElements[name].expand();
+        }
+    }
+}
+
+WebInspector.ComputedStylePropertiesSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype;
+
+WebInspector.BlankStylePropertiesSection = function(defaultSelectorText)
+{
+    WebInspector.StylePropertiesSection.call(this, {selectorText: defaultSelectorText, rule: {isViaInspector: true}}, true, false, false);
+    this.element.addStyleClass("blank-section");
+}
+
+WebInspector.BlankStylePropertiesSection.prototype = {
+    expand: function()
+    {
+        // Do nothing, blank sections are not expandable.
+    },
+
+    editingSelectorCommitted: function(element, newContent, oldContent, context)
+    {
+        var self = this;
+        function successCallback(newRule, doesSelectorAffectSelectedNode)
+        {
+            var styleRule = { section: self, style: newRule.style, selectorText: newRule.selectorText, sourceURL: newRule.sourceURL, rule: newRule };
+            self.makeNormal(styleRule);
+
+            if (!doesSelectorAffectSelectedNode) {
+                self.noAffect = true;
+                self.element.addStyleClass("no-affect");
+            }
+
+            self.subtitleElement.textContent = WebInspector.UIString("via inspector");
+            self.expand();
+
+            self.addNewBlankProperty().startEditing();
+        }
+
+        WebInspector.cssModel.addRule(this.pane.node.id, newContent, successCallback, this.editingSelectorCancelled.bind(this));
+    },
+
+    editingSelectorCancelled: function()
+    {
+        this.pane.removeSection(this);
+    },
+
+    makeNormal: function(styleRule)
+    {
+        this.element.removeStyleClass("blank-section");
+        this.styleRule = styleRule;
+        this.rule = styleRule.rule;
+        this.identifier = styleRule.selectorText + ":via inspector";
+        this.__proto__ = WebInspector.StylePropertiesSection.prototype;
+    }
+}
+
+WebInspector.BlankStylePropertiesSection.prototype.__proto__ = WebInspector.StylePropertiesSection.prototype;
+
+WebInspector.StylePropertyTreeElement = function(styleRule, style, property, shorthand, inherited, overloaded)
+{
+    this._styleRule = styleRule;
+    this.style = style;
+    this.property = property;
+    this.shorthand = shorthand;
+    this._inherited = inherited;
+    this._overloaded = overloaded;
+
+    // Pass an empty title, the title gets made later in onattach.
+    TreeElement.call(this, "", null, shorthand);
+}
+
+WebInspector.StylePropertyTreeElement.prototype = {
+    get inherited()
+    {
+        return this._inherited;
+    },
+
+    set inherited(x)
+    {
+        if (x === this._inherited)
+            return;
+        this._inherited = x;
+        this.updateState();
+    },
+
+    get overloaded()
+    {
+        return this._overloaded;
+    },
+
+    set overloaded(x)
+    {
+        if (x === this._overloaded)
+            return;
+        this._overloaded = x;
+        this.updateState();
+    },
+
+    get disabled()
+    {
+        return this.property.disabled;
+    },
+
+    get name()
+    {
+        if (!this.disabled || !this.property.text)
+            return this.property.name;
+
+        var text = this.property.text;
+        var index = text.indexOf(":");
+        if (index < 1)
+            return this.property.name;
+
+        return text.substring(0, index).trim();
+    },
+
+    get priority()
+    {
+        if (this.disabled)
+            return ""; // rely upon raw text to render it in the value field
+        return this.property.priority;
+    },
+
+    get value()
+    {
+        if (!this.disabled || !this.property.text)
+            return this.property.value;
+
+        var match = this.property.text.match(/(.*);\s*/);
+        if (!match || !match[1])
+            return this.property.value;
+
+        var text = match[1];
+        var index = text.indexOf(":");
+        if (index < 1)
+            return this.property.value;
+
+        return text.substring(index + 1).trim();
+    },
+
+    get parsedOk()
+    {
+        return this.property.parsedOk;
+    },
+
+    onattach: function()
+    {
+        this.updateTitle();
+    },
+
+    updateTitle: function()
+    {
+        var value = this.value;
+
+        this.updateState();
+
+        var enabledCheckboxElement;
+        if (this.parsedOk) {
+            enabledCheckboxElement = document.createElement("input");
+            enabledCheckboxElement.className = "enabled-button";
+            enabledCheckboxElement.type = "checkbox";
+            enabledCheckboxElement.checked = !this.disabled;
+            enabledCheckboxElement.addEventListener("change", this.toggleEnabled.bind(this), false);
+        }
+
+        var nameElement = document.createElement("span");
+        nameElement.className = "webkit-css-property";
+        nameElement.textContent = this.name;
+        this.nameElement = nameElement;
+
+        var valueElement = document.createElement("span");
+        valueElement.className = "value";
+        this.valueElement = valueElement;
+
+        if (value) {
+            var self = this;
+
+            function processValue(regex, processor, nextProcessor, valueText)
+            {
+                var container = document.createDocumentFragment();
+
+                var items = valueText.replace(regex, "\0$1\0").split("\0");
+                for (var i = 0; i < items.length; ++i) {
+                    if ((i % 2) === 0) {
+                        if (nextProcessor)
+                            container.appendChild(nextProcessor(items[i]));
+                        else
+                            container.appendChild(document.createTextNode(items[i]));
+                    } else {
+                        var processedNode = processor(items[i]);
+                        if (processedNode)
+                            container.appendChild(processedNode);
+                    }
+                }
+
+                return container;
+            }
+
+            function linkifyURL(url)
+            {
+                var hrefUrl = url;
+                var match = hrefUrl.match(/['"]?([^'"]+)/);
+                if (match)
+                    hrefUrl = match[1];
+                var container = document.createDocumentFragment();
+                container.appendChild(document.createTextNode("url("));
+                if (self._styleRule.sourceURL)
+                    hrefUrl = WebInspector.completeURL(self._styleRule.sourceURL, hrefUrl);
+                else if (WebInspector.panels.elements.focusedDOMNode)
+                    hrefUrl = WebInspector.resourceURLForRelatedNode(WebInspector.panels.elements.focusedDOMNode, hrefUrl);
+                var hasResource = !!WebInspector.resourceForURL(hrefUrl);
+                // FIXME: WebInspector.linkifyURLAsNode() should really use baseURI.
+                container.appendChild(WebInspector.linkifyURLAsNode(hrefUrl, url, null, hasResource));
+                container.appendChild(document.createTextNode(")"));
+                return container;
+            }
+
+            function processColor(text)
+            {
+                try {
+                    var color = new WebInspector.Color(text);
+                } catch (e) {
+                    return document.createTextNode(text);
+                }
+
+                var swatchElement = document.createElement("span");
+                swatchElement.title = WebInspector.UIString("Click to change color format");
+                swatchElement.className = "swatch";
+                swatchElement.style.setProperty("background-color", text);
+
+                swatchElement.addEventListener("click", changeColorDisplay, false);
+                swatchElement.addEventListener("dblclick", function(event) { event.stopPropagation() }, false);
+
+                var format;
+                if (WebInspector.settings.colorFormat === "original")
+                    format = "original";
+                else if (Preferences.showColorNicknames && color.nickname)
+                    format = "nickname";
+                else if (WebInspector.settings.colorFormat === "rgb")
+                    format = (color.simple ? "rgb" : "rgba");
+                else if (WebInspector.settings.colorFormat === "hsl")
+                    format = (color.simple ? "hsl" : "hsla");
+                else if (color.simple)
+                    format = (color.hasShortHex() ? "shorthex" : "hex");
+                else
+                    format = "rgba";
+
+                var colorValueElement = document.createElement("span");
+                colorValueElement.textContent = color.toString(format);
+
+                function nextFormat(curFormat)
+                {
+                    // The format loop is as follows:
+                    // * original
+                    // * rgb(a)
+                    // * hsl(a)
+                    // * nickname (if the color has a nickname)
+                    // * if the color is simple:
+                    //   - shorthex (if has short hex)
+                    //   - hex
+                    switch (curFormat) {
+                        case "original":
+                            return color.simple ? "rgb" : "rgba";
+
+                        case "rgb":
+                        case "rgba":
+                            return color.simple ? "hsl" : "hsla";
+
+                        case "hsl":
+                        case "hsla":
+                            if (color.nickname)
+                                return "nickname";
+                            if (color.simple)
+                                return color.hasShortHex() ? "shorthex" : "hex";
+                            else
+                                return "original";
+
+                        case "shorthex":
+                            return "hex";
+
+                        case "hex":
+                            return "original";
+
+                        case "nickname":
+                            if (color.simple)
+                                return color.hasShortHex() ? "shorthex" : "hex";
+                            else
+                                return "original";
+
+                        default:
+                            return null;
+                    }
+                }
+
+                function changeColorDisplay(event)
+                {
+                    do {
+                        format = nextFormat(format);
+                        var currentValue = color.toString(format || "");
+                    } while (format && currentValue === color.value && format !== "original");
+
+                    if (format)
+                        colorValueElement.textContent = currentValue;
+                }
+
+                var container = document.createDocumentFragment();
+                container.appendChild(swatchElement);
+                container.appendChild(colorValueElement);
+                return container;
+            }
+
+            var colorRegex = /((?:rgb|hsl)a?\([^)]+\)|#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3}|\b\w+\b(?!-))/g;
+            var colorProcessor = processValue.bind(window, colorRegex, processColor, null);
+
+            valueElement.appendChild(processValue(/url\(\s*([^)\s]+)\s*\)/g, linkifyURL, colorProcessor, value));
+        }
+
+        this.listItemElement.removeChildren();
+        nameElement.normalize();
+        valueElement.normalize();
+
+        if (!this.treeOutline)
+            return;
+
+        // Append the checkbox for root elements of an editable section.
+        if (enabledCheckboxElement && this.treeOutline.section && this.treeOutline.section.editable && this.parent.root)
+            this.listItemElement.appendChild(enabledCheckboxElement);
+        this.listItemElement.appendChild(nameElement);
+        this.listItemElement.appendChild(document.createTextNode(": "));
+        this.listItemElement.appendChild(valueElement);
+        this.listItemElement.appendChild(document.createTextNode(";"));
+
+        if (!this.parsedOk) {
+            // Avoid having longhands under an invalid shorthand.
+            this.hasChildren = false;
+            this.listItemElement.addStyleClass("not-parsed-ok");
+        }
+        if (this.property.inactive)
+            this.listItemElement.addStyleClass("inactive");
+
+        this.tooltip = this.property.propertyText;
+    },
+
+    updateAll: function(updateAllRules)
+    {
+        if (!this.treeOutline)
+            return;
+        if (updateAllRules && this.treeOutline.section && this.treeOutline.section.pane)
+            this.treeOutline.section.pane.update(null, this.treeOutline.section);
+        else if (this.treeOutline.section)
+            this.treeOutline.section.update(true);
+        else
+            this.updateTitle(); // FIXME: this will not show new properties. But we don't hit this case yet.
+    },
+
+    toggleEnabled: function(event)
+    {
+        var disabled = !event.target.checked;
+
+        function callback(newStyle)
+        {
+            if (!newStyle)
+                return;
+
+            this.style = newStyle;
+            this._styleRule.style = newStyle;
+
+            if (this.treeOutline.section && this.treeOutline.section.pane)
+                this.treeOutline.section.pane.dispatchEventToListeners("style property toggled");
+
+            this.updateAll(true);
+        }
+
+        this.property.setDisabled(disabled, callback.bind(this));
+    },
+
+    updateState: function()
+    {
+        if (!this.listItemElement)
+            return;
+
+        if (this.style.isPropertyImplicit(this.name) || this.value === "initial")
+            this.listItemElement.addStyleClass("implicit");
+        else
+            this.listItemElement.removeStyleClass("implicit");
+
+        this.selectable = !this.inherited;
+        if (this.inherited)
+            this.listItemElement.addStyleClass("inherited");
+        else
+            this.listItemElement.removeStyleClass("inherited");
+
+        if (this.overloaded)
+            this.listItemElement.addStyleClass("overloaded");
+        else
+            this.listItemElement.removeStyleClass("overloaded");
+
+        if (this.disabled)
+            this.listItemElement.addStyleClass("disabled");
+        else
+            this.listItemElement.removeStyleClass("disabled");
+    },
+
+    onpopulate: function()
+    {
+        // Only populate once and if this property is a shorthand.
+        if (this.children.length || !this.shorthand)
+            return;
+
+        var longhandProperties = this.style.getLonghandProperties(this.name);
+        for (var i = 0; i < longhandProperties.length; ++i) {
+            var name = longhandProperties[i].name;
+
+
+            if (this.treeOutline.section) {
+                var inherited = this.treeOutline.section.isPropertyInherited(name);
+                var overloaded = this.treeOutline.section.isPropertyOverloaded(name);
+            }
+
+            var liveProperty = this.style.getLiveProperty(name);
+            var item = new WebInspector.StylePropertyTreeElement(this._styleRule, this.style, liveProperty, false, inherited, overloaded);
+            this.appendChild(item);
+        }
+    },
+
+    ondblclick: function(event)
+    {
+        this.startEditing(event.target);
+        event.stopPropagation();
+    },
+
+    restoreNameElement: function()
+    {
+        // Restore <span class="webkit-css-property"> if it doesn't yet exist or was accidentally deleted.
+        if (this.nameElement === this.listItemElement.querySelector(".webkit-css-property"))
+            return;
+
+        this.nameElement = document.createElement("span");
+        this.nameElement.className = "webkit-css-property";
+        this.nameElement.textContent = "";
+        this.listItemElement.insertBefore(this.nameElement, this.listItemElement.firstChild);
+    },
+
+    startEditing: function(selectElement)
+    {
+        // FIXME: we don't allow editing of longhand properties under a shorthand right now.
+        if (this.parent.shorthand)
+            return;
+
+        if (this.treeOutline.section && !this.treeOutline.section.editable)
+            return;
+
+        if (!selectElement)
+            selectElement = this.nameElement; // No arguments passed in - edit the name element by default.
+        else
+            selectElement = selectElement.enclosingNodeOrSelfWithClass("webkit-css-property") || selectElement.enclosingNodeOrSelfWithClass("value");
+
+        var isEditingName = selectElement === this.nameElement;
+        if (!isEditingName && selectElement !== this.valueElement) {
+            // Double-click in the LI - start editing value.
+            isEditingName = false;
+            selectElement = this.valueElement;
+        }
+
+        if (WebInspector.isBeingEdited(selectElement))
+            return;
+
+        var context = {
+            expanded: this.expanded,
+            hasChildren: this.hasChildren,
+            keyDownListener: isEditingName ? null : this.editingValueKeyDown.bind(this),
+            isEditingName: isEditingName
+        };
+
+        // Lie about our children to prevent expanding on double click and to collapse shorthands.
+        this.hasChildren = false;
+
+        if (!isEditingName)
+            selectElement.addEventListener("keydown", context.keyDownListener, false);
+        if (selectElement.parentElement)
+            selectElement.parentElement.addStyleClass("child-editing");
+        selectElement.textContent = selectElement.textContent; // remove color swatch and the like
+
+        function shouldCommitValueSemicolon(text, cursorPosition)
+        {
+            // FIXME: should this account for semicolons inside comments?
+            var openQuote = "";
+            for (var i = 0; i < cursorPosition; ++i) {
+                var ch = text[i];
+                if (ch === "\\" && openQuote !== "")
+                    ++i; // skip next character inside string
+                else if (!openQuote && (ch === "\"" || ch === "'"))
+                    openQuote = ch;
+                else if (openQuote === ch)
+                    openQuote = "";
+            }
+            return !openQuote;
+        }
+
+        function nameValueFinishHandler(context, isEditingName, event)
+        {
+            // FIXME: the ":"/";" detection does not work for non-US layouts due to the event being keydown rather than keypress.
+            var isFieldInputTerminated = (event.keyCode === WebInspector.KeyboardShortcut.Keys.Semicolon.code) &&
+                (isEditingName ? event.shiftKey : (!event.shiftKey && shouldCommitValueSemicolon(event.target.textContent, event.target.selectionLeftOffset)));
+            if (isEnterKey(event) || isFieldInputTerminated) {
+                // Enter or colon (for name)/semicolon outside of string (for value).
+                event.preventDefault();
+                return "move-forward";
+            } else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code)
+                return "cancel";
+            else if (!isEditingName && this._newProperty && event.keyCode === WebInspector.KeyboardShortcut.Keys.Backspace.code) {
+                // For a new property, when Backspace is pressed at the beginning of new property value, move back to the property name.
+                var selection = window.getSelection();
+                if (selection.isCollapsed && !selection.focusOffset) {
+                    event.preventDefault();
+                    return "move-backward";
+                }
+            } else if (event.keyIdentifier === "U+0009") // Tab key.
+                return "move-" + (event.shiftKey ? "backward" : "forward");
+        }
+
+        function pasteHandler(context, event)
+        {
+            var data = event.clipboardData.getData("Text");
+            if (!data)
+                return;
+            var colonIdx = data.indexOf(":");
+            if (colonIdx < 0)
+                return;
+            var name = data.substring(0, colonIdx).trim();
+            var value = data.substring(colonIdx + 1).trim();
+
+            event.preventDefault();
+
+            if (!("originalName" in context)) {
+                context.originalName = this.nameElement.textContent;
+                context.originalValue = this.valueElement.textContent;
+            }
+            this.nameElement.textContent = name;
+            this.valueElement.textContent = value;
+            this.nameElement.normalize();
+            this.valueElement.normalize();
+
+            return "move-forward";
+        }
+
+        WebInspector.startEditing(selectElement, {
+            context: context,
+            commitHandler: this.editingCommitted.bind(this),
+            cancelHandler: this.editingCancelled.bind(this),
+            customFinishHandler: nameValueFinishHandler.bind(this, context, isEditingName),
+            pasteHandler: isEditingName ? pasteHandler.bind(this, context) : null
+        });
+
+        this._prompt = new WebInspector.StylesSidebarPane.CSSPropertyPrompt(selectElement, isEditingName ? WebInspector.cssNameCompletions : WebInspector.CSSKeywordCompletions.forProperty(this.nameElement.textContent));
+        window.getSelection().setBaseAndExtent(selectElement, 0, selectElement, 1);
+    },
+
+    editingValueKeyDown: function(event)
+    {
+        if (event.handled)
+            return;
+        var key = event.keyIdentifier || event.key;
+        var arrowKeyPressed = (key === "Up" || key === "Down");
+        var pageKeyPressed = (key === "PageUp" || key === "PageDown");
+        if (!arrowKeyPressed && !pageKeyPressed)
+            return;
+
+        var selection = window.getSelection();
+        if (!selection.rangeCount)
+            return;
+
+        var selectionRange = selection.getRangeAt(0);
+        if (selectionRange.commonAncestorContainer !== this.valueElement && !selectionRange.commonAncestorContainer.isDescendant(this.valueElement))
+            return;
+
+        var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, WebInspector.StylesSidebarPane.StyleValueDelimiters, this.valueElement);
+        var wordString = wordRange.toString();
+        var replacementString = wordString;
+
+        var matches = /(.*?)(-?\d+(?:\.\d+)?)(.*)/.exec(wordString);
+        if (matches && matches.length) {
+            var prefix = matches[1];
+            var number = parseFloat(matches[2]);
+            var suffix = matches[3];
+
+            // If the number is near zero or the number is one and the direction will take it near zero.
+            var numberNearZero = (number < 1 && number > -1);
+            if (number === 1 && key === "Down")
+                numberNearZero = true;
+            else if (number === -1 && key === "Up")
+                numberNearZero = true;
+
+            if (numberNearZero && event.altKey && arrowKeyPressed) {
+                if (key === "Down")
+                    number = Math.ceil(number - 1);
+                else
+                    number = Math.floor(number + 1);
+            } else {
+                // Jump by 10 when shift is down or jump by 0.1 when near zero or Alt/Option is down.
+                // Also jump by 10 for page up and down, or by 100 if shift is held with a page key.
+                var changeAmount = 1;
+                if (event.shiftKey && pageKeyPressed)
+                    changeAmount = 100;
+                else if (event.shiftKey || pageKeyPressed)
+                    changeAmount = 10;
+                else if (event.altKey || numberNearZero)
+                    changeAmount = 0.1;
+
+                if (key === "Down" || key === "PageDown")
+                    changeAmount *= -1;
+
+                // Make the new number and constrain it to a precision of 6, this matches numbers the engine returns.
+                // Use the Number constructor to forget the fixed precision, so 1.100000 will print as 1.1.
+                number = Number((number + changeAmount).toFixed(6));
+            }
+
+            replacementString = prefix + number + suffix;
+
+            var replacementTextNode = document.createTextNode(replacementString);
+
+            wordRange.deleteContents();
+            wordRange.insertNode(replacementTextNode);
+
+            var finalSelectionRange = document.createRange();
+            finalSelectionRange.setStart(replacementTextNode, 0);
+            finalSelectionRange.setEnd(replacementTextNode, replacementString.length);
+
+            selection.removeAllRanges();
+            selection.addRange(finalSelectionRange);
+
+            event.handled = true;
+            event.preventDefault();
+
+            if (!("originalPropertyText" in this)) {
+                // Remember the rule's original CSS text on [Page](Up|Down), so it can be restored
+                // if the editing is canceled.
+                this.originalPropertyText = this.property.propertyText;
+            }
+
+            // Synthesize property text disregarding any comments, custom whitespace etc.
+            this.applyStyleText(this.nameElement.textContent + ": " + this.valueElement.textContent);
+        }
+    },
+
+    editingEnded: function(context)
+    {
+        this.hasChildren = context.hasChildren;
+        if (context.expanded)
+            this.expand();
+        var editedElement = context.isEditingName ? this.nameElement : this.valueElement;
+        if (!context.isEditingName)
+            editedElement.removeEventListener("keydown", context.keyDownListener, false);
+        if (editedElement.parentElement)
+            editedElement.parentElement.removeStyleClass("child-editing");
+
+        delete this.originalPropertyText;
+    },
+
+    editingCancelled: function(element, context)
+    {
+        this._removePrompt();
+        if ("originalPropertyText" in this)
+            this.applyStyleText(this.originalPropertyText, true);
+        else {
+            if (this._newProperty)
+                this.treeOutline.removeChild(this);
+            else
+                this.updateTitle();
+        }
+
+        // This should happen last, as it clears the info necessary to restore the property value after [Page]Up/Down changes.
+        this.editingEnded(context);
+    },
+
+    editingCommitted: function(element, userInput, previousContent, context, moveDirection)
+    {
+        this._removePrompt();
+        this.editingEnded(context);
+        var isEditingName = context.isEditingName;
+
+        // Determine where to move to before making changes
+        var createNewProperty, moveToPropertyName, moveToSelector;
+        var moveTo = this;
+        var moveToOther = (isEditingName ^ (moveDirection === "forward"));
+        var abandonNewProperty = this._newProperty && !userInput && (moveToOther || isEditingName);
+        if (moveDirection === "forward" && !isEditingName || moveDirection === "backward" && isEditingName) {
+            do {
+                moveTo = (moveDirection === "forward" ? moveTo.nextSibling : moveTo.previousSibling);
+            } while(moveTo && !moveTo.selectable);
+
+           if (moveTo)
+                moveToPropertyName = moveTo.name;
+            else if (moveDirection === "forward" && (!this._newProperty || userInput))
+                createNewProperty = true;
+            else if (moveDirection === "backward" && this.treeOutline.section.rule)
+                moveToSelector = true;
+        }
+
+        // Make the Changes and trigger the moveToNextCallback after updating.
+        var blankInput = /^\s*$/.test(userInput);
+        var isDataPasted = "originalName" in context;
+        var isDirtyViaPaste = isDataPasted && (this.nameElement.textContent !== context.originalName || this.valueElement.textContent !== context.originalValue);
+        var shouldCommitNewProperty = this._newProperty && (moveToOther || (!moveDirection && !isEditingName) || (isEditingName && blankInput));
+        if (((userInput !== previousContent || isDirtyViaPaste) && !this._newProperty) || shouldCommitNewProperty) {
+            this.treeOutline.section._afterUpdate = moveToNextCallback.bind(this, this._newProperty, !blankInput, this.treeOutline.section);
+            var propertyText;
+            if (blankInput || (this._newProperty && /^\s*$/.test(this.valueElement.textContent)))
+                propertyText = "";
+            else {
+                if (isEditingName)
+                    propertyText = userInput + ": " + this.valueElement.textContent;
+                else
+                    propertyText = this.nameElement.textContent + ": " + userInput;
+            }
+            this.applyStyleText(propertyText, true);
+        } else {
+            if (!isDataPasted && !this._newProperty)
+                this.updateTitle();
+            moveToNextCallback(this._newProperty, false, this.treeOutline.section);
+        }
+
+        var moveToIndex = moveTo && this.treeOutline ? this.treeOutline.children.indexOf(moveTo) : -1;
+
+        // The Callback to start editing the next/previous property/selector.
+        function moveToNextCallback(alreadyNew, valueChanged, section)
+        {
+            if (!moveDirection)
+                return;
+
+            // User just tabbed through without changes.
+            if (moveTo && moveTo.parent) {
+                moveTo.startEditing(!isEditingName ? moveTo.nameElement : moveTo.valueElement);
+                return;
+            }
+
+            // User has made a change then tabbed, wiping all the original treeElements.
+            // Recalculate the new treeElement for the same property we were going to edit next.
+            if (moveTo && !moveTo.parent) {
+                var propertyElements = section.propertiesTreeOutline.children;
+                if (moveDirection === "forward" && blankInput && !isEditingName)
+                    --moveToIndex;
+                if (moveToIndex >= propertyElements.length && !this._newProperty)
+                    createNewProperty = true;
+                else {
+                    var treeElement = moveToIndex >= 0 ? propertyElements[moveToIndex] : null;
+                    if (treeElement) {
+                        treeElement.startEditing(!isEditingName ? treeElement.nameElement : treeElement.valueElement);
+                        return;
+                    } else if (!alreadyNew)
+                        moveToSelector = true;
+                }
+            }
+
+            // Create a new attribute in this section (or move to next editable selector if possible).
+            if (createNewProperty) {
+                if (alreadyNew && !valueChanged && (isEditingName ^ (moveDirection === "backward")))
+                    return;
+
+                section.addNewBlankProperty().startEditing();
+                return;
+            }
+
+            if (abandonNewProperty) {
+                var sectionToEdit = moveDirection === "backward" ? section : section.nextEditableSibling();
+                if (sectionToEdit && sectionToEdit.rule)
+                    sectionToEdit.startEditingSelector();
+                return;
+            }
+
+            if (moveToSelector)
+                section.startEditingSelector();
+        }
+    },
+
+    _removePrompt: function()
+    {
+        // BUG 53242. This cannot go into editingEnded(), as it should always happen first for any editing outcome.
+        if (this._prompt) {
+            this._prompt.removeFromElement();
+            delete this._prompt;
+        }
+    },
+
+    _hasBeenAppliedToPageViaUpDown: function()
+    {
+        // New properties applied via up/down have an originalPropertyText and will be deleted later
+        // on, if cancelled, when the empty string gets applied as their style text.
+        return ("originalPropertyText" in this);
+    },
+
+    applyStyleText: function(styleText, updateInterface)
+    {
+        var section = this.treeOutline.section;
+        var elementsPanel = WebInspector.panels.elements;
+        styleText = styleText.replace(/\s/g, " ").trim(); // Replace &nbsp; with whitespace.
+        var styleTextLength = styleText.length;
+        if (!styleTextLength && updateInterface && this._newProperty && !this._hasBeenAppliedToPageViaUpDown()) {
+            // The user deleted everything and never applied a new property value via Up/Down scrolling, so remove the tree element and update.
+            this.parent.removeChild(this);
+            section.afterUpdate();
+            return;
+        }
+
+        function callback(newStyle)
+        {
+            if (!newStyle) {
+                // The user typed something, but it didn't parse. Just abort and restore
+                // the original title for this property.  If this was a new attribute and
+                // we couldn't parse, then just remove it.
+                if (this._newProperty) {
+                    this.parent.removeChild(this);
+                    return;
+                }
+                if (updateInterface)
+                    this.updateTitle();
+                return;
+            }
+
+            this.style = newStyle;
+            this.property = newStyle.propertyAt(this.property.index);
+            this._styleRule.style = this.style;
+
+            if (section && section.pane)
+                section.pane.dispatchEventToListeners("style edited");
+
+            if (updateInterface)
+                this.updateAll(true);
+        }
+
+        // Append a ";" if the new text does not end in ";".
+        // FIXME: this does not handle trailing comments.
+        if (styleText.length && !/;\s*$/.test(styleText))
+            styleText += ";";
+        this.property.setText(styleText, updateInterface, callback.bind(this));
+    }
+}
+
+WebInspector.StylePropertyTreeElement.prototype.__proto__ = TreeElement.prototype;
+
+WebInspector.StylesSidebarPane.CSSPropertyPrompt = function(element, cssCompletions)
+{
+    WebInspector.TextPrompt.call(this, element, this._buildPropertyCompletions.bind(this), WebInspector.StylesSidebarPane.StyleValueDelimiters, true);
+    this._cssCompletions = cssCompletions;
+}
+
+WebInspector.StylesSidebarPane.CSSPropertyPrompt.prototype = {
+    upKeyPressed: function(event)
+    {
+        this._handleNameOrValueUpDown(event);
+    },
+
+    downKeyPressed: function(event)
+    {
+        this._handleNameOrValueUpDown(event);
+    },
+
+    tabKeyPressed: function(event)
+    {
+        this.acceptAutoComplete();
+    },
+
+    _handleNameOrValueUpDown: function(event)
+    {
+        var reverse = (event.keyIdentifier || event.key) === "Up";
+        if (this.autoCompleteElement)
+            this.complete(false, reverse); // Accept the current suggestion, if any.
+        else {
+            // Select the word suffix to affect it when computing the subsequent suggestion.
+            this._selectCurrentWordSuffix();
+        }
+
+        this.complete(false, reverse); // Actually increment/decrement the suggestion.
+        event.handled = true;
+    },
+
+    _selectCurrentWordSuffix: function()
+    {
+        var selection = window.getSelection();
+        if (!selection.rangeCount)
+            return;
+
+        var selectionRange = selection.getRangeAt(0);
+        if (!selectionRange.commonAncestorContainer.isDescendant(this.element))
+            return;
+        var wordSuffixRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, WebInspector.StylesSidebarPane.StyleValueDelimiters, this.element, "forward");
+        if (!wordSuffixRange.toString())
+            return;
+        selection.removeAllRanges();
+        selection.addRange(wordSuffixRange);
+    },
+
+    _buildPropertyCompletions: function(wordRange, bestMatchOnly, completionsReadyCallback)
+    {
+        if (!this._cssCompletions) return;
+
+        var prefix = wordRange.toString().toLowerCase();
+        var results;
+        if (bestMatchOnly) {
+            results = [];
+            var firstMatch = this._cssCompletions.firstStartsWith(prefix);
+            if (firstMatch)
+                results.push(firstMatch);
+            return completionsReadyCallback(results);
+        }
+
+        results = this._cssCompletions.startsWith(prefix);
+        if (results)
+            completionsReadyCallback(results);
+    }
+}
+
+WebInspector.StylesSidebarPane.CSSPropertyPrompt.prototype.__proto__ = WebInspector.TextPrompt.prototype;
diff --git a/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/TextPrompt.js b/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/TextPrompt.js
new file mode 100644
index 0000000..052fe40
--- /dev/null
+++ b/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/TextPrompt.js
@@ -0,0 +1,481 @@
+/*
+ * Copyright (C) 2008 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.TextPrompt = function(element, completions, stopCharacters, omitHistory)
+{
+    this.element = element;
+    this.element.addStyleClass("text-prompt");
+    this.completions = completions;
+    this.completionStopCharacters = stopCharacters;
+    if (!omitHistory) {
+        this.history = [];
+        this.historyOffset = 0;
+    }
+    this._boundOnKeyDown = this._onKeyDown.bind(this);
+    this.element.addEventListener("keydown", this._boundOnKeyDown, true);
+}
+
+WebInspector.TextPrompt.prototype = {
+    get text()
+    {
+        return this.element.textContent;
+    },
+
+    set text(x)
+    {
+        if (!x) {
+            // Append a break element instead of setting textContent to make sure the selection is inside the prompt.
+            this.element.removeChildren();
+
+            // For IE  we don't need a <br> to correctly set console caret; otherwise there will be two lines (incorrect) instead of one
+            if (!navigator.userAgent.match(/MSIE/i)) {
+			
+                this.element.appendChild(document.createElement("br"));
+            }
+        } else
+            this.element.textContent = x;
+
+        this.moveCaretToEndOfPrompt();
+    },
+
+    removeFromElement: function()
+    {
+        this.clearAutoComplete(true);
+        this.element.removeEventListener("keydown", this._boundOnKeyDown, true);
+    },
+
+    _onKeyDown: function(event)
+    {
+        function defaultAction()
+        {
+            this.clearAutoComplete();
+            this.autoCompleteSoon();
+        }
+
+        if (event.handled)
+            return;
+
+        var handled = false,
+            key = event.keyIdentifier || event.key;
+
+        switch (key) {
+            case "Up":
+                this.upKeyPressed(event);
+                break;
+            case "Down":
+                this.downKeyPressed(event);
+                break;
+            case "U+0009": // Tab
+                this.tabKeyPressed(event);
+                break;
+            case "Right":
+            case "End":
+                if (!this.acceptAutoComplete())
+                    this.autoCompleteSoon();
+                break;
+            case "Alt":
+            case "Meta":
+            case "Shift":
+            case "Control":
+                break;
+            case "U+0050": // Ctrl+P = Previous
+                if (this.history && WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
+                    handled = true;
+                    this._moveBackInHistory();
+                    break;
+                }
+                defaultAction.call(this);
+                break;
+            case "U+004E": // Ctrl+N = Next
+                if (this.history && WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
+                    handled = true;
+                    this._moveForwardInHistory();
+                    break;
+                }
+                defaultAction.call(this);
+                break;
+            default:
+                defaultAction.call(this);
+                break;
+        }
+
+        if (event.keyCode == 13 || event.charCode == 13) {
+            handled = true;
+            event.target.blur();
+        }
+
+        handled |= event.handled;
+        if (handled) {
+            event.handled = true;
+            event.preventDefault();
+            event.stopPropagation();
+        }
+    },
+
+    acceptAutoComplete: function()
+    {
+        if (!this.autoCompleteElement || !this.autoCompleteElement.parentNode)
+            return false;
+
+        var text = this.autoCompleteElement.textContent;
+        var textNode = document.createTextNode(text);
+        this.autoCompleteElement.parentNode.replaceChild(textNode, this.autoCompleteElement);
+        delete this.autoCompleteElement;
+
+        var finalSelectionRange = document.createRange();
+        finalSelectionRange.setStart(textNode, text.length);
+        finalSelectionRange.setEnd(textNode, text.length);
+
+        var selection = window.getSelection();
+        selection.removeAllRanges();
+        selection.addRange(finalSelectionRange);
+
+        return true;
+    },
+
+    clearAutoComplete: function(includeTimeout)
+    {
+        if (includeTimeout && "_completeTimeout" in this) {
+            clearTimeout(this._completeTimeout);
+            delete this._completeTimeout;
+        }
+
+        if (!this.autoCompleteElement)
+            return;
+
+        if (this.autoCompleteElement.parentNode)
+            this.autoCompleteElement.parentNode.removeChild(this.autoCompleteElement);
+        delete this.autoCompleteElement;
+
+        if (!this._userEnteredRange || !this._userEnteredText)
+            return;
+
+        this._userEnteredRange.deleteContents();
+        this.element.pruneEmptyTextNodes();
+
+        var userTextNode = document.createTextNode(this._userEnteredText);
+        this._userEnteredRange.insertNode(userTextNode);
+
+        var selectionRange = document.createRange();
+        selectionRange.setStart(userTextNode, this._userEnteredText.length);
+        selectionRange.setEnd(userTextNode, this._userEnteredText.length);
+
+        var selection = window.getSelection();
+        selection.removeAllRanges();
+        selection.addRange(selectionRange);
+
+        delete this._userEnteredRange;
+        delete this._userEnteredText;
+    },
+
+    autoCompleteSoon: function()
+    {
+        if (!("_completeTimeout" in this))
+            this._completeTimeout = setTimeout(this.complete.bind(this, true), 250);
+    },
+
+    complete: function(auto, reverse)
+    {
+        this.clearAutoComplete(true);
+        var selection = window.getSelection();
+        if (!selection.rangeCount)
+            return;
+
+        var selectionRange = selection.getRangeAt(0);
+        var isEmptyInput = selectionRange.commonAncestorContainer === this.element; // this.element has no child Text nodes.
+
+        // Do not attempt to auto-complete an empty input in the auto mode (only on demand).
+        if (auto && isEmptyInput)
+            return;
+        if (!auto && !isEmptyInput && !selectionRange.commonAncestorContainer.isDescendant(this.element))
+            return;
+        if (auto && !this.isCaretAtEndOfPrompt())
+            return;
+        var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, this.completionStopCharacters, this.element, "backward");
+        this.completions(wordPrefixRange, auto, this._completionsReady.bind(this, selection, auto, wordPrefixRange, reverse));
+    },
+
+    _completionsReady: function(selection, auto, originalWordPrefixRange, reverse, completions)
+    {
+        if (!completions || !completions.length)
+            return;
+
+        var selectionRange = selection.getRangeAt(0);
+
+        var fullWordRange = document.createRange();
+        fullWordRange.setStart(originalWordPrefixRange.startContainer, originalWordPrefixRange.startOffset);
+        fullWordRange.setEnd(selectionRange.endContainer, selectionRange.endOffset);
+
+        if (originalWordPrefixRange.toString() + selectionRange.toString() != fullWordRange.toString())
+            return;
+
+        var wordPrefixLength = originalWordPrefixRange.toString().length;
+
+        if (auto)
+            var completionText = completions[0];
+        else {
+            if (completions.length === 1) {
+                var completionText = completions[0];
+                wordPrefixLength = completionText.length;
+            } else {
+                var commonPrefix = completions[0];
+                for (var i = 0; i < completions.length; ++i) {
+                    var completion = completions[i];
+                    var lastIndex = Math.min(commonPrefix.length, completion.length);
+                    for (var j = wordPrefixLength; j < lastIndex; ++j) {
+                        if (commonPrefix[j] !== completion[j]) {
+                            commonPrefix = commonPrefix.substr(0, j);
+                            break;
+                        }
+                    }
+                }
+                wordPrefixLength = commonPrefix.length;
+
+                if (selection.isCollapsed)
+                    var completionText = completions[0];
+                else {
+                    var currentText = fullWordRange.toString();
+
+                    var foundIndex = null;
+                    for (var i = 0; i < completions.length; ++i) {
+                        if (completions[i] === currentText)
+                            foundIndex = i;
+                    }
+
+                    var nextIndex = foundIndex + (reverse ? -1 : 1);
+                    if (foundIndex === null || nextIndex >= completions.length)
+                        var completionText = completions[0];
+                    else if (nextIndex < 0)
+                        var completionText = completions[completions.length - 1];
+                    else
+                        var completionText = completions[nextIndex];
+                }
+            }
+        }
+
+        this._userEnteredRange = fullWordRange;
+        this._userEnteredText = fullWordRange.toString();
+
+        fullWordRange.deleteContents();
+        this.element.pruneEmptyTextNodes();
+
+        var finalSelectionRange = document.createRange();
+
+        if (auto) {
+            var prefixText = completionText.substring(0, wordPrefixLength);
+            var suffixText = completionText.substring(wordPrefixLength);
+
+            var prefixTextNode = document.createTextNode(prefixText);
+            fullWordRange.insertNode(prefixTextNode);
+
+            this.autoCompleteElement = document.createElement("span");
+            this.autoCompleteElement.className = "auto-complete-text";
+            this.autoCompleteElement.textContent = suffixText;
+
+            prefixTextNode.parentNode.insertBefore(this.autoCompleteElement, prefixTextNode.nextSibling);
+
+            finalSelectionRange.setStart(prefixTextNode, wordPrefixLength);
+            finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength);
+        } else {
+            var completionTextNode = document.createTextNode(completionText);
+            fullWordRange.insertNode(completionTextNode);
+
+            if (completions.length > 1)
+                finalSelectionRange.setStart(completionTextNode, wordPrefixLength);
+            else
+                finalSelectionRange.setStart(completionTextNode, completionText.length);
+
+            finalSelectionRange.setEnd(completionTextNode, completionText.length);
+        }
+
+        selection.removeAllRanges();
+        selection.addRange(finalSelectionRange);
+    },
+
+    isCaretInsidePrompt: function()
+    {
+        return this.element.isInsertionCaretInside();
+    },
+
+    isCaretAtEndOfPrompt: function()
+    {
+        var selection = window.getSelection();
+        if (!selection.rangeCount || !selection.isCollapsed)
+            return false;
+
+        var selectionRange = selection.getRangeAt(0);
+        var node = selectionRange.startContainer;
+        if (node !== this.element && !node.isDescendant(this.element))
+            return false;
+
+        if (node.nodeType === Node.TEXT_NODE && selectionRange.startOffset < node.nodeValue.length)
+            return false;
+
+        var foundNextText = false;
+        while (node) {
+            if (node.nodeType === Node.TEXT_NODE && node.nodeValue.length) {
+                if (foundNextText)
+                    return false;
+                foundNextText = true;
+            }
+
+            node = node.traverseNextNode(this.element);
+        }
+
+        return true;
+    },
+
+    isCaretOnFirstLine: function()
+    {
+        var selection = window.getSelection();
+        var focusNode = selection.focusNode;
+        if (!focusNode || focusNode.nodeType !== Node.TEXT_NODE || focusNode.parentNode !== this.element)
+            return true;
+
+        if (focusNode.textContent.substring(0, selection.focusOffset).indexOf("\n") !== -1)
+            return false;
+        focusNode = focusNode.previousSibling;
+
+        while (focusNode) {
+            if (focusNode.nodeType !== Node.TEXT_NODE)
+                return true;
+            if (focusNode.textContent.indexOf("\n") !== -1)
+                return false;
+            focusNode = focusNode.previousSibling;
+        }
+
+        return true;
+    },
+
+    isCaretOnLastLine: function()
+    {
+        var selection = window.getSelection();
+        var focusNode = selection.focusNode;
+        if (!focusNode || focusNode.nodeType !== Node.TEXT_NODE || focusNode.parentNode !== this.element)
+            return true;
+
+        if (focusNode.textContent.substring(selection.focusOffset).indexOf("\n") !== -1)
+            return false;
+        focusNode = focusNode.nextSibling;
+
+        while (focusNode) {
+            if (focusNode.nodeType !== Node.TEXT_NODE)
+                return true;
+            if (focusNode.textContent.indexOf("\n") !== -1)
+                return false;
+            focusNode = focusNode.nextSibling;
+        }
+
+        return true;
+    },
+
+    moveCaretToEndOfPrompt: function()
+    {
+        var selection = window.getSelection();
+        var selectionRange = document.createRange();
+
+        var offset = this.element.childNodes.length;
+        selectionRange.setStart(this.element, offset);
+        selectionRange.setEnd(this.element, offset);
+
+        selection.removeAllRanges();
+        selection.addRange(selectionRange);
+    },
+
+    tabKeyPressed: function(event)
+    {
+        event.handled = true;
+        this.complete(false, event.shiftKey);
+    },
+
+    upKeyPressed: function(event)
+    {
+        if (!this.isCaretOnFirstLine())
+            return;
+
+        event.handled = true;
+        this._moveBackInHistory();
+    },
+
+    downKeyPressed: function(event)
+    {
+        if (!this.isCaretOnLastLine())
+            return;
+
+        event.handled = true;
+        this._moveForwardInHistory();
+    },
+
+    _moveBackInHistory: function()
+    {
+        if (!this.history || this.historyOffset == this.history.length)
+            return;
+
+        this.clearAutoComplete(true);
+
+        if (this.historyOffset === 0)
+            this.tempSavedCommand = this.text;
+
+        ++this.historyOffset;
+        this.text = this.history[this.history.length - this.historyOffset];
+
+        this.element.scrollIntoView(true);
+        var firstNewlineIndex = this.text.indexOf("\n");
+        if (firstNewlineIndex === -1)
+            this.moveCaretToEndOfPrompt();
+        else {
+            var selection = window.getSelection();
+            var selectionRange = document.createRange();
+
+            selectionRange.setStart(this.element.firstChild, firstNewlineIndex);
+            selectionRange.setEnd(this.element.firstChild, firstNewlineIndex);
+
+            selection.removeAllRanges();
+            selection.addRange(selectionRange);
+        }
+    },
+
+    _moveForwardInHistory: function()
+    {
+        if (!this.history || this.historyOffset === 0)
+            return;
+
+        this.clearAutoComplete(true);
+
+        --this.historyOffset;
+
+        if (this.historyOffset === 0) {
+            this.text = this.tempSavedCommand;
+            delete this.tempSavedCommand;
+            return;
+        }
+
+        this.text = this.history[this.history.length - this.historyOffset];
+        this.element.scrollIntoView();
+    }
+}
diff --git a/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/inspector.css b/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/inspector.css
new file mode 100644
index 0000000..1ad1a2f
--- /dev/null
+++ b/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/inspector.css
@@ -0,0 +1,4579 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
+ * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+html {
+    height: 100%;
+}
+
+body {
+    cursor: default;
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    overflow: hidden;
+    font-family: Lucida Grande, sans-serif;
+    font-size: 10px;
+    margin: 0;
+    -webkit-text-size-adjust: none;
+    -ms-text-size-adjust: none;
+    -moz-text-size-adjust: none;
+    -webkit-user-select: none;
+    -ms-user-select: none;
+    -moz-user-select: none;
+}
+
+* {
+    -webkit-box-sizing: border-box;
+    box-sizing: border-box;
+    -moz-box-sizing: border-box;
+}
+
+:focus {
+    outline: none;
+}
+
+input[type="search"]:focus, input[type="text"]:focus {
+    outline: auto 5px -webkit-focus-ring-color;
+}
+
+iframe, a img {
+    border: none;
+}
+
+img {
+    -webkit-user-drag: none;
+}
+
+.hidden {
+    display: none !important;
+}
+
+#toolbar {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    height: 56px;
+    display: -webkit-box;
+    display: -ms-flexbox;
+    display: -moz-box;
+    padding: 0 5px;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(191, 191, 191)), to(rgb(151, 151, 151)));
+    background-image: linear-gradient(to bottom, rgb(191, 191, 191) 0%, rgb(151, 151, 151) 100%);
+    border-bottom: 1px solid rgb(80, 80, 80);
+    -webkit-box-orient: horizontal;
+    -webkit-background-origin: padding;
+    -webkit-background-clip: padding;
+    -ms-flex-direction: row;
+    -moz-box-orient: horizontal;
+    background-origin: padding;
+    background-clip: padding;
+}
+
+body.inactive #toolbar {
+    background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(233, 233, 233)), to(rgb(207, 207, 207)));
+    background-image: linear-gradient(to bottom, rgb(233, 233, 233) 0%, rgb(207, 207, 207) 100%);
+    border-bottom: 1px solid rgb(64%, 64%, 64%);
+}
+
+body.detached.platform-mac-leopard #toolbar,
+body.detached.platform-mac-snowleopard #toolbar {
+    background: transparent !important;
+}
+
+body.attached #toolbar {
+    height: 34px;
+    border-top: 1px solid rgb(100, 100, 100);
+    cursor: row-resize;
+    padding-left: 0;
+}
+
+body.attached.port-qt #toolbar {
+    cursor: auto;
+}
+
+body.attached.inactive #toolbar {
+    border-top: 1px solid rgb(64%, 64%, 64%);
+}
+
+.toolbar-item {
+    display: -webkit-box;
+    display: -ms-flexbox;
+    display: -moz-box;
+    padding: 4px 6px;
+    margin: 0;
+    background-color: transparent;
+    border-style: none;
+    border-color: transparent;
+    -webkit-box-orient: vertical;
+    -webkit-box-align: center;
+    -webkit-box-pack: end;
+    -ms-flex-direction: column;
+    -ms-flex-align: center;
+    -ms-flex-pack: end;
+    -moz-box-orient: vertical;
+    -moz-box-align: center;
+    -moz-box-pack: end;
+}
+
+.toolbar-item.toggleable.toggled-on {
+    border-width: 0 2px 0 2px;
+    padding: 4px 4px;
+    -webkit-border-image: url(Images/toolbarItemSelected.png) 0 2 0 2;
+    border-image: url(Images/toolbarItemSelected.png) 0 2 0 2;
+    border-style: solid;
+}
+
+.toolbar-item.flexable-space {
+    -webkit-box-flex: 1;
+    -ms-flex: 1;
+    -moz-box-flex: 1;
+    visibility: hidden;
+}
+
+.toolbar-item input {
+    margin-bottom: 8px;
+}
+
+.toolbar-icon {
+    display: inline-block;
+    width: 32px;
+    height: 32px;
+    -webkit-background-size: 100% auto;
+    background-size: 100% auto;
+}
+
+body.attached .toolbar-icon {
+    width: 24px;
+    height: 24px;
+    vertical-align: middle;
+}
+
+.toolbar-item:active .toolbar-icon {
+    background-position: 0 32px;
+}
+
+body.attached .toolbar-item:active .toolbar-icon {
+    background-position: 0 24px;
+}
+
+.toolbar-label {
+    font-size: 11px;
+    font-family: Lucida Grande, sans-serif;
+    text-shadow: rgba(255, 255, 255, 0.5) 0 1px 0;
+}
+
+.toolbar-item.toggleable:active .toolbar-label {
+    text-shadow: none;
+}
+
+body.attached .toolbar-label {
+    display: inline-block;
+    vertical-align: middle;
+    margin-left: 3px;
+}
+
+body.attached #search-toolbar-label {
+    display: none;
+}
+
+#search {
+    width: 205px;
+    font-size: 16px;
+    margin-bottom: 5px;
+}
+
+body.attached #search {
+    font-size: 11px;
+    margin-bottom: 8px;
+}
+
+#search-results-matches {
+    font-size: 11px;
+    text-shadow: rgba(255, 255, 255, 0.5) 0 1px 0;
+    margin-bottom: 22px;
+}
+
+body.attached #search-results-matches {
+    margin-bottom: 6px;
+}
+
+.toolbar-item.elements .toolbar-icon {
+    background-image: url(Images/elementsIcon.png);
+}
+
+.toolbar-item.resources .toolbar-icon {
+    background-image: url(Images/resourcesIcon.png);
+}
+
+.toolbar-item.network .toolbar-icon {
+    background-image: url(Images/networkIcon.png);
+}
+
+.toolbar-item.scripts .toolbar-icon {
+    background-image: url(Images/scriptsIcon.png);
+}
+
+.toolbar-item.timeline .toolbar-icon {
+    background-image: url(Images/timelineIcon.png);
+}
+
+.toolbar-item.profiles .toolbar-icon {
+    background-image: url(Images/profilesIcon.png);
+}
+
+.toolbar-item.audits .toolbar-icon {
+    background-image: url(Images/auditsIcon.png);
+}
+
+.toolbar-item.console .toolbar-icon {
+    background-image: url(Images/consoleIcon.png);
+}
+
+#close-button-left, #close-button-right {
+    width: 14px;
+    height: 14px;
+    background-image: url(Images/closeButtons.png);
+    background-position: 0 0;
+    background-color: transparent;
+    border: 0 none transparent;
+    margin: 5px 0;
+}
+
+#close-button-left:hover, #close-button-right:hover {
+    background-position: 14px 0;
+}
+
+#close-button-left:active, #close-button-right:active {
+    background-position: 28px 0;
+}
+
+body.detached .toolbar-item.close-left, body.detached .toolbar-item.close-right {
+    display: none;
+}
+
+body.attached.port-qt .toolbar-item.close-left, body.attached.port-qt .toolbar-item.close-right {
+    display: none;
+}
+
+body.platform-mac .toolbar-item.close-right {
+    display: none;
+}
+
+body:not(.platform-mac) .toolbar-item.close-left {
+    display: none;
+}
+
+#main {
+    position: absolute;
+    z-index: 1;
+    top: 56px;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    overflow: hidden;
+    background-color: white;
+}
+
+body.attached #main {
+    top: 34px;
+}
+
+#main-panels {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 23px;
+    overflow: hidden;
+}
+
+#main-status-bar {
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    right: 0;
+}
+
+body.drawer-visible #main-status-bar {
+    height: 24px;
+    background-image: url(Images/statusbarResizerVertical.png), url(Images/statusbarBackground.png);
+    background-repeat: no-repeat, repeat-x;
+    background-position: right center, center;
+    cursor: row-resize;
+}
+
+body.drawer-visible #main-status-bar * {
+    cursor: default;
+}
+
+body.drawer-visible #main-panels {
+    bottom: 24px;
+}
+
+.status-bar {
+    background-color: rgb(235, 235, 235);
+    background-image: url(Images/statusbarBackground.png);
+    background-repeat: repeat-x;
+    white-space: nowrap;
+    height: 23px;
+    overflow: hidden;
+    z-index: 12;
+}
+
+.status-bar > div {
+    display: inline-block;
+    vertical-align: top;
+}
+
+.status-bar-item {
+    display: inline-block;
+    height: 24px;
+    padding: 0;
+    margin-left: -1px;
+    margin-right: 0;
+    vertical-align: top;
+    border: 0 transparent none;
+    background-color: transparent;
+}
+
+.status-bar-item:active {
+    position: relative;
+    z-index: 200;
+}
+
+.glyph {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background-color: rgba(0, 0, 0, 0.75);
+    z-index: 1;
+}
+
+.glyph.shadow {
+    top: 1px;
+    background-color: white !important;
+    z-index: 0;
+}
+
+button.status-bar-item {
+    position: relative;
+    width: 32px;
+    background-image: url(Images/statusbarButtons.png);
+    background-position: 0 0;
+}
+
+button.status-bar-item:active {
+    background-position: 32px 0 !important;
+}
+
+button.status-bar-item .glyph.shadow {
+    background-color: rgba(255, 255, 255, 0.33) !important;
+}
+
+button.status-bar-item.toggled-on .glyph {
+    background-color: rgb(66, 129, 235);
+}
+
+button.status-bar-item.toggled-1 .glyph {
+    background-color: rgb(66, 129, 235);
+}
+
+button.status-bar-item.toggled-2 .glyph {
+    background-color: purple;
+}
+
+button.status-bar-item:disabled {
+    opacity: 0.5;
+    background-position: 0 0 !important;
+}
+
+select.status-bar-item {
+    min-width: 48px;
+    border-width: 0 17px 0 2px;
+    padding: 0 2px 0 6px;
+    font-weight: bold;
+    color: rgb(48, 48, 48);
+    text-shadow: rgba(255, 255, 255, 0.75) 0 1px 0;
+    -webkit-border-image: url(Images/statusbarMenuButton.png) 0 17 0 2;
+    border-image: url(Images/statusbarMenuButton.png) 0 17 0 2;
+    -webkit-border-radius: 0;
+    border-radius: 0;
+    -webkit-appearance: none;
+    -moz-appearance: none;
+}
+
+select.status-bar-item:active {
+    color: black;
+    -webkit-border-image: url(Images/statusbarMenuButtonSelected.png) 0 17 0 2;
+    border-image: url(Images/statusbarMenuButtonSelected.png) 0 17 0 2;
+}
+
+#dock-status-bar-item .glyph {
+    -webkit-mask-image: url(Images/undockButtonGlyph.png);
+}
+
+body.detached #dock-status-bar-item .glyph {
+    -webkit-mask-image: url(Images/dockButtonGlyph.png);
+}
+
+body.port-qt #dock-status-bar-item {
+    display: none
+}
+
+#console-status-bar-item .glyph {
+    -webkit-mask-image: url(Images/consoleButtonGlyph.png);
+}
+
+.clear-status-bar-item .glyph {
+    -webkit-mask-image: url(Images/clearConsoleButtonGlyph.png);
+}
+
+#counters {
+    position: absolute;
+    right: 16px;
+    top: 0;
+    cursor: pointer;
+    padding: 6px 2px 6px 0px;
+    font-size: 10px;
+    height: 19px;
+}
+
+#error-warning-count {
+    display: inline;
+}
+
+#error-warning-count:hover {
+    border-bottom: 1px solid rgb(96, 96, 96);
+}
+
+#error-count::before {
+    content: url(Images/errorIcon.png);
+    width: 10px;
+    height: 10px;
+    vertical-align: -1px;
+    margin-right: 2px;
+}
+
+#error-count + #warning-count {
+    margin-left: 6px;
+}
+
+#warning-count::before {
+    content: url(Images/warningIcon.png);
+    width: 10px;
+    height: 10px;
+    vertical-align: -1px;
+    margin-right: 2px;
+}
+
+#drawer {
+    display: none;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    height: 200px;
+    background-color: white;
+    background-image: url(Images/statusbarBottomBackground.png);
+    background-repeat: repeat-x;
+    background-position: bottom;
+}
+
+body.drawer-visible #drawer {
+    display: block;
+}
+
+#drawer-status-bar {
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    background: none;
+}
+
+.monospace {
+    font-size: 10px !important;
+    font-family: monospace;
+}
+
+body.platform-mac .monospace, body.platform-mac .source-code {
+    font-family: Monaco, monospace;
+}
+
+/* Keep .platform-mac to make the rule more specific than the general one above. */
+body.platform-mac.platform-mac-snowleopard .monospace,
+body.platform-mac.platform-mac-snowleopard .source-code {
+    font-size: 11px !important;
+    font-family: Menlo, monospace;
+}
+
+body.platform-windows .monospace, body.platform-windows .source-code {
+    font-size: 12px !important;
+    font-family: Consolas, Lucida Console, monospace;
+}
+
+body.platform-linux .monospace, body.platform-linux .source-code {
+    font-size: 11px !important;
+    font-family: dejavu sans mono, monospace;
+}
+
+#console-messages {
+    position: absolute;
+    z-index: 0;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 23px;
+    padding: 2px 0;
+    overflow-y: auto;
+    overflow-y: overlay;
+    word-wrap: break-word;
+    -webkit-user-select: text;
+    -ms-user-select: text;
+    -moz-user-select: text;
+    -webkit-text-size-adjust: auto;
+    -ms-text-size-adjust: auto;
+    -moz-text-size-adjust: auto;
+}
+
+#console-prompt {
+    position: relative;
+    padding: 1px 22px 1px 24px;
+    min-height: 16px;
+    white-space: pre-wrap;
+    -webkit-user-modify: read-write-plaintext-only;
+    -moz-user-modify: read-write;
+}
+
+#console-prompt::before {
+    background-image: url(Images/userInputIcon.png);
+}
+
+.console-user-command-result.console-log-level::before {
+    background-image: url(Images/userInputResultIcon.png);
+}
+
+.console-message, .console-user-command {
+    position: relative;
+    border-bottom: 1px solid rgb(240, 240, 240);
+    padding: 1px 22px 1px 24px;
+    min-height: 16px;
+}
+
+.console-adjacent-user-command-result {
+    border-bottom: none;
+}
+
+.console-adjacent-user-command-result + .console-user-command-result.console-log-level::before {
+    background-image: none;
+}
+
+.console-message::before, .console-user-command::before, #console-prompt::before, .console-group-title::before {
+    position: absolute;
+    display: block;
+    content: "";
+    left: 7px;
+    top: 0.8em;
+    width: 10px;
+    height: 10px;
+    margin-top: -5px;
+    -webkit-user-select: none;
+    -ms-user-select: none;
+    -moz-user-select: none;
+}
+
+/* Hack to detect IE*/
+@media screen\0 {
+    /* Set image directly to console div element instead of using pseudo selector
+since it causes displaying caret in incorrecty place*/
+    #console-prompt {
+        background: url(Images/userInputIcon.png) 7px 5px no-repeat;
+    }
+
+    #console-prompt::before{
+        content: none !important;
+    }
+
+    /*Set icons as background-image since IE doesn't support -webkit-mask-image*/
+    #console-status-bar-item .glyph {
+        background-image: url(Images/consoleButtonGlyph.png);
+    }
+
+    .clear-status-bar-item .glyph {
+        background-image: url(Images/clearConsoleButtonGlyph.png);
+    }
+
+    .node-search-status-bar-item .glyph {
+        background-image: url(Images/nodeSearchButtonGlyph.png);
+    }
+
+    #console-status-bar-item .glyph,
+    .clear-status-bar-item .glyph,
+    .node-search-status-bar-item .glyph{
+        background-color: transparent;
+    }
+
+    /*Set background image for selected tab since IE doesn't support border-image property*/
+    .toolbar-item.toggleable.toggled-on {
+        background: url(Images/toolbarItemSelected.png);
+        background-size: 1px 100%;
+    }
+}
+
+/* Hack to detect Firefox*/
+@-moz-document url-prefix() {
+    /*Set icons as background-image since FF doesn't support mask-image*/
+    #console-status-bar-item .glyph {
+        background-image: url(Images/consoleButtonGlyph.png);
+    }
+
+    .clear-status-bar-item .glyph {
+        background-image: url(Images/clearConsoleButtonGlyph.png);
+    }
+
+    .node-search-status-bar-item .glyph {
+        background-image: url(Images/nodeSearchButtonGlyph.png);
+    }
+
+    #console-status-bar-item .glyph,
+    .clear-status-bar-item .glyph,
+    .node-search-status-bar-item .glyph{
+        background-color: transparent;
+    }
+}
+
+.console-message .bubble {
+    display: inline-block;
+    height: 14px;
+    background-color: rgb(128, 151, 189);
+    vertical-align: middle;
+    white-space: nowrap;
+    padding: 1px 4px;
+    margin-top: -2px;
+    margin-right: 4px;
+    text-align: left;
+    font-size: 11px;
+    line-height: normal;
+    font-family: Helvetica, Arial, sans-serif;
+    font-weight: bold;
+    text-shadow: none;
+    color: white;
+    -webkit-border-radius: 7px;
+    border-radius: 7px;
+}
+
+.console-message-text {
+    white-space: pre-wrap;
+}
+
+.repeated-message {
+    padding-left: 6px;
+}
+
+.repeated-message.console-error-level::before, .repeated-message.console-warning-level:before, .repeated-message.console-debug-level:before {
+    visibility: hidden;
+}
+
+.console-group .console-group > .console-group-messages {
+    margin-left: 16px;
+}
+
+.console-group-title {
+    font-weight: bold;
+}
+
+.console-group-title::before {
+    background-image: url(Images/disclosureTriangleSmallDown.png);
+    top: 0.6em;
+    width: 11px;
+    height: 12px;
+}
+
+.console-group.collapsed .console-group-title::before {
+    background-image: url(Images/disclosureTriangleSmallRight.png);
+}
+
+.console-group.collapsed > .console-group-messages {
+    display: none;
+}
+
+.console-error-level .console-message-text {
+    color: red;
+}
+
+.console-debug-level .console-message-text {
+    color: blue;
+}
+
+.console-debug-level::before {
+    background-image: url(Images/searchSmallBrightBlue.png);
+}
+
+.console-error-level::before {
+    background-image: url(Images/errorIcon.png);
+}
+
+.console-warning-level::before {
+    background-image: url(Images/warningIcon.png);
+}
+
+.console-user-command .console-message {
+    margin-left: -24px;
+    padding-right: 0;
+    border-bottom: none;
+}
+
+.console-user-command::before {
+    background-image: url(Images/userInputPreviousIcon.png);
+}
+
+.console-user-command > .console-message-text {
+    color: rgb(0, 128, 255);
+}
+
+#console-messages a {
+    color: rgb(33%, 33%, 33%);
+    cursor: pointer;
+}
+
+#console-messages a:hover {
+    color: rgb(15%, 15%, 15%);
+}
+
+.console-message-url {
+    float: right;
+    margin-left: 4px;
+}
+
+.console-group-messages .section {
+    margin: 0 0 0 12px !important;
+}
+
+.console-group-messages .section .header {
+    padding: 0 8px 0 0;
+    background-image: none;
+    border: none;
+    min-height: 0;
+}
+
+.console-group-messages .section .header::before {
+    position: absolute;
+    top: 1px;
+    left: 1px;
+    width: 8px;
+    height: 8px;
+    content: url(Images/treeRightTriangleBlack.png);
+}
+
+.console-group-messages .section.expanded .header::before {
+    content: url(Images/treeDownTriangleBlack.png);
+}
+
+.console-group-messages .section .header .title {
+    color: black;
+    font-weight: normal;
+}
+
+.console-group-messages .section .properties li .info {
+    padding-top: 0;
+    padding-bottom: 0;
+    color: rgb(60%, 60%, 60%);
+}
+
+.console-group-messages .outline-disclosure {
+    padding-left: 0;
+}
+
+.console-group-messages .outline-disclosure > ol {
+    padding: 0 0 0 12px !important;
+}
+
+.console-group-messages .outline-disclosure, .console-group-messages .outline-disclosure ol {
+    font-size: inherit;
+    line-height: 12px;
+}
+
+.console-group-messages .outline-disclosure.single-node li {
+    padding-left: 2px;
+}
+
+.console-group-messages .outline-disclosure li .selection {
+    margin-left: -6px;
+    margin-right: -6px;
+}
+
+.console-group-messages .add-attribute {
+    display: none;
+}
+
+.console-formatted-object, .console-formatted-node {
+    position: relative;
+    display: inline-block;
+    vertical-align: top;
+}
+
+.console-formatted-object .section, .console-formatted-node .section {
+    position: static;
+}
+
+.console-formatted-object .properties, .console-formatted-node .properties {
+    padding-left: 0 !important;
+}
+
+.console-formatted-number {
+    color: rgb(28, 0, 207);
+}
+
+.console-formatted-string, .console-formatted-regexp {
+    color: rgb(196, 26, 22);
+}
+
+.console-formatted-null, .console-formatted-undefined {
+    color: rgb(128, 128, 128);
+}
+
+.error-message {
+    color: red;
+}
+
+.auto-complete-text, .editing .auto-complete-text {
+    color: rgb(128, 128, 128) !important;
+    -webkit-user-select: none;
+    -ms-user-select: none;
+    -moz-user-select: none;
+    -webkit-user-modify: read-only;
+    -moz-user-modify: read-only;
+}
+
+.panel {
+    display: none;
+    overflow: hidden;
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+}
+
+.panel.visible {
+    display: block;
+}
+
+.webkit-line-gutter-backdrop {
+    /* Keep this in sync with view-source.css (.webkit-line-gutter-backdrop) */
+    width: 31px;
+    background-color: rgb(240, 240, 240);
+    border-right: 1px solid rgb(187, 187, 187);
+    position: absolute;
+    z-index: -1;
+    left: 0;
+    top: 0;
+    height: 100%
+}
+
+.resource-view {
+    display: none;
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 0;
+    bottom: 0;
+    overflow: auto;
+}
+
+.resource-view.visible {
+    display: block;
+}
+
+.resource-view.font {
+    font-size: 60px;
+    white-space: pre-wrap;
+    word-wrap: break-word;
+    text-align: center;
+    padding: 15px;
+}
+
+.resource-view.image > .image {
+    padding: 20px 20px 10px 20px;
+    text-align: center;
+}
+
+.resource-view.image > .info {
+    padding-bottom: 10px;
+    font-size: 11px;
+    -webkit-user-select: text;
+    -ms-user-select: text;
+    -moz-user-select: text;
+}
+
+.resource-view.image img.resource-image-view {
+    max-width: 100%;
+    max-height: 1000px;
+    background-image: url(Images/checker.png);
+    -webkit-box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.5);
+    box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.5);
+    -webkit-user-select: text;
+    -ms-user-select: text;
+    -moz-user-select: text;
+    -webkit-user-drag: auto;
+}
+
+.resource-url {
+    vertical-align: middle;
+}
+
+.resource-status-image {
+    margin-top: -3px;
+    vertical-align: middle;
+}
+
+.resource-view.image .title {
+    text-align: center;
+    font-size: 13px;
+}
+
+.resource-view.image .infoList {
+    margin: 0;
+}
+
+.resource-view.image .infoList dt {
+    font-weight: bold;
+    display: inline-block;
+    width: 50%;
+    text-align: right;
+    color: rgb(76, 76, 76);
+}
+
+.resource-view.image .infoList dd {
+    display: inline-block;
+    padding-left: 8px;
+    width: 50%;
+    text-align: left;
+    margin: 0;
+}
+
+.resource-view.image .infoList dd::after {
+    white-space: pre;
+    content: "\A";
+}
+
+.resource-timing-row {
+    position: relative;
+    height: 12px;
+}
+
+.resource-timing-bar {
+    position: absolute;
+    background-color: red;
+    border-left: 1px solid red;
+    opacity: 0.4;
+}
+
+.resource-timing-bar-title {
+    position: absolute;
+}
+
+#elements-content {
+    display: block;
+    overflow: auto;
+    padding: 0;
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 325px;
+    bottom: 0;
+}
+
+#elements-sidebar {
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    width: 325px;
+    border-left: 1px solid rgb(64%, 64%, 64%);
+    cursor: default;
+    overflow: auto;
+}
+
+.crumbs {
+    display: inline-block;
+    font-size: 11px;
+    line-height: 19px;
+    text-shadow: rgba(255, 255, 255, 0.75) 0 1px 0;
+    color: rgb(20, 20, 20);
+    margin-left: -1px;
+    padding-right: 12px;
+}
+
+.crumbs .crumb {
+    height: 24px;
+    border-width: 0 12px 0 2px;
+    -webkit-border-image: url(Images/segment.png) 0 12 0 2;
+    border-image: url(Images/segment.png) 0 12 0 2;
+    margin-right: -12px;
+    padding-left: 18px;
+    padding-right: 2px;
+    white-space: nowrap;
+    line-height: 23px;
+    float: right;
+}
+
+.crumbs .crumb.collapsed > * {
+    display: none;
+}
+
+.crumbs .crumb.collapsed::before {
+    content: "\2026";
+    font-weight: bold;
+}
+
+.crumbs .crumb.compact .extra {
+    display: none;
+}
+
+.crumbs .crumb.dimmed {
+    color: rgba(0, 0, 0, 0.45);
+}
+
+.crumbs .crumb.start {
+    padding-left: 7px;
+}
+
+.crumbs .crumb.end {
+    border-width: 0 2px 0 2px;
+    padding-right: 6px;
+    -webkit-border-image: url(Images/segmentEnd.png) 0 2 0 2;
+    border-image: url(Images/segmentEnd.png) 0 2 0 2;
+}
+
+.crumbs .crumb.selected {
+    -webkit-border-image: url(Images/segmentSelected.png) 0 12 0 2;
+    border-image: url(Images/segmentSelected.png) 0 12 0 2;
+    color: black;
+    text-shadow: rgba(255, 255, 255, 0.5) 0 1px 0;
+}
+
+.crumbs .crumb.selected:hover {
+    -webkit-border-image: url(Images/segmentSelected.png) 0 12 0 2;
+    border-image: url(Images/segmentSelected.png) 0 12 0 2;
+}
+
+.crumbs .crumb.selected.end, .crumbs .crumb.selected.end:hover {
+    -webkit-border-image: url(Images/segmentSelectedEnd.png) 0 2 0 2;
+    border-image: url(Images/segmentSelectedEnd.png) 0 2 0 2;
+}
+
+.crumbs .crumb:hover {
+    -webkit-border-image: url(Images/segmentHover.png) 0 12 0 2;
+    border-image: url(Images/segmentHover.png) 0 12 0 2;
+    color: black;
+}
+
+.crumbs .crumb.dimmed:hover {
+    -webkit-border-image: url(Images/segmentHover.png) 0 12 0 2;
+    border-image: url(Images/segmentHover.png) 0 12 0 2;
+    color: rgba(0, 0, 0, 0.75);
+}
+
+.crumbs .crumb.end:hover {
+    -webkit-border-image: url(Images/segmentHoverEnd.png) 0 2 0 2;
+    border-image: url(Images/segmentHoverEnd.png) 0 2 0 2;
+}
+
+.outline-disclosure li.hovered:not(.selected) .selection {
+    display: block;
+    left: 3px;
+    right: 3px;
+    background-color: rgba(56, 121, 217, 0.1);
+    -webkit-border-radius: 5px;
+    border-radius: 5px;
+}
+
+.outline-disclosure li.highlighted .highlight {
+    background-color: rgb(255, 230, 179);
+    -webkit-border-radius: 4px;
+    border-radius: 4px;
+    padding-bottom: 2px;
+    margin-bottom: -2px;
+}
+
+.outline-disclosure li.selected.highlighted .highlight {
+    background-color: transparent;
+    padding-bottom: 0;
+    margin-bottom: 0;
+}
+
+.outline-disclosure li .selection {
+    display: none;
+    position: absolute;
+    left: 0;
+    right: 0;
+    height: 15px;
+    z-index: -1;
+}
+
+.outline-disclosure li.selected .selection {
+    display: block;
+    background-color: rgb(212, 212, 212);
+}
+
+.outline-disclosure ol:focus li.selected .selection {
+    background-color: rgb(56, 121, 217);
+}
+
+.outline-disclosure {
+    font-size: 11px;
+}
+
+.outline-disclosure > ol {
+    position: relative;
+    padding: 2px 6px !important;
+    margin: 0;
+    color: black;
+    cursor: default;
+    min-width: 100%;
+}
+
+.outline-disclosure, .outline-disclosure ol {
+    list-style-type: none;
+    -webkit-padding-start: 12px;
+    -moz-padding-start: 12px;
+    margin: 0;
+}
+
+.source-code {
+    font-family: monospace;
+    font-size: 10px !important;
+    white-space: pre-wrap;
+}
+
+.outline-disclosure li {
+    padding: 0 0 0 14px;
+    margin-top: 1px;
+    margin-bottom: 1px;
+    word-wrap: break-word;
+    text-indent: -2px;
+}
+
+.resources .outline-disclosure li {
+    text-indent: -1px;
+}
+
+.outline-disclosure ol:focus li.selected {
+    color: white;
+}
+
+.outline-disclosure ol:focus li.selected * {
+    color: inherit;
+}
+
+.outline-disclosure li.parent {
+    text-indent: -12px
+}
+
+.outline-disclosure li .webkit-html-tag.close {
+    margin-left: -12px;
+}
+
+.outline-disclosure li.parent::before {
+    content: url(Images/treeRightTriangleBlack.png);
+    float: left;
+    width: 8px;
+    height: 8px;
+    margin-top: 1px;
+    padding-right: 2px;
+}
+
+.outline-disclosure li.parent::before {
+    content: url(Images/treeRightTriangleBlack.png);
+}
+
+.outline-disclosure ol:focus li.parent.selected::before {
+    content: url(Images/treeRightTriangleWhite.png);
+}
+
+.outline-disclosure li.parent.expanded::before {
+    content: url(Images/treeDownTriangleBlack.png);
+}
+
+.outline-disclosure ol:focus li.parent.expanded.selected::before {
+    content: url(Images/treeDownTriangleWhite.png);
+}
+
+.outline-disclosure ol.children {
+    display: none;
+}
+
+.outline-disclosure ol.children.expanded {
+    display: block;
+}
+
+.add-attribute {
+    margin-left: 1px;
+    margin-right: 1px;
+    white-space: nowrap;
+}
+
+.placard {
+    position: relative;
+    margin-top: 1px;
+    padding: 3px 8px 4px 18px;
+    min-height: 18px;
+    white-space: nowrap;
+}
+
+.placard:nth-of-type(2n) {
+    background-color: rgb(234, 243, 255);
+}
+
+.placard.selected {
+    border-top: 1px solid rgb(145, 160, 192);
+    background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(162, 177, 207)), to(rgb(120, 138, 177)));
+    background-image: linear-gradient(to bottom, rgb(162, 177, 207) 0%, rgb(120, 138, 177) 100%);
+    -webkit-background-origin: padding;
+    -webkit-background-clip: padding;
+    background-origin: padding;
+    background-clip: padding;
+}
+
+:focus .placard.selected {
+    border-top: 1px solid rgb(68, 128, 200);
+    background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(92, 147, 213)), to(rgb(21, 83, 170)));
+    background-image: linear-gradient(to bottom, rgb(92, 147, 213) 0%, rgb(21, 83, 170) 100%);
+}
+
+body.inactive .placard.selected {
+    border-top: 1px solid rgb(151, 151, 151);
+    background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(180, 180, 180)), to(rgb(138, 138, 138)));
+    background-image: linear-gradient(to bottom, rgb(180, 180, 180) 0%, rgb(138, 138, 138) 100%);
+}
+
+.placard .title {
+    color: black;
+    font-weight: normal;
+    word-wrap: break-word;
+    white-space: normal;
+}
+
+.placard.selected .title {
+    color: white;
+    font-weight: bold;
+}
+
+.placard .subtitle {
+    float: right;
+    font-size: 10px;
+    margin-left: 5px;
+    max-width: 55%;
+    color: rgba(0, 0, 0, 0.7);
+    text-overflow: ellipsis;
+    overflow: hidden;
+}
+
+.placard.selected .subtitle {
+    color: rgba(255, 255, 255, 0.7);
+}
+
+.placard .subtitle a {
+    color: inherit;
+}
+
+.section {
+    position: relative;
+    margin-top: 1px;
+}
+
+.watch-expressions-buttons-container {
+    text-align: center;
+}
+
+.events-pane .section:not(:nth-of-type(1)) {
+    border-top: 1px solid rgb(191, 191, 191);
+}
+
+.event-bar:first-child {
+    margin-top: 1px;
+}
+
+.section .header {
+    color: black;
+    padding: 0 8px 0 18px;
+    min-height: 18px;
+    white-space: nowrap;
+    -webkit-background-origin: padding;
+    -webkit-background-clip: padding;
+    background-origin: padding;
+    background-clip: padding;
+}
+
+.section .header::before {
+    position: absolute;
+    top: 2px;
+    left: 7px;
+    width: 8px;
+    height: 8px;
+    content: url(Images/treeRightTriangleBlack.png);
+    opacity: 0.8;
+}
+
+.section.expanded .header::before {
+    content: url(Images/treeDownTriangleBlack.png);
+}
+
+.section .header .title, .event-bar .header .title {
+    font-weight: normal;
+    word-wrap: break-word;
+    white-space: normal;
+    line-height: 18px;
+}
+
+.section .header .title.blank-title {
+    font-style: italic;
+}
+
+.section .header label, .event-bar .header label {
+    display: none;
+}
+
+.section.expanded .header label, .event-bar.expanded .header label {
+    display: inline;
+}
+
+.section .header .subtitle, .event-bar .header .subtitle {
+    float: right;
+    margin-left: 5px;
+    max-width: 55%;
+    text-overflow: ellipsis;
+    overflow: hidden;
+}
+
+.section .header .subtitle a {
+    color: inherit;
+}
+
+.section .properties, .event-bar .event-properties {
+    display: none;
+}
+
+.section.expanded .properties, .event-bar.expanded .event-properties {
+    display: block;
+    padding-left: 16px;
+}
+
+.section.no-affect .properties li {
+    opacity: 0.5;
+}
+
+.section.no-affect .properties li.editing {
+    opacity: 1.0;
+}
+
+.properties-tree {
+    margin: 0;
+    padding: 0 6px 2px;
+    list-style: none;
+    min-height: 18px;
+}
+
+.properties-tree li {
+    margin-left: 12px;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    -webkit-user-select: text;
+    -ms-user-select: text;
+    -moz-user-select: text;
+    cursor: auto;
+}
+
+.properties-tree li.parent {
+    margin-left: 1px;
+}
+
+.properties-tree li.parent::before {
+    content: url(Images/treeRightTriangleBlack.png);
+    opacity: 0.75;
+    float: left;
+    width: 8px;
+    height: 8px;
+    margin-top: 0;
+    padding-right: 3px;
+    -webkit-user-select: none;
+    -ms-user-select: none;
+    -moz-user-select: none;
+    cursor: default;
+}
+
+.properties-tree li.parent.expanded::before {
+    content: url(Images/treeDownTriangleBlack.png);
+    margin-top: 1px;
+}
+
+.properties-tree li .info {
+    padding-top: 4px;
+    padding-bottom: 3px;
+}
+
+.properties-tree ol {
+    display: none;
+    margin: 0;
+    -webkit-padding-start: 12px;
+    -moz-padding-start: 12px;
+    list-style: none;
+}
+
+.properties-tree ol.expanded {
+    display: block;
+}
+
+.event-listener-breakpoints .event-category {
+    font-size: 11px;
+    font-weight: bold;
+    color: rgb(96, 96, 96);
+    padding-top: 2px;
+}
+
+.event-listener-breakpoints.properties-tree .children li {
+    margin-left: 12px;
+    height: 16px;
+}
+
+.event-listener-breakpoints .checkbox-elem {
+    font-size: 10px;
+    float: left;
+    top: -2px;
+    position: relative;
+    left: -1px;
+}
+
+.section .event-bars {
+    display: none;
+}
+
+.section.expanded .event-bars {
+    display: block;
+}
+
+.event-bar {
+    position: relative;
+    margin-left: 10px;
+}
+
+.event-bars .event-bar .header {
+    padding: 0 8px 0 18px;
+    min-height: 16px;
+    opacity: 1.0;
+    white-space: nowrap;
+    -webkit-background-origin: padding;
+    -webkit-background-clip: padding;
+    background-origin: padding;
+    background-clip: padding;
+}
+
+.event-bars .event-bar .header .title {
+    font-weight: normal;
+    color: black;
+    text-shadow: white 0 1px 0;
+}
+
+.event-bars .event-bar .header .subtitle {
+    color: rgba(90, 90, 90, 0.75);
+}
+
+.event-bars .event-bar .header::before {
+    position: absolute;
+    top: 2px;
+    left: 7px;
+    width: 8px;
+    height: 8px;
+    opacity: 0.75;
+    content: url(Images/treeRightTriangleBlack.png);
+}
+
+.event-bars .event-bar.expanded .header::before {
+    content: url(Images/treeDownTriangleBlack.png);
+}
+
+.editing {
+    -webkit-user-select: text;
+    -ms-user-select: text;
+    -moz-user-select: text;
+    -webkit-box-shadow: rgba(0, 0, 0, .5) 3px 3px 4px;
+    box-shadow: rgba(0, 0, 0, .5) 3px 3px 4px;
+    outline: 1px solid rgb(66%, 66%, 66%) !important;
+    background-color: white;
+    -webkit-user-modify: read-write-plaintext-only;
+    -moz-user-modify: read-write;
+    text-overflow: clip !important;
+    padding-left: 2px;
+    margin-left: -2px;
+    padding-right: 2px;
+    margin-right: -2px;
+    margin-bottom: -1px;
+    padding-bottom: 1px;
+    opacity: 1.0 !important;
+}
+
+.editing, .editing * {
+    color: black !important;
+    text-decoration: none !important;
+}
+
+.child-editing {
+    color: black !important;
+    text-decoration: none !important;
+    overflow: visible !important;
+}
+
+.editing br {
+    display: none;
+}
+
+.elements-tree-editor {
+    -webkit-user-select: text;
+    -ms-user-select: text;
+    -moz-user-select: text;
+    -webkit-user-modify: read-write-plaintext-only;
+    -moz-user-modify: read-write-plaintext-only;
+}
+
+.section .properties li.editing {
+    margin-left: 10px;
+    text-overflow: clip;
+}
+
+li.editing .swatch, li.editing .enabled-button,  li.editing-sub-part .delete-button {
+    display: none !important;
+}
+
+.watch-expressions > li.editing-sub-part .name {
+    display: block;
+    width: 100%;
+}
+
+.watch-expressions > li.editing-sub-part .value, .watch-expressions > li.editing-sub-part .separator  {
+    display: none;
+}
+
+.watch-expressions-error-level {
+    color: red;
+}
+
+.section .properties li.editing-sub-part {
+    padding: 3px 6px 8px 18px;
+    margin: -3px -6px -8px -6px;
+    text-overflow: clip;
+}
+
+/* FIXME: need a better icon (comment in bug 27514) */
+.section .properties .delete-button {
+    width: 10px;
+    height: 10px;
+    background-image: url(Images/errorIcon.png);
+    background-position: 0 0;
+    background-color: transparent;
+    background-repeat: no-repeat;
+    border: 0 none transparent;
+}
+
+.section .properties .name, .event-properties .name {
+    color: rgb(136, 19, 145);
+}
+
+.section .properties .value.dimmed {
+    color: rgb(100, 100, 100);
+}
+
+.section .properties .value.error {
+    color: red;
+}
+
+.section .properties .number, .event-properties .number {
+    color: blue;
+}
+
+.section .properties .keyword, .event-properties .keyword {
+    color: rgb(136, 19, 79);
+}
+
+.section .properties .color, .event-properties .color {
+    color: rgb(118, 15, 21);
+}
+
+.swatch {
+    display: inline-block;
+    vertical-align: baseline;
+    margin-left: 1px;
+    margin-right: 2px;
+    margin-bottom: -1px;
+    width: 1em;
+    height: 1em;
+    border: 1px solid rgba(128, 128, 128, 0.6);
+}
+
+.swatch:hover {
+    border: 1px solid rgba(64, 64, 64, 0.8);
+}
+
+.pane:not(.expanded) + .pane, .pane:first-of-type {
+    margin-top: -1px;
+}
+
+.pane > .title {
+    background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(243, 243, 243)), color-stop(0.05, rgb(243, 243, 243)), color-stop(0.05, rgb(230, 230, 230)), to(rgb(209, 209, 209)));
+    background-image: linear-gradient(to bottom, rgb(243, 243, 243) 0%, rgb(243, 243, 243) 10%, rgb(230, 230, 230) 40%, rgb(209, 209, 209) 100%);
+    height: 20px;
+    padding: 0 5px;
+    border-top: 1px solid rgb(189, 189, 189);
+    border-bottom: 1px solid rgb(189, 189, 189);
+    font-weight: bold;
+    font-size: 12px;
+    line-height: 18px;
+    color: rgb(110, 110, 110);
+    text-shadow: white 0 1px 0;
+    -webkit-background-origin: padding;
+    -webkit-background-clip: padding;
+    background-origin: padding;
+    background-clip: padding;
+}
+
+.pane > .title:active {
+    background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(231, 231, 231)), color-stop(0.05, rgb(231, 231, 231)), color-stop(0.05, rgb(207, 207, 207)), to(rgb(186, 186, 186)));
+    background-image: linear-gradient(to bottom, rgb(231, 231, 231) 0%,rgb(231, 231, 231) 10%, rgb(207, 207, 207) 40%, rgb(186, 186, 186) 100%);
+    border-top: 1px solid rgb(178, 178, 178);
+    border-bottom: 1px solid rgb(178, 178, 178);
+}
+
+.pane > .title::before {
+    content: url(Images/disclosureTriangleSmallRightBlack.png);
+    float: left;
+    width: 11px;
+    height: 12px;
+    margin-right: 2px;
+    margin-top: 1px;
+}
+
+.pane.expanded > .title::before {
+    content: url(Images/disclosureTriangleSmallDownBlack.png);
+}
+
+.pane > .title > select {
+    float: right;
+    width: 23px;
+    height: 17px;
+    color: transparent;
+    background-color: transparent;
+    border: none;
+    background-image: url(Images/paneSettingsButtons.png);
+    background-repeat: no-repeat;
+    margin: 1px 0 0 0;
+    padding: 0;
+    -webkit-border-radius: 0;
+    border-radius: 0;
+    -webkit-appearance: none;
+    -moz-appearance: none;
+    /* hack for appearance for non-webkit browsers */
+    padding-left: 10px;
+    padding-right: 13px;
+}
+
+.pane > .title > select:hover {
+    background-position: -23px 0px;
+}
+
+.pane > .title > select:active {
+    background-position: -46px 0px;
+}
+
+.pane > .title > select > option, .pane > .title > select > hr {
+    color: black;
+}
+
+.pane > .title > button.add {
+    float: right;
+    width: 23px;
+    height: 17px;
+    color: transparent;
+    background-color: transparent;
+    border: none;
+    background-image: url(Images/paneAddButtons.png);
+    background-repeat: no-repeat;
+    margin: 1px 0 0 0;
+    padding: 0;
+    -webkit-border-radius: 0;
+    border-radius: 0;
+    -webkit-appearance: none;
+    -moz-appearance: none;
+}
+
+.pane > .title > button.add:hover {
+    background-position: -23px 0px;
+}
+
+.pane > .title > button.add:active {
+    background-position: -46px 0px;
+}
+
+.pane > .body {
+    position: relative;
+    display: none;
+    overflow-y: auto;
+    overflow-x: hidden;
+}
+
+.pane > .body .info {
+    text-align: center;
+    font-style: italic;
+    font-size: 10px;
+    padding: 6px;
+    color: black;
+}
+
+.pane > .body .placard + .info {
+    border-top: 1px solid rgb(189, 189, 189);
+    background-color: rgb(255, 255, 194);
+}
+
+.pane.expanded > .body, .pane.expanded > .growbar {
+    display: block;
+}
+
+.pane > .body .breakpoint-condition {
+    display: block;
+    margin-top: 4px;
+    margin-bottom: 4px;
+    margin-left: 25px;
+    margin-right: 10px;
+}
+
+.pane.expanded:nth-last-of-type(1) {
+    border-bottom: 1px solid rgb(189, 189, 189);
+}
+
+.pane > .growbar {
+    display: none;
+    background-image: url(Images/paneGrowHandleLine.png), url(Images/paneBottomGrow.png);
+    background-repeat: no-repeat, repeat-x;
+    background-position: center center, bottom;
+    height: 5px;
+}
+
+.sidebar-pane-subtitle {
+    position: absolute;
+    right: 0;
+    font-weight: normal;
+}
+
+body.platform-windows .sidebar-pane-subtitle {
+    padding-top: 1px;
+}
+
+.sidebar-pane-subtitle input, .section .header input[type=checkbox] {
+    font-size: inherit;
+    hight: 1em;
+    width: 1em;
+    margin-left: 0;
+    margin-top: 0;
+    margin-bottom: 0.25em;
+    vertical-align: middle;
+    /*Hack for IE - 'box-sizing: border-box' significantly reduce checkbox size so we set it to default*/
+    box-sizing: content-box;
+}
+
+.metrics {
+    padding: 8px;
+    font-size: 10px;
+    text-align: center;
+    white-space: nowrap;
+}
+
+.metrics .label {
+    position: absolute;
+    margin-top: -10px;
+    font-size: 9px;
+    color: grey;
+    background-color: white;
+    margin-left: 3px;
+    padding-left: 2px;
+    padding-right: 2px;
+}
+
+.metrics .position {
+    border: 1px rgb(66%, 66%, 66%) dotted;
+    display: inline-block;
+    text-align: center;
+    padding: 3px;
+    margin: 3px;
+}
+
+.metrics .margin {
+    border: 1px dashed;
+    display: inline-block;
+    text-align: center;
+    vertical-align: middle;
+    padding: 3px;
+    margin: 3px;
+}
+
+.metrics .border {
+    border: 1px black solid;
+    display: inline-block;
+    text-align: center;
+    vertical-align: middle;
+    padding: 3px;
+    margin: 3px;
+}
+
+.metrics .padding {
+    border: 1px grey dashed;
+    display: inline-block;
+    text-align: center;
+    vertical-align: middle;
+    padding: 3px;
+    margin: 3px;
+}
+
+.metrics .content {
+    position: static;
+    border: 1px grey solid;
+    display: inline-block;
+    text-align: center;
+    vertical-align: middle;
+    padding: 3px;
+    margin: 3px;
+    min-width: 80px;
+    text-align: center;
+    overflow: visible;
+}
+
+.metrics .content span {
+    display: inline-block;
+}
+
+.metrics .editing {
+    position: relative;
+    z-index: 100;
+}
+
+.metrics .left {
+    display: inline-block;
+    vertical-align: middle;
+}
+
+.metrics .right {
+    display: inline-block;
+    vertical-align: middle;
+}
+
+.metrics .top {
+    display: inline-block;
+}
+
+.metrics .bottom {
+    display: inline-block;
+}
+
+.sidebar {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    width: 200px;
+    overflow-y: auto;
+    overflow-x: hidden;
+    background-color: rgb(214, 221, 229);
+    border-right: 1px solid rgb(64%, 64%, 64%);
+}
+
+body.inactive .sidebar {
+    background-color: rgb(232, 232, 232);
+}
+
+.frame-storage-tree-item .icon {
+    content: url(Images/frame.png);
+}
+
+.database-storage-tree-item .icon {
+    content: url(Images/database.png);
+}
+
+.database-table-storage-tree-item .icon {
+    content: url(Images/databaseTable.png);
+}
+
+.domstorage-storage-tree-item.local-storage .icon {
+    content: url(Images/localStorage.png);
+}
+
+.domstorage-storage-tree-item.session-storage .icon {
+    content: url(Images/sessionStorage.png);
+}
+
+.cookie-storage-tree-item .icon {
+    content: url(Images/cookie.png);
+}
+
+.application-cache-storage-tree-item .icon {
+    content: url(Images/applicationCache.png);
+}
+
+/* FIXME: Make separate png for file-system */
+.file-system-storage-tree-item .icon {
+    content: url(Images/applicationCache.png);
+}
+
+#storage-views {
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 200px;
+    bottom: 0;
+}
+
+.resources.panel .sidebar {
+    padding-left: 0;
+    z-index: 10;
+}
+
+.resources.panel .sidebar li {
+    height: 17px;
+    white-space: nowrap;
+    text-indent: 0;
+    margin-left: -2px;
+}
+
+.resources.panel .sidebar li.parent {
+    text-indent: 0;
+    margin-left: -12px;
+}
+
+.resources.panel .sidebar li.selected {
+    color: white;
+    text-shadow: rgba(0, 0, 0, 0.33) 0 1px 0;
+    font-weight: bold;
+}
+
+.resources.panel .sidebar li.selected .selection {
+    background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(162, 177, 207)), to(rgb(120, 138, 177)));
+    background-image: linear-gradient(to bottom, rgb(162, 177, 207) 0%, rgb(120, 138, 177) 100%);
+    border-top: 1px solid #979797;
+    height: 17px;
+}
+
+.resources.panel .sidebar :focus li.selected .selection {
+    background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(92, 147, 213)), to(rgb(21, 83, 170)));
+    background-image: linear-gradient(to bottom, rgb(92, 147, 213) 0%, rgb(21, 83, 170) 100%);
+    border-top: 1px solid rgb(68, 128, 200);
+}
+
+body.inactive .resources.panel .sidebar li.selected .selection {
+    background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(180, 180, 180)), to(rgb(138, 138, 138)));
+    background-image: linear-gradient(to bottom, rgb(180, 180, 180) 0%, rgb(138, 138, 138) 100%);
+    border-top: 1px solid rgb(151, 151, 151);
+}
+
+.resources.panel .sidebar .icon {
+    width: 16px;
+    height: 16px;
+    float: left;
+}
+
+.resources.panel .base-storage-tree-element-title {
+    overflow: hidden;
+    position: relative;
+    text-overflow: ellipsis;
+    padding-left: 2px;
+    top: 1px;
+}
+
+li.selected .base-storage-tree-element-subtitle {
+    color: white;
+}
+
+.base-storage-tree-element-subtitle {
+    padding-left: 2px;
+    color: rgb(80, 80, 80);
+    text-shadow: none;
+}
+
+.resources.panel .status {
+    float: right;
+    height: 16px;
+    margin-top: 1px;
+    margin-left: 4px;
+    line-height: 1em;
+}
+
+.resources.panel li .status .bubble {
+    height: 13px;
+    padding-top: 0;
+}
+
+.storage-view {
+    display: none;
+    overflow: hidden;
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+}
+
+.storage-view.visible {
+    display: block;
+}
+
+.storage-view {
+    overflow: hidden;
+}
+
+.storage-view .data-grid {
+    border: none;
+    height: 100%;
+}
+
+.storage-empty-view, .storage-view .storage-table-error {
+    position: absolute;
+    top: 0;
+    bottom: 25%;
+    left: 0;
+    right: 0;
+    font-size: 24px;
+    color: rgb(75%, 75%, 75%);
+    margin-top: auto;
+    margin-bottom: auto;
+    height: 50px;
+    line-height: 26px;
+    text-align: center;
+    font-weight: bold;
+    padding: 10px;
+    white-space: pre-wrap;
+}
+
+.storage-view .storage-table-error {
+    color: rgb(66%, 33%, 33%);
+}
+
+.data-grid {
+    position: relative;
+    border: 1px solid #aaa;
+}
+
+.data-grid .highlight {
+    background-color: rgb(255, 230, 179);
+}
+
+.data-grid tr.selected .highlight {
+    background-color: transparent;
+}
+
+.data-grid table {
+    table-layout: fixed;
+    border-spacing: 0;
+    border-collapse: collapse;
+    width: 100%;
+    font-size: 10px;
+    font-family: Lucida Grande, sans-serif;
+}
+
+.data-grid .data-container {
+    position: absolute;
+    top: 16px;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    padding-right: 14px;
+    overflow-x: hidden;
+    overflow-y: overlay;
+}
+
+.data-grid.inline .data-container {
+    position: static;
+}
+
+.data-grid th {
+    text-align: left;
+    background-image: url(Images/glossyHeader.png);
+    background-repeat: repeat-x;
+    border-right: 1px solid rgb(179, 179, 179);
+    border-bottom: 1px solid rgb(179, 179, 179);
+    height: 15px;
+    font-weight: normal;
+    vertical-align: middle;
+    padding: 0 4px;
+    white-space: nowrap;
+}
+
+.data-grid th.corner {
+    width: 15px;
+    border-right: 0 none transparent;
+}
+
+.data-grid tr.filler {
+    display: table-row !important;
+    height: auto !important;
+}
+
+.data-grid tr.filler td {
+    height: auto !important;
+    padding: 0 !important;
+}
+
+.data-grid table.data {
+    position: absolute;
+    left: 0;
+    top: 0;
+    right: 16px;
+    bottom: 0;
+    height: 100%;
+    border-top: 0 none transparent;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(white), color-stop(0.5, white), color-stop(0.5, rgb(234, 243, 255)), to(rgb(234, 243, 255)));
+    background-image: linear-gradient(to bottom, white 0%, white 10%, rgb(234, 243, 255) 40%, rgb(234, 243, 255) 100%);
+    -webkit-background-size: 1px 32px;
+    background-size: 1px 32px;
+}
+
+.data-grid.inline table.data {
+    position: static;
+}
+
+.data-grid table.data tr {
+    display: none;
+}
+
+.data-grid table.data tr.revealed {
+    display: table-row;
+}
+
+.data-grid td {
+    vertical-align: top;
+    height: 12px;
+    line-height: 12px;
+    padding: 2px 4px;
+    white-space: nowrap;
+    border-right: 1px solid #aaa;
+    -webkit-user-select: text;
+    -ms-user-select: text;
+    -moz-user-select: text;
+}
+
+.data-grid td > div, .data-grid th > div {
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    overflow: hidden;
+}
+
+.data-grid .centered div {
+    text-align: center;
+}
+
+.data-grid .right div {
+    text-align: right;
+}
+
+.data-grid th.sortable div {
+    position: relative;
+}
+
+.data-grid th.sortable:active {
+    background-image: url(Images/glossyHeaderPressed.png);
+}
+
+.data-grid th.sort-ascending, .data-grid th.sort-descending {
+    border-right: 1px solid rgb(107, 140, 196);
+    border-bottom: 1px solid rgb(107, 140, 196);
+    background-image: url(Images/glossyHeaderSelected.png);
+    background-repeat: repeat-x;
+}
+
+.data-grid th.sortable.sort-ascending:active, .data-grid th.sortable.sort-descending:active {
+    background-image: url(Images/glossyHeaderSelectedPressed.png);
+}
+
+.data-grid th.sort-ascending > div::after {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    right: 0;
+    height: 12px;
+    margin-bottom: auto;
+    margin-top: auto;
+    width: 8px;
+    content: url(Images/treeUpTriangleBlack.png);
+}
+
+.data-grid th.sort-descending > div::after {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    right: 0;
+    height: 8px;
+    margin-bottom: auto;
+    margin-top: auto;
+    width: 8px;
+    content: url(Images/treeDownTriangleBlack.png);
+}
+
+.data-grid button {
+    line-height: 19px;
+}
+
+body.inactive .data-grid th.sort-ascending, body.inactive .data-grid th.sort-descending {
+    background-image: url(Images/glossyHeader.png);
+    border-right: 1px solid rgb(179, 179, 179);
+    border-bottom: 1px solid rgb(179, 179, 179);
+}
+
+.data-grid tr.parent td.disclosure::before {
+    float: left;
+    content: url(Images/treeRightTriangleBlack.png);
+    width: 8px;
+    height: 8px;
+    margin-right: 2px;
+    -webkit-user-select: none;
+    -ms-user-select: none;
+    -moz-user-select: none;
+}
+
+.data-grid tr.expanded td.disclosure::before {
+    content: url(Images/treeDownTriangleBlack.png);
+    width: 8px;
+    height: 8px;
+    margin-top: 1px;
+}
+
+.data-grid tr.selected {
+    background-color: rgb(212, 212, 212);
+    color: inherit;
+}
+
+.data-grid:focus tr.selected {
+    background-color: rgb(56, 121, 217);
+    color: white;
+}
+
+.data-grid:focus tr.parent.selected td.disclosure::before {
+    content: url(Images/treeRightTriangleWhite.png);
+}
+
+.data-grid:focus tr.expanded.selected td.disclosure::before {
+    content: url(Images/treeDownTriangleWhite.png);
+}
+
+.data-grid tr:not(.parent) td.disclosure {
+    text-indent: 10px;
+}
+
+.data-grid-resizer {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    width: 5px;
+    z-index: 500;
+    cursor: col-resize;
+}
+
+.storage-view.query {
+    padding: 2px 0;
+    overflow-y: overlay;
+    overflow-x: hidden;
+    -webkit-text-size-adjust: auto;
+    -ms-text-size-adjust: auto;
+    -moz-text-size-adjust: auto;
+}
+
+.database-query-prompt {
+    position: relative;
+    padding: 1px 22px 1px 24px;
+    min-height: 16px;
+    white-space: pre-wrap;
+    -webkit-user-modify: read-write-plaintext-only;
+    -moz-user-modify: read-write;
+    -webkit-user-select: text;
+    -ms-user-select: text;
+    -moz-user-select: text;
+}
+
+.database-user-query::before, .database-query-prompt::before, .database-query-result::before {
+    position: absolute;
+    display: block;
+    content: "";
+    left: 7px;
+    top: 0.8em;
+    width: 10px;
+    height: 10px;
+    margin-top: -5px;
+    -webkit-user-select: none;
+    -ms-user-select: none;
+    -moz-user-select: none;
+}
+
+.database-query-prompt::before {
+    background-image: url(Images/userInputIcon.png);
+}
+
+.database-user-query {
+    position: relative;
+    border-bottom: 1px solid rgb(245, 245, 245);
+    padding: 1px 22px 1px 24px;
+    min-height: 16px;
+}
+
+.database-user-query::before {
+    background-image: url(Images/userInputPreviousIcon.png);
+}
+
+.database-query-text {
+    color: rgb(0, 128, 255);
+    -webkit-user-select: text;
+    -ms-user-select: text;
+    -moz-user-select: none;
+}
+
+.database-query-result {
+    position: relative;
+    padding: 1px 22px 1px 24px;
+    min-height: 16px;
+    margin-left: -24px;
+    padding-right: 0;
+}
+
+.database-query-result.error {
+    color: red;
+    -webkit-user-select: text;
+    -ms-user-select: text;
+    -moz-user-select: none;
+}
+
+.database-query-result.error::before {
+    background-image: url(Images/errorIcon.png);
+}
+
+.panel-enabler-view {
+    z-index: 1000;
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background-color: white;
+    font-size: 13px;
+    text-align: center;
+    overflow-x: hidden;
+    overflow-y: overlay;
+    display: none;
+}
+
+.panel-enabler-view.visible {
+    display: block;
+}
+
+.panel-enabler-view .panel-enabler-view-content {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    max-height: 390px;
+    margin: auto;
+    white-space: nowrap;
+}
+
+.panel-enabler-view h1 {
+    color: rgb(110, 116, 128);
+    font-size: 16px;
+    line-height: 20px;
+    font-weight: normal;
+    margin-top: 0;
+}
+
+.panel-enabler-disclaimer {
+    font-size: 10px;
+    color: rgb(110, 116, 128);
+    margin-bottom: 12px;
+    margin-left: 20px;
+}
+
+.panel-enabler-disclaimer:empty {
+    display: none;
+}
+
+.panel-enabler-view img, div.welcome-instructions-aligner {
+    height: 100%;
+    min-height: 200px;
+    max-width: 100%;
+    top: 0;
+    bottom: 0;
+    padding: 20px 0 20px 20px;
+    margin: auto;
+    vertical-align: middle;
+}
+
+.panel-enabler-view img.hidden {
+    display: initial !important;
+    width: 0;
+}
+
+.panel-enabler-view form {
+    display: inline-block;
+    vertical-align: middle;
+    width: 330px;
+    margin: 0;
+    padding: 15px;
+    white-space: normal;
+}
+
+.panel-enabler-view label {
+    position: relative;
+    display: block;
+    text-align: left;
+    word-break: break-word;
+    margin: 0 0 5px 20px;
+}
+
+.panel-enabler-view button:not(.status-bar-item), .pane button, button.show-all-nodes {
+    color: rgb(6, 6, 6);
+    background-color: transparent;
+    border: 1px solid rgb(165, 165, 165);
+    background-color: rgb(237, 237, 237);
+    background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)));
+    background-image: linear-gradient(to bottom, rgb(252, 252, 252) 0%, rgb(233, 233, 233) 100%);
+    -webkit-border-radius: 12px;
+    border-radius: 12px;
+    -webkit-appearance: none;
+    -moz-appearance: none;
+}
+
+.panel-enabler-view button:not(.status-bar-item) {
+    font-size: 13px;
+    margin: 6px 0 0 0;
+    padding: 3px 20px;
+    height: 24px;
+}
+
+button.show-all-nodes {
+    font-size: 13px;
+    margin: 0;
+    padding: 0 20px;
+    height: 20px;
+}
+
+.panel-enabler-view.welcome {
+    z-index: auto;
+}
+
+.panel-enabler-view.welcome div.welcome-instructions-aligner {
+    display: inline-block;
+    width: 0;
+}
+
+.panel-enabler-view.welcome .instructions {
+    display: inline-block;
+    vertical-align: middle;
+    margin: 0;
+    white-space: normal;
+    line-height: 175%;
+}
+
+.panel-enabler-view.welcome .message {
+    margin-bottom: 2ex;
+}
+
+.panel-enabler-view.welcome button.status-bar-item {
+    background-image: none;
+    vertical-align: top;
+}
+
+.pane button {
+    margin: 6px 0 6px 3px;
+    padding: 2px 9px;
+}
+
+.panel-enabler-view button:active:not(.status-bar-item), .pane button:active, button.show-all-nodes:active {
+    background-color: rgb(215, 215, 215);
+    background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(194, 194, 194)), to(rgb(239, 239, 239)));
+    background-image: linear-gradient(to bottom, rgb(194, 194, 194) 0%, rgb(239, 239, 239) 100%);
+}
+
+body.inactive .panel-enabler-view button:not(.status-bar-item), .panel-enabler-view button:disabled:not(.status-bar-item), body.inactive .pane button, .pane button:disabled, body.inactive button.show-all-nodes {
+    color: rgb(130, 130, 130);
+    border-color: rgb(212, 212, 212);
+    background-color: rgb(239, 239, 239);
+    background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(250, 250, 250)), to(rgb(235, 235, 235)));
+    background-image: linear-gradient(to bottom, rgb(250, 250, 250) 0%, rgb(235, 235, 235) 100%);
+}
+
+.panel-enabler-view input {
+    height: 17px;
+    width: 17px;
+    border: 1px solid rgb(165, 165, 165);
+    background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)));
+    background-image: linear-gradient(to bottom, rgb(252, 252, 252) 0%, rgb(223, 223, 223) 100%);
+    -webkit-border-radius: 8px;
+    border-radius: 8px;
+    -webkit-appearance: none;
+    -moz-appearance: none;
+    vertical-align: middle;
+    margin: 0 5px 5px 0;
+}
+
+.panel-enabler-view input:active {
+    background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(194, 194, 194)), to(rgb(239, 239, 239)));
+    background-image: linear-gradient(to bottom, rgb(194, 194, 194) 0%, rgb(239, 239, 239) 100%);
+}
+
+.panel-enabler-view input:checked {
+    background: url(Images/radioDot.png) center no-repeat,
+    -webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)));
+    background-image: linear-gradient(to bottom, rgb(252, 252, 252) 0%, rgb(223, 223, 223) 100%);
+}
+
+.panel-enabler-view.scripts img {
+    content: url(Images/scriptsSilhouette.png);
+}
+
+.panel-enabler-view.profiles img {
+    content: url(Images/profilesSilhouette.png);
+}
+
+button.enable-toggle-status-bar-item .glyph {
+    -webkit-mask-image: url(Images/enableOutlineButtonGlyph.png);
+}
+
+button.enable-toggle-status-bar-item.toggled-on .glyph {
+    -webkit-mask-image: url(Images/enableSolidButtonGlyph.png);
+}
+
+.scripts-pause-on-exceptions-status-bar-item .glyph {
+    -webkit-mask-image: url(Images/pauseOnExceptionButtonGlyph.png);
+}
+
+#scripts-status-bar {
+    position: absolute;
+    top: -1px;
+    left: 0;
+    right: 0;
+    height: 24px;
+}
+
+#scripts-files {
+    max-width: 250px;
+}
+
+#scripts-files option.extension-script {
+    color: rgb(70, 134, 240);
+}
+
+#scripts-functions {
+    max-width: 150px;
+}
+
+#scripts-status-bar .status-bar-item img {
+    margin-top: 2px;
+}
+
+#scripts-back img {
+    content: url(Images/back.png);
+}
+
+#scripts-forward img {
+    content: url(Images/forward.png);
+}
+
+#scripts-pause img {
+    content: url(Images/debuggerPause.png);
+}
+
+#scripts-pause.paused img {
+    content: url(Images/debuggerContinue.png);
+}
+
+#scripts-step-over img {
+    content: url(Images/debuggerStepOver.png);
+}
+
+#scripts-step-into img {
+    content: url(Images/debuggerStepInto.png);
+}
+
+#scripts-step-out img {
+    content: url(Images/debuggerStepOut.png);
+}
+
+.toggle-breakpoints .glyph {
+    -webkit-mask-image: url(Images/breakpointsActivateButtonGlyph.png);
+    background-color: rgb(96, 96, 96) !important;
+}
+
+.toggle-breakpoints.toggled-on .glyph {
+    -webkit-mask-image: url(Images/breakpointsDeactivateButtonGlyph.png);
+}
+
+#scripts-debugger-status {
+    position: absolute;
+    line-height: 24px;
+    top: 0;
+    right: 8px;
+}
+
+#scripts-sidebar-resizer-widget {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    right: 225px;
+    width: 16px;
+    cursor: col-resize;
+    background-image: url(Images/statusbarResizerHorizontal.png);
+    background-repeat: no-repeat;
+    background-position: center;
+}
+
+#scripts-sidebar-buttons {
+    position: absolute;
+    right: 0;
+    top: 0;
+    bottom: 0;
+    width: 225px;
+    overflow: hidden;
+    border-left: 1px solid rgb(64%, 64%, 64%);
+}
+
+#script-resource-views {
+    display: block;
+    padding: 0;
+    position: absolute;
+    top: 23px;
+    left: 0;
+    right: 225px;
+    bottom: 0;
+}
+
+.script-view {
+    display: none;
+    overflow: hidden;
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+}
+
+.script-view.visible {
+    display: block;
+}
+
+#scripts-sidebar {
+    position: absolute;
+    top: 23px;
+    right: 0;
+    bottom: 0;
+    width: 225px;
+    border-left: 1px solid rgb(64%, 64%, 64%);
+    cursor: default;
+    overflow: auto;
+}
+
+.resources-larger-resources-status-bar-item .glyph {
+    -webkit-mask-image: url(Images/largerResourcesButtonGlyph.png);
+}
+
+#resources-filter, #console-filter.console-filter-top {
+    background: -webkit-gradient(linear, left top, left bottom, from(rgb(236, 236, 236)), to(rgb(217, 217, 217)));
+    background-image: linear-gradient(to bottom, rgb(236, 236, 236) 0%, rgb(217, 217, 217) 100%);
+    border-bottom: 1px solid rgb(64%, 64%, 64%);
+    width: 100%;
+}
+
+#console-messages.console-filter-top {
+    margin-top: 23px;
+}
+
+#console-filter {
+    margin-top: 1px;
+}
+
+.tabbed-pane {
+    -webkit-box-orient: vertical;
+    -ms-flex-direction: column;
+    -moz-box-orient: vertical;
+    height: 100%;
+}
+
+.tabbed-pane-content {
+    -webkit-box-flex: 1;
+    -ms-flex: 1;
+    -moz-box-flex: 1;
+    position: relative;
+}
+
+.tabbed-pane-header {
+    height: 23px;
+    padding: 0 10px;
+    border-bottom: 1px solid rgb(163, 163, 163);
+}
+
+.tabbed-pane-header li {
+    display: inline-block;
+    margin-top: 2px;
+    font-size: 11px;
+    font-weight: bold;
+    color: rgb(46, 46, 46);
+    background: transparent;
+    text-shadow: rgba(255, 255, 255, 0.5) 0 1px 0;
+    vertical-align: middle;
+    padding: 3px 7px 2px;
+    height: 21px;
+    border: 1px solid transparent;
+    border-bottom: none;
+}
+
+.tabbed-pane-header li.selected {
+    background-color: white;
+    border: 1px solid rgb(163, 163, 163);
+    border-bottom: none;
+}
+
+.scope-bar {
+    height: 23px;
+    padding: 2px 10px 0;
+    overflow: hidden;
+}
+
+.scope-bar li {
+    display: inline-block;
+    margin: 1px 2px 0 0;
+    padding: 1px 7px 3px;
+    font-size: 11px;
+    line-height: 12px;
+    font-weight: bold;
+    color: rgb(46, 46, 46);
+    background: transparent;
+    text-shadow: rgba(255, 255, 255, 0.5) 0 1px 0;
+    -webkit-border-radius: 8px;
+    border-radius: 8px;
+    vertical-align: middle;
+}
+
+.scope-bar-divider {
+    margin: 1px 9px 0 8px;
+    background-color: rgba(0, 0, 0, 0.4);
+    height: 16px;
+    width: 1px;
+    vertical-align: middle;
+    display: inline-block;
+}
+
+.scope-bar li.selected, .scope-bar li:hover, .scope-bar li:active {
+    color: white;
+    text-shadow: rgba(0, 0, 0, 0.4) 0 1px 0;
+}
+
+.scope-bar li:hover {
+    background: rgba(0, 0, 0, 0.2);
+}
+
+.scope-bar li.selected {
+    background: rgba(0, 0, 0, 0.3);
+    -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.5) inset, 0 -1px 1px rgba(255, 255, 255, 0.25) inset, 0 1px 0 rgba(255, 255, 255, 0.5);
+    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.5) inset, 0 -1px 1px rgba(255, 255, 255, 0.25) inset, 0 1px 0 rgba(255, 255, 255, 0.5);
+}
+
+.scope-bar li:active {
+    background: rgba(0, 0, 0, 0.5);
+    -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.5) inset, 0 -1px 1px rgba(255, 255, 255, 0.25) inset, 0 1px 0 rgba(255, 255, 255, 0.5);
+    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.5) inset, 0 -1px 1px rgba(255, 255, 255, 0.25) inset, 0 1px 0 rgba(255, 255, 255, 0.5);
+}
+
+#resources-container {
+    position: absolute;
+    top: 23px;
+    left: 0;
+    bottom: 0;
+    right: 0;
+    border-right: 0 none transparent;
+    overflow-y: auto;
+    overflow-x: hidden;
+}
+
+#resources-container.viewing-resource {
+    right: auto;
+    width: 200px;
+    border-right: 1px solid rgb(64%, 64%, 64%);
+}
+
+#resources-container.viewing-resource #resources-sidebar {
+    width: 100%;
+    border-right: 0 none transparent;
+}
+
+#resources-sidebar {
+    min-height: 100%;
+    bottom: auto;
+    overflow: visible;
+}
+
+#resources-container-content {
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 200px;
+    min-height: 100%;
+}
+
+#resources-container.viewing-resource #resources-container-content {
+    display: none;
+}
+
+#resources-summary {
+    position: absolute;
+    padding-top: 20px;
+    top: 0;
+    left: 0;
+    right: 0;
+    height: 93px;
+    margin-left: -1px;
+    border-left: 1px solid rgb(102, 102, 102);
+    background-color: rgb(101, 111, 130);
+    background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0)), to(rgba(0, 0, 0, 0.5)));
+    background-image: linear-gradient(to bottom, rgb(0, 0, 0) 0%, rgb(0, 0, 0) 50%);
+    background-repeat: repeat-x;
+    background-position: bottom;
+    text-align: center;
+    text-shadow: black 0 1px 1px;
+    white-space: nowrap;
+    color: white;
+    -webkit-background-size: 1px 6px;
+    -webkit-background-origin: padding;
+    -webkit-background-clip: padding;
+    background-size: 1px 6px;
+    background-origin: padding;
+    background-clip: padding;
+    z-index: 400;
+}
+
+.summary-graph-legend {
+    margin-top: -10px;
+    padding-left: 15px;
+}
+
+.summary-graph-legend-item {
+    display: inline-block;
+    font-weight: bold;
+    margin-right: 15px;
+    vertical-align: top;
+}
+
+.summary-graph-legend-item.total {
+    margin-left: 10px;
+}
+
+.summary-graph-legend-label {
+    display: inline-block;
+    text-align: left;
+}
+
+.summary-graph-legend-header {
+    font-size: 12px;
+}
+
+.summary-graph-legend-value {
+    font-size: 10px;
+}
+
+.summary-graph-legend-swatch {
+    vertical-align: top;
+    margin-top: 1px;
+    margin-right: 3px;
+}
+
+.resources-dividers {
+    position: absolute;
+    left: 0;
+    right: 0;
+    height: 100%;
+    top: 0;
+    z-index: -100;
+}
+
+.resources-event-dividers {
+    position: absolute;
+    left: 0;
+    right: 5px;
+    height: 100%;
+    top: 0;
+    z-index: 300;
+    pointer-events: none;
+}
+
+.timeline .resources-event-dividers {
+    height: 19px;
+}
+
+.resources-dividers-label-bar {
+    position: absolute;
+    top: 0;
+    left: 0px;
+    right: 0;
+    background-color: rgba(255, 255, 255, 0.8);
+    background-clip: padding;
+    border-bottom: 1px solid rgba(0, 0, 0, 0.3);
+    height: 20px;
+    z-index: 200;
+}
+
+.resources-divider {
+    position: absolute;
+    width: 1px;
+    top: 0;
+    bottom: 0;
+    background-color: rgba(0, 0, 0, 0.1);
+}
+
+.resources-event-divider-padding {
+    position: absolute;
+    width: 8px;
+    top: 0;
+    bottom: 0;
+    pointer-events: auto;
+}
+
+.resources-event-divider {
+    position: absolute;
+    width: 2px;
+    top: 0;
+    bottom: 0;
+    z-index: 300;
+}
+
+.resources-red-divider {
+    background-color: rgba(255, 0, 0, 0.5);
+}
+
+.resources-blue-divider {
+    background-color: rgba(0, 0, 255, 0.5);
+}
+
+.resources-orange-divider {
+    background-color: rgba(255, 178, 23, 0.5);
+}
+
+.resources-divider.last {
+    background-color: transparent;
+}
+
+.resources-divider-label {
+    position: absolute;
+    top: 4px;
+    right: 3px;
+    font-size: 9px;
+    color: rgb(50%, 50%, 50%);
+    white-space: nowrap;
+}
+
+.memory-graph-label {
+    position: absolute;
+    top: 5px;
+    left: 5px;
+    font-size: 9px;
+    color: rgb(50%, 50%, 50%);
+    white-space: nowrap;
+}
+
+.resources-graph-label {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    margin: auto -7px;
+    height: 13px;
+    line-height: 13px;
+    font-size: 9px;
+    color: rgba(0, 0, 0, 0.75);
+    text-shadow: rgba(255, 255, 255, 0.25) 1px 0 0, rgba(255, 255, 255, 0.25) -1px 0 0, rgba(255, 255, 255, 0.333) 0 1px 0, rgba(255, 255, 255, 0.25) 0 -1px 0;
+    z-index: 150;
+    overflow: hidden;
+    text-align: center;
+    font-weight: bold;
+    opacity: 0;
+    -webkit-transition: opacity 250ms ease-in-out;
+    transition: opacity 250ms ease-in-out;
+}
+
+.resources-graph-side:hover .resources-graph-label {
+    opacity: 1;
+}
+
+.resources-graph-label:empty {
+    display: none;
+}
+
+.resources-graph-label.waiting {
+    margin-right: 5px;
+}
+
+.resources-graph-label.waiting-right {
+    margin-left: 5px;
+}
+
+.resources-graph-label.before {
+    color: rgba(0, 0, 0, 0.7);
+    text-shadow: none;
+    text-align: right;
+    margin-right: 2px;
+}
+
+.resources-graph-label.before::after {
+    padding-left: 2px;
+    height: 6px;
+    content: url(Images/graphLabelCalloutLeft.png);
+}
+
+.resources-graph-label.after {
+    color: rgba(0, 0, 0, 0.7);
+    text-shadow: none;
+    text-align: left;
+    margin-left: 2px;
+}
+
+.resources-graph-label.after::before {
+    padding-right: 2px;
+    height: 6px;
+    content: url(Images/graphLabelCalloutRight.png);
+}
+
+.resources-graph-bar {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    margin: auto -7px;
+    border-width: 6px 7px;
+    height: 13px;
+    min-width: 14px;
+    opacity: 0.65;
+    -webkit-border-image: url(Images/timelinePillGray.png) 6 7 6 7;
+    border-image: url(Images/timelinePillGray.png) 6 7 6 7;
+}
+
+.resources-category-documents, .resources-category-stylesheets, .resources-category-images,
+.resources-category-scripts, .resources-category-xhr, .resources-category-fonts,
+.resources-category-websockets, .resources-category-other {
+    display: none;
+}
+
+.filter-all .resources-category-documents, .filter-documents .resources-category-documents,
+.filter-all .resources-category-stylesheets, .filter-stylesheets .resources-category-stylesheets,
+.filter-all .resources-category-images, .filter-images .resources-category-images,
+.filter-all .resources-category-scripts, .filter-scripts .resources-category-scripts,
+.filter-all .resources-category-xhr, .filter-xhr .resources-category-xhr,
+.filter-all .resources-category-fonts, .filter-fonts .resources-category-fonts,
+.filter-all .resources-category-websockets, .filter-websockets .resources-category-websockets,
+.filter-all .resources-category-other, .filter-other .resources-category-other,
+.resource-sidebar-tree-item.selected {
+    display: list-item;
+}
+
+.console-warning-level, .console-error-level, .console-log-level {
+    display: none;
+}
+
+.filter-all .console-warning-level, .filter-warnings .console-warning-level,
+.filter-all .console-error-level, .filter-errors .console-error-level,
+.filter-all .console-log-level, .filter-logs .console-log-level {
+    display: block;
+}
+
+.console-user-command-result {
+    display: block;
+}
+
+.resources-graph-bar.waiting, .resources-graph-bar.waiting-right {
+    opacity: 0.35;
+}
+
+.resource-cached .resources-graph-bar {
+    -webkit-border-image: url(Images/timelineHollowPillGray.png) 6 7 6 7;
+    border-image: url(Images/timelineHollowPillGray.png) 6 7 6 7;
+}
+
+.resources-category-documents .resources-graph-bar {
+    -webkit-border-image: url(Images/timelinePillBlue.png) 6 7 6 7;
+    border-image: url(Images/timelinePillBlue.png) 6 7 6 7;
+}
+
+.resources-category-documents.resource-cached .resources-graph-bar {
+    -webkit-border-image: url(Images/timelineHollowPillBlue.png) 6 7 6 7;
+    border-image: url(Images/timelineHollowPillBlue.png) 6 7 6 7;
+}
+
+.resources-category-stylesheets .resources-graph-bar {
+    -webkit-border-image: url(Images/timelinePillGreen.png) 6 7 6 7;
+    border-image: url(Images/timelinePillGreen.png) 6 7 6 7;
+}
+
+.resources-category-stylesheets.resource-cached .resources-graph-bar {
+    -webkit-border-image: url(Images/timelineHollowPillGreen.png) 6 7 6 7;
+    border-image: url(Images/timelineHollowPillGreen.png) 6 7 6 7;
+}
+
+.resources-category-images .resources-graph-bar {
+    -webkit-border-image: url(Images/timelinePillPurple.png) 6 7 6 7;
+    border-image: url(Images/timelinePillPurple.png) 6 7 6 7;
+}
+
+.resources-category-images.resource-cached .resources-graph-bar {
+    -webkit-border-image: url(Images/timelineHollowPillPurple.png) 6 7 6 7;
+    border-image: url(Images/timelineHollowPillPurple.png) 6 7 6 7;
+}
+
+.resources-category-fonts .resources-graph-bar {
+    -webkit-border-image: url(Images/timelinePillRed.png) 6 7 6 7;
+    border-image: url(Images/timelinePillRed.png) 6 7 6 7;
+}
+
+.resources-category-fonts.resource-cached .resources-graph-bar {
+    -webkit-border-image: url(Images/timelineHollowPillRed.png) 6 7 6 7;
+    border-image: url(Images/timelineHollowPillRed.png) 6 7 6 7;
+}
+
+.resources-category-scripts .resources-graph-bar {
+    -webkit-border-image: url(Images/timelinePillOrange.png) 6 7 6 7;
+    border-image: url(Images/timelinePillOrange.png) 6 7 6 7;
+}
+
+.resources-category-scripts.resource-cached .resources-graph-bar {
+    -webkit-border-image: url(Images/timelineHollowPillOrange.png) 6 7 6 7;
+    border-image: url(Images/timelineHollowPillOrange.png) 6 7 6 7;
+}
+
+.resources-category-xhr .resources-graph-bar {
+    -webkit-border-image: url(Images/timelinePillYellow.png) 6 7 6 7;
+    border-image: url(Images/timelinePillYellow.png) 6 7 6 7;
+}
+
+.resources-category-xhr.resource-cached .resources-graph-bar {
+    -webkit-border-image: url(Images/timelineHollowPillYellow.png) 6 7 6 7;
+    border-image: url(Images/timelineHollowPillYellow.png) 6 7 6 7;
+}
+
+/* FIXME: Create bar images for WebSocket. */
+.resources-category-websockets .resources-graph-bar {
+    -webkit-border-image: url(Images/timelinePillGray.png) 6 7 6 7;
+    border-image: url(Images/timelinePillGray.png) 6 7 6 7;
+}
+
+.resources-category-websockets.resource-cached .resources-graph-bar {
+    -webkit-border-image: url(Images/timelineHollowPillGray.png) 6 7 6 7;
+    border-image: url(Images/timelineHollowPillGray.png) 6 7 6 7;
+}
+
+#resource-views {
+    position: absolute;
+    top: 23px;
+    right: 0;
+    left: 200px;
+    bottom: 0;
+}
+
+.source-view-frame {
+    width: 100%;
+    height: 100%;
+}
+
+.sidebar-resizer-vertical {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    width: 5px;
+    z-index: 500;
+    cursor: col-resize;
+}
+
+.resources .sidebar-resizer-vertical {
+    top: 23px;
+}
+
+.sidebar-tree, .sidebar-tree .children {
+    position: relative;
+    padding: 0;
+    margin: 0;
+    list-style: none;
+    font-size: 11px;
+}
+
+.sidebar-tree-section {
+    position: relative;
+    height: 18px;
+    padding: 4px 10px 6px 10px;
+    white-space: nowrap;
+    margin-top: 1px;
+    color: rgb(92, 110, 129);
+    font-weight: bold;
+    text-shadow: rgba(255, 255, 255, 0.75) 0 1px 0;
+}
+
+.sidebar-tree-item {
+    position: relative;
+    height: 36px;
+    padding: 0 5px 0 5px;
+    white-space: nowrap;
+    margin-top: 1px;
+    line-height: 34px;
+    border-top: 1px solid transparent;
+}
+
+.sidebar-tree .children {
+    display: none;
+}
+
+.sidebar-tree .children.expanded {
+    display: block;
+}
+
+.sidebar-tree-section + .children > .sidebar-tree-item {
+    padding-left: 10px !important;
+}
+
+.sidebar-tree-section + .children.small > .sidebar-tree-item {
+    padding-left: 17px !important;
+}
+
+.sidebar-tree > .children > .sidebar-tree-item {
+    padding-left: 37px;
+}
+
+.sidebar-tree > .children > .children > .sidebar-tree-item {
+    padding-left: 37px;
+}
+
+.sidebar-tree.hide-disclosure-buttons > .children {
+    display: none;
+}
+
+.sidebar-tree > .children.hide-disclosure-buttons > .children {
+    display: none;
+}
+
+.sidebar-tree.some-expandable:not(.hide-disclosure-buttons) > .sidebar-tree-item:not(.parent) .icon {
+    margin-left: 16px;
+}
+
+.sidebar-tree-item .disclosure-button {
+    float: left;
+    width: 16px;
+    height: 100%;
+    border: 0;
+    background-color: transparent;
+    background-image: url(Images/disclosureTriangleSmallRight.png);
+    background-repeat: no-repeat;
+    background-position: center;
+    -webkit-apearance: none;
+    -moz-apearance: none;
+}
+
+.sidebar-tree.hide-disclosure-buttons .sidebar-tree-item .disclosure-button {
+    display: none;
+}
+
+body.inactive .sidebar-tree-item .disclosure-button {
+    background-image: url(Images/disclosureTriangleSmallRightBlack.png);
+}
+
+body.inactive .sidebar-tree-item.expanded .disclosure-button {
+    background-image: url(Images/disclosureTriangleSmallDownBlack.png);
+}
+
+body.inactive .sidebar-tree-item .disclosure-button:active {
+    background-image: url(Images/disclosureTriangleSmallRightDownBlack.png);
+}
+
+.sidebar-tree-item.selected .disclosure-button {
+    background-image: url(Images/disclosureTriangleSmallRightWhite.png) !important;
+}
+
+.sidebar-tree-item.expanded .disclosure-button {
+    background-image: url(Images/disclosureTriangleSmallDown.png);
+}
+
+.sidebar-tree-item.selected.expanded .disclosure-button {
+    background-image: url(Images/disclosureTriangleSmallDownWhite.png) !important;
+}
+
+.sidebar-tree-item.selected .disclosure-button:active {
+    background-image: url(Images/disclosureTriangleSmallRightDownWhite.png) !important;
+}
+
+.sidebar-tree-item .disclosure-button:active {
+    background-image: url(Images/disclosureTriangleSmallRightDown.png);
+}
+
+.sidebar-tree-item .icon {
+    float: left;
+    width: 32px;
+    height: 32px;
+    margin-top: 1px;
+    margin-right: 3px;
+}
+
+li .status {
+    float: right;
+    height: 16px;
+    margin-top: 9px;
+    margin-left: 4px;
+    line-height: 1em;
+}
+
+li .status:empty {
+    display: none;
+}
+
+li .status .bubble {
+    display: inline-block;
+    height: 14px;
+    min-width: 16px;
+    margin-top: 1px;
+    background-color: rgb(128, 151, 189);
+    vertical-align: middle;
+    white-space: nowrap;
+    padding: 1px 4px;
+    text-align: center;
+    font-size: 11px;
+    line-height: normal;
+    font-family: Helvetica, Arial, sans-serif;
+    font-weight: bold;
+    text-shadow: none;
+    color: white;
+    -webkit-border-radius: 7px;
+    border-radius: 7px;
+}
+
+li .status .bubble:empty {
+    display: none;
+}
+
+li.selected .status .bubble {
+    background-color: white !important;
+    color: rgb(132, 154, 190) !important;
+}
+
+:focus li.selected .status .bubble {
+    color: rgb(36, 98, 172) !important;
+}
+
+body.inactive li.selected .status .bubble {
+    color: rgb(159, 159, 159) !important;
+}
+
+.sidebar-tree.small .sidebar-tree-item, .sidebar-tree .children.small .sidebar-tree-item, .sidebar-tree-item.small, .small .resources-graph-side {
+    height: 20px;
+}
+
+.sidebar-tree.small .sidebar-tree-item .icon, .sidebar-tree .children.small .sidebar-tree-item .icon, .sidebar-tree-item.small .icon {
+    width: 16px;
+    height: 16px;
+}
+
+.sidebar-tree.small .sidebar-tree-item .status, .sidebar-tree .children.small .sidebar-tree-item .status, .sidebar-tree-item.small .status {
+    margin-top: 1px;
+}
+
+.sidebar-tree-item.selected {
+    color: white;
+    border-top: 1px solid rgb(145, 160, 192);
+    background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(162, 177, 207)), to(rgb(120, 138, 177)));
+    background-image: linear-gradient(to bottom, rgb(162, 177, 207) 0%, rgb(120, 138, 177) 100%);
+    text-shadow: rgba(0, 0, 0, 0.33) 0 1px 0;
+    font-weight: bold;
+    -webkit-background-origin: padding;
+    -webkit-background-clip: padding;
+    background-origin: padding;
+    background-clip: padding;
+}
+
+:focus .sidebar-tree-item.selected {
+    border-top: 1px solid rgb(68, 128, 200);
+    background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(92, 147, 213)), to(rgb(21, 83, 170)));
+    background-image: linear-gradient(to bottom, rgb(92, 147, 213) 0%, rgb(21, 83, 170) 100%);
+}
+
+body.inactive .sidebar-tree-item.selected {
+    border-top: 1px solid rgb(151, 151, 151);
+    background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(180, 180, 180)), to(rgb(138, 138, 138)));
+    background-image: linear-gradient(to bottom, rgb(180, 180, 180) 0%, rgb(138, 138, 138) 100%);
+}
+
+.sidebar-tree-item .titles {
+    position: relative;
+    top: 5px;
+    line-height: 11px;
+    padding-bottom: 1px;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    white-space: nowrap;
+}
+
+.sidebar-tree-item .titles.no-subtitle {
+    top: 10px;
+}
+
+.sidebar-tree.small .sidebar-tree-item .titles, .sidebar-tree .children.small .sidebar-tree-item .titles, .sidebar-tree-item.small .titles {
+    top: 2px;
+    line-height: normal;
+}
+
+.sidebar-tree:not(.small) .sidebar-tree-item:not(.small) .title::after, .sidebar-tree .children:not(.small) .sidebar-tree-item .title::after {
+    content: "\A";
+    white-space: pre;
+}
+
+.sidebar-tree-item .subtitle {
+    font-size: 9px;
+    color: rgba(0, 0, 0, 0.7);
+}
+
+.sidebar-tree.small .sidebar-tree-item .subtitle, .sidebar-tree .children.small .sidebar-tree-item .subtitle, .sidebar-tree-item.small .subtitle {
+    display: none;
+}
+
+.sidebar-tree-item.selected .subtitle {
+    color: rgba(255, 255, 255, 0.9);
+}
+
+#resources-graphs {
+    position: absolute;
+    left: 0;
+    right: 0;
+    max-height: 100%;
+    top: 112px;
+}
+
+.resources-graph-side {
+    position: relative;
+    height: 36px;
+    padding: 0 5px;
+    white-space: nowrap;
+    margin-top: 1px;
+    border-top: 1px solid transparent;
+    overflow: hidden;
+}
+
+.resources-graph-bar-area {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    right: 8px;
+    left: 9px;
+}
+
+#resources-container:not(.viewing-resource) .resource-sidebar-tree-item:nth-of-type(2n) {
+    background-color: rgba(0, 0, 0, 0.05);
+}
+
+#resources-container:not(.viewing-resource) .resources-graph-side:nth-of-type(2n) {
+    background-color: rgba(0, 0, 0, 0.05);
+}
+
+.resources-time-graph-sidebar-item .icon {
+    content: url(Images/resourcesTimeGraphIcon.png);
+}
+
+.resources-size-graph-sidebar-item .icon {
+    content: url(Images/resourcesSizeGraphIcon.png);
+}
+
+.resources-size-graph-sidebar-item .icon {
+    content: url(Images/resourcesSizeGraphIcon.png);
+}
+
+.resource-sidebar-tree-item .icon {
+    content: url(Images/resourcePlainIcon.png);
+}
+
+.children.small .resource-sidebar-tree-item .icon {
+    content: url(Images/resourcePlainIconSmall.png);
+}
+
+.resource-sidebar-tree-item.resources-category-documents .icon {
+    content: url(Images/resourceDocumentIcon.png);
+}
+
+.children.small .resource-sidebar-tree-item.resources-category-documents .icon {
+    content: url(Images/resourceDocumentIconSmall.png);
+}
+
+.resource-sidebar-tree-item.resources-category-stylesheets .icon {
+    content: url(Images/resourceCSSIcon.png);
+}
+
+.children.small .resource-sidebar-tree-item.resources-category-stylesheets .icon {
+    content: url(Images/resourceDocumentIconSmall.png);
+}
+
+.resource-sidebar-tree-item.resources-category-images .icon {
+    position: relative;
+    background-image: url(Images/resourcePlainIcon.png);
+    background-repeat: no-repeat;
+    content: "";
+}
+
+.resources-category-images .image-resource-icon-preview {
+    position: absolute;
+    margin: auto;
+    top: 3px;
+    bottom: 4px;
+    left: 5px;
+    right: 5px;
+    max-width: 18px;
+    max-height: 21px;
+    min-width: 1px;
+    min-height: 1px;
+}
+
+.children.small .resource-sidebar-tree-item.resources-category-images .icon {
+    background-image: url(Images/resourcePlainIconSmall.png);
+    content: "";
+}
+
+.children.small .resources-category-images .image-resource-icon-preview {
+    top: 2px;
+    bottom: 1px;
+    left: 3px;
+    right: 3px;
+    max-width: 8px;
+    max-height: 11px;
+}
+
+.resource-sidebar-tree-item.resources-category-fonts .icon {
+    content: url(Images/resourcePlainIcon.png);
+}
+
+.children.small .resource-sidebar-tree-item.resources-category-fonts .icon {
+    content: url(Images/resourcePlainIconSmall.png);
+}
+
+.resource-sidebar-tree-item.resources-category-scripts .icon {
+    content: url(Images/resourceJSIcon.png);
+}
+
+.children.small .resource-sidebar-tree-item.resources-category-scripts .icon {
+    content: url(Images/resourceDocumentIconSmall.png);
+}
+
+.resource-sidebar-tree-item.resources-category-xhr .icon {
+    content: url(Images/resourcePlainIcon.png);
+}
+
+.children.small .resource-sidebar-tree-item.resources-category-xhr .icon {
+    content: url(Images/resourceDocumentIconSmall.png);
+}
+
+.bubble.debug, .console-debug-level .bubble {
+    background-color: rgb(0, 0, 255) !important;
+}
+
+.bubble.warning, .console-warning-level .bubble {
+    background-color: rgb(232, 164, 0) !important;
+}
+
+.bubble.error, .console-error-level .bubble {
+    background-color: rgb(216, 35, 35) !important;
+}
+
+.bubble.search-matches {
+    background-image: url(Images/searchSmallWhite.png);
+    background-repeat: no-repeat;
+    background-position: 3px 2px;
+    padding-left: 13px !important;
+}
+
+li.selected .bubble.search-matches {
+    background-image: url(Images/searchSmallBlue.png);
+}
+
+:focus li.selected .bubble.search-matches {
+    background-image: url(Images/searchSmallBrightBlue.png);
+}
+
+body.inactive li.selected .bubble.search-matches {
+    background-image: url(Images/searchSmallGray.png);
+}
+
+/* Timeline Style */
+
+#timeline-overview-panel {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    height: 80px;
+}
+
+#timeline-overview-panel .timeline-graph-bar {
+    pointer-events: none;
+}
+
+.timeline-sidebar-background {
+    top: 90px;
+    bottom: 0;
+}
+
+.timeline .sidebar {
+    overflow-y: hidden;
+    z-index: 100;
+    min-height: 100%;
+    bottom: auto;
+}
+
+#timeline-overview-separator {
+    position: absolute;
+    top: 80px;
+    left: 0;
+    right: 0;
+    background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(253, 253, 253)), to(rgb(213, 213, 213)));
+    background-image: linear-gradient(to bottom, rgb(253, 253, 253) 0%, rgb(213, 213, 213) 100%);
+    border-top: 1px solid rgb(140, 140, 140);
+    border-bottom: 1px solid rgb(115, 115, 115);
+    height: 10px;
+}
+
+#timeline-overview-sidebar {
+    position: absolute;
+    width: 200px;
+    top: 0px;
+    bottom: 0px;
+    left: 0px;
+    padding-top: 2px;
+    background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(242, 242, 242)), to(rgb(209, 209, 209)));
+    background-image: linear-gradient(to bottom, rgb(242, 242, 242) 0%, rgb(209, 209, 209) 100%);
+    border-right: 1px solid rgb(163, 163, 163);
+}
+
+#timeline-overview-grid {
+    position: absolute;
+    top: 0px;
+    bottom: 0px;
+    left: 200px;
+    right: 0px;
+    background-color: rgb(255, 255, 255);
+}
+
+.timeline-window-selector {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    background-color: rgba(125, 173, 217, 0.5);
+    z-index: 250;
+}
+
+#timeline-overview-window {
+    background-color: white;
+    position: absolute;
+    left: 0;
+    right: 0;
+    top: 0;
+    bottom: 60px;
+    z-index: 150;
+}
+
+.timeline-overview-dividers-background {
+    left: 0%;
+    right: 0%;
+    top: 0px;
+    bottom: 60px;
+    background-color: black;
+    position: absolute;
+}
+
+.timeline-overview-window-rulers {
+    top: 0;
+    bottom: 0;
+    position: absolute;
+    opacity: 0.2;
+    border-right: 1px solid black;
+    border-left: 1px solid black;
+    z-index: 150;
+}
+
+.timeline-window-resizer {
+    position: absolute;
+    top: 0px;
+    bottom: 60px;
+    width: 5px;
+    margin-left: -3px;
+    margin-right: -2px;
+    background-color: rgb(153, 153, 153);
+    z-index: 500;
+    cursor: col-resize;
+    -webkit-border-radius: 2px;
+    border-radius: 2px;
+    -webkit-box-shadow: white 1px 0 0, white -1px 0 0, white 0 1px 0, white 0 -1px 0;
+    box-shadow: white 1px 0 0, white -1px 0 0, white 0 1px 0, white 0 -1px 0;
+}
+
+#timeline-overview-grid #resources-graphs {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    height: 80px;
+}
+
+#timeline-container {
+    position: absolute;
+    top: 90px;
+    left: 0;
+    bottom: 0;
+    right: 0;
+    border-right: 0 none transparent;
+    overflow-y: auto;
+    overflow-x: hidden;
+}
+
+.timeline-category-statusbar-item {
+    height: 24px;
+    line-height: 24px;
+    padding-left: 6px;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    font-weight: bold;
+}
+
+.timeline-category-statusbar-item .timeline-category-checkbox {
+    width: 10px;
+    height: 11px;
+    margin: 0 3px 0 5px;
+    padding: 0;
+    background-image: url(Images/timelineCheckmarks.png);
+    background-repeat: no-repeat;
+    background-position: 0 -66px;
+    vertical-align: -1px;
+    -webkit-appearance: none;
+    -moz-appearance: none;
+}
+
+.timeline-category-statusbar-item .timeline-category-checkbox:checked {
+    background-position-x: -10px;
+}
+
+.timeline-category-statusbar-item.timeline-category-loading .timeline-category-checkbox {
+    background-position-y: 0;
+}
+
+.timeline-category-statusbar-item.timeline-category-scripting .timeline-category-checkbox {
+    background-position-y: -33px;
+}
+
+.timeline-category-statusbar-item.timeline-category-rendering .timeline-category-checkbox {
+    background-position-y: -11px;
+}
+
+.timeline-tree-item {
+    height: 18px;
+    line-height: 15px;
+    padding-right: 5px;
+    padding-left: 10px;
+    padding-top: 2px;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    overflow: hidden;
+}
+
+.timeline-expandable {
+    position: absolute;
+    border-left: 1px solid rgb(163, 163, 163);
+}
+
+.timeline-expandable-left {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    width: 3px;
+    border-top: 1px solid rgb(163, 163, 163);
+    border-bottom: 1px solid rgb(163, 163, 163);
+}
+
+.timeline-expandable-collapsed {
+    background-image: url(Images/disclosureTriangleSmallRightBlack.png);
+    background-position-x: 1px;
+    background-position-y: 2px;
+    background-repeat: no-repeat;
+}
+
+.timeline-expandable-expanded {
+    background-image: url(Images/disclosureTriangleSmallDownBlack.png);
+    background-position-x: 1px;
+    background-position-y: 3px;
+    background-repeat: no-repeat;
+}
+
+.timeline-tree-item .type {
+    padding-left: 14px;
+}
+
+.timeline-tree-item .count {
+    font-family: Helvetica, Arial, sans-serif;
+    font-weight: bold;
+}
+
+.timeline-tree-item .timeline-tree-icon {
+    background-image: url(Images/timelineDots.png);
+    margin-top: 2px;
+    width: 12px;
+    height: 12px;
+    position: absolute;
+}
+
+.timeline-tree-item.even {
+    background-color: rgba(0, 0, 0, 0.05);
+}
+
+.timeline-tree-item .data.dimmed {
+    color: rgba(0, 0, 0, 0.7);
+}
+
+#timeline-overview-timelines,
+#timeline-overview-memory {
+    position: absolute;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    top: 20px;
+    z-index: 160;
+}
+
+#timeline-overview-memory > canvas {
+    position: absolute;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    top: 5px;
+}
+
+
+#timeline-graphs {
+    position: absolute;
+    left: 0;
+    right: 0;
+    max-height: 100%;
+    top: 19px;
+}
+
+.timeline-graph-side {
+    position: relative;
+    height: 18px;
+    padding: 0 5px;
+    white-space: nowrap;
+    margin-top: 0px;
+    border-top: 1px solid transparent;
+    overflow: hidden;
+    pointer-events: none;
+}
+
+.timeline-overview-graph-side {
+    height: 20px;
+    z-index: 170;
+    pointer-events: none;
+}
+
+.timeline-overview-graph-side .timeline-graph-bar {
+    height: 13px;
+}
+
+.timeline-graph-bar-area {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    right: 0;
+    left: 3px;
+    pointer-events: none;
+}
+
+.timeline-graph-bar {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    margin: auto -2px;
+    border-width: 4px 4px 5px;
+    height: 9px;
+    min-width: 5px;
+    opacity: 0.8;
+    -webkit-border-image: url(Images/timelineBarGray.png) 4 4 5 4;
+    border-image: url(Images/timelineBarGray.png) 4 4 5 4;
+    z-index: 180;
+    pointer-events: visibleFill;
+}
+
+.timeline-graph-bar.with-children {
+    opacity: 0.2;
+}
+
+.timeline-graph-bar.cpu {
+    opacity: 0.6;
+}
+
+.timeline-graph-side.even {
+    background-color: rgba(0, 0, 0, 0.05);
+}
+
+.timeline-category-loading .timeline-graph-bar {
+    -webkit-border-image: url(Images/timelineBarBlue.png) 4 4 5 4;
+    border-image: url(Images/timelineBarBlue.png) 4 4 5 4;
+}
+
+.timeline-category-scripting .timeline-graph-bar {
+    -webkit-border-image: url(Images/timelineBarOrange.png) 4 4 5 4;
+    border-image: url(Images/timelineBarOrange.png) 4 4 5 4;
+}
+
+.timeline-category-rendering .timeline-graph-bar {
+    -webkit-border-image: url(Images/timelineBarPurple.png) 4 4 5 4;
+    border-image: url(Images/timelineBarPurple.png) 4 4 5 4;
+}
+
+.timeline-aggregated-category {
+    display: inline-block;
+    height: 11px;
+    margin-right: 2px;
+    margin-left: 6px;
+    position: relative;
+    top: 2px;
+    width: 10px;
+}
+
+.timeline-loading {
+    -webkit-border-image: url(Images/timelineBarBlue.png) 4 4 5 4;
+    border-image: url(Images/timelineBarBlue.png) 4 4 5 4;
+}
+
+.timeline-scripting {
+    -webkit-border-image: url(Images/timelineBarOrange.png) 4 4 5 4;
+    border-image: url(Images/timelineBarOrange.png) 4 4 5 4;
+}
+
+.timeline-rendering {
+    -webkit-border-image: url(Images/timelineBarPurple.png) 4 4 5 4;
+    border-image: url(Images/timelineBarPurple.png) 4 4 5 4;
+}
+
+.popover .timeline-aggregated-category.timeline-loading {
+    margin-left: 0px;
+}
+
+.timeline-category-loading .timeline-tree-icon {
+    background-position-y: 0px;
+}
+
+.timeline-category-scripting .timeline-tree-icon {
+    background-position-y: 48px;
+}
+
+.timeline-category-rendering .timeline-tree-icon {
+    background-position-y: 72px;
+}
+
+.timeline-details {
+    -webkit-user-select: text;
+    -ms-user-select: text;
+    -moz-user-select: text;
+    vertical-align: top;
+}
+
+.timeline-function-name {
+    text-align: right;
+}
+
+.timeline-stacktrace-title {
+    padding-top: 4px;
+}
+
+.timeline-details-row-title {
+    font-weight: bold;
+    text-align: right;
+    white-space: nowrap;
+}
+
+.timeline-details-row-data {
+    white-space: nowrap;
+}
+
+.timeline-details-title {
+    border-bottom: 1px solid #B8B8B8;
+    font-size: 11px;
+    font-weight: bold;
+    padding-bottom: 5px;
+    padding-top: 0px;
+    white-space: nowrap;
+}
+
+.timeline-filter-status-bar-item .glyph {
+    -webkit-mask-image: url(Images/largerResourcesButtonGlyph.png);
+}
+
+.timeline-filter-status-bar-item.toggled-on .glyph {
+    background-color: rgb(66, 129, 235) !important;
+}
+
+.timeline-records-counter, .storage-application-cache-status, .storage-application-cache-connectivity {
+    font-size: 11px;
+    text-shadow: white 0 1px 0;
+}
+
+#main-status-bar > .timeline-records-counter {
+    float: right;
+    margin-top: 4px;
+    margin-right: 25px;
+}
+
+#counters > .timeline-records-counter {
+    float: left;
+    margin-top: -2px;
+}
+
+.storage-application-cache-status-icon, .storage-application-cache-connectivity-icon {
+    margin-bottom: -3px;
+    margin-left: 5px;
+    vertical-align: middle;
+}
+
+.status-bar-divider {
+    margin-left: 7px;
+    border-right: 1px solid #CCC;
+}
+
+.storage-application-cache-status, .storage-application-cache-connectivity {
+    position: relative;
+    top: 4px;
+}
+
+/* Profiler Style */
+
+#profile-views {
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 200px;
+    bottom: 0;
+}
+
+.status-bar-items {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    left: 200px;
+    overflow: hidden;
+    border-left: 1px solid rgb(184, 184, 184);
+    margin-left: -1px;
+}
+
+.profile-sidebar-tree-item .icon {
+    content: url(Images/profileIcon.png);
+}
+
+.profile-sidebar-tree-item.small .icon {
+    content: url(Images/profileSmallIcon.png);
+}
+
+.profile-group-sidebar-tree-item .icon {
+    content: url(Images/profileGroupIcon.png);
+}
+
+.profile-view {
+    display: none;
+    overflow: hidden;
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+}
+
+.profile-view.visible {
+    display: block;
+}
+
+.profile-view .data-grid {
+    border: none;
+    height: 100%;
+}
+
+.profile-view .data-grid th.average-column {
+    text-align: center;
+}
+
+.profile-view .data-grid td.average-column {
+    text-align: right;
+}
+
+.profile-view .data-grid th.self-column {
+    text-align: center;
+}
+
+.profile-view .data-grid td.self-column {
+    text-align: right;
+}
+
+.profile-view .data-grid th.total-column {
+    text-align: center;
+}
+
+.profile-view .data-grid td.total-column {
+    text-align: right;
+}
+
+.profile-view .data-grid .calls-column {
+    text-align: center;
+}
+
+.profile-node-file {
+    float: right;
+    color: gray;
+    margin-top: -1px;
+}
+
+.data-grid tr.selected .profile-node-file {
+    color: rgb(33%, 33%, 33%);
+}
+
+.data-grid:focus tr.selected .profile-node-file {
+    color: white;
+}
+
+button.enable-toggle-status-bar-item .glyph {
+}
+
+.record-profile-status-bar-item .glyph {
+    -webkit-mask-image: url(Images/recordButtonGlyph.png);
+}
+
+.record-profile-status-bar-item.toggled-on .glyph {
+    -webkit-mask-image: url(Images/recordToggledButtonGlyph.png);
+    background-color: rgb(216, 0, 0) !important;
+}
+
+/* FIXME: should have its own glyph. */
+.heap-snapshot-status-bar-item .glyph {
+    -webkit-mask-image: url(Images/focusButtonGlyph.png);
+}
+
+.node-search-status-bar-item .glyph {
+    -webkit-mask-image: url(Images/nodeSearchButtonGlyph.png);
+}
+
+.percent-time-status-bar-item .glyph {
+    -webkit-mask-image: url(Images/percentButtonGlyph.png);
+}
+
+.focus-profile-node-status-bar-item .glyph {
+    -webkit-mask-image: url(Images/focusButtonGlyph.png);
+}
+
+.exclude-profile-node-status-bar-item .glyph {
+    -webkit-mask-image: url(Images/excludeButtonGlyph.png);
+}
+
+.reset-profile-status-bar-item .glyph {
+    -webkit-mask-image: url(Images/reloadButtonGlyph.png);
+}
+
+.delete-storage-status-bar-item .glyph {
+    -webkit-mask-image: url(Images/excludeButtonGlyph.png);
+}
+
+.refresh-storage-status-bar-item .glyph {
+    -webkit-mask-image: url(Images/reloadButtonGlyph.png);
+}
+
+ol.breakpoint-list {
+    -webkit-padding-start: 0;
+    -moz-padding-start: 0;
+    list-style: none;
+    margin: 0;
+}
+
+.breakpoint-list li {
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    padding: 2px 0;
+    color: black;
+}
+
+.breakpoint-list li:hover {
+    color: rgb(15%, 15%, 15%);
+}
+
+.breakpoint-list .checkbox-elem {
+    font-size: 10px;
+    margin: 0 4px;
+    vertical-align: top;
+    position: relative;
+    z-index: 1;
+}
+
+.breakpoint-list .source-text {
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    margin: 2px 0 0px 20px;
+}
+
+.pane .breakpoint-hit {
+    background-color: rgb(255, 255, 194);
+}
+
+li.breakpoint-hit .breakpoint-hit-marker {
+    background-color: rgb(255, 255, 194);
+    height: 18px;
+    left: 0px;
+    margin-top: -16px;
+    position: absolute;
+    right: 0px;
+    z-index: -1;
+}
+
+.webkit-html-js-node, .webkit-html-css-node {
+    white-space: pre;
+}
+
+.source-frame-breakpoint-condition {
+    z-index: 30;
+    padding: 4px;
+    background-color: rgb(203, 226, 255);
+    -webkit-border-radius: 7px;
+    border-radius: 7px;
+    border: 2px solid rgb(169, 172, 203);
+    width: 90%;
+}
+
+.source-frame-breakpoint-message {
+    background-color: transparent;
+    font-family: Lucida Grande, sans-serif;
+    font-weight: normal;
+    font-size: 11px;
+    text-align: left;
+    text-shadow: none;
+    color: rgb(85, 85, 85);
+    cursor: default;
+    margin: 0 0 2px 0;
+}
+
+#source-frame-breakpoint-condition {
+    margin: 0;
+    border: 1px inset rgb(190, 190, 190) !important;
+    width: 100%;
+    box-shadow: none !important;
+    outline: none !important;
+    -webkit-user-modify: read-write;
+    -moz-user-modify: read-write;
+}
+
+.source-frame-popover-title {
+    text-overflow: ellipsis;
+    overflow: hidden;
+    white-space: nowrap;
+    font-weight: bold;
+    padding-left: 18px;
+}
+
+.source-frame-popover-tree {
+    border-top: 1px solid rgb(194, 194, 147);
+    overflow: auto;
+    position: absolute;
+    top: 15px;
+    bottom: 0;
+    left: 0;
+    right: 0;
+}
+
+.source-frame-eval-expression {
+    border: 1px solid rgb(163, 41, 34);
+    margin: -1px;
+    background-color: rgb(255, 255, 194);
+}
+
+.styles-sidebar-separator {
+    background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(243, 243, 243)), color-stop(0.05, rgb(243, 243, 243)), color-stop(0.05, rgb(230, 230, 230)), to(rgb(209, 209, 209)));
+    background-image: linear-gradient(to bottom, rgb(243, 243, 243) 0%,rgb(243, 243 ,243) 10%, rgb(230, 230, 230) 40%, rgb(209, 209, 209) 100%);
+    padding: 0 5px;
+    border-top: 1px solid rgb(189, 189, 189);
+    border-bottom: 1px solid rgb(189, 189, 189);
+    color: rgb(110, 110, 110);
+    text-shadow: white 0 1px 0;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    font-size: 11px;
+}
+
+.styles-selector {
+    cursor: text;
+}
+
+.workers-list {
+    list-style: none;
+    margin: 0;
+    padding: 0;
+}
+
+.workers-list > li {
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    margin-left: 1em;
+    font-size: 12px;
+}
+
+a.worker-item {
+    color: rgb(33%, 33%, 33%);
+    cursor: pointer;
+    text-decoration: none;
+}
+
+.styles-section {
+    padding: 2px 2px 4px 4px;
+    min-height: 18px;
+    white-space: nowrap;
+    -webkit-background-origin: padding;
+    -webkit-background-clip: padding;
+    background-origin: padding;
+    background-clip: padding;
+    -webkit-user-select: text;
+    -ms-user-select: text;
+    -moz-user-select: text;
+}
+
+.styles-section:not(.first-styles-section) {
+    border-top: 1px solid rgb(191, 191, 191);
+}
+
+.styles-section.read-only {
+    background-color: rgb(240, 240, 240);
+}
+
+.styles-section .properties li.not-parsed-ok {
+    margin-left: 0px;
+}
+
+.styles-section .properties li.not-parsed-ok::before {
+    content: url(Images/warningIcon.png);
+    opacity: 0.75;
+    float: left;
+    width: 8px;
+    height: 8px;
+    margin-top: 0;
+    padding-right: 5px;
+    vertical-align: sub;
+    -webkit-user-select: none;
+    -ms-user-select: none;
+    -moz-user-select: none;
+    cursor: default;
+}
+
+.styles-section .header {
+    white-space: nowrap;
+    -webkit-background-origin: padding;
+    -webkit-background-clip: padding;
+    background-origin: padding;
+    background-clip: padding;
+}
+
+.styles-section .header .title {
+    word-wrap: break-word;
+    white-space: normal;
+}
+
+.styles-section .header .subtitle {
+    color: rgb(85, 85, 85);
+    float: right;
+    margin-left: 5px;
+    max-width: 65%;
+    text-overflow: ellipsis;
+    overflow: hidden;
+}
+
+.styles-section .header .subtitle a {
+    color: inherit;
+}
+
+.styles-section a::before {
+    content: attr(data-uncopyable);
+}
+
+.styles-section .properties {
+    display: none;
+    margin: 0;
+    padding: 2px 4px 0 8px;
+    list-style: none;
+}
+
+.styles-section.no-affect .properties li {
+    opacity: 0.5;
+}
+
+.styles-section.no-affect .properties li.editing {
+    opacity: 1.0;
+}
+
+.styles-section.expanded .properties {
+    display: block;
+}
+
+.styles-section .properties li {
+    margin-left: 12px;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    cursor: auto;
+}
+
+.styles-section .properties li.parent {
+    margin-left: 1px;
+}
+
+.styles-section .properties ol {
+    display: none;
+    margin: 0;
+    -webkit-padding-start: 12px;
+    -moz-padding-start: 12px;
+    list-style: none;
+}
+
+.styles-section .properties ol.expanded {
+    display: block;
+}
+
+.styles-section .properties li.parent::before {
+    content: url(Images/treeRightTriangleBlack.png);
+    opacity: 0.75;
+    float: left;
+    width: 8px;
+    height: 8px;
+    margin-top: 0;
+    padding-right: 3px;
+    -webkit-user-select: none;
+    -ms-user-select: none;
+    -moz-user-select: none;
+    cursor: default;
+}
+
+.styles-section .properties li.parent.expanded::before {
+    content: url(Images/treeDownTriangleBlack.png);
+    margin-top: 1px;
+}
+
+.styles-section .properties li .info {
+    padding-top: 4px;
+    padding-bottom: 3px;
+}
+
+.styles-section:hover .properties .enabled-button {
+    display: block;
+}
+
+.styles-section .properties li.disabled .enabled-button {
+    display: block;
+}
+
+.styles-section .properties .enabled-button {
+    display: none;
+    float: right;
+    font-size: 10px;
+    margin: 0 0 0 4px;
+    vertical-align: top;
+    position: relative;
+    z-index: 1;
+    /*Removes checkbox padding that is set in IE by default*/
+    padding: 0;
+}
+
+.styles-section .properties .overloaded, .styles-section .properties .inactive, .styles-section .properties .disabled {
+    text-decoration: line-through;
+}
+
+.styles-section.computed-style .properties .disabled {
+    text-decoration: none;
+    opacity: 0.5;
+}
+
+.styles-section .properties .implicit, .styles-section .properties .inherited {
+    opacity: 0.5;
+}
+
+
+.body .styles-section .properties .inherited {
+    display: none;
+}
+
+.body.show-inherited .styles-section .properties .inherited {
+    display: block;
+}
+
+a.worker-item:hover {
+    color: rgb(15%, 15%, 15%);
+}
+
+.resource-content-unavailable {
+    color: rgb(50%, 50%, 50%);
+    font-style: italic;
+    font-size: 14px;
+    text-align: center;
+    padding: 32px;
+}
+
+.node-link {
+    text-decoration: underline;
+    cursor: pointer;
+}
+
+.cursor-pointer {
+    cursor: pointer;
+}
+
+.cursor-auto {
+    cursor: auto;
+}
+
+.please-wait-msg {
+    position: absolute;
+    left: 0;
+    top: 0;
+    border: 4px black solid;
+    border-radius: 4px;
+    background-color: black;
+    opacity: 0.85;
+    color: white;
+    font-size: 12px;
+    font-weight: bold;
+    z-index: 10000;
+}
\ No newline at end of file
diff --git a/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/inspector.js b/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/inspector.js
new file mode 100644
index 0000000..9707cb3
--- /dev/null
+++ b/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/inspector.js
@@ -0,0 +1,1936 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
+ * Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com).
+ * Copyright (C) 2009 Joseph Pecoraro
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Keep this ; so that concatenated version of the script worked.
+;(function preloadImages()
+{
+    (new Image()).src = "Images/clearConsoleButtonGlyph.png";
+    (new Image()).src = "Images/consoleButtonGlyph.png";
+    (new Image()).src = "Images/dockButtonGlyph.png";
+    (new Image()).src = "Images/enableOutlineButtonGlyph.png";
+    (new Image()).src = "Images/enableSolidButtonGlyph.png";
+    (new Image()).src = "Images/excludeButtonGlyph.png";
+    (new Image()).src = "Images/focusButtonGlyph.png";
+    (new Image()).src = "Images/largerResourcesButtonGlyph.png";
+    (new Image()).src = "Images/nodeSearchButtonGlyph.png";
+    (new Image()).src = "Images/pauseOnExceptionButtonGlyph.png";
+    (new Image()).src = "Images/percentButtonGlyph.png";
+    (new Image()).src = "Images/recordButtonGlyph.png";
+    (new Image()).src = "Images/recordToggledButtonGlyph.png";
+    (new Image()).src = "Images/reloadButtonGlyph.png";
+    (new Image()).src = "Images/undockButtonGlyph.png";
+})();
+
+var WebInspector = {
+    resources: {},
+    missingLocalizedStrings: {},
+    pendingDispatches: 0,
+
+    get platform()
+    {
+        if (!("_platform" in this))
+            this._platform = InspectorFrontendHost.platform();
+
+        return this._platform;
+    },
+
+    get platformFlavor()
+    {
+        if (!("_platformFlavor" in this))
+            this._platformFlavor = this._detectPlatformFlavor();
+
+        return this._platformFlavor;
+    },
+
+    _detectPlatformFlavor: function()
+    {
+        const userAgent = navigator.userAgent;
+
+        if (this.platform === "windows") {
+            var match = userAgent.match(/Windows NT (\d+)\.(?:\d+)/);
+            if (match && match[1] >= 6)
+                return WebInspector.PlatformFlavor.WindowsVista;
+            return null;
+        } else if (this.platform === "mac") {
+            var match = userAgent.match(/Mac OS X\s*(?:(\d+)_(\d+))?/);
+            if (!match || match[1] != 10)
+                return WebInspector.PlatformFlavor.MacSnowLeopard;
+            switch (Number(match[2])) {
+                case 4:
+                    return WebInspector.PlatformFlavor.MacTiger;
+                case 5:
+                    return WebInspector.PlatformFlavor.MacLeopard;
+                case 6:
+                default:
+                    return WebInspector.PlatformFlavor.MacSnowLeopard;
+            }
+        }
+
+        return null;
+    },
+
+    get port()
+    {
+        if (!("_port" in this))
+            this._port = InspectorFrontendHost.port();
+
+        return this._port;
+    },
+
+    get previousFocusElement()
+    {
+        return this._previousFocusElement;
+    },
+
+    get currentFocusElement()
+    {
+        return this._currentFocusElement;
+    },
+
+    set currentFocusElement(x)
+    {
+        if (this._currentFocusElement !== x)
+            this._previousFocusElement = this._currentFocusElement;
+        this._currentFocusElement = x;
+
+        if (this._currentFocusElement && typeof(this._currentFocusElement.focus) === 'function') {
+            this._currentFocusElement.focus();
+
+            // Hack for IE - return if 'select' is in focus; otherwise it will lost the focus after we call addRange.
+            if(this._currentFocusElement.nodeName.toUpperCase() == 'SELECT'){
+                return;
+            }
+
+            // Make a caret selection inside the new element if there isn't a range selection and
+            // there isn't already a caret selection inside.
+            var selection = window.getSelection();
+            if (selection.isCollapsed && !this._currentFocusElement.isInsertionCaretInside()) {
+                var selectionRange = this._currentFocusElement.ownerDocument.createRange();
+                selectionRange.setStart(this._currentFocusElement, 0);
+                selectionRange.setEnd(this._currentFocusElement, 0);
+
+                selection.removeAllRanges();
+                selection.addRange(selectionRange);
+            }
+        } // Hack for IE - do not call blur() for body element; otherwise browser window will become inactive
+        else if (this._previousFocusElement && this._previousFocusElement.nodeName.toUpperCase() != 'BODY')
+            this._previousFocusElement.blur();
+    },
+
+    get currentPanel()
+    {
+        return this._currentPanel;
+    },
+
+    set currentPanel(x)
+    {
+        if (this._currentPanel === x)
+            return;
+
+        if (this._currentPanel)
+            this._currentPanel.hide();
+
+        this._currentPanel = x;
+
+        this.updateSearchLabel();
+
+        if (x) {
+            x.show();
+
+            if (this.currentQuery) {
+                if (x.performSearch) {
+                    function performPanelSearch()
+                    {
+                        this.updateSearchMatchesCount();
+
+                        x.currentQuery = this.currentQuery;
+                        x.performSearch(this.currentQuery);
+                    }
+
+                    // Perform the search on a timeout so the panel switches fast.
+                    setTimeout(performPanelSearch.bind(this), 0);
+                } else {
+                    // Update to show Not found for panels that can't be searched.
+                    this.updateSearchMatchesCount();
+                }
+            }
+        }
+
+        for (var panelName in WebInspector.panels) {
+            if (WebInspector.panels[panelName] === x) {
+                WebInspector.settings.lastActivePanel = panelName;
+                this._panelHistory.setPanel(panelName);
+            }
+        }
+    },
+
+    createDOMBreakpointsSidebarPane: function()
+    {
+        var pane = new WebInspector.NativeBreakpointsSidebarPane(WebInspector.UIString("DOM Breakpoints"));
+        function breakpointAdded(event)
+        {
+            pane.addBreakpointItem(new WebInspector.BreakpointItem(event.data));
+        }
+        WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.DOMBreakpointAdded, breakpointAdded);
+        return pane;
+    },
+
+    createXHRBreakpointsSidebarPane: function()
+    {
+        var pane = new WebInspector.XHRBreakpointsSidebarPane();
+        function breakpointAdded(event)
+        {
+            pane.addBreakpointItem(new WebInspector.BreakpointItem(event.data));
+        }
+        WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.XHRBreakpointAdded, breakpointAdded);
+        return pane;
+    },
+
+    _createPanels: function()
+    {
+        var hiddenPanels = (InspectorFrontendHost.hiddenPanels() || "").split(',');
+        if (hiddenPanels.indexOf("elements") === -1)
+            this.panels.elements = new WebInspector.ElementsPanel();
+        if (hiddenPanels.indexOf("resources") === -1)
+            this.panels.resources = new WebInspector.ResourcesPanel();
+        if (hiddenPanels.indexOf("network") === -1)
+            this.panels.network = new WebInspector.NetworkPanel();
+        if (hiddenPanels.indexOf("scripts") === -1)
+            this.panels.scripts = new WebInspector.ScriptsPanel();
+        if (hiddenPanels.indexOf("timeline") === -1)
+            this.panels.timeline = new WebInspector.TimelinePanel();
+        if (hiddenPanels.indexOf("profiles") === -1) {
+            this.panels.profiles = new WebInspector.ProfilesPanel();
+            this.panels.profiles.registerProfileType(new WebInspector.CPUProfileType());
+            if (Preferences.heapProfilerPresent) {
+                if (!Preferences.detailedHeapProfiles)
+                    this.panels.profiles.registerProfileType(new WebInspector.HeapSnapshotProfileType());
+                else
+                    this.panels.profiles.registerProfileType(new WebInspector.DetailedHeapshotProfileType());
+            }
+        }
+        if (hiddenPanels.indexOf("audits") === -1)
+            this.panels.audits = new WebInspector.AuditsPanel();
+        if (hiddenPanels.indexOf("console") === -1)
+            this.panels.console = new WebInspector.ConsolePanel();
+    },
+
+    get attached()
+    {
+        return this._attached;
+    },
+
+    set attached(x)
+    {
+        if (this._attached === x)
+            return;
+
+        this._attached = x;
+
+        this.updateSearchLabel();
+
+        var dockToggleButton = document.getElementById("dock-status-bar-item");
+        var body = document.body;
+
+        if (x) {
+            body.removeStyleClass("detached");
+            body.addStyleClass("attached");
+            dockToggleButton.title = WebInspector.UIString("Undock into separate window.");
+        } else {
+            body.removeStyleClass("attached");
+            body.addStyleClass("detached");
+            dockToggleButton.title = WebInspector.UIString("Dock to main window.");
+        }
+        if (this.drawer)
+            this.drawer.resize();
+    },
+
+    get errors()
+    {
+        return this._errors || 0;
+    },
+
+    set errors(x)
+    {
+        x = Math.max(x, 0);
+
+        if (this._errors === x)
+            return;
+        this._errors = x;
+        this._updateErrorAndWarningCounts();
+    },
+
+    get warnings()
+    {
+        return this._warnings || 0;
+    },
+
+    set warnings(x)
+    {
+        x = Math.max(x, 0);
+
+        if (this._warnings === x)
+            return;
+        this._warnings = x;
+        this._updateErrorAndWarningCounts();
+    },
+
+    _updateErrorAndWarningCounts: function()
+    {
+        var errorWarningElement = document.getElementById("error-warning-count");
+        if (!errorWarningElement)
+            return;
+
+        if (!this.errors && !this.warnings) {
+            errorWarningElement.addStyleClass("hidden");
+            return;
+        }
+
+        errorWarningElement.removeStyleClass("hidden");
+
+        errorWarningElement.removeChildren();
+
+        if (this.errors) {
+            var errorElement = document.createElement("span");
+            errorElement.id = "error-count";
+            errorElement.textContent = this.errors;
+            errorWarningElement.appendChild(errorElement);
+        }
+
+        if (this.warnings) {
+            var warningsElement = document.createElement("span");
+            warningsElement.id = "warning-count";
+            warningsElement.textContent = this.warnings;
+            errorWarningElement.appendChild(warningsElement);
+        }
+
+        if (this.errors) {
+            if (this.warnings) {
+                if (this.errors == 1) {
+                    if (this.warnings == 1)
+                        errorWarningElement.title = WebInspector.UIString("%d error, %d warning", this.errors, this.warnings);
+                    else
+                        errorWarningElement.title = WebInspector.UIString("%d error, %d warnings", this.errors, this.warnings);
+                } else if (this.warnings == 1)
+                    errorWarningElement.title = WebInspector.UIString("%d errors, %d warning", this.errors, this.warnings);
+                else
+                    errorWarningElement.title = WebInspector.UIString("%d errors, %d warnings", this.errors, this.warnings);
+            } else if (this.errors == 1)
+                errorWarningElement.title = WebInspector.UIString("%d error", this.errors);
+            else
+                errorWarningElement.title = WebInspector.UIString("%d errors", this.errors);
+        } else if (this.warnings == 1)
+            errorWarningElement.title = WebInspector.UIString("%d warning", this.warnings);
+        else if (this.warnings)
+            errorWarningElement.title = WebInspector.UIString("%d warnings", this.warnings);
+        else
+            errorWarningElement.title = null;
+    },
+
+    highlightDOMNode: function(nodeId)
+    {
+        if ("_hideDOMNodeHighlightTimeout" in this) {
+            clearTimeout(this._hideDOMNodeHighlightTimeout);
+            delete this._hideDOMNodeHighlightTimeout;
+        }
+
+        if (this._highlightedDOMNodeId === nodeId)
+            return;
+
+        this._highlightedDOMNodeId = nodeId;
+        if (nodeId)
+            InspectorBackend.highlightDOMNode(nodeId);
+        else
+            InspectorBackend.hideDOMNodeHighlight();
+    },
+
+    highlightDOMNodeForTwoSeconds: function(nodeId)
+    {
+        this.highlightDOMNode(nodeId);
+        this._hideDOMNodeHighlightTimeout = setTimeout(this.highlightDOMNode.bind(this, 0), 2000);
+    },
+
+    wireElementWithDOMNode: function(element, nodeId)
+    {
+        element.addEventListener("click", this._updateFocusedNode.bind(this, nodeId), false);
+        element.addEventListener("mouseover", this.highlightDOMNode.bind(this, nodeId), false);
+        element.addEventListener("mouseout", this.highlightDOMNode.bind(this, 0), false);
+    },
+
+    _updateFocusedNode: function(nodeId)
+    {
+        this.currentPanel = this.panels.elements;
+        this.panels.elements.updateFocusedNode(nodeId);
+    },
+
+    get networkResources()
+    {
+        return this.panels.network.resources;
+    },
+
+    networkResourceById: function(id)
+    {
+        return this.panels.network.resourceById(id);
+    },
+
+    forAllResources: function(callback)
+    {
+        WebInspector.resourceTreeModel.forAllResources(callback);
+    },
+
+    resourceForURL: function(url)
+    {
+        return this.resourceTreeModel.resourceForURL(url);
+    },
+
+    openLinkExternallyLabel: function()
+    {
+        return WebInspector.UIString("Open Link in New Window");
+    }
+}
+
+WebInspector.PlatformFlavor = {
+    WindowsVista: "windows-vista",
+    MacTiger: "mac-tiger",
+    MacLeopard: "mac-leopard",
+    MacSnowLeopard: "mac-snowleopard"
+};
+
+(function parseQueryParameters()
+{
+    WebInspector.queryParamsObject = {};
+    var queryParams = window.location.search;
+    if (!queryParams)
+        return;
+    var params = queryParams.substring(1).split("&");
+    for (var i = 0; i < params.length; ++i) {
+        var pair = params[i].split("=");
+        WebInspector.queryParamsObject[pair[0]] = pair[1];
+    }
+})();
+
+WebInspector.loaded = function()
+{
+    if ("page" in WebInspector.queryParamsObject) {
+        var page = WebInspector.queryParamsObject.page;
+        var host = "host" in WebInspector.queryParamsObject ? WebInspector.queryParamsObject.host : window.location.host;
+        WebInspector.socket = new WebSocket("ws://" + host + "/devtools/page/" + page);
+        WebInspector.socket.onmessage = function(message) { InspectorBackend.dispatch(message.data); }
+        WebInspector.socket.onerror = function(error) { console.error(error); }
+        WebInspector.socket.onopen = function() {
+            InspectorFrontendHost.sendMessageToBackend = WebInspector.socket.send.bind(WebInspector.socket);
+            InspectorFrontendHost.loaded = WebInspector.socket.send.bind(WebInspector.socket, "loaded");
+            WebInspector.doLoadedDone();
+        }
+        return;
+    }
+    WebInspector.doLoadedDone();
+}
+
+WebInspector.doLoadedDone = function()
+{
+    InspectorFrontendHost.loaded();
+
+    var platform = WebInspector.platform;
+    document.body.addStyleClass("platform-" + platform);
+    var flavor = WebInspector.platformFlavor;
+    if (flavor)
+        document.body.addStyleClass("platform-" + flavor);
+    var port = WebInspector.port;
+    document.body.addStyleClass("port-" + port);
+
+    WebInspector.settings = new WebInspector.Settings();
+
+    this._registerShortcuts();
+
+    // set order of some sections explicitly
+    WebInspector.shortcutsHelp.section(WebInspector.UIString("Console"));
+    WebInspector.shortcutsHelp.section(WebInspector.UIString("Elements Panel"));
+
+    this.drawer = new WebInspector.Drawer();
+    this.console = new WebInspector.ConsoleView(this.drawer);
+    this.drawer.visibleView = this.console;
+    this.resourceTreeModel = new WebInspector.ResourceTreeModel();
+    this.networkManager = new WebInspector.NetworkManager(this.resourceTreeModel);
+    this.domAgent = new WebInspector.DOMAgent();
+
+    InspectorBackend.registerDomainDispatcher("Inspector", this);
+
+    this.resourceCategories = {
+        documents: new WebInspector.ResourceCategory("documents", WebInspector.UIString("Documents"), "rgb(47,102,236)"),
+        stylesheets: new WebInspector.ResourceCategory("stylesheets", WebInspector.UIString("Stylesheets"), "rgb(157,231,119)"),
+        images: new WebInspector.ResourceCategory("images", WebInspector.UIString("Images"), "rgb(164,60,255)"),
+        scripts: new WebInspector.ResourceCategory("scripts", WebInspector.UIString("Scripts"), "rgb(255,121,0)"),
+        xhr: new WebInspector.ResourceCategory("xhr", WebInspector.UIString("XHR"), "rgb(231,231,10)"),
+        fonts: new WebInspector.ResourceCategory("fonts", WebInspector.UIString("Fonts"), "rgb(255,82,62)"),
+        websockets: new WebInspector.ResourceCategory("websockets", WebInspector.UIString("WebSockets"), "rgb(186,186,186)"), // FIXME: Decide the color.
+        other: new WebInspector.ResourceCategory("other", WebInspector.UIString("Other"), "rgb(186,186,186)")
+    };
+
+    this.cssModel = new WebInspector.CSSStyleModel();
+    this.debuggerModel = new WebInspector.DebuggerModel();
+
+    this.breakpointManager = new WebInspector.BreakpointManager();
+
+    this.panels = {};
+    this._createPanels();
+    this._panelHistory = new WebInspector.PanelHistory();
+
+    var toolbarElement = document.getElementById("toolbar");
+    var previousToolbarItem = toolbarElement.children[0];
+
+    this.panelOrder = [];
+    for (var panelName in this.panels)
+        previousToolbarItem = WebInspector.addPanelToolbarIcon(toolbarElement, this.panels[panelName], previousToolbarItem);
+
+    this.Tips = {
+        ResourceNotCompressed: {id: 0, message: WebInspector.UIString("You could save bandwidth by having your web server compress this transfer with gzip or zlib.")}
+    };
+
+    this.Warnings = {
+        IncorrectMIMEType: {id: 0, message: WebInspector.UIString("Resource interpreted as %s but transferred with MIME type %s.")}
+    };
+
+    this.addMainEventListeners(document);
+
+    window.addEventListener("resize", this.windowResize.bind(this), true);
+
+    document.addEventListener("focus", this.focusChanged.bind(this), true);
+    document.addEventListener("keydown", this.documentKeyDown.bind(this), false);
+    document.addEventListener("beforecopy", this.documentCanCopy.bind(this), true);
+    document.addEventListener("copy", this.documentCopy.bind(this), true);
+    document.addEventListener("contextmenu", this.contextMenuEventFired.bind(this), true);
+
+    var dockToggleButton = document.getElementById("dock-status-bar-item");
+    dockToggleButton.addEventListener("click", this.toggleAttach.bind(this), false);
+
+    if (this.attached)
+        dockToggleButton.title = WebInspector.UIString("Undock into separate window.");
+    else
+        dockToggleButton.title = WebInspector.UIString("Dock to main window.");
+
+    var errorWarningCount = document.getElementById("error-warning-count");
+    errorWarningCount.addEventListener("click", this.showConsole.bind(this), false);
+    this._updateErrorAndWarningCounts();
+
+    var searchField = document.getElementById("search");
+    searchField.addEventListener("search", this.performSearch.bind(this), false); // when the search is emptied
+    searchField.addEventListener("mousedown", this._searchFieldManualFocus.bind(this), false); // when the search field is manually selected
+    searchField.addEventListener("keydown", this._searchKeyDown.bind(this), true);
+
+    toolbarElement.addEventListener("mousedown", this.toolbarDragStart, true);
+    document.getElementById("close-button-left").addEventListener("click", this.close, true);
+    document.getElementById("close-button-right").addEventListener("click", this.close, true);
+
+    this.extensionServer.initExtensions();
+
+    function onPopulateScriptObjects()
+    {
+        if (!WebInspector.currentPanel)
+            WebInspector.showPanel(WebInspector.settings.lastActivePanel);
+    }
+    InspectorBackend.populateScriptObjects(onPopulateScriptObjects);
+
+    if (Preferences.debuggerAlwaysEnabled || WebInspector.settings.debuggerEnabled)
+        this.debuggerModel.enableDebugger();
+    if (Preferences.profilerAlwaysEnabled || WebInspector.settings.profilerEnabled)
+        InspectorBackend.enableProfiler();
+    if (WebInspector.settings.monitoringXHREnabled)
+        InspectorBackend.setMonitoringXHREnabled(true);
+
+    InspectorBackend.setConsoleMessagesEnabled(true);
+
+    function propertyNamesCallback(names)
+    {
+        WebInspector.cssNameCompletions = new WebInspector.CSSCompletions(names);
+    }
+    // As a DOMAgent method, this needs to happen after the frontend has loaded and the agent is available.
+    InspectorBackend.getSupportedCSSProperties(propertyNamesCallback);
+}
+
+WebInspector.addPanelToolbarIcon = function(toolbarElement, panel, previousToolbarItem)
+{
+    var panelToolbarItem = panel.toolbarItem;
+    this.panelOrder.push(panel);
+    panelToolbarItem.addEventListener("click", this._toolbarItemClicked.bind(this));
+    if (previousToolbarItem)
+        toolbarElement.insertBefore(panelToolbarItem, previousToolbarItem.nextSibling);
+    else
+        toolbarElement.insertBefore(panelToolbarItem, toolbarElement.firstChild);
+    return panelToolbarItem;
+}
+
+var windowLoaded = function()
+{
+    var localizedStringsURL = InspectorFrontendHost.localizedStringsURL();
+    if (localizedStringsURL) {
+        var localizedStringsScriptElement = document.createElement("script");
+        localizedStringsScriptElement.addEventListener("load", WebInspector.loaded.bind(WebInspector), false);
+        localizedStringsScriptElement.type = "text/javascript";
+        localizedStringsScriptElement.src = localizedStringsURL;
+        document.head.appendChild(localizedStringsScriptElement);
+    } else
+        WebInspector.loaded();
+
+    window.removeEventListener("DOMContentLoaded", windowLoaded, false);
+    delete windowLoaded;
+};
+
+window.addEventListener("DOMContentLoaded", windowLoaded, false);
+
+WebInspector.dispatch = function(message) {
+    // We'd like to enforce asynchronous interaction between the inspector controller and the frontend.
+    // This is important to LayoutTests.
+    function delayDispatch()
+    {
+        InspectorBackend.dispatch(message);
+        WebInspector.pendingDispatches--;
+    }
+    WebInspector.pendingDispatches++;
+    setTimeout(delayDispatch, 0);
+}
+
+WebInspector.dispatchMessageFromBackend = function(messageObject)
+{
+    WebInspector.dispatch(messageObject);
+}
+
+WebInspector.windowResize = function(event)
+{
+    if (this.currentPanel)
+        this.currentPanel.resize();
+    this.drawer.resize();
+}
+
+WebInspector.windowFocused = function(event)
+{
+    // Fires after blur, so when focusing on either the main inspector
+    // or an <iframe> within the inspector we should always remove the
+    // "inactive" class.
+    if (event.target.document.nodeType === Node.DOCUMENT_NODE)
+        document.body.removeStyleClass("inactive");
+}
+
+WebInspector.windowBlurred = function(event)
+{
+    // Leaving the main inspector or an <iframe> within the inspector.
+    // We can add "inactive" now, and if we are moving the focus to another
+    // part of the inspector then windowFocused will correct this.
+    if (event.target.document.nodeType === Node.DOCUMENT_NODE)
+        document.body.addStyleClass("inactive");
+}
+
+WebInspector.focusChanged = function(event)
+{
+    this.currentFocusElement = event.target;
+}
+
+WebInspector.setAttachedWindow = function(attached)
+{
+    this.attached = attached;
+}
+
+WebInspector.close = function(event)
+{
+    if (this._isClosing)
+        return;
+    this._isClosing = true;
+    InspectorFrontendHost.closeWindow();
+}
+
+WebInspector.disconnectFromBackend = function()
+{
+    InspectorFrontendHost.disconnectFromBackend();
+}
+
+WebInspector.documentClick = function(event)
+{
+    var anchor = event.target.enclosingNodeOrSelfWithNodeName("a");
+    if (!anchor || anchor.target === "_blank")
+        return;
+
+    // Prevent the link from navigating, since we don't do any navigation by following links normally.
+    event.preventDefault();
+    event.stopPropagation();
+
+    function followLink()
+    {
+        // FIXME: support webkit-html-external-link links here.
+        if (WebInspector.canShowSourceLine(anchor.href, anchor.getAttribute("line_number"), anchor.getAttribute("preferred_panel"))) {
+            if (anchor.hasStyleClass("webkit-html-external-link")) {
+                anchor.removeStyleClass("webkit-html-external-link");
+                anchor.addStyleClass("webkit-html-resource-link");
+            }
+
+            WebInspector.showSourceLine(anchor.href, anchor.getAttribute("line_number"), anchor.getAttribute("preferred_panel"));
+            return;
+        }
+
+        const profileMatch = WebInspector.ProfileType.URLRegExp.exec(anchor.href);
+        if (profileMatch) {
+            WebInspector.showProfileForURL(anchor.href);
+            return;
+        }
+
+        var parsedURL = anchor.href.asParsedURL();
+        if (parsedURL && parsedURL.scheme === "webkit-link-action") {
+            if (parsedURL.host === "show-panel") {
+                var panel = parsedURL.path.substring(1);
+                if (WebInspector.panels[panel])
+                    WebInspector.showPanel(panel);
+            }
+            return;
+        }
+
+        WebInspector.showPanel("resources");
+    }
+
+    if (WebInspector.followLinkTimeout)
+        clearTimeout(WebInspector.followLinkTimeout);
+
+    if (anchor.preventFollowOnDoubleClick) {
+        // Start a timeout if this is the first click, if the timeout is canceled
+        // before it fires, then a double clicked happened or another link was clicked.
+        if (event.detail === 1)
+            WebInspector.followLinkTimeout = setTimeout(followLink, 333);
+        return;
+    }
+
+    followLink();
+}
+
+WebInspector.openResource = function(resourceURL, inResourcesPanel)
+{
+    var resource = WebInspector.resourceForURL(resourceURL);
+    if (inResourcesPanel && resource) {
+        WebInspector.panels.resources.showResource(resource);
+        WebInspector.showPanel("resources");
+    } else
+        InspectorBackend.openInInspectedWindow(resource ? resource.url : resourceURL);
+}
+
+WebInspector._registerShortcuts = function()
+{
+    var shortcut = WebInspector.KeyboardShortcut;
+    var section = WebInspector.shortcutsHelp.section(WebInspector.UIString("All Panels"));
+    var keys = [
+        shortcut.shortcutToString("]", shortcut.Modifiers.CtrlOrMeta),
+        shortcut.shortcutToString("[", shortcut.Modifiers.CtrlOrMeta)
+    ];
+    section.addRelatedKeys(keys, WebInspector.UIString("Next/previous panel"));
+    section.addKey(shortcut.shortcutToString(shortcut.Keys.Esc), WebInspector.UIString("Toggle console"));
+    section.addKey(shortcut.shortcutToString("f", shortcut.Modifiers.CtrlOrMeta), WebInspector.UIString("Search"));
+    if (WebInspector.isMac()) {
+        keys = [
+            shortcut.shortcutToString("g", shortcut.Modifiers.Meta),
+            shortcut.shortcutToString("g", shortcut.Modifiers.Meta | shortcut.Modifiers.Shift)
+        ];
+        section.addRelatedKeys(keys, WebInspector.UIString("Find next/previous"));
+    }
+}
+
+WebInspector.documentKeyDown = function(event)
+{
+    var isInputElement = event.target.nodeName === "INPUT";
+    var isInEditMode = event.target.enclosingNodeOrSelfWithClass("text-prompt") || WebInspector.isEditingAnyField();
+    const helpKey = WebInspector.isMac() ? "U+003F" : "U+00BF"; // "?" for both platforms
+    var key = event.keyIdentifier || event.key;
+    if (key === "F1" ||
+        (key === helpKey && event.shiftKey && (!isInEditMode && !isInputElement || event.metaKey))) {
+        WebInspector.shortcutsHelp.show();
+        event.stopPropagation();
+        event.preventDefault();
+        return;
+    }
+
+    if (WebInspector.isEditingAnyField())
+        return;
+
+    if (this.currentFocusElement && this.currentFocusElement.handleKeyEvent) {
+        this.currentFocusElement.handleKeyEvent(event);
+        if (event.handled) {
+            event.preventDefault();
+            return;
+        }
+    }
+
+    if (this.currentPanel && this.currentPanel.handleShortcut) {
+        this.currentPanel.handleShortcut(event);
+        if (event.handled) {
+            event.preventDefault();
+            return;
+        }
+    }
+
+    var isMac = WebInspector.isMac();
+    switch (key) {
+        case "Left":
+            var isBackKey = !isInEditMode && (isMac ? event.metaKey : event.ctrlKey);
+            if (isBackKey && this._panelHistory.canGoBack()) {
+                this._panelHistory.goBack();
+                event.preventDefault();
+            }
+            break;
+
+        case "Right":
+            var isForwardKey = !isInEditMode && (isMac ? event.metaKey : event.ctrlKey);
+            if (isForwardKey && this._panelHistory.canGoForward()) {
+                this._panelHistory.goForward();
+                event.preventDefault();
+            }
+            break;
+
+        case "U+001B": // Escape key
+            event.preventDefault();
+            if (this.drawer.fullPanel)
+                return;
+
+            this.drawer.visible = !this.drawer.visible;
+            break;
+
+        case "U+0046": // F key
+            if (isMac)
+                var isFindKey = event.metaKey && !event.ctrlKey && !event.altKey && !event.shiftKey;
+            else
+                var isFindKey = event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey;
+
+            if (isFindKey) {
+                WebInspector.focusSearchField();
+                event.preventDefault();
+            }
+            break;
+
+        case "F3":
+            if (!isMac) {
+                WebInspector.focusSearchField();
+                event.preventDefault();
+            }
+            break;
+
+        case "U+0047": // G key
+            if (isMac && event.metaKey && !event.ctrlKey && !event.altKey) {
+                if (event.shiftKey) {
+                    if (this.currentPanel.jumpToPreviousSearchResult)
+                        this.currentPanel.jumpToPreviousSearchResult();
+                } else if (this.currentPanel.jumpToNextSearchResult)
+                    this.currentPanel.jumpToNextSearchResult();
+                event.preventDefault();
+            }
+            break;
+
+        // Windows and Mac have two different definitions of [, so accept both.
+        case "U+005B":
+        case "U+00DB": // [ key
+            if (isMac)
+                var isRotateLeft = event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey;
+            else
+                var isRotateLeft = event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;
+
+            if (isRotateLeft) {
+                var index = this.panelOrder.indexOf(this.currentPanel);
+                index = (index === 0) ? this.panelOrder.length - 1 : index - 1;
+                this.panelOrder[index].toolbarItem.click();
+                event.preventDefault();
+            }
+
+            break;
+
+        // Windows and Mac have two different definitions of ], so accept both.
+        case "U+005D":
+        case "U+00DD":  // ] key
+            if (isMac)
+                var isRotateRight = event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey;
+            else
+                var isRotateRight = event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;
+
+            if (isRotateRight) {
+                var index = this.panelOrder.indexOf(this.currentPanel);
+                index = (index + 1) % this.panelOrder.length;
+                this.panelOrder[index].toolbarItem.click();
+                event.preventDefault();
+            }
+
+            break;
+
+        case "U+0052": // R key
+            if ((event.metaKey && isMac) || (event.ctrlKey && !isMac)) {
+                InspectorBackend.reloadPage(event.shiftKey);
+                event.preventDefault();
+            }
+            break;
+        case "F5":
+            if (!isMac)
+                InspectorBackend.reloadPage(event.ctrlKey || event.shiftKey);
+            break;
+    }
+}
+
+WebInspector.documentCanCopy = function(event)
+{
+    if (this.currentPanel && this.currentPanel.handleCopyEvent)
+        event.preventDefault();
+}
+
+WebInspector.documentCopy = function(event)
+{
+    if (this.currentPanel && this.currentPanel.handleCopyEvent)
+        this.currentPanel.handleCopyEvent(event);
+}
+
+WebInspector.contextMenuEventFired = function(event)
+{
+    if (event.handled || event.target.hasStyleClass("popup-glasspane"))
+        event.preventDefault();
+}
+
+WebInspector.animateStyle = function(animations, duration, callback)
+{
+    var interval;
+    var complete = 0;
+    var hasCompleted = false;
+
+    const intervalDuration = (1000 / 30); // 30 frames per second.
+    const animationsLength = animations.length;
+    const propertyUnit = {opacity: ""};
+    const defaultUnit = "px";
+
+    function cubicInOut(t, b, c, d)
+    {
+        if ((t/=d/2) < 1) return c/2*t*t*t + b;
+        return c/2*((t-=2)*t*t + 2) + b;
+    }
+
+    // Pre-process animations.
+    for (var i = 0; i < animationsLength; ++i) {
+        var animation = animations[i];
+        var element = null, start = null, end = null, key = null;
+        for (key in animation) {
+            if (key === "element")
+                element = animation[key];
+            else if (key === "start")
+                start = animation[key];
+            else if (key === "end")
+                end = animation[key];
+        }
+
+        if (!element || !end)
+            continue;
+
+        if (!start) {
+            var computedStyle = element.ownerDocument.defaultView.getComputedStyle(element);
+            start = {};
+            for (key in end)
+                start[key] = parseInt(computedStyle.getPropertyValue(key));
+            animation.start = start;
+        } else
+            for (key in start)
+                element.style.setProperty(key, start[key] + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
+    }
+
+    function animateLoop()
+    {
+        // Advance forward.
+        complete += intervalDuration;
+        var next = complete + intervalDuration;
+
+        // Make style changes.
+        for (var i = 0; i < animationsLength; ++i) {
+            var animation = animations[i];
+            var element = animation.element;
+            var start = animation.start;
+            var end = animation.end;
+            if (!element || !end)
+                continue;
+
+            var style = element.style;
+            for (key in end) {
+                var endValue = end[key];
+                if (next < duration) {
+                    var startValue = start[key];
+                    var newValue = cubicInOut(complete, startValue, endValue - startValue, duration);
+                    style.setProperty(key, newValue + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
+                } else
+                    style.setProperty(key, endValue + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
+            }
+        }
+
+        // End condition.
+        if (complete >= duration) {
+            hasCompleted = true;
+            clearInterval(interval);
+            if (callback)
+                callback();
+        }
+    }
+
+    function forceComplete()
+    {
+        if (!hasCompleted) {
+            complete = duration;
+            animateLoop();
+        }
+    }
+
+    function cancel()
+    {
+        hasCompleted = true;
+        clearInterval(interval);
+    }
+
+    interval = setInterval(animateLoop, intervalDuration);
+    return {
+        cancel: cancel,
+        forceComplete: forceComplete
+    };
+}
+
+WebInspector.updateSearchLabel = function()
+{
+    if (!this.currentPanel)
+        return;
+
+    var newLabel = WebInspector.UIString("Search %s", this.currentPanel.toolbarItemLabel);
+    if (this.attached)
+        document.getElementById("search").setAttribute("placeholder", newLabel);
+    else {
+        document.getElementById("search").removeAttribute("placeholder");
+        document.getElementById("search-toolbar-label").textContent = newLabel;
+    }
+}
+
+WebInspector.focusSearchField = function()
+{
+    var searchField = document.getElementById("search");
+    searchField.focus();
+    searchField.select();
+}
+
+WebInspector.toggleAttach = function()
+{
+    if (!this.attached)
+        InspectorFrontendHost.requestAttachWindow();
+    else
+        InspectorFrontendHost.requestDetachWindow();
+}
+
+WebInspector.toolbarDragStart = function(event)
+{
+    if ((!WebInspector.attached && WebInspector.platformFlavor !== WebInspector.PlatformFlavor.MacLeopard && WebInspector.platformFlavor !== WebInspector.PlatformFlavor.MacSnowLeopard) || WebInspector.port == "qt")
+        return;
+
+    var target = event.target;
+    if (target.hasStyleClass("toolbar-item") && target.hasStyleClass("toggleable"))
+        return;
+
+    var toolbar = document.getElementById("toolbar");
+    if (target !== toolbar && !target.hasStyleClass("toolbar-item"))
+        return;
+
+    toolbar.lastScreenX = event.screenX;
+    toolbar.lastScreenY = event.screenY;
+
+    WebInspector.elementDragStart(toolbar, WebInspector.toolbarDrag, WebInspector.toolbarDragEnd, event, (WebInspector.attached ? "row-resize" : "default"));
+}
+
+WebInspector.toolbarDragEnd = function(event)
+{
+    var toolbar = document.getElementById("toolbar");
+
+    WebInspector.elementDragEnd(event);
+
+    delete toolbar.lastScreenX;
+    delete toolbar.lastScreenY;
+}
+
+WebInspector.toolbarDrag = function(event)
+{
+    var toolbar = document.getElementById("toolbar");
+
+    if (WebInspector.attached) {
+        var height = window.innerHeight - (event.screenY - toolbar.lastScreenY);
+
+        InspectorFrontendHost.setAttachedWindowHeight(height);
+    } else {
+        var x = event.screenX - toolbar.lastScreenX;
+        var y = event.screenY - toolbar.lastScreenY;
+
+        // We cannot call window.moveBy here because it restricts the movement
+        // of the window at the edges.
+        InspectorFrontendHost.moveWindowBy(x, y);
+    }
+
+    toolbar.lastScreenX = event.screenX;
+    toolbar.lastScreenY = event.screenY;
+
+    event.preventDefault();
+}
+
+WebInspector.elementDragStart = function(element, dividerDrag, elementDragEnd, event, cursor)
+{
+    if (this._elementDraggingEventListener || this._elementEndDraggingEventListener)
+        this.elementDragEnd(event);
+
+    this._elementDraggingEventListener = dividerDrag;
+    this._elementEndDraggingEventListener = elementDragEnd;
+
+    document.addEventListener("mousemove", dividerDrag, true);
+    document.addEventListener("mouseup", elementDragEnd, true);
+
+    document.body.style.cursor = cursor;
+
+    event.preventDefault();
+}
+
+WebInspector.elementDragEnd = function(event)
+{
+    document.removeEventListener("mousemove", this._elementDraggingEventListener, true);
+    document.removeEventListener("mouseup", this._elementEndDraggingEventListener, true);
+
+    document.body.style.removeProperty("cursor");
+
+    delete this._elementDraggingEventListener;
+    delete this._elementEndDraggingEventListener;
+
+    event.preventDefault();
+}
+
+WebInspector.toggleSearchingForNode = function()
+{
+    if (this.panels.elements) {
+        this.showPanel("elements");
+        this.panels.elements.toggleSearchingForNode();
+    }
+}
+
+WebInspector.showConsole = function()
+{
+    this.drawer.showView(this.console);
+}
+
+WebInspector.showPanel = function(panel)
+{
+    if (!(panel in this.panels))
+        panel = "elements";
+    this.currentPanel = this.panels[panel];
+}
+
+WebInspector.domContentEventFired = function(time)
+{
+    this.panels.audits.mainResourceDOMContentTime = time;
+    if (this.panels.network)
+        this.panels.network.mainResourceDOMContentTime = time;
+    this.extensionServer.notifyPageDOMContentLoaded((time - WebInspector.mainResource.startTime) * 1000);
+    this.mainResourceDOMContentTime = time;
+}
+
+WebInspector.loadEventFired = function(time)
+{
+    this.panels.audits.mainResourceLoadTime = time;
+    this.panels.network.mainResourceLoadTime = time;
+    this.panels.resources.loadEventFired();
+    this.extensionServer.notifyPageLoaded((time - WebInspector.mainResource.startTime) * 1000);
+    this.mainResourceLoadTime = time;
+}
+
+WebInspector.searchingForNodeWasEnabled = function()
+{
+    this.panels.elements.searchingForNodeWasEnabled();
+}
+
+WebInspector.searchingForNodeWasDisabled = function()
+{
+    this.panels.elements.searchingForNodeWasDisabled();
+}
+
+WebInspector.reset = function()
+{
+    this.debuggerModel.reset();
+
+    for (var panelName in this.panels) {
+        var panel = this.panels[panelName];
+        if ("reset" in panel)
+            panel.reset();
+    }
+
+    this.resources = {};
+    this.highlightDOMNode(0);
+
+    this.console.clearMessages();
+    this.extensionServer.notifyInspectorReset();
+}
+
+WebInspector.bringToFront = function()
+{
+    InspectorFrontendHost.bringToFront();
+}
+
+WebInspector.inspectedURLChanged = function(url)
+{
+    InspectorFrontendHost.inspectedURLChanged(url);
+    this.settings.inspectedURLChanged(url);
+    this.extensionServer.notifyInspectedURLChanged();
+}
+
+WebInspector.log = function(message, messageLevel)
+{
+    // remember 'this' for setInterval() callback
+    var self = this;
+
+    // return indication if we can actually log a message
+    function isLogAvailable()
+    {
+        return WebInspector.ConsoleMessage && WebInspector.RemoteObject && self.console;
+    }
+
+    // flush the queue of pending messages
+    function flushQueue()
+    {
+        var queued = WebInspector.log.queued;
+        if (!queued)
+            return;
+
+        for (var i = 0; i < queued.length; ++i)
+            logMessage(queued[i]);
+
+        delete WebInspector.log.queued;
+    }
+
+    // flush the queue if it console is available
+    // - this function is run on an interval
+    function flushQueueIfAvailable()
+    {
+        if (!isLogAvailable())
+            return;
+
+        clearInterval(WebInspector.log.interval);
+        delete WebInspector.log.interval;
+
+        flushQueue();
+    }
+
+    // actually log the message
+    function logMessage(message)
+    {
+        var repeatCount = 1;
+        if (message == WebInspector.log.lastMessage)
+            repeatCount = WebInspector.log.repeatCount + 1;
+
+        WebInspector.log.lastMessage = message;
+        WebInspector.log.repeatCount = repeatCount;
+
+        // ConsoleMessage expects a proxy object
+        message = new WebInspector.RemoteObject.fromPrimitiveValue(message);
+
+        // post the message
+        var msg = new WebInspector.ConsoleMessage(
+            WebInspector.ConsoleMessage.MessageSource.Other,
+            WebInspector.ConsoleMessage.MessageType.Log,
+            messageLevel || WebInspector.ConsoleMessage.MessageLevel.Debug,
+            -1,
+            null,
+            repeatCount,
+            null,
+            [message],
+            null);
+
+        self.console.addMessage(msg);
+    }
+
+    // if we can't log the message, queue it
+    if (!isLogAvailable()) {
+        if (!WebInspector.log.queued)
+            WebInspector.log.queued = [];
+
+        WebInspector.log.queued.push(message);
+
+        if (!WebInspector.log.interval)
+            WebInspector.log.interval = setInterval(flushQueueIfAvailable, 1000);
+
+        return;
+    }
+
+    // flush the pending queue if any
+    flushQueue();
+
+    // log the message
+    logMessage(message);
+}
+
+WebInspector.drawLoadingPieChart = function(canvas, percent) {
+    var g = canvas.getContext("2d");
+    var darkColor = "rgb(122, 168, 218)";
+    var lightColor = "rgb(228, 241, 251)";
+    var cx = 8;
+    var cy = 8;
+    var r = 7;
+
+    g.beginPath();
+    g.arc(cx, cy, r, 0, Math.PI * 2, false);
+    g.closePath();
+
+    g.lineWidth = 1;
+    g.strokeStyle = darkColor;
+    g.fillStyle = lightColor;
+    g.fill();
+    g.stroke();
+
+    var startangle = -Math.PI / 2;
+    var endangle = startangle + (percent * Math.PI * 2);
+
+    g.beginPath();
+    g.moveTo(cx, cy);
+    g.arc(cx, cy, r, startangle, endangle, false);
+    g.closePath();
+
+    g.fillStyle = darkColor;
+    g.fill();
+}
+
+WebInspector.updateFocusedNode = function(nodeId)
+{
+    this._updateFocusedNode(nodeId);
+    this.highlightDOMNodeForTwoSeconds(nodeId);
+}
+
+WebInspector.displayNameForURL = function(url)
+{
+    if (!url)
+        return "";
+
+    var resource = this.resourceForURL(url);
+    if (resource)
+        return resource.displayName;
+
+    if (!WebInspector.mainResource)
+        return url.trimURL("");
+
+    var lastPathComponent = WebInspector.mainResource.lastPathComponent;
+    var index = WebInspector.mainResource.url.indexOf(lastPathComponent);
+    if (index !== -1 && index + lastPathComponent.length === WebInspector.mainResource.url.length) {
+        var baseURL = WebInspector.mainResource.url.substring(0, index);
+        if (url.indexOf(baseURL) === 0)
+            return url.substring(index);
+    }
+
+    return url.trimURL(WebInspector.mainResource.domain);
+}
+
+WebInspector._choosePanelToShowSourceLine = function(url, line, preferredPanel)
+{
+    preferredPanel = preferredPanel || "resources";
+
+    var panel = this.panels[preferredPanel];
+    if (panel && panel.canShowSourceLine(url, line))
+        return panel;
+    panel = this.panels.resources;
+    return panel.canShowSourceLine(url, line) ? panel : null;
+}
+
+WebInspector.canShowSourceLine = function(url, line, preferredPanel)
+{
+    return !!this._choosePanelToShowSourceLine(url, line, preferredPanel);
+}
+
+WebInspector.showSourceLine = function(url, line, preferredPanel)
+{
+    this.currentPanel = this._choosePanelToShowSourceLine(url, line, preferredPanel);
+    if (!this.currentPanel)
+        return false;
+    if (this.drawer)
+        this.drawer.immediatelyFinishAnimation();
+    this.currentPanel.showSourceLine(url, line);
+    return true;
+}
+
+WebInspector.linkifyStringAsFragment = function(string)
+{
+    var container = document.createDocumentFragment();
+    var linkStringRegEx = /(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\/\/|www\.)[\w$\-_+*'=\|\/\\(){}[\]%@&#~,:;.!?]{2,}[\w$\-_+*=\|\/\\({%@&#~]/;
+    var lineColumnRegEx = /:(\d+)(:(\d+))?$/;
+
+    while (string) {
+        var linkString = linkStringRegEx.exec(string);
+        if (!linkString)
+            break;
+
+        linkString = linkString[0];
+        var title = linkString;
+        var linkIndex = string.indexOf(linkString);
+        var nonLink = string.substring(0, linkIndex);
+        container.appendChild(document.createTextNode(nonLink));
+
+        var profileStringMatches = WebInspector.ProfileType.URLRegExp.exec(title);
+        if (profileStringMatches)
+            title = WebInspector.panels.profiles.displayTitleForProfileLink(profileStringMatches[2], profileStringMatches[1]);
+
+        var realURL = (linkString.indexOf("www.") === 0 ? "http://" + linkString : linkString);
+        var lineColumnMatch = lineColumnRegEx.exec(realURL);
+        if (lineColumnMatch)
+            realURL = realURL.substring(0, realURL.length - lineColumnMatch[0].length);
+
+        var hasResourceWithURL = !!WebInspector.resourceForURL(realURL);
+        var urlNode = WebInspector.linkifyURLAsNode(realURL, title, null, hasResourceWithURL);
+        container.appendChild(urlNode);
+        if (lineColumnMatch) {
+            urlNode.setAttribute("line_number", lineColumnMatch[1]);
+            urlNode.setAttribute("preferred_panel", "scripts");
+        }
+        string = string.substring(linkIndex + linkString.length, string.length);
+    }
+
+    if (string)
+        container.appendChild(document.createTextNode(string));
+
+    return container;
+}
+
+WebInspector.showProfileForURL = function(url)
+{
+    WebInspector.showPanel("profiles");
+    WebInspector.panels.profiles.showProfileForURL(url);
+}
+
+WebInspector.linkifyURLAsNode = function(url, linkText, classes, isExternal, tooltipText)
+{
+    if (!linkText)
+        linkText = url;
+    classes = (classes ? classes + " " : "");
+    classes += isExternal ? "webkit-html-external-link" : "webkit-html-resource-link";
+
+    var a = document.createElement("a");
+    a.href = url;
+    a.className = classes;
+    if (typeof tooltipText === "undefined")
+        a.title = url;
+    else if (typeof tooltipText !== "string" || tooltipText.length)
+        a.title = tooltipText;
+    a.textContent = linkText;
+
+    return a;
+}
+
+WebInspector.linkifyURL = function(url, linkText, classes, isExternal, tooltipText)
+{
+    // Use the DOM version of this function so as to avoid needing to escape attributes.
+    // FIXME:  Get rid of linkifyURL entirely.
+    return WebInspector.linkifyURLAsNode(url, linkText, classes, isExternal, tooltipText).outerHTML;
+}
+
+WebInspector.linkifyResourceAsNode = function(url, preferredPanel, lineNumber, classes, tooltipText)
+{
+    var linkText = WebInspector.displayNameForURL(url);
+    if (lineNumber)
+        linkText += ":" + lineNumber;
+    var node = WebInspector.linkifyURLAsNode(url, linkText, classes, false, tooltipText);
+    node.setAttribute("line_number", lineNumber);
+    node.setAttribute("preferred_panel", preferredPanel);
+    return node;
+}
+
+WebInspector.resourceURLForRelatedNode = function(node, url)
+{
+    if (!url || url.indexOf("://") > 0)
+        return url;
+
+    for (var frameOwnerCandidate = node; frameOwnerCandidate; frameOwnerCandidate = frameOwnerCandidate.parentNode) {
+        if (frameOwnerCandidate.documentURL) {
+            var result = WebInspector.completeURL(frameOwnerCandidate.documentURL, url);
+            if (result)
+                return result;
+            break;
+        }
+    }
+
+    // documentURL not found or has bad value
+    var resourceURL = url;
+    function callback(resource)
+    {
+        if (resource.path === url) {
+            resourceURL = resource.url;
+            return true;
+        }
+    }
+    WebInspector.forAllResources(callback);
+    return resourceURL;
+}
+
+WebInspector.completeURL = function(baseURL, href)
+{
+    if (href) {
+        // Return absolute URLs as-is.
+        var parsedHref = href.asParsedURL();
+        if (parsedHref && parsedHref.scheme)
+            return href;
+    }
+
+    var parsedURL = baseURL.asParsedURL();
+    if (parsedURL) {
+        var path = href;
+        if (path.charAt(0) !== "/") {
+            var basePath = parsedURL.path;
+            // A href of "?foo=bar" implies "basePath?foo=bar".
+            // With "basePath?a=b" and "?foo=bar" we should get "basePath?foo=bar".
+            var prefix;
+            if (path.charAt(0) === "?") {
+                var basePathCutIndex = basePath.indexOf("?");
+                if (basePathCutIndex !== -1)
+                    prefix = basePath.substring(0, basePathCutIndex);
+                else
+                    prefix = basePath;
+            } else
+                prefix = basePath.substring(0, basePath.lastIndexOf("/")) + "/";
+
+            path = prefix + path;
+        } else if (path.length > 1 && path.charAt(1) === "/") {
+            // href starts with "//" which is a full URL with the protocol dropped (use the baseURL protocol).
+            return parsedURL.scheme + ":" + path;
+        }
+        return parsedURL.scheme + "://" + parsedURL.host + (parsedURL.port ? (":" + parsedURL.port) : "") + path;
+    }
+    return null;
+}
+
+WebInspector.addMainEventListeners = function(doc)
+{
+    doc.defaultView.addEventListener("focus", this.windowFocused.bind(this), false);
+    doc.defaultView.addEventListener("blur", this.windowBlurred.bind(this), false);
+    doc.addEventListener("click", this.documentClick.bind(this), true);
+}
+
+WebInspector._searchFieldManualFocus = function(event)
+{
+    this.currentFocusElement = event.target;
+    this._previousFocusElement = event.target;
+}
+
+WebInspector._searchKeyDown = function(event)
+{
+    // Escape Key will clear the field and clear the search results
+    if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) {
+        // If focus belongs here and text is empty - nothing to do, return unhandled.
+        if (event.target.value === "" && this.currentFocusElement === this.previousFocusElement)
+            return;
+        event.preventDefault();
+        event.stopPropagation();
+        // When search was selected manually and is currently blank, we'd like Esc stay unhandled
+        // and hit console drawer handler.
+        event.target.value = "";
+
+        this.performSearch(event);
+        this.currentFocusElement = this.previousFocusElement;
+        if (this.currentFocusElement === event.target)
+            this.currentFocusElement.select();
+        return false;
+    }
+
+    if (!isEnterKey(event))
+        return false;
+
+    // Select all of the text so the user can easily type an entirely new query.
+    event.target.select();
+
+    // Only call performSearch if the Enter key was pressed. Otherwise the search
+    // performance is poor because of searching on every key. The search field has
+    // the incremental attribute set, so we still get incremental searches.
+    this.performSearch(event);
+
+    // Call preventDefault since this was the Enter key. This prevents a "search" event
+    // from firing for key down. This stops performSearch from being called twice in a row.
+    event.preventDefault();
+}
+
+WebInspector.performSearch = function(event)
+{
+    var forceSearch = (event.keyIdentifier || event.key) === "Enter";
+    this.doPerformSearch(event.target.value, forceSearch, event.shiftKey, false);
+}
+
+WebInspector.cancelSearch = function()
+{
+    document.getElementById("search").value = "";
+    this.doPerformSearch("");
+}
+
+WebInspector.doPerformSearch = function(query, forceSearch, isBackwardSearch, repeatSearch)
+{
+    var isShortSearch = (query.length < 3);
+
+    // Clear a leftover short search flag due to a non-conflicting forced search.
+    if (isShortSearch && this.shortSearchWasForcedByKeyEvent && this.currentQuery !== query)
+        delete this.shortSearchWasForcedByKeyEvent;
+
+    // Indicate this was a forced search on a short query.
+    if (isShortSearch && forceSearch)
+        this.shortSearchWasForcedByKeyEvent = true;
+
+    if (!query || !query.length || (!forceSearch && isShortSearch)) {
+        // Prevent clobbering a short search forced by the user.
+        if (this.shortSearchWasForcedByKeyEvent) {
+            delete this.shortSearchWasForcedByKeyEvent;
+            return;
+        }
+
+        delete this.currentQuery;
+
+        for (var panelName in this.panels) {
+            var panel = this.panels[panelName];
+            var hadCurrentQuery = !!panel.currentQuery;
+            delete panel.currentQuery;
+            if (hadCurrentQuery && panel.searchCanceled)
+                panel.searchCanceled();
+        }
+
+        this.updateSearchMatchesCount();
+
+        return;
+    }
+
+    if (!repeatSearch && query === this.currentPanel.currentQuery && this.currentPanel.currentQuery === this.currentQuery) {
+        // When this is the same query and a forced search, jump to the next
+        // search result for a good user experience.
+        if (forceSearch) {
+            if (!isBackwardSearch && this.currentPanel.jumpToNextSearchResult)
+                this.currentPanel.jumpToNextSearchResult();
+            else if (isBackwardSearch && this.currentPanel.jumpToPreviousSearchResult)
+                this.currentPanel.jumpToPreviousSearchResult();
+        }
+        return;
+    }
+
+    this.currentQuery = query;
+
+    this.updateSearchMatchesCount();
+
+    if (!this.currentPanel.performSearch)
+        return;
+
+    this.currentPanel.currentQuery = query;
+    this.currentPanel.performSearch(query);
+}
+
+WebInspector.frontendReused = function()
+{
+    this.networkManager.reset();
+    this.reset();
+}
+
+WebInspector.addNodesToSearchResult = function(nodeIds)
+{
+    WebInspector.panels.elements.addNodesToSearchResult(nodeIds);
+}
+
+WebInspector.updateSearchMatchesCount = function(matches, panel)
+{
+    if (!panel)
+        panel = this.currentPanel;
+
+    panel.currentSearchMatches = matches;
+
+    if (panel !== this.currentPanel)
+        return;
+
+    if (!this.currentPanel.currentQuery) {
+        document.getElementById("search-results-matches").addStyleClass("hidden");
+        return;
+    }
+
+    if (matches) {
+        if (matches === 1)
+            var matchesString = WebInspector.UIString("1 match");
+        else
+            var matchesString = WebInspector.UIString("%d matches", matches);
+    } else
+        var matchesString = WebInspector.UIString("Not Found");
+
+    var matchesToolbarElement = document.getElementById("search-results-matches");
+    matchesToolbarElement.removeStyleClass("hidden");
+    matchesToolbarElement.textContent = matchesString;
+}
+
+WebInspector.UIString = function(string)
+{
+    if (window.localizedStrings && string in window.localizedStrings)
+        string = window.localizedStrings[string];
+    else {
+        if (!(string in WebInspector.missingLocalizedStrings)) {
+            if (!WebInspector.InspectorBackendStub)
+                console.error("Localized string \"" + string + "\" not found.");
+            WebInspector.missingLocalizedStrings[string] = true;
+        }
+
+        if (Preferences.showMissingLocalizedStrings)
+            string += " (not localized)";
+    }
+
+    return String.vsprintf(string, Array.prototype.slice.call(arguments, 1));
+}
+
+WebInspector.formatLocalized = function(format, substitutions, formatters, initialValue, append)
+{
+    return String.format(WebInspector.UIString(format), substitutions, formatters, initialValue, append);
+}
+
+WebInspector.isMac = function()
+{
+    if (!("_isMac" in this))
+        this._isMac = WebInspector.platform === "mac";
+
+    return this._isMac;
+}
+
+WebInspector.isBeingEdited = function(element)
+{
+    return element.__editing;
+}
+
+WebInspector.isEditingAnyField = function()
+{
+    return this.__editing;
+}
+
+// Available config fields (all optional):
+// context: Object - an arbitrary context object to be passed to the commit and cancel handlers
+// commitHandler: Function - handles editing "commit" outcome
+// cancelHandler: Function - handles editing "cancel" outcome
+// customFinishHandler: Function - custom finish handler for the editing session (invoked on keydown)
+// pasteHandler: Function - handles the "paste" event, return values are the same as those for customFinishHandler
+// multiline: Boolean - whether the edited element is multiline
+WebInspector.startEditing = function(element, config)
+{
+    if (element.__editing)
+        return;
+    element.__editing = true;
+    WebInspector.__editing = true;
+
+    config = config || {};
+    var committedCallback = config.commitHandler;
+    var cancelledCallback = config.cancelHandler;
+    var pasteCallback = config.pasteHandler;
+    var context = config.context;
+    var oldText = getContent(element);
+    var moveDirection = "";
+
+    element.addStyleClass("editing");
+    element.setAttribute("contenteditable", "true");
+
+    var oldTabIndex = element.tabIndex;
+    if (element.tabIndex < 0)
+        element.tabIndex = 0;
+
+    function blurEventListener() {
+        editingCommitted.call(element);
+    }
+
+    function getContent(element) {
+        if (element.tagName === "INPUT" && element.type === "text")
+            return element.value;
+        else
+            return element.textContent;
+    }
+
+    function cleanUpAfterEditing() {
+        delete this.__editing;
+        delete WebInspector.__editing;
+
+        this.removeStyleClass("editing");
+        this.removeAttribute("contenteditable");
+
+        this.tabIndex = oldTabIndex;
+        this.scrollTop = 0;
+        this.scrollLeft = 0;
+
+        element.removeEventListener("blur", blurEventListener, false);
+        element.removeEventListener("keydown", keyDownEventListener, true);
+        if (pasteCallback)
+            element.removeEventListener("paste", pasteEventListener, true);
+
+        if (element === WebInspector.currentFocusElement || element.isAncestor(WebInspector.currentFocusElement))
+            WebInspector.currentFocusElement = WebInspector.previousFocusElement;
+    }
+
+    function editingCancelled() {
+        if (this.tagName === "INPUT" && this.type === "text")
+            this.value = oldText;
+        else
+            this.textContent = oldText;
+
+        cleanUpAfterEditing.call(this);
+
+        if (cancelledCallback)
+            cancelledCallback(this, context);
+    }
+
+    function editingCommitted() {
+        cleanUpAfterEditing.call(this);
+
+        if (committedCallback)
+            committedCallback(this, getContent(this), oldText, context, moveDirection);
+    }
+
+    function defaultFinishHandler(event)
+    {
+        var isMetaOrCtrl = WebInspector.isMac() ?
+            event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey :
+            event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;
+        if (isEnterKey(event) && (!config.multiline || isMetaOrCtrl))
+            return "commit";
+        else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code)
+            return "cancel";
+        else if ((event.keyIdentifier || event.key) === "U+0009") // Tab key
+            return "move-" + (event.shiftKey ? "backward" : "forward");
+    }
+
+    function handleEditingResult(result, event)
+    {
+        if (result === "commit") {
+            editingCommitted.call(element);
+            event.preventDefault();
+            event.stopPropagation();
+        } else if (result === "cancel") {
+            editingCancelled.call(element);
+            event.preventDefault();
+            event.stopPropagation();
+        } else if (result && result.indexOf("move-") === 0) {
+            moveDirection = result.substring(5);
+            if ((event.keyIdentifier || event.key) !== "U+0009")
+                blurEventListener();
+        }
+    }
+
+    function pasteEventListener(event)
+    {
+        var result = pasteCallback(event);
+        handleEditingResult(result, event);
+    }
+
+    function keyDownEventListener(event)
+    {
+        var handler = config.customFinishHandler || defaultFinishHandler;
+        var result = handler(event);
+        handleEditingResult(result, event);
+    }
+
+    element.addEventListener("blur", blurEventListener, false);
+    element.addEventListener("keydown", keyDownEventListener, true);
+    if (pasteCallback)
+        element.addEventListener("paste", pasteEventListener, true);
+
+    WebInspector.currentFocusElement = element;
+    return {
+        cancel: editingCancelled.bind(element),
+        commit: editingCommitted.bind(element)
+    };
+}
+
+WebInspector._toolbarItemClicked = function(event)
+{
+    var toolbarItem = event.currentTarget;
+    this.currentPanel = toolbarItem.panel;
+}
+
+// This table maps MIME types to the Resource.Types which are valid for them.
+// The following line:
+//    "text/html":                {0: 1},
+// means that text/html is a valid MIME type for resources that have type
+// WebInspector.Resource.Type.Document (which has a value of 0).
+WebInspector.MIMETypes = {
+    "text/html":                   {0: true},
+    "text/xml":                    {0: true},
+    "text/plain":                  {0: true},
+    "application/xhtml+xml":       {0: true},
+    "text/css":                    {1: true},
+    "text/xsl":                    {1: true},
+    "image/jpeg":                  {2: true},
+    "image/png":                   {2: true},
+    "image/gif":                   {2: true},
+    "image/bmp":                   {2: true},
+    "image/vnd.microsoft.icon":    {2: true},
+    "image/x-icon":                {2: true},
+    "image/x-xbitmap":             {2: true},
+    "font/ttf":                    {3: true},
+    "font/opentype":               {3: true},
+    "application/x-font-type1":    {3: true},
+    "application/x-font-ttf":      {3: true},
+    "application/x-font-woff":     {3: true},
+    "application/x-truetype-font": {3: true},
+    "text/javascript":             {4: true},
+    "text/ecmascript":             {4: true},
+    "application/javascript":      {4: true},
+    "application/ecmascript":      {4: true},
+    "application/x-javascript":    {4: true},
+    "text/javascript1.1":          {4: true},
+    "text/javascript1.2":          {4: true},
+    "text/javascript1.3":          {4: true},
+    "text/jscript":                {4: true},
+    "text/livescript":             {4: true},
+}
+
+WebInspector.PanelHistory = function()
+{
+    this._history = [];
+    this._historyIterator = -1;
+}
+
+WebInspector.PanelHistory.prototype = {
+    canGoBack: function()
+    {
+        return this._historyIterator > 0;
+    },
+
+    goBack: function()
+    {
+        this._inHistory = true;
+        WebInspector.currentPanel = WebInspector.panels[this._history[--this._historyIterator]];
+        delete this._inHistory;
+    },
+
+    canGoForward: function()
+    {
+        return this._historyIterator < this._history.length - 1;
+    },
+
+    goForward: function()
+    {
+        this._inHistory = true;
+        WebInspector.currentPanel = WebInspector.panels[this._history[++this._historyIterator]];
+        delete this._inHistory;
+    },
+
+    setPanel: function(panelName)
+    {
+        if (this._inHistory)
+            return;
+
+        this._history.splice(this._historyIterator + 1, this._history.length - this._historyIterator - 1);
+        if (!this._history.length || this._history[this._history.length - 1] !== panelName)
+            this._history.push(panelName);
+        this._historyIterator = this._history.length - 1;
+    }
+}
diff --git a/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/utilities.js b/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/utilities.js
new file mode 100644
index 0000000..f64ed53
--- /dev/null
+++ b/weinre.build/vendor-override/webkit/WebCore/inspector/front-end/utilities.js
@@ -0,0 +1,1087 @@
+/*
+ * Copyright (C) 2007 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Contains diff method based on Javascript Diff Algorithm By John Resig
+ * http://ejohn.org/files/jsdiff.js (released under the MIT license).
+ */
+
+Function.prototype.bind = function(thisObject)
+{
+    var func = this;
+    var args = Array.prototype.slice.call(arguments, 1);
+    function bound()
+    {
+        return func.apply(thisObject, args.concat(Array.prototype.slice.call(arguments, 0)));
+    }
+    bound.toString = function() {
+        return "bound: " + func;
+    };
+    return bound;
+}
+
+Node.prototype.rangeOfWord = function(offset, stopCharacters, stayWithinNode, direction)
+{
+    var startNode;
+    var startOffset = 0;
+    var endNode;
+    var endOffset = 0;
+
+    if (!stayWithinNode)
+        stayWithinNode = this;
+
+    if (!direction || direction === "backward" || direction === "both") {
+        var node = this;
+        while (node) {
+            if (node === stayWithinNode) {
+                if (!startNode)
+                    startNode = stayWithinNode;
+                break;
+            }
+
+            if (node.nodeType === Node.TEXT_NODE) {
+                var start = (node === this ? (offset - 1) : (node.nodeValue.length - 1));
+                for (var i = start; i >= 0; --i) {
+                    if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
+                        startNode = node;
+                        startOffset = i + 1;
+                        break;
+                    }
+                }
+            }
+
+            if (startNode)
+                break;
+
+            node = node.traversePreviousNode(stayWithinNode);
+        }
+
+        if (!startNode) {
+            startNode = stayWithinNode;
+            startOffset = 0;
+        }
+    } else {
+        startNode = this;
+        startOffset = offset;
+    }
+
+    if (!direction || direction === "forward" || direction === "both") {
+        node = this;
+        while (node) {
+            if (node === stayWithinNode) {
+                if (!endNode)
+                    endNode = stayWithinNode;
+                break;
+            }
+
+            if (node.nodeType === Node.TEXT_NODE) {
+                var start = (node === this ? offset : 0);
+                for (var i = start; i < node.nodeValue.length; ++i) {
+                    if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
+                        endNode = node;
+                        endOffset = i;
+                        break;
+                    }
+                }
+            }
+
+            if (endNode)
+                break;
+
+            node = node.traverseNextNode(stayWithinNode);
+        }
+
+        if (!endNode) {
+            endNode = stayWithinNode;
+            endOffset = stayWithinNode.nodeType === Node.TEXT_NODE ? stayWithinNode.nodeValue.length : stayWithinNode.childNodes.length;
+        }
+    } else {
+        endNode = this;
+        endOffset = offset;
+    }
+
+    var result = this.ownerDocument.createRange();
+    result.setStart(startNode, startOffset);
+    result.setEnd(endNode, endOffset);
+
+    return result;
+}
+
+Node.prototype.traverseNextTextNode = function(stayWithin)
+{
+    var node = this.traverseNextNode(stayWithin);
+    if (!node)
+        return;
+
+    while (node && node.nodeType !== Node.TEXT_NODE)
+        node = node.traverseNextNode(stayWithin);
+
+    return node;
+}
+
+Node.prototype.rangeBoundaryForOffset = function(offset)
+{
+    var node = this.traverseNextTextNode(this);
+    while (node && offset > node.nodeValue.length) {
+        offset -= node.nodeValue.length;
+        node = node.traverseNextTextNode(this);
+    }
+    if (!node)
+        return { container: this, offset: 0 };
+    return { container: node, offset: offset };
+}
+
+Element.prototype.removeStyleClass = function(className) 
+{
+    // Test for the simple case first.
+    if (this.className === className) {
+        this.className = "";
+        return;
+    }
+
+    var index = this.className.indexOf(className);
+    if (index === -1)
+        return;
+
+    this.className = this.className.split(" ").filter(function(s) {
+        return s && s !== className;
+    }).join(" ");
+}
+
+Element.prototype.removeMatchingStyleClasses = function(classNameRegex)
+{
+    var regex = new RegExp("(^|\\s+)" + classNameRegex + "($|\\s+)");
+    if (regex.test(this.className))
+        this.className = this.className.replace(regex, " ");
+}
+
+Element.prototype.addStyleClass = function(className) 
+{
+    if (className && !this.hasStyleClass(className))
+        this.className += (this.className.length ? " " + className : className);
+}
+
+Element.prototype.hasStyleClass = function(className) 
+{
+    if (!className)
+        return false;
+    // Test for the simple case
+    if (this.className === className)
+        return true;
+
+    var index = this.className.indexOf(className);
+    if (index === -1)
+        return false;
+    var toTest = " " + this.className + " ";
+    return toTest.indexOf(" " + className + " ", index) !== -1;
+}
+
+Element.prototype.positionAt = function(x, y)
+{
+    this.style.left = x + "px";
+    this.style.top = y + "px";
+}
+
+Element.prototype.pruneEmptyTextNodes = function()
+{
+    var sibling = this.firstChild;
+    while (sibling) {
+        var nextSibling = sibling.nextSibling;
+        if (sibling.nodeType === this.TEXT_NODE && sibling.nodeValue === "")
+            this.removeChild(sibling);
+        sibling = nextSibling;
+    }
+}
+
+Element.prototype.isScrolledToBottom = function()
+{
+    // This code works only for 0-width border
+    return this.scrollTop + this.clientHeight === this.scrollHeight;
+}
+
+Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray)
+{
+    for (var node = this; node && node !== this.ownerDocument; node = node.parentNode)
+        for (var i = 0; i < nameArray.length; ++i)
+            if (node.nodeName.toLowerCase() === nameArray[i].toLowerCase())
+                return node;
+    return null;
+}
+
+Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName)
+{
+    return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]);
+}
+
+Node.prototype.enclosingNodeOrSelfWithClass = function(className)
+{
+    for (var node = this; node && node !== this.ownerDocument; node = node.parentNode)
+        if (node.nodeType === Node.ELEMENT_NODE && node.hasStyleClass(className))
+            return node;
+    return null;
+}
+
+Node.prototype.enclosingNodeWithClass = function(className)
+{
+    if (!this.parentNode)
+        return null;
+    return this.parentNode.enclosingNodeOrSelfWithClass(className);
+}
+
+Element.prototype.query = function(query) 
+{
+    return this.ownerDocument.evaluate(query, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
+}
+
+Element.prototype.removeChildren = function()
+{
+    if (this.firstChild)
+        this.textContent = "";
+}
+
+Element.prototype.isInsertionCaretInside = function()
+{
+    var selection = window.getSelection();
+    if (!selection.rangeCount || !selection.isCollapsed)
+        return false;
+    var selectionRange = selection.getRangeAt(0);
+    return selectionRange.startContainer === this || selectionRange.startContainer.isDescendant(this);
+}
+
+Element.prototype.createChild = function(elementName, className)
+{
+    var element = document.createElement(elementName);
+    if (className)
+        element.className = className;
+    this.appendChild(element);
+    return element;
+}
+
+Object.defineProperty(Element.prototype, "totalOffsetLeft", {get: function()
+{
+    var total = 0;
+    for (var element = this; element; element = element.offsetParent)
+        total += element.offsetLeft + (this !== element ? element.clientLeft : 0);
+    return total;
+}});
+
+Object.defineProperty(Element.prototype, "totalOffsetTop", {get: function()
+{
+    var total = 0;
+    for (var element = this; element; element = element.offsetParent)
+        total += element.offsetTop + (this !== element ? element.clientTop : 0);
+    return total;
+}});
+
+Element.prototype.offsetRelativeToWindow = function(targetWindow)
+{
+    var elementOffset = {x: 0, y: 0};
+    var curElement = this;
+    var curWindow = this.ownerDocument.defaultView;
+    while (curWindow && curElement) {
+        elementOffset.x += curElement.totalOffsetLeft;
+        elementOffset.y += curElement.totalOffsetTop;
+        if (curWindow === targetWindow)
+            break;
+
+        curElement = curWindow.frameElement;
+        curWindow = curWindow.parent;
+    }
+
+    return elementOffset;
+}
+
+Object.defineProperty(KeyboardEvent.prototype, "data", {get: function()
+{
+    // Emulate "data" attribute from DOM 3 TextInput event.
+    // See http://www.w3.org/TR/DOM-Level-3-Events/#events-Events-TextEvent-data
+    switch (this.type) {
+        case "keypress":
+            if (!this.ctrlKey && !this.metaKey)
+                return String.fromCharCode(this.charCode);
+            else
+                return "";
+        case "keydown":
+        case "keyup":
+            if (!this.ctrlKey && !this.metaKey && !this.altKey)
+                return String.fromCharCode(this.which);
+            else
+                return "";
+    }
+}});
+
+Text.prototype.select = function(start, end)
+{
+    start = start || 0;
+    end = end || this.textContent.length;
+
+    if (start < 0)
+        start = end + start;
+
+    var selection = window.getSelection();
+    selection.removeAllRanges();
+    var range = document.createRange();
+    range.setStart(this, start);
+    range.setEnd(this, end);
+    selection.addRange(range);
+    return this;
+}
+
+Object.defineProperty(Element.prototype, "selectionLeftOffset", {get: function() {
+    // Calculate selection offset relative to the current element.
+
+    var selection = window.getSelection();
+    if (!selection.containsNode(this, true))
+        return null;
+
+    var leftOffset = selection.anchorOffset;
+    var node = selection.anchorNode;
+
+    while (node !== this) {
+        while (node.previousSibling) {
+            node = node.previousSibling;
+            leftOffset += node.textContent.length;
+        }
+        node = node.parentNode;
+    }
+
+    return leftOffset;
+}});
+
+Node.prototype.isWhitespace = isNodeWhitespace;
+Node.prototype.displayName = nodeDisplayName;
+Node.prototype.isAncestor = function(node)
+{
+    return isAncestorNode(this, node);
+};
+Node.prototype.isDescendant = isDescendantNode;
+Node.prototype.traverseNextNode = traverseNextNode;
+Node.prototype.traversePreviousNode = traversePreviousNode;
+Node.prototype.onlyTextChild = onlyTextChild;
+
+String.prototype.hasSubstring = function(string, caseInsensitive)
+{
+    if (!caseInsensitive)
+        return this.indexOf(string) !== -1;
+    return this.match(new RegExp(string.escapeForRegExp(), "i"));
+}
+
+String.prototype.findAll = function(string)
+{
+    var matches = [];
+    var i = this.indexOf(string);
+    while (i !== -1) {
+        matches.push(i);
+        i = this.indexOf(string, i + string.length);
+    }
+    return matches;
+}
+
+String.prototype.lineEndings = function()
+{
+    if (!this._lineEndings) {
+        this._lineEndings = this.findAll("\n");
+        this._lineEndings.push(this.length);
+    }
+    return this._lineEndings;
+}
+
+String.prototype.asParsedURL = function()
+{
+    // RegExp groups:
+    // 1 - scheme
+    // 2 - hostname
+    // 3 - ?port
+    // 4 - ?path
+    // 5 - ?fragment
+    var match = this.match(/^([^:]+):\/\/([^\/:]*)(?::([\d]+))?(?:(\/[^#]*)(?:#(.*))?)?$/i);
+    if (!match)
+        return null;
+    var result = {};
+    result.scheme = match[1].toLowerCase();
+    result.host = match[2];
+    result.port = match[3];
+    result.path = match[4] || "/";
+    result.fragment = match[5];
+    return result;
+}
+
+String.prototype.escapeCharacters = function(chars)
+{
+    var foundChar = false;
+    for (var i = 0; i < chars.length; ++i) {
+        if (this.indexOf(chars.charAt(i)) !== -1) {
+            foundChar = true;
+            break;
+        }
+    }
+
+    if (!foundChar)
+        return this;
+
+    var result = "";
+    for (var i = 0; i < this.length; ++i) {
+        if (chars.indexOf(this.charAt(i)) !== -1)
+            result += "\\";
+        result += this.charAt(i);
+    }
+
+    return result;
+}
+
+String.prototype.escapeForRegExp = function()
+{
+    return this.escapeCharacters("^[]{}()\\.$*+?|");
+}
+
+String.prototype.escapeHTML = function()
+{
+    return this.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
+}
+
+String.prototype.collapseWhitespace = function()
+{
+    return this.replace(/[\s\xA0]+/g, " ");
+}
+
+String.prototype.trimURL = function(baseURLDomain)
+{
+    var result = this.replace(/^(https|http|file):\/\//i, "");
+    if (baseURLDomain)
+        result = result.replace(new RegExp("^" + baseURLDomain.escapeForRegExp(), "i"), "");
+    return result;
+}
+
+function isNodeWhitespace()
+{
+    if (!this || this.nodeType !== Node.TEXT_NODE)
+        return false;
+    if (!this.nodeValue.length)
+        return true;
+    return this.nodeValue.match(/^[\s\xA0]+$/);
+}
+
+function nodeDisplayName()
+{
+    if (!this)
+        return "";
+
+    switch (this.nodeType) {
+        case Node.DOCUMENT_NODE:
+            return "Document";
+
+        case Node.ELEMENT_NODE:
+            var name = "<" + this.nodeName.toLowerCase();
+
+            if (this.hasAttributes()) {
+                var value = this.getAttribute("id");
+                if (value)
+                    name += " id=\"" + value + "\"";
+                value = this.getAttribute("class");
+                if (value)
+                    name += " class=\"" + value + "\"";
+                if (this.nodeName.toLowerCase() === "a") {
+                    value = this.getAttribute("name");
+                    if (value)
+                        name += " name=\"" + value + "\"";
+                    value = this.getAttribute("href");
+                    if (value)
+                        name += " href=\"" + value + "\"";
+                } else if (this.nodeName.toLowerCase() === "img") {
+                    value = this.getAttribute("src");
+                    if (value)
+                        name += " src=\"" + value + "\"";
+                } else if (this.nodeName.toLowerCase() === "iframe") {
+                    value = this.getAttribute("src");
+                    if (value)
+                        name += " src=\"" + value + "\"";
+                } else if (this.nodeName.toLowerCase() === "input") {
+                    value = this.getAttribute("name");
+                    if (value)
+                        name += " name=\"" + value + "\"";
+                    value = this.getAttribute("type");
+                    if (value)
+                        name += " type=\"" + value + "\"";
+                } else if (this.nodeName.toLowerCase() === "form") {
+                    value = this.getAttribute("action");
+                    if (value)
+                        name += " action=\"" + value + "\"";
+                }
+            }
+
+            return name + ">";
+
+        case Node.TEXT_NODE:
+            if (isNodeWhitespace.call(this))
+                return "(whitespace)";
+            return "\"" + this.nodeValue + "\"";
+
+        case Node.COMMENT_NODE:
+            return "<!--" + this.nodeValue + "-->";
+            
+        case Node.DOCUMENT_TYPE_NODE:
+            var docType = "<!DOCTYPE " + this.nodeName;
+            if (this.publicId) {
+                docType += " PUBLIC \"" + this.publicId + "\"";
+                if (this.systemId)
+                    docType += " \"" + this.systemId + "\"";
+            } else if (this.systemId)
+                docType += " SYSTEM \"" + this.systemId + "\"";
+            if (this.internalSubset)
+                docType += " [" + this.internalSubset + "]";
+            return docType + ">";
+    }
+
+    return this.nodeName.toLowerCase().collapseWhitespace();
+}
+
+function isAncestorNode(ancestor, node)
+{
+    if (!node || !ancestor)
+        return false;
+
+    var currentNode = node.parentNode;
+    while (currentNode) {
+        if (ancestor === currentNode)
+            return true;
+        currentNode = currentNode.parentNode;
+    }
+    return false;
+}
+
+function isDescendantNode(descendant)
+{
+    return isAncestorNode(descendant, this);
+}
+
+function traverseNextNode(stayWithin)
+{
+    if (!this)
+        return;
+
+    var node = this.firstChild;
+    if (node)
+        return node;
+
+    if (stayWithin && this === stayWithin)
+        return null;
+
+    node = this.nextSibling;
+    if (node)
+        return node;
+
+    node = this;
+    while (node && !node.nextSibling && (!stayWithin || !node.parentNode || node.parentNode !== stayWithin))
+        node = node.parentNode;
+    if (!node)
+        return null;
+
+    return node.nextSibling;
+}
+
+function traversePreviousNode(stayWithin)
+{
+    if (!this)
+        return;
+    if (stayWithin && this === stayWithin)
+        return null;
+    var node = this.previousSibling;
+    while (node && node.lastChild)
+        node = node.lastChild;
+    if (node)
+        return node;
+    return this.parentNode;
+}
+
+function onlyTextChild()
+{
+    if (!this)
+        return null;
+
+    var firstChild = this.firstChild;
+    if (!firstChild || firstChild.nodeType !== Node.TEXT_NODE)
+        return null;
+
+    var sibling = firstChild.nextSibling;
+    return sibling ? null : firstChild;
+}
+
+function appropriateSelectorForNode(node, justSelector)
+{
+    if (!node)
+        return "";
+
+    var lowerCaseName = node.localName || node.nodeName.toLowerCase();
+
+    var id = node.getAttribute("id");
+    if (id) {
+        var selector = "#" + id;
+        return (justSelector ? selector : lowerCaseName + selector);
+    }
+
+    var className = node.getAttribute("class");
+    if (className) {
+        var selector = "." + className.replace(/\s+/, ".");
+        return (justSelector ? selector : lowerCaseName + selector);
+    }
+
+    if (lowerCaseName === "input" && node.getAttribute("type"))
+        return lowerCaseName + "[type=\"" + node.getAttribute("type") + "\"]";
+
+    return lowerCaseName;
+}
+
+function getDocumentForNode(node)
+{
+    return node.nodeType == Node.DOCUMENT_NODE ? node : node.ownerDocument;
+}
+
+function parentNode(node)
+{
+    return node.parentNode;
+}
+
+Number.millisToString = function(ms, higherResolution)
+{
+    return Number.secondsToString(ms / 1000, higherResolution);
+}
+
+Number.secondsToString = function(seconds, higherResolution)
+{
+    if (seconds === 0)
+        return "0";
+
+    var ms = seconds * 1000;
+    if (higherResolution && ms < 1000)
+        return WebInspector.UIString("%.3fms", ms);
+    else if (ms < 1000)
+        return WebInspector.UIString("%.0fms", ms);
+
+    if (seconds < 60)
+        return WebInspector.UIString("%.2fs", seconds);
+
+    var minutes = seconds / 60;
+    if (minutes < 60)
+        return WebInspector.UIString("%.1fmin", minutes);
+
+    var hours = minutes / 60;
+    if (hours < 24)
+        return WebInspector.UIString("%.1fhrs", hours);
+
+    var days = hours / 24;
+    return WebInspector.UIString("%.1f days", days);
+}
+
+Number.bytesToString = function(bytes, higherResolution)
+{
+    if (typeof higherResolution === "undefined")
+        higherResolution = true;
+
+    if (bytes < 1024)
+        return WebInspector.UIString("%.0fB", bytes);
+
+    var kilobytes = bytes / 1024;
+    if (higherResolution && kilobytes < 1024)
+        return WebInspector.UIString("%.2fKB", kilobytes);
+    else if (kilobytes < 1024)
+        return WebInspector.UIString("%.0fKB", kilobytes);
+
+    var megabytes = kilobytes / 1024;
+    if (higherResolution)
+        return WebInspector.UIString("%.2fMB", megabytes);
+    else
+        return WebInspector.UIString("%.0fMB", megabytes);
+}
+
+Number.constrain = function(num, min, max)
+{
+    if (num < min)
+        num = min;
+    else if (num > max)
+        num = max;
+    return num;
+}
+
+HTMLTextAreaElement.prototype.moveCursorToEnd = function()
+{
+    var length = this.value.length;
+    this.setSelectionRange(length, length);
+}
+
+Object.defineProperty(Array.prototype, "remove", { value: function(value, onlyFirst)
+{
+    if (onlyFirst) {
+        var index = this.indexOf(value);
+        if (index !== -1)
+            this.splice(index, 1);
+        return;
+    }
+
+    var length = this.length;
+    for (var i = 0; i < length; ++i) {
+        if (this[i] === value)
+            this.splice(i, 1);
+    }
+}});
+
+Object.defineProperty(Array.prototype, "keySet", { value: function()
+{
+    var keys = {};
+    for (var i = 0; i < this.length; ++i)
+        keys[this[i]] = true;
+    return keys;
+}});
+
+Object.defineProperty(Array.prototype, "upperBound", { value: function(value)
+{
+    var first = 0;
+    var count = this.length;
+    while (count > 0) {
+      var step = count >> 1;
+      var middle = first + step;
+      if (value >= this[middle]) {
+          first = middle + 1;
+          count -= step + 1;
+      } else
+          count = step;
+    }
+    return first;
+}});
+
+Array.diff = function(left, right)
+{
+    var o = left;
+    var n = right;
+
+    var ns = {};
+    var os = {};
+
+    for (var i = 0; i < n.length; i++) {
+        if (ns[n[i]] == null)
+            ns[n[i]] = { rows: [], o: null };
+        ns[n[i]].rows.push(i);
+    }
+
+    for (var i = 0; i < o.length; i++) {
+        if (os[o[i]] == null)
+            os[o[i]] = { rows: [], n: null };
+        os[o[i]].rows.push(i);
+    }
+
+    for (var i in ns) {
+        if (ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1) {
+            n[ns[i].rows[0]] = { text: n[ns[i].rows[0]], row: os[i].rows[0] };
+            o[os[i].rows[0]] = { text: o[os[i].rows[0]], row: ns[i].rows[0] };
+        }
+    }
+
+    for (var i = 0; i < n.length - 1; i++) {
+        if (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null && n[i + 1] == o[n[i].row + 1]) {
+            n[i + 1] = { text: n[i + 1], row: n[i].row + 1 };
+            o[n[i].row + 1] = { text: o[n[i].row + 1], row: i + 1 };
+        }
+    }
+
+    for (var i = n.length - 1; i > 0; i--) {
+        if (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null && 
+            n[i - 1] == o[n[i].row - 1]) {
+            n[i - 1] = { text: n[i - 1], row: n[i].row - 1 };
+            o[n[i].row - 1] = { text: o[n[i].row - 1], row: i - 1 };
+        }
+    }
+
+    return { left: o, right: n };
+}
+
+Array.convert = function(list)
+{
+    // Cast array-like object to an array.
+    return Array.prototype.slice.call(list);
+}
+
+function insertionIndexForObjectInListSortedByFunction(anObject, aList, aFunction)
+{
+    var first = 0;
+    var last = aList.length - 1;
+    var floor = Math.floor;
+    var mid, c;
+
+    while (first <= last) {
+        mid = floor((first + last) / 2);
+        c = aFunction(anObject, aList[mid]);
+
+        if (c > 0)
+            first = mid + 1;
+        else if (c < 0)
+            last = mid - 1;
+        else {
+            // Return the first occurance of an item in the list.
+            while (mid > 0 && aFunction(anObject, aList[mid - 1]) === 0)
+                mid--;
+            first = mid;
+            break;
+        }
+    }
+
+    return first;
+}
+
+String.sprintf = function(format)
+{
+    return String.vsprintf(format, Array.prototype.slice.call(arguments, 1));
+}
+
+String.tokenizeFormatString = function(format)
+{
+    var tokens = [];
+    var substitutionIndex = 0;
+
+    function addStringToken(str)
+    {
+        tokens.push({ type: "string", value: str });
+    }
+
+    function addSpecifierToken(specifier, precision, substitutionIndex)
+    {
+        tokens.push({ type: "specifier", specifier: specifier, precision: precision, substitutionIndex: substitutionIndex });
+    }
+
+    var index = 0;
+    for (var precentIndex = format.indexOf("%", index); precentIndex !== -1; precentIndex = format.indexOf("%", index)) {
+        addStringToken(format.substring(index, precentIndex));
+        index = precentIndex + 1;
+
+        if (format[index] === "%") {
+            addStringToken("%");
+            ++index;
+            continue;
+        }
+
+        if (!isNaN(format[index])) {
+            // The first character is a number, it might be a substitution index.
+            var number = parseInt(format.substring(index));
+            while (!isNaN(format[index]))
+                ++index;
+            // If the number is greater than zero and ends with a "$",
+            // then this is a substitution index.
+            if (number > 0 && format[index] === "$") {
+                substitutionIndex = (number - 1);
+                ++index;
+            }
+        }
+
+        var precision = -1;
+        if (format[index] === ".") {
+            // This is a precision specifier. If no digit follows the ".",
+            // then the precision should be zero.
+            ++index;
+            precision = parseInt(format.substring(index));
+            if (isNaN(precision))
+                precision = 0;
+            while (!isNaN(format[index]))
+                ++index;
+        }
+
+        addSpecifierToken(format[index], precision, substitutionIndex);
+
+        ++substitutionIndex;
+        ++index;
+    }
+
+    addStringToken(format.substring(index));
+
+    return tokens;
+}
+
+String.standardFormatters = {
+    d: function(substitution)
+    {
+        if (typeof substitution == "object" && WebInspector.RemoteObject.type(substitution) === "number")
+            substitution = substitution.description;
+        substitution = parseInt(substitution);
+        return !isNaN(substitution) ? substitution : 0;
+    },
+
+    f: function(substitution, token)
+    {
+        if (typeof substitution == "object" && WebInspector.RemoteObject.type(substitution) === "number")
+            substitution = substitution.description;
+        substitution = parseFloat(substitution);
+        if (substitution && token.precision > -1)
+            substitution = substitution.toFixed(token.precision);
+        return !isNaN(substitution) ? substitution : (token.precision > -1 ? Number(0).toFixed(token.precision) : 0);
+    },
+
+    s: function(substitution)
+    {
+        if (typeof substitution == "object" && WebInspector.RemoteObject.type(substitution) !== "null")
+            substitution = substitution.description;
+        return substitution;
+    },
+};
+
+String.vsprintf = function(format, substitutions)
+{
+    return String.format(format, substitutions, String.standardFormatters, "", function(a, b) { return a + b; }).formattedResult;
+}
+
+String.format = function(format, substitutions, formatters, initialValue, append)
+{
+    if (!format || !substitutions || !substitutions.length)
+        return { formattedResult: append(initialValue, format), unusedSubstitutions: substitutions };
+
+    function prettyFunctionName()
+    {
+        return "String.format(\"" + format + "\", \"" + substitutions.join("\", \"") + "\")";
+    }
+
+    function warn(msg)
+    {
+        console.warn(prettyFunctionName() + ": " + msg);
+    }
+
+    function error(msg)
+    {
+        console.error(prettyFunctionName() + ": " + msg);
+    }
+
+    var result = initialValue;
+    var tokens = String.tokenizeFormatString(format);
+    var usedSubstitutionIndexes = {};
+
+    for (var i = 0; i < tokens.length; ++i) {
+        var token = tokens[i];
+
+        if (token.type === "string") {
+            result = append(result, token.value);
+            continue;
+        }
+
+        if (token.type !== "specifier") {
+            error("Unknown token type \"" + token.type + "\" found.");
+            continue;
+        }
+
+        if (token.substitutionIndex >= substitutions.length) {
+            // If there are not enough substitutions for the current substitutionIndex
+            // just output the format specifier literally and move on.
+            error("not enough substitution arguments. Had " + substitutions.length + " but needed " + (token.substitutionIndex + 1) + ", so substitution was skipped.");
+            result = append(result, "%" + (token.precision > -1 ? token.precision : "") + token.specifier);
+            continue;
+        }
+
+        usedSubstitutionIndexes[token.substitutionIndex] = true;
+
+        if (!(token.specifier in formatters)) {
+            // Encountered an unsupported format character, treat as a string.
+            warn("unsupported format character \u201C" + token.specifier + "\u201D. Treating as a string.");
+            result = append(result, substitutions[token.substitutionIndex]);
+            continue;
+        }
+
+        result = append(result, formatters[token.specifier](substitutions[token.substitutionIndex], token));
+    }
+
+    var unusedSubstitutions = [];
+    for (var i = 0; i < substitutions.length; ++i) {
+        if (i in usedSubstitutionIndexes)
+            continue;
+        unusedSubstitutions.push(substitutions[i]);
+    }
+
+    return { formattedResult: result, unusedSubstitutions: unusedSubstitutions };
+}
+
+function isEnterKey(event) {
+    // Check if in IME.
+    return (event.keyCode !== 229 && event.keyIdentifier === "Enter") || event.keyCode == 13 || event.charCode == 13;
+}
+
+
+function highlightSearchResult(element, offset, length)
+{
+    var lineText = element.textContent;
+    var endOffset = offset + length;
+    var highlightNode = document.createElement("span");
+    highlightNode.className = "webkit-search-result";
+    highlightNode.textContent = lineText.substring(offset, endOffset);
+
+    var boundary = element.rangeBoundaryForOffset(offset);
+    var textNode = boundary.container;
+    var text = textNode.textContent;
+
+    if (boundary.offset + length < text.length) {
+        // Selection belong to a single split mode.
+        textNode.textContent = text.substring(boundary.offset + length);
+        textNode.parentElement.insertBefore(highlightNode, textNode);
+        var prefixNode = document.createTextNode(text.substring(0, boundary.offset));
+        textNode.parentElement.insertBefore(prefixNode, highlightNode);
+        return highlightNode;
+    }
+
+    var parentElement = textNode.parentElement;
+    var anchorElement = textNode.nextSibling;
+
+    length -= text.length - boundary.offset;
+    textNode.textContent = text.substring(0, boundary.offset);
+    textNode = textNode.traverseNextTextNode(element);
+
+    while (textNode) {
+        var text = textNode.textContent;
+        if (length < text.length) {
+            textNode.textContent = text.substring(length);
+            break;
+        }
+
+        length -= text.length;
+        textNode.textContent = "";
+        textNode = textNode.traverseNextTextNode(element);
+    }
+
+    parentElement.insertBefore(highlightNode, anchorElement);
+    return highlightNode;
+}
+
+function createSearchRegex(query)
+{
+    var regex = "";
+    for (var i = 0; i < query.length; ++i) {
+        var char = query.charAt(i);
+        if (char === "]")
+            char = "\\]";
+        regex += "[" + char + "]";
+    }
+    return new RegExp(regex, "i");
+}
+
+function offerFileForDownload(contents)
+{
+    var builder = new BlobBuilder();
+    builder.append(contents);
+    var blob = builder.getBlob("application/octet-stream");
+    var url = window.webkitURL.createObjectURL(blob);
+    window.open(url);
+}
diff --git a/weinre.build/vendor/webkit/WebCore/inspector/front-end/AuditLauncherView.js b/weinre.build/vendor/webkit/WebCore/inspector/front-end/AuditLauncherView.js
index df16a41..e7ab735 100644
--- a/weinre.build/vendor/webkit/WebCore/inspector/front-end/AuditLauncherView.js
+++ b/weinre.build/vendor/webkit/WebCore/inspector/front-end/AuditLauncherView.js
@@ -101,7 +101,7 @@
             return aTitle.localeCompare(bTitle);
         }
         var insertBefore = insertionIndexForObjectInListSortedByFunction(category, this._sortedCategories, compareCategories);
-        this._categoriesElement.insertBefore(categoryElement, this._categoriesElement.children[insertBefore]);
+        this._categoriesElement.insertBefore(categoryElement, this._categoriesElement.children[insertBefore] || null);
         this._sortedCategories.splice(insertBefore, 0, category);
         this._updateButton();
     },
diff --git a/weinre.build/vendor/webkit/WebCore/inspector/front-end/ConsoleView.js b/weinre.build/vendor/webkit/WebCore/inspector/front-end/ConsoleView.js
index 35d1ebf..42fd799 100644
--- a/weinre.build/vendor/webkit/WebCore/inspector/front-end/ConsoleView.js
+++ b/weinre.build/vendor/webkit/WebCore/inspector/front-end/ConsoleView.js
@@ -45,6 +45,7 @@
     this.messagesElement.addEventListener("click", this._messagesClicked.bind(this), true);
 
     this.promptElement = document.getElementById("console-prompt");
+    this.promptElement.setAttribute("contenteditable", "true");
     this.promptElement.className = "source-code";
     this.promptElement.addEventListener("keydown", this._promptKeyDown.bind(this), true);
     this.prompt = new WebInspector.TextPrompt(this.promptElement, this.completions.bind(this), ExpressionStopCharacters + ".");
diff --git a/weinre.build/vendor/webkit/WebCore/inspector/front-end/ElementsTreeOutline.js b/weinre.build/vendor/webkit/WebCore/inspector/front-end/ElementsTreeOutline.js
index 56c3e75..dab33a6 100644
--- a/weinre.build/vendor/webkit/WebCore/inspector/front-end/ElementsTreeOutline.js
+++ b/weinre.build/vendor/webkit/WebCore/inspector/front-end/ElementsTreeOutline.js
@@ -1060,7 +1060,11 @@
             var previous = element.previousSibling;
             if (!previous || previous.nodeType !== Node.TEXT_NODE)
                 element.parentNode.insertBefore(document.createTextNode(" "), element);
-            element.outerHTML = this._attributeHTML(name, value);
+
+            // outerHTML should not be used to replace node content in IE, updated with replaceChild usage
+			element.innerHTML = this._attributeHTML(name, value);
+			element.parentNode.replaceChild(element.firstChild, element);
+            //element.outerHTML = this._attributeHTML(name, value);
         }
 
         var parseContainerElement = document.createElement("span");
diff --git a/weinre.build/vendor/webkit/WebCore/inspector/front-end/Settings.js b/weinre.build/vendor/webkit/WebCore/inspector/front-end/Settings.js
index 68b81a5..f20078a 100644
--- a/weinre.build/vendor/webkit/WebCore/inspector/front-end/Settings.js
+++ b/weinre.build/vendor/webkit/WebCore/inspector/front-end/Settings.js
@@ -85,14 +85,17 @@
         if (key in this)
             return;
 
-        this.__defineGetter__(key, this._get.bind(this, key, defaultValue));
-        this.__defineSetter__(key, this._set.bind(this, key));
+        Object.defineProperty(this, key,{
+            get : this._get.bind(this, key, defaultValue),
+            set : this._set.bind(this, key)});
     },
 
     installProjectSetting: function(key, defaultValue)
     {
-        this.__defineGetter__(key, this._getProjectSetting.bind(this, key, defaultValue));
-        this.__defineSetter__(key, this._setProjectSetting.bind(this, key));
+        Object.defineProperty(this, key,{
+            get : this._getProjectSetting.bind(this, key, defaultValue),
+            set : this._setProjectSetting.bind(this, key)});
+
     },
 
     inspectedURLChanged: function(url)
diff --git a/weinre.build/vendor/webkit/WebCore/inspector/front-end/StylesSidebarPane.js b/weinre.build/vendor/webkit/WebCore/inspector/front-end/StylesSidebarPane.js
index 57d3b76..211b059 100644
--- a/weinre.build/vendor/webkit/WebCore/inspector/front-end/StylesSidebarPane.js
+++ b/weinre.build/vendor/webkit/WebCore/inspector/front-end/StylesSidebarPane.js
@@ -402,6 +402,7 @@
 
     _rebuildSectionsForStyleRules: function(styleRules, usedProperties, disabledComputedProperties, pseudoId, anchorElement)
     {
+        anchorElement = anchorElement || null;
         // Make a property section for each style rule.
         var sections = [];
         var lastWasSeparator = true;
@@ -1534,7 +1535,7 @@
             expanded: this.expanded,
             hasChildren: this.hasChildren,
             keyDownListener: isEditingName ? null : this.editingValueKeyDown.bind(this),
-            isEditingName: isEditingName,
+            isEditingName: isEditingName
         };
 
         // Lie about our children to prevent expanding on double click and to collapse shorthands.
@@ -1625,8 +1626,9 @@
     {
         if (event.handled)
             return;
-        var arrowKeyPressed = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down");
-        var pageKeyPressed = (event.keyIdentifier === "PageUp" || event.keyIdentifier === "PageDown");
+        var key = event.keyIdentifier || event.key;
+        var arrowKeyPressed = (key === "Up" || key === "Down");
+        var pageKeyPressed = (key === "PageUp" || key === "PageDown");
         if (!arrowKeyPressed && !pageKeyPressed)
             return;
 
@@ -1650,13 +1652,13 @@
 
             // If the number is near zero or the number is one and the direction will take it near zero.
             var numberNearZero = (number < 1 && number > -1);
-            if (number === 1 && event.keyIdentifier === "Down")
+            if (number === 1 && key === "Down")
                 numberNearZero = true;
-            else if (number === -1 && event.keyIdentifier === "Up")
+            else if (number === -1 && key === "Up")
                 numberNearZero = true;
 
             if (numberNearZero && event.altKey && arrowKeyPressed) {
-                if (event.keyIdentifier === "Down")
+                if (key === "Down")
                     number = Math.ceil(number - 1);
                 else
                     number = Math.floor(number + 1);
@@ -1671,7 +1673,7 @@
                 else if (event.altKey || numberNearZero)
                     changeAmount = 0.1;
 
-                if (event.keyIdentifier === "Down" || event.keyIdentifier === "PageDown")
+                if (key === "Down" || key === "PageDown")
                     changeAmount *= -1;
 
                 // Make the new number and constrain it to a precision of 6, this matches numbers the engine returns.
@@ -1926,7 +1928,7 @@
 
     _handleNameOrValueUpDown: function(event)
     {
-        var reverse = event.keyIdentifier === "Up";
+        var reverse = (event.keyIdentifier || event.key) === "Up";
         if (this.autoCompleteElement)
             this.complete(false, reverse); // Accept the current suggestion, if any.
         else {
@@ -1956,6 +1958,8 @@
 
     _buildPropertyCompletions: function(wordRange, bestMatchOnly, completionsReadyCallback)
     {
+        if (!this._cssCompletions) return;
+
         var prefix = wordRange.toString().toLowerCase();
         var results;
         if (bestMatchOnly) {
diff --git a/weinre.build/vendor/webkit/WebCore/inspector/front-end/TextPrompt.js b/weinre.build/vendor/webkit/WebCore/inspector/front-end/TextPrompt.js
index 36a38cc..684dfa7 100644
--- a/weinre.build/vendor/webkit/WebCore/inspector/front-end/TextPrompt.js
+++ b/weinre.build/vendor/webkit/WebCore/inspector/front-end/TextPrompt.js
@@ -51,7 +51,12 @@
         if (!x) {
             // Append a break element instead of setting textContent to make sure the selection is inside the prompt.
             this.element.removeChildren();
+
+            // For IE  we don't need a <br> to correctly set console caret; otherwise there will be two lines (incorrect) instead of one
+            if (!navigator.userAgent.match(/MSIE/i)) {
+			
             this.element.appendChild(document.createElement("br"));
+            }
         } else
             this.element.textContent = x;
 
@@ -75,9 +80,10 @@
         if (event.handled)
             return;
 
-        var handled = false;
+        var handled = false,
+            key = event.keyIdentifier || event.key;
 
-        switch (event.keyIdentifier) {
+        switch (key) {
             case "Up":
                 this.upKeyPressed(event);
                 break;
@@ -118,6 +124,11 @@
                 break;
         }
 
+        if (event.keyCode == 13 || event.charCode == 13) {
+            handled = true;
+            event.target.blur();
+        }
+
         handled |= event.handled;
         if (handled) {
             event.handled = true;
diff --git a/weinre.build/vendor/webkit/WebCore/inspector/front-end/inspector.css b/weinre.build/vendor/webkit/WebCore/inspector/front-end/inspector.css
index c992806..d188ce4 100644
--- a/weinre.build/vendor/webkit/WebCore/inspector/front-end/inspector.css
+++ b/weinre.build/vendor/webkit/WebCore/inspector/front-end/inspector.css
@@ -43,11 +43,17 @@
     font-size: 10px;
     margin: 0;
     -webkit-text-size-adjust: none;
+    -ms-text-size-adjust: none;
+	-moz-text-size-adjust: none;
     -webkit-user-select: none;
+	-ms-user-select: none;
+	-moz-user-select: none;
 }
 
 * {
     -webkit-box-sizing: border-box;
+    box-sizing: border-box;
+	-moz-box-sizing: border-box;
 }
 
 :focus {
@@ -77,16 +83,24 @@
     right: 0;
     height: 56px;
     display: -webkit-box;
+    display: -ms-flexbox;
+	display: -moz-box;
     padding: 0 5px;
     background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(191, 191, 191)), to(rgb(151, 151, 151)));
+    background-image: linear-gradient(to bottom, rgb(191, 191, 191) 0%, rgb(151, 151, 151) 100%);
     border-bottom: 1px solid rgb(80, 80, 80);
     -webkit-box-orient: horizontal;
     -webkit-background-origin: padding;
     -webkit-background-clip: padding;
+    -ms-flex-direction: row;
+	-moz-box-orient: horizontal;
+    background-origin: padding;
+    background-clip: padding;
 }
 
 body.inactive #toolbar {
     background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(233, 233, 233)), to(rgb(207, 207, 207)));
+    background-image: linear-gradient(to bottom, rgb(233, 233, 233) 0%, rgb(207, 207, 207) 100%);
     border-bottom: 1px solid rgb(64%, 64%, 64%);
 }
 
@@ -112,6 +126,8 @@
 
 .toolbar-item {
     display: -webkit-box;
+    display: -ms-flexbox;
+	display: -moz-box;
     padding: 4px 6px;
     margin: 0;
     background-color: transparent;
@@ -120,16 +136,26 @@
     -webkit-box-orient: vertical;
     -webkit-box-align: center;
     -webkit-box-pack: end;
+    -ms-flex-direction: column;
+    -ms-flex-align: center;
+    -ms-flex-pack: end;
+	-moz-box-orient: vertical;
+	-moz-box-align: center;
+	-moz-box-pack: end;
 }
 
 .toolbar-item.toggleable.toggled-on {
     border-width: 0 2px 0 2px;
     padding: 4px 4px;
     -webkit-border-image: url(Images/toolbarItemSelected.png) 0 2 0 2;
+	border-image: url(Images/toolbarItemSelected.png) 0 2 0 2;
+	border-style: solid;
 }
 
 .toolbar-item.flexable-space {
     -webkit-box-flex: 1;
+    -ms-flex: 1;
+	-moz-box-flex: 1;
     visibility: hidden;
 }
 
@@ -142,6 +168,7 @@
     width: 32px;
     height: 32px;
     -webkit-background-size: 100% auto;
+    background-size: 100% auto;
 }
 
 body.attached .toolbar-icon {
@@ -399,13 +426,17 @@
     color: rgb(48, 48, 48);
     text-shadow: rgba(255, 255, 255, 0.75) 0 1px 0;
     -webkit-border-image: url(Images/statusbarMenuButton.png) 0 17 0 2;
+	border-image: url(Images/statusbarMenuButton.png) 0 17 0 2;
     -webkit-border-radius: 0;
+	border-radius: 0;
     -webkit-appearance: none;
+	-moz-appearance: none;
 }
 
 select.status-bar-item:active {
     color: black;
     -webkit-border-image: url(Images/statusbarMenuButtonSelected.png) 0 17 0 2;
+	border-image: url(Images/statusbarMenuButtonSelected.png) 0 17 0 2;
 }
 
 #dock-status-bar-item .glyph {
@@ -525,10 +556,15 @@
     right: 0;
     bottom: 23px;
     padding: 2px 0;
-    overflow-y: overlay;
+	overflow-y: auto;
+	overflow-y: overlay;
     word-wrap: break-word;
     -webkit-user-select: text;
+	-ms-user-select: text;
+	-moz-user-select: text;
     -webkit-text-size-adjust: auto;
+    -ms-text-size-adjust: auto;
+	-moz-text-size-adjust: auto;
 }
 
 #console-prompt {
@@ -537,6 +573,7 @@
     min-height: 16px; 
     white-space: pre-wrap;
     -webkit-user-modify: read-write-plaintext-only;
+	-moz-user-modify: read-write;
 }
 
 #console-prompt::before {
@@ -572,6 +609,68 @@
     height: 10px;
     margin-top: -5px;
     -webkit-user-select: none;
+	-ms-user-select: none;
+	-moz-user-select: none;
+}
+
+/* Hack to detect IE*/
+@media screen\0 {
+    /* Set image directly to console div element instead of using pseudo selector
+    since it causes displaying caret in incorrecty place*/
+    #console-prompt {
+        background: url(Images/userInputIcon.png) 7px 5px no-repeat;
+    }
+
+    #console-prompt::before{
+        content: none !important;
+    }
+
+    /*Set icons as background-image since IE doesn't support -webkit-mask-image*/
+    #console-status-bar-item .glyph {
+        background-image: url(Images/consoleButtonGlyph.png);
+    }
+
+    .clear-status-bar-item .glyph {
+        background-image: url(Images/clearConsoleButtonGlyph.png);
+    }
+
+    .node-search-status-bar-item .glyph {
+        background-image: url(Images/nodeSearchButtonGlyph.png);
+    }
+
+    #console-status-bar-item .glyph,
+    .clear-status-bar-item .glyph,
+    .node-search-status-bar-item .glyph{
+        background-color: transparent;
+    }
+
+    /*Set background image for selected tab since IE doesn't support border-image property*/
+    .toolbar-item.toggleable.toggled-on {
+        background: url(Images/toolbarItemSelected.png);
+        background-size: 1px 100%;
+    }
+}
+
+/* Hack to detect Firefox*/
+@-moz-document url-prefix() {
+  	/*Set icons as background-image since FF doesn't support mask-image*/
+    #console-status-bar-item .glyph {
+        background-image: url(Images/consoleButtonGlyph.png);
+    }
+
+    .clear-status-bar-item .glyph {
+        background-image: url(Images/clearConsoleButtonGlyph.png);
+    }
+
+    .node-search-status-bar-item .glyph {
+        background-image: url(Images/nodeSearchButtonGlyph.png);
+    }
+
+    #console-status-bar-item .glyph,
+    .clear-status-bar-item .glyph,
+    .node-search-status-bar-item .glyph{
+        background-color: transparent;
+    }
 }
 
 .console-message .bubble {
@@ -591,6 +690,7 @@
     text-shadow: none;
     color: white;
     -webkit-border-radius: 7px;
+    border-radius: 7px;
 }
 
 .console-message-text {
@@ -770,7 +870,10 @@
 .auto-complete-text, .editing .auto-complete-text {
     color: rgb(128, 128, 128) !important;
     -webkit-user-select: none;
+	-ms-user-select: none;
+	-moz-user-select: none;
     -webkit-user-modify: read-only;
+	-moz-user-modify: read-only;
 }
 
 .panel {
@@ -830,6 +933,8 @@
     padding-bottom: 10px;
     font-size: 11px;
     -webkit-user-select: text;
+	-ms-user-select: text;
+	-moz-user-select: text;
 }
 
 .resource-view.image img.resource-image-view {
@@ -837,7 +942,10 @@
     max-height: 1000px;
     background-image: url(Images/checker.png);
     -webkit-box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.5);
+    box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.5);
     -webkit-user-select: text;
+	-ms-user-select: text;
+	-moz-user-select: text;
     -webkit-user-drag: auto;
 }
 
@@ -932,6 +1040,7 @@
     height: 24px;
     border-width: 0 12px 0 2px;
     -webkit-border-image: url(Images/segment.png) 0 12 0 2;
+	border-image: url(Images/segment.png) 0 12 0 2;
     margin-right: -12px;
     padding-left: 18px;
     padding-right: 2px;
@@ -965,34 +1074,41 @@
     border-width: 0 2px 0 2px;
     padding-right: 6px;
     -webkit-border-image: url(Images/segmentEnd.png) 0 2 0 2;
+	border-image: url(Images/segmentEnd.png) 0 2 0 2;
 }
 
 .crumbs .crumb.selected {
     -webkit-border-image: url(Images/segmentSelected.png) 0 12 0 2;
+	border-image: url(Images/segmentSelected.png) 0 12 0 2;
     color: black;
     text-shadow: rgba(255, 255, 255, 0.5) 0 1px 0;
 }
 
 .crumbs .crumb.selected:hover {
     -webkit-border-image: url(Images/segmentSelected.png) 0 12 0 2;
+	border-image: url(Images/segmentSelected.png) 0 12 0 2;
 }
 
 .crumbs .crumb.selected.end, .crumbs .crumb.selected.end:hover {
     -webkit-border-image: url(Images/segmentSelectedEnd.png) 0 2 0 2;
+	border-image: url(Images/segmentSelectedEnd.png) 0 2 0 2;
 }
 
 .crumbs .crumb:hover {
     -webkit-border-image: url(Images/segmentHover.png) 0 12 0 2;
+	border-image: url(Images/segmentHover.png) 0 12 0 2;
     color: black;
 }
 
 .crumbs .crumb.dimmed:hover {
     -webkit-border-image: url(Images/segmentHover.png) 0 12 0 2;
+	border-image: url(Images/segmentHover.png) 0 12 0 2;
     color: rgba(0, 0, 0, 0.75);
 }
 
 .crumbs .crumb.end:hover {
     -webkit-border-image: url(Images/segmentHoverEnd.png) 0 2 0 2;
+	border-image: url(Images/segmentHoverEnd.png) 0 2 0 2;
 }
 
 .outline-disclosure li.hovered:not(.selected) .selection {
@@ -1001,11 +1117,13 @@
     right: 3px;
     background-color: rgba(56, 121, 217, 0.1);
     -webkit-border-radius: 5px;
+    border-radius: 5px;
 }
 
 .outline-disclosure li.highlighted .highlight {
     background-color: rgb(255, 230, 179);
     -webkit-border-radius: 4px;
+    border-radius: 4px;
     padding-bottom: 2px;
     margin-bottom: -2px;
 }
@@ -1050,6 +1168,7 @@
 .outline-disclosure, .outline-disclosure ol {
     list-style-type: none;
     -webkit-padding-start: 12px;
+	-moz-padding-start: 12px;
     margin: 0;
 }
 
@@ -1141,18 +1260,23 @@
 .placard.selected {
     border-top: 1px solid rgb(145, 160, 192);
     background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(162, 177, 207)), to(rgb(120, 138, 177)));
+    background-image: linear-gradient(to bottom, rgb(162, 177, 207) 0%, rgb(120, 138, 177) 100%);
     -webkit-background-origin: padding;
     -webkit-background-clip: padding;
+    background-origin: padding;
+    background-clip: padding;
 }
 
 :focus .placard.selected {
     border-top: 1px solid rgb(68, 128, 200);
     background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(92, 147, 213)), to(rgb(21, 83, 170)));
+    background-image: linear-gradient(to bottom, rgb(92, 147, 213) 0%, rgb(21, 83, 170) 100%);
 }
 
 body.inactive .placard.selected {
     border-top: 1px solid rgb(151, 151, 151);
     background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(180, 180, 180)), to(rgb(138, 138, 138)));
+    background-image: linear-gradient(to bottom, rgb(180, 180, 180) 0%, rgb(138, 138, 138) 100%);
 }
 
 .placard .title {
@@ -1209,6 +1333,8 @@
     white-space: nowrap;
     -webkit-background-origin: padding;
     -webkit-background-clip: padding;
+    background-origin: padding;
+    background-clip: padding;
 }
 
 .section .header::before {
@@ -1286,6 +1412,8 @@
     text-overflow: ellipsis;
     overflow: hidden;
     -webkit-user-select: text;
+	-ms-user-select: text;
+	-moz-user-select: text;
     cursor: auto;
 }
 
@@ -1302,6 +1430,8 @@
     margin-top: 0;
     padding-right: 3px;
     -webkit-user-select: none;
+	-ms-user-select: none;
+	-moz-user-select: none;
     cursor: default;
 }
 
@@ -1319,6 +1449,7 @@
     display: none;
     margin: 0;
     -webkit-padding-start: 12px;
+	-moz-padding-start: 12px;
     list-style: none;
 }
 
@@ -1366,6 +1497,8 @@
     white-space: nowrap;
     -webkit-background-origin: padding;
     -webkit-background-clip: padding;
+    background-origin: padding;
+    background-clip: padding;
 }
 
 .event-bars .event-bar .header .title {
@@ -1394,10 +1527,14 @@
 
 .editing {
     -webkit-user-select: text;
+	-ms-user-select: text;
+	-moz-user-select: text;
     -webkit-box-shadow: rgba(0, 0, 0, .5) 3px 3px 4px;
+    box-shadow: rgba(0, 0, 0, .5) 3px 3px 4px;
     outline: 1px solid rgb(66%, 66%, 66%) !important;
     background-color: white;
     -webkit-user-modify: read-write-plaintext-only;
+	-moz-user-modify: read-write;
     text-overflow: clip !important;
     padding-left: 2px;
     margin-left: -2px;
@@ -1425,7 +1562,10 @@
 
 .elements-tree-editor {
     -webkit-user-select: text;
+	-ms-user-select: text;
+	-moz-user-select: text;
     -webkit-user-modify: read-write-plaintext-only;
+	-moz-user-modify: read-write-plaintext-only;
 }
 
 .section .properties li.editing {
@@ -1512,6 +1652,7 @@
 
 .pane > .title {
     background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(243, 243, 243)), color-stop(0.05, rgb(243, 243, 243)), color-stop(0.05, rgb(230, 230, 230)), to(rgb(209, 209, 209)));
+    background-image: linear-gradient(to bottom, rgb(243, 243, 243) 0%, rgb(243, 243, 243) 10%, rgb(230, 230, 230) 40%, rgb(209, 209, 209) 100%);
     height: 20px;
     padding: 0 5px;
     border-top: 1px solid rgb(189, 189, 189);
@@ -1523,10 +1664,13 @@
     text-shadow: white 0 1px 0;
     -webkit-background-origin: padding;
     -webkit-background-clip: padding;
+    background-origin: padding;
+    background-clip: padding;
 }
 
 .pane > .title:active {
     background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(231, 231, 231)), color-stop(0.05, rgb(231, 231, 231)), color-stop(0.05, rgb(207, 207, 207)), to(rgb(186, 186, 186)));
+    background-image: linear-gradient(to bottom, rgb(231, 231, 231) 0%,rgb(231, 231, 231) 10%, rgb(207, 207, 207) 40%, rgb(186, 186, 186) 100%);
     border-top: 1px solid rgb(178, 178, 178);
     border-bottom: 1px solid rgb(178, 178, 178);
 }
@@ -1556,7 +1700,12 @@
     margin: 1px 0 0 0;
     padding: 0;
     -webkit-border-radius: 0;
+    border-radius: 0;
     -webkit-appearance: none;
+	-moz-appearance: none;
+	/* hack for appearance for non-webkit browsers */
+	padding-left: 10px;
+	padding-right: 13px;
 }
 
 .pane > .title > select:hover {
@@ -1583,7 +1732,9 @@
     margin: 1px 0 0 0;
     padding: 0;
     -webkit-border-radius: 0;
+    border-radius: 0;
     -webkit-appearance: none;
+	-moz-appearance: none;
 }
 
 .pane > .title > button.add:hover {
@@ -1655,7 +1806,9 @@
     margin-left: 0;
     margin-top: 0;
     margin-bottom: 0.25em;
-    vertical-align: bottom;
+    vertical-align: middle;
+    /*Hack for IE - 'box-sizing: border-box' significantly reduce checkbox size so we set it to default*/
+    box-sizing: content-box;
 }
 
 .metrics {
@@ -1833,17 +1986,20 @@
 
 .resources.panel .sidebar li.selected .selection {
     background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(162, 177, 207)), to(rgb(120, 138, 177)));
+    background-image: linear-gradient(to bottom, rgb(162, 177, 207) 0%, rgb(120, 138, 177) 100%);
     border-top: 1px solid #979797;
     height: 17px;
 }
 
 .resources.panel .sidebar :focus li.selected .selection {
     background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(92, 147, 213)), to(rgb(21, 83, 170)));
+    background-image: linear-gradient(to bottom, rgb(92, 147, 213) 0%, rgb(21, 83, 170) 100%);
     border-top: 1px solid rgb(68, 128, 200);
 }
 
 body.inactive .resources.panel .sidebar li.selected .selection {
     background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(180, 180, 180)), to(rgb(138, 138, 138)));
+    background-image: linear-gradient(to bottom, rgb(180, 180, 180) 0%, rgb(138, 138, 138) 100%);
     border-top: 1px solid rgb(151, 151, 151);
 }
 
@@ -2003,7 +2159,9 @@
     height: 100%;
     border-top: 0 none transparent;
     background-image: -webkit-gradient(linear, left top, left bottom, from(white), color-stop(0.5, white), color-stop(0.5, rgb(234, 243, 255)), to(rgb(234, 243, 255)));
+    background-image: linear-gradient(to bottom, white 0%, white 10%, rgb(234, 243, 255) 40%, rgb(234, 243, 255) 100%);
     -webkit-background-size: 1px 32px;
+    background-size: 1px 32px;
 }
 
 .data-grid.inline table.data {
@@ -2026,6 +2184,8 @@
     white-space: nowrap;
     border-right: 1px solid #aaa;
     -webkit-user-select: text;
+	-ms-user-select: text;
+	-moz-user-select: text;
 }
 
 .data-grid td > div, .data-grid th > div {
@@ -2102,6 +2262,8 @@
     height: 8px;
     margin-right: 2px;
     -webkit-user-select: none;
+	-ms-user-select: none;
+	-moz-user-select: none;
 }
 
 .data-grid tr.expanded td.disclosure::before {
@@ -2147,6 +2309,8 @@
     overflow-y: overlay;
     overflow-x: hidden;
     -webkit-text-size-adjust: auto;
+    -ms-text-size-adjust: auto;
+	-moz-text-size-adjust: auto;
 }
 
 .database-query-prompt {
@@ -2155,7 +2319,10 @@
     min-height: 16px; 
     white-space: pre-wrap;
     -webkit-user-modify: read-write-plaintext-only;
+	-moz-user-modify: read-write;
     -webkit-user-select: text;
+	-ms-user-select: text;
+	-moz-user-select: text;
 }
 
 .database-user-query::before, .database-query-prompt::before, .database-query-result::before {
@@ -2168,6 +2335,8 @@
     height: 10px;
     margin-top: -5px;
     -webkit-user-select: none;
+	-ms-user-select: none;
+	-moz-user-select: none;
 }
 
 .database-query-prompt::before {
@@ -2188,6 +2357,8 @@
 .database-query-text {
     color: rgb(0, 128, 255);
     -webkit-user-select: text;
+	-ms-user-select: text;
+	-moz-user-select: none;
 }
 
 .database-query-result {
@@ -2201,6 +2372,8 @@
 .database-query-result.error {
     color: red;
     -webkit-user-select: text;
+	-ms-user-select: text;
+	-moz-user-select: none;
 }
 
 .database-query-result.error::before {
@@ -2295,8 +2468,11 @@
     border: 1px solid rgb(165, 165, 165);
     background-color: rgb(237, 237, 237);
     background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)));
+    background-image: linear-gradient(to bottom, rgb(252, 252, 252) 0%, rgb(233, 233, 233) 100%);
     -webkit-border-radius: 12px;
+    border-radius: 12px;
     -webkit-appearance: none;
+	-moz-appearance: none;
 }
 
 .panel-enabler-view button:not(.status-bar-item) {
@@ -2347,6 +2523,7 @@
 .panel-enabler-view button:active:not(.status-bar-item), .pane button:active, button.show-all-nodes:active {
     background-color: rgb(215, 215, 215);
     background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(194, 194, 194)), to(rgb(239, 239, 239)));
+    background-image: linear-gradient(to bottom, rgb(194, 194, 194) 0%, rgb(239, 239, 239) 100%);
 }
 
 body.inactive .panel-enabler-view button:not(.status-bar-item), .panel-enabler-view button:disabled:not(.status-bar-item), body.inactive .pane button, .pane button:disabled, body.inactive button.show-all-nodes {
@@ -2354,6 +2531,7 @@
     border-color: rgb(212, 212, 212);
     background-color: rgb(239, 239, 239);
     background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(250, 250, 250)), to(rgb(235, 235, 235)));
+    background-image: linear-gradient(to bottom, rgb(250, 250, 250) 0%, rgb(235, 235, 235) 100%);
 }
 
 .panel-enabler-view input {
@@ -2361,19 +2539,24 @@
     width: 17px;
     border: 1px solid rgb(165, 165, 165);
     background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)));
+    background-image: linear-gradient(to bottom, rgb(252, 252, 252) 0%, rgb(223, 223, 223) 100%);
     -webkit-border-radius: 8px;
+    border-radius: 8px;
     -webkit-appearance: none;
+	-moz-appearance: none;
     vertical-align: middle;
     margin: 0 5px 5px 0;
 }
 
 .panel-enabler-view input:active {
     background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(194, 194, 194)), to(rgb(239, 239, 239)));
+    background-image: linear-gradient(to bottom, rgb(194, 194, 194) 0%, rgb(239, 239, 239) 100%);
 }
 
 .panel-enabler-view input:checked {
     background: url(Images/radioDot.png) center no-repeat,
                 -webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)));
+    background-image: linear-gradient(to bottom, rgb(252, 252, 252) 0%, rgb(223, 223, 223) 100%);
 }
 
 .panel-enabler-view.scripts img {
@@ -2527,6 +2710,7 @@
 
 #resources-filter, #console-filter.console-filter-top {
     background: -webkit-gradient(linear, left top, left bottom, from(rgb(236, 236, 236)), to(rgb(217, 217, 217)));
+    background-image: linear-gradient(to bottom, rgb(236, 236, 236) 0%, rgb(217, 217, 217) 100%);
     border-bottom: 1px solid rgb(64%, 64%, 64%);
     width: 100%;
 }
@@ -2541,11 +2725,15 @@
 
 .tabbed-pane {
     -webkit-box-orient: vertical;
+    -ms-flex-direction: column;
+	-moz-box-orient: vertical;
     height: 100%;
 }
 
 .tabbed-pane-content {
     -webkit-box-flex: 1;
+    -ms-flex: 1;
+	-moz-box-flex: 1;
     position: relative;
 }
 
@@ -2593,6 +2781,7 @@
     background: transparent;
     text-shadow: rgba(255, 255, 255, 0.5) 0 1px 0;
     -webkit-border-radius: 8px;
+    border-radius: 8px;
     vertical-align: middle;
 }
 
@@ -2617,11 +2806,13 @@
 .scope-bar li.selected {
     background: rgba(0, 0, 0, 0.3);
     -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.5) inset, 0 -1px 1px rgba(255, 255, 255, 0.25) inset, 0 1px 0 rgba(255, 255, 255, 0.5);
+    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.5) inset, 0 -1px 1px rgba(255, 255, 255, 0.25) inset, 0 1px 0 rgba(255, 255, 255, 0.5);
 }
 
 .scope-bar li:active {
     background: rgba(0, 0, 0, 0.5);
     -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.5) inset, 0 -1px 1px rgba(255, 255, 255, 0.25) inset, 0 1px 0 rgba(255, 255, 255, 0.5);
+    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.5) inset, 0 -1px 1px rgba(255, 255, 255, 0.25) inset, 0 1px 0 rgba(255, 255, 255, 0.5);
 }
 
 #resources-container {
@@ -2675,6 +2866,7 @@
     border-left: 1px solid rgb(102, 102, 102);
     background-color: rgb(101, 111, 130);
     background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0)), to(rgba(0, 0, 0, 0.5)));
+    background-image: linear-gradient(to bottom, rgb(0, 0, 0) 0%, rgb(0, 0, 0) 50%);
     background-repeat: repeat-x;
     background-position: bottom;
     text-align: center;
@@ -2684,6 +2876,9 @@
     -webkit-background-size: 1px 6px;
     -webkit-background-origin: padding;
     -webkit-background-clip: padding;
+    background-size: 1px 6px;
+    background-origin: padding;
+    background-clip: padding;
     z-index: 400;
 }
 
@@ -2831,6 +3026,7 @@
     font-weight: bold;
     opacity: 0;
     -webkit-transition: opacity 250ms ease-in-out;
+    transition: opacity 250ms ease-in-out;
 }
 
 .resources-graph-side:hover .resources-graph-label {
@@ -2885,6 +3081,7 @@
     min-width: 14px;
     opacity: 0.65;
     -webkit-border-image: url(Images/timelinePillGray.png) 6 7 6 7;
+	border-image: url(Images/timelinePillGray.png) 6 7 6 7;
 }
 
 .resources-category-documents, .resources-category-stylesheets, .resources-category-images,
@@ -2925,63 +3122,78 @@
 
 .resource-cached .resources-graph-bar {
     -webkit-border-image: url(Images/timelineHollowPillGray.png) 6 7 6 7;
+	border-image: url(Images/timelineHollowPillGray.png) 6 7 6 7;
 }
 
 .resources-category-documents .resources-graph-bar {
     -webkit-border-image: url(Images/timelinePillBlue.png) 6 7 6 7;
+	border-image: url(Images/timelinePillBlue.png) 6 7 6 7;
 }
 
 .resources-category-documents.resource-cached .resources-graph-bar {
     -webkit-border-image: url(Images/timelineHollowPillBlue.png) 6 7 6 7;
+	border-image: url(Images/timelineHollowPillBlue.png) 6 7 6 7;
 }
 
 .resources-category-stylesheets .resources-graph-bar {
     -webkit-border-image: url(Images/timelinePillGreen.png) 6 7 6 7;
+	border-image: url(Images/timelinePillGreen.png) 6 7 6 7;
 }
 
 .resources-category-stylesheets.resource-cached .resources-graph-bar {
     -webkit-border-image: url(Images/timelineHollowPillGreen.png) 6 7 6 7;
+	border-image: url(Images/timelineHollowPillGreen.png) 6 7 6 7;
 }
 
 .resources-category-images .resources-graph-bar {
     -webkit-border-image: url(Images/timelinePillPurple.png) 6 7 6 7;
+	border-image: url(Images/timelinePillPurple.png) 6 7 6 7;
 }
 
 .resources-category-images.resource-cached .resources-graph-bar {
     -webkit-border-image: url(Images/timelineHollowPillPurple.png) 6 7 6 7;
+	border-image: url(Images/timelineHollowPillPurple.png) 6 7 6 7;
 }
 
 .resources-category-fonts .resources-graph-bar {
     -webkit-border-image: url(Images/timelinePillRed.png) 6 7 6 7;
+	border-image: url(Images/timelinePillRed.png) 6 7 6 7;
 }
 
 .resources-category-fonts.resource-cached .resources-graph-bar {
     -webkit-border-image: url(Images/timelineHollowPillRed.png) 6 7 6 7;
+	border-image: url(Images/timelineHollowPillRed.png) 6 7 6 7;
 }
 
 .resources-category-scripts .resources-graph-bar {
     -webkit-border-image: url(Images/timelinePillOrange.png) 6 7 6 7;
+	border-image: url(Images/timelinePillOrange.png) 6 7 6 7;
 }
 
 .resources-category-scripts.resource-cached .resources-graph-bar {
     -webkit-border-image: url(Images/timelineHollowPillOrange.png) 6 7 6 7;
+	border-image: url(Images/timelineHollowPillOrange.png) 6 7 6 7;
 }
 
 .resources-category-xhr .resources-graph-bar {
     -webkit-border-image: url(Images/timelinePillYellow.png) 6 7 6 7;
+	border-image: url(Images/timelinePillYellow.png) 6 7 6 7;
 }
 
 .resources-category-xhr.resource-cached .resources-graph-bar {
     -webkit-border-image: url(Images/timelineHollowPillYellow.png) 6 7 6 7;
+	border-image: url(Images/timelineHollowPillYellow.png) 6 7 6 7;
 }
 
 /* FIXME: Create bar images for WebSocket. */
 .resources-category-websockets .resources-graph-bar {
     -webkit-border-image: url(Images/timelinePillGray.png) 6 7 6 7;
+	border-image: url(Images/timelinePillGray.png) 6 7 6 7;
 }
 
 .resources-category-websockets.resource-cached .resources-graph-bar {
    -webkit-border-image: url(Images/timelineHollowPillGray.png) 6 7 6 7;
+	border-image: url(Images/timelineHollowPillGray.png) 6 7 6 7;
 }
 
 #resource-views {
@@ -3085,6 +3297,7 @@
     background-repeat: no-repeat;
     background-position: center;
     -webkit-apearance: none;
+	-moz-apearance: none;
 }
 
 .sidebar-tree.hide-disclosure-buttons .sidebar-tree-item .disclosure-button {
@@ -3160,6 +3373,7 @@
     text-shadow: none;
     color: white;
     -webkit-border-radius: 7px;
+    border-radius: 7px;
 }
 
 li .status .bubble:empty {
@@ -3196,20 +3410,25 @@
     color: white;
     border-top: 1px solid rgb(145, 160, 192);
     background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(162, 177, 207)), to(rgb(120, 138, 177)));
+    background-image: linear-gradient(to bottom, rgb(162, 177, 207) 0%, rgb(120, 138, 177) 100%);
     text-shadow: rgba(0, 0, 0, 0.33) 0 1px 0;
     font-weight: bold;
     -webkit-background-origin: padding;
     -webkit-background-clip: padding;
+    background-origin: padding;
+    background-clip: padding;
 }
 
 :focus .sidebar-tree-item.selected {
     border-top: 1px solid rgb(68, 128, 200);
     background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(92, 147, 213)), to(rgb(21, 83, 170)));
+    background-image: linear-gradient(to bottom, rgb(92, 147, 213) 0%, rgb(21, 83, 170) 100%);
 }
 
 body.inactive .sidebar-tree-item.selected {
     border-top: 1px solid rgb(151, 151, 151);
     background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(180, 180, 180)), to(rgb(138, 138, 138)));
+    background-image: linear-gradient(to bottom, rgb(180, 180, 180) 0%, rgb(138, 138, 138) 100%);
 }
 
 .sidebar-tree-item .titles {
@@ -3440,6 +3659,7 @@
     left: 0;
     right: 0;
     background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(253, 253, 253)), to(rgb(213, 213, 213)));
+    background-image: linear-gradient(to bottom, rgb(253, 253, 253) 0%, rgb(213, 213, 213) 100%);
     border-top: 1px solid rgb(140, 140, 140);
     border-bottom: 1px solid rgb(115, 115, 115);
     height: 10px;
@@ -3453,6 +3673,7 @@
     left: 0px;
     padding-top: 2px;
     background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(242, 242, 242)), to(rgb(209, 209, 209)));
+    background-image: linear-gradient(to bottom, rgb(242, 242, 242) 0%, rgb(209, 209, 209) 100%);
     border-right: 1px solid rgb(163, 163, 163);
 }
 
@@ -3513,7 +3734,9 @@
     z-index: 500;
     cursor: col-resize;
     -webkit-border-radius: 2px;
+    border-radius: 2px;
     -webkit-box-shadow: white 1px 0 0, white -1px 0 0, white 0 1px 0, white 0 -1px 0;
+    box-shadow: white 1px 0 0, white -1px 0 0, white 0 1px 0, white 0 -1px 0;
 }
 
 #timeline-overview-grid #resources-graphs {
@@ -3555,6 +3778,7 @@
     background-position: 0 -66px;
     vertical-align: -1px;
     -webkit-appearance: none;
+	-moz-appearance: none;
 }
 
 .timeline-category-statusbar-item .timeline-category-checkbox:checked {
@@ -3705,6 +3929,7 @@
     min-width: 5px;
     opacity: 0.8;
     -webkit-border-image: url(Images/timelineBarGray.png) 4 4 5 4;
+	border-image: url(Images/timelineBarGray.png) 4 4 5 4;
     z-index: 180;
     pointer-events: visibleFill;
 }
@@ -3723,14 +3948,17 @@
 
 .timeline-category-loading .timeline-graph-bar {
     -webkit-border-image: url(Images/timelineBarBlue.png) 4 4 5 4;
+	border-image: url(Images/timelineBarBlue.png) 4 4 5 4;
 }
 
 .timeline-category-scripting .timeline-graph-bar {
     -webkit-border-image: url(Images/timelineBarOrange.png) 4 4 5 4;
+	border-image: url(Images/timelineBarOrange.png) 4 4 5 4;
 }
 
 .timeline-category-rendering .timeline-graph-bar {
     -webkit-border-image: url(Images/timelineBarPurple.png) 4 4 5 4;
+	border-image: url(Images/timelineBarPurple.png) 4 4 5 4;
 }
 
 .timeline-aggregated-category {
@@ -3745,14 +3973,17 @@
 
 .timeline-loading {
     -webkit-border-image: url(Images/timelineBarBlue.png) 4 4 5 4;
+	border-image: url(Images/timelineBarBlue.png) 4 4 5 4;
 }
 
 .timeline-scripting {
     -webkit-border-image: url(Images/timelineBarOrange.png) 4 4 5 4;
+	border-image: url(Images/timelineBarOrange.png) 4 4 5 4;
 }
 
 .timeline-rendering {
     -webkit-border-image: url(Images/timelineBarPurple.png) 4 4 5 4;
+	border-image: url(Images/timelineBarPurple.png) 4 4 5 4;
 }
 
 .popover .timeline-aggregated-category.timeline-loading {
@@ -3773,6 +4004,8 @@
 
 .timeline-details {
     -webkit-user-select: text;
+	-ms-user-select: text;
+	-moz-user-select: text;
     vertical-align: top;
 }
 
@@ -3983,6 +4216,7 @@
 
 ol.breakpoint-list {
     -webkit-padding-start: 0;
+	-moz-padding-start: 0;
     list-style: none;
     margin: 0;
 }
@@ -4037,6 +4271,7 @@
     padding: 4px;
     background-color: rgb(203, 226, 255);
     -webkit-border-radius: 7px;
+    border-radius: 7px;
     border: 2px solid rgb(169, 172, 203); 
     width: 90%; 
 }
@@ -4060,6 +4295,7 @@
     box-shadow: none !important;
     outline: none !important;
     -webkit-user-modify: read-write;
+	-moz-user-modify: read-write;
 }
 
 .source-frame-popover-title {
@@ -4088,6 +4324,7 @@
 
 .styles-sidebar-separator {
     background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(243, 243, 243)), color-stop(0.05, rgb(243, 243, 243)), color-stop(0.05, rgb(230, 230, 230)), to(rgb(209, 209, 209)));
+    background-image: linear-gradient(to bottom, rgb(243, 243, 243) 0%,rgb(243, 243 ,243) 10%, rgb(230, 230, 230) 40%, rgb(209, 209, 209) 100%);
     padding: 0 5px;
     border-top: 1px solid rgb(189, 189, 189);
     border-bottom: 1px solid rgb(189, 189, 189);
@@ -4129,7 +4366,11 @@
     white-space: nowrap;
     -webkit-background-origin: padding;
     -webkit-background-clip: padding;
+    background-origin: padding;
+    background-clip: padding;
     -webkit-user-select: text;
+	-ms-user-select: text;
+	-moz-user-select: text;
 }
 
 .styles-section:not(.first-styles-section) {
@@ -4154,6 +4395,8 @@
     padding-right: 5px;
     vertical-align: sub;
     -webkit-user-select: none;
+	-ms-user-select: none;
+	-moz-user-select: none;
     cursor: default;
 }
 
@@ -4161,6 +4404,8 @@
     white-space: nowrap;
     -webkit-background-origin: padding;
     -webkit-background-clip: padding;
+    background-origin: padding;
+    background-clip: padding;
 }
 
 .styles-section .header .title {
@@ -4220,6 +4465,7 @@
     display: none;
     margin: 0;
     -webkit-padding-start: 12px;
+	-moz-padding-start: 12px;
     list-style: none;
 }
 
@@ -4236,6 +4482,8 @@
     margin-top: 0;
     padding-right: 3px;
     -webkit-user-select: none;
+	-ms-user-select: none;
+	-moz-user-select: none;
     cursor: default;
 }
 
@@ -4265,6 +4513,8 @@
     vertical-align: top;
     position: relative;
     z-index: 1;
+    /*Removes checkbox padding that is set in IE by default*/
+    padding: 0;
 }
 
 .styles-section .properties .overloaded, .styles-section .properties .inactive, .styles-section .properties .disabled {
diff --git a/weinre.build/vendor/webkit/WebCore/inspector/front-end/inspector.js b/weinre.build/vendor/webkit/WebCore/inspector/front-end/inspector.js
index 0959289..9707cb3 100644
--- a/weinre.build/vendor/webkit/WebCore/inspector/front-end/inspector.js
+++ b/weinre.build/vendor/webkit/WebCore/inspector/front-end/inspector.js
@@ -120,9 +120,14 @@
             this._previousFocusElement = this._currentFocusElement;
         this._currentFocusElement = x;
 
-        if (this._currentFocusElement) {
+        if (this._currentFocusElement && typeof(this._currentFocusElement.focus) === 'function') {
             this._currentFocusElement.focus();
 
+            // Hack for IE - return if 'select' is in focus; otherwise it will lost the focus after we call addRange.
+            if(this._currentFocusElement.nodeName.toUpperCase() == 'SELECT'){
+                return;
+            }
+
             // Make a caret selection inside the new element if there isn't a range selection and
             // there isn't already a caret selection inside.
             var selection = window.getSelection();
@@ -134,7 +139,8 @@
                 selection.removeAllRanges();
                 selection.addRange(selectionRange);
             }
-        } else if (this._previousFocusElement)
+        } // Hack for IE - do not call blur() for body element; otherwise browser window will become inactive
+        else if (this._previousFocusElement && this._previousFocusElement.nodeName.toUpperCase() != 'BODY')
             this._previousFocusElement.blur();
     },
 
@@ -755,9 +761,9 @@
     var isInputElement = event.target.nodeName === "INPUT";
     var isInEditMode = event.target.enclosingNodeOrSelfWithClass("text-prompt") || WebInspector.isEditingAnyField();
     const helpKey = WebInspector.isMac() ? "U+003F" : "U+00BF"; // "?" for both platforms
-
-    if (event.keyIdentifier === "F1" ||
-        (event.keyIdentifier === helpKey && event.shiftKey && (!isInEditMode && !isInputElement || event.metaKey))) {
+    var key = event.keyIdentifier || event.key;
+    if (key === "F1" ||
+        (key === helpKey && event.shiftKey && (!isInEditMode && !isInputElement || event.metaKey))) {
         WebInspector.shortcutsHelp.show();
         event.stopPropagation();
         event.preventDefault();
@@ -784,7 +790,7 @@
     }
 
     var isMac = WebInspector.isMac();
-    switch (event.keyIdentifier) {
+    switch (key) {
         case "Left":
             var isBackKey = !isInEditMode && (isMac ? event.metaKey : event.ctrlKey);
             if (isBackKey && this._panelHistory.canGoBack()) {
@@ -1562,7 +1568,7 @@
 
 WebInspector.performSearch = function(event)
 {
-    var forceSearch = event.keyIdentifier === "Enter";
+    var forceSearch = (event.keyIdentifier || event.key) === "Enter";
     this.doPerformSearch(event.target.value, forceSearch, event.shiftKey, false);
 }
 
@@ -1732,6 +1738,7 @@
     var moveDirection = "";
 
     element.addStyleClass("editing");
+    element.setAttribute("contenteditable", "true");
 
     var oldTabIndex = element.tabIndex;
     if (element.tabIndex < 0)
@@ -1753,6 +1760,8 @@
         delete WebInspector.__editing;
 
         this.removeStyleClass("editing");
+        this.removeAttribute("contenteditable");
+
         this.tabIndex = oldTabIndex;
         this.scrollTop = 0;
         this.scrollLeft = 0;
@@ -1794,7 +1803,7 @@
             return "commit";
         else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code)
             return "cancel";
-        else if (event.keyIdentifier === "U+0009") // Tab key
+        else if ((event.keyIdentifier || event.key) === "U+0009") // Tab key
             return "move-" + (event.shiftKey ? "backward" : "forward");
     }
 
@@ -1810,7 +1819,7 @@
             event.stopPropagation();
         } else if (result && result.indexOf("move-") === 0) {
             moveDirection = result.substring(5);
-            if (event.keyIdentifier !== "U+0009")
+            if ((event.keyIdentifier || event.key) !== "U+0009")
                 blurEventListener();
         }
     }
diff --git a/weinre.build/vendor/webkit/WebCore/inspector/front-end/utilities.js b/weinre.build/vendor/webkit/WebCore/inspector/front-end/utilities.js
index 64670e1..f64ed53 100644
--- a/weinre.build/vendor/webkit/WebCore/inspector/front-end/utilities.js
+++ b/weinre.build/vendor/webkit/WebCore/inspector/front-end/utilities.js
@@ -280,21 +280,21 @@
     return element;
 }
 
-Element.prototype.__defineGetter__("totalOffsetLeft", function()
+Object.defineProperty(Element.prototype, "totalOffsetLeft", {get: function()
 {
     var total = 0;
     for (var element = this; element; element = element.offsetParent)
         total += element.offsetLeft + (this !== element ? element.clientLeft : 0);
     return total;
-});
+}});
 
-Element.prototype.__defineGetter__("totalOffsetTop", function()
+Object.defineProperty(Element.prototype, "totalOffsetTop", {get: function()
 {
     var total = 0;
     for (var element = this; element; element = element.offsetParent)
         total += element.offsetTop + (this !== element ? element.clientTop : 0);
     return total;
-});
+}});
 
 Element.prototype.offsetRelativeToWindow = function(targetWindow)
 {
@@ -314,7 +314,7 @@
     return elementOffset;
 }
 
-KeyboardEvent.prototype.__defineGetter__("data", function()
+Object.defineProperty(KeyboardEvent.prototype, "data", {get: function()
 {
     // Emulate "data" attribute from DOM 3 TextInput event.
     // See http://www.w3.org/TR/DOM-Level-3-Events/#events-Events-TextEvent-data
@@ -331,7 +331,7 @@
             else
                 return "";
     }
-});
+}});
 
 Text.prototype.select = function(start, end)
 {
@@ -350,7 +350,7 @@
     return this;
 }
 
-Element.prototype.__defineGetter__("selectionLeftOffset", function() {
+Object.defineProperty(Element.prototype, "selectionLeftOffset", {get: function() {
     // Calculate selection offset relative to the current element.
 
     var selection = window.getSelection();
@@ -369,7 +369,7 @@
     }
 
     return leftOffset;
-});
+}});
 
 Node.prototype.isWhitespace = isNodeWhitespace;
 Node.prototype.displayName = nodeDisplayName;
@@ -1017,7 +1017,7 @@
 
 function isEnterKey(event) {
     // Check if in IME.
-    return event.keyCode !== 229 && event.keyIdentifier === "Enter";
+    return (event.keyCode !== 229 && event.keyIdentifier === "Enter") || event.keyCode == 13 || event.charCode == 13;
 }
 
 
diff --git a/weinre.web/client/weinre/browser-support-check.js b/weinre.web/client/weinre/browser-support-check.js
new file mode 100644
index 0000000..dba38fe
--- /dev/null
+++ b/weinre.web/client/weinre/browser-support-check.js
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+var iSupported = false;
+
+if (navigator.userAgent.match(/webkit/i)) {
+    iSupported = true;
+} else if (navigator.userAgent.match(/MSIE/i)) {
+    var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
+    iSupported = re.exec(navigator.userAgent) !== null && parseFloat(RegExp.$1) >= 10;
+} else if (navigator.userAgent.match(/Firefox/i)) {
+	var re = new RegExp("Firefox/([0-9]{1,}[\.0-9]{0,})");
+	iSupported = re.exec(navigator.userAgent) !== null && parseFloat(RegExp.$1) >= 18;
+}
+
+if (!iSupported) {
+    alert("It seems your browser or its version is not supported. This web page is designed to work in webkit-based browsers, latest InternetExplorer and Firefox")
+}
diff --git a/weinre.web/client/weinre/check-for-webkit.js b/weinre.web/client/weinre/check-for-webkit.js
deleted file mode 100644
index 1b66a5f..0000000
--- a/weinre.web/client/weinre/check-for-webkit.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-if (!navigator.userAgent.match(/webkit/i)) {
-    alert("This web page is only designed to work in WebKit-based browsers.  Sorry.  Best of luck.")
-}
diff --git a/weinre.web/client/weinre/hacks.js b/weinre.web/client/weinre/hacks.js
index 6f0290b..b0927ee 100644
--- a/weinre.web/client/weinre/hacks.js
+++ b/weinre.web/client/weinre/hacks.js
@@ -41,3 +41,95 @@
 }
 
 })();
+
+// __proto__ inheritance support; Weinre client classes only
+(function () {
+
+    var hasProto = "__proto__" in Object.prototype;
+
+    if (!hasProto) {
+        Object.defineProperty(Object.prototype, '__proto__', {set : function(value){
+            var tmpFunc = new Function();
+            tmpFunc.prototype = Object.create(value);
+
+            function copyProperties(a, b) {
+                var d;
+                for (var i in b) {
+                    d = Object.getOwnPropertyDescriptor(b, i);
+
+                    if (d &&(d.get || d.set)) {
+                        Object.defineProperty(a, i, d);
+                    } else {
+                        a[i] = b[i];
+                    }
+                }
+                return a;
+            }
+
+            function findProtoOwner(root, proto, depth){
+
+                if (depth > 1) return;
+
+                var props = Object.getOwnPropertyNames(root),
+                    prop,
+                    d;
+
+                for (var i = props.length; i--;) {
+                    prop = props[i];
+
+                    d = Object.getOwnPropertyDescriptor(root, prop);
+
+                    if (d && (d.get || d.set))  continue;
+
+                    if (typeof(root[prop]) === 'function' && root[prop].prototype === proto) {
+                        return root[prop];
+                    }
+
+                    if (root[prop] && root[prop].prototype instanceof WebInspector.Object) {
+                        var owner = findProtoOwner(root[prop], proto, depth+1);
+
+                        if (owner) return owner;
+                    }
+                }
+            }
+
+            copyProperties(tmpFunc.prototype, this);
+
+            // hack to be able to redefine object prototype; we can't do it another way
+            // because we have prototype as 'this' here only
+            var owner = findProtoOwner (window.WebInspector, this, 0);
+
+            if (owner) {
+                owner.prototype = new tmpFunc();
+                owner.prototype.proto = value;
+            }
+
+        }, get : function(){
+            return this.proto;
+        }});
+    }
+})();
+
+//if (!Object.prototype.__defineGetter__) {
+//    Object.prototype.__defineGetter__ = function (key, fn) {
+//        Object.defineProperty(this, key, {get: fn});
+//    }
+//}
+//
+//if (!Object.prototype.__defineSetter__) {
+//    Object.prototype.__defineSetter__ = function (key, fn) {
+//        Object.defineProperty(this, key, {set: fn, configurable: true, writable : true});
+//    }
+//}
+
+// hack for not existing scrollIntoViewIfNeeded
+if (!HTMLElement.prototype.scrollIntoViewIfNeeded){
+    HTMLElement.prototype.scrollIntoViewIfNeeded = function(alignWithTop) {
+		return this.scrollIntoView(alignWithTop);
+	};
+}
+
+// hack for not existing setBaseAndExtent
+if (!Selection.prototype.setBaseAndExtent){
+    Selection.prototype.setBaseAndExtent = Selection.prototype.selectAllChildren;
+}
\ No newline at end of file
diff --git a/weinre.web/modules/weinre/client/Client.coffee b/weinre.web/modules/weinre/client/Client.coffee
index 54422a4..dfc0d88 100644
--- a/weinre.web/modules/weinre/client/Client.coffee
+++ b/weinre.web/modules/weinre/client/Client.coffee
@@ -90,6 +90,7 @@
         WebInspector.currentPanel = panel
 
         toolButtonsToHide = [ 'scripts' ]
+        toolButtonsToHide.push 'resources', 'network', 'timeline', 'profiles', 'audits' if navigator.userAgent.match(/MSIE/i)
         for toolButtonToHide in toolButtonsToHide
             continue unless WebInspector.panels[toolButtonToHide]
             continue unless WebInspector.panels[toolButtonToHide].toolbarItem
diff --git a/weinre.web/modules/weinre/client/RemotePanel.coffee b/weinre.web/modules/weinre/client/RemotePanel.coffee
index f191ee7..8f730f5 100644
--- a/weinre.web/modules/weinre/client/RemotePanel.coffee
+++ b/weinre.web/modules/weinre/client/RemotePanel.coffee
@@ -30,10 +30,10 @@
 #-------------------------------------------------------------------------------
 module.exports = class RemotePanel extends WebInspector.Panel
 
-    RemotePanel::__defineGetter__("toolbarItemClass", -> "remote")
-    RemotePanel::__defineGetter__("toolbarItemLabel", -> "Remote")
-    RemotePanel::__defineGetter__("statusBarItems", -> [])
-    RemotePanel::__defineGetter__("defaultFocusedElement", -> @contentElement)
+    Object.defineProperty RemotePanel::, "toolbarItemClass", get: -> "remote"
+    Object.defineProperty RemotePanel::, "toolbarItemLabel", get: -> "Remote"
+    Object.defineProperty RemotePanel::, "statusBarItems", get: -> []
+    Object.defineProperty RemotePanel::, "defaultFocusedElement", get: -> @contentElement
 
     constructor: ->
         super "remote"
diff --git a/weinre.web/modules/weinre/common/HookLib.coffee b/weinre.web/modules/weinre/common/HookLib.coffee
index 4780dc3..3e5d27c 100644
--- a/weinre.web/modules/weinre/common/HookLib.coffee
+++ b/weinre.web/modules/weinre/common/HookLib.coffee
@@ -72,7 +72,10 @@
             return
         else
             hookedFunction   = getHookedFunction(@target, this)
-            object[property] = hookedFunction
+            #In IE we should not override standard storage functions because IE does it incorrectly - all values that set as
+            # storage properties (e.g. localStorage.setItem = function()[...]) are cast to String.
+            # That leads to "Function expected" exception when any of overridden function is called.
+            object[property] = hookedFunction  unless navigator.userAgent.match(/MSIE/i) and (object is localStorage or object is sessionStorage)
 
     #---------------------------------------------------------------------------
     addHooks: (hooks) ->
diff --git a/weinre.web/modules/weinre/common/WebSocketXhr.coffee b/weinre.web/modules/weinre/common/WebSocketXhr.coffee
index 50ead99..6e10488 100644
--- a/weinre.web/modules/weinre/common/WebSocketXhr.coffee
+++ b/weinre.web/modules/weinre/common/WebSocketXhr.coffee
@@ -195,7 +195,10 @@
         if null == handler
             throw new Ex(arguments, "handler must not be null")
 
-        xhr = new XMLHttpRequest()
+        # Fix for XMLHttpRequest issue in Cordova for WP8 - Cordova overrides standard XMLHttpRequest object but
+        # overriden object causes dropping connections between target and server, so we should use Original
+        # XMLHttpRequest that is stored in XMLHttpRequest.noConflict.
+        xhr = (if XMLHttpRequest.noConflict then new XMLHttpRequest.noConflict() else new XMLHttpRequest())
         xhr.httpSocket = this
         xhr.httpSocketHandler = handler
         xhr.onreadystatechange = _xhrEventHandler
diff --git a/weinre.web/modules/weinre/target/ElementHighlighter.coffee b/weinre.web/modules/weinre/target/ElementHighlighter.coffee
index 991e9c1..3dae1ed 100644
--- a/weinre.web/modules/weinre/target/ElementHighlighter.coffee
+++ b/weinre.web/modules/weinre/target/ElementHighlighter.coffee
@@ -78,18 +78,18 @@
 
       metrics.width         = element.offsetWidth
       metrics.height        = element.offsetHeight
-      metrics.marginLeft    = fromPx(cStyle["margin-left"])
-      metrics.marginRight   = fromPx(cStyle["margin-right"])
-      metrics.marginTop     = fromPx(cStyle["margin-top"])
-      metrics.marginBottom  = fromPx(cStyle["margin-bottom"])
-      metrics.borderLeft    = fromPx(cStyle["border-left-width"])
-      metrics.borderRight   = fromPx(cStyle["border-right-width"])
-      metrics.borderTop     = fromPx(cStyle["border-top-width"])
-      metrics.borderBottom  = fromPx(cStyle["border-bottom-width"])
-      metrics.paddingLeft   = fromPx(cStyle["padding-left"])
-      metrics.paddingRight  = fromPx(cStyle["padding-right"])
-      metrics.paddingTop    = fromPx(cStyle["padding-top"])
-      metrics.paddingBottom = fromPx(cStyle["padding-bottom"])
+      metrics.marginLeft    = fromPx(cStyle["margin-left"] || cStyle["marginLeft"])
+      metrics.marginRight   = fromPx(cStyle["margin-right"] || cStyle["marginRight"])
+      metrics.marginTop     = fromPx(cStyle["margin-top"] || cStyle["marginTop"])
+      metrics.marginBottom  = fromPx(cStyle["margin-bottom"] || cStyle["marginBottom"])
+      metrics.borderLeft    = fromPx(cStyle["border-left-width"] || cStyle["borderLeftWidth"])
+      metrics.borderRight   = fromPx(cStyle["border-right-width"] || cStyle["borderRightWidth"])
+      metrics.borderTop     = fromPx(cStyle["border-top-width"] || cStyle["borderTopWidth"])
+      metrics.borderBottom  = fromPx(cStyle["border-bottom-width"] || cStyle["borderBottomWidth"])
+      metrics.paddingLeft   = fromPx(cStyle["padding-left"] || cStyle["paddingLeft"])
+      metrics.paddingRight  = fromPx(cStyle["padding-right"] || cStyle["paddingRight"])
+      metrics.paddingTop    = fromPx(cStyle["padding-top"] || cStyle["paddingTop"])
+      metrics.paddingBottom = fromPx(cStyle["padding-bottom"] || cStyle["paddingBottom"])
 
       metrics.x -= metrics.marginLeft
       metrics.y -= metrics.marginTop
diff --git a/weinre.web/modules/weinre/target/Target.coffee b/weinre.web/modules/weinre/target/Target.coffee
index 1a2fa52..4999c3a 100644
--- a/weinre.web/modules/weinre/target/Target.coffee
+++ b/weinre.web/modules/weinre/target/Target.coffee
@@ -194,7 +194,7 @@
 
     #---------------------------------------------------------------------------
     setDocument: () ->
-        Weinre.elementHighlighter = ElementHighlighter.create()
+        Weinre.elementHighlighter = ElementHighlighter.create() unless Weinre.elementHighlighter
 
         nodeId   = Weinre.nodeStore.getNodeId(document)
         nodeData = Weinre.nodeStore.getNodeData(nodeId, 2)