{"action":"created","comment":{"url":"https://api.github.com/repos/mozilla/teach.webmaker.org/pulls/comments/32488081","id":32488081,"diff_hunk":"@@ -0,0 +1,169 @@\n+// AnchorManagerMixin is a React mixin that can be used to make the\n+// component support permalinkable anchors (URL fragments) that\n+// attract the user's attention to them when navigated to.\n+//\n+// Any component that uses this mixin supports an `anchorId` prop,\n+// which is the URL fragment (without the leading hash) of the anchor.\n+// This is expected to be constant throughout the lifetime of the\n+// component. (If `anchorId` is undefined, the mixin will be largely\n+// disabled.)\n+//\n+// When the window's location hash matches the component's anchor id,\n+// either at component mount time or during the `hashchange` window\n+// event, the component's `attractAttentionToAnchor` state will be\n+// set to `true` for 4 seconds. Additionally, if the component\n+// defines a `handleAttractAttentionToAnchor` method, it will be\n+// called. (The `attractAttentionToAnchor` method can be used to\n+// manually trigger this behavior as well.)\n+//\n+// The 4-second default can be changed if the component defines\n+// an instance variable called `ATTRACT_ATTENTION_TO_ANCHOR_DURATION`,\n+// which should be set to an integer value in milliseconds.\n+//\n+// Note that this mixin will *not* directly affect the component's\n+// rendering in any way. This means that it is not responsible for e.g.:\n+//\n+// * Setting any CSS classes, transitions, or animations.\n+// * Setting the `id` attribute of any elements.\n+// * Creating permalinks.\n+\n+var React = require('react');\n+\n+var DEFAULT_ATTRACT_DURATION = 4000;\n+\n+// AnchorManager is a largely private singleton class that maintains a\n+// registry mapping anchor names to React components and listens for\n+// location hash changes.\n+//\n+// When a registered component needs to be navigated to, its\n+// `handleNavigateToAnchor` method is called; when it needs to\n+// be navigated from, its `handleNavigateFromAnchor` method is called.\n+var AnchorManager = function() {\n+  this.anchorMap = {};\n+  this.initialized = false;\n+  this.currentAnchor = null;\n+  this.handleHashChange = this.handleHashChange.bind(this);\n+};\n+\n+AnchorManager.prototype = {\n+  register: function(component) {\n+    var anchorId = component.props.anchorId;\n+    if (process.env.NODE_ENV !== 'production' &&\n+        anchorId in this.anchorMap) {\n+      console.warn('Anchor for #' + anchorId + ' already registered.');\n+    }\n+    this.anchorMap[anchorId] = component;\n+    if (!this.initialized) {\n+      this.initialize();\n+      this.initialized = true;\n+    }\n+    this.handleHashChange();\n+    return component;\n+  },\n+  unregister: function(component) {\n+    var anchorId = component.props.anchorId;\n+    if (process.env.NODE_ENV !== 'production') {\n+      if (!(anchorId in this.anchorMap)) {\n+        console.warn('Anchor for #' + anchorId + ' does not exist.');\n+      } else if (this.anchorMap[anchorId] !== component) {\n+        console.warn('Anchor mismatch for #' + anchorId + '.');\n+      }\n+    }\n+    if (this.currentAnchor === component) {\n+      this.currentAnchor = null;\n+    }\n+    delete this.anchorMap[anchorId];\n+  },\n+  initialize: function() {\n+    window.addEventListener('hashchange', this.handleHashChange);\n+  },\n+  getHash: function() {\n+    return window.location.hash.slice(1);\n+  },\n+  handleHashChange: function() {\n+    var newAnchor = this.anchorMap[this.getHash()];\n+\n+    if (this.currentAnchor) {\n+      if (newAnchor === this.currentAnchor) {\n+        return;\n+      } else {\n+        this.currentAnchor.handleNavigateFromAnchor();\n+        this.currentAnchor = null;\n+      }\n+    }\n+    if (newAnchor) {\n+      this.currentAnchor = newAnchor;\n+      this.currentAnchor.handleNavigateToAnchor();\n+    }\n+  }\n+};\n+\n+var defaultAnchorManager = new AnchorManager();\n+\n+var AnchorManagerMixin = {\n+  propTypes: {\n+    anchorId: React.PropTypes.string,\n+    anchorManager: React.PropTypes.object\n+  },\n+  getDefaultProps: function() {\n+    return {\n+      anchorManager: defaultAnchorManager\n+    };\n+  },\n+  getInitialState: function() {\n+    return {\n+      attractAttentionToAnchor: false\n+    };\n+  },\n+  componentDidMount: function() {\n+    if (this.props.anchorId) {\n+      this.props.anchorManager.register(this);\n+    }\n+  },\n+  componentWillUnmount: function() {\n+    if (this.props.anchorId) {\n+      this.props.anchorManager.unregister(this);\n+    }\n+    this.cancelAttractAttentionToAnchor();\n+  },\n+  handleNavigateToAnchor: function() {\n+    this.attractAttentionToAnchor();\n+  },\n+  handleNavigateFromAnchor: function() {\n+    this.cancelAttractAttentionToAnchor();\n+  },\n+  attractAttentionToAnchor: function() {\n+    this.setState({\n+      attractAttentionToAnchor: true\n+    });\n+    window.clearTimeout(this.attractTimeout);\n+    this.attractTimeout = window.setTimeout(","path":"mixins/anchor-manager.js","position":140,"original_position":140,"commit_id":"098867113549818de54348331f4200da70b1e6f9","original_commit_id":"098867113549818de54348331f4200da70b1e6f9","user":{"login":"mmmavis","id":2896608,"avatar_url":"https://avatars.githubusercontent.com/u/2896608?v=3","gravatar_id":"","url":"https://api.github.com/users/mmmavis","html_url":"https://github.com/mmmavis","followers_url":"https://api.github.com/users/mmmavis/followers","following_url":"https://api.github.com/users/mmmavis/following{/other_user}","gists_url":"https://api.github.com/users/mmmavis/gists{/gist_id}","starred_url":"https://api.github.com/users/mmmavis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mmmavis/subscriptions","organizations_url":"https://api.github.com/users/mmmavis/orgs","repos_url":"https://api.github.com/users/mmmavis/repos","events_url":"https://api.github.com/users/mmmavis/events{/privacy}","received_events_url":"https://api.github.com/users/mmmavis/received_events","type":"User","site_admin":false},"body":"Nice! And thanks for bringing up that `TimeoutTransitionGroup` issue again :+1: ","created_at":"2015-06-16T03:12:57Z","updated_at":"2015-06-16T03:12:57Z","html_url":"https://github.com/mozilla/teach.webmaker.org/pull/993#discussion_r32488081","pull_request_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/pulls/993","_links":{"self":{"href":"https://api.github.com/repos/mozilla/teach.webmaker.org/pulls/comments/32488081"},"html":{"href":"https://github.com/mozilla/teach.webmaker.org/pull/993#discussion_r32488081"},"pull_request":{"href":"https://api.github.com/repos/mozilla/teach.webmaker.org/pulls/993"}}},"pull_request":{"url":"https://api.github.com/repos/mozilla/teach.webmaker.org/pulls/993","id":36890675,"html_url":"https://github.com/mozilla/teach.webmaker.org/pull/993","diff_url":"https://github.com/mozilla/teach.webmaker.org/pull/993.diff","patch_url":"https://github.com/mozilla/teach.webmaker.org/pull/993.patch","issue_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/issues/993","number":993,"state":"open","locked":false,"title":"Add permalinks for Web Literacy Map expander sections","user":{"login":"toolness","id":124687,"avatar_url":"https://avatars.githubusercontent.com/u/124687?v=3","gravatar_id":"","url":"https://api.github.com/users/toolness","html_url":"https://github.com/toolness","followers_url":"https://api.github.com/users/toolness/followers","following_url":"https://api.github.com/users/toolness/following{/other_user}","gists_url":"https://api.github.com/users/toolness/gists{/gist_id}","starred_url":"https://api.github.com/users/toolness/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/toolness/subscriptions","organizations_url":"https://api.github.com/users/toolness/orgs","repos_url":"https://api.github.com/users/toolness/repos","events_url":"https://api.github.com/users/toolness/events{/privacy}","received_events_url":"https://api.github.com/users/toolness/received_events","type":"User","site_admin":false},"body":"This is a potential fix for #975. It's a bit weird because our Expander already actually behaves somewhat inconsistently, and making it accessible is not particularly straightforward.\r\n\r\nRight now this adds a [section sign (§)](http://en.wikipedia.org/wiki/Section_sign) at the top-right of each expander section. Clicking on it will set your browser's current URL to a permalink for the section. Here's an example permalink to the Accessibility section of the Web Literacy Map, hosted on my personal deployment branch thingy:\r\n\r\nhttp://mozteach.toolness.org/teach-like-mozilla/web-literacy/#accessibility\r\n\r\nVisiting that *should* automatically expand the Accessibility section and focus keyboard navigation on it.\r\n\r\n(You can also see what that link looks like [with JS disabled](http://mozteach.toolness.org/teach-like-mozilla/web-literacy/?safemode=on#accessibility).)\r\n\r\nRight now this PR throws out a lot of the focus/blur stuff in the existing code because (A) it was buggy/not behaving consistently and (B) trying to make it un-buggy resulted in lots of weird annoying edge cases, such as always collapsing the current section when switching to a different application.\r\n","created_at":"2015-06-03T23:56:43Z","updated_at":"2015-06-16T03:12:57Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4ca50019caff2a60047a4c1f8f5b8b5cd315dd37","assignee":{"login":"mmmavis","id":2896608,"avatar_url":"https://avatars.githubusercontent.com/u/2896608?v=3","gravatar_id":"","url":"https://api.github.com/users/mmmavis","html_url":"https://github.com/mmmavis","followers_url":"https://api.github.com/users/mmmavis/followers","following_url":"https://api.github.com/users/mmmavis/following{/other_user}","gists_url":"https://api.github.com/users/mmmavis/gists{/gist_id}","starred_url":"https://api.github.com/users/mmmavis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mmmavis/subscriptions","organizations_url":"https://api.github.com/users/mmmavis/orgs","repos_url":"https://api.github.com/users/mmmavis/repos","events_url":"https://api.github.com/users/mmmavis/events{/privacy}","received_events_url":"https://api.github.com/users/mmmavis/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/pulls/993/commits","review_comments_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/pulls/993/comments","review_comment_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/issues/993/comments","statuses_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/statuses/098867113549818de54348331f4200da70b1e6f9","head":{"label":"toolness:expander-permalinks","ref":"expander-permalinks","sha":"098867113549818de54348331f4200da70b1e6f9","user":{"login":"toolness","id":124687,"avatar_url":"https://avatars.githubusercontent.com/u/124687?v=3","gravatar_id":"","url":"https://api.github.com/users/toolness","html_url":"https://github.com/toolness","followers_url":"https://api.github.com/users/toolness/followers","following_url":"https://api.github.com/users/toolness/following{/other_user}","gists_url":"https://api.github.com/users/toolness/gists{/gist_id}","starred_url":"https://api.github.com/users/toolness/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/toolness/subscriptions","organizations_url":"https://api.github.com/users/toolness/orgs","repos_url":"https://api.github.com/users/toolness/repos","events_url":"https://api.github.com/users/toolness/events{/privacy}","received_events_url":"https://api.github.com/users/toolness/received_events","type":"User","site_admin":false},"repo":{"id":31624744,"name":"teach.webmaker.org","full_name":"toolness/teach.webmaker.org","owner":{"login":"toolness","id":124687,"avatar_url":"https://avatars.githubusercontent.com/u/124687?v=3","gravatar_id":"","url":"https://api.github.com/users/toolness","html_url":"https://github.com/toolness","followers_url":"https://api.github.com/users/toolness/followers","following_url":"https://api.github.com/users/toolness/following{/other_user}","gists_url":"https://api.github.com/users/toolness/gists{/gist_id}","starred_url":"https://api.github.com/users/toolness/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/toolness/subscriptions","organizations_url":"https://api.github.com/users/toolness/orgs","repos_url":"https://api.github.com/users/toolness/repos","events_url":"https://api.github.com/users/toolness/events{/privacy}","received_events_url":"https://api.github.com/users/toolness/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/toolness/teach.webmaker.org","description":"This repo is for tracking initiatives of the Mozilla Learning Networks team.","fork":true,"url":"https://api.github.com/repos/toolness/teach.webmaker.org","forks_url":"https://api.github.com/repos/toolness/teach.webmaker.org/forks","keys_url":"https://api.github.com/repos/toolness/teach.webmaker.org/keys{/key_id}","collaborators_url":"https://api.github.com/repos/toolness/teach.webmaker.org/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/toolness/teach.webmaker.org/teams","hooks_url":"https://api.github.com/repos/toolness/teach.webmaker.org/hooks","issue_events_url":"https://api.github.com/repos/toolness/teach.webmaker.org/issues/events{/number}","events_url":"https://api.github.com/repos/toolness/teach.webmaker.org/events","assignees_url":"https://api.github.com/repos/toolness/teach.webmaker.org/assignees{/user}","branches_url":"https://api.github.com/repos/toolness/teach.webmaker.org/branches{/branch}","tags_url":"https://api.github.com/repos/toolness/teach.webmaker.org/tags","blobs_url":"https://api.github.com/repos/toolness/teach.webmaker.org/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/toolness/teach.webmaker.org/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/toolness/teach.webmaker.org/git/refs{/sha}","trees_url":"https://api.github.com/repos/toolness/teach.webmaker.org/git/trees{/sha}","statuses_url":"https://api.github.com/repos/toolness/teach.webmaker.org/statuses/{sha}","languages_url":"https://api.github.com/repos/toolness/teach.webmaker.org/languages","stargazers_url":"https://api.github.com/repos/toolness/teach.webmaker.org/stargazers","contributors_url":"https://api.github.com/repos/toolness/teach.webmaker.org/contributors","subscribers_url":"https://api.github.com/repos/toolness/teach.webmaker.org/subscribers","subscription_url":"https://api.github.com/repos/toolness/teach.webmaker.org/subscription","commits_url":"https://api.github.com/repos/toolness/teach.webmaker.org/commits{/sha}","git_commits_url":"https://api.github.com/repos/toolness/teach.webmaker.org/git/commits{/sha}","comments_url":"https://api.github.com/repos/toolness/teach.webmaker.org/comments{/number}","issue_comment_url":"https://api.github.com/repos/toolness/teach.webmaker.org/issues/comments{/number}","contents_url":"https://api.github.com/repos/toolness/teach.webmaker.org/contents/{+path}","compare_url":"https://api.github.com/repos/toolness/teach.webmaker.org/compare/{base}...{head}","merges_url":"https://api.github.com/repos/toolness/teach.webmaker.org/merges","archive_url":"https://api.github.com/repos/toolness/teach.webmaker.org/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/toolness/teach.webmaker.org/downloads","issues_url":"https://api.github.com/repos/toolness/teach.webmaker.org/issues{/number}","pulls_url":"https://api.github.com/repos/toolness/teach.webmaker.org/pulls{/number}","milestones_url":"https://api.github.com/repos/toolness/teach.webmaker.org/milestones{/number}","notifications_url":"https://api.github.com/repos/toolness/teach.webmaker.org/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/toolness/teach.webmaker.org/labels{/name}","releases_url":"https://api.github.com/repos/toolness/teach.webmaker.org/releases{/id}","created_at":"2015-03-03T22:25:23Z","updated_at":"2015-05-19T14:38:36Z","pushed_at":"2015-06-15T21:45:06Z","git_url":"git://github.com/toolness/teach.webmaker.org.git","ssh_url":"git@github.com:toolness/teach.webmaker.org.git","clone_url":"https://github.com/toolness/teach.webmaker.org.git","svn_url":"https://github.com/toolness/teach.webmaker.org","homepage":"http://teach.mofostaging.net/","size":19883,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"mozilla:develop","ref":"develop","sha":"09c0406fde6dab40bc1117aa5a9cb2fae05fdad3","user":{"login":"mozilla","id":131524,"avatar_url":"https://avatars.githubusercontent.com/u/131524?v=3","gravatar_id":"","url":"https://api.github.com/users/mozilla","html_url":"https://github.com/mozilla","followers_url":"https://api.github.com/users/mozilla/followers","following_url":"https://api.github.com/users/mozilla/following{/other_user}","gists_url":"https://api.github.com/users/mozilla/gists{/gist_id}","starred_url":"https://api.github.com/users/mozilla/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mozilla/subscriptions","organizations_url":"https://api.github.com/users/mozilla/orgs","repos_url":"https://api.github.com/users/mozilla/repos","events_url":"https://api.github.com/users/mozilla/events{/privacy}","received_events_url":"https://api.github.com/users/mozilla/received_events","type":"Organization","site_admin":false},"repo":{"id":30430269,"name":"teach.webmaker.org","full_name":"mozilla/teach.webmaker.org","owner":{"login":"mozilla","id":131524,"avatar_url":"https://avatars.githubusercontent.com/u/131524?v=3","gravatar_id":"","url":"https://api.github.com/users/mozilla","html_url":"https://github.com/mozilla","followers_url":"https://api.github.com/users/mozilla/followers","following_url":"https://api.github.com/users/mozilla/following{/other_user}","gists_url":"https://api.github.com/users/mozilla/gists{/gist_id}","starred_url":"https://api.github.com/users/mozilla/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mozilla/subscriptions","organizations_url":"https://api.github.com/users/mozilla/orgs","repos_url":"https://api.github.com/users/mozilla/repos","events_url":"https://api.github.com/users/mozilla/events{/privacy}","received_events_url":"https://api.github.com/users/mozilla/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mozilla/teach.webmaker.org","description":"This repo is for tracking initiatives of the Mozilla Learning Networks team.","fork":false,"url":"https://api.github.com/repos/mozilla/teach.webmaker.org","forks_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/forks","keys_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/teams","hooks_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/hooks","issue_events_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/issues/events{/number}","events_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/events","assignees_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/assignees{/user}","branches_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/branches{/branch}","tags_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/tags","blobs_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/git/refs{/sha}","trees_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/statuses/{sha}","languages_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/languages","stargazers_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/stargazers","contributors_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/contributors","subscribers_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/subscribers","subscription_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/subscription","commits_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/commits{/sha}","git_commits_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/git/commits{/sha}","comments_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/comments{/number}","issue_comment_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/issues/comments{/number}","contents_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/contents/{+path}","compare_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/merges","archive_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/downloads","issues_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/issues{/number}","pulls_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/pulls{/number}","milestones_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/milestones{/number}","notifications_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/labels{/name}","releases_url":"https://api.github.com/repos/mozilla/teach.webmaker.org/releases{/id}","created_at":"2015-02-06T19:54:24Z","updated_at":"2015-06-08T16:26:28Z","pushed_at":"2015-06-16T00:32:12Z","git_url":"git://github.com/mozilla/teach.webmaker.org.git","ssh_url":"git@github.com:mozilla/teach.webmaker.org.git","clone_url":"https://github.com/mozilla/teach.webmaker.org.git","svn_url":"https://github.com/mozilla/teach.webmaker.org","homepage":"http://teach.mofostaging.net/","size":100989,"stargazers_count":10,"watchers_count":10,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":22,"mirror_url":null,"open_issues_count":117,"forks":22,"open_issues":117,"watchers":10,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/mozilla/teach.webmaker.org/pulls/993"},"html":{"href":"https://github.com/mozilla/teach.webmaker.org/pull/993"},"issue":{"href":"https://api.github.com/repos/mozilla/teach.webmaker.org/issues/993"},"comments":{"href":"https://api.github.com/repos/mozilla/teach.webmaker.org/issues/993/comments"},"review_comments":{"href":"https://api.github.com/repos/mozilla/teach.webmaker.org/pulls/993/comments"},"review_comment":{"href":"https://api.github.com/repos/mozilla/teach.webmaker.org/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mozilla/teach.webmaker.org/pulls/993/commits"},"statuses":{"href":"https://api.github.com/repos/mozilla/teach.webmaker.org/statuses/098867113549818de54348331f4200da70b1e6f9"}}}}