UNPKG

stylus

Version:

Robust, expressive, and feature-rich CSS superset

245 lines (207 loc) 4.2 kB
/*! * Stylus - Object * Copyright (c) Automattic <developer.wordpress.com> * MIT Licensed */ /** * Module dependencies. */ var Node = require('./node') , nodes = require('./') , nativeObj = {}.constructor; module.exports = class Object extends Node { /** * Initialize a new `Object`. * * @api public */ constructor() { super(); this.vals = {}; this.keys = {}; } /** * Set `key` to `val`. * * @param {String} key * @param {Node} val * @return {Object} for chaining * @api public */ setValue(key, val) { this.vals[key] = val; return this; }; /** * Alias for `setValue` for compatible API */ get set() { return this.setValue; } /** * Set `key` to `val`. * * @param {String} key * @param {Node} val * @return {Object} for chaining * @api public */ setKey(key, val) { this.keys[key] = val; return this; }; /** * Return length. * * @return {Number} * @api public */ get length() { return nativeObj.keys(this.vals).length; }; /** * Get `key`. * * @param {String} key * @return {Node} * @api public */ get(key) { return this.vals[key] || nodes.null; }; /** * Has `key`? * * @param {String} key * @return {Boolean} * @api public */ has(key) { return key in this.vals; }; /** * Operate on `right` with the given `op`. * * @param {String} op * @param {Node} right * @return {Node} * @api public */ operate(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 super.operate(op, right); } }; /** * Return Boolean based on the length of this object. * * @return {Boolean} * @api public */ toBoolean() { return new nodes.Boolean(this.length); }; /** * Convert object to string with properties. * * @return {String} * @api private */ toBlock() { 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 */ clone(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 */ toJSON() { 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 */ toString() { var obj = {}; for (var prop in this.vals) { obj[prop] = this.vals[prop].toString(); } return JSON.stringify(obj); }; };