hexo/node_modules/cheerio/lib/api/css.js

122 lines
2.4 KiB
JavaScript
Raw Normal View History

2023-10-03 11:14:36 +08:00
var domEach = require('../utils').domEach,
_ = {
pick: require('lodash.pick'),
};
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, styles[prop]);
}
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;
}, {});
}