{"action":"created","comment":{"url":"https://api.github.com/repos/facebook/stetho/pulls/comments/25717418","id":25717418,"diff_hunk":"@@ -2,30 +2,233 @@\n \n package com.facebook.stetho.inspector.protocol.module;\n \n+import com.facebook.stetho.common.LogUtil;\n+import com.facebook.stetho.common.Util;\n+import com.facebook.stetho.inspector.elements.DOMProvider;\n+import com.facebook.stetho.inspector.elements.NodeAttribute;\n+import com.facebook.stetho.inspector.elements.NodeDescriptor;\n+import com.facebook.stetho.inspector.elements.NodeType;\n+import com.facebook.stetho.inspector.helper.ChromePeerManager;\n+import com.facebook.stetho.inspector.helper.ObjectIdMapper;\n+import com.facebook.stetho.inspector.helper.PeersRegisteredListener;\n import com.facebook.stetho.inspector.jsonrpc.JsonRpcPeer;\n import com.facebook.stetho.inspector.jsonrpc.JsonRpcResult;\n import com.facebook.stetho.inspector.protocol.ChromeDevtoolsDomain;\n import com.facebook.stetho.inspector.protocol.ChromeDevtoolsMethod;\n+import com.facebook.stetho.json.ObjectMapper;\n import com.facebook.stetho.json.annotation.JsonProperty;\n \n import org.json.JSONObject;\n \n+import java.util.ArrayList;\n+import java.util.Collections;\n+import java.util.List;\n+\n public class DOM implements ChromeDevtoolsDomain {\n-  public DOM() {\n+  private final ChromePeerManager mPeerManager;\n+  private final DOMProvider.Factory mDOMProviderFactory;\n+\n+  private ObjectMapper mObjectMapper;\n+  private DOMProvider mDOMProvider;\n+  private DOMObjectIdMapper mObjectIdMapper;\n+\n+  public DOM(DOMProvider.Factory providerFactory) {\n+    mDOMProviderFactory = Util.throwIfNull(providerFactory);\n+\n+    mPeerManager = new ChromePeerManager();\n+    mPeerManager.setListener(new PeerManagerListener());\n+  }\n+\n+  private final class PeerManagerListener extends PeersRegisteredListener {\n+    @Override\n+    protected void onFirstPeerRegistered() {\n+      assert(mDOMProvider == null);\n+\n+      mObjectMapper = new ObjectMapper();","path":"stetho/src/main/java/com/facebook/stetho/inspector/protocol/module/DOM.java","position":47,"original_position":47,"commit_id":"0ae2df0edeec3e41f56d42cc2f78b6e971c680e6","original_commit_id":"0ae2df0edeec3e41f56d42cc2f78b6e971c680e6","user":{"login":"jasta","id":83791,"avatar_url":"https://avatars.githubusercontent.com/u/83791?v=3","gravatar_id":"","url":"https://api.github.com/users/jasta","html_url":"https://github.com/jasta","followers_url":"https://api.github.com/users/jasta/followers","following_url":"https://api.github.com/users/jasta/following{/other_user}","gists_url":"https://api.github.com/users/jasta/gists{/gist_id}","starred_url":"https://api.github.com/users/jasta/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jasta/subscriptions","organizations_url":"https://api.github.com/users/jasta/orgs","repos_url":"https://api.github.com/users/jasta/repos","events_url":"https://api.github.com/users/jasta/events{/privacy}","received_events_url":"https://api.github.com/users/jasta/received_events","type":"User","site_admin":false},"body":"This is unnecessary FWIW.  `ObjectMapper` is basically just static functions (we should have made them static functions actually).  It has no initialization and accounts for just 1 object.  Likewise, `mObjectIdMapper` is also very small if you clear the data structure.  It's only `mDOMProvider` that's considered large and is special cased using this pattern.\r\n\r\nIt's your choice as to whether you adjust things, but you must use `@Nullable` for all fields that you deinitialization in this way which is where I think you'll find that the choice is a little uglier than I think you'd prefer (IntelliJ will start warning you all over about possible null access).","created_at":"2015-03-03T19:23:56Z","updated_at":"2015-03-03T19:23:56Z","html_url":"https://github.com/facebook/stetho/pull/73#discussion_r25717418","pull_request_url":"https://api.github.com/repos/facebook/stetho/pulls/73","_links":{"self":{"href":"https://api.github.com/repos/facebook/stetho/pulls/comments/25717418"},"html":{"href":"https://github.com/facebook/stetho/pull/73#discussion_r25717418"},"pull_request":{"href":"https://api.github.com/repos/facebook/stetho/pulls/73"}}},"pull_request":{"url":"https://api.github.com/repos/facebook/stetho/pulls/73","id":29939697,"html_url":"https://github.com/facebook/stetho/pull/73","diff_url":"https://github.com/facebook/stetho/pull/73.diff","patch_url":"https://github.com/facebook/stetho/pull/73.patch","issue_url":"https://api.github.com/repos/facebook/stetho/issues/73","number":73,"state":"open","locked":false,"title":"Initial check-in for Elements tab","user":{"login":"rickbrew","id":10873410,"avatar_url":"https://avatars.githubusercontent.com/u/10873410?v=3","gravatar_id":"","url":"https://api.github.com/users/rickbrew","html_url":"https://github.com/rickbrew","followers_url":"https://api.github.com/users/rickbrew/followers","following_url":"https://api.github.com/users/rickbrew/following{/other_user}","gists_url":"https://api.github.com/users/rickbrew/gists{/gist_id}","starred_url":"https://api.github.com/users/rickbrew/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rickbrew/subscriptions","organizations_url":"https://api.github.com/users/rickbrew/orgs","repos_url":"https://api.github.com/users/rickbrew/repos","events_url":"https://api.github.com/users/rickbrew/events{/privacy}","received_events_url":"https://api.github.com/users/rickbrew/received_events","type":"User","site_admin":false},"body":"This is a first stab at providing an Elements tab for Stetho.\r\n\r\nThe DOM class handles the JSON protocol and element <--> node ID mapping. An element is meant to be a real object in whatever DOM-type tree is being plugged in via a DOM.Provider implementation. We implement this in UIDOMProvider and our \"DOM-type tree\" is an Android application. We use the android.app.Application as the root of the DOM, its children are the android.app.Activity instances (initial list retrieved via a hack, then updated via Application.ActivityLifecycleCallbacks), then the android.view.Window and finally its android.view.View tree.\r\n\r\nWe use DOM.NodeDescriptor to describe an element in terms of a node (DOM.Node). In UIDOMProvider we use the element's class to figure out which descriptor(s) to use, but another DOM.Provider implementation could potentially choose another strategy.\r\n\r\nFor instance, an android.view.ViewGroup is an \"element.\" ViewGroupNodeDescriptor knows how to describe it in DOM.Node terms (name, children), and how to hook into it (with ViewGroup.OnHierarchyChangedListener) in order to report updates (via DOM.childNodeInserted / DOM.childNodeRemoved). Also participating in this are ViewNodeDescriptor (technically anyway, since it's currently empty) and ObjectNodeDescriptor (mostly just knows how to shorten class names to remove all the \"android.*.*\" package name noise).\r\n\r\nIn the Elements tab you can mouse-over a node and it will cause the Android device to draw a red highlight over the corresponding View. This is ultimately handled in the WindowNodeDescriptor class because that's where the highlighting View is installed (and uninstalled).\r\n\r\nFIrst step on #14 \r\n\r\n![screen shot 2015-02-24 at 1 27 13 pm](https://cloud.githubusercontent.com/assets/10873410/6359566/06d20ef2-bc29-11e4-8f81-1857c90f0680.png)","created_at":"2015-02-24T21:53:30Z","updated_at":"2015-03-03T19:23:56Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4f70d71b82d6c80b1965dfcdab072cb0ff4a09f9","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/facebook/stetho/pulls/73/commits","review_comments_url":"https://api.github.com/repos/facebook/stetho/pulls/73/comments","review_comment_url":"https://api.github.com/repos/facebook/stetho/pulls/comments{/number}","comments_url":"https://api.github.com/repos/facebook/stetho/issues/73/comments","statuses_url":"https://api.github.com/repos/facebook/stetho/statuses/0ae2df0edeec3e41f56d42cc2f78b6e971c680e6","head":{"label":"rickbrew:elements","ref":"elements","sha":"0ae2df0edeec3e41f56d42cc2f78b6e971c680e6","user":{"login":"rickbrew","id":10873410,"avatar_url":"https://avatars.githubusercontent.com/u/10873410?v=3","gravatar_id":"","url":"https://api.github.com/users/rickbrew","html_url":"https://github.com/rickbrew","followers_url":"https://api.github.com/users/rickbrew/followers","following_url":"https://api.github.com/users/rickbrew/following{/other_user}","gists_url":"https://api.github.com/users/rickbrew/gists{/gist_id}","starred_url":"https://api.github.com/users/rickbrew/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rickbrew/subscriptions","organizations_url":"https://api.github.com/users/rickbrew/orgs","repos_url":"https://api.github.com/users/rickbrew/repos","events_url":"https://api.github.com/users/rickbrew/events{/privacy}","received_events_url":"https://api.github.com/users/rickbrew/received_events","type":"User","site_admin":false},"repo":{"id":30989042,"name":"stetho","full_name":"rickbrew/stetho","owner":{"login":"rickbrew","id":10873410,"avatar_url":"https://avatars.githubusercontent.com/u/10873410?v=3","gravatar_id":"","url":"https://api.github.com/users/rickbrew","html_url":"https://github.com/rickbrew","followers_url":"https://api.github.com/users/rickbrew/followers","following_url":"https://api.github.com/users/rickbrew/following{/other_user}","gists_url":"https://api.github.com/users/rickbrew/gists{/gist_id}","starred_url":"https://api.github.com/users/rickbrew/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rickbrew/subscriptions","organizations_url":"https://api.github.com/users/rickbrew/orgs","repos_url":"https://api.github.com/users/rickbrew/repos","events_url":"https://api.github.com/users/rickbrew/events{/privacy}","received_events_url":"https://api.github.com/users/rickbrew/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/rickbrew/stetho","description":"Stetho is a debug bridge for Android applications, enabling the powerful Chrome Developer Tools and much more.","fork":true,"url":"https://api.github.com/repos/rickbrew/stetho","forks_url":"https://api.github.com/repos/rickbrew/stetho/forks","keys_url":"https://api.github.com/repos/rickbrew/stetho/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rickbrew/stetho/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rickbrew/stetho/teams","hooks_url":"https://api.github.com/repos/rickbrew/stetho/hooks","issue_events_url":"https://api.github.com/repos/rickbrew/stetho/issues/events{/number}","events_url":"https://api.github.com/repos/rickbrew/stetho/events","assignees_url":"https://api.github.com/repos/rickbrew/stetho/assignees{/user}","branches_url":"https://api.github.com/repos/rickbrew/stetho/branches{/branch}","tags_url":"https://api.github.com/repos/rickbrew/stetho/tags","blobs_url":"https://api.github.com/repos/rickbrew/stetho/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rickbrew/stetho/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rickbrew/stetho/git/refs{/sha}","trees_url":"https://api.github.com/repos/rickbrew/stetho/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rickbrew/stetho/statuses/{sha}","languages_url":"https://api.github.com/repos/rickbrew/stetho/languages","stargazers_url":"https://api.github.com/repos/rickbrew/stetho/stargazers","contributors_url":"https://api.github.com/repos/rickbrew/stetho/contributors","subscribers_url":"https://api.github.com/repos/rickbrew/stetho/subscribers","subscription_url":"https://api.github.com/repos/rickbrew/stetho/subscription","commits_url":"https://api.github.com/repos/rickbrew/stetho/commits{/sha}","git_commits_url":"https://api.github.com/repos/rickbrew/stetho/git/commits{/sha}","comments_url":"https://api.github.com/repos/rickbrew/stetho/comments{/number}","issue_comment_url":"https://api.github.com/repos/rickbrew/stetho/issues/comments{/number}","contents_url":"https://api.github.com/repos/rickbrew/stetho/contents/{+path}","compare_url":"https://api.github.com/repos/rickbrew/stetho/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rickbrew/stetho/merges","archive_url":"https://api.github.com/repos/rickbrew/stetho/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rickbrew/stetho/downloads","issues_url":"https://api.github.com/repos/rickbrew/stetho/issues{/number}","pulls_url":"https://api.github.com/repos/rickbrew/stetho/pulls{/number}","milestones_url":"https://api.github.com/repos/rickbrew/stetho/milestones{/number}","notifications_url":"https://api.github.com/repos/rickbrew/stetho/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rickbrew/stetho/labels{/name}","releases_url":"https://api.github.com/repos/rickbrew/stetho/releases{/id}","created_at":"2015-02-18T21:52:05Z","updated_at":"2015-02-18T21:52:06Z","pushed_at":"2015-03-03T00:28:24Z","git_url":"git://github.com/rickbrew/stetho.git","ssh_url":"git@github.com:rickbrew/stetho.git","clone_url":"https://github.com/rickbrew/stetho.git","svn_url":"https://github.com/rickbrew/stetho","homepage":"http://facebook.github.io/stetho/","size":740,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"facebook:elements","ref":"elements","sha":"84efa0c17a81d165cb63b1d64a79315bc8d06a47","user":{"login":"facebook","id":69631,"avatar_url":"https://avatars.githubusercontent.com/u/69631?v=3","gravatar_id":"","url":"https://api.github.com/users/facebook","html_url":"https://github.com/facebook","followers_url":"https://api.github.com/users/facebook/followers","following_url":"https://api.github.com/users/facebook/following{/other_user}","gists_url":"https://api.github.com/users/facebook/gists{/gist_id}","starred_url":"https://api.github.com/users/facebook/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/facebook/subscriptions","organizations_url":"https://api.github.com/users/facebook/orgs","repos_url":"https://api.github.com/users/facebook/repos","events_url":"https://api.github.com/users/facebook/events{/privacy}","received_events_url":"https://api.github.com/users/facebook/received_events","type":"Organization","site_admin":false},"repo":{"id":29703871,"name":"stetho","full_name":"facebook/stetho","owner":{"login":"facebook","id":69631,"avatar_url":"https://avatars.githubusercontent.com/u/69631?v=3","gravatar_id":"","url":"https://api.github.com/users/facebook","html_url":"https://github.com/facebook","followers_url":"https://api.github.com/users/facebook/followers","following_url":"https://api.github.com/users/facebook/following{/other_user}","gists_url":"https://api.github.com/users/facebook/gists{/gist_id}","starred_url":"https://api.github.com/users/facebook/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/facebook/subscriptions","organizations_url":"https://api.github.com/users/facebook/orgs","repos_url":"https://api.github.com/users/facebook/repos","events_url":"https://api.github.com/users/facebook/events{/privacy}","received_events_url":"https://api.github.com/users/facebook/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/facebook/stetho","description":"Stetho is a debug bridge for Android applications, enabling the powerful Chrome Developer Tools and much more.","fork":false,"url":"https://api.github.com/repos/facebook/stetho","forks_url":"https://api.github.com/repos/facebook/stetho/forks","keys_url":"https://api.github.com/repos/facebook/stetho/keys{/key_id}","collaborators_url":"https://api.github.com/repos/facebook/stetho/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/facebook/stetho/teams","hooks_url":"https://api.github.com/repos/facebook/stetho/hooks","issue_events_url":"https://api.github.com/repos/facebook/stetho/issues/events{/number}","events_url":"https://api.github.com/repos/facebook/stetho/events","assignees_url":"https://api.github.com/repos/facebook/stetho/assignees{/user}","branches_url":"https://api.github.com/repos/facebook/stetho/branches{/branch}","tags_url":"https://api.github.com/repos/facebook/stetho/tags","blobs_url":"https://api.github.com/repos/facebook/stetho/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/facebook/stetho/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/facebook/stetho/git/refs{/sha}","trees_url":"https://api.github.com/repos/facebook/stetho/git/trees{/sha}","statuses_url":"https://api.github.com/repos/facebook/stetho/statuses/{sha}","languages_url":"https://api.github.com/repos/facebook/stetho/languages","stargazers_url":"https://api.github.com/repos/facebook/stetho/stargazers","contributors_url":"https://api.github.com/repos/facebook/stetho/contributors","subscribers_url":"https://api.github.com/repos/facebook/stetho/subscribers","subscription_url":"https://api.github.com/repos/facebook/stetho/subscription","commits_url":"https://api.github.com/repos/facebook/stetho/commits{/sha}","git_commits_url":"https://api.github.com/repos/facebook/stetho/git/commits{/sha}","comments_url":"https://api.github.com/repos/facebook/stetho/comments{/number}","issue_comment_url":"https://api.github.com/repos/facebook/stetho/issues/comments{/number}","contents_url":"https://api.github.com/repos/facebook/stetho/contents/{+path}","compare_url":"https://api.github.com/repos/facebook/stetho/compare/{base}...{head}","merges_url":"https://api.github.com/repos/facebook/stetho/merges","archive_url":"https://api.github.com/repos/facebook/stetho/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/facebook/stetho/downloads","issues_url":"https://api.github.com/repos/facebook/stetho/issues{/number}","pulls_url":"https://api.github.com/repos/facebook/stetho/pulls{/number}","milestones_url":"https://api.github.com/repos/facebook/stetho/milestones{/number}","notifications_url":"https://api.github.com/repos/facebook/stetho/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/facebook/stetho/labels{/name}","releases_url":"https://api.github.com/repos/facebook/stetho/releases{/id}","created_at":"2015-01-22T22:34:10Z","updated_at":"2015-03-03T17:56:13Z","pushed_at":"2015-03-02T22:30:27Z","git_url":"git://github.com/facebook/stetho.git","ssh_url":"git@github.com:facebook/stetho.git","clone_url":"https://github.com/facebook/stetho.git","svn_url":"https://github.com/facebook/stetho","homepage":"http://facebook.github.io/stetho/","size":1716,"stargazers_count":1727,"watchers_count":1727,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":97,"mirror_url":null,"open_issues_count":12,"forks":97,"open_issues":12,"watchers":1727,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/facebook/stetho/pulls/73"},"html":{"href":"https://github.com/facebook/stetho/pull/73"},"issue":{"href":"https://api.github.com/repos/facebook/stetho/issues/73"},"comments":{"href":"https://api.github.com/repos/facebook/stetho/issues/73/comments"},"review_comments":{"href":"https://api.github.com/repos/facebook/stetho/pulls/73/comments"},"review_comment":{"href":"https://api.github.com/repos/facebook/stetho/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/facebook/stetho/pulls/73/commits"},"statuses":{"href":"https://api.github.com/repos/facebook/stetho/statuses/0ae2df0edeec3e41f56d42cc2f78b6e971c680e6"}}}}