You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
214 lines
3.7 KiB
214 lines
3.7 KiB
9 years ago
|
|
||
|
/*!
|
||
|
* 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 = {};
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* 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.set = function(key, val){
|
||
|
this.vals[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;
|
||
|
for (var key in this.vals) {
|
||
|
clone.vals[key] = this.vals[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,
|
||
|
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);
|
||
|
};
|