hexo/node_modules/stylus/lib/nodes/object.js

245 lines
4.4 KiB
JavaScript
Raw Normal View History

2023-10-03 11:14:36 +08:00
/*!
* Stylus - Object
* Copyright (c) Automattic <developer.wordpress.com>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var Node = require('./node')
, nodes = require('./')
, nativeObj = {}.constructor;
/**
* Initialize a new `Object`.
*
* @api public
*/
var Object = module.exports = function Object(){
Node.call(this);
this.vals = {};
this.keys = {};
};
/**
* Inherit from `Node.prototype`.
*/
Object.prototype.__proto__ = Node.prototype;
/**
* Set `key` to `val`.
*
* @param {String} key
* @param {Node} val
* @return {Object} for chaining
* @api public
*/
Object.prototype.setValue = function(key, val){
this.vals[key] = val;
return this;
};
/**
* Alias for `setValue` for compatible API
*/
Object.prototype.set = Object.prototype.setValue;
/**
* Set `key` to `val`.
*
* @param {String} key
* @param {Node} val
* @return {Object} for chaining
* @api public
*/
Object.prototype.setKey = function(key, val){
this.keys[key] = val;
return this;
};
/**
* Return length.
*
* @return {Number}
* @api public
*/
Object.prototype.__defineGetter__('length', function() {
return nativeObj.keys(this.vals).length;
});
/**
* Get `key`.
*
* @param {String} key
* @return {Node}
* @api public
*/
Object.prototype.get = function(key){
return this.vals[key] || nodes.null;
};
/**
* Has `key`?
*
* @param {String} key
* @return {Boolean}
* @api public
*/
Object.prototype.has = function(key){
return key in this.vals;
};
/**
* Operate on `right` with the given `op`.
*
* @param {String} op
* @param {Node} right
* @return {Node}
* @api public
*/
Object.prototype.operate = function(op, right){
switch (op) {
case '.':
case '[]':
return this.get(right.hash);
case '==':
var vals = this.vals
, a
, b;
if ('object' != right.nodeName || this.length != right.length)
return nodes.false;
for (var key in vals) {
a = vals[key];
b = right.vals[key];
if (a.operate(op, b).isFalse)
return nodes.false;
}
return nodes.true;
case '!=':
return this.operate('==', right).negate();
default:
return Node.prototype.operate.call(this, op, right);
}
};
/**
* Return Boolean based on the length of this object.
*
* @return {Boolean}
* @api public
*/
Object.prototype.toBoolean = function(){
return nodes.Boolean(this.length);
};
/**
* Convert object to string with properties.
*
* @return {String}
* @api private
*/
Object.prototype.toBlock = function(){
var str = '{'
, key
, val;
for (key in this.vals) {
val = this.get(key);
if ('object' == val.first.nodeName) {
str += key + ' ' + val.first.toBlock();
} else {
switch (key) {
case '@charset':
str += key + ' ' + val.first.toString() + ';';
break;
default:
str += key + ':' + toString(val) + ';';
}
}
}
str += '}';
return str;
function toString(node) {
if (node.nodes) {
return node.nodes.map(toString).join(node.isList ? ',' : ' ');
} else if ('literal' == node.nodeName && ',' == node.val) {
return '\\,';
}
return node.toString();
}
};
/**
* Return a clone of this node.
*
* @return {Node}
* @api public
*/
Object.prototype.clone = function(parent){
var clone = new Object;
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
var key;
for (key in this.vals) {
clone.vals[key] = this.vals[key].clone(parent, clone);
}
for (key in this.keys) {
clone.keys[key] = this.keys[key].clone(parent, clone);
}
return clone;
};
/**
* Return a JSON representation of this node.
*
* @return {Object}
* @api public
*/
Object.prototype.toJSON = function(){
return {
__type: 'Object',
vals: this.vals,
keys: this.keys,
lineno: this.lineno,
column: this.column,
filename: this.filename
};
};
/**
* Return "{ <prop>: <val> }"
*
* @return {String}
* @api public
*/
Object.prototype.toString = function(){
var obj = {};
for (var prop in this.vals) {
obj[prop] = this.vals[prop].toString();
}
return JSON.stringify(obj);
};