Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: toString should stringify node #74

Merged
merged 4 commits into from
Mar 7, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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) {
const after = this.raw(node, 'after');

Expand Down
23 changes: 16 additions & 7 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
const Input = require('postcss/lib/input');

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

// TODO: walk methods for custom nodes
const { stringify } = require('./ValuesStringifier');

module.exports = {
parse(css, options) {
Expand All @@ -22,13 +20,24 @@ 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(node, builder) {
shellscape marked this conversation as resolved.
Show resolved Hide resolved
// 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));
});
}
Loading