Comparing version 3.0.6 to 3.0.7
@@ -0,1 +1,5 @@ | ||
## 3.0.7 | ||
* Fix IE filter parsing with multiple commands. | ||
* Safer way to consume PostCSS object as plugin (by Maxime Thirouin). | ||
## 3.0.6 | ||
@@ -2,0 +6,0 @@ * Fix missing semicolon when comment comes after last declaration. |
"use strict"; | ||
var _classProps = function (child, staticProps, instanceProps) { | ||
if (staticProps) Object.defineProperties(child, staticProps); | ||
if (instanceProps) Object.defineProperties(child.prototype, instanceProps); | ||
}; | ||
var _extends = function (child, parent) { | ||
@@ -33,70 +28,42 @@ child.prototype = Object.create(parent.prototype, { | ||
_classProps(AtRule, null, { | ||
stringify: { | ||
writable: true, | ||
AtRule.prototype.stringify = function (builder, semicolon) { | ||
var name = "@" + this.name; | ||
var params = this.params ? this.stringifyRaw("params") : ""; | ||
if (typeof (this.afterName) != "undefined") { | ||
name += this.afterName; | ||
} else if (params) { | ||
name += " "; | ||
} | ||
// Stringify at-rule | ||
value: function (builder, semicolon) { | ||
var name = "@" + this.name; | ||
var params = this.params ? this.stringifyRaw("params") : ""; | ||
if (this.childs) { | ||
this.stringifyBlock(builder, name + params); | ||
} else { | ||
var before = this.style("beforeRule"); | ||
if (before) builder(before); | ||
var end = (this.between || "") + (semicolon ? ";" : ""); | ||
builder(name + params + end, this); | ||
} | ||
}; | ||
if (typeof (this.afterName) != "undefined") { | ||
name += this.afterName; | ||
} else if (params) { | ||
name += " "; | ||
} | ||
AtRule.prototype.append = function (child) { | ||
if (!this.childs) this.childs = []; | ||
return Container.prototype.append.call(this, child); | ||
}; | ||
if (this.childs) { | ||
this.stringifyBlock(builder, name + params); | ||
} else { | ||
var before = this.style("beforeRule"); | ||
if (before) builder(before); | ||
var end = (this.between || "") + (semicolon ? ";" : ""); | ||
builder(name + params + end, this); | ||
} | ||
} | ||
}, | ||
append: { | ||
writable: true, | ||
AtRule.prototype.prepend = function (child) { | ||
if (!this.childs) this.childs = []; | ||
return Container.prototype.prepend.call(this, child); | ||
}; | ||
AtRule.prototype.insertBefore = function (exist, add) { | ||
if (!this.childs) this.childs = []; | ||
return Container.prototype.insertBefore.call(this, exist, add); | ||
}; | ||
// Hack to mark, that at-rule contains childs | ||
value: function (child) { | ||
if (!this.childs) this.childs = []; | ||
return Container.prototype.append.call(this, child); | ||
} | ||
}, | ||
prepend: { | ||
writable: true, | ||
AtRule.prototype.insertAfter = function (exist, add) { | ||
if (!this.childs) this.childs = []; | ||
return Container.prototype.insertAfter.call(this, exist, add); | ||
}; | ||
// Hack to mark, that at-rule contains childs | ||
value: function (child) { | ||
if (!this.childs) this.childs = []; | ||
return Container.prototype.prepend.call(this, child); | ||
} | ||
}, | ||
insertBefore: { | ||
writable: true, | ||
// Hack to mark, that at-rule contains childs | ||
value: function (exist, add) { | ||
if (!this.childs) this.childs = []; | ||
return Container.prototype.insertBefore.call(this, exist, add); | ||
} | ||
}, | ||
insertAfter: { | ||
writable: true, | ||
// Hack to mark, that at-rule contains childs | ||
value: function (exist, add) { | ||
if (!this.childs) this.childs = []; | ||
return Container.prototype.insertAfter.call(this, exist, add); | ||
} | ||
} | ||
}); | ||
return AtRule; | ||
@@ -103,0 +70,0 @@ })(Container); |
"use strict"; | ||
var _classProps = function (child, staticProps, instanceProps) { | ||
if (staticProps) Object.defineProperties(child, staticProps); | ||
if (instanceProps) Object.defineProperties(child.prototype, instanceProps); | ||
}; | ||
var _extends = function (child, parent) { | ||
@@ -31,26 +26,16 @@ child.prototype = Object.create(parent.prototype, { | ||
_classProps(Comment, null, { | ||
styleMap: { | ||
writable: true, | ||
value: function () { | ||
return { | ||
commentLeft: this.left, | ||
commentRight: this.right | ||
}; | ||
} | ||
}, | ||
stringify: { | ||
writable: true, | ||
Comment.prototype.styleMap = function () { | ||
return { | ||
commentLeft: this.left, | ||
commentRight: this.right | ||
}; | ||
}; | ||
Comment.prototype.stringify = function (builder) { | ||
if (this.before) builder(this.before); | ||
var left = this.style("commentLeft"); | ||
var right = this.style("commentRight"); | ||
builder("/*" + left + this.text + right + "*/", this); | ||
}; | ||
// Stringify declaration | ||
value: function (builder) { | ||
if (this.before) builder(this.before); | ||
var left = this.style("commentLeft"); | ||
var right = this.style("commentRight"); | ||
builder("/*" + left + this.text + right + "*/", this); | ||
} | ||
} | ||
}); | ||
return Comment; | ||
@@ -57,0 +42,0 @@ })(Node); |
@@ -31,396 +31,246 @@ "use strict"; | ||
_classProps(Container, null, { | ||
styleMap: { | ||
writable: true, | ||
value: function () { | ||
var style = { | ||
beforeRule: this.before, | ||
beforeOpen: this.between | ||
}; | ||
if (this.childs && this.childs.length) { | ||
style.beforeClose = this.after; | ||
} else { | ||
style.emptyBody = this.after; | ||
} | ||
return style; | ||
} | ||
}, | ||
stringifyContent: { | ||
writable: true, | ||
Container.prototype.styleMap = function () { | ||
var style = { | ||
beforeRule: this.before, | ||
beforeOpen: this.between | ||
}; | ||
if (this.childs && this.childs.length) { | ||
style.beforeClose = this.after; | ||
} else { | ||
style.emptyBody = this.after; | ||
} | ||
return style; | ||
}; | ||
Container.prototype.stringifyContent = function (builder) { | ||
if (!this.childs) return; | ||
// Stringify container childs | ||
value: function (builder) { | ||
if (!this.childs) return; | ||
var i, last = this.childs.length - 1; | ||
while (last > 0) { | ||
if (this.childs[last].type != "comment") break; | ||
last -= 1; | ||
} | ||
var i, last = this.childs.length - 1; | ||
while (last > 0) { | ||
if (this.childs[last].type != "comment") break; | ||
last -= 1; | ||
} | ||
for (i = 0; i < this.childs.length; i++) { | ||
this.childs[i].stringify(builder, last != i || this.semicolon); | ||
} | ||
}; | ||
for (i = 0; i < this.childs.length; i++) { | ||
this.childs[i].stringify(builder, last != i || this.semicolon); | ||
} | ||
} | ||
}, | ||
stringifyBlock: { | ||
writable: true, | ||
Container.prototype.stringifyBlock = function (builder, start) { | ||
var before = this.style("beforeRule"); | ||
if (before) builder(before); | ||
builder(start + this.style("beforeOpen") + "{", this, "start"); | ||
var after; | ||
if (this.childs && this.childs.length) { | ||
this.stringifyContent(builder); | ||
after = this.style("beforeClose"); | ||
} else { | ||
after = this.style("emptyBody"); | ||
} | ||
// Stringify node with start (for example, selector) and brackets block | ||
// with child inside | ||
value: function (builder, start) { | ||
var before = this.style("beforeRule"); | ||
if (before) builder(before); | ||
builder(start + this.style("beforeOpen") + "{", this, "start"); | ||
if (after) builder(after); | ||
builder("}", this, "end"); | ||
}; | ||
var after; | ||
if (this.childs && this.childs.length) { | ||
this.stringifyContent(builder); | ||
after = this.style("beforeClose"); | ||
} else { | ||
after = this.style("emptyBody"); | ||
} | ||
Container.prototype.push = function (child) { | ||
child.parent = this; | ||
this.childs.push(child); | ||
return this; | ||
}; | ||
if (after) builder(after); | ||
builder("}", this, "end"); | ||
} | ||
}, | ||
push: { | ||
writable: true, | ||
Container.prototype.each = function (callback) { | ||
if (!this.lastEach) this.lastEach = 0; | ||
if (!this.indexes) this.indexes = {}; | ||
this.lastEach += 1; | ||
var id = this.lastEach; | ||
this.indexes[id] = 0; | ||
// Add child to end of list without any checks. | ||
// Please, use `append()` method, `push()` is mostly for parser. | ||
value: function (child) { | ||
child.parent = this; | ||
this.childs.push(child); | ||
return this; | ||
} | ||
}, | ||
each: { | ||
writable: true, | ||
if (!this.childs) return; | ||
var index, result; | ||
while (this.indexes[id] < this.childs.length) { | ||
index = this.indexes[id]; | ||
result = callback(this.childs[index], index); | ||
if (result === false) break; | ||
// Execute `callback` on every child element. First arguments will be child | ||
// node, second will be index. | ||
// | ||
// css.each( (rule, i) => { | ||
// console.log(rule.type + ' at ' + i); | ||
// }); | ||
// | ||
// It is safe for add and remove elements to list while iterating: | ||
// | ||
// css.each( (rule) => { | ||
// css.insertBefore( rule, addPrefix(rule) ); | ||
// # On next iteration will be next rule, regardless of that | ||
// # list size was increased | ||
// }); | ||
value: function (callback) { | ||
if (!this.lastEach) this.lastEach = 0; | ||
if (!this.indexes) this.indexes = {}; | ||
this.indexes[id] += 1; | ||
} | ||
this.lastEach += 1; | ||
var id = this.lastEach; | ||
this.indexes[id] = 0; | ||
delete this.indexes[id]; | ||
if (!this.childs) return; | ||
if (result === false) return false; | ||
}; | ||
var index, result; | ||
while (this.indexes[id] < this.childs.length) { | ||
index = this.indexes[id]; | ||
result = callback(this.childs[index], index); | ||
if (result === false) break; | ||
Container.prototype.eachInside = function (callback) { | ||
return this.each(function (child, i) { | ||
var result = callback(child, i); | ||
this.indexes[id] += 1; | ||
} | ||
delete this.indexes[id]; | ||
if (result === false) return false; | ||
if (result !== false && child.eachInside) { | ||
result = child.eachInside(callback); | ||
} | ||
}, | ||
eachInside: { | ||
writable: true, | ||
if (result === false) return result; | ||
}); | ||
}; | ||
// Execute callback on every child in all rules inside. | ||
// | ||
// First argument will be child node, second will be index inside parent. | ||
// | ||
// css.eachInside( (node, i) => { | ||
// console.log(node.type + ' at ' + i); | ||
// }); | ||
// | ||
// Also as `each` it is safe of insert/remove nodes inside iterating. | ||
value: function (callback) { | ||
return this.each(function (child, i) { | ||
var result = callback(child, i); | ||
if (result !== false && child.eachInside) { | ||
result = child.eachInside(callback); | ||
} | ||
if (result === false) return result; | ||
}); | ||
Container.prototype.eachDecl = function (callback) { | ||
return this.eachInside(function (child, i) { | ||
if (child.type == "decl") { | ||
var result = callback(child, i); | ||
if (result === false) return result; | ||
} | ||
}, | ||
eachDecl: { | ||
writable: true, | ||
}); | ||
}; | ||
// Execute callback on every declaration in all rules inside. | ||
// It will goes inside at-rules recursivelly. | ||
// | ||
// First argument will be declaration node, second will be index inside | ||
// parent rule. | ||
// | ||
// css.eachDecl( (decl, i) => { | ||
// console.log(decl.prop + ' in ' + decl.parent.selector + ':' + i); | ||
// }); | ||
// | ||
// Also as `each` it is safe of insert/remove nodes inside iterating. | ||
value: function (callback) { | ||
return this.eachInside(function (child, i) { | ||
if (child.type == "decl") { | ||
var result = callback(child, i); | ||
if (result === false) return result; | ||
} | ||
}); | ||
Container.prototype.eachRule = function (callback) { | ||
return this.eachInside(function (child, i) { | ||
if (child.type == "rule") { | ||
var result = callback(child, i); | ||
if (result === false) return result; | ||
} | ||
}, | ||
eachRule: { | ||
writable: true, | ||
}); | ||
}; | ||
// Execute `callback` on every rule in conatiner and inside child at-rules. | ||
// | ||
// First argument will be rule node, second will be index inside parent. | ||
// | ||
// css.eachRule( (rule, i) => { | ||
// if ( parent.type == 'atrule' ) { | ||
// console.log(rule.selector + ' in ' + rule.parent.name); | ||
// } else { | ||
// console.log(rule.selector + ' at ' + i); | ||
// } | ||
// }); | ||
value: function (callback) { | ||
return this.eachInside(function (child, i) { | ||
if (child.type == "rule") { | ||
var result = callback(child, i); | ||
if (result === false) return result; | ||
} | ||
}); | ||
Container.prototype.eachAtRule = function (callback) { | ||
return this.eachInside(function (child, i) { | ||
if (child.type == "atrule") { | ||
var result = callback(child, i); | ||
if (result === false) return result; | ||
} | ||
}, | ||
eachAtRule: { | ||
writable: true, | ||
}); | ||
}; | ||
// Execute `callback` on every at-rule in conatiner and inside at-rules. | ||
// | ||
// First argument will be at-rule node, second will be index inside parent. | ||
// | ||
// css.eachAtRule( (atrule, parent, i) => { | ||
// if ( parent.type == 'atrule' ) { | ||
// console.log(atrule.name + ' in ' + atrule.parent.name); | ||
// } else { | ||
// console.log(atrule.name + ' at ' + i); | ||
// } | ||
// }); | ||
value: function (callback) { | ||
return this.eachInside(function (child, i) { | ||
if (child.type == "atrule") { | ||
var result = callback(child, i); | ||
if (result === false) return result; | ||
} | ||
}); | ||
Container.prototype.eachComment = function (callback) { | ||
return this.eachInside(function (child, i) { | ||
if (child.type == "comment") { | ||
var result = callback(child, i); | ||
if (result === false) return result; | ||
} | ||
}, | ||
eachComment: { | ||
writable: true, | ||
}); | ||
}; | ||
Container.prototype.append = function (child) { | ||
var childs = this.normalize(child, this.last); | ||
for (var i = 0; i < childs.length; i++) { | ||
this.childs.push(childs[i]); | ||
} | ||
return this; | ||
}; | ||
// Execute callback on every block comment (only between rules | ||
// and declarations, not inside selectors and values) in all rules inside. | ||
// | ||
// First argument will be comment node, second will be index inside | ||
// parent rule. | ||
// | ||
// css.eachComment( (comment, i) => { | ||
// console.log(comment.content + ' at ' + i); | ||
// }); | ||
// | ||
// Also as `each` it is safe of insert/remove nodes inside iterating. | ||
value: function (callback) { | ||
return this.eachInside(function (child, i) { | ||
if (child.type == "comment") { | ||
var result = callback(child, i); | ||
if (result === false) return result; | ||
} | ||
}); | ||
} | ||
}, | ||
append: { | ||
writable: true, | ||
Container.prototype.prepend = function (child) { | ||
var childs = this.normalize(child, this.first, "prepend").reverse(); | ||
for (var i = 0; i < childs.length; i++) { | ||
this.childs.unshift(childs[i]); | ||
} | ||
for (var id in this.indexes) { | ||
this.indexes[id] = this.indexes[id] + childs.length; | ||
} | ||
// Add child to container. | ||
// | ||
// css.append(rule); | ||
// | ||
// You can add declaration by hash: | ||
// | ||
// rule.append({ prop: 'color', value: 'black' }); | ||
value: function (child) { | ||
var childs = this.normalize(child, this.last); | ||
for (var i = 0; i < childs.length; i++) { | ||
this.childs.push(childs[i]); | ||
} | ||
return this; | ||
} | ||
}, | ||
prepend: { | ||
writable: true, | ||
return this; | ||
}; | ||
Container.prototype.insertBefore = function (exist, add) { | ||
exist = this.index(exist); | ||
// Add child to beginning of container | ||
// | ||
// css.prepend(rule); | ||
// | ||
// You can add declaration by hash: | ||
// | ||
// rule.prepend({ prop: 'color', value: 'black' }); | ||
value: function (child) { | ||
var childs = this.normalize(child, this.first, "prepend").reverse(); | ||
for (var i = 0; i < childs.length; i++) { | ||
this.childs.unshift(childs[i]); | ||
} | ||
var type = exist === 0 ? "prepend" : false; | ||
var childs = this.normalize(add, this.childs[exist], type).reverse(); | ||
for (var i = 0; i < childs.length; i++) { | ||
this.childs.splice(exist, 0, childs[i]); | ||
} | ||
for (var id in this.indexes) { | ||
this.indexes[id] = this.indexes[id] + childs.length; | ||
} | ||
return this; | ||
var index; | ||
for (var id in this.indexes) { | ||
index = this.indexes[id]; | ||
if (exist <= index) { | ||
this.indexes[id] = index + childs.length; | ||
} | ||
}, | ||
insertBefore: { | ||
writable: true, | ||
} | ||
return this; | ||
}; | ||
// Insert new `added` child before `exist`. | ||
// You can set node object or node index (it will be faster) in `exist`. | ||
// | ||
// css.insertAfter(1, rule); | ||
// | ||
// You can add declaration by hash: | ||
// | ||
// rule.insertBefore(1, { prop: 'color', value: 'black' }); | ||
value: function (exist, add) { | ||
exist = this.index(exist); | ||
Container.prototype.insertAfter = function (exist, add) { | ||
exist = this.index(exist); | ||
var type = exist === 0 ? "prepend" : false; | ||
var childs = this.normalize(add, this.childs[exist], type).reverse(); | ||
for (var i = 0; i < childs.length; i++) { | ||
this.childs.splice(exist, 0, childs[i]); | ||
} | ||
var childs = this.normalize(add, this.childs[exist]).reverse(); | ||
for (var i = 0; i < childs.length; i++) { | ||
this.childs.splice(exist + 1, 0, childs[i]); | ||
} | ||
var index; | ||
for (var id in this.indexes) { | ||
index = this.indexes[id]; | ||
if (exist <= index) { | ||
this.indexes[id] = index + childs.length; | ||
} | ||
} | ||
return this; | ||
var index; | ||
for (var id in this.indexes) { | ||
index = this.indexes[id]; | ||
if (exist < index) { | ||
this.indexes[id] = index + childs.length; | ||
} | ||
}, | ||
insertAfter: { | ||
writable: true, | ||
} | ||
return this; | ||
}; | ||
// Insert new `added` child after `exist`. | ||
// You can set node object or node index (it will be faster) in `exist`. | ||
// | ||
// css.insertAfter(1, rule); | ||
// | ||
// You can add declaration by hash: | ||
// | ||
// rule.insertAfter(1, { prop: 'color', value: 'black' }); | ||
value: function (exist, add) { | ||
exist = this.index(exist); | ||
Container.prototype.remove = function (child) { | ||
child = this.index(child); | ||
this.childs.splice(child, 1); | ||
var childs = this.normalize(add, this.childs[exist]).reverse(); | ||
for (var i = 0; i < childs.length; i++) { | ||
this.childs.splice(exist + 1, 0, childs[i]); | ||
} | ||
var index; | ||
for (var id in this.indexes) { | ||
index = this.indexes[id]; | ||
if (exist < index) { | ||
this.indexes[id] = index + childs.length; | ||
} | ||
} | ||
return this; | ||
var index; | ||
for (var id in this.indexes) { | ||
index = this.indexes[id]; | ||
if (index >= child) { | ||
this.indexes[id] = index - 1; | ||
} | ||
}, | ||
remove: { | ||
writable: true, | ||
} | ||
return this; | ||
}; | ||
// Remove `child` by index or node. | ||
// | ||
// css.remove(2); | ||
value: function (child) { | ||
child = this.index(child); | ||
this.childs.splice(child, 1); | ||
Container.prototype.every = function (condition) { | ||
return this.childs.every(condition); | ||
}; | ||
var index; | ||
for (var id in this.indexes) { | ||
index = this.indexes[id]; | ||
if (index >= child) { | ||
this.indexes[id] = index - 1; | ||
} | ||
} | ||
Container.prototype.some = function (condition) { | ||
return this.childs.some(condition); | ||
}; | ||
return this; | ||
} | ||
}, | ||
every: { | ||
writable: true, | ||
Container.prototype.index = function (child) { | ||
if (typeof (child) == "number") { | ||
return child; | ||
} else { | ||
return this.childs.indexOf(child); | ||
} | ||
}; | ||
Container.prototype.normalize = function (child, sample) { | ||
if (!child.type && !Array.isArray(child)) { | ||
child = new Declaration(child); | ||
} | ||
// Return true if all childs return true in `condition`. | ||
// Just shorcut for `childs.every`. | ||
value: function (condition) { | ||
return this.childs.every(condition); | ||
var childs; | ||
if (child.type == "root") { | ||
childs = child.childs; | ||
} else if (Array.isArray(child)) { | ||
childs = child.map(function (i) { | ||
return i.clone(); | ||
}); | ||
} else { | ||
if (child.parent) { | ||
child = child.clone(); | ||
} | ||
}, | ||
some: { | ||
writable: true, | ||
childs = [child]; | ||
} | ||
// Return true if one or more childs return true in `condition`. | ||
// Just shorcut for `childs.some`. | ||
value: function (condition) { | ||
return this.childs.some(condition); | ||
for (var i = 0; i < childs.length; i++) { | ||
child = childs[i]; | ||
child.parent = this; | ||
if (typeof (child.before) == "undefined" && sample) { | ||
child.before = sample.before; | ||
} | ||
}, | ||
index: { | ||
writable: true, | ||
} | ||
return childs; | ||
}; | ||
// Return index of child | ||
value: function (child) { | ||
if (typeof (child) == "number") { | ||
return child; | ||
} else { | ||
return this.childs.indexOf(child); | ||
} | ||
} | ||
}, | ||
_classProps(Container, null, { | ||
first: { | ||
@@ -439,37 +289,2 @@ // Shortcut to get first child | ||
} | ||
}, | ||
normalize: { | ||
writable: true, | ||
// Normalize child before insert. Copy before from `sample`. | ||
value: function (child, sample) { | ||
if (!child.type && !Array.isArray(child)) { | ||
child = new Declaration(child); | ||
} | ||
var childs; | ||
if (child.type == "root") { | ||
childs = child.childs; | ||
} else if (Array.isArray(child)) { | ||
childs = child.map(function (i) { | ||
return i.clone(); | ||
}); | ||
} else { | ||
if (child.parent) { | ||
child = child.clone(); | ||
} | ||
childs = [child]; | ||
} | ||
for (var i = 0; i < childs.length; i++) { | ||
child = childs[i]; | ||
child.parent = this; | ||
if (typeof (child.before) == "undefined" && sample) { | ||
child.before = sample.before; | ||
} | ||
} | ||
return childs; | ||
} | ||
} | ||
@@ -476,0 +291,0 @@ }); |
"use strict"; | ||
var _classProps = function (child, staticProps, instanceProps) { | ||
if (staticProps) Object.defineProperties(child, staticProps); | ||
if (instanceProps) Object.defineProperties(child.prototype, instanceProps); | ||
}; | ||
var _extends = function (child, parent) { | ||
@@ -66,46 +61,36 @@ child.prototype = Object.create(parent.prototype, { | ||
_classProps(CssSyntaxError, null, { | ||
highlight: { | ||
writable: true, | ||
CssSyntaxError.prototype.highlight = function (color) { | ||
var num = this.line - 1; | ||
var lines = this.source.split("\n"); | ||
var prev = num > 0 ? lines[num - 1] + "\n" : ""; | ||
var broken = lines[num]; | ||
var next = num < lines.length - 1 ? "\n" + lines[num + 1] : ""; | ||
// Return source of broken lines | ||
value: function (color) { | ||
var num = this.line - 1; | ||
var lines = this.source.split("\n"); | ||
var mark = "\n"; | ||
for (var i = 0; i < this.column - 1; i++) { | ||
mark += " "; | ||
} | ||
var prev = num > 0 ? lines[num - 1] + "\n" : ""; | ||
var broken = lines[num]; | ||
var next = num < lines.length - 1 ? "\n" + lines[num + 1] : ""; | ||
if (typeof (color) == "undefined" && typeof (process) != "undefined") { | ||
if (process.stdout && process.env) { | ||
color = process.stdout.isTTY && !process.env.NODE_DISABLE_COLORS; | ||
} | ||
} | ||
var mark = "\n"; | ||
for (var i = 0; i < this.column - 1; i++) { | ||
mark += " "; | ||
} | ||
if (color) { | ||
mark += "\u001b[1;31m^\u001b[0m"; | ||
} else { | ||
mark += "^"; | ||
} | ||
if (typeof (color) == "undefined" && typeof (process) != "undefined") { | ||
if (process.stdout && process.env) { | ||
color = process.stdout.isTTY && !process.env.NODE_DISABLE_COLORS; | ||
} | ||
} | ||
return prev + broken + mark + next; | ||
}; | ||
if (color) { | ||
mark += "\u001b[1;31m^\u001b[0m"; | ||
} else { | ||
mark += "^"; | ||
} | ||
CssSyntaxError.prototype.toString = function () { | ||
var text = this.message; | ||
if (this.source) text += "\n" + this.highlight(); | ||
return text; | ||
}; | ||
return prev + broken + mark + next; | ||
} | ||
}, | ||
toString: { | ||
writable: true, | ||
value: function () { | ||
var text = this.message; | ||
if (this.source) text += "\n" + this.highlight(); | ||
return text; | ||
} | ||
} | ||
}); | ||
return CssSyntaxError; | ||
@@ -112,0 +97,0 @@ })(SyntaxError); |
"use strict"; | ||
var _classProps = function (child, staticProps, instanceProps) { | ||
if (staticProps) Object.defineProperties(child, staticProps); | ||
if (instanceProps) Object.defineProperties(child.prototype, instanceProps); | ||
}; | ||
var _extends = function (child, parent) { | ||
@@ -32,48 +27,32 @@ child.prototype = Object.create(parent.prototype, { | ||
_classProps(Declaration, null, { | ||
styleMap: { | ||
writable: true, | ||
value: function () { | ||
return { | ||
beforeDecl: this.before, | ||
colon: this.between | ||
}; | ||
} | ||
}, | ||
stringify: { | ||
writable: true, | ||
Declaration.prototype.styleMap = function () { | ||
return { | ||
beforeDecl: this.before, | ||
colon: this.between | ||
}; | ||
}; | ||
Declaration.prototype.stringify = function (builder, semicolon) { | ||
var before = this.style("beforeDecl"); | ||
if (before) builder(before); | ||
// Stringify declaration | ||
value: function (builder, semicolon) { | ||
var before = this.style("beforeDecl"); | ||
if (before) builder(before); | ||
var between = this.style("colon"); | ||
var string = this.prop + between + this.stringifyRaw("value"); | ||
var between = this.style("colon"); | ||
var string = this.prop + between + this.stringifyRaw("value"); | ||
if (this.important) { | ||
string += this._important || " !important"; | ||
} | ||
if (this.important) { | ||
string += this._important || " !important"; | ||
} | ||
if (semicolon) string += ";"; | ||
builder(string, this); | ||
}; | ||
if (semicolon) string += ";"; | ||
builder(string, this); | ||
} | ||
}, | ||
clone: { | ||
writable: true, | ||
Declaration.prototype.clone = function (overrides) { | ||
if (overrides === undefined) overrides = {}; | ||
var cloned = Node.prototype.clone.call(this, overrides); | ||
delete cloned.before; | ||
delete cloned.between; | ||
return cloned; | ||
}; | ||
// Clean `before` and `between` property in clone to copy it from new | ||
// parent rule | ||
value: function (overrides) { | ||
if (overrides === undefined) overrides = {}; | ||
var cloned = Node.prototype.clone.call(this, overrides); | ||
delete cloned.before; | ||
delete cloned.between; | ||
return cloned; | ||
} | ||
} | ||
}); | ||
return Declaration; | ||
@@ -80,0 +59,0 @@ })(Node); |
"use strict"; | ||
var _classProps = function (child, staticProps, instanceProps) { | ||
if (staticProps) Object.defineProperties(child, staticProps); | ||
if (instanceProps) Object.defineProperties(child.prototype, instanceProps); | ||
}; | ||
var CssSyntaxError = require("./css-syntax-error"); | ||
@@ -50,47 +45,29 @@ var PreviousMap = require("./previous-map"); | ||
_classProps(Input, null, { | ||
error: { | ||
writable: true, | ||
Input.prototype.error = function (message, line, column) { | ||
throw new CssSyntaxError(this, message, line, column); | ||
}; | ||
Input.prototype.origin = function (line, column) { | ||
if (!this.map) return false; | ||
var consumer = this.map.consumer(); | ||
// Throw syntax error from this input | ||
value: function (message, line, column) { | ||
throw new CssSyntaxError(this, message, line, column); | ||
} | ||
}, | ||
origin: { | ||
writable: true, | ||
var from = consumer.originalPositionFor({ line: line, column: column }); | ||
if (!from.source) return false; | ||
var result = { | ||
file: this.mapResolve(from.source), | ||
line: from.line, | ||
column: from.column | ||
}; | ||
// Get origin position of code if source map was given | ||
value: function (line, column) { | ||
if (!this.map) return false; | ||
var consumer = this.map.consumer(); | ||
var source = consumer.sourceContentFor(result.file); | ||
if (source) result.source = source; | ||
var from = consumer.originalPositionFor({ line: line, column: column }); | ||
if (!from.source) return false; | ||
return result; | ||
}; | ||
var result = { | ||
file: this.mapResolve(from.source), | ||
line: from.line, | ||
column: from.column | ||
}; | ||
Input.prototype.mapResolve = function (file) { | ||
return path.resolve(this.map.consumer().sourceRoot || ".", file); | ||
}; | ||
var source = consumer.sourceContentFor(result.file); | ||
if (source) result.source = source; | ||
return result; | ||
} | ||
}, | ||
mapResolve: { | ||
writable: true, | ||
// Return path relative from source map root | ||
value: function (file) { | ||
return path.resolve(this.map.consumer().sourceRoot || ".", file); | ||
} | ||
} | ||
}); | ||
return Input; | ||
@@ -97,0 +74,0 @@ })(); |
"use strict"; | ||
var _classProps = function (child, staticProps, instanceProps) { | ||
if (staticProps) Object.defineProperties(child, staticProps); | ||
if (instanceProps) Object.defineProperties(child.prototype, instanceProps); | ||
}; | ||
var Result = require("./result"); | ||
@@ -22,319 +17,241 @@ | ||
_classProps(MapGenerator, null, { | ||
isMap: { | ||
writable: true, | ||
MapGenerator.prototype.isMap = function () { | ||
if (typeof (this.opts.map) != "undefined") { | ||
return !!this.opts.map; | ||
} else { | ||
return this.previous().length > 0; | ||
} | ||
}; | ||
// Should map be generated | ||
value: function () { | ||
if (typeof (this.opts.map) != "undefined") { | ||
return !!this.opts.map; | ||
} else { | ||
return this.previous().length > 0; | ||
MapGenerator.prototype.previous = function () { | ||
var _this = this; | ||
if (!this.previousMaps) { | ||
this.previousMaps = []; | ||
this.root.eachInside(function (node) { | ||
if (node.source && node.source.map) { | ||
if (_this.previousMaps.indexOf(node.source.map) == -1) { | ||
_this.previousMaps.push(node.source.map); | ||
} | ||
} | ||
} | ||
}, | ||
previous: { | ||
writable: true, | ||
}); | ||
} | ||
return this.previousMaps; | ||
}; | ||
// Return source map arrays from previous compilation step (like Sass) | ||
value: function () { | ||
var _this = this; | ||
if (!this.previousMaps) { | ||
this.previousMaps = []; | ||
this.root.eachInside(function (node) { | ||
if (node.source && node.source.map) { | ||
if (_this.previousMaps.indexOf(node.source.map) == -1) { | ||
_this.previousMaps.push(node.source.map); | ||
} | ||
} | ||
}); | ||
} | ||
MapGenerator.prototype.isInline = function () { | ||
if (typeof (this.mapOpts.inline) != "undefined") { | ||
return this.mapOpts.inline; | ||
} | ||
return this.previousMaps; | ||
} | ||
}, | ||
isInline: { | ||
writable: true, | ||
var annotation = this.mapOpts.annotation; | ||
if (typeof (annotation) != "undefined" && annotation !== true) { | ||
return false; | ||
} | ||
if (this.previous().length) { | ||
return this.previous().some(function (i) { | ||
return i.inline; | ||
}); | ||
} else { | ||
return true; | ||
} | ||
}; | ||
// Should we inline source map to annotation comment | ||
value: function () { | ||
if (typeof (this.mapOpts.inline) != "undefined") { | ||
return this.mapOpts.inline; | ||
} | ||
MapGenerator.prototype.isSourcesContent = function () { | ||
if (typeof (this.mapOpts.sourcesContent) != "undefined") { | ||
return this.mapOpts.sourcesContent; | ||
} | ||
if (this.previous().length) { | ||
return this.previous().some(function (i) { | ||
return i.withContent(); | ||
}); | ||
} else { | ||
return true; | ||
} | ||
}; | ||
var annotation = this.mapOpts.annotation; | ||
if (typeof (annotation) != "undefined" && annotation !== true) { | ||
return false; | ||
} | ||
MapGenerator.prototype.clearAnnotation = function () { | ||
if (this.mapOpts.annotation === false) return; | ||
if (this.previous().length) { | ||
return this.previous().some(function (i) { | ||
return i.inline; | ||
}); | ||
} else { | ||
return true; | ||
} | ||
var node; | ||
for (var i = this.root.childs.length - 1; i >= 0; i--) { | ||
node = this.root.childs[i]; | ||
if (node.type != "comment") continue; | ||
if (node.text.match(/^# sourceMappingURL=/)) { | ||
this.root.remove(i); | ||
return; | ||
} | ||
}, | ||
isSourcesContent: { | ||
writable: true, | ||
} | ||
}; | ||
// Should we set sourcesContent | ||
value: function () { | ||
if (typeof (this.mapOpts.sourcesContent) != "undefined") { | ||
return this.mapOpts.sourcesContent; | ||
MapGenerator.prototype.setSourcesContent = function () { | ||
var _this2 = this; | ||
var already = {}; | ||
this.root.eachInside(function (node) { | ||
if (node.source) { | ||
var file = node.source.file || node.source.id; | ||
if (file && !already[file]) { | ||
already[file] = true; | ||
var relative = _this2.relative(file); | ||
_this2.map.setSourceContent(relative, node.source.content); | ||
} | ||
if (this.previous().length) { | ||
return this.previous().some(function (i) { | ||
return i.withContent(); | ||
}); | ||
} else { | ||
return true; | ||
} | ||
} | ||
}, | ||
clearAnnotation: { | ||
writable: true, | ||
}); | ||
}; | ||
MapGenerator.prototype.applyPrevMaps = function () { | ||
var prev, previous = this.previous(); | ||
for (var i = 0; i < previous.length; i++) { | ||
prev = previous[i]; | ||
// Clear source map annotation comment | ||
value: function () { | ||
if (this.mapOpts.annotation === false) return; | ||
var from = this.relative(prev.file); | ||
var root = prev.root || path.dirname(prev.file); | ||
var map; | ||
var node; | ||
for (var i = this.root.childs.length - 1; i >= 0; i--) { | ||
node = this.root.childs[i]; | ||
if (node.type != "comment") continue; | ||
if (node.text.match(/^# sourceMappingURL=/)) { | ||
this.root.remove(i); | ||
return; | ||
} | ||
} | ||
} | ||
}, | ||
setSourcesContent: { | ||
writable: true, | ||
// Set origin CSS content | ||
value: function () { | ||
var _this2 = this; | ||
var already = {}; | ||
this.root.eachInside(function (node) { | ||
if (node.source) { | ||
var file = node.source.file || node.source.id; | ||
if (file && !already[file]) { | ||
already[file] = true; | ||
var relative = _this2.relative(file); | ||
_this2.map.setSourceContent(relative, node.source.content); | ||
} | ||
} | ||
if (this.mapOpts.sourcesContent === false) { | ||
map = new mozilla.SourceMapConsumer(prev.text); | ||
map.sourcesContent = map.sourcesContent.map(function (i) { | ||
return null; | ||
}); | ||
} else { | ||
map = prev.consumer(); | ||
} | ||
}, | ||
applyPrevMaps: { | ||
writable: true, | ||
this.map.applySourceMap(map, from, this.relative(root)); | ||
} | ||
}; | ||
// Apply source map from previous compilation step (like Sass) | ||
value: function () { | ||
var prev, previous = this.previous(); | ||
for (var i = 0; i < previous.length; i++) { | ||
prev = previous[i]; | ||
MapGenerator.prototype.isAnnotation = function () { | ||
if (this.isInline()) { | ||
return true; | ||
} else if (typeof (this.mapOpts.annotation) != "undefined") { | ||
return this.mapOpts.annotation; | ||
} else if (this.previous().length) { | ||
return this.previous().some(function (i) { | ||
return i.annotation; | ||
}); | ||
} else { | ||
return true; | ||
} | ||
}; | ||
var from = this.relative(prev.file); | ||
var root = prev.root || path.dirname(prev.file); | ||
var map; | ||
MapGenerator.prototype.addAnnotation = function () { | ||
var content; | ||
if (this.mapOpts.sourcesContent === false) { | ||
map = new mozilla.SourceMapConsumer(prev.text); | ||
map.sourcesContent = map.sourcesContent.map(function (i) { | ||
return null; | ||
}); | ||
} else { | ||
map = prev.consumer(); | ||
} | ||
if (this.isInline()) { | ||
content = "data:application/json;base64," + Base64.encode(this.map.toString()); | ||
} else if (typeof (this.mapOpts.annotation) == "string") { | ||
content = this.mapOpts.annotation; | ||
} else { | ||
content = this.outputFile() + ".map"; | ||
} | ||
this.map.applySourceMap(map, from, this.relative(root)); | ||
} | ||
} | ||
}, | ||
isAnnotation: { | ||
writable: true, | ||
this.css += "\n/*# sourceMappingURL=" + content + " */"; | ||
}; | ||
MapGenerator.prototype.outputFile = function () { | ||
if (this.opts.to) { | ||
return this.relative(this.opts.to); | ||
} else if (this.opts.from) { | ||
return this.relative(this.opts.from); | ||
} else { | ||
return "to.css"; | ||
} | ||
}; | ||
// Should we add annotation comment | ||
value: function () { | ||
if (this.isInline()) { | ||
return true; | ||
} else if (typeof (this.mapOpts.annotation) != "undefined") { | ||
return this.mapOpts.annotation; | ||
} else if (this.previous().length) { | ||
return this.previous().some(function (i) { | ||
return i.annotation; | ||
}); | ||
} else { | ||
return true; | ||
} | ||
} | ||
}, | ||
addAnnotation: { | ||
writable: true, | ||
MapGenerator.prototype.generateMap = function () { | ||
this.stringify(); | ||
if (this.isSourcesContent()) this.setSourcesContent(); | ||
if (this.previous().length > 0) this.applyPrevMaps(); | ||
if (this.isAnnotation()) this.addAnnotation(); | ||
if (this.isInline()) { | ||
return [this.css]; | ||
} else { | ||
return [this.css, this.map]; | ||
} | ||
}; | ||
// Add source map annotation comment if it is needed | ||
value: function () { | ||
var content; | ||
MapGenerator.prototype.relative = function (file) { | ||
var from = this.opts.to ? path.dirname(this.opts.to) : "."; | ||
if (this.isInline()) { | ||
content = "data:application/json;base64," + Base64.encode(this.map.toString()); | ||
} else if (typeof (this.mapOpts.annotation) == "string") { | ||
content = this.mapOpts.annotation; | ||
} else { | ||
content = this.outputFile() + ".map"; | ||
} | ||
if (typeof (this.mapOpts.annotation) == "string") { | ||
from = path.dirname(path.resolve(from, this.mapOpts.annotation)); | ||
} | ||
this.css += "\n/*# sourceMappingURL=" + content + " */"; | ||
} | ||
}, | ||
outputFile: { | ||
writable: true, | ||
file = path.relative(from, file); | ||
if (path.sep == "\\") { | ||
return file.replace(/\\/g, "/"); | ||
} else { | ||
return file; | ||
} | ||
}; | ||
MapGenerator.prototype.sourcePath = function (node) { | ||
return this.relative(node.source.file || node.source.id); | ||
}; | ||
// Return output CSS file path | ||
value: function () { | ||
if (this.opts.to) { | ||
return this.relative(this.opts.to); | ||
} else if (this.opts.from) { | ||
return this.relative(this.opts.from); | ||
} else { | ||
return "to.css"; | ||
} | ||
} | ||
}, | ||
generateMap: { | ||
writable: true, | ||
MapGenerator.prototype.stringify = function () { | ||
var _this3 = this; | ||
this.css = ""; | ||
this.map = new mozilla.SourceMapGenerator({ file: this.outputFile() }); | ||
var line = 1; | ||
var column = 1; | ||
// Return Result object with map | ||
value: function () { | ||
this.stringify(); | ||
if (this.isSourcesContent()) this.setSourcesContent(); | ||
if (this.previous().length > 0) this.applyPrevMaps(); | ||
if (this.isAnnotation()) this.addAnnotation(); | ||
var lines, last; | ||
var builder = function (str, node, type) { | ||
_this3.css += str; | ||
if (this.isInline()) { | ||
return [this.css]; | ||
} else { | ||
return [this.css, this.map]; | ||
} | ||
if (node && node.source && node.source.start && type != "end") { | ||
_this3.map.addMapping({ | ||
source: _this3.sourcePath(node), | ||
original: { | ||
line: node.source.start.line, | ||
column: node.source.start.column - 1 | ||
}, | ||
generated: { | ||
line: line, | ||
column: column - 1 | ||
} | ||
}); | ||
} | ||
}, | ||
relative: { | ||
writable: true, | ||
// Return path relative from output CSS file | ||
value: function (file) { | ||
var from = this.opts.to ? path.dirname(this.opts.to) : "."; | ||
if (typeof (this.mapOpts.annotation) == "string") { | ||
from = path.dirname(path.resolve(from, this.mapOpts.annotation)); | ||
} | ||
file = path.relative(from, file); | ||
if (path.sep == "\\") { | ||
return file.replace(/\\/g, "/"); | ||
} else { | ||
return file; | ||
} | ||
lines = str.match(/\n/g); | ||
if (lines) { | ||
line += lines.length; | ||
last = str.lastIndexOf("\n"); | ||
column = str.length - last; | ||
} else { | ||
column = column + str.length; | ||
} | ||
}, | ||
sourcePath: { | ||
writable: true, | ||
// Return path of node source for map | ||
value: function (node) { | ||
return this.relative(node.source.file || node.source.id); | ||
} | ||
}, | ||
stringify: { | ||
writable: true, | ||
// Return CSS string and source map | ||
value: function () { | ||
var _this3 = this; | ||
this.css = ""; | ||
this.map = new mozilla.SourceMapGenerator({ file: this.outputFile() }); | ||
var line = 1; | ||
var column = 1; | ||
var lines, last; | ||
var builder = function (str, node, type) { | ||
_this3.css += str; | ||
if (node && node.source && node.source.start && type != "end") { | ||
_this3.map.addMapping({ | ||
source: _this3.sourcePath(node), | ||
original: { | ||
line: node.source.start.line, | ||
column: node.source.start.column - 1 | ||
}, | ||
generated: { | ||
line: line, | ||
column: column - 1 | ||
} | ||
}); | ||
if (node && node.source && node.source.end && type != "start") { | ||
_this3.map.addMapping({ | ||
source: _this3.sourcePath(node), | ||
original: { | ||
line: node.source.end.line, | ||
column: node.source.end.column | ||
}, | ||
generated: { | ||
line: line, | ||
column: column | ||
} | ||
lines = str.match(/\n/g); | ||
if (lines) { | ||
line += lines.length; | ||
last = str.lastIndexOf("\n"); | ||
column = str.length - last; | ||
} else { | ||
column = column + str.length; | ||
} | ||
if (node && node.source && node.source.end && type != "start") { | ||
_this3.map.addMapping({ | ||
source: _this3.sourcePath(node), | ||
original: { | ||
line: node.source.end.line, | ||
column: node.source.end.column | ||
}, | ||
generated: { | ||
line: line, | ||
column: column | ||
} | ||
}); | ||
} | ||
}; | ||
this.root.stringify(builder); | ||
}); | ||
} | ||
}, | ||
generate: { | ||
writable: true, | ||
}; | ||
this.root.stringify(builder); | ||
}; | ||
// Return Result object with or without map | ||
value: function () { | ||
this.clearAnnotation(); | ||
MapGenerator.prototype.generate = function () { | ||
this.clearAnnotation(); | ||
if (this.isMap()) { | ||
return this.generateMap(); | ||
} else { | ||
return [this.root.toString()]; | ||
} | ||
} | ||
if (this.isMap()) { | ||
return this.generateMap(); | ||
} else { | ||
return [this.root.toString()]; | ||
} | ||
}); | ||
}; | ||
@@ -341,0 +258,0 @@ return MapGenerator; |
229
lib/node.js
"use strict"; | ||
var _classProps = function (child, staticProps, instanceProps) { | ||
if (staticProps) Object.defineProperties(child, staticProps); | ||
if (instanceProps) Object.defineProperties(child.prototype, instanceProps); | ||
}; | ||
// Recursivly clone objects | ||
@@ -42,161 +37,105 @@ var clone = function (obj, parent) { | ||
_classProps(Node, null, { | ||
removeSelf: { | ||
writable: true, | ||
Node.prototype.removeSelf = function () { | ||
if (this.parent) { | ||
this.parent.remove(this); | ||
} | ||
return this; | ||
}; | ||
Node.prototype.replace = function (nodes) { | ||
this.parent.insertBefore(this, nodes); | ||
this.parent.remove(this); | ||
return this; | ||
}; | ||
// Remove this node from parent | ||
// | ||
// decl.removeSelf(); | ||
// | ||
// Note, that removing by index is faster: | ||
// | ||
// rule.each( (decl, i) => rule.remove(i) ); | ||
value: function () { | ||
if (this.parent) { | ||
this.parent.remove(this); | ||
} | ||
return this; | ||
} | ||
}, | ||
replace: { | ||
writable: true, | ||
Node.prototype.toString = function () { | ||
var result = ""; | ||
var builder = function (str) { | ||
return result += str; | ||
}; | ||
this.stringify(builder); | ||
return result; | ||
}; | ||
Node.prototype.clone = function (overrides) { | ||
if (overrides === undefined) overrides = {}; | ||
var cloned = clone(this); | ||
for (var name in overrides) { | ||
cloned[name] = overrides[name]; | ||
} | ||
return cloned; | ||
}; | ||
// Shortcut to insert nodes before and remove self. | ||
// | ||
// importNode.replace( loadedRoot ); | ||
value: function (nodes) { | ||
this.parent.insertBefore(this, nodes); | ||
this.parent.remove(this); | ||
return this; | ||
} | ||
}, | ||
toString: { | ||
writable: true, | ||
Node.prototype.toJSON = function () { | ||
var fixed = {}; | ||
for (var name in this) { | ||
if (!this.hasOwnProperty(name)) continue; | ||
if (name == "parent") continue; | ||
var value = this[name]; | ||
// Return CSS string of current node | ||
// | ||
// decl.toString(); //=> " color: black" | ||
value: function () { | ||
var result = ""; | ||
var builder = function (str) { | ||
return result += str; | ||
}; | ||
this.stringify(builder); | ||
return result; | ||
if (value instanceof Array) { | ||
fixed[name] = value.map(function (i) { | ||
return (typeof (i) == "object" && i.toJSON) ? i.toJSON() : i; | ||
}); | ||
} else if (typeof (value) == "object" && value.toJSON) { | ||
fixed[name] = value.toJSON(); | ||
} else { | ||
fixed[name] = value; | ||
} | ||
}, | ||
clone: { | ||
writable: true, | ||
} | ||
return fixed; | ||
}; | ||
// Clone current node | ||
// | ||
// rule.append( decl.clone() ); | ||
// | ||
// You can override properties while cloning: | ||
// | ||
// rule.append( decl.clone({ value: '0' }) ); | ||
value: function (overrides) { | ||
if (overrides === undefined) overrides = {}; | ||
var cloned = clone(this); | ||
for (var name in overrides) { | ||
cloned[name] = overrides[name]; | ||
} | ||
return cloned; | ||
} | ||
}, | ||
toJSON: { | ||
writable: true, | ||
Node.prototype.styleMap = function () { | ||
return {}; | ||
}; | ||
Node.prototype.style = function (name) { | ||
// Already had | ||
var value = this.styleMap()[name]; | ||
if (typeof (value) != "undefined") return value; | ||
// Remove `parent` node on cloning to fix circular structures | ||
value: function () { | ||
var fixed = {}; | ||
var parent = this.parent; | ||
for (var name in this) { | ||
if (!this.hasOwnProperty(name)) continue; | ||
if (name == "parent") continue; | ||
var value = this[name]; | ||
// Hack for first rule in CSS | ||
if (!parent && (name == "beforeRule" || name == "beforeDecl")) { | ||
return ""; | ||
} | ||
if (name == "beforeRule" && !parent.parent && parent.first == this) { | ||
return ""; | ||
} | ||
if (value instanceof Array) { | ||
fixed[name] = value.map(function (i) { | ||
return (typeof (i) == "object" && i.toJSON) ? i.toJSON() : i; | ||
}); | ||
} else if (typeof (value) == "object" && value.toJSON) { | ||
fixed[name] = value.toJSON(); | ||
} else { | ||
fixed[name] = value; | ||
} | ||
} | ||
// Floating child without parent | ||
if (!parent) return this.defaultStyle[name]; | ||
return fixed; | ||
} | ||
}, | ||
styleMap: { | ||
writable: true, | ||
value: function () { | ||
return {}; | ||
} | ||
}, | ||
style: { | ||
writable: true, | ||
// Detect style by other nodes | ||
var root = parent; | ||
while (root.parent) root = root.parent; | ||
if (!root.styleCache) root.styleCache = {}; | ||
if (typeof (root.styleCache[name]) != "undefined") { | ||
return root.styleCache[name]; | ||
} | ||
// Copy code style from first node with same type | ||
value: function (name) { | ||
// Already had | ||
var value = this.styleMap()[name]; | ||
if (typeof (value) != "undefined") return value; | ||
root.eachInside(function (other) { | ||
value = other.styleMap()[name]; | ||
if (typeof (value) != "undefined") return false; | ||
}); | ||
if (typeof (value) == "undefined") value = this.defaultStyle[name]; | ||
var parent = this.parent; | ||
root.styleCache[name] = value; | ||
return value; | ||
}; | ||
// Hack for first rule in CSS | ||
if (!parent && (name == "beforeRule" || name == "beforeDecl")) { | ||
return ""; | ||
} | ||
if (name == "beforeRule" && !parent.parent && parent.first == this) { | ||
return ""; | ||
} | ||
// Floating child without parent | ||
if (!parent) return this.defaultStyle[name]; | ||
// Detect style by other nodes | ||
var root = parent; | ||
while (root.parent) root = root.parent; | ||
if (!root.styleCache) root.styleCache = {}; | ||
if (typeof (root.styleCache[name]) != "undefined") { | ||
return root.styleCache[name]; | ||
} | ||
root.eachInside(function (other) { | ||
value = other.styleMap()[name]; | ||
if (typeof (value) != "undefined") return false; | ||
}); | ||
if (typeof (value) == "undefined") value = this.defaultStyle[name]; | ||
root.styleCache[name] = value; | ||
return value; | ||
} | ||
}, | ||
stringifyRaw: { | ||
writable: true, | ||
// Use raw value if origin was not changed | ||
value: function (prop) { | ||
var value = this[prop]; | ||
var raw = this["_" + prop]; | ||
if (raw && raw.value === value) { | ||
return raw.raw; | ||
} else { | ||
return value; | ||
} | ||
} | ||
Node.prototype.stringifyRaw = function (prop) { | ||
var value = this[prop]; | ||
var raw = this["_" + prop]; | ||
if (raw && raw.value === value) { | ||
return raw.raw; | ||
} else { | ||
return value; | ||
} | ||
}); | ||
}; | ||
@@ -203,0 +142,0 @@ return Node; |
"use strict"; | ||
var _classProps = function (child, staticProps, instanceProps) { | ||
if (staticProps) Object.defineProperties(child, staticProps); | ||
if (instanceProps) Object.defineProperties(child.prototype, instanceProps); | ||
}; | ||
var Declaration = require("./declaration"); | ||
@@ -29,474 +24,442 @@ var tokenize = require("./tokenize"); | ||
_classProps(Parser, null, { | ||
tokenize: { | ||
writable: true, | ||
value: function () { | ||
this.tokens = tokenize(this.input); | ||
} | ||
}, | ||
loop: { | ||
writable: true, | ||
value: function () { | ||
var token; | ||
while (this.pos < this.tokens.length) { | ||
token = this.tokens[this.pos]; | ||
Parser.prototype.tokenize = function () { | ||
this.tokens = tokenize(this.input); | ||
}; | ||
switch (token[0]) { | ||
case "word": | ||
case ":": | ||
this.word(token); | ||
break; | ||
Parser.prototype.loop = function () { | ||
var token; | ||
while (this.pos < this.tokens.length) { | ||
token = this.tokens[this.pos]; | ||
case "}": | ||
this.end(token); | ||
break; | ||
switch (token[0]) { | ||
case "word": | ||
case ":": | ||
this.word(token); | ||
break; | ||
case "comment": | ||
this.comment(token); | ||
break; | ||
case "}": | ||
this.end(token); | ||
break; | ||
case "at-word": | ||
this.atrule(token); | ||
break; | ||
case "comment": | ||
this.comment(token); | ||
break; | ||
case "{": | ||
this.emptyRule(token); | ||
break; | ||
case "at-word": | ||
this.atrule(token); | ||
break; | ||
default: | ||
this.spaces += token[1]; | ||
break; | ||
} | ||
case "{": | ||
this.emptyRule(token); | ||
break; | ||
this.pos += 1; | ||
} | ||
this.endFile(); | ||
default: | ||
this.spaces += token[1]; | ||
break; | ||
} | ||
}, | ||
comment: { | ||
writable: true, | ||
value: function (token) { | ||
var node = new Comment(); | ||
this.init(node, token[2], token[3]); | ||
node.source.end = { line: token[4], column: token[5] }; | ||
var text = token[1].slice(2, -2); | ||
if (text.match(/^\s*$/)) { | ||
node.left = text; | ||
node.text = ""; | ||
node.right = ""; | ||
} else { | ||
var match = text.match(/^(\s*)([^]*[^\s])(\s*)$/); | ||
node.left = match[1]; | ||
node.text = match[2]; | ||
node.right = match[3]; | ||
} | ||
} | ||
}, | ||
emptyRule: { | ||
writable: true, | ||
value: function (token) { | ||
var node = new Rule(); | ||
this.init(node, token[2], token[3]); | ||
node.between = ""; | ||
node.selector = ""; | ||
this.current = node; | ||
} | ||
}, | ||
word: { | ||
writable: true, | ||
value: function () { | ||
var token; | ||
var end = false; | ||
var type = null; | ||
var colon = false; | ||
var bracket = null; | ||
var brackets = 0; | ||
this.pos += 1; | ||
} | ||
this.endFile(); | ||
}; | ||
var start = this.pos; | ||
this.pos += 1; | ||
while (true) { | ||
token = this.tokens[this.pos]; | ||
if (!token) { | ||
this.pos -= 1; | ||
end = true; | ||
break; | ||
} | ||
Parser.prototype.comment = function (token) { | ||
var node = new Comment(); | ||
this.init(node, token[2], token[3]); | ||
node.source.end = { line: token[4], column: token[5] }; | ||
type = token[0]; | ||
if (type == "(") { | ||
if (!bracket) bracket = token; | ||
brackets += 1; | ||
} else if (type == ")") { | ||
brackets -= 1; | ||
if (brackets === 0) bracket = null; | ||
} else if (brackets === 0) { | ||
if (type == ";") { | ||
if (colon) { | ||
this.decl(this.tokens.slice(start, this.pos + 1)); | ||
return; | ||
} else { | ||
break; | ||
} | ||
} else if (type == "{") { | ||
this.rule(this.tokens.slice(start, this.pos + 1)); | ||
return; | ||
} else if (type == "}") { | ||
this.pos -= 1; | ||
end = true; | ||
break; | ||
} else if (type == "at-word") { | ||
this.pos -= 1; | ||
break; | ||
} else { | ||
if (type == ":") colon = true; | ||
} | ||
} | ||
var text = token[1].slice(2, -2); | ||
if (text.match(/^\s*$/)) { | ||
node.left = text; | ||
node.text = ""; | ||
node.right = ""; | ||
} else { | ||
var match = text.match(/^(\s*)([^]*[^\s])(\s*)$/); | ||
node.left = match[1]; | ||
node.text = match[2]; | ||
node.right = match[3]; | ||
} | ||
}; | ||
this.pos += 1; | ||
} | ||
Parser.prototype.emptyRule = function (token) { | ||
var node = new Rule(); | ||
this.init(node, token[2], token[3]); | ||
node.between = ""; | ||
node.selector = ""; | ||
this.current = node; | ||
}; | ||
if (brackets > 0 && !this.input.safe) { | ||
this.input.error("Unclosed bracket", bracket[2], bracket[3]); | ||
} | ||
Parser.prototype.word = function () { | ||
var token; | ||
var end = false; | ||
var type = null; | ||
var colon = false; | ||
var bracket = null; | ||
var brackets = 0; | ||
if (end && colon) { | ||
while (this.pos > start) { | ||
token = this.tokens[this.pos][0]; | ||
if (token != "space" && token != "comment") break; | ||
this.pos -= 1; | ||
var start = this.pos; | ||
this.pos += 1; | ||
while (true) { | ||
token = this.tokens[this.pos]; | ||
if (!token) { | ||
this.pos -= 1; | ||
end = true; | ||
break; | ||
} | ||
type = token[0]; | ||
if (type == "(") { | ||
if (!bracket) bracket = token; | ||
brackets += 1; | ||
} else if (type == ")") { | ||
brackets -= 1; | ||
if (brackets === 0) bracket = null; | ||
} else if (brackets === 0) { | ||
if (type == ";") { | ||
if (colon) { | ||
this.decl(this.tokens.slice(start, this.pos + 1)); | ||
return; | ||
} else { | ||
break; | ||
} | ||
this.decl(this.tokens.slice(start, this.pos + 1)); | ||
} else if (type == "{") { | ||
this.rule(this.tokens.slice(start, this.pos + 1)); | ||
return; | ||
} | ||
if (this.input.safe) { | ||
var buffer = this.tokens.slice(start, this.pos + 1); | ||
this.spaces += buffer.map(function (i) { | ||
return i[1]; | ||
}).join(""); | ||
} else if (type == "}") { | ||
this.pos -= 1; | ||
end = true; | ||
break; | ||
} else if (type == "at-word") { | ||
this.pos -= 1; | ||
break; | ||
} else { | ||
token = this.tokens[start]; | ||
this.input.error("Unknown word", token[2], token[3]); | ||
if (type == ":") colon = true; | ||
} | ||
} | ||
}, | ||
rule: { | ||
writable: true, | ||
value: function (tokens) { | ||
tokens.pop(); | ||
var node = new Rule(); | ||
this.init(node, tokens[0][2], tokens[0][3]); | ||
this.pos += 1; | ||
} | ||
node.between = this.spacesFromEnd(tokens); | ||
this.raw(node, "selector", tokens); | ||
this.current = node; | ||
if (brackets > 0 && !this.input.safe) { | ||
this.input.error("Unclosed bracket", bracket[2], bracket[3]); | ||
} | ||
if (end && colon) { | ||
while (this.pos > start) { | ||
token = this.tokens[this.pos][0]; | ||
if (token != "space" && token != "comment") break; | ||
this.pos -= 1; | ||
} | ||
}, | ||
decl: { | ||
writable: true, | ||
value: function (tokens) { | ||
var node = new Declaration(); | ||
this.init(node); | ||
this.decl(this.tokens.slice(start, this.pos + 1)); | ||
return; | ||
} | ||
var last = tokens[tokens.length - 1]; | ||
if (last[0] == ";") { | ||
this.semicolon = true; | ||
tokens.pop(); | ||
} | ||
if (last[4]) { | ||
node.source.end = { line: last[4], column: last[5] }; | ||
} else { | ||
node.source.end = { line: last[2], column: last[3] }; | ||
} | ||
if (this.input.safe) { | ||
var buffer = this.tokens.slice(start, this.pos + 1); | ||
this.spaces += buffer.map(function (i) { | ||
return i[1]; | ||
}).join(""); | ||
} else { | ||
token = this.tokens[start]; | ||
this.input.error("Unknown word", token[2], token[3]); | ||
} | ||
}; | ||
while (tokens[0][0] != "word") { | ||
node.before += tokens.shift()[1]; | ||
} | ||
node.source.start = { line: tokens[0][2], column: tokens[0][3] }; | ||
Parser.prototype.rule = function (tokens) { | ||
tokens.pop(); | ||
node.prop = tokens.shift()[1]; | ||
node.between = ""; | ||
var node = new Rule(); | ||
this.init(node, tokens[0][2], tokens[0][3]); | ||
var token; | ||
while (tokens.length) { | ||
token = tokens.shift(); | ||
node.between = this.spacesFromEnd(tokens); | ||
this.raw(node, "selector", tokens); | ||
this.current = node; | ||
}; | ||
if (token[0] == ":") { | ||
node.between += token[1]; | ||
break; | ||
} else if (token[0] != "space" && token[0] != "comment") { | ||
this.unknownWord(node, token, tokens); | ||
} else { | ||
node.between += token[1]; | ||
} | ||
} | ||
Parser.prototype.decl = function (tokens) { | ||
var node = new Declaration(); | ||
this.init(node); | ||
if (node.prop[0] == "_" || node.prop[0] == "*") { | ||
node.before += node.prop[0]; | ||
node.prop = node.prop.slice(1); | ||
} | ||
node.between += this.spacesFromStart(tokens); | ||
var last = tokens[tokens.length - 1]; | ||
if (last[0] == ";") { | ||
this.semicolon = true; | ||
tokens.pop(); | ||
} | ||
if (last[4]) { | ||
node.source.end = { line: last[4], column: last[5] }; | ||
} else { | ||
node.source.end = { line: last[2], column: last[3] }; | ||
} | ||
if (this.input.safe) this.checkMissedSemicolon(tokens); | ||
while (tokens[0][0] != "word") { | ||
node.before += tokens.shift()[1]; | ||
} | ||
node.source.start = { line: tokens[0][2], column: tokens[0][3] }; | ||
for (var i = tokens.length - 1; i > 0; i--) { | ||
token = tokens[i]; | ||
if (token[1] == "!important") { | ||
node.important = true; | ||
var string = this.stringFrom(tokens, i); | ||
string = this.spacesFromEnd(tokens) + string; | ||
if (string != " !important") node._important = string; | ||
break; | ||
} else if (token[0] != "space" && token[0] != "comment") { | ||
break; | ||
} | ||
} | ||
node.prop = tokens.shift()[1]; | ||
node.between = ""; | ||
this.raw(node, "value", tokens); | ||
var token; | ||
while (tokens.length) { | ||
token = tokens.shift(); | ||
if (node.value.indexOf(":") != -1 && !this.input.safe) { | ||
this.checkMissedSemicolon(tokens); | ||
} | ||
if (token[0] == ":") { | ||
node.between += token[1]; | ||
break; | ||
} else if (token[0] != "space" && token[0] != "comment") { | ||
this.unknownWord(node, token, tokens); | ||
} else { | ||
node.between += token[1]; | ||
} | ||
}, | ||
atrule: { | ||
writable: true, | ||
value: function (token) { | ||
var node = new AtRule(); | ||
node.name = token[1].slice(1); | ||
if (node.name === "") { | ||
if (this.input.safe) { | ||
node.name = ""; | ||
} else { | ||
this.input.error("At-rule without name", token[2], token[3]); | ||
} | ||
} | ||
this.init(node, token[2], token[3]); | ||
} | ||
var next; | ||
var last = false; | ||
var open = false; | ||
var params = []; | ||
while (true) { | ||
this.pos += 1; | ||
token = this.tokens[this.pos]; | ||
if (node.prop[0] == "_" || node.prop[0] == "*") { | ||
node.before += node.prop[0]; | ||
node.prop = node.prop.slice(1); | ||
} | ||
node.between += this.spacesFromStart(tokens); | ||
if (!token) { | ||
last = true; | ||
break; | ||
} else if (token[0] == ";") { | ||
node.source.end = { line: token[2], column: token[3] }; | ||
this.semicolon = true; | ||
break; | ||
} else if (token[0] == "{") { | ||
open = true; | ||
break; | ||
} else { | ||
params.push(token); | ||
} | ||
} | ||
if (this.input.safe) this.checkMissedSemicolon(tokens); | ||
node.between = this.spacesFromEnd(params); | ||
if (params.length) { | ||
node.afterName = this.spacesFromStart(params); | ||
this.raw(node, "params", params); | ||
if (last) { | ||
token = params[params.length - 1]; | ||
node.source.end = { line: token[4], column: token[5] }; | ||
this.spaces = node.between; | ||
node.between = ""; | ||
} | ||
} else { | ||
node.afterName = ""; | ||
node.params = ""; | ||
} | ||
if (open) { | ||
node.childs = []; | ||
this.current = node; | ||
} | ||
for (var i = tokens.length - 1; i > 0; i--) { | ||
token = tokens[i]; | ||
if (token[1] == "!important") { | ||
node.important = true; | ||
var string = this.stringFrom(tokens, i); | ||
string = this.spacesFromEnd(tokens) + string; | ||
if (string != " !important") node._important = string; | ||
break; | ||
} else if (token[0] != "space" && token[0] != "comment") { | ||
break; | ||
} | ||
}, | ||
end: { | ||
writable: true, | ||
value: function (token) { | ||
if (this.semicolon) { | ||
this.current.semicolon = true; | ||
this.semicolon = false; | ||
} | ||
this.current.after = (this.current.after || "") + this.spaces; | ||
this.spaces = ""; | ||
} | ||
if (this.current.parent) { | ||
this.current.source.end = { line: token[2], column: token[3] }; | ||
this.current = this.current.parent; | ||
} else if (!this.input.safe) { | ||
this.input.error("Unexpected }", token[2], token[3]); | ||
} else { | ||
this.current.after += "}"; | ||
} | ||
this.raw(node, "value", tokens); | ||
if (node.value.indexOf(":") != -1 && !this.input.safe) { | ||
this.checkMissedSemicolon(tokens); | ||
} | ||
}; | ||
Parser.prototype.atrule = function (token) { | ||
var node = new AtRule(); | ||
node.name = token[1].slice(1); | ||
if (node.name === "") { | ||
if (this.input.safe) { | ||
node.name = ""; | ||
} else { | ||
this.input.error("At-rule without name", token[2], token[3]); | ||
} | ||
}, | ||
endFile: { | ||
writable: true, | ||
value: function () { | ||
if (this.current.parent && !this.input.safe) { | ||
var pos = this.current.source.start; | ||
this.input.error("Unclosed block", pos.line, pos.column); | ||
} | ||
} | ||
this.init(node, token[2], token[3]); | ||
if (this.semicolon) this.current.semicolon = true; | ||
this.current.after = (this.current.after || "") + this.spaces; | ||
var next; | ||
var last = false; | ||
var open = false; | ||
var params = []; | ||
while (true) { | ||
this.pos += 1; | ||
token = this.tokens[this.pos]; | ||
while (this.current.parent) { | ||
this.current = this.current.parent; | ||
this.current.after = ""; | ||
} | ||
if (!token) { | ||
last = true; | ||
break; | ||
} else if (token[0] == ";") { | ||
node.source.end = { line: token[2], column: token[3] }; | ||
this.semicolon = true; | ||
break; | ||
} else if (token[0] == "{") { | ||
open = true; | ||
break; | ||
} else { | ||
params.push(token); | ||
} | ||
}, | ||
unknownWord: { | ||
writable: true, | ||
value: function (node, token) { | ||
if (this.input.safe) { | ||
node.source.start = { line: token[2], column: token[3] }; | ||
node.before += node.prop + node.between; | ||
node.prop = token[1]; | ||
node.between = ""; | ||
} else { | ||
this.input.error("Unknown word", token[2], token[3]); | ||
} | ||
} | ||
node.between = this.spacesFromEnd(params); | ||
if (params.length) { | ||
node.afterName = this.spacesFromStart(params); | ||
this.raw(node, "params", params); | ||
if (last) { | ||
token = params[params.length - 1]; | ||
node.source.end = { line: token[4], column: token[5] }; | ||
this.spaces = node.between; | ||
node.between = ""; | ||
} | ||
}, | ||
checkMissedSemicolon: { | ||
writable: true, | ||
value: function (tokens) { | ||
var colon = false; | ||
var brackets = 0; | ||
for (var i = 0; i < tokens.length; i++) { | ||
token = tokens[i][0]; | ||
if (token == "(") { | ||
brackets += 1; | ||
} else if (token == ")") { | ||
brackets -= 0; | ||
} else if (i > 1 && brackets === 0 && token == ":") { | ||
colon = i; | ||
break; | ||
} | ||
} | ||
} else { | ||
node.afterName = ""; | ||
node.params = ""; | ||
} | ||
if (colon === false) return; | ||
if (open) { | ||
node.childs = []; | ||
this.current = node; | ||
} | ||
}; | ||
if (this.input.safe) { | ||
var split; | ||
for (split = colon - 1; split >= 0; split--) { | ||
if (tokens[split][0] == "word") break; | ||
} | ||
for (split -= 1; split >= 0; split--) { | ||
if (tokens[split][0] != "space") { | ||
split += 1; | ||
break; | ||
} | ||
} | ||
var other = tokens.splice(split, tokens.length - split); | ||
this.decl(other); | ||
} else { | ||
var token; | ||
var founded = 0; | ||
for (var j = colon - 1; j >= 0; j--) { | ||
token = tokens[j]; | ||
if (token[0] != "space") { | ||
founded += 1; | ||
if (founded == 2) break; | ||
} | ||
} | ||
this.input.error("Missed semicolon", token[4], token[5]); | ||
} | ||
} | ||
}, | ||
init: { | ||
writable: true, | ||
Parser.prototype.end = function (token) { | ||
if (this.semicolon) { | ||
this.current.semicolon = true; | ||
this.semicolon = false; | ||
} | ||
this.current.after = (this.current.after || "") + this.spaces; | ||
this.spaces = ""; | ||
if (this.current.parent) { | ||
this.current.source.end = { line: token[2], column: token[3] }; | ||
this.current = this.current.parent; | ||
} else if (!this.input.safe) { | ||
this.input.error("Unexpected }", token[2], token[3]); | ||
} else { | ||
this.current.after += "}"; | ||
} | ||
}; | ||
// Helpers | ||
Parser.prototype.endFile = function () { | ||
if (this.current.parent && !this.input.safe) { | ||
var pos = this.current.source.start; | ||
this.input.error("Unclosed block", pos.line, pos.column); | ||
} | ||
value: function (node, line, column) { | ||
this.current.push(node); | ||
if (this.semicolon) this.current.semicolon = true; | ||
this.current.after = (this.current.after || "") + this.spaces; | ||
node.source = { start: { line: line, column: column }, content: this.input.css }; | ||
if (this.input.map) node.source.map = this.input.map; | ||
if (this.input.file) { | ||
node.source.file = this.input.file; | ||
while (this.current.parent) { | ||
this.current = this.current.parent; | ||
this.current.after = ""; | ||
} | ||
}; | ||
Parser.prototype.unknownWord = function (node, token) { | ||
if (this.input.safe) { | ||
node.source.start = { line: token[2], column: token[3] }; | ||
node.before += node.prop + node.between; | ||
node.prop = token[1]; | ||
node.between = ""; | ||
} else { | ||
this.input.error("Unknown word", token[2], token[3]); | ||
} | ||
}; | ||
Parser.prototype.checkMissedSemicolon = function (tokens) { | ||
var prev = null; | ||
var colon = false; | ||
var brackets = 0; | ||
var type, token; | ||
for (var i = 0; i < tokens.length; i++) { | ||
token = tokens[i]; | ||
type = token[0]; | ||
if (type == "(") { | ||
brackets += 1; | ||
} else if (type == ")") { | ||
brackets -= 0; | ||
} else if (brackets === 0 && type == ":") { | ||
if (prev[0] == "word" && prev[1] == "progid") { | ||
continue; | ||
} else { | ||
node.source.id = this.input.id; | ||
colon = i; | ||
break; | ||
} | ||
} | ||
node.before = this.spaces; | ||
this.spaces = ""; | ||
if (node.type != "comment") this.semicolon = false; | ||
prev = token; | ||
} | ||
if (colon === false) return; | ||
if (this.input.safe) { | ||
var split; | ||
for (split = colon - 1; split >= 0; split--) { | ||
if (tokens[split][0] == "word") break; | ||
} | ||
}, | ||
raw: { | ||
writable: true, | ||
value: function (node, prop, tokens) { | ||
var i; | ||
var value = ""; | ||
var clean = true; | ||
for (i = 0; i < tokens.length; i++) { | ||
if (tokens[i][0] == "comment") { | ||
clean = false; | ||
} else { | ||
value += tokens[i][1]; | ||
} | ||
for (split -= 1; split >= 0; split--) { | ||
if (tokens[split][0] != "space") { | ||
split += 1; | ||
break; | ||
} | ||
if (!clean) { | ||
var origin = ""; | ||
for (i = 0; i < tokens.length; i++) { | ||
origin += tokens[i][1]; | ||
} | ||
node["_" + prop] = { value: value, raw: origin }; | ||
} | ||
node[prop] = value; | ||
} | ||
}, | ||
spacesFromEnd: { | ||
writable: true, | ||
value: function (tokens) { | ||
var next; | ||
var spaces = ""; | ||
while (tokens.length) { | ||
next = tokens[tokens.length - 1][0]; | ||
if (next != "space" && next != "comment") break; | ||
spaces += tokens.pop()[1]; | ||
var other = tokens.splice(split, tokens.length - split); | ||
this.decl(other); | ||
} else { | ||
var founded = 0; | ||
for (var j = colon - 1; j >= 0; j--) { | ||
token = tokens[j]; | ||
if (token[0] != "space") { | ||
founded += 1; | ||
if (founded == 2) break; | ||
} | ||
return spaces; | ||
} | ||
}, | ||
spacesFromStart: { | ||
writable: true, | ||
value: function (tokens) { | ||
var next; | ||
var spaces = ""; | ||
while (tokens.length) { | ||
next = tokens[0][0]; | ||
if (next != "space" && next != "comment") break; | ||
spaces += tokens.shift()[1]; | ||
} | ||
return spaces; | ||
this.input.error("Missed semicolon", token[4], token[5]); | ||
} | ||
}; | ||
Parser.prototype.init = function (node, line, column) { | ||
this.current.push(node); | ||
node.source = { start: { line: line, column: column }, content: this.input.css }; | ||
if (this.input.map) node.source.map = this.input.map; | ||
if (this.input.file) { | ||
node.source.file = this.input.file; | ||
} else { | ||
node.source.id = this.input.id; | ||
} | ||
node.before = this.spaces; | ||
this.spaces = ""; | ||
if (node.type != "comment") this.semicolon = false; | ||
}; | ||
Parser.prototype.raw = function (node, prop, tokens) { | ||
var i; | ||
var value = ""; | ||
var clean = true; | ||
for (i = 0; i < tokens.length; i++) { | ||
if (tokens[i][0] == "comment") { | ||
clean = false; | ||
} else { | ||
value += tokens[i][1]; | ||
} | ||
}, | ||
stringFrom: { | ||
writable: true, | ||
value: function (tokens, from) { | ||
var result = ""; | ||
for (var i = from; i < tokens.length; i++) { | ||
result += tokens[i][1]; | ||
} | ||
tokens.splice(from, tokens.length - from); | ||
return result; | ||
} | ||
if (!clean) { | ||
var origin = ""; | ||
for (i = 0; i < tokens.length; i++) { | ||
origin += tokens[i][1]; | ||
} | ||
node["_" + prop] = { value: value, raw: origin }; | ||
} | ||
}); | ||
node[prop] = value; | ||
}; | ||
Parser.prototype.spacesFromEnd = function (tokens) { | ||
var next; | ||
var spaces = ""; | ||
while (tokens.length) { | ||
next = tokens[tokens.length - 1][0]; | ||
if (next != "space" && next != "comment") break; | ||
spaces += tokens.pop()[1]; | ||
} | ||
return spaces; | ||
}; | ||
Parser.prototype.spacesFromStart = function (tokens) { | ||
var next; | ||
var spaces = ""; | ||
while (tokens.length) { | ||
next = tokens[0][0]; | ||
if (next != "space" && next != "comment") break; | ||
spaces += tokens.shift()[1]; | ||
} | ||
return spaces; | ||
}; | ||
Parser.prototype.stringFrom = function (tokens, from) { | ||
var result = ""; | ||
for (var i = from; i < tokens.length; i++) { | ||
result += tokens[i][1]; | ||
} | ||
tokens.splice(from, tokens.length - from); | ||
return result; | ||
}; | ||
return Parser; | ||
@@ -503,0 +466,0 @@ })(); |
"use strict"; | ||
var _slice = Array.prototype.slice; | ||
var _classProps = function (child, staticProps, instanceProps) { | ||
if (staticProps) Object.defineProperties(child, staticProps); | ||
if (instanceProps) Object.defineProperties(child.prototype, instanceProps); | ||
}; | ||
var Declaration = require("./declaration"); | ||
@@ -26,65 +21,47 @@ var Comment = require("./comment"); | ||
_classProps(PostCSS, null, { | ||
use: { | ||
writable: true, | ||
PostCSS.prototype.use = function (plugin) { | ||
plugin = this.normalize(plugin); | ||
if (typeof (plugin) == "object" && Array.isArray(plugin.processors)) { | ||
this.processors = this.processors.concat(plugin.processors); | ||
} else { | ||
this.processors.push(plugin); | ||
} | ||
return this; | ||
}; | ||
PostCSS.prototype.process = function (css, opts) { | ||
if (opts === undefined) opts = {}; | ||
if (opts.map == "inline") { | ||
opts.map = { inline: true }; | ||
console.warn("Shortcut map: \"inline\" is deprecated " + "and will be remove in 3.1"); | ||
} | ||
// Add another function to CSS processors | ||
value: function (processor) { | ||
processor = this.normalize(processor); | ||
if (processor instanceof PostCSS) { | ||
this.processors = this.processors.concat(processor.processors); | ||
} else { | ||
this.processors.push(processor); | ||
} | ||
return this; | ||
var parsed; | ||
if (css instanceof Root) { | ||
parsed = css; | ||
} else if (css instanceof Result) { | ||
parsed = css.root; | ||
if (css.map && typeof (opts.map) == "undefined") { | ||
opts.map = { prev: css.map }; | ||
} | ||
}, | ||
process: { | ||
writable: true, | ||
} else { | ||
parsed = postcss.parse(css, opts); | ||
} | ||
for (var i = 0; i < this.processors.length; i++) { | ||
var returned = this.processors[i](parsed, opts); | ||
if (returned instanceof Root) parsed = returned; | ||
} | ||
// Process CSS throw installed processors | ||
value: function (css, opts) { | ||
if (opts === undefined) opts = {}; | ||
if (opts.map == "inline") { | ||
opts.map = { inline: true }; | ||
console.warn("Shortcut map: \"inline\" is deprecated " + "and will be remove in 3.1"); | ||
} | ||
return parsed.toResult(opts); | ||
}; | ||
var parsed; | ||
if (css instanceof Root) { | ||
parsed = css; | ||
} else if (css instanceof Result) { | ||
parsed = css.root; | ||
if (css.map && typeof (opts.map) == "undefined") { | ||
opts.map = { prev: css.map }; | ||
} | ||
} else { | ||
parsed = postcss.parse(css, opts); | ||
} | ||
for (var i = 0; i < this.processors.length; i++) { | ||
var returned = this.processors[i](parsed, opts); | ||
if (returned instanceof Root) parsed = returned; | ||
} | ||
return parsed.toResult(opts); | ||
} | ||
}, | ||
normalize: { | ||
writable: true, | ||
// Return processor function | ||
value: function (processor) { | ||
var type = typeof (processor); | ||
if ((type == "object" || type == "function") && processor.postcss) { | ||
return processor.postcss; | ||
} else { | ||
return processor; | ||
} | ||
} | ||
PostCSS.prototype.normalize = function (plugin) { | ||
var type = typeof (plugin); | ||
if ((type == "object" || type == "function") && plugin.postcss) { | ||
return plugin.postcss; | ||
} else { | ||
return plugin; | ||
} | ||
}); | ||
}; | ||
@@ -91,0 +68,0 @@ return PostCSS; |
"use strict"; | ||
var _classProps = function (child, staticProps, instanceProps) { | ||
if (staticProps) Object.defineProperties(child, staticProps); | ||
if (instanceProps) Object.defineProperties(child.prototype, instanceProps); | ||
}; | ||
var mozilla = require("source-map"); | ||
@@ -23,97 +18,64 @@ var Base64 = require("js-base64").Base64; | ||
_classProps(PreviousMap, null, { | ||
consumer: { | ||
writable: true, | ||
PreviousMap.prototype.consumer = function () { | ||
if (!this.consumerCache) { | ||
this.consumerCache = new mozilla.SourceMapConsumer(this.text); | ||
} | ||
return this.consumerCache; | ||
}; | ||
PreviousMap.prototype.withContent = function () { | ||
return !!(this.consumer().sourcesContent && this.consumer().sourcesContent.length > 0); | ||
}; | ||
// Return SourceMapConsumer object to read map | ||
value: function () { | ||
if (!this.consumerCache) { | ||
this.consumerCache = new mozilla.SourceMapConsumer(this.text); | ||
} | ||
return this.consumerCache; | ||
} | ||
}, | ||
withContent: { | ||
writable: true, | ||
PreviousMap.prototype.startWith = function (string, start) { | ||
if (!string) return false; | ||
return string.substr(0, start.length) == start; | ||
}; | ||
PreviousMap.prototype.loadAnnotation = function (css) { | ||
var match = css.match(/\/\*\s*# sourceMappingURL=(.*)\s*\*\//); | ||
if (match) this.annotation = match[1].trim(); | ||
}; | ||
// Is map has sources content | ||
value: function () { | ||
return !!(this.consumer().sourcesContent && this.consumer().sourcesContent.length > 0); | ||
} | ||
}, | ||
startWith: { | ||
writable: true, | ||
PreviousMap.prototype.decodeInline = function (text) { | ||
var uri = "data:application/json,"; | ||
var base64 = "data:application/json;base64,"; | ||
if (this.startWith(text, uri)) { | ||
return decodeURIComponent(text.substr(uri.length)); | ||
} else if (this.startWith(text, base64)) { | ||
return Base64.decode(text.substr(base64.length)); | ||
} else { | ||
var encoding = text.match(/data:application\/json;([^,]+),/)[1]; | ||
throw new Error("Unsupported source map encoding " + encoding); | ||
} | ||
}; | ||
// Is `string` is starting with `start` | ||
value: function (string, start) { | ||
if (!string) return false; | ||
return string.substr(0, start.length) == start; | ||
} | ||
}, | ||
loadAnnotation: { | ||
writable: true, | ||
PreviousMap.prototype.loadMap = function (file, prev) { | ||
if (prev === false) return; | ||
// Load for annotation comment from previous compilation step | ||
value: function (css) { | ||
var match = css.match(/\/\*\s*# sourceMappingURL=(.*)\s*\*\//); | ||
if (match) this.annotation = match[1].trim(); | ||
if (prev) { | ||
if (typeof (prev) == "string") { | ||
return prev; | ||
} else if (prev instanceof mozilla.SourceMapConsumer) { | ||
return mozilla.SourceMapGenerator.fromSourceMap(prev).toString(); | ||
} else if (prev instanceof mozilla.SourceMapGenerator) { | ||
return prev.toString(); | ||
} else if (typeof (prev) == "object" && prev.mappings) { | ||
return JSON.stringify(prev); | ||
} else { | ||
throw new Error("Unsupported previous source map format: " + prev.toString()); | ||
} | ||
}, | ||
decodeInline: { | ||
writable: true, | ||
} else if (this.inline) { | ||
return this.decodeInline(this.annotation); | ||
} else if (this.annotation) { | ||
var map = this.annotation; | ||
if (file) map = path.join(path.dirname(file), map); | ||
// Encode different type of inline | ||
value: function (text) { | ||
var uri = "data:application/json,"; | ||
var base64 = "data:application/json;base64,"; | ||
if (this.startWith(text, uri)) { | ||
return decodeURIComponent(text.substr(uri.length)); | ||
} else if (this.startWith(text, base64)) { | ||
return Base64.decode(text.substr(base64.length)); | ||
} else { | ||
var encoding = text.match(/data:application\/json;([^,]+),/)[1]; | ||
throw new Error("Unsupported source map encoding " + encoding); | ||
} | ||
this.root = path.dirname(map); | ||
if (fs.existsSync && fs.existsSync(map)) { | ||
return fs.readFileSync(map, "utf-8").toString().trim(); | ||
} | ||
}, | ||
loadMap: { | ||
writable: true, | ||
// Load previous map | ||
value: function (file, prev) { | ||
if (prev === false) return; | ||
if (prev) { | ||
if (typeof (prev) == "string") { | ||
return prev; | ||
} else if (prev instanceof mozilla.SourceMapConsumer) { | ||
return mozilla.SourceMapGenerator.fromSourceMap(prev).toString(); | ||
} else if (prev instanceof mozilla.SourceMapGenerator) { | ||
return prev.toString(); | ||
} else if (typeof (prev) == "object" && prev.mappings) { | ||
return JSON.stringify(prev); | ||
} else { | ||
throw new Error("Unsupported previous source map format: " + prev.toString()); | ||
} | ||
} else if (this.inline) { | ||
return this.decodeInline(this.annotation); | ||
} else if (this.annotation) { | ||
var map = this.annotation; | ||
if (file) map = path.join(path.dirname(file), map); | ||
this.root = path.dirname(map); | ||
if (fs.existsSync && fs.existsSync(map)) { | ||
return fs.readFileSync(map, "utf-8").toString().trim(); | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
}; | ||
@@ -120,0 +82,0 @@ return PreviousMap; |
@@ -18,2 +18,13 @@ "use strict"; | ||
Result.prototype.toString = function () { | ||
return this.css; | ||
}; | ||
Result.prototype.stringify = function () { | ||
var map = new MapGenerator(this.root, this.opts); | ||
var generated = map.generate(); | ||
this.cssCached = generated[0]; | ||
this.mapCached = generated[1]; | ||
}; | ||
_classProps(Result, null, { | ||
@@ -33,23 +44,2 @@ map: { | ||
} | ||
}, | ||
toString: { | ||
writable: true, | ||
// Return CSS string on any try to print | ||
value: function () { | ||
return this.css; | ||
} | ||
}, | ||
stringify: { | ||
writable: true, | ||
// Generate CSS and map | ||
value: function () { | ||
var map = new MapGenerator(this.root, this.opts); | ||
var generated = map.generate(); | ||
this.cssCached = generated[0]; | ||
this.mapCached = generated[1]; | ||
} | ||
} | ||
@@ -56,0 +46,0 @@ }); |
"use strict"; | ||
var _classProps = function (child, staticProps, instanceProps) { | ||
if (staticProps) Object.defineProperties(child, staticProps); | ||
if (instanceProps) Object.defineProperties(child.prototype, instanceProps); | ||
}; | ||
var _extends = function (child, parent) { | ||
@@ -37,67 +32,44 @@ child.prototype = Object.create(parent.prototype, { | ||
_classProps(Root, null, { | ||
remove: { | ||
writable: true, | ||
Root.prototype.remove = function (child) { | ||
child = this.index(child); | ||
if (child === 0 && this.childs.length > 1) { | ||
this.childs[1].before = this.childs[child].before; | ||
} | ||
// Fix space when we remove first child | ||
value: function (child) { | ||
child = this.index(child); | ||
return Container.prototype.remove.call(this, child); | ||
}; | ||
if (child === 0 && this.childs.length > 1) { | ||
this.childs[1].before = this.childs[child].before; | ||
} | ||
Root.prototype.normalize = function (child, sample, type) { | ||
var childs = Container.prototype.normalize.call(this, child, sample, type); | ||
return Container.prototype.remove.call(this, child); | ||
} | ||
}, | ||
normalize: { | ||
writable: true, | ||
// Fix spaces on insert before first rule | ||
value: function (child, sample, type) { | ||
var childs = Container.prototype.normalize.call(this, child, sample, type); | ||
for (var i = 0; i < childs.length; i++) { | ||
if (type == "prepend") { | ||
if (this.childs.length > 1) { | ||
sample.before = this.childs[1].before; | ||
} else if (this.childs.length == 1) { | ||
sample.before = this.after; | ||
} | ||
} else { | ||
if (this.childs.length > 1) { | ||
if (sample) childs[i].before = sample.before; | ||
} else { | ||
childs[i].before = this.after; | ||
} | ||
} | ||
for (var i = 0; i < childs.length; i++) { | ||
if (type == "prepend") { | ||
if (this.childs.length > 1) { | ||
sample.before = this.childs[1].before; | ||
} else if (this.childs.length == 1) { | ||
sample.before = this.after; | ||
} | ||
return childs; | ||
} else { | ||
if (this.childs.length > 1) { | ||
if (sample) childs[i].before = sample.before; | ||
} else { | ||
childs[i].before = this.after; | ||
} | ||
} | ||
}, | ||
stringify: { | ||
writable: true, | ||
} | ||
return childs; | ||
}; | ||
// Stringify styles | ||
value: function (builder) { | ||
this.stringifyContent(builder); | ||
if (this.after) builder(this.after); | ||
} | ||
}, | ||
toResult: { | ||
writable: true, | ||
Root.prototype.stringify = function (builder) { | ||
this.stringifyContent(builder); | ||
if (this.after) builder(this.after); | ||
}; | ||
Root.prototype.toResult = function (opts) { | ||
if (opts === undefined) opts = {}; | ||
return new Result(this, opts); | ||
}; | ||
// Generate processing result with optional source map | ||
value: function (opts) { | ||
if (opts === undefined) opts = {}; | ||
return new Result(this, opts); | ||
} | ||
} | ||
}); | ||
return Root; | ||
@@ -104,0 +76,0 @@ })(Container); |
@@ -34,2 +34,6 @@ "use strict"; | ||
Rule.prototype.stringify = function (builder) { | ||
this.stringifyBlock(builder, this.stringifyRaw("selector")); | ||
}; | ||
_classProps(Rule, null, { | ||
@@ -45,11 +49,2 @@ selectors: { | ||
} | ||
}, | ||
stringify: { | ||
writable: true, | ||
// Stringify rule | ||
value: function (builder) { | ||
this.stringifyBlock(builder, this.stringifyRaw("selector")); | ||
} | ||
} | ||
@@ -56,0 +51,0 @@ }); |
{ | ||
"name": "postcss", | ||
"version": "3.0.6", | ||
"version": "3.0.7", | ||
"description": "Framework for CSS postprocessors with full source map support", | ||
@@ -41,3 +41,3 @@ "keywords": [ | ||
"rework": "1.0.1", | ||
"should": "4.3.0", | ||
"should": "4.3.1", | ||
"mensch": "0.3.1", | ||
@@ -49,3 +49,3 @@ "stylus": "0.49.3", | ||
"less": "2.1.1", | ||
"6to5": "1.14.7" | ||
"6to5": "1.14.17" | ||
}, | ||
@@ -52,0 +52,0 @@ "scripts": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
94954
1826