Merge branch 'issue/2' into develop
diff --git a/weinre.web/demo/weinre-demo-min.html b/weinre.web/demo/weinre-demo-min.html
index 5d985b8..74db41a 100644
--- a/weinre.web/demo/weinre-demo-min.html
+++ b/weinre.web/demo/weinre-demo-min.html
@@ -19,6 +19,11 @@
     color: blue;
 }
 
+#metrics {
+    margin:   1em;
+    border:   0.2em solid;
+    padding:  3em;
+}
 </style>
 </head>
 
@@ -27,6 +32,7 @@
 <h1 class="blue">this is a blue h1 element</h1>
 <h1 style="color:red">this is a red h1 element</h1>
 <p>Some text, <i>some italic text</i>, and <b>some bold text</b>.
+<div id="metrics">a div</div>
 </body>
 
 </html>
diff --git a/weinre.web/demo/weinre-demo-pieces.html b/weinre.web/demo/weinre-demo-pieces.html
index 690bea2..cc59ef6 100644
--- a/weinre.web/demo/weinre-demo-pieces.html
+++ b/weinre.web/demo/weinre-demo-pieces.html
@@ -32,6 +32,7 @@
 <script src="/weinre/target/CSSStore.transportd.js"                                ></script>
 <script src="/weinre/target/InjectedScriptHostImpl.transportd.js"                  ></script>
 <script src="/weinre/target/Target.transportd.js"                                  ></script>
+<script src="/weinre/target/ElementHighlighter.transportd.js"                                  ></script>
 <script src="/interfaces/all-json-idls.js"                                         ></script>
 
 <script type="text/javascript">
@@ -47,6 +48,11 @@
     color: blue;
 }
 
+#metrics {
+    margin:   1em;
+    border:   0.2em solid;
+    padding:  3em;
+}
 </style>
 </head>
 
@@ -55,6 +61,7 @@
 <h1 class="blue">this is a blue h1 element</h1>
 <h1 style="color:red">this is a red h1 element</h1>
 <p>Some text, <i>some italic text</i>, and <b>some bold text</b>.
+<div id="metrics">a div</div>
 </body>
 
 </html>
diff --git a/weinre.web/demo/weinre-demo.html b/weinre.web/demo/weinre-demo.html
index 3434762..04463ab 100644
--- a/weinre.web/demo/weinre-demo.html
+++ b/weinre.web/demo/weinre-demo.html
@@ -19,6 +19,11 @@
     color: blue;
 }
 
+#metrics {
+    margin:   1em;
+    border:   0.2em solid;
+    padding:  3em;
+}
 </style>
 </head>
 
@@ -27,6 +32,8 @@
 <h1 class="blue">this is a blue h1 element</h1>
 <h1 style="color:red">this is a red h1 element</h1>
 <p>Some text, <i>some italic text</i>, and <b>some bold text</b>.
+
+<div id="metrics">a div</div>
 </body>
 
 </html>
