Skip to content

Loading…

autoprefixer support #472

Merged
merged 4 commits into from

6 participants

@mente

Hello,

This PR adds support of great lib autoprefixer that helps to solve down vendor-specific nightmare in css. I know there are mixins, but not everyone uses sass, less or other css compilers.

Looking forward for comments.

@ai
ai commented

CSS Tricks publish good article, why Autoprefixer is cool and how it works: http://css-tricks.com/autoprefixer/

@mente mente referenced this pull request
Closed

Added AutoprefixerFilter #483

@stof stof commented on an outdated diff
src/Assetic/Filter/AutoprefixerFilter.php
((28 lines not shown))
+ private $autoprefixerBin;
+
+ /**
+ * @var string
+ */
+ private $browsers;
+
+ public function __construct($autoprefixerBin)
+ {
+ $this->autoprefixerBin = $autoprefixerBin;
+ }
+
+ /**
+ * @param string $browser
+ */
+ public function setBrowsers($browser)
@stof Collaborator
stof added a note

I would find it more logical to configure the browsers as an array in PHP and build the comma separated string only when calling the binary.

Note that when calling autoprefixer programmatically in JS, browsers are also passed as an array

@mente
mente added a note

Yes, I think it would be more clear

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@stof stof commented on an outdated diff
src/Assetic/Filter/AutoprefixerFilter.php
((36 lines not shown))
+ {
+ $this->autoprefixerBin = $autoprefixerBin;
+ }
+
+ /**
+ * @param string $browser
+ */
+ public function setBrowsers($browser)
+ {
+ $this->browsers = $browser;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ $input = $asset->getContent();
+ $pb = $this->createProcessBuilder(array($this->autoprefixerBin, '-o', '-'));
@stof Collaborator
stof added a note

you should use an output file instead of stdout because proc_open on windows has issues when the output is too large. See other filters to see how it is done

@mente
mente added a note

arghhh. Ok

@mente
mente added a note

I believe this is the issue. But there are other filters that use same proc_open, i.e. CoffeeScriptFilter. They should be fixed too?

@mente
mente added a note

Same problem exists for SassFilter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@mente

Should I squash commits into 1?

@ai
ai commented

What How To I should post on Autoprefixer README.md?

@mente

@ai i'll provide PR to your repo. Also there will be PR for Symfony2 Bundle after this PR is merged. Hopefully soon enough :)

@guill3m

What's the status on this PR?

Is it planned to be merged to core or should we use it as a custom filter?

Thank you.

@patchampoux

Please merge this?

Thank you.

@kriswallsmith kriswallsmith merged commit 7c9639d into kriswallsmith:master

1 check passed

Details default The Travis CI build passed
@kriswallsmith

Thank you!

@mente

Awesome, thanks!

@stof
Collaborator

tests are broken on Travis

@mente

PR was made more than year ago, might be outdated. Checking it

@ai
ai commented

Autoprefixer was rewritten several times since this PR ;).

@mente mente added a commit to mente/assetic that referenced this pull request
@mente mente fixed autoprefixer unit tests introduced in #472 39db3f5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Showing with 199 additions and 1 deletion.
  1. +1 −0 .travis.yml
  2. +1 −0 README.md
  3. +2 −1 package.json
  4. +86 −0 src/Assetic/Filter/AutoprefixerFilter.php
  5. +109 −0 tests/Assetic/Test/Filter/AutoprefixerFilterTest.php
