Skip to content

Commit

Permalink
fix: toString should stringify node (#74)
Browse files Browse the repository at this point in the history
* fix: toString should stringify node

* refactor: rename, rework inherited nodes for toString

* chore: remove commented code
  • Loading branch information
shellscape authored Mar 7, 2019
1 parent bc08be3 commit 3b10553
Show file tree
Hide file tree
Showing 46 changed files with 513 additions and 87 deletions.
1 change: 1 addition & 0 deletions lib/ValuesParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ module.exports = class ValuesParser extends Parser {
const inline = Comment.testInline(token);
const node = this.lastNode;
node.inline = inline;
Object.setPrototypeOf(node, Comment.prototype);
}

fromFirst(tokens, Constructor) {
Expand Down
7 changes: 6 additions & 1 deletion lib/ValuesStringifier.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
const Stringifier = require('postcss/lib/stringifier');

module.exports = class LessStringifier extends Stringifier {
module.exports = class ValuesStringifier extends Stringifier {
static stringify(node, builder) {
const stringifier = new ValuesStringifier(builder);
stringifier.stringify(node);
}

basic(node, value) {
const print = value || node.value;
const after = node.raws.after ? this.raw(node, 'after') || '' : '';
Expand Down
16 changes: 11 additions & 5 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
const Input = require('postcss/lib/input');

const Parser = require('./ValuesParser');
const Stringifier = require('./ValuesStringifier');
const { stringify } = require('./ValuesStringifier');

module.exports = {
parse(css, options) {
Expand All @@ -20,13 +20,19 @@ module.exports = {

parser.parse();

const { root } = parser;
const ogToString = root.toString;

function toString(stringifier) {
return ogToString.bind(root)(stringifier || module.exports.stringify);
}

root.toString = toString.bind(root);

return parser.root;
},

stringify(node, builder) {
const stringifier = new Stringifier(builder);
stringifier.stringify(node);
},
stringify,

nodeToString(node) {
let result = '';
Expand Down
7 changes: 4 additions & 3 deletions lib/nodes/AtWord.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ const AtRule = require('postcss/lib/node');

const { registerWalker } = require('../walker');

const { stringify } = require('../ValuesStringifier');

class AtWord extends AtRule {
constructor(options) {
super(options);
this.type = 'atword';
toString(stringifier = stringify) {
return super.toString(stringifier);
}
}

Expand Down
90 changes: 50 additions & 40 deletions lib/nodes/Comment.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,61 +8,71 @@
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of this Source Code Form.
*/
const Comment = require('postcss/lib/comment');
const PostCssComment = require('postcss/lib/comment');

const { stringify } = require('../ValuesStringifier');

const inlineRegex = /(\/\/)/;

Comment.testInline = (token) => inlineRegex.test(token[1]);
class Comment extends PostCssComment {
static testInline(token) {
return inlineRegex.test(token[1]);
}

Comment.tokenizeNext = (tokens, parser) => {
const [first] = tokens;
const newlineIndex = tokens.findIndex((t) => /\n/.test(t[1]));
let bits = tokens;
let rest = [];
static tokenizeNext(tokens, parser) {
const [first] = tokens;
const newlineIndex = tokens.findIndex((t) => /\n/.test(t[1]));
let bits = tokens;
let rest = [];

if (newlineIndex >= 0) {
bits = tokens.slice(0, newlineIndex);
rest = tokens.slice(newlineIndex);
}
if (newlineIndex >= 0) {
bits = tokens.slice(0, newlineIndex);
rest = tokens.slice(newlineIndex);
}

bits = bits.map((t) => t[1]);

bits = bits.map((t) => t[1]);
// see tilde comment in tokenizeInline
const text = bits.concat('~~').join('');
const last = bits[bits.length - 1];
const newToken = ['comment', text, first[2], first[3], last[2], last[3]];

// see tilde comment in tokenizeInline
const text = bits.concat('~~').join('');
const last = bits[bits.length - 1];
const newToken = ['comment', text, first[2], first[3], last[2], last[3]];
parser.back([newToken, ...rest]);
}

parser.back([newToken, ...rest]);
};
static tokenizeInline(tokens, parser) {
const [first, ...rest] = tokens;
const bits = first[1].split(/(\/\/.+)/).filter((t) => !!t);
const newTokens = [];
const [, , startLine, , endLine] = first;
let [, , , startChar, , endChar] = first;

Comment.tokenizeInline = (tokens, parser) => {
const [first, ...rest] = tokens;
const bits = first[1].split(/(\/\/.+)/).filter((t) => !!t);
const newTokens = [];
const [, , startLine, , endLine] = first;
let [, , , startChar, , endChar] = first;
for (let bit of bits) {
const comment = bit.slice(0, 2) === '//';
const type = comment ? 'comment' : 'word';

for (let bit of bits) {
const comment = bit.slice(0, 2) === '//';
const type = comment ? 'comment' : 'word';
if (comment) {
// the Parser base comment() method trims the last two characters when creating the node
// these tildes are added to counter that. it's hacky, but it works, and we don't have to
// re-implement the method
bit += '~~';
}

if (comment) {
// the Parser base comment() method trims the last two characters when creating the node
// these tildes are added to counter that. it's hacky, but it works, and we don't have to
// re-implement the method
bit += '~~';
}
if (bit !== bits[0]) {
startChar = endChar + 1;
}

if (bit !== bits[0]) {
startChar = endChar + 1;
}
endChar = startChar + bit.length - 1;

endChar = startChar + bit.length - 1;
newTokens.push([type, bit, startLine, startChar, endLine, endChar]);
}

newTokens.push([type, bit, startLine, startChar, endLine, endChar]);
parser.back(newTokens.concat(rest));
}

parser.back(newTokens.concat(rest));
};
toString(stringifier = stringify) {
return super.toString(stringifier);
}
}

module.exports = Comment;
21 changes: 21 additions & 0 deletions lib/nodes/Container.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
Copyright © 2018 Andrew Powell
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of this Source Code Form.
*/
const PostCssContainer = require('postcss/lib/container');

const { stringify } = require('../ValuesStringifier');

class Container extends PostCssContainer {
toString(stringifier = stringify) {
return super.toString(stringifier);
}
}

module.exports = Container;
4 changes: 2 additions & 2 deletions lib/nodes/Func.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of this Source Code Form.
*/
const Container = require('postcss/lib/container');

const { registerWalker } = require('../walker');

const Container = require('./Container');

const colorFunctions = ['hsl', 'hsla', 'rgb', 'rgba'];

class Func extends Container {
Expand Down
4 changes: 2 additions & 2 deletions lib/nodes/Interpolation.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of this Source Code Form.
*/
const Container = require('postcss/lib/container');

const { registerWalker } = require('../walker');

const Container = require('./Container');

class Interpolation extends Container {
constructor(options = {}) {
super(options);
Expand Down
21 changes: 21 additions & 0 deletions lib/nodes/Node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
Copyright © 2018 Andrew Powell
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of this Source Code Form.
*/
const PostCssNode = require('postcss/lib/node');

const { stringify } = require('../ValuesStringifier');

class Node extends PostCssNode {
toString(stringifier = stringify) {
return super.toString(stringifier || {});
}
}

module.exports = Node;
3 changes: 2 additions & 1 deletion lib/nodes/Numeric.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
included in all copies or substantial portions of this Source Code Form.
*/
const isNumber = require('is-number');
const Node = require('postcss/lib/node');

const { registerWalker } = require('../walker');

const Node = require('./Node');

const unitRegex = /%|ch|cm|em|ex|in|mm|pc|pt|px|rem|vh|vmax|vmin|vw$/i;

class Numeric extends Node {
Expand Down
4 changes: 2 additions & 2 deletions lib/nodes/Operator.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of this Source Code Form.
*/
const Node = require('postcss/lib/node');

const { registerWalker } = require('../walker');

const Node = require('./Node');

const operators = ['+', '-', '/', '*', '%'];
const operRegex = new RegExp(`([/|*}])`);

Expand Down
4 changes: 2 additions & 2 deletions lib/nodes/Punctuation.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of this Source Code Form.
*/
const Node = require('postcss/lib/node');

const { getTokens } = require('../tokenize');
const { registerWalker } = require('../walker');

const Node = require('./Node');

/**
* @desc Punctuation nodes can contain:
* , : ( ) { } [ ]
Expand Down
4 changes: 2 additions & 2 deletions lib/nodes/Quoted.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of this Source Code Form.
*/
const Node = require('postcss/lib/node');

const { registerWalker } = require('../walker');

const Node = require('./Node');

class Quoted extends Node {
constructor(options) {
super(options);
Expand Down
4 changes: 2 additions & 2 deletions lib/nodes/UnicodeRange.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of this Source Code Form.
*/
const Node = require('postcss/lib/node');

const { registerWalker } = require('../walker');

const Node = require('./Node');

class UnicodeRange extends Node {
constructor(options) {
super(options);
Expand Down
3 changes: 2 additions & 1 deletion lib/nodes/Word.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
*/
const colors = require('color-name');
const isUrl = require('is-url-superb');
const Node = require('postcss/lib/node');

const { registerWalker } = require('../walker');

const Node = require('./Node');

const escapeRegex = /^\\(.+)/;
const hexRegex = /^#(.+)/;
const colorRegex = /^#([0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;
Expand Down
2 changes: 2 additions & 0 deletions test/atword.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ for (const fixture of snapshot) {
const string = nodeToString(root);

t.is(string, fixture);
t.is(fixture, root.toString());
t.snapshot(root.first.toString());
t.snapshot(string);
t.snapshot(nodes);
});
Expand Down
2 changes: 2 additions & 0 deletions test/comment.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ for (const fixture of snapshot) {
const string = nodeToString(root);

t.is(string, fixture);
t.is(fixture, root.toString());
t.snapshot(root.first.toString());
t.snapshot(string);
t.snapshot(nodes);
});
Expand Down
3 changes: 2 additions & 1 deletion test/fixtures/interpolation.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ module.exports = {
options: {
interpolation: { prefix: '#' }
},
snapshot: ['#{batman}', '#{2px}', '#{2 * 2px}']
snapshot: ['#{batman}', '#{2px}', '#{2 * 2px}'],
throws: ['#{batman']
};
2 changes: 2 additions & 0 deletions test/func.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ for (const fixture of snapshot) {
const string = nodeToString(root);

t.is(string, fixture);
t.is(fixture, root.toString());
t.snapshot(root.first.toString());
t.snapshot(string);
t.snapshot(nodes);
});
Expand Down
10 changes: 9 additions & 1 deletion test/interpolation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const test = require('ava');

const { nodeToString, parse } = require('../lib');

const { options, snapshot } = require('./fixtures/interpolation');
const { options, snapshot, throws } = require('./fixtures/interpolation');

for (const fixture of snapshot) {
test(fixture, (t) => {
Expand All @@ -24,7 +24,15 @@ for (const fixture of snapshot) {
const string = nodeToString(root);

t.is(string, fixture);
t.is(fixture, root.toString());
t.snapshot(root.first.toString());
t.snapshot(string);
t.snapshot(nodes);
});
}

for (const fixture of throws) {
test(fixture, (t) => {
t.throws(() => parse(fixture));
});
}
2 changes: 2 additions & 0 deletions test/numeric.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ for (const fixture of snapshot) {
const string = nodeToString(root);

t.is(string, fixture);
t.is(fixture, root.toString());
t.snapshot(root.first.toString());
t.snapshot(string);
t.snapshot(nodes);
});
Expand Down
Loading

1 comment on commit 3b10553

@papandreou
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eagerly awaiting a new release with this fix :)

Please sign in to comment.