diff --git a/weinre.web/modules/weinre/target/ElementHighlighter.scoop b/weinre.web/modules/weinre/target/ElementHighlighter.scoop
new file mode 100644
index 0000000..88f2ef1
--- /dev/null
+++ b/weinre.web/modules/weinre/target/ElementHighlighter.scoop
@@ -0,0 +1,153 @@
+
+/*
+ * weinre is available under *either* the terms of the modified BSD license *or* the
+ * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
+ * 
+ * Copyright (c) 2010, 2011 IBM Corporation
+ */
+
+require ../common/Binding
+require ../common/Weinre
+
+//-----------------------------------------------------------------------------
+// 
+//-----------------------------------------------------------------------------
+class ElementHighlighter
+    this.boxMargin  = document.createElement("div")
+    this.boxBorder  = document.createElement("div")
+    this.boxPadding = document.createElement("div")
+    this.boxContent = document.createElement("div")
+    
+    this.boxMargin.appendChild(this.boxBorder)
+    this.boxBorder.appendChild(this.boxPadding)
+    this.boxPadding.appendChild(this.boxContent)
+    
+    this.boxMargin.style.backgroundColor  = "#FCC"
+    this.boxBorder.style.backgroundColor  = "#000"
+    this.boxPadding.style.backgroundColor = "#CFC"
+    this.boxContent.style.backgroundColor = "#CCF"
+    
+    this.boxMargin.style.opacity =
+    this.boxBorder.style.opacity =
+    this.boxPadding.style.opacity =
+    this.boxContent.style.opacity = 0.6
+    
+    this.boxMargin.style.position =
+    this.boxBorder.style.position =
+    this.boxPadding.style.position =
+    this.boxContent.style.position = "absolute"
+    
+//-----------------------------------------------------------------------------
+// 
+//-----------------------------------------------------------------------------
+method on(element)
+    if (null == element) return
+    if (element.nodeType != Node.ELEMENT_NODE) return
+    
+    this.calculateMetrics(element)
+    document.body.appendChild(this.boxMargin)
+    this.boxMargin.style.opacity = 0.6
+
+//-----------------------------------------------------------------------------
+// 
+//-----------------------------------------------------------------------------
+method off
+    this.boxMargin.style.opacity = 0
+    document.body.removeChild(this.boxMargin)
+
+//-----------------------------------------------------------------------------
+// 
+//-----------------------------------------------------------------------------
+getter element
+    return this.boxMargin
+
+//-----------------------------------------------------------------------------
+// 
+//-----------------------------------------------------------------------------
+method calculateMetrics(element)
+
+    var metrics = getMetrics(element)
+    
+    this.boxMargin.style.top     = metrics.y      + "px"
+    this.boxMargin.style.left    = metrics.x      + "px"
+    this.boxMargin.style.height  = metrics.height + "px"
+    this.boxMargin.style.width   = metrics.width  + "px"
+
+    this.boxBorder.style.top     = metrics.marginTop    + "px"
+    this.boxBorder.style.left    = metrics.marginLeft   + "px"
+    this.boxBorder.style.bottom  = metrics.marginBottom + "px"
+    this.boxBorder.style.right   = metrics.marginRight  + "px"
+
+    this.boxPadding.style.top    = metrics.borderTop    + "px"
+    this.boxPadding.style.left   = metrics.borderLeft   + "px"
+    this.boxPadding.style.bottom = metrics.borderBottom + "px"
+    this.boxPadding.style.right  = metrics.borderRight  + "px"
+    
+    this.boxContent.style.top    = metrics.paddingTop    + "px"
+    this.boxContent.style.left   = metrics.paddingLeft   + "px"
+    this.boxContent.style.bottom = metrics.paddingBottom + "px"
+    this.boxContent.style.right  = metrics.paddingRight  + "px"
+    
+//-----------------------------------------------------------------------------
+// 
+//-----------------------------------------------------------------------------
+function getMetrics(element)
+    var result = {}
+    
+    // get the x,y position
+    var left = 0
+    var top  = 0
+        
+    var el = element
+    do {
+        left += el.offsetLeft
+        top  += el.offsetTop
+    } while (el = el.offsetParent)
+    
+    result.x = left
+    result.y = top
+
+    // get the computed style
+    var cStyle = document.defaultView.getComputedStyle(element)
+    
+    result.width  = fromPx(cStyle["width"])
+    result.height = fromPx(cStyle["height"])
+    
+    result.marginLeft    = fromPx(cStyle["margin-left"])
+    result.marginRight   = fromPx(cStyle["margin-right"])
+    result.marginTop     = fromPx(cStyle["margin-top"])
+    result.marginBottom  = fromPx(cStyle["margin-bottom"])
+    
+    result.borderLeft    = fromPx(cStyle["border-left-width"])
+    result.borderRight   = fromPx(cStyle["border-right-width"])
+    result.borderTop     = fromPx(cStyle["border-top-width"])
+    result.borderBottom  = fromPx(cStyle["border-bottom-width"])
+    
+    result.paddingLeft   = fromPx(cStyle["padding-left"])
+    result.paddingRight  = fromPx(cStyle["padding-right"])
+    result.paddingTop    = fromPx(cStyle["padding-top"])
+    result.paddingBottom = fromPx(cStyle["padding-bottom"])
+
+    result.width += 
+        result.marginLeft  + result.marginRight +
+        result.borderRight  +
+        result.paddingLeft + result.paddingRight
+        
+    result.height += 
+        result.marginTop  + result.marginBottom +
+        result.borderBottom  +
+        result.paddingTop + result.paddingBottom
+        
+    result.x -= 
+        result.marginLeft
+        
+    result.y -= 
+        result.marginTop
+
+    return result
+    
+//-----------------------------------------------------------------------------
+// 
+//-----------------------------------------------------------------------------
+function fromPx(string) 
+    return parseInt(string.replace(/px$/,""))
diff --git a/weinre.web/modules/weinre/target/NodeStore.scoop b/weinre.web/modules/weinre/target/NodeStore.scoop
index 27aeefc..d2762b8 100644
--- a/weinre.web/modules/weinre/target/NodeStore.scoop
+++ b/weinre.web/modules/weinre/target/NodeStore.scoop
@@ -146,6 +146,7 @@
     
     for (var i=0; i<node.childNodes.length; i++) {
         if (this.isWhitespace(node.childNodes[i])) continue
+        if (node == this.highlightElement) continue
         count++
     }
     
