Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add runtime CSS minification, !important replacement, and tree shaking #1048

Merged
merged 32 commits into from
Apr 6, 2018
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
48a538b
Add sabberworm/php-css-parser composer dependency
westonruter Mar 26, 2018
0e994a9
Add initial Server Timing response headers
westonruter Mar 27, 2018
8271fac
Use sabberworm/php-css-parser to sanitize CSS
westonruter Mar 30, 2018
a96b39b
Delete illegal properties (behavior and -moz-binding)
westonruter Mar 30, 2018
06fca39
Include sabberworm/php-css-parser from composer in build; always comp…
westonruter Mar 30, 2018
c27e9a2
Add check for composer install; update contributing with dev installa…
westonruter Mar 30, 2018
8ef82f7
Add tests for AMP_Response_Headers
westonruter Mar 30, 2018
e16aba2
Add missing phpdoc for functions in amp.php
westonruter Mar 30, 2018
036c631
Improve handling of style[amp-keyframes] by merging multiples and ens…
westonruter Mar 30, 2018
fd04b20
Transform !important property qualifiers into rules with more specifi…
westonruter Mar 31, 2018
5da10f3
Remove illegal @-rules and ensure properties inside @media/@supports …
westonruter Mar 31, 2018
523d5ee
Include css_spec from validator in AMP_Allowed_Tags_Generated
westonruter Mar 31, 2018
1889f70
Capture full cdata spec for amp-keyframes and amp-custom to use for v…
westonruter Mar 31, 2018
9187710
Discontinue deleting scroll/auto values for overflow properties since…
westonruter Mar 31, 2018
3d18b8a
Add parsing and validation of keyframes
westonruter Mar 31, 2018
f245a8f
Ensure stylesheets are output in legacy post templates
westonruter Apr 1, 2018
6c49807
Bump required PHP to 5.3.2 for sake of php-css-parser
westonruter Apr 1, 2018
3e3266b
Add class-based selector tree shaking of CSS rules
westonruter Apr 1, 2018
6b5f97e
Further reduce CSS size by deleting individual selectors that lack va…
westonruter Apr 1, 2018
ae68eee
Prevent :not() pseudo-selectors from tree shaking classes erroneously
westonruter Apr 1, 2018
6d4778e
Remove attribute selectors prior to searching for class names to prev…
westonruter Apr 2, 2018
2693f7e
Simplify accounting for used class names when tree shaking
westonruter Apr 2, 2018
faef934
Make font-face source urls non-relative; replace data: URLs with (ass…
westonruter Apr 2, 2018
cb3cc2c
Use expiring transients when no external object cache present
westonruter Apr 2, 2018
346eae2
Handle selector specificity variability; give high specificity to rul…
westonruter Apr 2, 2018
14c22c2
Convert all URLs (including background-image) to have absolute paths
westonruter Apr 2, 2018
313f0b9
Merge branch 'develop' of https://github.com/Automattic/amp-wp into a…
westonruter Apr 5, 2018
bede9de
Prevent filtering selectors which reference dynamic elements
westonruter Apr 5, 2018
adb1fb1
Skip removing style rules when the total CSS does not exceed max_bytes
westonruter Apr 6, 2018
a8fddf2
Verify existence of font file source for data: URL
westonruter Apr 6, 2018
3cd9fdd
Add tests for validation errors raised during style sanitization
westonruter Apr 6, 2018
efd1965
Add testing for remove_unused_rules=sometimes and excessive_css
westonruter Apr 6, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ matrix:
env: WP_VERSION=4.7

install:
- if [[ $DEV_LIB_SKIP =~ composer ]]; then composer install --no-dev; fi
- nvm install 6 && nvm use 6
- export DEV_LIB_PATH=dev-lib
- source $DEV_LIB_PATH/travis.install.sh
Expand Down
12 changes: 9 additions & 3 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,21 @@ module.exports = function( grunt ) {
args: [ 'ls-files' ]
},
function( err, res ) {
var paths;
if ( err ) {
throw new Error( err.message );
}

paths = res.stdout.trim().split( /\n/ ).filter( function( file ) {
return ! /^(\.|bin|([^/]+)+\.(md|json|xml)|Gruntfile\.js|tests|wp-assets|dev-lib|readme\.md|composer\..*)/.test( file );
} );
paths.push( 'vendor/autoload.php' );
paths.push( 'vendor/composer/**' );
paths.push( 'vendor/sabberworm/php-css-parser/lib/**' );

grunt.config.set( 'copy', {
build: {
src: res.stdout.trim().split( /\n/ ).filter( function( file ) {
return ! /^(\.|bin|([^/]+)+\.(md|json|xml)|Gruntfile\.js|tests|wp-assets|dev-lib|readme\.md|composer\..*)/.test( file );
} ),
src: paths,
dest: 'build',
expand: true
}
Expand Down
70 changes: 64 additions & 6 deletions amp.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,32 @@
function _amp_print_php_version_admin_notice() {
?>
<div class="notice notice-error">
<p><?php esc_html_e( 'The AMP plugin requires PHP 5.3+. Please contact your host to update your PHP version.', 'amp' ); ?></p>
</div>
<p><?php esc_html_e( 'The AMP plugin requires PHP 5.3+. Please contact your host to update your PHP version.', 'amp' ); ?></p>
</div>
<?php
}
if ( version_compare( phpversion(), '5.3', '<' ) ) {
if ( version_compare( phpversion(), '5.3.2', '<' ) ) {
add_action( 'admin_notices', '_amp_print_php_version_admin_notice' );
return;
}

/**
* Print admin notice when composer install has not been performed.
*
* @since 1.0
*/
function _amp_print_composer_install_admin_notice() {
?>
<div class="notice notice-error">
<p><?php esc_html_e( 'You appear to be running the AMP plugin from source. Please do `composer install` to finish installation.', 'amp' ); ?></p>
</div>
<?php
}
if ( ! file_exists( __DIR__ . '/vendor/autoload.php' ) || ! file_exists( __DIR__ . '/vendor/sabberworm/php-css-parser' ) ) {
add_action( 'admin_notices', '_amp_print_composer_install_admin_notice' );
return;
}

define( 'AMP__FILE__', __FILE__ );
define( 'AMP__DIR__', dirname( __FILE__ ) );
define( 'AMP__VERSION', '1.0-alpha' );
Expand All @@ -42,6 +59,12 @@ function _amp_print_php_version_admin_notice() {
require_once AMP__DIR__ . '/includes/admin/functions.php';

register_activation_hook( __FILE__, 'amp_activate' );

/**
* Handle activation of plugin.
*
* @since 0.2
*/
function amp_activate() {
amp_after_setup_theme();
if ( ! did_action( 'amp_init' ) ) {
Expand All @@ -51,8 +74,14 @@ function amp_activate() {
}

register_deactivation_hook( __FILE__, 'amp_deactivate' );

/**
* Handle deactivation of plugin.
*
* @since 0.2
*/
function amp_deactivate() {
// We need to manually remove the amp endpoint
// We need to manually remove the amp endpoint.
global $wp_rewrite;
foreach ( $wp_rewrite->endpoints as $index => $endpoint ) {
if ( amp_get_slug() === $endpoint[1] ) {
Expand Down Expand Up @@ -130,8 +159,16 @@ function amp_init() {
add_action( 'wp', 'amp_maybe_add_actions' );
}

// Make sure the `amp` query var has an explicit value.
// Avoids issues when filtering the deprecated `query_string` hook.
/**
* Make sure the `amp` query var has an explicit value.
*
* This avoids issues when filtering the deprecated `query_string` hook.
*
* @since 0.3.3
*
* @param array $query_vars Query vars.
* @return array Query vars.
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice improvements here with the DocBlocks and @since tags.

function amp_force_query_var_value( $query_vars ) {
if ( isset( $query_vars[ amp_get_slug() ] ) && '' === $query_vars[ amp_get_slug() ] ) {
$query_vars[ amp_get_slug() ] = 1;
Expand Down Expand Up @@ -250,20 +287,41 @@ function amp_is_canonical() {
return false;
}

/**
* Load classes.
*
* @since 0.2
* @deprecated As of 0.6 since autoloading is now employed.
*/
function amp_load_classes() {
_deprecated_function( __FUNCTION__, '0.6' );
}

/**
* Add frontend actions.
*
* @since 0.2
*/
function amp_add_frontend_actions() {
require_once AMP__DIR__ . '/includes/amp-frontend-actions.php';
}

/**
* Add post template actions.
*
* @since 0.2
*/
function amp_add_post_template_actions() {
require_once AMP__DIR__ . '/includes/amp-post-template-actions.php';
require_once AMP__DIR__ . '/includes/amp-post-template-functions.php';
amp_post_template_init_hooks();
}

/**
* Add action to do post template rendering at template_redirect action.
*
* @since 0.2
*/
function amp_prepare_render() {
add_action( 'template_redirect', 'amp_render' );
}
Expand Down
37 changes: 31 additions & 6 deletions bin/amphtml-update.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,12 +356,37 @@ def GetTagSpec(tag_spec, attr_lists):
for (field_descriptor, field_value) in tag_spec.cdata.ListFields():
if isinstance(field_value, (unicode, str, bool, int)):
cdata_dict[ field_descriptor.name ] = field_value
else:
if hasattr( field_value, '_values' ):
cdata_dict[ field_descriptor.name ] = {}
for _value in field_value._values:
for (key,val) in _value.ListFields():
cdata_dict[ field_descriptor.name ][ key.name ] = val
elif hasattr( field_value, '_values' ):
cdata_dict[ field_descriptor.name ] = {}
for _value in field_value._values:
for (key,val) in _value.ListFields():
cdata_dict[ field_descriptor.name ][ key.name ] = val
elif 'css_spec' == field_descriptor.name:
css_spec = {}

css_spec['allowed_at_rules'] = []
for at_rule_spec in field_value.at_rule_spec:
if '$DEFAULT' == at_rule_spec.name:
continue
css_spec['allowed_at_rules'].append( at_rule_spec.name )

for css_spec_field_name in ( 'allowed_declarations', 'font_url_spec', 'image_url_spec', 'validate_keyframes' ):
if not hasattr( field_value, css_spec_field_name ):
continue
css_spec_field_value = getattr( field_value, css_spec_field_name )
if isinstance(css_spec_field_value, (list, collections.Sequence, google.protobuf.internal.containers.RepeatedScalarFieldContainer)):
css_spec[ css_spec_field_name ] = [ val for val in css_spec_field_value ]
elif hasattr( css_spec_field_value, 'ListFields' ):
css_spec[ css_spec_field_name ] = {}
for (css_spec_field_item_descriptor, css_spec_field_item_value) in getattr( field_value, css_spec_field_name ).ListFields():
if isinstance(css_spec_field_item_value, (list, collections.Sequence, google.protobuf.internal.containers.RepeatedScalarFieldContainer)):
css_spec[ css_spec_field_name ][ css_spec_field_item_descriptor.name ] = [ val for val in css_spec_field_item_value ]
else:
css_spec[ css_spec_field_name ][ css_spec_field_item_descriptor.name ] = css_spec_field_item_value
else:
css_spec[ css_spec_field_name ] = css_spec_field_value

cdata_dict['css_spec'] = css_spec
if len( cdata_dict ) > 0:
tag_spec_dict['cdata'] = cdata_dict

Expand Down
9 changes: 9 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@
"type": "wordpress-plugin",
"license": "GPL-2.0",
"version": "1.0.0",
"repositories": [
{
"type": "vcs",
"url": "https://github.com/xwp/PHP-CSS-Parser"
}
],
"require": {
"sabberworm/php-css-parser": "dev-master"
},
"require-dev": {
"wp-coding-standards/wpcs": "^0.14.0",
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.4",
Expand Down
77 changes: 63 additions & 14 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 15 additions & 3 deletions contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,22 @@

Thanks for taking the time to contribute!

To clone this repository
``` bash
$ git clone --recursive [email protected]:Automattic/amp-wp.git
To start, clone this repository into your WordPress install being used for development:

```bash
cd wp-content/plugins && git clone --recursive [email protected]:Automattic/amp-wp.git amp
```

If you happened to have cloned without `--recursive` previously, please do `git submodule update --init` to ensure the [dev-lib](https://github.com/xwp/wp-dev-lib/) submodule is available for development.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a good idea to add this.


Lastly, to get the plugin running in your WordPress install, run `composer install` and then activate the plugin via the WordPress dashboard or `wp plugin activate amp`.

To install the `pre-commit` hook, do `bash dev-lib/install-pre-commit-hook.sh`.

Note that pull requests will be checked against [WordPress-Coding-Standards](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards) with PHPCS, and for JavaScript linting is done with ESLint and (for now) JSCS and JSHint.

To run the Grunt commands, please first `npm install -g grunt-cli` and then `npm install`.

## Updating Allowed Tags And Attributes

The file `class-amp-allowed-tags-generated.php` has the AMP specification's allowed tags and attributes. It's used in sanitization.
Expand Down Expand Up @@ -72,6 +83,7 @@ When you push a commit to your PR, Travis CI will run the PHPUnit tests and snif

Contributors who want to make a new release, follow these steps:

0. Do `grunt build` and install the `amp.zip` onto a normal WordPress install running a stable release build; do smoke test to ensure it works.
1. Bump plugin versions in `package.json` (×1), `package-lock.json` (×1, just do `npm install` first), `composer.json` (×1), and in `amp.php` (×2: the metadata block in the header and also the `AMP__VERSION` constant).
2. Add changelog entry to readme.
3. Merge release branch into `master`.
Expand Down
Loading