home *** CD-ROM | disk | FTP | other *** search
/ Computer Active 2010 July / CA07.iso / Multimedija / QuickTimeInstaller.exe / AppleApplicationSupport.msi / WebKit.resources_inspector_ObjectPropertiesSection.js < prev    next >
Encoding:
Text File  |  2010-03-15  |  10.1 KB  |  282 lines

  1. /*
  2.  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions
  6.  * are met:
  7.  * 1. Redistributions of source code must retain the above copyright
  8.  *    notice, this list of conditions and the following disclaimer.
  9.  * 2. Redistributions in binary form must reproduce the above copyright
  10.  *    notice, this list of conditions and the following disclaimer in the
  11.  *    documentation and/or other materials provided with the distribution.
  12.  *
  13.  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
  14.  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
  17.  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  18.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  19.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  20.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  21.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23.  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24.  */
  25.  
  26. WebInspector.ObjectPropertiesSection = function(object, title, subtitle, emptyPlaceholder, ignoreHasOwnProperty, extraProperties, treeElementConstructor)
  27. {
  28.     if (!title) {
  29.         title = Object.describe(object);
  30.         if (title.match(/Prototype$/)) {
  31.             title = title.replace(/Prototype$/, "");
  32.             if (!subtitle)
  33.                 subtitle = WebInspector.UIString("Prototype");
  34.         }
  35.     }
  36.  
  37.     this.emptyPlaceholder = (emptyPlaceholder || WebInspector.UIString("No Properties"));
  38.     this.object = object;
  39.     this.ignoreHasOwnProperty = ignoreHasOwnProperty;
  40.     this.extraProperties = extraProperties;
  41.     this.treeElementConstructor = treeElementConstructor || WebInspector.ObjectPropertyTreeElement;
  42.     this.editable = true;
  43.  
  44.     WebInspector.PropertiesSection.call(this, title, subtitle);
  45. }
  46.  
  47. WebInspector.ObjectPropertiesSection.prototype = {
  48.     onpopulate: function()
  49.     {
  50.         this.update();
  51.     },
  52.  
  53.     update: function()
  54.     {
  55.         var properties = [];
  56.         for (var prop in this.object)
  57.             properties.push(prop);
  58.         if (this.extraProperties)
  59.             for (var prop in this.extraProperties)
  60.                 properties.push(prop);
  61.         properties.sort();
  62.  
  63.         this.propertiesTreeOutline.removeChildren();
  64.  
  65.         for (var i = 0; i < properties.length; ++i) {
  66.             var object = this.object;
  67.             var propertyName = properties[i];
  68.             if (this.extraProperties && propertyName in this.extraProperties)
  69.                 object = this.extraProperties;
  70.             if (propertyName === "__treeElementIdentifier")
  71.                 continue;
  72.             if (!this.ignoreHasOwnProperty && "hasOwnProperty" in object && !object.hasOwnProperty(propertyName))
  73.                 continue;
  74.             this.propertiesTreeOutline.appendChild(new this.treeElementConstructor(object, propertyName));
  75.         }
  76.  
  77.         if (!this.propertiesTreeOutline.children.length) {
  78.             var title = "<div class=\"info\">" + this.emptyPlaceholder + "</div>";
  79.             var infoElement = new TreeElement(title, null, false);
  80.             this.propertiesTreeOutline.appendChild(infoElement);
  81.         }
  82.     }
  83. }
  84.  
  85. WebInspector.ObjectPropertiesSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype;
  86.  
  87. WebInspector.ObjectPropertyTreeElement = function(parentObject, propertyName)
  88. {
  89.     this.parentObject = parentObject;
  90.     this.propertyName = propertyName;
  91.  
  92.     // Pass an empty title, the title gets made later in onattach.
  93.     TreeElement.call(this, "", null, false);
  94. }
  95.  
  96. WebInspector.ObjectPropertyTreeElement.prototype = {
  97.     safePropertyValue: function(object, propertyName)
  98.     {
  99.         if (object["__lookupGetter__"] && object.__lookupGetter__(propertyName))
  100.             return;
  101.         return object[propertyName];
  102.     },
  103.  
  104.     onpopulate: function()
  105.     {
  106.         if (this.children.length && !this.shouldRefreshChildren)
  107.             return;
  108.  
  109.         this.removeChildren();
  110.  
  111.         var childObject = this.safePropertyValue(this.parentObject, this.propertyName);
  112.         var properties = Object.sortedProperties(childObject);
  113.         for (var i = 0; i < properties.length; ++i) {
  114.             var propertyName = properties[i];
  115.             if (propertyName === "__treeElementIdentifier")
  116.                 continue;
  117.             this.appendChild(new this.treeOutline.section.treeElementConstructor(childObject, propertyName));
  118.         }
  119.     },
  120.  
  121.     ondblclick: function(element, event)
  122.     {
  123.         this.startEditing();
  124.     },
  125.  
  126.     onattach: function()
  127.     {
  128.         this.update();
  129.     },
  130.  
  131.     update: function()
  132.     {
  133.         var childObject = this.safePropertyValue(this.parentObject, this.propertyName);
  134.         var isGetter = ("__lookupGetter__" in this.parentObject && this.parentObject.__lookupGetter__(this.propertyName));
  135.  
  136.         var nameElement = document.createElement("span");
  137.         nameElement.className = "name";
  138.         nameElement.textContent = this.propertyName;
  139.  
  140.         this.valueElement = document.createElement("span");
  141.         this.valueElement.className = "value";
  142.         if (!isGetter) {
  143.             this.valueElement.textContent = Object.describe(childObject, true);
  144.         } else {
  145.             // FIXME: this should show something like "getter" (bug 16734).
  146.             this.valueElement.textContent = "\u2014"; // em dash
  147.             this.valueElement.addStyleClass("dimmed");
  148.         }
  149.  
  150.         this.listItemElement.removeChildren();
  151.  
  152.         this.listItemElement.appendChild(nameElement);
  153.         this.listItemElement.appendChild(document.createTextNode(": "));
  154.         this.listItemElement.appendChild(this.valueElement);
  155.  
  156.         var hasSubProperties = false;
  157.         var type = typeof childObject;
  158.         if (childObject && (type === "object" || type === "function")) {
  159.             for (subPropertyName in childObject) {
  160.                 if (subPropertyName === "__treeElementIdentifier")
  161.                     continue;
  162.                 hasSubProperties = true;
  163.                 break;
  164.             }
  165.         }
  166.  
  167.         this.hasChildren = hasSubProperties;
  168.     },
  169.  
  170.     updateSiblings: function()
  171.     {
  172.         if (this.parent.root)
  173.             this.treeOutline.section.update();
  174.         else
  175.             this.parent.shouldRefreshChildren = true;
  176.     },
  177.  
  178.     startEditing: function()
  179.     {
  180.         if (WebInspector.isBeingEdited(this.valueElement) || !this.treeOutline.section.editable)
  181.             return;
  182.  
  183.         var context = { expanded: this.expanded };
  184.  
  185.         // Lie about our children to prevent expanding on double click and to collapse subproperties.
  186.         this.hasChildren = false;
  187.  
  188.         this.listItemElement.addStyleClass("editing-sub-part");
  189.  
  190.         WebInspector.startEditing(this.valueElement, this.editingCommitted.bind(this), this.editingCancelled.bind(this), context);
  191.     },
  192.  
  193.     editingEnded: function(context)
  194.     {
  195.         this.listItemElement.scrollLeft = 0;
  196.         this.listItemElement.removeStyleClass("editing-sub-part");
  197.         if (context.expanded)
  198.             this.expand();
  199.     },
  200.  
  201.     editingCancelled: function(element, context)
  202.     {
  203.         this.update();
  204.         this.editingEnded(context);
  205.     },
  206.  
  207.     editingCommitted: function(element, userInput, previousContent, context)
  208.     {
  209.         if (userInput === previousContent)
  210.             return this.editingCancelled(element, context); // nothing changed, so cancel
  211.  
  212.         this.applyExpression(userInput, true);
  213.  
  214.         this.editingEnded(context);
  215.     },
  216.  
  217.     evaluateExpression: function(expression, callback)
  218.     {
  219.         // Evaluate in the currently selected call frame if the debugger is paused.
  220.         // Otherwise evaluate in against the inspected window.
  221.         if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused && this.treeOutline.section.editInSelectedCallFrameWhenPaused)
  222.             return WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, callback);
  223.         try {
  224.             var result = InspectorController.inspectedWindow().eval(expression);
  225.             callback(result);
  226.         } catch (e) {
  227.             callback(e, true);
  228.         }
  229.     },
  230.  
  231.     applyExpression: function(expression, updateInterface)
  232.     {
  233.         var expressionLength = expression.trimWhitespace().length;
  234.  
  235.         if (!expressionLength) {
  236.             // The user deleted everything, so try to delete the property.
  237.             delete this.parentObject[this.propertyName];
  238.  
  239.             if (updateInterface) {
  240.                 if (this.propertyName in this.parentObject) {
  241.                     // The property was not deleted, so update.
  242.                     this.update();
  243.                 } else {
  244.                     // The property was deleted, so remove this tree element.
  245.                     this.parent.removeChild(this);
  246.                 }
  247.             }
  248.  
  249.             return;
  250.         }
  251.  
  252.         try {
  253.             // Surround the expression in parenthesis so the result of the eval is the result
  254.             // of the whole expression not the last potential sub-expression.
  255.             var result = this.evaluateExpression("(" + expression + ")");
  256.  
  257.             // Store the result in the property.
  258.             this.parentObject[this.propertyName] = result;
  259.         } catch(e) {
  260.             try {
  261.                 // Try to update as a string
  262.                 var result = this.evaluateExpression("\"" + expression.escapeCharacters("\"") + "\"");
  263.  
  264.                 // Store the result in the property.
  265.                 this.parentObject[this.propertyName] = result;
  266.             } catch(e) {
  267.                 // The expression failed so don't change the value. So just update and return.
  268.                 if (updateInterface)
  269.                     this.update();
  270.                 return;
  271.             }
  272.         }
  273.  
  274.         if (updateInterface) {
  275.             // Call updateSiblings since their value might be based on the value that just changed.
  276.             this.updateSiblings();
  277.         }
  278.     }
  279. }
  280.  
  281. WebInspector.ObjectPropertyTreeElement.prototype.__proto__ = TreeElement.prototype;
  282.