@@ -159,6 +160,7 @@
     
     for (var i=0; i<node.childNodes.length; i++) {
         if (this.isWhitespace(node.childNodes[i])) continue
+        if (node == this.highlightElement) continue
         ids.push(this.getNodeId(node.childNodes[i]))
     }
     
@@ -172,3 +174,8 @@
     if (node.nodeType != Node.TEXT_NODE) return false
     return !!node.nodeValue.match(/^\s*$/) 
 
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+method setHighlightElement(node) 
+    this.highlightElement = node
diff --git a/weinre.web/modules/weinre/target/Target.scoop b/weinre.web/modules/weinre/target/Target.scoop
index 605fca9..4c2269c 100644
--- a/weinre.web/modules/weinre/target/Target.scoop
+++ b/weinre.web/modules/weinre/target/Target.scoop
@@ -13,6 +13,7 @@
 
 require ./NodeStore
 require ./CSSStore
+require ./ElementHighlighter
 require ./InjectedScriptHostImpl
 require ./WebInspectorApplicationCacheHandlerImpl
 require ./WebInspectorBackendHandlerImpl
@@ -137,6 +138,9 @@
 // 
 //-----------------------------------------------------------------------------
 method setDocument()
+    Weinre.elementHighlighter = new ElementHighlighter()
+    Weinre.nodeStore.setHighlightElement(Weinre.elementHighlighter.element)
+    
     var nodeId = Weinre.nodeStore.getNodeId(document)
     var nodeData = Weinre.nodeStore.getNodeData(nodeId, 2)
 
diff --git a/weinre.web/modules/weinre/target/WebInspectorControllerHandlerImpl.scoop b/weinre.web/modules/weinre/target/WebInspectorControllerHandlerImpl.scoop
index 680c260..61a17a9 100644
--- a/weinre.web/modules/weinre/target/WebInspectorControllerHandlerImpl.scoop
+++ b/weinre.web/modules/weinre/target/WebInspectorControllerHandlerImpl.scoop
@@ -171,15 +171,27 @@
 //
 //-----------------------------------------------------------------------------
 method highlightDOMNode(/*int*/ nodeId, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
+    var node = Weinre.nodeStore.getNode(nodeId)
+    if (!node) {
+        console.log(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
+        return
+    }
+
+    Weinre.elementHighlighter.on(node)
+    
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback)
+    }
 
 //-----------------------------------------------------------------------------
 //
 //-----------------------------------------------------------------------------
 method hideDOMNodeHighlight(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
+    Weinre.elementHighlighter.off()
+    
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback)
+    }
 
 //-----------------------------------------------------------------------------
 //