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

autoprefixer support #472

Merged
merged 4 commits into from Aug 27, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -8,6 +8,7 @@
"typescript": "*",
"less": "*",
"handlebars": "*",
"uglify-js": "*"
"uglify-js": "*",
"autoprefixer": "*"
}
}
86 changes: 86 additions & 0 deletions 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)
{
}
}
109 changes: 109 additions & 0 deletions 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());
}
}