{"action":"created","comment":{"url":"https://api.github.com/repos/Polymer/polytool/pulls/comments/60467182","id":60467182,"diff_hunk":"@@ -0,0 +1,237 @@\n+/**\n+ * @license\n+ * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.\n+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\n+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\n+ * The complete set of contributors may be found at 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 http://polymer.github.io/PATENTS.txt\n+ */\n+\n+import * as dom5 from 'dom5';\n+import * as path from 'path';\n+import {Transform} from 'stream';\n+import File = require('vinyl');\n+\n+const pred = dom5.predicates;\n+\n+const extensionsForType = {\n+  'text/ecmascript-6': 'js',\n+  'application/javascript': 'js',\n+  'text/javascript': 'js',\n+  'application/x-typescript': 'ts',\n+  'text/x-typescript': 'ts',\n+};\n+\n+/**\n+ * Splits and rejoins inline scripts and styles from HTML files.\n+ *\n+ * Use `HtmlProject.prototype.split` and `HtmlProject.prototype.rejoin` to\n+ * surround processing steps that operate on the extracted resources.\n+ * HtmlProject works well with gulp-if to process files based on filename.\n+ */\n+export class HtmlProject {\n+\n+  _splitFiles : Map<string, SplitFile> = new Map();\n+  _parts : Map<string, SplitFile> = new Map();\n+  split = new Splitter(this);\n+  rejoin = new Rejoiner(this);\n+\n+  isSplitFile(parentPath: string): boolean {\n+    return this._splitFiles.has(parentPath);\n+  }\n+\n+  getSplitFile(parentPath: string): SplitFile {\n+    let splitFile = this._splitFiles.get(parentPath);\n+    if (!splitFile) {\n+      splitFile = new SplitFile(parentPath);\n+      this._splitFiles.set(parentPath, splitFile);\n+    }\n+    return splitFile;\n+  }\n+\n+  addSplitPath(parentPath: string, childPath: string): void {\n+    let splitFile = this.getSplitFile(parentPath);\n+    splitFile.addPartPath(childPath);\n+    this._parts.set(childPath, splitFile);\n+  }\n+\n+  getParentFile(childPath: string): SplitFile {\n+    return this._parts.get(childPath);\n+  }\n+\n+}\n+\n+\n+/**\n+ * Represents a file that is split into multiple files.\n+ */\n+class SplitFile {\n+  path : string;\n+  parts : Map<string, string> = new Map();\n+  outstandingPartCount = 0;\n+  vinylFile : File = null;\n+\n+  constructor(path: string) {\n+    this.path = path;\n+  }\n+\n+  addPartPath(path: string): void {\n+    this.parts.set(path, null);\n+    this.outstandingPartCount++;\n+  }\n+\n+  setPartContent(path: string, content: string): void {\n+    console.assert(this.parts.get(path) === null);\n+    console.assert(this.outstandingPartCount > 0);\n+    this.parts.set(path, content);\n+    this.outstandingPartCount--;\n+  }\n+\n+  get isComplete(): boolean {\n+    return this.outstandingPartCount === 0 && this.vinylFile != null;\n+  }\n+}\n+\n+/**\n+ * Splits HTML files, extracting scripts and styles into separate `File`s.\n+ */\n+class Splitter extends Transform {\n+\n+  static isInlineScript = pred.AND(\n+    pred.hasTagName('script'),\n+    pred.NOT(pred.hasAttr('src'))\n+  );\n+\n+  _project : HtmlProject;\n+\n+  constructor(project) {\n+    super({objectMode: true});\n+    this._project = project;\n+  }\n+\n+  _transform(file: File, encoding: string, callback: (error?, data?) => void): void {\n+    if (file.contents && file.path.endsWith('.html')) {\n+      try {\n+        let contents = file.contents.toString();\n+        let doc = dom5.parse(contents);\n+        let body = dom5.query(doc, pred.hasTagName('body'));\n+        let head = dom5.query(doc, pred.hasTagName('head'));\n+        let scriptTags = dom5.queryAll(doc, Splitter.isInlineScript);\n+        let styleTags = dom5.queryAll(doc, pred.hasTagName('style'));\n+\n+        let scripts = [];\n+        let styles = [];\n+\n+        for (let i = 0; i < scriptTags.length; i++) {\n+          let scriptTag = scriptTags[i];\n+          let source = dom5.getTextContent(scriptTag);\n+          // let typeAtribute = dom5.getAttribute(scriptTag, 'type');","path":"src/build/html-project.ts","position":129,"original_position":129,"commit_id":"a0a00ed5f6a55c6320ed3787f51fe7e253e66fa4","original_commit_id":"a0a00ed5f6a55c6320ed3787f51fe7e253e66fa4","user":{"login":"garlicnation","id":1105965,"avatar_url":"https://avatars.githubusercontent.com/u/1105965?v=3","gravatar_id":"","url":"https://api.github.com/users/garlicnation","html_url":"https://github.com/garlicnation","followers_url":"https://api.github.com/users/garlicnation/followers","following_url":"https://api.github.com/users/garlicnation/following{/other_user}","gists_url":"https://api.github.com/users/garlicnation/gists{/gist_id}","starred_url":"https://api.github.com/users/garlicnation/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/garlicnation/subscriptions","organizations_url":"https://api.github.com/users/garlicnation/orgs","repos_url":"https://api.github.com/users/garlicnation/repos","events_url":"https://api.github.com/users/garlicnation/events{/privacy}","received_events_url":"https://api.github.com/users/garlicnation/received_events","type":"User","site_admin":false},"body":"remove commented code","created_at":"2016-04-20T18:55:53Z","updated_at":"2016-04-20T18:55:53Z","html_url":"https://github.com/Polymer/polytool/pull/14#discussion_r60467182","pull_request_url":"https://api.github.com/repos/Polymer/polytool/pulls/14","_links":{"self":{"href":"https://api.github.com/repos/Polymer/polytool/pulls/comments/60467182"},"html":{"href":"https://github.com/Polymer/polytool/pull/14#discussion_r60467182"},"pull_request":{"href":"https://api.github.com/repos/Polymer/polytool/pulls/14"}}},"pull_request":{"url":"https://api.github.com/repos/Polymer/polytool/pulls/14","id":66416330,"html_url":"https://github.com/Polymer/polytool/pull/14","diff_url":"https://github.com/Polymer/polytool/pull/14.diff","patch_url":"https://github.com/Polymer/polytool/pull/14.patch","issue_url":"https://api.github.com/repos/Polymer/polytool/issues/14","number":14,"state":"open","locked":false,"title":"Initial build pipeline","user":{"login":"justinfagnani","id":522948,"avatar_url":"https://avatars.githubusercontent.com/u/522948?v=3","gravatar_id":"","url":"https://api.github.com/users/justinfagnani","html_url":"https://github.com/justinfagnani","followers_url":"https://api.github.com/users/justinfagnani/followers","following_url":"https://api.github.com/users/justinfagnani/following{/other_user}","gists_url":"https://api.github.com/users/justinfagnani/gists{/gist_id}","starred_url":"https://api.github.com/users/justinfagnani/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/justinfagnani/subscriptions","organizations_url":"https://api.github.com/users/justinfagnani/orgs","repos_url":"https://api.github.com/users/justinfagnani/repos","events_url":"https://api.github.com/users/justinfagnani/events{/privacy}","received_events_url":"https://api.github.com/users/justinfagnani/received_events","type":"User","site_admin":false},"body":"This adds a generic build pipeline to polytool.\r\n\r\n * Builds can be extended by the project gulpfile by exporting a `transforms` property.\r\n * HTML files are split similar to crisper, but style should also be split (WIP), and they are recombined by default. script and style tags are not moved like in cripser.\r\n * Vulcanize reads files from the gulp stream unlike default gulp-vulcanize. This means that transformed files are passed through vulcanize. I'm uncertain how well that actually works with normal gulp-vulcanize, as it might depend on the ordering and completeness of other transform steps and whether they've written to disk yet.\r\n* entrypoints and source globs can be specified, but there's only support for a single entrypoint right now. This needs to be expanded to multiple entrypoints, and sharding.\r\n\r\nFuture work:\r\n  * ES6 module support: transform `<script type=module>` to an HTML import that loads an HTML file with non-module script tag.\r\n  * polystyle support: auto-wrap external CSS in a dom-module\r\n  * service worker / manifest type things\r\n  * optionally run packages through the pipeline. Right now there's an escape hatch in the loader that vulcanize uses to read from disk, but piping packages through the compiler might be preferable, especially with npm and packages that have esnext fields.\r\n\r\nThe code is a bit of a mess, but I wanted to get this up for interested parties.\r\n\r\n@robdodson @addyosmani @garlicnation","created_at":"2016-04-14T01:18:41Z","updated_at":"2016-04-20T18:55:53Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9b1eed6b4441bb71a88a09c2c4069c4ef0b80ef7","assignee":{"login":"garlicnation","id":1105965,"avatar_url":"https://avatars.githubusercontent.com/u/1105965?v=3","gravatar_id":"","url":"https://api.github.com/users/garlicnation","html_url":"https://github.com/garlicnation","followers_url":"https://api.github.com/users/garlicnation/followers","following_url":"https://api.github.com/users/garlicnation/following{/other_user}","gists_url":"https://api.github.com/users/garlicnation/gists{/gist_id}","starred_url":"https://api.github.com/users/garlicnation/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/garlicnation/subscriptions","organizations_url":"https://api.github.com/users/garlicnation/orgs","repos_url":"https://api.github.com/users/garlicnation/repos","events_url":"https://api.github.com/users/garlicnation/events{/privacy}","received_events_url":"https://api.github.com/users/garlicnation/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/Polymer/polytool/pulls/14/commits","review_comments_url":"https://api.github.com/repos/Polymer/polytool/pulls/14/comments","review_comment_url":"https://api.github.com/repos/Polymer/polytool/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Polymer/polytool/issues/14/comments","statuses_url":"https://api.github.com/repos/Polymer/polytool/statuses/a0a00ed5f6a55c6320ed3787f51fe7e253e66fa4","head":{"label":"Polymer:build","ref":"build","sha":"a0a00ed5f6a55c6320ed3787f51fe7e253e66fa4","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":51951003,"name":"polytool","full_name":"Polymer/polytool","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/polytool","description":"A command-line tool for Polymer projects","fork":false,"url":"https://api.github.com/repos/Polymer/polytool","forks_url":"https://api.github.com/repos/Polymer/polytool/forks","keys_url":"https://api.github.com/repos/Polymer/polytool/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Polymer/polytool/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Polymer/polytool/teams","hooks_url":"https://api.github.com/repos/Polymer/polytool/hooks","issue_events_url":"https://api.github.com/repos/Polymer/polytool/issues/events{/number}","events_url":"https://api.github.com/repos/Polymer/polytool/events","assignees_url":"https://api.github.com/repos/Polymer/polytool/assignees{/user}","branches_url":"https://api.github.com/repos/Polymer/polytool/branches{/branch}","tags_url":"https://api.github.com/repos/Polymer/polytool/tags","blobs_url":"https://api.github.com/repos/Polymer/polytool/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Polymer/polytool/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Polymer/polytool/git/refs{/sha}","trees_url":"https://api.github.com/repos/Polymer/polytool/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Polymer/polytool/statuses/{sha}","languages_url":"https://api.github.com/repos/Polymer/polytool/languages","stargazers_url":"https://api.github.com/repos/Polymer/polytool/stargazers","contributors_url":"https://api.github.com/repos/Polymer/polytool/contributors","subscribers_url":"https://api.github.com/repos/Polymer/polytool/subscribers","subscription_url":"https://api.github.com/repos/Polymer/polytool/subscription","commits_url":"https://api.github.com/repos/Polymer/polytool/commits{/sha}","git_commits_url":"https://api.github.com/repos/Polymer/polytool/git/commits{/sha}","comments_url":"https://api.github.com/repos/Polymer/polytool/comments{/number}","issue_comment_url":"https://api.github.com/repos/Polymer/polytool/issues/comments{/number}","contents_url":"https://api.github.com/repos/Polymer/polytool/contents/{+path}","compare_url":"https://api.github.com/repos/Polymer/polytool/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Polymer/polytool/merges","archive_url":"https://api.github.com/repos/Polymer/polytool/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Polymer/polytool/downloads","issues_url":"https://api.github.com/repos/Polymer/polytool/issues{/number}","pulls_url":"https://api.github.com/repos/Polymer/polytool/pulls{/number}","milestones_url":"https://api.github.com/repos/Polymer/polytool/milestones{/number}","notifications_url":"https://api.github.com/repos/Polymer/polytool/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Polymer/polytool/labels{/name}","releases_url":"https://api.github.com/repos/Polymer/polytool/releases{/id}","deployments_url":"https://api.github.com/repos/Polymer/polytool/deployments","created_at":"2016-02-17T19:57:15Z","updated_at":"2016-04-20T17:32:33Z","pushed_at":"2016-04-19T23:47:36Z","git_url":"git://github.com/Polymer/polytool.git","ssh_url":"git@github.com:Polymer/polytool.git","clone_url":"https://github.com/Polymer/polytool.git","svn_url":"https://github.com/Polymer/polytool","homepage":null,"size":25,"stargazers_count":6,"watchers_count":6,"language":"TypeScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":9,"forks":4,"open_issues":9,"watchers":6,"default_branch":"master"}},"base":{"label":"Polymer:master","ref":"master","sha":"f01affcf9648109b07deffcc1e8d551a4297bf72","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":51951003,"name":"polytool","full_name":"Polymer/polytool","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/polytool","description":"A command-line tool for Polymer projects","fork":false,"url":"https://api.github.com/repos/Polymer/polytool","forks_url":"https://api.github.com/repos/Polymer/polytool/forks","keys_url":"https://api.github.com/repos/Polymer/polytool/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Polymer/polytool/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Polymer/polytool/teams","hooks_url":"https://api.github.com/repos/Polymer/polytool/hooks","issue_events_url":"https://api.github.com/repos/Polymer/polytool/issues/events{/number}","events_url":"https://api.github.com/repos/Polymer/polytool/events","assignees_url":"https://api.github.com/repos/Polymer/polytool/assignees{/user}","branches_url":"https://api.github.com/repos/Polymer/polytool/branches{/branch}","tags_url":"https://api.github.com/repos/Polymer/polytool/tags","blobs_url":"https://api.github.com/repos/Polymer/polytool/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Polymer/polytool/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Polymer/polytool/git/refs{/sha}","trees_url":"https://api.github.com/repos/Polymer/polytool/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Polymer/polytool/statuses/{sha}","languages_url":"https://api.github.com/repos/Polymer/polytool/languages","stargazers_url":"https://api.github.com/repos/Polymer/polytool/stargazers","contributors_url":"https://api.github.com/repos/Polymer/polytool/contributors","subscribers_url":"https://api.github.com/repos/Polymer/polytool/subscribers","subscription_url":"https://api.github.com/repos/Polymer/polytool/subscription","commits_url":"https://api.github.com/repos/Polymer/polytool/commits{/sha}","git_commits_url":"https://api.github.com/repos/Polymer/polytool/git/commits{/sha}","comments_url":"https://api.github.com/repos/Polymer/polytool/comments{/number}","issue_comment_url":"https://api.github.com/repos/Polymer/polytool/issues/comments{/number}","contents_url":"https://api.github.com/repos/Polymer/polytool/contents/{+path}","compare_url":"https://api.github.com/repos/Polymer/polytool/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Polymer/polytool/merges","archive_url":"https://api.github.com/repos/Polymer/polytool/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Polymer/polytool/downloads","issues_url":"https://api.github.com/repos/Polymer/polytool/issues{/number}","pulls_url":"https://api.github.com/repos/Polymer/polytool/pulls{/number}","milestones_url":"https://api.github.com/repos/Polymer/polytool/milestones{/number}","notifications_url":"https://api.github.com/repos/Polymer/polytool/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Polymer/polytool/labels{/name}","releases_url":"https://api.github.com/repos/Polymer/polytool/releases{/id}","deployments_url":"https://api.github.com/repos/Polymer/polytool/deployments","created_at":"2016-02-17T19:57:15Z","updated_at":"2016-04-20T17:32:33Z","pushed_at":"2016-04-19T23:47:36Z","git_url":"git://github.com/Polymer/polytool.git","ssh_url":"git@github.com:Polymer/polytool.git","clone_url":"https://github.com/Polymer/polytool.git","svn_url":"https://github.com/Polymer/polytool","homepage":null,"size":25,"stargazers_count":6,"watchers_count":6,"language":"TypeScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":9,"forks":4,"open_issues":9,"watchers":6,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Polymer/polytool/pulls/14"},"html":{"href":"https://github.com/Polymer/polytool/pull/14"},"issue":{"href":"https://api.github.com/repos/Polymer/polytool/issues/14"},"comments":{"href":"https://api.github.com/repos/Polymer/polytool/issues/14/comments"},"review_comments":{"href":"https://api.github.com/repos/Polymer/polytool/pulls/14/comments"},"review_comment":{"href":"https://api.github.com/repos/Polymer/polytool/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Polymer/polytool/pulls/14/commits"},"statuses":{"href":"https://api.github.com/repos/Polymer/polytool/statuses/a0a00ed5f6a55c6320ed3787f51fe7e253e66fa4"}}}}