diff --git a/Readme.md b/Readme.md index 15c187437e..44dc7db186 100644 --- a/Readme.md +++ b/Readme.md @@ -544,6 +544,10 @@ $('ul').text() // Pear ``` +#### .css( [propertName] )
.css( [ propertyNames] )
.css( [propertyName], [value] )
.css( [propertName], [function] )
.css( [properties] ) + +Get the value of a style property for the first element in the set of matched elements or set one or more CSS properties for every matched element. + ### Rendering When you're ready to render the document, you can use the `html` utility function: diff --git a/lib/api/css.js b/lib/api/css.js index 307c704574..5346d01b7e 100644 --- a/lib/api/css.js +++ b/lib/api/css.js @@ -1,3 +1,5 @@ +var _ = require('underscore'); +var toString = Object.prototype.toString; /** * Set / Get css. @@ -8,56 +10,67 @@ * @api public */ -exports.css = function(prop, val){ - if (undefined == prop) return get(this); - - switch (arguments.length) { - case 2: return set(this, prop, val); - case 0: return get(this); - case 1: return 'object' == typeof prop - ? set(this, prop) - : get(this, prop); +exports.css = function(prop, val) { + if (arguments.length === 2 || + // When `prop` is a "plain" object + (toString.call(prop) === '[object Object]')) { + return this.each(function(idx) { + set.call(this, prop, val, idx); + }); + } else { + return get.call(this, prop); } }; /** * Set styles of all elements. * - * @param {Cheerio} self * @param {String|Object} prop * @param {String} val + * @param {Number} idx - optional index within the selection * @return {self} * @api private */ -function set(self, prop, val){ +function set(prop, val, idx) { if ('string' == typeof prop) { - var styles = get(self); - styles[prop] = val; - return self.attr('style', stringify(styles)); + var styles = get.call(this); + if (_.isFunction(val)) { + val = val.call(this[0], idx, this[0]); + } + + if (val === '') { + delete styles[prop]; + } else if (val != null) { + styles[prop] = val; + } + + return this.attr('style', stringify(styles)); } else if ('object' == typeof prop) { Object.keys(prop).forEach(function(k){ - set(self, k, prop[k]); - }); - return self; + set.call(this, k, prop[k]); + }, this); + return this; } } /** * Get parsed styles of the first element. * - * @param {Cheerio} self * @param {String} prop * @return {Object} * @api private */ -function get(self, prop){ - var styles = parse(self.attr('style')); - if (undefined == styles) throw new Error('undefined'); - return 2 == arguments.length - ? styles[prop] - : styles; +function get(prop) { + var styles = parse(this.attr('style')); + if (typeof prop === 'string') { + return styles[prop]; + } else if (_.isArray(prop)) { + return _.pick(styles, prop); + } else { + return styles; + } } /** @@ -68,7 +81,7 @@ function get(self, prop){ * @api private */ -function stringify(obj){ +function stringify(obj) { return Object.keys(obj || {}) .reduce(function(str, prop){ return str += '' @@ -88,7 +101,7 @@ function stringify(obj){ * @api private */ -function parse(styles){ +function parse(styles) { styles = (styles || '').trim(); if ('' == styles) return {}; diff --git a/test/api.css.js b/test/api.css.js index a77ca3aa18..564d95a125 100644 --- a/test/api.css.js +++ b/test/api.css.js @@ -1,43 +1,73 @@ - var expect = require('expect.js'); var $ = require('..'); -describe('$(...)', function(){ - - describe('.css', function(){ - it('(): should get all styles as object', function(){ - var el = $('
  • '); - expect(el.css()).to.eql({ hai: 'there', wassup: 0 }); - }) +describe('$(...)', function() { - it('(undefined): should retrun all styles as object', function(){ - var el = $('
  • '); - expect(el.css()).to.eql({ color: 'white' }); - }) - - it('(prop): should return a css property value', function(){ + describe('.css', function() { + it('(prop): should return a css property value', function() { var el = $('
  • '); expect(el.css('hai')).to.equal('there'); - }) + }); + + it('([prop1, prop2]): should return the specified property values as an object', function() { + var el = $('
  • '); + expect(el.css(['margin', 'color'])).to.eql({ margin: '1px', color: 'blue' }); + }); + + it('(prop, val): should set a css property', function() { + var el = $('
  • '); + el.css('color', 'red'); + expect(el.attr('style')).to.equal('margin: 0; color: red;'); + expect(el.eq(1).attr('style')).to.equal('color: red;'); + }); + + it('(prop, ""): should unset a css property', function() { + var el = $('
  • '); + el.css('padding', ''); + expect(el.attr('style')).to.equal('margin: 0;'); + }); + + describe('(prop, function):', function() { + beforeEach(function() { + this.$el = $('
    '); + }); + + it('should iterate over the selection', function() { + var count = 0; + var $el = this.$el; + this.$el.css('margin', function(idx, elem) { + expect(idx).to.equal(count); + expect(elem).to.equal($el[count]); + expect(this).to.equal($el[count]); + count++; + }); + expect(count).to.equal(3); + }); - it('(prop, val): should set a css property', function(){ - var el = $('
  • '); - el.css('wassup', 0); - expect(el.attr('style')).to.equal('wassup: 0;'); - }) + it('should set each attribute independently', function() { + var values = ['4px', '', undefined]; + this.$el.css('margin', function(idx) { + return values[idx]; + }); + expect(this.$el.eq(0).attr('style')).to.equal('margin: 4px;'); + expect(this.$el.eq(1).attr('style')).to.equal(''); + expect(this.$el.eq(2).attr('style')).to.equal('margin: 0;'); + }); + }); - it('(obj): should set each key and val', function(){ - var el = $('
  • '); + it('(obj): should set each key and val', function() { + var el = $('
  • '); el.css({ foo: 0 }); - expect(el.attr('style')).to.equal('foo: 0;'); - }) + expect(el.eq(0).attr('style')).to.equal('padding: 0; foo: 0;'); + expect(el.eq(1).attr('style')).to.equal('foo: 0;'); + }); describe('parser', function(){ - it('should allow any whitespace between declarations', function(){ + it('should allow any whitespace between declarations', function() { var el = $('
  • '); - expect(el.css()).to.eql({ one: 0, two: 1 }); - }) - }) - }) + expect(el.css(['one', 'two'])).to.eql({ one: 0, two: 1 }); + }); + }); + }); -}) +});