{"action":"created","comment":{"url":"https://api.github.com/repos/Polymer/polymer-linter/pulls/comments/82915495","pull_request_review_id":3787585,"id":82915495,"diff_hunk":"@@ -0,0 +1,140 @@\n+/**\n+ * @license\n+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.\n+ * This code may only be used under the BSD style license found at\n+ * http://polymer.github.io/LICENSE.txt\n+ * The complete set of authors may be found at\n+ * http://polymer.github.io/AUTHORS.txt\n+ * The complete set of contributors may be found at\n+ * http://polymer.github.io/CONTRIBUTORS.txt\n+ * Code distributed by Google as part of the polymer project is also\n+ * subject to an additional IP rights grant found at\n+ * http://polymer.github.io/PATENTS.txt\n+ */\n+// import {PolymerElement} from 'polymer-analyzer/lib/polymer/polymer-element';\n+import * as dom5 from 'dom5';\n+import * as parse5 from 'parse5';\n+import {ParsedHtmlDocument} from 'polymer-analyzer/lib/html/html-document';\n+import {Document} from 'polymer-analyzer/lib/model/model';\n+import {Severity, Warning} from 'polymer-analyzer/lib/warning/warning';\n+\n+import * as expressions from '../expressions';\n+import * as matchers from '../matchers';\n+import {Rule} from '../rule';\n+\n+export const a11yAttributes: Set<string> = new Set([\n+  'aria-activedescendant',\n+  'aria-atomic',\n+  'aria-autocomplete',\n+  'aria-busy',\n+  'aria-checked',\n+  'aria-controls',\n+  'aria-describedby',\n+  'aria-disabled',\n+  'aria-dropeffect',\n+  'aria-expanded',\n+  'aria-flowto',\n+  'aria-grabbed',\n+  'aria-haspopup',\n+  'aria-hidden',\n+  'aria-invalid',\n+  'aria-label',\n+  'aria-labelledby',\n+  'aria-level',\n+  'aria-live',\n+  'aria-multiline',\n+  'aria-multiselectable',\n+  'aria-orientation',\n+  'aria-owns',\n+  'aria-posinset',\n+  'aria-pressed',\n+  'aria-readonly',\n+  'aria-relevant',\n+  'aria-required',\n+  'aria-selected',\n+  'aria-setsize',\n+  'aria-sort',\n+  'aria-valuemax',\n+  'aria-valuemin',\n+  'aria-valuenow',\n+  'aria-valuetext',\n+  'role'\n+]);\n+\n+export const nativeAttributes: Set<string> = new Set([\n+  'accesskey',\n+  'class',\n+  'contenteditable',\n+  'contextmenu',\n+  'dir',\n+  'draggable',\n+  'dropzone',\n+  'hidden',\n+  'href',\n+  'id',\n+  'itemprop',\n+  'lang',\n+  'spellcheck',\n+  'style',\n+  'style',\n+  'tabindex',\n+  'title'\n+]);\n+\n+const expressionParser = new expressions.ExpressionParser();\n+\n+export class NativeAttributeBinding implements Rule {\n+  public async check(document: Document): Promise<Warning[]> {\n+    const warnings: Warning[] = [];\n+    const templates = dom5.queryAll(\n+        document.parsedDocument.ast,\n+        dom5.predicates.OR(\n+            matchers.isDomBindTemplate, matchers.isDomModuleTemplate));\n+\n+    for (const template of templates) {\n+      for (const element of dom5.queryAll(\n+               parse5.treeAdapters.default.getTemplateContent(template),\n+               (e) => true)) {\n+        for (const attr of element.attrs) {\n+          if (this._isBindingExpression(attr.value) &&\n+              !this._canAttributeUseNativeBinding(element, attr)) {\n+            const parsedHtml = document.parsedDocument;\n+            if (!(parsedHtml instanceof ParsedHtmlDocument)) {\n+              continue;\n+            }\n+            warnings.push({\n+              code: 'native-attribute-binding',\n+              message: `The expression ${attr.value} bound to attribute ` +\n+                  `'${attr.name}' should use $= instead of =`,\n+              severity: Severity.ERROR,\n+              sourceRange:\n+                  parsedHtml.sourceRangeForAttribute(element, attr.name)!\n+            });\n+          }\n+        }\n+      }\n+    }\n+    return warnings;\n+  }\n+\n+  private _canAttributeUseNativeBinding(\n+      element: parse5.ASTNode,\n+      attr: parse5.ASTAttribute): boolean {\n+    const name: string = attr.name.toLowerCase();\n+    if (name === 'for' && dom5.predicates.hasTagName('label')(element)) {\n+      return false;\n+    }\n+    if (nativeAttributes.has(name)) {\n+      return false;\n+    }\n+    if (name.indexOf('data-') === 0 && attr.name[name.length - 1] !== '$') {\n+      return false;\n+    }\n+    return true;\n+  }\n+\n+  private _isBindingExpression(expression: string): boolean {\n+    const bindingMatch = expressionParser.extractBindingExpression(expression);\n+    return !!bindingMatch || false;","path":"src/rules/native-attribute-binding.ts","position":138,"original_position":138,"commit_id":"e45c72a40540d84e60d7de589ebe73fcd33e7810","original_commit_id":"0a4211ddf13a95588cabdcab2a4821a7eadb6737","user":{"login":"rictic","id":1659,"avatar_url":"https://avatars.githubusercontent.com/u/1659?v=3","gravatar_id":"","url":"https://api.github.com/users/rictic","html_url":"https://github.com/rictic","followers_url":"https://api.github.com/users/rictic/followers","following_url":"https://api.github.com/users/rictic/following{/other_user}","gists_url":"https://api.github.com/users/rictic/gists{/gist_id}","starred_url":"https://api.github.com/users/rictic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rictic/subscriptions","organizations_url":"https://api.github.com/users/rictic/orgs","repos_url":"https://api.github.com/users/rictic/repos","events_url":"https://api.github.com/users/rictic/events{/privacy}","received_events_url":"https://api.github.com/users/rictic/received_events","type":"User","site_admin":false},"body":"AFAIK `!!foo || false` is equal to `!!foo` for all values of `foo`.","created_at":"2016-10-12T00:12:35Z","updated_at":"2016-10-12T00:23:04Z","html_url":"https://github.com/Polymer/polymer-linter/pull/1#discussion_r82915495","pull_request_url":"https://api.github.com/repos/Polymer/polymer-linter/pulls/1","_links":{"self":{"href":"https://api.github.com/repos/Polymer/polymer-linter/pulls/comments/82915495"},"html":{"href":"https://github.com/Polymer/polymer-linter/pull/1#discussion_r82915495"},"pull_request":{"href":"https://api.github.com/repos/Polymer/polymer-linter/pulls/1"}}},"pull_request":{"url":"https://api.github.com/repos/Polymer/polymer-linter/pulls/1","id":88179680,"html_url":"https://github.com/Polymer/polymer-linter/pull/1","diff_url":"https://github.com/Polymer/polymer-linter/pull/1.diff","patch_url":"https://github.com/Polymer/polymer-linter/pull/1.patch","issue_url":"https://api.github.com/repos/Polymer/polymer-linter/issues/1","number":1,"state":"open","locked":false,"title":"Initial commit of Analyzer-based Linter.  Ported over first linter 'unbalanced-delimiters'","user":{"login":"usergenic","id":578,"avatar_url":"https://avatars.githubusercontent.com/u/578?v=3","gravatar_id":"","url":"https://api.github.com/users/usergenic","html_url":"https://github.com/usergenic","followers_url":"https://api.github.com/users/usergenic/followers","following_url":"https://api.github.com/users/usergenic/following{/other_user}","gists_url":"https://api.github.com/users/usergenic/gists{/gist_id}","starred_url":"https://api.github.com/users/usergenic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/usergenic/subscriptions","organizations_url":"https://api.github.com/users/usergenic/orgs","repos_url":"https://api.github.com/users/usergenic/repos","events_url":"https://api.github.com/users/usergenic/events{/privacy}","received_events_url":"https://api.github.com/users/usergenic/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-10-06T00:11:05Z","updated_at":"2016-10-12T00:23:04Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c0d1c2ca7cd7ac8da097f1e1f00c2a3ae6616f71","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/Polymer/polymer-linter/pulls/1/commits","review_comments_url":"https://api.github.com/repos/Polymer/polymer-linter/pulls/1/comments","review_comment_url":"https://api.github.com/repos/Polymer/polymer-linter/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Polymer/polymer-linter/issues/1/comments","statuses_url":"https://api.github.com/repos/Polymer/polymer-linter/statuses/e45c72a40540d84e60d7de589ebe73fcd33e7810","head":{"label":"Polymer:brand-new-linter","ref":"brand-new-linter","sha":"e45c72a40540d84e60d7de589ebe73fcd33e7810","user":{"login":"Polymer","id":2159051,"avatar_url":"https://avatars.githubusercontent.com/u/2159051?v=3","gravatar_id":"","url":"https://api.github.com/users/Polymer","html_url":"https://github.com/Polymer","followers_url":"https://api.github.com/users/Polymer/followers","following_url":"https://api.github.com/users/Polymer/following{/other_user}","gists_url":"https://api.github.com/users/Polymer/gists{/gist_id}","starred_url":"https://api.github.com/users/Polymer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Polymer/subscriptions","organizations_url":"https://api.github.com/users/Polymer/orgs","repos_url":"https://api.github.com/users/Polymer/repos","events_url":"https://api.github.com/users/Polymer/events{/privacy}","received_events_url":"https://api.github.com/users/Polymer/received_events","type":"Organization","site_admin":false},"repo":{"id":69921209,"name":"polymer-linter","full_name":"Polymer/polymer-linter","owner":{"login":"Polymer","id":2159051,"avatar_url":"https://avatars.githubusercontent.com/u/2159051?v=3","gravatar_id":"","url":"https://api.github.com/users/Polymer","html_url":"https://github.com/Polymer","followers_url":"https://api.github.com/users/Polymer/followers","following_url":"https://api.github.com/users/Polymer/following{/other_user}","gists_url":"https://api.github.com/users/Polymer/gists{/gist_id}","starred_url":"https://api.github.com/users/Polymer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Polymer/subscriptions","organizations_url":"https://api.github.com/users/Polymer/orgs","repos_url":"https://api.github.com/users/Polymer/repos","events_url":"https://api.github.com/users/Polymer/events{/privacy}","received_events_url":"https://api.github.com/users/Polymer/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Polymer/polymer-linter","description":"Lint Polymer!","fork":false,"url":"https://api.github.com/repos/Polymer/polymer-linter","forks_url":"https://api.github.com/repos/Polymer/polymer-linter/forks","keys_url":"https://api.github.com/repos/Polymer/polymer-linter/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Polymer/polymer-linter/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Polymer/polymer-linter/teams","hooks_url":"https://api.github.com/repos/Polymer/polymer-linter/hooks","issue_events_url":"https://api.github.com/repos/Polymer/polymer-linter/issues/events{/number}","events_url":"https://api.github.com/repos/Polymer/polymer-linter/events","assignees_url":"https://api.github.com/repos/Polymer/polymer-linter/assignees{/user}","branches_url":"https://api.github.com/repos/Polymer/polymer-linter/branches{/branch}","tags_url":"https://api.github.com/repos/Polymer/polymer-linter/tags","blobs_url":"https://api.github.com/repos/Polymer/polymer-linter/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Polymer/polymer-linter/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Polymer/polymer-linter/git/refs{/sha}","trees_url":"https://api.github.com/repos/Polymer/polymer-linter/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Polymer/polymer-linter/statuses/{sha}","languages_url":"https://api.github.com/repos/Polymer/polymer-linter/languages","stargazers_url":"https://api.github.com/repos/Polymer/polymer-linter/stargazers","contributors_url":"https://api.github.com/repos/Polymer/polymer-linter/contributors","subscribers_url":"https://api.github.com/repos/Polymer/polymer-linter/subscribers","subscription_url":"https://api.github.com/repos/Polymer/polymer-linter/subscription","commits_url":"https://api.github.com/repos/Polymer/polymer-linter/commits{/sha}","git_commits_url":"https://api.github.com/repos/Polymer/polymer-linter/git/commits{/sha}","comments_url":"https://api.github.com/repos/Polymer/polymer-linter/comments{/number}","issue_comment_url":"https://api.github.com/repos/Polymer/polymer-linter/issues/comments{/number}","contents_url":"https://api.github.com/repos/Polymer/polymer-linter/contents/{+path}","compare_url":"https://api.github.com/repos/Polymer/polymer-linter/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Polymer/polymer-linter/merges","archive_url":"https://api.github.com/repos/Polymer/polymer-linter/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Polymer/polymer-linter/downloads","issues_url":"https://api.github.com/repos/Polymer/polymer-linter/issues{/number}","pulls_url":"https://api.github.com/repos/Polymer/polymer-linter/pulls{/number}","milestones_url":"https://api.github.com/repos/Polymer/polymer-linter/milestones{/number}","notifications_url":"https://api.github.com/repos/Polymer/polymer-linter/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Polymer/polymer-linter/labels{/name}","releases_url":"https://api.github.com/repos/Polymer/polymer-linter/releases{/id}","deployments_url":"https://api.github.com/repos/Polymer/polymer-linter/deployments","created_at":"2016-10-04T00:04:41Z","updated_at":"2016-10-06T00:12:38Z","pushed_at":"2016-10-12T00:13:22Z","git_url":"git://github.com/Polymer/polymer-linter.git","ssh_url":"git@github.com:Polymer/polymer-linter.git","clone_url":"https://github.com/Polymer/polymer-linter.git","svn_url":"https://github.com/Polymer/polymer-linter","homepage":null,"size":7,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":2,"forks":1,"open_issues":2,"watchers":0,"default_branch":"master"}},"base":{"label":"Polymer:master","ref":"master","sha":"1c46ba58053aa3fcb820422f1d409082c56698b0","user":{"login":"Polymer","id":2159051,"avatar_url":"https://avatars.githubusercontent.com/u/2159051?v=3","gravatar_id":"","url":"https://api.github.com/users/Polymer","html_url":"https://github.com/Polymer","followers_url":"https://api.github.com/users/Polymer/followers","following_url":"https://api.github.com/users/Polymer/following{/other_user}","gists_url":"https://api.github.com/users/Polymer/gists{/gist_id}","starred_url":"https://api.github.com/users/Polymer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Polymer/subscriptions","organizations_url":"https://api.github.com/users/Polymer/orgs","repos_url":"https://api.github.com/users/Polymer/repos","events_url":"https://api.github.com/users/Polymer/events{/privacy}","received_events_url":"https://api.github.com/users/Polymer/received_events","type":"Organization","site_admin":false},"repo":{"id":69921209,"name":"polymer-linter","full_name":"Polymer/polymer-linter","owner":{"login":"Polymer","id":2159051,"avatar_url":"https://avatars.githubusercontent.com/u/2159051?v=3","gravatar_id":"","url":"https://api.github.com/users/Polymer","html_url":"https://github.com/Polymer","followers_url":"https://api.github.com/users/Polymer/followers","following_url":"https://api.github.com/users/Polymer/following{/other_user}","gists_url":"https://api.github.com/users/Polymer/gists{/gist_id}","starred_url":"https://api.github.com/users/Polymer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Polymer/subscriptions","organizations_url":"https://api.github.com/users/Polymer/orgs","repos_url":"https://api.github.com/users/Polymer/repos","events_url":"https://api.github.com/users/Polymer/events{/privacy}","received_events_url":"https://api.github.com/users/Polymer/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Polymer/polymer-linter","description":"Lint Polymer!","fork":false,"url":"https://api.github.com/repos/Polymer/polymer-linter","forks_url":"https://api.github.com/repos/Polymer/polymer-linter/forks","keys_url":"https://api.github.com/repos/Polymer/polymer-linter/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Polymer/polymer-linter/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Polymer/polymer-linter/teams","hooks_url":"https://api.github.com/repos/Polymer/polymer-linter/hooks","issue_events_url":"https://api.github.com/repos/Polymer/polymer-linter/issues/events{/number}","events_url":"https://api.github.com/repos/Polymer/polymer-linter/events","assignees_url":"https://api.github.com/repos/Polymer/polymer-linter/assignees{/user}","branches_url":"https://api.github.com/repos/Polymer/polymer-linter/branches{/branch}","tags_url":"https://api.github.com/repos/Polymer/polymer-linter/tags","blobs_url":"https://api.github.com/repos/Polymer/polymer-linter/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Polymer/polymer-linter/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Polymer/polymer-linter/git/refs{/sha}","trees_url":"https://api.github.com/repos/Polymer/polymer-linter/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Polymer/polymer-linter/statuses/{sha}","languages_url":"https://api.github.com/repos/Polymer/polymer-linter/languages","stargazers_url":"https://api.github.com/repos/Polymer/polymer-linter/stargazers","contributors_url":"https://api.github.com/repos/Polymer/polymer-linter/contributors","subscribers_url":"https://api.github.com/repos/Polymer/polymer-linter/subscribers","subscription_url":"https://api.github.com/repos/Polymer/polymer-linter/subscription","commits_url":"https://api.github.com/repos/Polymer/polymer-linter/commits{/sha}","git_commits_url":"https://api.github.com/repos/Polymer/polymer-linter/git/commits{/sha}","comments_url":"https://api.github.com/repos/Polymer/polymer-linter/comments{/number}","issue_comment_url":"https://api.github.com/repos/Polymer/polymer-linter/issues/comments{/number}","contents_url":"https://api.github.com/repos/Polymer/polymer-linter/contents/{+path}","compare_url":"https://api.github.com/repos/Polymer/polymer-linter/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Polymer/polymer-linter/merges","archive_url":"https://api.github.com/repos/Polymer/polymer-linter/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Polymer/polymer-linter/downloads","issues_url":"https://api.github.com/repos/Polymer/polymer-linter/issues{/number}","pulls_url":"https://api.github.com/repos/Polymer/polymer-linter/pulls{/number}","milestones_url":"https://api.github.com/repos/Polymer/polymer-linter/milestones{/number}","notifications_url":"https://api.github.com/repos/Polymer/polymer-linter/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Polymer/polymer-linter/labels{/name}","releases_url":"https://api.github.com/repos/Polymer/polymer-linter/releases{/id}","deployments_url":"https://api.github.com/repos/Polymer/polymer-linter/deployments","created_at":"2016-10-04T00:04:41Z","updated_at":"2016-10-06T00:12:38Z","pushed_at":"2016-10-12T00:13:22Z","git_url":"git://github.com/Polymer/polymer-linter.git","ssh_url":"git@github.com:Polymer/polymer-linter.git","clone_url":"https://github.com/Polymer/polymer-linter.git","svn_url":"https://github.com/Polymer/polymer-linter","homepage":null,"size":7,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":2,"forks":1,"open_issues":2,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Polymer/polymer-linter/pulls/1"},"html":{"href":"https://github.com/Polymer/polymer-linter/pull/1"},"issue":{"href":"https://api.github.com/repos/Polymer/polymer-linter/issues/1"},"comments":{"href":"https://api.github.com/repos/Polymer/polymer-linter/issues/1/comments"},"review_comments":{"href":"https://api.github.com/repos/Polymer/polymer-linter/pulls/1/comments"},"review_comment":{"href":"https://api.github.com/repos/Polymer/polymer-linter/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Polymer/polymer-linter/pulls/1/commits"},"statuses":{"href":"https://api.github.com/repos/Polymer/polymer-linter/statuses/e45c72a40540d84e60d7de589ebe73fcd33e7810"}}}}
{"actor":{"display_login":"rictic"}}