var _ = require('lodash'), domEach = require('../utils').domEach; var toString = Object.prototype.toString; /** * Set / Get css. * * @param {String|Object} prop * @param {String} val * @return {self} * @api public */ exports.css = function(prop, val) { if (arguments.length === 2 || // When `prop` is a "plain" object (toString.call(prop) === '[object Object]')) { return domEach(this, function(idx, el) { setCss(el, prop, val, idx); }); } else { return getCss(this[0], prop); } }; /** * Set styles of all elements. * * @param {String|Object} prop * @param {String} val * @param {Number} idx - optional index within the selection * @return {self} * @api private */ function setCss(el, prop, val, idx) { if ('string' == typeof prop) { var styles = getCss(el); if (typeof val === 'function') { val = val.call(el, idx, el); } if (val === '') { delete styles[prop]; } else if (val != null) { styles[prop] = val; } el.attribs.style = stringify(styles); } else if ('object' == typeof prop) { Object.keys(prop).forEach(function(k){ setCss(el, k, prop[k]); }); } } /** * Get parsed styles of the first element. * * @param {String} prop * @return {Object} * @api private */ function getCss(el, prop) { var styles = parse(el.attribs.style); if (typeof prop === 'string') { return styles[prop]; } else if (Array.isArray(prop)) { return _.pick(styles, prop); } else { return styles; } } /** * Stringify `obj` to styles. * * @param {Object} obj * @return {Object} * @api private */ function stringify(obj) { return Object.keys(obj || {}) .reduce(function(str, prop){ return str += '' + (str ? ' ' : '') + prop + ': ' + obj[prop] + ';'; }, ''); } /** * Parse `styles`. * * @param {String} styles * @return {Object} * @api private */ function parse(styles) { styles = (styles || '').trim(); if (!styles) return {}; return styles .split(';') .reduce(function(obj, str){ var n = str.indexOf(':'); // skip if there is no :, or if it is the first/last character if (n < 1 || n === str.length-1) return obj; obj[str.slice(0,n).trim()] = str.slice(n+1).trim(); return obj; }, {}); }