{"action":"created","comment":{"url":"https://api.github.com/repos/Automattic/amp-wp/pulls/comments/80335742","id":80335742,"diff_hunk":"@@ -0,0 +1,102 @@\n+<?php\n+\n+require_once( AMP__DIR__ . '/includes/sanitizers/class-amp-base-sanitizer.php' );\n+\n+/**\n+ * Collects inline styles and outputs them in the amp-custom stylesheet.\n+ */\n+class AMP_Style_Sanitizer extends AMP_Base_Sanitizer {\n+\tprivate $styles = array();\n+\n+\tpublic function sanitize() {\n+\t\t$body = $this->get_body_node();\n+\t\t$this->collect_styles_recursive( $body );\n+\n+\t\tif ( ! empty( $this->styles ) ) {\n+\t\t\tadd_action( 'amp_post_template_css', array( $this, 'append_styles' ), 99 );\n+\t\t}\n+\t}\n+\n+\tprivate function collect_styles_recursive( $node ) {\n+\t\tif ( $node->nodeType !== XML_ELEMENT_NODE ) {\n+\t\t\treturn;\n+\t\t}\n+\n+\t\tif ( $node->hasAttributes() && $node instanceof DOMElement ) {\n+\t\t\t$style = $node->getAttribute( 'style' );\n+\t\t\t$class = $node->getAttribute( 'class' );\n+\n+\t\t\tif ( $style ) {\n+\t\t\t\t$style = $this->process_style( $style );\n+\n+\t\t\t\tif ( $style ) {\n+\t\t\t\t\t$class_name = $this->generate_class_name( $style );\n+\t\t\t\t\t$new_class  = trim( $class . ' ' . $class_name );\n+\n+\t\t\t\t\t$node->setAttribute( 'class', $new_class );\n+\t\t\t\t\t$this->styles[ $class_name ] = $style;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\n+\t\t$length = $node->childNodes->length;\n+\t\tfor ( $i = $length - 1; $i >= 0; $i -- ) {\n+\t\t\t$child_node = $node->childNodes->item( $i );\n+\n+\t\t\t$this->collect_styles_recursive( $child_node );\n+\t\t}\n+\t}\n+\n+\tprivate function process_style( $string ) {\n+\t\t// Filter properties\n+\t\t$string = safecss_filter_attr( $string );\n+\n+\t\tif ( ! $string ) {\n+\t\t\treturn '';\n+\t\t}\n+\n+\t\t// Normalize order\n+\t\t$arr = array_map( 'trim', explode( ';', $string ) );\n+\t\tsort( $arr );\n+\n+\t\t// Normalize whitespace\n+\t\tforeach ( $arr as $index => $rule ) {\n+\t\t\t$arr2 = array_map( 'trim', explode( ':', $rule, 2 ) );\n+\t\t\tif ( 2 === count( $arr2 ) ) {\n+\t\t\t\t$arr[ $index ] = $arr2[0] . ': ' . $arr2[1];\n+\t\t\t}\n+\t\t}\n+\n+\t\t// Handle overflow rule\n+\t\t// https://www.ampproject.org/docs/reference/spec.html#properties\n+\t\tif ( $overflow = preg_grep( '/^overflow.*(auto|scroll)$/', $arr ) ) {\n+\t\t\tforeach( $overflow as $index => $rule ) {\n+\t\t\t\tunset( $arr[ $index ] );\n+\t\t\t}\n+\t\t}\n+\n+\t\tif ( empty( $arr ) ) {\n+\t\t\treturn '';\n+\t\t}\n+\n+\t\treturn implode( \";\\n\\t\", $arr ) . ';';","path":"includes/sanitizers/class-amp-style-sanitizer.php","position":82,"original_position":82,"commit_id":"28092c4de741f9ee05fd5d8320d9ead4112eedac","original_commit_id":"5e084e86872eb373fdf73afe82bfbb9acdbea068","user":{"login":"mjangda","id":86105,"avatar_url":"https://avatars.githubusercontent.com/u/86105?v=3","gravatar_id":"","url":"https://api.github.com/users/mjangda","html_url":"https://github.com/mjangda","followers_url":"https://api.github.com/users/mjangda/followers","following_url":"https://api.github.com/users/mjangda/following{/other_user}","gists_url":"https://api.github.com/users/mjangda/gists{/gist_id}","starred_url":"https://api.github.com/users/mjangda/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mjangda/subscriptions","organizations_url":"https://api.github.com/users/mjangda/orgs","repos_url":"https://api.github.com/users/mjangda/repos","events_url":"https://api.github.com/users/mjangda/events{/privacy}","received_events_url":"https://api.github.com/users/mjangda/received_events","type":"User","site_admin":false},"body":"Not sure I understand your example. What would the original `style` attribute look like in this edge case?\r\n\r\nAMP has limits on how much CSS you can include (although, not 100% sure if whitespace counts) so we should try to keep it as slim as possible. Plus, no need to send extra bytes if we can avoid it.","created_at":"2016-09-23T22:09:48Z","updated_at":"2016-09-23T22:09:48Z","html_url":"https://github.com/Automattic/amp-wp/pull/470#discussion_r80335742","pull_request_url":"https://api.github.com/repos/Automattic/amp-wp/pulls/470","_links":{"self":{"href":"https://api.github.com/repos/Automattic/amp-wp/pulls/comments/80335742"},"html":{"href":"https://github.com/Automattic/amp-wp/pull/470#discussion_r80335742"},"pull_request":{"href":"https://api.github.com/repos/Automattic/amp-wp/pulls/470"}}},"pull_request":{"url":"https://api.github.com/repos/Automattic/amp-wp/pulls/470","id":85113090,"html_url":"https://github.com/Automattic/amp-wp/pull/470","diff_url":"https://github.com/Automattic/amp-wp/pull/470.diff","patch_url":"https://github.com/Automattic/amp-wp/pull/470.patch","issue_url":"https://api.github.com/repos/Automattic/amp-wp/issues/470","number":470,"state":"open","locked":false,"title":"Preserve Inline Styles","user":{"login":"coreymckrill","id":916023,"avatar_url":"https://avatars.githubusercontent.com/u/916023?v=3","gravatar_id":"","url":"https://api.github.com/users/coreymckrill","html_url":"https://github.com/coreymckrill","followers_url":"https://api.github.com/users/coreymckrill/followers","following_url":"https://api.github.com/users/coreymckrill/following{/other_user}","gists_url":"https://api.github.com/users/coreymckrill/gists{/gist_id}","starred_url":"https://api.github.com/users/coreymckrill/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/coreymckrill/subscriptions","organizations_url":"https://api.github.com/users/coreymckrill/orgs","repos_url":"https://api.github.com/users/coreymckrill/repos","events_url":"https://api.github.com/users/coreymckrill/events{/privacy}","received_events_url":"https://api.github.com/users/coreymckrill/received_events","type":"User","site_admin":false},"body":"Adds the `AMP_Style_Sanitizer` sanitizer class, which runs before the Blacklist class, and finds all of the element nodes within the content that have a `style` attribute. For each one, it stores the contents of `style` and generates a unique class name, which it adds to the element. Then, during template rendering, it outputs these class names and their styles in the `amp-custom` stylesheet in the document head.\r\n\r\nThis preserves critical style information that gets stripped from the elements by the Blacklist class, which appears to be the root cause of the problems in #344, #358, #362, and #395.\r\n\r\nThis also includes unit tests for the new sanitizer class. Testing on the performance impact of this additional sanitizer class was done using [this script](https://github.com/coreymckrill/amp-sanitize-cases).","created_at":"2016-09-13T19:49:16Z","updated_at":"2016-09-23T22:09:48Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9d632b33c5cc460e9fe61151555677aeb379bba4","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/Automattic/amp-wp/pulls/470/commits","review_comments_url":"https://api.github.com/repos/Automattic/amp-wp/pulls/470/comments","review_comment_url":"https://api.github.com/repos/Automattic/amp-wp/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Automattic/amp-wp/issues/470/comments","statuses_url":"https://api.github.com/repos/Automattic/amp-wp/statuses/28092c4de741f9ee05fd5d8320d9ead4112eedac","head":{"label":"coreymckrill:master","ref":"master","sha":"28092c4de741f9ee05fd5d8320d9ead4112eedac","user":{"login":"coreymckrill","id":916023,"avatar_url":"https://avatars.githubusercontent.com/u/916023?v=3","gravatar_id":"","url":"https://api.github.com/users/coreymckrill","html_url":"https://github.com/coreymckrill","followers_url":"https://api.github.com/users/coreymckrill/followers","following_url":"https://api.github.com/users/coreymckrill/following{/other_user}","gists_url":"https://api.github.com/users/coreymckrill/gists{/gist_id}","starred_url":"https://api.github.com/users/coreymckrill/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/coreymckrill/subscriptions","organizations_url":"https://api.github.com/users/coreymckrill/orgs","repos_url":"https://api.github.com/users/coreymckrill/repos","events_url":"https://api.github.com/users/coreymckrill/events{/privacy}","received_events_url":"https://api.github.com/users/coreymckrill/received_events","type":"User","site_admin":false},"repo":{"id":67749006,"name":"amp-wp","full_name":"coreymckrill/amp-wp","owner":{"login":"coreymckrill","id":916023,"avatar_url":"https://avatars.githubusercontent.com/u/916023?v=3","gravatar_id":"","url":"https://api.github.com/users/coreymckrill","html_url":"https://github.com/coreymckrill","followers_url":"https://api.github.com/users/coreymckrill/followers","following_url":"https://api.github.com/users/coreymckrill/following{/other_user}","gists_url":"https://api.github.com/users/coreymckrill/gists{/gist_id}","starred_url":"https://api.github.com/users/coreymckrill/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/coreymckrill/subscriptions","organizations_url":"https://api.github.com/users/coreymckrill/orgs","repos_url":"https://api.github.com/users/coreymckrill/repos","events_url":"https://api.github.com/users/coreymckrill/events{/privacy}","received_events_url":"https://api.github.com/users/coreymckrill/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/coreymckrill/amp-wp","description":"WordPress plugin for adding AMP support","fork":true,"url":"https://api.github.com/repos/coreymckrill/amp-wp","forks_url":"https://api.github.com/repos/coreymckrill/amp-wp/forks","keys_url":"https://api.github.com/repos/coreymckrill/amp-wp/keys{/key_id}","collaborators_url":"https://api.github.com/repos/coreymckrill/amp-wp/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/coreymckrill/amp-wp/teams","hooks_url":"https://api.github.com/repos/coreymckrill/amp-wp/hooks","issue_events_url":"https://api.github.com/repos/coreymckrill/amp-wp/issues/events{/number}","events_url":"https://api.github.com/repos/coreymckrill/amp-wp/events","assignees_url":"https://api.github.com/repos/coreymckrill/amp-wp/assignees{/user}","branches_url":"https://api.github.com/repos/coreymckrill/amp-wp/branches{/branch}","tags_url":"https://api.github.com/repos/coreymckrill/amp-wp/tags","blobs_url":"https://api.github.com/repos/coreymckrill/amp-wp/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/coreymckrill/amp-wp/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/coreymckrill/amp-wp/git/refs{/sha}","trees_url":"https://api.github.com/repos/coreymckrill/amp-wp/git/trees{/sha}","statuses_url":"https://api.github.com/repos/coreymckrill/amp-wp/statuses/{sha}","languages_url":"https://api.github.com/repos/coreymckrill/amp-wp/languages","stargazers_url":"https://api.github.com/repos/coreymckrill/amp-wp/stargazers","contributors_url":"https://api.github.com/repos/coreymckrill/amp-wp/contributors","subscribers_url":"https://api.github.com/repos/coreymckrill/amp-wp/subscribers","subscription_url":"https://api.github.com/repos/coreymckrill/amp-wp/subscription","commits_url":"https://api.github.com/repos/coreymckrill/amp-wp/commits{/sha}","git_commits_url":"https://api.github.com/repos/coreymckrill/amp-wp/git/commits{/sha}","comments_url":"https://api.github.com/repos/coreymckrill/amp-wp/comments{/number}","issue_comment_url":"https://api.github.com/repos/coreymckrill/amp-wp/issues/comments{/number}","contents_url":"https://api.github.com/repos/coreymckrill/amp-wp/contents/{+path}","compare_url":"https://api.github.com/repos/coreymckrill/amp-wp/compare/{base}...{head}","merges_url":"https://api.github.com/repos/coreymckrill/amp-wp/merges","archive_url":"https://api.github.com/repos/coreymckrill/amp-wp/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/coreymckrill/amp-wp/downloads","issues_url":"https://api.github.com/repos/coreymckrill/amp-wp/issues{/number}","pulls_url":"https://api.github.com/repos/coreymckrill/amp-wp/pulls{/number}","milestones_url":"https://api.github.com/repos/coreymckrill/amp-wp/milestones{/number}","notifications_url":"https://api.github.com/repos/coreymckrill/amp-wp/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/coreymckrill/amp-wp/labels{/name}","releases_url":"https://api.github.com/repos/coreymckrill/amp-wp/releases{/id}","deployments_url":"https://api.github.com/repos/coreymckrill/amp-wp/deployments","created_at":"2016-09-08T23:50:00Z","updated_at":"2016-09-08T23:50:01Z","pushed_at":"2016-09-19T18:35:13Z","git_url":"git://github.com/coreymckrill/amp-wp.git","ssh_url":"git@github.com:coreymckrill/amp-wp.git","clone_url":"https://github.com/coreymckrill/amp-wp.git","svn_url":"https://github.com/coreymckrill/amp-wp","homepage":"https://wordpress.org/plugins/amp/","size":1938,"stargazers_count":0,"watchers_count":0,"language":"PHP","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":"Automattic:master","ref":"master","sha":"40d33993c2cde07312262f921fbfcad0de9e60ed","user":{"login":"Automattic","id":887802,"avatar_url":"https://avatars.githubusercontent.com/u/887802?v=3","gravatar_id":"","url":"https://api.github.com/users/Automattic","html_url":"https://github.com/Automattic","followers_url":"https://api.github.com/users/Automattic/followers","following_url":"https://api.github.com/users/Automattic/following{/other_user}","gists_url":"https://api.github.com/users/Automattic/gists{/gist_id}","starred_url":"https://api.github.com/users/Automattic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Automattic/subscriptions","organizations_url":"https://api.github.com/users/Automattic/orgs","repos_url":"https://api.github.com/users/Automattic/repos","events_url":"https://api.github.com/users/Automattic/events{/privacy}","received_events_url":"https://api.github.com/users/Automattic/received_events","type":"Organization","site_admin":false},"repo":{"id":42912130,"name":"amp-wp","full_name":"Automattic/amp-wp","owner":{"login":"Automattic","id":887802,"avatar_url":"https://avatars.githubusercontent.com/u/887802?v=3","gravatar_id":"","url":"https://api.github.com/users/Automattic","html_url":"https://github.com/Automattic","followers_url":"https://api.github.com/users/Automattic/followers","following_url":"https://api.github.com/users/Automattic/following{/other_user}","gists_url":"https://api.github.com/users/Automattic/gists{/gist_id}","starred_url":"https://api.github.com/users/Automattic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Automattic/subscriptions","organizations_url":"https://api.github.com/users/Automattic/orgs","repos_url":"https://api.github.com/users/Automattic/repos","events_url":"https://api.github.com/users/Automattic/events{/privacy}","received_events_url":"https://api.github.com/users/Automattic/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Automattic/amp-wp","description":"WordPress plugin for adding AMP support","fork":false,"url":"https://api.github.com/repos/Automattic/amp-wp","forks_url":"https://api.github.com/repos/Automattic/amp-wp/forks","keys_url":"https://api.github.com/repos/Automattic/amp-wp/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Automattic/amp-wp/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Automattic/amp-wp/teams","hooks_url":"https://api.github.com/repos/Automattic/amp-wp/hooks","issue_events_url":"https://api.github.com/repos/Automattic/amp-wp/issues/events{/number}","events_url":"https://api.github.com/repos/Automattic/amp-wp/events","assignees_url":"https://api.github.com/repos/Automattic/amp-wp/assignees{/user}","branches_url":"https://api.github.com/repos/Automattic/amp-wp/branches{/branch}","tags_url":"https://api.github.com/repos/Automattic/amp-wp/tags","blobs_url":"https://api.github.com/repos/Automattic/amp-wp/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Automattic/amp-wp/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Automattic/amp-wp/git/refs{/sha}","trees_url":"https://api.github.com/repos/Automattic/amp-wp/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Automattic/amp-wp/statuses/{sha}","languages_url":"https://api.github.com/repos/Automattic/amp-wp/languages","stargazers_url":"https://api.github.com/repos/Automattic/amp-wp/stargazers","contributors_url":"https://api.github.com/repos/Automattic/amp-wp/contributors","subscribers_url":"https://api.github.com/repos/Automattic/amp-wp/subscribers","subscription_url":"https://api.github.com/repos/Automattic/amp-wp/subscription","commits_url":"https://api.github.com/repos/Automattic/amp-wp/commits{/sha}","git_commits_url":"https://api.github.com/repos/Automattic/amp-wp/git/commits{/sha}","comments_url":"https://api.github.com/repos/Automattic/amp-wp/comments{/number}","issue_comment_url":"https://api.github.com/repos/Automattic/amp-wp/issues/comments{/number}","contents_url":"https://api.github.com/repos/Automattic/amp-wp/contents/{+path}","compare_url":"https://api.github.com/repos/Automattic/amp-wp/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Automattic/amp-wp/merges","archive_url":"https://api.github.com/repos/Automattic/amp-wp/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Automattic/amp-wp/downloads","issues_url":"https://api.github.com/repos/Automattic/amp-wp/issues{/number}","pulls_url":"https://api.github.com/repos/Automattic/amp-wp/pulls{/number}","milestones_url":"https://api.github.com/repos/Automattic/amp-wp/milestones{/number}","notifications_url":"https://api.github.com/repos/Automattic/amp-wp/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Automattic/amp-wp/labels{/name}","releases_url":"https://api.github.com/repos/Automattic/amp-wp/releases{/id}","deployments_url":"https://api.github.com/repos/Automattic/amp-wp/deployments","created_at":"2015-09-22T04:52:15Z","updated_at":"2016-09-23T17:55:17Z","pushed_at":"2016-09-23T17:53:26Z","git_url":"git://github.com/Automattic/amp-wp.git","ssh_url":"git@github.com:Automattic/amp-wp.git","clone_url":"https://github.com/Automattic/amp-wp.git","svn_url":"https://github.com/Automattic/amp-wp","homepage":"https://wordpress.org/plugins/amp/","size":2412,"stargazers_count":791,"watchers_count":791,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":129,"mirror_url":null,"open_issues_count":94,"forks":129,"open_issues":94,"watchers":791,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Automattic/amp-wp/pulls/470"},"html":{"href":"https://github.com/Automattic/amp-wp/pull/470"},"issue":{"href":"https://api.github.com/repos/Automattic/amp-wp/issues/470"},"comments":{"href":"https://api.github.com/repos/Automattic/amp-wp/issues/470/comments"},"review_comments":{"href":"https://api.github.com/repos/Automattic/amp-wp/pulls/470/comments"},"review_comment":{"href":"https://api.github.com/repos/Automattic/amp-wp/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Automattic/amp-wp/pulls/470/commits"},"statuses":{"href":"https://api.github.com/repos/Automattic/amp-wp/statuses/28092c4de741f9ee05fd5d8320d9ead4112eedac"}}}}
{"actor":{"display_login":"mjangda"}}