mirror of
https://github.com/hanzoai/postcss.git
synced 2026-09-24 17:01:56 +00:00
Move Node#style to Stringifier
This commit is contained in:
+2
-169
@@ -2,20 +2,6 @@ import CssSyntaxError from './css-syntax-error';
|
||||
import Stringifier from './stringifier';
|
||||
import warnOnce from './warn-once';
|
||||
|
||||
const defaultStyle = {
|
||||
colon: ': ',
|
||||
indent: ' ',
|
||||
beforeDecl: '\n',
|
||||
beforeRule: '\n',
|
||||
beforeOpen: ' ',
|
||||
beforeClose: '\n',
|
||||
beforeComment: '\n',
|
||||
after: '\n',
|
||||
emptyBody: '',
|
||||
commentLeft: ' ',
|
||||
commentRight: ' '
|
||||
};
|
||||
|
||||
let cloneNode = function (obj, parent) {
|
||||
let cloned = new obj.constructor();
|
||||
|
||||
@@ -169,161 +155,8 @@ export default class Node {
|
||||
}
|
||||
|
||||
style(own, detect) {
|
||||
let value;
|
||||
if ( !detect ) detect = own;
|
||||
|
||||
// Already had
|
||||
if ( own ) {
|
||||
value = this.raw[own];
|
||||
if ( typeof value !== 'undefined' ) return value;
|
||||
}
|
||||
|
||||
let parent = this.parent;
|
||||
|
||||
// Hack for first rule in CSS
|
||||
if ( detect === 'before' ) {
|
||||
if ( !parent || parent.type === 'root' && parent.first === this ) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
// Floating child without parent
|
||||
if ( !parent ) return defaultStyle[detect];
|
||||
|
||||
// Detect style by other nodes
|
||||
let root = this.root();
|
||||
if ( !root.styleCache ) root.styleCache = { };
|
||||
if ( typeof root.styleCache[detect] !== 'undefined' ) {
|
||||
return root.styleCache[detect];
|
||||
}
|
||||
|
||||
if ( detect === 'semicolon' ) {
|
||||
root.eachInside( (i) => {
|
||||
if ( i.nodes && i.nodes.length && i.last.type === 'decl' ) {
|
||||
value = i.raw.semicolon;
|
||||
if ( typeof value !== 'undefined' ) return false;
|
||||
}
|
||||
});
|
||||
} else if ( detect === 'emptyBody' ) {
|
||||
root.eachInside( (i) => {
|
||||
if ( i.nodes && i.nodes.length === 0 ) {
|
||||
value = i.raw.after;
|
||||
if ( typeof value !== 'undefined' ) return false;
|
||||
}
|
||||
});
|
||||
} else if ( detect === 'indent' ) {
|
||||
root.eachInside( (i) => {
|
||||
let p = i.parent;
|
||||
if ( p && p !== root && p.parent && p.parent === root ) {
|
||||
if ( typeof i.raw.before !== 'undefined' ) {
|
||||
let parts = i.raw.before.split('\n');
|
||||
value = parts[parts.length - 1];
|
||||
value = value.replace(/[^\s]/g, '');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if ( detect === 'beforeComment' ) {
|
||||
root.eachComment( (i) => {
|
||||
if ( typeof i.raw.before !== 'undefined' ) {
|
||||
value = i.raw.before;
|
||||
if ( value.indexOf('\n') !== -1 ) {
|
||||
value = value.replace(/[^\n]+$/, '');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if ( typeof value === 'undefined' ) {
|
||||
value = this.style(null, 'beforeDecl');
|
||||
}
|
||||
} else if ( detect === 'beforeDecl' ) {
|
||||
root.eachDecl( (i) => {
|
||||
if ( typeof i.raw.before !== 'undefined' ) {
|
||||
value = i.raw.before;
|
||||
if ( value.indexOf('\n') !== -1 ) {
|
||||
value = value.replace(/[^\n]+$/, '');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if ( typeof value === 'undefined' ) {
|
||||
value = this.style(null, 'beforeRule');
|
||||
}
|
||||
} else if ( detect === 'beforeRule' ) {
|
||||
root.eachInside( (i) => {
|
||||
if ( i.nodes && (i.parent !== root || root.first !== i) ) {
|
||||
if ( typeof i.raw.before !== 'undefined' ) {
|
||||
value = i.raw.before;
|
||||
if ( value.indexOf('\n') !== -1 ) {
|
||||
value = value.replace(/[^\n]+$/, '');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if ( detect === 'beforeClose' ) {
|
||||
root.eachInside( (i) => {
|
||||
if ( i.nodes && i.nodes.length > 0 ) {
|
||||
if ( typeof i.raw.after !== 'undefined' ) {
|
||||
value = i.raw.after;
|
||||
if ( value.indexOf('\n') !== -1 ) {
|
||||
value = value.replace(/[^\n]+$/, '');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if ( detect === 'before' || detect === 'after' ) {
|
||||
if ( this.type === 'decl' ) {
|
||||
value = this.style(null, 'beforeDecl');
|
||||
} else if ( this.type === 'comment' ) {
|
||||
value = this.style(null, 'beforeComment');
|
||||
} else if ( detect === 'before' ) {
|
||||
value = this.style(null, 'beforeRule');
|
||||
} else {
|
||||
value = this.style(null, 'beforeClose');
|
||||
}
|
||||
|
||||
let node = this.parent;
|
||||
let depth = 0;
|
||||
while ( node && node.type !== 'root' ) {
|
||||
depth += 1;
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
if ( value.indexOf('\n') !== -1 ) {
|
||||
let indent = this.style(null, 'indent');
|
||||
if ( indent.length ) {
|
||||
for ( let step = 0; step < depth; step++ ) value += indent;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
} else if ( detect === 'colon' ) {
|
||||
root.eachDecl( (i) => {
|
||||
if ( typeof i.raw.between !== 'undefined' ) {
|
||||
value = i.raw.between.replace(/[^\s:]/g, '');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else if ( detect === 'beforeOpen' ) {
|
||||
root.eachInside( (i) => {
|
||||
if ( i.type !== 'decl' ) {
|
||||
value = i.raw.between;
|
||||
if ( typeof value !== 'undefined' ) return false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
root.eachInside( (i) => {
|
||||
value = i.raw[own];
|
||||
if ( typeof value !== 'undefined' ) return false;
|
||||
});
|
||||
}
|
||||
|
||||
if ( typeof value === 'undefined' ) value = defaultStyle[detect];
|
||||
|
||||
root.styleCache[detect] = value;
|
||||
return value;
|
||||
let str = new Stringifier();
|
||||
return str.style(this, own, detect);
|
||||
}
|
||||
|
||||
root() {
|
||||
|
||||
+183
-11
@@ -1,3 +1,17 @@
|
||||
const defaultStyle = {
|
||||
colon: ': ',
|
||||
indent: ' ',
|
||||
beforeDecl: '\n',
|
||||
beforeRule: '\n',
|
||||
beforeOpen: ' ',
|
||||
beforeClose: '\n',
|
||||
beforeComment: '\n',
|
||||
after: '\n',
|
||||
emptyBody: '',
|
||||
commentLeft: ' ',
|
||||
commentRight: ' '
|
||||
};
|
||||
|
||||
export default class Stringifier {
|
||||
|
||||
constructor(builder) {
|
||||
@@ -14,18 +28,18 @@ export default class Stringifier {
|
||||
}
|
||||
|
||||
comment(node) {
|
||||
let before = node.style('before');
|
||||
let before = this.style(node, 'before');
|
||||
if ( before ) this.builder(before);
|
||||
let left = node.style('left', 'commentLeft');
|
||||
let right = node.style('right', 'commentRight');
|
||||
let left = this.style(node, 'left', 'commentLeft');
|
||||
let right = this.style(node, 'right', 'commentRight');
|
||||
this.builder('/*' + left + node.text + right + '*/', node);
|
||||
}
|
||||
|
||||
decl(node, semicolon) {
|
||||
let before = node.style('before');
|
||||
let before = this.style(node, 'before');
|
||||
if ( before ) this.builder(before);
|
||||
|
||||
let between = node.style('between', 'colon');
|
||||
let between = this.style(node, 'between', 'colon');
|
||||
let string = node.prop + between + this.raw(node, 'value');
|
||||
|
||||
if ( node.important ) {
|
||||
@@ -54,7 +68,7 @@ export default class Stringifier {
|
||||
this.block(node, name + params);
|
||||
|
||||
} else {
|
||||
let before = node.style('before');
|
||||
let before = this.style(node, 'before');
|
||||
if ( before ) this.builder(before);
|
||||
let end = (node.raw.between || '') + (semicolon ? ';' : '');
|
||||
this.builder(name + params + end, node);
|
||||
@@ -70,31 +84,189 @@ export default class Stringifier {
|
||||
last -= 1;
|
||||
}
|
||||
|
||||
let semicolon = node.style('semicolon');
|
||||
let semicolon = this.style(node, 'semicolon');
|
||||
for ( let i = 0; i < node.nodes.length; i++ ) {
|
||||
this.stringify(node.nodes[i], last !== i || semicolon);
|
||||
}
|
||||
}
|
||||
|
||||
block(node, start) {
|
||||
let before = node.style('before');
|
||||
let before = this.style(node, 'before');
|
||||
if ( before ) this.builder(before);
|
||||
|
||||
let between = node.style('between', 'beforeOpen');
|
||||
let between = this.style(node, 'between', 'beforeOpen');
|
||||
this.builder(start + between + '{', node, 'start');
|
||||
|
||||
let after;
|
||||
if ( node.nodes && node.nodes.length ) {
|
||||
this.body(node);
|
||||
after = node.style('after');
|
||||
after = this.style(node, 'after');
|
||||
} else {
|
||||
after = node.style('after', 'emptyBody');
|
||||
after = this.style(node, 'after', 'emptyBody');
|
||||
}
|
||||
|
||||
if ( after ) this.builder(after);
|
||||
this.builder('}', node, 'end');
|
||||
}
|
||||
|
||||
style(node, own, detect) {
|
||||
let value;
|
||||
if ( !detect ) detect = own;
|
||||
|
||||
// Already had
|
||||
if ( own ) {
|
||||
value = node.raw[own];
|
||||
if ( typeof value !== 'undefined' ) return value;
|
||||
}
|
||||
|
||||
let parent = node.parent;
|
||||
|
||||
// Hack for first rule in CSS
|
||||
if ( detect === 'before' ) {
|
||||
if ( !parent || parent.type === 'root' && parent.first === node ) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
// Floating child without parent
|
||||
if ( !parent ) return defaultStyle[detect];
|
||||
|
||||
// Detect style by other nodes
|
||||
let root = node.root();
|
||||
if ( !root.styleCache ) root.styleCache = { };
|
||||
if ( typeof root.styleCache[detect] !== 'undefined' ) {
|
||||
return root.styleCache[detect];
|
||||
}
|
||||
|
||||
if ( detect === 'semicolon' ) {
|
||||
root.eachInside( (i) => {
|
||||
if ( i.nodes && i.nodes.length && i.last.type === 'decl' ) {
|
||||
value = i.raw.semicolon;
|
||||
if ( typeof value !== 'undefined' ) return false;
|
||||
}
|
||||
});
|
||||
} else if ( detect === 'emptyBody' ) {
|
||||
root.eachInside( (i) => {
|
||||
if ( i.nodes && i.nodes.length === 0 ) {
|
||||
value = i.raw.after;
|
||||
if ( typeof value !== 'undefined' ) return false;
|
||||
}
|
||||
});
|
||||
} else if ( detect === 'indent' ) {
|
||||
root.eachInside( (i) => {
|
||||
let p = i.parent;
|
||||
if ( p && p !== root && p.parent && p.parent === root ) {
|
||||
if ( typeof i.raw.before !== 'undefined' ) {
|
||||
let parts = i.raw.before.split('\n');
|
||||
value = parts[parts.length - 1];
|
||||
value = value.replace(/[^\s]/g, '');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if ( detect === 'beforeComment' ) {
|
||||
root.eachComment( (i) => {
|
||||
if ( typeof i.raw.before !== 'undefined' ) {
|
||||
value = i.raw.before;
|
||||
if ( value.indexOf('\n') !== -1 ) {
|
||||
value = value.replace(/[^\n]+$/, '');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if ( typeof value === 'undefined' ) {
|
||||
value = this.style(node, null, 'beforeDecl');
|
||||
}
|
||||
} else if ( detect === 'beforeDecl' ) {
|
||||
root.eachDecl( (i) => {
|
||||
if ( typeof i.raw.before !== 'undefined' ) {
|
||||
value = i.raw.before;
|
||||
if ( value.indexOf('\n') !== -1 ) {
|
||||
value = value.replace(/[^\n]+$/, '');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if ( typeof value === 'undefined' ) {
|
||||
value = this.style(node, null, 'beforeRule');
|
||||
}
|
||||
} else if ( detect === 'beforeRule' ) {
|
||||
root.eachInside( (i) => {
|
||||
if ( i.nodes && (i.parent !== root || root.first !== i) ) {
|
||||
if ( typeof i.raw.before !== 'undefined' ) {
|
||||
value = i.raw.before;
|
||||
if ( value.indexOf('\n') !== -1 ) {
|
||||
value = value.replace(/[^\n]+$/, '');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if ( detect === 'beforeClose' ) {
|
||||
root.eachInside( (i) => {
|
||||
if ( i.nodes && i.nodes.length > 0 ) {
|
||||
if ( typeof i.raw.after !== 'undefined' ) {
|
||||
value = i.raw.after;
|
||||
if ( value.indexOf('\n') !== -1 ) {
|
||||
value = value.replace(/[^\n]+$/, '');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if ( detect === 'before' || detect === 'after' ) {
|
||||
if ( node.type === 'decl' ) {
|
||||
value = this.style(node, null, 'beforeDecl');
|
||||
} else if ( node.type === 'comment' ) {
|
||||
value = this.style(node, null, 'beforeComment');
|
||||
} else if ( detect === 'before' ) {
|
||||
value = this.style(node, null, 'beforeRule');
|
||||
} else {
|
||||
value = this.style(node, null, 'beforeClose');
|
||||
}
|
||||
|
||||
let buf = node.parent;
|
||||
let depth = 0;
|
||||
while ( buf && buf.type !== 'root' ) {
|
||||
depth += 1;
|
||||
buf = buf.parent;
|
||||
}
|
||||
|
||||
if ( value.indexOf('\n') !== -1 ) {
|
||||
let indent = this.style(node, null, 'indent');
|
||||
if ( indent.length ) {
|
||||
for ( let step = 0; step < depth; step++ ) value += indent;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
} else if ( detect === 'colon' ) {
|
||||
root.eachDecl( (i) => {
|
||||
if ( typeof i.raw.between !== 'undefined' ) {
|
||||
value = i.raw.between.replace(/[^\s:]/g, '');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else if ( detect === 'beforeOpen' ) {
|
||||
root.eachInside( (i) => {
|
||||
if ( i.type !== 'decl' ) {
|
||||
value = i.raw.between;
|
||||
if ( typeof value !== 'undefined' ) return false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
root.eachInside( (i) => {
|
||||
value = i.raw[own];
|
||||
if ( typeof value !== 'undefined' ) return false;
|
||||
});
|
||||
}
|
||||
|
||||
if ( typeof value === 'undefined' ) value = defaultStyle[detect];
|
||||
|
||||
root.styleCache[detect] = value;
|
||||
return value;
|
||||
}
|
||||
|
||||
raw(node, prop) {
|
||||
let value = node[prop];
|
||||
let raw = node.raw[prop];
|
||||
|
||||
+1
-109
@@ -254,119 +254,11 @@ describe('Node', () => {
|
||||
|
||||
describe('style()', () => {
|
||||
|
||||
it('uses node style', () => {
|
||||
let rule = new Rule({ selector: 'a', raw: { between: '\n' } });
|
||||
expect(rule.style('between', 'beforeOpen')).to.eql('\n');
|
||||
});
|
||||
|
||||
it('hacks before for nodes without parent', () => {
|
||||
it('has shortcut to stringifier', () => {
|
||||
let rule = new Rule({ selector: 'a' });
|
||||
expect(rule.style('before')).to.eql('');
|
||||
});
|
||||
|
||||
it('hacks before for first node', () => {
|
||||
let root = new Root();
|
||||
root.append(new Rule({ selector: 'a' }));
|
||||
expect(root.first.style('before')).to.eql('');
|
||||
});
|
||||
|
||||
it('hacks before for first decl', () => {
|
||||
let decl = new Declaration({ prop: 'color', value: 'black' });
|
||||
expect(decl.style('before')).to.eql('');
|
||||
|
||||
let rule = new Rule({ selector: 'a' });
|
||||
rule.append(decl);
|
||||
expect(decl.style('before')).to.eql('\n ');
|
||||
});
|
||||
|
||||
it('detects after style', () => {
|
||||
let root = new Root();
|
||||
root.append({ selector: 'a', raw: { after: ' ' } });
|
||||
root.first.append({ prop: 'color', value: 'black' });
|
||||
root.append({ selector: 'a' });
|
||||
expect(root.last.style('after')).to.eql(' ');
|
||||
});
|
||||
|
||||
it('uses defaults without parent', () => {
|
||||
let rule = new Rule({ selector: 'a' });
|
||||
expect(rule.style('between', 'beforeOpen')).to.eql(' ');
|
||||
});
|
||||
|
||||
it('uses defaults for unique node', () => {
|
||||
let root = new Root();
|
||||
root.append(new Rule({ selector: 'a' }));
|
||||
expect(root.first.style('between', 'beforeOpen')).to.eql(' ');
|
||||
});
|
||||
|
||||
it('clones style from first node', () => {
|
||||
let root = new Root();
|
||||
root.append( new Rule({ selector: 'a', raw: { between: '' } }) );
|
||||
root.append( new Rule({ selector: 'b' }) );
|
||||
|
||||
expect(root.last.style('between', 'beforeOpen')).to.eql('');
|
||||
});
|
||||
|
||||
it('indents by default', () => {
|
||||
let root = new Root();
|
||||
root.append( new AtRule({ name: 'page' }) );
|
||||
root.first.append( new Rule({ selector: 'a' }) );
|
||||
root.first.first.append({ prop: 'color', value: 'black' });
|
||||
|
||||
expect(root.toString()).to.eql('@page {\n' +
|
||||
' a {\n' +
|
||||
' color: black\n' +
|
||||
' }\n' +
|
||||
'}');
|
||||
});
|
||||
|
||||
it('clones indent', () => {
|
||||
let compress = parse('@page{ a{ } }');
|
||||
let spaces = parse('@page {\n a {\n }\n}');
|
||||
|
||||
compress.first.first.append({ prop: 'color', value: 'black' });
|
||||
expect(compress.toString()).to.eql('@page{ a{ color: black } }');
|
||||
|
||||
spaces.first.first.append({ prop: 'color', value: 'black' });
|
||||
expect(spaces.toString())
|
||||
.to.eql('@page {\n a {\n color: black\n }\n}');
|
||||
});
|
||||
|
||||
it('clones indent by types', () => {
|
||||
let css = parse('a {\n color: black\n}\n\nb {\n}');
|
||||
css.append(new Rule({ selector: 'em' }));
|
||||
css.last.append({ prop: 'z-index', value: '1' });
|
||||
|
||||
expect(css.last.toString()).to.eql('\n\nem {\n z-index: 1\n}');
|
||||
});
|
||||
|
||||
it('clones indent by before and after', () => {
|
||||
let css = parse('@page{\n\n a{\n color: black}}');
|
||||
css.first.append(new Rule({ selector: 'b' }));
|
||||
css.first.last.append({ prop: 'z-index', value: '1' });
|
||||
|
||||
expect(css.first.last.toString()).to.eql('\n\n b{\n z-index: 1}');
|
||||
});
|
||||
|
||||
it('clones semicolon only from rules with children', () => {
|
||||
let css = parse('a{}b{one:1;}');
|
||||
expect(css.first.style('semicolon')).to.be.true;
|
||||
});
|
||||
|
||||
it('clones only spaces in before', () => {
|
||||
let css = parse('a{*one:1}');
|
||||
css.first.append({ prop: 'two', value: '2' });
|
||||
css.append({ name: 'keyframes', params: 'a' });
|
||||
css.last.append({ selector: 'from'});
|
||||
expect(css.toString())
|
||||
.to.eql('a{*one:1;two:2}\n@keyframes a{\nfrom{}}');
|
||||
});
|
||||
|
||||
it('clones only spaces in between', () => {
|
||||
let css = parse('a{one/**/:1}');
|
||||
css.first.append({ prop: 'two', value: '2' });
|
||||
expect(css.toString()).to.eql('a{one/**/:1;two:2}');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('root()', () => {
|
||||
|
||||
+126
-5
@@ -1,12 +1,20 @@
|
||||
import Stringifier from '../lib/stringifier';
|
||||
import Node from '../lib/node';
|
||||
import Declaration from '../lib/declaration';
|
||||
import AtRule from '../lib/at-rule';
|
||||
import parse from '../lib/parse';
|
||||
import Node from '../lib/node';
|
||||
import Root from '../lib/root';
|
||||
import Rule from '../lib/rule';
|
||||
|
||||
import { expect } from 'chai';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
|
||||
describe('stringifier', () => {
|
||||
let str;
|
||||
before( () => {
|
||||
str = new Stringifier();
|
||||
});
|
||||
|
||||
describe('.stringify()', () => {
|
||||
|
||||
@@ -24,10 +32,6 @@ describe('stringifier', () => {
|
||||
});
|
||||
|
||||
describe('.raw()', () => {
|
||||
let str;
|
||||
before( () => {
|
||||
str = new Stringifier();
|
||||
});
|
||||
|
||||
it('creates trimmed/raw property', () => {
|
||||
let b = new Node({ one: 'trim' });
|
||||
@@ -46,4 +50,121 @@ describe('stringifier', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('style()', () => {
|
||||
|
||||
it('uses node style', () => {
|
||||
let rule = new Rule({ selector: 'a', raw: { between: '\n' } });
|
||||
expect(str.style(rule, 'between', 'beforeOpen')).to.eql('\n');
|
||||
});
|
||||
|
||||
it('hacks before for nodes without parent', () => {
|
||||
let rule = new Rule({ selector: 'a' });
|
||||
expect(str.style(rule, 'before')).to.eql('');
|
||||
});
|
||||
|
||||
it('hacks before for first node', () => {
|
||||
let root = new Root();
|
||||
root.append(new Rule({ selector: 'a' }));
|
||||
expect(str.style(root.first, 'before')).to.eql('');
|
||||
});
|
||||
|
||||
it('hacks before for first decl', () => {
|
||||
let decl = new Declaration({ prop: 'color', value: 'black' });
|
||||
expect(str.style(decl, 'before')).to.eql('');
|
||||
|
||||
let rule = new Rule({ selector: 'a' });
|
||||
rule.append(decl);
|
||||
expect(str.style(decl, 'before')).to.eql('\n ');
|
||||
});
|
||||
|
||||
it('detects after style', () => {
|
||||
let root = new Root();
|
||||
root.append({ selector: 'a', raw: { after: ' ' } });
|
||||
root.first.append({ prop: 'color', value: 'black' });
|
||||
root.append({ selector: 'a' });
|
||||
expect(str.style(root.last, 'after')).to.eql(' ');
|
||||
});
|
||||
|
||||
it('uses defaults without parent', () => {
|
||||
let rule = new Rule({ selector: 'a' });
|
||||
expect(str.style(rule, 'between', 'beforeOpen')).to.eql(' ');
|
||||
});
|
||||
|
||||
it('uses defaults for unique node', () => {
|
||||
let root = new Root();
|
||||
root.append(new Rule({ selector: 'a' }));
|
||||
expect(str.style(root.first, 'between', 'beforeOpen')).to.eql(' ');
|
||||
});
|
||||
|
||||
it('clones style from first node', () => {
|
||||
let root = new Root();
|
||||
root.append( new Rule({ selector: 'a', raw: { between: '' } }) );
|
||||
root.append( new Rule({ selector: 'b' }) );
|
||||
|
||||
expect(str.style(root.last, 'between', 'beforeOpen')).to.eql('');
|
||||
});
|
||||
|
||||
it('indents by default', () => {
|
||||
let root = new Root();
|
||||
root.append( new AtRule({ name: 'page' }) );
|
||||
root.first.append( new Rule({ selector: 'a' }) );
|
||||
root.first.first.append({ prop: 'color', value: 'black' });
|
||||
|
||||
expect(root.toString()).to.eql('@page {\n' +
|
||||
' a {\n' +
|
||||
' color: black\n' +
|
||||
' }\n' +
|
||||
'}');
|
||||
});
|
||||
|
||||
it('clones indent', () => {
|
||||
let compress = parse('@page{ a{ } }');
|
||||
let spaces = parse('@page {\n a {\n }\n}');
|
||||
|
||||
compress.first.first.append({ prop: 'color', value: 'black' });
|
||||
expect(compress.toString()).to.eql('@page{ a{ color: black } }');
|
||||
|
||||
spaces.first.first.append({ prop: 'color', value: 'black' });
|
||||
expect(spaces.toString())
|
||||
.to.eql('@page {\n a {\n color: black\n }\n}');
|
||||
});
|
||||
|
||||
it('clones indent by types', () => {
|
||||
let css = parse('a {\n color: black\n}\n\nb {\n}');
|
||||
css.append(new Rule({ selector: 'em' }));
|
||||
css.last.append({ prop: 'z-index', value: '1' });
|
||||
|
||||
expect(css.last.toString()).to.eql('\n\nem {\n z-index: 1\n}');
|
||||
});
|
||||
|
||||
it('clones indent by before and after', () => {
|
||||
let css = parse('@page{\n\n a{\n color: black}}');
|
||||
css.first.append(new Rule({ selector: 'b' }));
|
||||
css.first.last.append({ prop: 'z-index', value: '1' });
|
||||
|
||||
expect(css.first.last.toString()).to.eql('\n\n b{\n z-index: 1}');
|
||||
});
|
||||
|
||||
it('clones semicolon only from rules with children', () => {
|
||||
let css = parse('a{}b{one:1;}');
|
||||
expect(str.style(css.first, 'semicolon')).to.be.true;
|
||||
});
|
||||
|
||||
it('clones only spaces in before', () => {
|
||||
let css = parse('a{*one:1}');
|
||||
css.first.append({ prop: 'two', value: '2' });
|
||||
css.append({ name: 'keyframes', params: 'a' });
|
||||
css.last.append({ selector: 'from'});
|
||||
expect(css.toString())
|
||||
.to.eql('a{*one:1;two:2}\n@keyframes a{\nfrom{}}');
|
||||
});
|
||||
|
||||
it('clones only spaces in between', () => {
|
||||
let css = parse('a{one/**/:1}');
|
||||
css.first.append({ prop: 'two', value: '2' });
|
||||
expect(css.toString()).to.eql('a{one/**/:1;two:2}');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user