View
1 .travis.yml
@@ -13,6 +13,7 @@ before_script:
- npm install uglify-js@1 && mkdir -p vendor/uglifyjs && mv node_modules vendor/uglifyjs
- npm install
- export UGLIFYJS_BIN=vendor/uglifyjs/node_modules/uglify-js/bin/uglifyjs
+ - export AUTOPREFIXER_BIN=node_modules/autoprefixer/bin/autoprefixer
# java deps
- mkdir -p vendor/java
View
1 README.md
@@ -74,6 +74,7 @@ foreach ($css as $leaf) {
The core provides the following filters in the `Assetic\Filter` namespace:
+ * `AutoprefixerFilter`: Parse and update vendor-specific properties using autoprefixer
* `CoffeeScriptFilter`: compiles CoffeeScript into Javascript
* `CompassFilter`: Compass CSS authoring framework
* `CssEmbedFilter`: embeds image data in your stylesheets
View
3 package.json
@@ -8,6 +8,7 @@
"typescript": "*",
"less": "*",
"handlebars": "*",
- "uglify-js": "*"
+ "uglify-js": "*",
+ "autoprefixer": "*"
}
}
View
86 src/Assetic/Filter/AutoprefixerFilter.php
@@ -0,0 +1,86 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2013 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+
+/**
+ * Parses CSS and adds vendor prefixes to rules using values from the Can I Use website
+ *
+ * @link https://github.com/ai/autoprefixer
+ * @author Alex Vasilenko <aa.vasilenko@gmail.com>
+ */
+class AutoprefixerFilter extends BaseNodeFilter
+{
+ /**
+ * @var string
+ */
+ private $autoprefixerBin;
+
+ /**
+ * @var array
+ */
+ private $browsers = array();
+
+ public function __construct($autoprefixerBin)
+ {
+ $this->autoprefixerBin = $autoprefixerBin;
+ }
+
+ /**
+ * @param array $browsers
+ */
+ public function setBrowsers(array $browsers)
+ {
+ $this->browsers = $browsers;
+ }
+
+ /**
+ * @param string $browser
+ */
+ public function addBrowser($browser)
+ {
+ $this->browsers[] = $browser;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ $input = $asset->getContent();
+ $pb = $this->createProcessBuilder(array($this->autoprefixerBin));
+
+ $pb->setInput($input);
+ if ($this->browsers) {
+ $pb->add('-b')->add(implode(',', $this->browsers));
+ }
+
+ $output = tempnam(sys_get_temp_dir(), 'assetic_autoprefixer');
+ $pb->add('-o')->add($output);
+
+ $proc = $pb->getProcess();
+ if (0 !== $proc->run()) {
+ throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+ }
+
+ $asset->setContent(file_get_contents($output));
+ unlink($output);
+ }
+
+ /**
+ * Filters an asset just before it's dumped.
+ *
+ * @param AssetInterface $asset An asset
+ */
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+}
View
109 tests/Assetic/Test/Filter/AutoprefixerFilterTest.php
@@ -0,0 +1,109 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2013 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Test\Filter;
+
+use Assetic\Asset\StringAsset;
+use Assetic\Filter\AutoprefixerFilter;
+
+/**
+ * @group integration
+ */
+class AutoprefixerFilterTest extends FilterTestCase
+{
+ /**
+ * @var AutoprefixerFilter
+ */
+ private $filter;
+
+ protected function setUp()
+ {
+ $autoprefixerBin = $this->findExecutable('autoprefixer', 'AUTOPREFIXER_BIN');
+
+ if (!$autoprefixerBin) {
+ $this->markTestSkipped('Unable to find `autoprefixer` executable.');
+ }
+
+ $this->filter = new AutoprefixerFilter($autoprefixerBin);
+ }
+
+ public function testFilterLoad()
+ {
+ $input = <<<CSS
+a {
+ display: flex;
+}
+CSS;
+ //TODO in some point of future this test will fail. Update test when new versions come out?
+ $expected = <<<CSS
+a {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -moz-box;
+ display: -ms-flexbox;
+ display: flex;
+}
+CSS;
+
+ $asset = new StringAsset($input);
+ $asset->load();
+
+ $this->filter->filterLoad($asset);
+
+ $this->assertEquals($expected, $asset->getContent());
+ }
+
+ public function testReallyOldBrowsers()
+ {
+ $input = <<<CSS
+img {
+ border-radius: 10px;
+}
+CSS;
+ $expected = <<<CSS
+img {
+ -moz-border-radius: 10px;
+ border-radius: 10px;
+}
+CSS;
+
+ $asset = new StringAsset($input);
+ $asset->load();
+
+ $this->filter->setBrowsers(array('ff 3'));
+ $this->filter->filterLoad($asset);
+
+ $this->assertEquals($expected, $asset->getContent());
+ }
+
+ public function testAddBrowser()
+ {
+ $input = <<<CSS
+img {
+ border-radius: 10px;
+}
+CSS;
+ $expected = <<<CSS
+img {
+ -moz-border-radius: 10px;
+ border-radius: 10px;
+}
+CSS;
+
+ $asset = new StringAsset($input);
+ $asset->load();
+
+ $this->filter->addBrowser('ff 3');
+ $this->filter->filterLoad($asset);
+
+ $this->assertEquals($expected, $asset->getContent());
+ }
+}
Something went wrong with that request. Please try again.