Git Product home page Git Product logo

rework's Introduction

rework Build Status

CSS manipulations built on css, allowing you to automate vendor prefixing, create your own properties, inline images, anything you can imagine!

Please refer to css for AST documentation and to report parser/stringifier issues.

Installation

$ npm install rework

Usage

var rework = require('rework');
var pluginA = require('pluginA');
var pluginB = require('pluginB');

rework('body { font-size: 12px; }', { source: 'source.css' })
  .use(pluginA)
  .use(pluginB)
  .toString({ sourcemap: true })

API

rework(code, [options])

Accepts a CSS string and returns a new Rework instance. The options are passed directly to css.parse.

Rework#use(fn)

Use the given plugin fn. A rework "plugin" is simply a function accepting the stylesheet root node and the Rework instance.

Rework#toString([options])

Returns the string representation of the manipulated CSS. The options are passed directly to css.stringify.

Unlike css.stringify, if you pass sourcemap: true a string will still be returned, with the source map inlined. Also use sourcemapAsObject: true if you want the css.stringify return value.

Plugins

Rework has a rich collection of plugins and mixins. Browse all the Rework plugins available on npm.

Plugins of particular note:

  • at2x – serve high resolution images
  • calc – resolve simple calc() expressions
  • colors – color helpers like rgba(#fc0, .5)
  • ease – several additional easing functions
  • extendextend: selector support
  • function – user-defined CSS functions
  • import – read and inline CSS via @import
  • inline – inline assets as data URIs
  • mixin – custom property logic with mixins
  • npm - inline CSS via @import using node's module resolver
  • references – property references like height: @width
  • url – rewrite url()s with a given function
  • variables – W3C-style variables

Built with rework

License

(The MIT License)

Copyright (c) 2012–2013 TJ Holowaychuk [email protected]

Copyright (c) 2014 Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

rework's People

Contributors

ai avatar anthonyshort avatar arnihermann avatar bclinkinbeard avatar bolasblack avatar chrisjshull avatar conradz avatar ericf avatar gr2m avatar idealhack avatar jankuca avatar jasonkuhrt avatar joakimbeng avatar joliss avatar jonathanong avatar kristoferjoseph avatar lennart avatar leoner avatar lydell avatar moox avatar necolas avatar novium avatar nv avatar rauchg avatar robotlolita avatar rschmukler avatar simme avatar tj avatar tootallnate avatar yuanchuan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rework's Issues

Fix prefixed gradient values with angles and keywords

The spec changed the way angles work (to bearing angles), so all prefixed implementations are 90 degrees off.

When I use linear-gradient(0deg, #fff, #ddd) it should convert the 0deg to 90deg in the prefixed functions.

It should also convert the unprefixed implementations use of the to and from keywords to the older prefixed syntax.

Stylus?

This is more of a question than an issue. Everything that stylus can do rework can be extended to do? Is there any exclusive benefit to stylus? I can't think of one other than more features right-now? What's your personal take on stylus, deprecated? I guess you could release a new version of stylus that is basically just a module/opinionated bundle of rework plugins ala Janus for vim?

Hm...

add .prefix([props]) support

array will increase perf since it's inefficient to loop per prop.. looks messier but this will be a more realistic use-case anyway

add scope

in-file, basically prefixSelector, @scope #photos ul etc

allow .inline(' ')

Right now it assumes the string inside .inline() does not have quotation marks around it. i would think you should allow them so that the API is the same as CSS's url().

For example, this would fail:

background: inline('logo.png')

but this will not:

background: inline(logo.png)

remove vars

into separate repo since it's pretty subjective

Media Query de-nester

It would be really useful to have a rework that removes nested @media rules:

@media screen and (min-width: 480px) {

    body{
        background-color:#6aa6cc;
        color:#000;    
    }

    @media screen and (min-width: 768px) {

        body{
            background-color:#000;
            color:#fff;    
        }
    }
}

becomes

@media screen and (min-width: 480px) {

    body{
        background-color:#6aa6cc;
        color:#000;    
    }
}
@media screen and (min-width: 768px) {
    body{
        background-color:#000;
        color:#fff;    
    }
}

but it would need to be much more clever when the inner media query doesn't imply the outer media query.

prefix selectors

I will be happy to implement this if you want, just need some pointers

this

::placeholder {
  color: #aaa
}

should eql

::-webkit-input-placeholder,
::-moz-placeholder,
::-ms-input-placeholder,
::-o-placeholder {
  color: #aaa
}

url() breaks on urls with data uris

the url function breaks when the path is a data uri. The path you get

data:image/png;base6

I don't really expect to get the full data uri, but there's no way to keep the original value. I think it should be changed so that if you return false it just doesn't do any replacements. Then I could check for 'data:' and if it's present then return false.

Don't change indentation

When I proccess

body {
    transition: all 1s ease-out;
}

or

body { transition: all 1s ease-out }

Rework will remove all my formatation and use own styles (without \n at end file):

body {
  transition: all 1s ease-out
}

It's not critical, but good postprocessor will change only that, you need.

can't extend a placeholder selector unless it has a root

%clearfix:before,
%clearfix:after {
  content: " ";
  display: table;
}

%clearfix:after {
  clear: both;
}

.clearfix {
  extend: %clearfix
}

Error:

    Error: failed to extend "%clearfix"
        at visit (/Users/jonathanong/Workspace/discore-css/node_modules/rework/lib/plugins/extend.js:43:24)
        at module.exports (/Users/jonathanong/Workspace/discore-css/node_modules/rework/lib/plugins/extend.js:22:7)
        at Array.forEach (native)
        at module.exports (/Users/jonathanong/Workspace/discore-css/node_modules/rework/lib/plugins/extend.js:16:17)
        at Rework.use (/Users/jonathanong/Workspace/discore-css/node_modules/rework/lib/rework.js:58:3)
        at Object.<anonymous> (/Users/jonathanong/Workspace/discore-css/index.js:7:2)
        at Module._compile (module.js:449:26)
        at Object.Module._extensions..js (module.js:467:10)
        at Module.load (module.js:356:32)
        at Function.Module._load (module.js:312:12)

Then I add a dummy placeholder:

%clearfix {

}

%clearfix:before,
%clearfix:after {
  content: " ";
  display: table;
}

%clearfix:after {
  clear: both;
}

.clearfix {
  extend: %clearfix
}

It compiles, but I get the following:

.clearfix {

}

%clearfix:after,
.clearfix:before {
  content: " ";
  display: table
}

.clearfix:after {
  clear: both
}

.clearfix {

}

Which is not correct.

!! Augment mixin to support property repeated with different values

I am going to use rework mixins to patch the flex spec so that users can work with the current spec and have the old syntax inserted automatically:

http://bennettfeely.com/flexplorer/
http://caniuse.com/#search=flex
http://zomigi.com/blog/flexbox-syntax-for-ie-10/
https://gist.github.com/cimmanon/4461470

I'm blocked by the fact that rework.mixin only accepts functions that return objects though. For instance this is how cross-browser display: flex needs to end up:

  display: -webkit-box;      /* OLD - iOS 6-, Safari 3.1-6 */
  display: -moz-box;         /* OLD - Firefox 19- (buggy but mostly works) */
  display: -ms-flexbox;      /* TWEENER - IE 10 */
  display: -webkit-flex;     /* NEW - Chrome */
  display: flex;             /* NEW, Spec - Opera 12.1, Firefox 20+ */

But that's not possible if I can only return an object since I need the same key but with different values. If we tweak rework.mixin to accept objects of functions that return either objects or arrays of objects then we are back in business:

rework.mixin({
  display: function() {
    return [{property:'display', value:'foo'}, { property:'display', value:'bar'}];
  }
})

@visionmedia Please bless this so I can get on with a PR including the changes + passing tests.

Rework crashes on comments

Here is my css:

.login-form {
    /*width: 500px;*/
    height: 200px;
    padding: 42px 0 0 0;
    margin: 0 auto;
}

And my rework function:

function (css) {
  return rework(css).toString();
}

When i compile it I get:

TypeError: Cannot call method 'map' of undefined
at Compiler.rule (/home/sel/Dokumenty/motim/mtm-www/node_modules/rework/node_modules/css/node_modules/css-stringify/index.js:162:25)
at Compiler.visit (/home/sel/Dokumenty/motim/mtm-www/node_modules/rework/node_modules/css/node_modules/css-stringify/index.js:44:15)
at Array.map (native)
at Compiler.compile (/home/sel/Dokumenty/motim/mtm-www/node_modules/rework/node_modules/css/node_modules/css-stringify/index.js:30:32)
at Object.module.exports [as stringify] (/home/sel/Dokumenty/motim/mtm-www/node_modules/rework/node_modules/css/node_modules/css-stringify/index.js:12:32)
at Rework.toString (/home/sel/Dokumenty/motim/mtm-www/node_modules/rework/lib/rework.js:86:14)
(...)

If i remove the comments everything works fine.

Move all plugins to separate libraries.

I think we should remove all the plugins from core. Follow the same philosophy of node.js itself and make them separate. This would prevent people from opening lots of pull requests asking for core status (e.g. #32 which does this at the moment). We could then create a simple wiki page like we did with component to list them.

For the command line interface I'd suggest a simple plugin technique where people can list the modules they have installed that supply 'rework' plugins.

Usage then becomes:

Usage: rework <plugins> [options]

Options:

  -h, --help            output usage information
  -V, --version         output the version number
  -v, --vendors <list>  specify list of vendors

e.g.

$ rework ease,vars,extend -v webkit,moz < my.css > my.reworked.css

We could have rework automatically attempt require(plugin) and then if that fails it could attempt require('rework-' + plugin)

This would vastly reduce the size of core and hopefully lead to it being pretty much locked stability once we've sorted how to handle async transformations and syntax transformations.

CSS stringify omits last semicolon in property declarations

After running rework on a css file the last property in the declarations is missing a semicolon.

Steps to reproduce

  1. run rework on a css file
.foo {
    background: var(var-background-color);
    border: 1px solid var(var-border-color);
}
  1. Observe results

Expected results

.foo {
    background: blue;
    border: 1px solid black;
}

Actual results

.foo {
    background: blue;
    border: 1px solid black
}

*notice the semicolon is missing

Allow to set vendors to prefixes

As I understand prefixValue create prefixes for all global vendors, but a lot of properties need only some vendors.

So, we need something like:

.use(rework.prefixValue('transform', ['-webkit-']))

Simple variables syntax

Variables syntax in CSS is totally mind fucked. We need special :root section, we use different var-NAME in declaration and just var(NAME) in usage.

If Rework’s vars isn’t spec equalent, maybe we should use normal syntax from Stylus or Sass (I prefer last one, because it is very easy to find variable usage in code and we can’t rewrite systems terms like red = blue).

Calculations

Calcultaions in CSS is very easefull.

li {
  width: 726px / 3;
}

Because robots are ours slaves, they must think and suffer, not.

Of course, it not only about lazy. We can use it in some automatization in future:

.logo {
  width: image-width('logo.png') / 2;
}

Or in generate background-size for retina sprite. Or use with references:

.preview {
  width: 150px;
  height: @width * 2;
}

But, of course, we can just use calc(), but it is too long and not every browser support it.

I think, most architectural way will be:

  • We have some preprocessor, that wrap any calculation 726px / 3 or 3px + 5em to calc().
  • Rework filter, that find calc() without different units (like 726px / 3 or 30px + 172px) and calculate it now.

improve extend perf

haven't measured anything benchmark-wise but an O(n) scan over the keys is lame

Crash on @-moz-document url-prefix()

Crashes when trying to process @-moz-document url-prefix()

.../node_modules/rework/node_modules/css/node_modules/css-stringify/index.js:150
    + node.declarations.map(this.declaration, this).join(';\n')
                        ^
TypeError: Cannot call method 'map' of undefined
    at Compiler.rule (/.../node_modules/rework/node_modules/css/node_modules/css-stringify/index.js:150:25)
    at Compiler.visit (/.../node_modules/rework/node_modules/css/node_modules/css-stringify/index.js:43:15)
    at Array.map (native)
    at Compiler.compile (/.../node_modules/rework/node_modules/css/node_modules/css-stringify/index.js:30:32)
    at Object.module.exports [as stringify] (/.../node_modules/rework/node_modules/css/node_modules/css-stringify/index.js:12:32)
    at Rework.toString (/.../node_modules/rework/lib/rework.js:86:14)
    at Object.<anonymous> (/.../rework.js:21:2)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
make: *** [build] Error 8

CSS:

@-moz-document url-prefix() {
  .icon-spin {
    height: .9em;
  }
  .btn .icon-spin {
    height: auto;
  }
  .icon-spin.icon-large {
    height: 1.25em;
  }
  .btn .icon-spin.icon-large {
    height: .75em;
  }
}

extend nesting

sniff around for rulesets with the given prefix? this is lame:

.exif .close
  extend: .dark-close-button
  &:before
    extend: .dark-close-button::before
  &:hover
    extend: .dark-close-button:hover
  &:active
    extend: .dark-close-button:active

but without the concept of nesting at the css-parse level, which then in turn no longer parsing valid CSS, we're fucked

media helpers

@media retina {

}

etc vs

@media only screen and (-webkit-min-device-pixel-ratio: 2) {

}

that sort of idea, iphone, ipad etc

A question on rework usage

The question is simple: would you use rework for Stylus? And/or rewrite the nib using it?

I'm currently working on implementing the gradients in the right way for nib and there are so many issues and bugs in Stylus itself that the code for the resulting mixins already became very messy and unreadable — I almost made a parser and a lot of helper functions for the Stylus objects.

It went to the state where I sat and thought that writing another preprocessor, but in a “right” way, where you could rewrite any selectors, properties and values would be not that bad idea. And then there's a rework!

I think that it would be really good to replace all those verbose functions in nib that are wtitten in Stylus to the rework plugins — working directly with parsed css would be so much easier than handling arrays of arguments!

So, I'd like to know would you use rework for stylus? It would be a somwhat logical step now, I think.

better transition shorthand syntax

w3c lies and states: none | [ all | <IDENT> ] [ ‘,’ [ all | <IDENT> ] ]*, however transition is defined as:

     [<‘transition-property’> || <‘transition-duration’> || <‘transition-timing-function’> || <‘transition-delay’> [, [<‘transition-property’> || <‘transition-duration’> || <‘transition-timing-function’> || <‘transition-delay’>]]*

which is incorrect from what I can see, it's ambiguous

Placeholder extend leaves empty selector

Using placeholder extension leaves an empty selector in the output.
An example of this can be seen in the test file:
https://github.com/visionmedia/rework/blob/master/test/fixtures/extend.nested.placeholder.out.css

Expected result seems like it would be either to insert background: black; or to remove the empty selector if the generated extended selectors cover that case in the cascade.

Steps to reproduce

  1. Create a placeholder selector:

    %dark-button {
        background: black;
    }
    
    .button {
        extend: %dark-button;
    }
  2. Run rework use extend

  3. Compare output

Expected result

.button {
    background: black;
}

Actual result

.button {
    background: black;
}

.button {

}

Asynchronous plugin support

Currently all plugins are expected to be synchronous which works fine when your only requirement is the CSS AST itself, but it would be great if plugins could also be asynchronous, for things more advanced plugins like:

Automatic generation of standard resolution images when retina version exists

  1. atx plugin processes stylesheet and injects retina-specific rules.
  2. magicalretinaplugin scans the AST again, and for every nonexistent background-image declaration inspects the physical image. if the standard image doesn't exist but the retina does, generate @2x image using something like node-canvas.

Automatic sprite-sheet generation

  1. Scan AST for background-image declarations and store dimensions.
  2. Generate spritesheets using bin-packing and then node-canvas for each pixel-ratio.

Image-processing tools

Tools like jpegoptim, optipng and pngcrush.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.