UNPKG

3.12 kBJavaScriptView Raw
1
2/*!
3 * Stylus - Query
4 * Copyright (c) Automattic <developer.wordpress.com>
5 * MIT Licensed
6 */
7
8/**
9 * Module dependencies.
10 */
11
12var Node = require('./node');
13
14/**
15 * Initialize a new `Query`.
16 *
17 * @api public
18 */
19
20var Query = module.exports = function Query(){
21 Node.call(this);
22 this.nodes = [];
23 this.type = '';
24 this.predicate = '';
25};
26
27/**
28 * Inherit from `Node.prototype`.
29 */
30
31Query.prototype.__proto__ = Node.prototype;
32
33/**
34 * Return a clone of this node.
35 *
36 * @return {Node}
37 * @api public
38 */
39
40Query.prototype.clone = function(parent){
41 var clone = new Query;
42 clone.predicate = this.predicate;
43 clone.type = this.type;
44 for (var i = 0, len = this.nodes.length; i < len; ++i) {
45 clone.push(this.nodes[i].clone(parent, clone));
46 }
47 clone.lineno = this.lineno;
48 clone.column = this.column;
49 clone.filename = this.filename;
50 return clone;
51};
52
53/**
54 * Push the given `feature`.
55 *
56 * @param {Feature} feature
57 * @api public
58 */
59
60Query.prototype.push = function(feature){
61 this.nodes.push(feature);
62};
63
64/**
65 * Return resolved type of this query.
66 *
67 * @return {String}
68 * @api private
69 */
70
71Query.prototype.__defineGetter__('resolvedType', function(){
72 if (this.type) {
73 return this.type.nodeName
74 ? this.type.string
75 : this.type;
76 }
77});
78
79/**
80 * Return resolved predicate of this query.
81 *
82 * @return {String}
83 * @api private
84 */
85
86Query.prototype.__defineGetter__('resolvedPredicate', function(){
87 if (this.predicate) {
88 return this.predicate.nodeName
89 ? this.predicate.string
90 : this.predicate;
91 }
92});
93
94/**
95 * Merges this query with the `other`.
96 *
97 * @param {Query} other
98 * @return {Query}
99 * @api private
100 */
101
102Query.prototype.merge = function(other){
103 var query = new Query
104 , p1 = this.resolvedPredicate
105 , p2 = other.resolvedPredicate
106 , t1 = this.resolvedType
107 , t2 = other.resolvedType
108 , type, pred;
109
110 // Stolen from Sass :D
111 t1 = t1 || t2;
112 t2 = t2 || t1;
113 if (('not' == p1) ^ ('not' == p2)) {
114 if (t1 == t2) return;
115 type = ('not' == p1) ? t2 : t1;
116 pred = ('not' == p1) ? p2 : p1;
117 } else if (('not' == p1) && ('not' == p2)) {
118 if (t1 != t2) return;
119 type = t1;
120 pred = 'not';
121 } else if (t1 != t2) {
122 return;
123 } else {
124 type = t1;
125 pred = p1 || p2;
126 }
127 query.predicate = pred;
128 query.type = type;
129 query.nodes = this.nodes.concat(other.nodes);
130 return query;
131};
132
133/**
134 * Return "<a> and <b> and <c>"
135 *
136 * @return {String}
137 * @api public
138 */
139
140Query.prototype.toString = function(){
141 var pred = this.predicate ? this.predicate + ' ' : ''
142 , type = this.type || ''
143 , len = this.nodes.length
144 , str = pred + type;
145 if (len) {
146 str += (type && ' and ') + this.nodes.map(function(expr){
147 return expr.toString();
148 }).join(' and ');
149 }
150 return str;
151};
152
153/**
154 * Return a JSON representation of this node.
155 *
156 * @return {Object}
157 * @api public
158 */
159
160Query.prototype.toJSON = function(){
161 return {
162 __type: 'Query',
163 predicate: this.predicate,
164 type: this.type,
165 nodes: this.nodes,
166 lineno: this.lineno,
167 column: this.column,
168 filename: this.filename
169 };
170};