Bug 1264686 - Reps: Use grip-array rep to display NamedNodeMap. r=linclark
authorgasolin <gasolin@gmail.com>
Thu, 21 Jul 2016 10:53:49 +0800
changeset 346353 68e53c6c8494aa4cd5500b3859488b3f2f2e9c3a
parent 346352 4abaf15d33453b20a721136f9f80454a7706df16
child 346354 c62730281061f7790bc811ab549ba26250e73a8c
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslinclark
bugs1264686
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1264686 - Reps: Use grip-array rep to display NamedNodeMap. r=linclark MozReview-Commit-ID: 9hy2A9wmrAW
devtools/client/shared/components/reps/grip-array.js
devtools/client/shared/components/reps/moz.build
devtools/client/shared/components/reps/named-node-map.js
devtools/client/shared/components/reps/rep.js
devtools/client/shared/components/test/mochitest/test_reps_grip-array.html
--- a/devtools/client/shared/components/reps/grip-array.js
+++ b/devtools/client/shared/components/reps/grip-array.js
@@ -30,18 +30,19 @@ define(function (require, exports, modul
       provider: React.PropTypes.object,
     },
 
     getLength: function (grip) {
       return grip.preview ? grip.preview.length : 0;
     },
 
     getTitle: function (object, context) {
-      if (this.props.objectLink) {
-        return this.props.objectLink({
+      let objectLink = this.props.objectLink || span;
+      if (this.props.mode != "tiny") {
+        return objectLink({
           object: object
         }, object.class);
       }
       return "";
     },
 
     arrayIterator: function (grip, max) {
       let items = [];
@@ -112,21 +113,22 @@ define(function (require, exports, modul
         let isEmpty = objectLength === 0;
         items = span({className: "length"}, isEmpty ? "" : objectLength);
       } else {
         let max = (mode == "short") ? 3 : 300;
         items = this.arrayIterator(object, max);
       }
 
       let objectLink = this.props.objectLink || span;
+      let title = this.getTitle(object);
 
       return (
         ObjectBox({
           className: "array"},
-          this.getTitle(object),
+          title,
           objectLink({
             className: "arrayLeftBracket",
             role: "presentation",
             object: object
           }, "["),
           items,
           objectLink({
             className: "arrayRightBracket",
--- a/devtools/client/shared/components/reps/moz.build
+++ b/devtools/client/shared/components/reps/moz.build
@@ -9,17 +9,16 @@ DevToolsModules(
     'attribute.js',
     'caption.js',
     'date-time.js',
     'document.js',
     'event.js',
     'function.js',
     'grip-array.js',
     'grip.js',
-    'named-node-map.js',
     'null.js',
     'number.js',
     'object-box.js',
     'object-link.js',
     'object-with-text.js',
     'object-with-url.js',
     'object.js',
     'prop-rep.js',
deleted file mode 100644
--- a/devtools/client/shared/components/reps/named-node-map.js
+++ /dev/null
@@ -1,180 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-// Make this available to both AMD and CJS environments
-define(function (require, exports, module) {
-  // ReactJS
-  const React = require("devtools/client/shared/vendor/react");
-
-  // Reps
-  const { createFactories, isGrip } = require("./rep-utils");
-  const { ObjectBox } = createFactories(require("./object-box"));
-  const { Caption } = createFactories(require("./caption"));
-
-  // Shortcuts
-  const { span } = React.DOM;
-
-  /**
-   * Used to render a map of values provided as a grip.
-   */
-  let NamedNodeMap = React.createClass({
-    displayName: "NamedNodeMap",
-
-    propTypes: {
-      object: React.PropTypes.object.isRequired,
-      mode: React.PropTypes.string,
-      provider: React.PropTypes.object,
-    },
-
-    getLength: function (object) {
-      return object.preview.length;
-    },
-
-    getTitle: function (object) {
-      if (this.props.objectLink && object.class) {
-        return this.props.objectLink({
-          object: object
-        }, object.class);
-      }
-      return object.class ? object.class : "";
-    },
-
-    getItems: function (array, max) {
-      let items = this.propIterator(array, max);
-
-      items = items.map(item => PropRep(item));
-
-      if (items.length > max + 1) {
-        items.pop();
-        let objectLink = this.props.objectLink || span;
-        items.push(Caption({
-          key: "more",
-          object: objectLink({
-            object: this.props.object
-          }, "more…")
-        }));
-      }
-
-      return items;
-    },
-
-    propIterator: function (grip, max) {
-      max = max || 3;
-
-      let props = [];
-
-      let provider = this.props.provider;
-      if (!provider) {
-        return props;
-      }
-
-      let ownProperties = grip.preview ? grip.preview.ownProperties : [];
-      for (let name in ownProperties) {
-        if (props.length > max) {
-          break;
-        }
-
-        let item = ownProperties[name];
-        let label = provider.getLabel(item);
-        let value = provider.getValue(item);
-
-        props.push(Object.assign({}, this.props, {
-          name: label,
-          object: value,
-          equal: ": ",
-          delim: ", ",
-        }));
-      }
-
-      return props;
-    },
-
-    render: function () {
-      let grip = this.props.object;
-      let mode = this.props.mode;
-
-      let items;
-      if (mode == "tiny") {
-        items = this.getLength(grip);
-      } else {
-        let max = (mode == "short") ? 3 : 100;
-        items = this.getItems(grip, max);
-      }
-
-      let objectLink = this.props.objectLink || span;
-
-      return (
-        ObjectBox({className: "NamedNodeMap"},
-          this.getTitle(grip),
-          objectLink({
-            className: "arrayLeftBracket",
-            role: "presentation",
-            object: grip
-          }, "["),
-          items,
-          objectLink({
-            className: "arrayRightBracket",
-            role: "presentation",
-            object: grip
-          }, "]")
-        )
-      );
-    },
-  });
-
-  /**
-   * Property for a grip object.
-   */
-  let PropRep = React.createFactory(React.createClass({
-    displayName: "PropRep",
-
-    propTypes: {
-      equal: React.PropTypes.string,
-      delim: React.PropTypes.string,
-    },
-
-    render: function () {
-      const { Rep } = createFactories(require("./rep"));
-
-      return (
-        span({},
-          span({
-            className: "nodeName"},
-            "$prop.name"
-          ),
-          span({
-            className: "objectEqual",
-            role: "presentation"},
-            this.props.equal
-          ),
-          Rep(this.props),
-          span({
-            className: "objectComma",
-            role: "presentation"},
-            this.props.delim
-          )
-        )
-      );
-    }
-  }));
-
-  // Registration
-
-  function supportsObject(grip, type) {
-    if (!isGrip(grip)) {
-      return false;
-    }
-
-    return (type == "NamedNodeMap" && grip.preview);
-  }
-
-  // Exports from this module
-  exports.NamedNodeMap = {
-    rep: NamedNodeMap,
-    supportsObject: supportsObject
-  };
-});
--- a/devtools/client/shared/components/reps/rep.js
+++ b/devtools/client/shared/components/reps/rep.js
@@ -22,17 +22,16 @@ define(function (require, exports, modul
   const { Obj } = require("./object");
 
   // DOM types (grips)
   const { Attribute } = require("./attribute");
   const { DateTime } = require("./date-time");
   const { Document } = require("./document");
   const { Event } = require("./event");
   const { Func } = require("./function");
-  const { NamedNodeMap } = require("./named-node-map");
   const { RegExp } = require("./regexp");
   const { StyleSheet } = require("./stylesheet");
   const { TextNode } = require("./text-node");
   const { Window } = require("./window");
   const { ObjectWithText } = require("./object-with-text");
   const { ObjectWithURL } = require("./object-with-url");
   const { GripArray } = require("./grip-array");
   const { Grip } = require("./grip");
@@ -41,17 +40,16 @@ define(function (require, exports, modul
   // XXX there should be a way for extensions to register a new
   // or modify an existing rep.
   let reps = [
     RegExp,
     StyleSheet,
     Event,
     DateTime,
     TextNode,
-    NamedNodeMap,
     Attribute,
     Func,
     ArrayRep,
     Document,
     Window,
     ObjectWithText,
     ObjectWithURL,
     GripArray,
--- a/devtools/client/shared/components/test/mochitest/test_reps_grip-array.html
+++ b/devtools/client/shared/components/test/mochitest/test_reps_grip-array.html
@@ -27,33 +27,35 @@ window.onload = Task.async(function* () 
   try {
     yield testBasic();
 
     // Test property iterator
     yield testMaxProps();
     yield testMoreThanShortMaxProps();
     yield testMoreThanLongMaxProps();
     yield testRecursiveArray();
+
+    yield testNamedNodeMap();
   } catch(e) {
     ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
   } finally {
     SimpleTest.finish();
   }
 
   function testBasic() {
     // Test array: `[]`
     const testName = "testBasic";
 
     // Test that correct rep is chosen
     const gripStub = getGripStub("testBasic");
     const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
     is(renderedRep.type, GripArray.rep, `Rep correctly selects ${GripArray.rep.displayName}`);
 
     // Test rendering
-    const defaultOutput = `[]`;
+    const defaultOutput = `Array[]`;
 
     const modeTests = [
       {
         mode: undefined,
         expectedOutput: defaultOutput,
       },
       {
         mode: "tiny",
@@ -71,17 +73,17 @@ window.onload = Task.async(function* () 
 
     testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
   }
 
   function testMaxProps() {
     // Test array: `[1, "foo", {}]`;
     const testName = "testMaxProps";
 
-    const defaultOutput = `[1, "foo", Object]`;
+    const defaultOutput = `Array[1, "foo", Object]`;
 
     const modeTests = [
       {
         mode: undefined,
         expectedOutput: defaultOutput,
       },
       {
         mode: "tiny",
@@ -99,46 +101,46 @@ window.onload = Task.async(function* () 
 
     testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
   }
 
   function testMoreThanShortMaxProps() {
     // Test array = `["test string"…] //4 items`
     const testName = "testMoreThanShortMaxProps";
 
-    const defaultOutput = `[${Array(maxLength.short).fill("\"test string\"").join(", ")}, more…]`;
+    const defaultOutput = `Array[${Array(maxLength.short).fill("\"test string\"").join(", ")}, more…]`;
 
     const modeTests = [
       {
         mode: undefined,
         expectedOutput: defaultOutput,
       },
       {
         mode: "tiny",
         expectedOutput: `[${maxLength.short + 1}]`,
       },
       {
         mode: "short",
         expectedOutput: defaultOutput,
       },
       {
         mode: "long",
-        expectedOutput: `[${Array(maxLength.short + 1).fill("\"test string\"").join(", ")}]`,
+        expectedOutput: `Array[${Array(maxLength.short + 1).fill("\"test string\"").join(", ")}]`,
       }
     ];
 
     testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
   }
 
   function testMoreThanLongMaxProps() {
     // Test array = `["test string"…] //301 items`
     const testName = "testMoreThanLongMaxProps";
 
-    const defaultShortOutput = `[${Array(maxLength.short).fill("\"test string\"").join(", ")}, more…]`;
-    const defaultLongOutput = `[${Array(maxLength.long).fill("\"test string\"").join(", ")}, more…]`;
+    const defaultShortOutput = `Array[${Array(maxLength.short).fill("\"test string\"").join(", ")}, more…]`;
+    const defaultLongOutput = `Array[${Array(maxLength.long).fill("\"test string\"").join(", ")}, more…]`;
 
     const modeTests = [
       {
         mode: undefined,
         expectedOutput: defaultShortOutput,
       },
       {
         mode: "tiny",
@@ -159,17 +161,17 @@ window.onload = Task.async(function* () 
 
   function testRecursiveArray() {
     // @TODO This is not how this feature should actually work
     // See Bug 1282465 - Reps: fix or remove recursive handling in grip-array
 
     // Test array = `let a = []; a = [a]`
     const testName = "testRecursiveArray";
 
-    const defaultOutput = `[[1]]`;
+    const defaultOutput = `Array[[1]]`;
 
     const modeTests = [
       {
         mode: undefined,
         expectedOutput: defaultOutput,
       },
       {
         mode: "tiny",
@@ -183,16 +185,43 @@ window.onload = Task.async(function* () 
         mode: "long",
         expectedOutput: defaultOutput,
       }
     ];
 
     testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
   }
 
+  function testNamedNodeMap() {
+    const testName = "testNamedNodeMap";
+
+    const defaultOutput = `NamedNodeMap[class="myclass", cellpadding="7", border="3"]`;
+
+    const modeTests = [
+      {
+        mode: undefined,
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "tiny",
+        expectedOutput: `[3]`,
+      },
+      {
+        mode: "short",
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "long",
+        expectedOutput: defaultOutput,
+      }
+    ];
+
+    testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
+  }
+
   function getGripStub(functionName) {
     switch (functionName) {
       case "testBasic":
         return {
           "type": "object",
           "class": "Array",
           "actor": "server1.conn0.obj35",
           "extensible": true,
@@ -306,15 +335,77 @@ window.onload = Task.async(function* () 
                 "preview": {
                   "kind": "ArrayLike",
                   "length": 1
                 }
               }
             ]
           }
         };
+
+        case "testNamedNodeMap":
+          return {
+            "type": "object",
+            "class": "NamedNodeMap",
+            "actor": "server1.conn3.obj42",
+            "extensible": true,
+            "frozen": false,
+            "sealed": false,
+            "ownPropertyLength": 6,
+            "preview": {
+              "kind": "ArrayLike",
+              "length": 3,
+              "items": [
+                {
+                  "type": "object",
+                  "class": "Attr",
+                  "actor": "server1.conn3.obj43",
+                  "extensible": true,
+                  "frozen": false,
+                  "sealed": false,
+                  "ownPropertyLength": 0,
+                  "preview": {
+                    "kind": "DOMNode",
+                    "nodeType": 2,
+                    "nodeName": "class",
+                    "value": "myclass"
+                  }
+                },
+                {
+                  "type": "object",
+                  "class": "Attr",
+                  "actor": "server1.conn3.obj44",
+                  "extensible": true,
+                  "frozen": false,
+                  "sealed": false,
+                  "ownPropertyLength": 0,
+                  "preview": {
+                    "kind": "DOMNode",
+                    "nodeType": 2,
+                    "nodeName": "cellpadding",
+                    "value": "7"
+                  }
+                },
+                {
+                  "type": "object",
+                  "class": "Attr",
+                  "actor": "server1.conn3.obj44",
+                  "extensible": true,
+                  "frozen": false,
+                  "sealed": false,
+                  "ownPropertyLength": 0,
+                  "preview": {
+                    "kind": "DOMNode",
+                    "nodeType": 2,
+                    "nodeName": "border",
+                    "value": "3"
+                  }
+                }
+              ]
+            }
+          };
     }
   }
 });
 </script>
 </pre>
 </body>
 </html>