{"action":"created","comment":{"url":"https://api.github.com/repos/videojs/video.js/pulls/comments/50748151","id":50748151,"diff_hunk":"@@ -0,0 +1,174 @@\n+/**\n+ * @file button.js\n+ */\n+import Component from './component';\n+import * as Dom from './utils/dom.js';\n+import * as Events from './utils/events.js';\n+import * as Fn from './utils/fn.js';\n+import log from './utils/log.js';\n+import document from 'global/document';\n+import assign from 'object.assign';\n+\n+/**\n+ * Clickable Component which is clickable or keyboard actionable, but is not a native HTML button\n+ *\n+ * @param {Object} player  Main Player\n+ * @param {Object=} options Object of option names and values\n+ * @extends Component\n+ * @class ClickableComponent\n+ */\n+class ClickableComponent extends Component {\n+\n+  constructor(player, options) {\n+    super(player, options);\n+\n+    this.emitTapEvents();\n+\n+    this.on('tap', this.handleClick);\n+    this.on('click', this.handleClick);\n+    this.on('focus', this.handleFocus);\n+    this.on('blur', this.handleBlur);\n+  }\n+\n+  /**\n+   * Create the component's DOM element\n+   *\n+   * @param {String=} type Element's node type. e.g. 'div'\n+   * @param {Object=} props An object of properties that should be set on the element\n+   * @param {Object=} attributes An object of attributes that should be set on the element\n+   * @return {Element}\n+   * @method createEl\n+   */\n+  createEl(tag='div', props={}, attributes={}) {\n+    props = assign({\n+      className: this.buildCSSClass(),\n+      tabIndex: 0\n+    }, props);\n+\n+    if (tag === 'button') {\n+      log.error(`Creating a ClickableComponent with an HTML element of ${tag} is not supported; use a Button instead.`);\n+    }\n+\n+    // Add ARIA attributes for clickable element which is not a native HTML button\n+    attributes = assign({\n+      role: 'button',\n+      'aria-live': 'polite' // let the screen reader user know that the text of the element may change\n+    }, attributes);\n+\n+    let el = super.createEl(tag, props, attributes);\n+\n+    this.createControlTextEl(el);\n+\n+    return el;\n+  }\n+\n+  /**\n+   * create control text\n+   *\n+   * @param {Element} el Parent element for the control text\n+   * @return {Element}\n+   * @method controlText\n+   */\n+  createControlTextEl(el) {\n+    this.controlTextEl_ = Dom.createEl('span', {\n+      className: 'vjs-control-text'\n+    });\n+\n+    if (el) {\n+      el.appendChild(this.controlTextEl_);\n+    }\n+\n+    this.controlText(this.controlText_);\n+\n+    return this.controlTextEl_;\n+  }\n+\n+  /**\n+   * Controls text - both request and localize\n+   *\n+   * @param {String} text Text for element\n+   * @return {String}\n+   * @method controlText\n+   */\n+  controlText(text) {\n+    if (!text) return this.controlText_ || 'Need Text';\n+\n+    this.controlText_ = text;\n+    this.controlTextEl_.innerHTML = this.localize(this.controlText_);\n+\n+    return this;\n+  }\n+\n+  /**\n+   * Allows sub components to stack CSS class names\n+   *\n+   * @return {String}\n+   * @method buildCSSClass\n+   */\n+  buildCSSClass() {\n+    return `vjs-control vjs-button ${super.buildCSSClass()}`;\n+  }\n+\n+  /**\n+   * Adds a child component inside this clickable-component\n+   *\n+   * @param {String|Component} child The class name or instance of a child to add\n+   * @param {Object=} options Options, including options to be passed to children of the child.\n+   * @return {Component} The child component (created by this process if a string was used)\n+   * @method addChild\n+   */\n+  addChild(child, options={}) {\n+    // TODO: Fix adding an actionable child to a ClickableComponent; currently\n+    // it will cause issues with assistive technology (e.g. screen readers)\n+    // which support ARIA, since an element with role=\"button\" cannot have\n+    // actionable child elements.\n+\n+    //let className = this.constructor.name;\n+    //log.warn(`Adding a child to a ClickableComponent (${className}) can cause issues with assistive technology which supports ARIA, since an element with role=\"button\" cannot have actionable child elements.`);\n+\n+    return super.addChild(child, options);\n+  }\n+\n+  /**\n+   * Handle Click - Override with specific functionality for component\n+   *\n+   * @method handleClick\n+   */\n+  handleClick() {}\n+\n+  /**\n+   * Handle Focus - Add keyboard functionality to element\n+   *\n+   * @method handleFocus\n+   */\n+  handleFocus() {\n+    Events.on(document, 'keydown', Fn.bind(this, this.handleKeyPress));\n+  }\n+\n+  /**\n+   * Handle KeyPress (document level) - Trigger click when Space or Enter key is pressed\n+   *\n+   * @method handleKeyPress\n+   */\n+  handleKeyPress(event) {\n+    // Support Space (32) or Enter (13) key operation to fire a click event\n+    if (event.which === 32 || event.which === 13) {\n+      event.preventDefault();\n+      this.handleClick(event);\n+    } else {\n+      super.handleKeyPress(event); // Pass keypress handling up for unsupported keys","path":"src/js/clickable-component.js","position":159,"original_position":159,"commit_id":"c0d540cf51eb0d6f781fc5e617e2d1b54ed4cab2","original_commit_id":"c0d540cf51eb0d6f781fc5e617e2d1b54ed4cab2","user":{"login":"gkatsev","id":535884,"avatar_url":"https://avatars.githubusercontent.com/u/535884?v=3","gravatar_id":"","url":"https://api.github.com/users/gkatsev","html_url":"https://github.com/gkatsev","followers_url":"https://api.github.com/users/gkatsev/followers","following_url":"https://api.github.com/users/gkatsev/following{/other_user}","gists_url":"https://api.github.com/users/gkatsev/gists{/gist_id}","starred_url":"https://api.github.com/users/gkatsev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gkatsev/subscriptions","organizations_url":"https://api.github.com/users/gkatsev/orgs","repos_url":"https://api.github.com/users/gkatsev/repos","events_url":"https://api.github.com/users/gkatsev/events{/privacy}","received_events_url":"https://api.github.com/users/gkatsev/received_events","type":"User","site_admin":false},"body":"We probably want the else to be:\r\n```js\r\n} else if (super.handleKeyPress) {\r\n  super.handleKeyPress(event);\r\n}\r\n```","created_at":"2016-01-25T20:06:22Z","updated_at":"2016-01-25T20:06:22Z","html_url":"https://github.com/videojs/video.js/pull/3032#discussion_r50748151","pull_request_url":"https://api.github.com/repos/videojs/video.js/pulls/3032","_links":{"self":{"href":"https://api.github.com/repos/videojs/video.js/pulls/comments/50748151"},"html":{"href":"https://github.com/videojs/video.js/pull/3032#discussion_r50748151"},"pull_request":{"href":"https://api.github.com/repos/videojs/video.js/pulls/3032"}}},"pull_request":{"url":"https://api.github.com/repos/videojs/video.js/pulls/3032","id":57043505,"html_url":"https://github.com/videojs/video.js/pull/3032","diff_url":"https://github.com/videojs/video.js/pull/3032.diff","patch_url":"https://github.com/videojs/video.js/pull/3032.patch","issue_url":"https://api.github.com/repos/videojs/video.js/issues/3032","number":3032,"state":"open","locked":false,"title":"Fix keyboard (Space or Enter) operation of buttons. Fixes #2888. Supercedes #2889","user":{"login":"OwenEdwards","id":2245205,"avatar_url":"https://avatars.githubusercontent.com/u/2245205?v=3","gravatar_id":"","url":"https://api.github.com/users/OwenEdwards","html_url":"https://github.com/OwenEdwards","followers_url":"https://api.github.com/users/OwenEdwards/followers","following_url":"https://api.github.com/users/OwenEdwards/following{/other_user}","gists_url":"https://api.github.com/users/OwenEdwards/gists{/gist_id}","starred_url":"https://api.github.com/users/OwenEdwards/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OwenEdwards/subscriptions","organizations_url":"https://api.github.com/users/OwenEdwards/orgs","repos_url":"https://api.github.com/users/OwenEdwards/repos","events_url":"https://api.github.com/users/OwenEdwards/events{/privacy}","received_events_url":"https://api.github.com/users/OwenEdwards/received_events","type":"User","site_admin":false},"body":"Better fix than #2889 for the problem with keyboard operation of buttons which was introduced by changing buttons to `<button>` elements, but leaving other clickable elements (menu buttons, poster image) as `<div>`s. By splitting them in different objects, this allows future changes to build on these two distinct bases.","created_at":"2016-01-25T09:02:34Z","updated_at":"2016-01-25T20:06:22Z","closed_at":null,"merged_at":null,"merge_commit_sha":null,"assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/videojs/video.js/pulls/3032/commits","review_comments_url":"https://api.github.com/repos/videojs/video.js/pulls/3032/comments","review_comment_url":"https://api.github.com/repos/videojs/video.js/pulls/comments{/number}","comments_url":"https://api.github.com/repos/videojs/video.js/issues/3032/comments","statuses_url":"https://api.github.com/repos/videojs/video.js/statuses/c0d540cf51eb0d6f781fc5e617e2d1b54ed4cab2","head":{"label":"OwenEdwards:fix/split-clickables-from-buttons","ref":"fix/split-clickables-from-buttons","sha":"c0d540cf51eb0d6f781fc5e617e2d1b54ed4cab2","user":{"login":"OwenEdwards","id":2245205,"avatar_url":"https://avatars.githubusercontent.com/u/2245205?v=3","gravatar_id":"","url":"https://api.github.com/users/OwenEdwards","html_url":"https://github.com/OwenEdwards","followers_url":"https://api.github.com/users/OwenEdwards/followers","following_url":"https://api.github.com/users/OwenEdwards/following{/other_user}","gists_url":"https://api.github.com/users/OwenEdwards/gists{/gist_id}","starred_url":"https://api.github.com/users/OwenEdwards/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OwenEdwards/subscriptions","organizations_url":"https://api.github.com/users/OwenEdwards/orgs","repos_url":"https://api.github.com/users/OwenEdwards/repos","events_url":"https://api.github.com/users/OwenEdwards/events{/privacy}","received_events_url":"https://api.github.com/users/OwenEdwards/received_events","type":"User","site_admin":false},"repo":{"id":23952785,"name":"video.js","full_name":"OwenEdwards/video.js","owner":{"login":"OwenEdwards","id":2245205,"avatar_url":"https://avatars.githubusercontent.com/u/2245205?v=3","gravatar_id":"","url":"https://api.github.com/users/OwenEdwards","html_url":"https://github.com/OwenEdwards","followers_url":"https://api.github.com/users/OwenEdwards/followers","following_url":"https://api.github.com/users/OwenEdwards/following{/other_user}","gists_url":"https://api.github.com/users/OwenEdwards/gists{/gist_id}","starred_url":"https://api.github.com/users/OwenEdwards/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OwenEdwards/subscriptions","organizations_url":"https://api.github.com/users/OwenEdwards/orgs","repos_url":"https://api.github.com/users/OwenEdwards/repos","events_url":"https://api.github.com/users/OwenEdwards/events{/privacy}","received_events_url":"https://api.github.com/users/OwenEdwards/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/OwenEdwards/video.js","description":"Video.js - open source HTML5 & Flash video player","fork":true,"url":"https://api.github.com/repos/OwenEdwards/video.js","forks_url":"https://api.github.com/repos/OwenEdwards/video.js/forks","keys_url":"https://api.github.com/repos/OwenEdwards/video.js/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OwenEdwards/video.js/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OwenEdwards/video.js/teams","hooks_url":"https://api.github.com/repos/OwenEdwards/video.js/hooks","issue_events_url":"https://api.github.com/repos/OwenEdwards/video.js/issues/events{/number}","events_url":"https://api.github.com/repos/OwenEdwards/video.js/events","assignees_url":"https://api.github.com/repos/OwenEdwards/video.js/assignees{/user}","branches_url":"https://api.github.com/repos/OwenEdwards/video.js/branches{/branch}","tags_url":"https://api.github.com/repos/OwenEdwards/video.js/tags","blobs_url":"https://api.github.com/repos/OwenEdwards/video.js/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OwenEdwards/video.js/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OwenEdwards/video.js/git/refs{/sha}","trees_url":"https://api.github.com/repos/OwenEdwards/video.js/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OwenEdwards/video.js/statuses/{sha}","languages_url":"https://api.github.com/repos/OwenEdwards/video.js/languages","stargazers_url":"https://api.github.com/repos/OwenEdwards/video.js/stargazers","contributors_url":"https://api.github.com/repos/OwenEdwards/video.js/contributors","subscribers_url":"https://api.github.com/repos/OwenEdwards/video.js/subscribers","subscription_url":"https://api.github.com/repos/OwenEdwards/video.js/subscription","commits_url":"https://api.github.com/repos/OwenEdwards/video.js/commits{/sha}","git_commits_url":"https://api.github.com/repos/OwenEdwards/video.js/git/commits{/sha}","comments_url":"https://api.github.com/repos/OwenEdwards/video.js/comments{/number}","issue_comment_url":"https://api.github.com/repos/OwenEdwards/video.js/issues/comments{/number}","contents_url":"https://api.github.com/repos/OwenEdwards/video.js/contents/{+path}","compare_url":"https://api.github.com/repos/OwenEdwards/video.js/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OwenEdwards/video.js/merges","archive_url":"https://api.github.com/repos/OwenEdwards/video.js/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OwenEdwards/video.js/downloads","issues_url":"https://api.github.com/repos/OwenEdwards/video.js/issues{/number}","pulls_url":"https://api.github.com/repos/OwenEdwards/video.js/pulls{/number}","milestones_url":"https://api.github.com/repos/OwenEdwards/video.js/milestones{/number}","notifications_url":"https://api.github.com/repos/OwenEdwards/video.js/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OwenEdwards/video.js/labels{/name}","releases_url":"https://api.github.com/repos/OwenEdwards/video.js/releases{/id}","deployments_url":"https://api.github.com/repos/OwenEdwards/video.js/deployments","created_at":"2014-09-12T08:26:09Z","updated_at":"2015-03-04T17:52:02Z","pushed_at":"2016-01-25T08:57:20Z","git_url":"git://github.com/OwenEdwards/video.js.git","ssh_url":"git@github.com:OwenEdwards/video.js.git","clone_url":"https://github.com/OwenEdwards/video.js.git","svn_url":"https://github.com/OwenEdwards/video.js","homepage":"www.videojs.com","size":14901,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_downloads":false,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"videojs:master","ref":"master","sha":"81caccd154d74e3688a12bd85b1439b5f5e566b3","user":{"login":"videojs","id":3287189,"avatar_url":"https://avatars.githubusercontent.com/u/3287189?v=3","gravatar_id":"","url":"https://api.github.com/users/videojs","html_url":"https://github.com/videojs","followers_url":"https://api.github.com/users/videojs/followers","following_url":"https://api.github.com/users/videojs/following{/other_user}","gists_url":"https://api.github.com/users/videojs/gists{/gist_id}","starred_url":"https://api.github.com/users/videojs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/videojs/subscriptions","organizations_url":"https://api.github.com/users/videojs/orgs","repos_url":"https://api.github.com/users/videojs/repos","events_url":"https://api.github.com/users/videojs/events{/privacy}","received_events_url":"https://api.github.com/users/videojs/received_events","type":"Organization","site_admin":false},"repo":{"id":667006,"name":"video.js","full_name":"videojs/video.js","owner":{"login":"videojs","id":3287189,"avatar_url":"https://avatars.githubusercontent.com/u/3287189?v=3","gravatar_id":"","url":"https://api.github.com/users/videojs","html_url":"https://github.com/videojs","followers_url":"https://api.github.com/users/videojs/followers","following_url":"https://api.github.com/users/videojs/following{/other_user}","gists_url":"https://api.github.com/users/videojs/gists{/gist_id}","starred_url":"https://api.github.com/users/videojs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/videojs/subscriptions","organizations_url":"https://api.github.com/users/videojs/orgs","repos_url":"https://api.github.com/users/videojs/repos","events_url":"https://api.github.com/users/videojs/events{/privacy}","received_events_url":"https://api.github.com/users/videojs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/videojs/video.js","description":"Video.js - open source HTML5 & Flash video player","fork":false,"url":"https://api.github.com/repos/videojs/video.js","forks_url":"https://api.github.com/repos/videojs/video.js/forks","keys_url":"https://api.github.com/repos/videojs/video.js/keys{/key_id}","collaborators_url":"https://api.github.com/repos/videojs/video.js/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/videojs/video.js/teams","hooks_url":"https://api.github.com/repos/videojs/video.js/hooks","issue_events_url":"https://api.github.com/repos/videojs/video.js/issues/events{/number}","events_url":"https://api.github.com/repos/videojs/video.js/events","assignees_url":"https://api.github.com/repos/videojs/video.js/assignees{/user}","branches_url":"https://api.github.com/repos/videojs/video.js/branches{/branch}","tags_url":"https://api.github.com/repos/videojs/video.js/tags","blobs_url":"https://api.github.com/repos/videojs/video.js/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/videojs/video.js/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/videojs/video.js/git/refs{/sha}","trees_url":"https://api.github.com/repos/videojs/video.js/git/trees{/sha}","statuses_url":"https://api.github.com/repos/videojs/video.js/statuses/{sha}","languages_url":"https://api.github.com/repos/videojs/video.js/languages","stargazers_url":"https://api.github.com/repos/videojs/video.js/stargazers","contributors_url":"https://api.github.com/repos/videojs/video.js/contributors","subscribers_url":"https://api.github.com/repos/videojs/video.js/subscribers","subscription_url":"https://api.github.com/repos/videojs/video.js/subscription","commits_url":"https://api.github.com/repos/videojs/video.js/commits{/sha}","git_commits_url":"https://api.github.com/repos/videojs/video.js/git/commits{/sha}","comments_url":"https://api.github.com/repos/videojs/video.js/comments{/number}","issue_comment_url":"https://api.github.com/repos/videojs/video.js/issues/comments{/number}","contents_url":"https://api.github.com/repos/videojs/video.js/contents/{+path}","compare_url":"https://api.github.com/repos/videojs/video.js/compare/{base}...{head}","merges_url":"https://api.github.com/repos/videojs/video.js/merges","archive_url":"https://api.github.com/repos/videojs/video.js/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/videojs/video.js/downloads","issues_url":"https://api.github.com/repos/videojs/video.js/issues{/number}","pulls_url":"https://api.github.com/repos/videojs/video.js/pulls{/number}","milestones_url":"https://api.github.com/repos/videojs/video.js/milestones{/number}","notifications_url":"https://api.github.com/repos/videojs/video.js/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/videojs/video.js/labels{/name}","releases_url":"https://api.github.com/repos/videojs/video.js/releases{/id}","deployments_url":"https://api.github.com/repos/videojs/video.js/deployments","created_at":"2010-05-14T18:45:10Z","updated_at":"2016-01-25T19:42:30Z","pushed_at":"2016-01-25T09:09:01Z","git_url":"git://github.com/videojs/video.js.git","ssh_url":"git@github.com:videojs/video.js.git","clone_url":"https://github.com/videojs/video.js.git","svn_url":"https://github.com/videojs/video.js","homepage":"www.videojs.com","size":84708,"stargazers_count":11468,"watchers_count":11468,"language":"JavaScript","has_issues":true,"has_downloads":false,"has_wiki":true,"has_pages":true,"forks_count":3321,"mirror_url":null,"open_issues_count":262,"forks":3321,"open_issues":262,"watchers":11468,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/videojs/video.js/pulls/3032"},"html":{"href":"https://github.com/videojs/video.js/pull/3032"},"issue":{"href":"https://api.github.com/repos/videojs/video.js/issues/3032"},"comments":{"href":"https://api.github.com/repos/videojs/video.js/issues/3032/comments"},"review_comments":{"href":"https://api.github.com/repos/videojs/video.js/pulls/3032/comments"},"review_comment":{"href":"https://api.github.com/repos/videojs/video.js/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/videojs/video.js/pulls/3032/commits"},"statuses":{"href":"https://api.github.com/repos/videojs/video.js/statuses/c0d540cf51eb0d6f781fc5e617e2d1b54ed4cab2"}}}}