1
1
'use strict' ;
2
2
3
3
var postcss = require ( 'postcss' ) ;
4
- // /*DEBUG*/ var appendout = require('fs').appendFileSync;
4
+ // /*DEBUG*/var appendout = require('fs').appendFileSync;
5
5
6
6
module . exports = postcss . plugin ( 'postcss-extend' , function extend ( ) {
7
7
@@ -11,7 +11,7 @@ module.exports = postcss.plugin('postcss-extend', function extend() {
11
11
var recurseStack = [ ] ;
12
12
var isAntiPatternCSS = false ;
13
13
14
- // /*DEBUG*/ appendout('./test/debugout.txt', '\n----------------------------------------');
14
+ // /*DEBUG*/appendout('./test/debugout.txt', '\n----------------------------------------');
15
15
16
16
css . walkAtRules ( function ( atRule ) {
17
17
if ( definingAtRules . indexOf ( atRule . name ) !== - 1 ) {
@@ -35,8 +35,8 @@ module.exports = postcss.plugin('postcss-extend', function extend() {
35
35
}
36
36
} else if ( tgtSaved . length === 1 ) {
37
37
targetNode . remove ( ) ;
38
- // /*DEBUG*/ } else {
39
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nSifted out placeholder/silent ' + tgtSaved[i]);
38
+ // /*DEBUG*/} else {
39
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nSifted out placeholder/silent ' + tgtSaved[i]);
40
40
}
41
41
}
42
42
if ( selectorAccumulator ) {
@@ -65,7 +65,7 @@ module.exports = postcss.plugin('postcss-extend', function extend() {
65
65
definition . append ( clone ) ;
66
66
} ) ;
67
67
definition . selector = '@define-placeholder ' + atRule . params . toString ( ) ;
68
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nDeclaring placeholder : ' + definition.selector);
68
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nDeclaring placeholder : ' + definition.selector);
69
69
atRule . parent . insertBefore ( atRule , definition ) ;
70
70
atRule . remove ( ) ;
71
71
}
@@ -93,9 +93,9 @@ module.exports = postcss.plugin('postcss-extend', function extend() {
93
93
//Strip all @define -placeholders and save slug-selectors present in tgtSaved
94
94
for ( var i = 0 ; i < tgtSaved . length ; i ++ ) {
95
95
if ( tgtSaved [ i ] . substring ( 0 , 20 ) === '@define-placeholder ' ) {
96
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nn[' + i + ']String = ' + tgtSaved[i] + ' Substring 0-20 = \'' + tgtSaved[i].substring(0, 20) + '\'');
96
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nn[' + i + ']String = ' + tgtSaved[i] + ' Substring 0-20 = \'' + tgtSaved[i].substring(0, 20) + '\'');
97
97
tgtSaved [ i ] = tgtSaved [ i ] . substring ( 20 , ( tgtSaved [ i ] . length ) ) ;
98
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nresString = \'' + tgtSaved[i] + '\'');
98
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nresString = \'' + tgtSaved[i] + '\'');
99
99
}
100
100
}
101
101
var tgtAccumulate = targetNode . selectors ;
@@ -106,15 +106,15 @@ module.exports = postcss.plugin('postcss-extend', function extend() {
106
106
//check if target has unresolved extensions, then extend them
107
107
if ( extensionRecursionHandler ( atRule , targetNode ) ) {
108
108
//We need to re-evaluate the current atRule, as other classes (once passed over) may now be matching, so re-process and exit.
109
- // /*DEBUG*/ appendout('./test/debugout.txt', '\n!Bumping evaluation of :' + atRule.parent);
109
+ // /*DEBUG*/appendout('./test/debugout.txt', '\n!Bumping evaluation of :' + atRule.parent);
110
110
processExtension ( atRule ) ;
111
111
couldExtend = true ;
112
112
return ;
113
113
}
114
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nfound and extending : ' + tgtSaved[n] + ' : ' + originSels);
114
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nfound and extending : ' + tgtSaved[n] + ' : ' + originSels);
115
115
116
116
tgtAccumulate = tgtAccumulate . concat ( originSels ) ;
117
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nCombined selectors :\n' + tgtAccumulate);
117
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nCombined selectors :\n' + tgtAccumulate);
118
118
couldExtend = true ;
119
119
//Operate on sub-elements of extendables (thus extending them)
120
120
} else if ( tgtSaved [ n ] . substring ( 1 ) . search ( / [ \s . : # ] / ) + 1 !== - 1 ) {
@@ -124,32 +124,32 @@ module.exports = postcss.plugin('postcss-extend', function extend() {
124
124
//check if target rule has unresolved extensions, then extend them
125
125
if ( extensionRecursionHandler ( atRule , targetNode ) ) {
126
126
//We need to re-evaluate the current atRule, as other classes (once passed over) may now be matching, so re-process and exit.
127
- // /*DEBUG*/ appendout('./test/debugout.txt', '\n!Bumping evaluation of :' + atRule.parent);
127
+ // /*DEBUG*/appendout('./test/debugout.txt', '\n!Bumping evaluation of :' + atRule.parent);
128
128
processExtension ( atRule ) ;
129
129
couldExtend = true ;
130
130
return ;
131
131
}
132
132
//tack onto target node
133
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nfound and extending : ' + tgtSaved[n].substring(0, tgtSaved[n].substring(1).search(/[\s.:#]/) + 1) + ' :\n' + tgtBase + ' (' + tgtSub + ')');
133
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nfound and extending : ' + tgtSaved[n].substring(0, tgtSaved[n].substring(1).search(/[\s.:#]/) + 1) + ' :\n' + tgtBase + ' (' + tgtSub + ')');
134
134
135
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nCalling formSubSelector with (\n' + originSels + ',\n' + tgtSub);
135
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nCalling formSubSelector with (\n' + originSels + ',\n' + tgtSub);
136
136
tgtAccumulate = tgtAccumulate . concat ( formSubSelector ( originSels , tgtSub ) ) ;
137
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nCombined selectors :\n' + tgtAccumulate);
137
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nCombined selectors :\n' + tgtAccumulate);
138
138
couldExtend = true ;
139
139
}
140
140
} //END OF sub root-extensions
141
141
}
142
142
if ( couldExtend ) {
143
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nStart uniqreq2 :\n' + tgtAccumulate);
143
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nStart uniqreq2 :\n' + tgtAccumulate);
144
144
//Kill off duplicate selectors
145
145
tgtAccumulate = uniqreq ( tgtAccumulate ) . toString ( ) . replace ( / , / g, ', ' ) ;
146
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nPost uniqreq2 :\n' + tgtAccumulate);
146
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nPost uniqreq2 :\n' + tgtAccumulate);
147
147
targetNode . selector = tgtAccumulate ;
148
148
}
149
149
} ) ;
150
150
//hasMediaAncestor === true: ---------------
151
151
} else {
152
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nAttempting to fetch declarations for ' + atRule.params + '...');
152
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nAttempting to fetch declarations for ' + atRule.params + '...');
153
153
var backFirstTargetNode ;
154
154
var targetNodeArray = [ ] ;
155
155
css . walkRules ( function ( subRule ) {
@@ -177,19 +177,19 @@ module.exports = postcss.plugin('postcss-extend', function extend() {
177
177
//check if rule has unresolved extensions, then extend them
178
178
if ( extensionRecursionHandler ( atRule , backFirstTargetNode ) ) {
179
179
//We need to re-evaluate the current atRule, as other classes (once passed over) may now be matching, so re-process and exit.
180
- // /*DEBUG*/ appendout('./test/debugout.txt', '\n!Bumping evaluation of :' + atRule.parent);
180
+ // /*DEBUG*/appendout('./test/debugout.txt', '\n!Bumping evaluation of :' + atRule.parent);
181
181
processExtension ( atRule ) ;
182
182
couldExtend = true ;
183
183
return ;
184
184
}
185
185
//In scope, tack on selector to target rule
186
186
if ( backFirstTargetNode . parent === atRule . parent . parent ) {
187
- // /*DEBUG*/ appendout('./test/debugout.txt', '\n...tacking onto backFirstTargetNode :' + backFirstTargetNode);
187
+ // /*DEBUG*/appendout('./test/debugout.txt', '\n...tacking onto backFirstTargetNode :' + backFirstTargetNode);
188
188
selectorRetainer = backFirstTargetNode . selectors ;
189
189
backFirstTargetNode . selector = uniqreq ( selectorRetainer . concat ( originSels ) ) . join ( ', ' ) ;
190
190
//Out of scope, direcly copy declarations
191
191
} else {
192
- // /*DEBUG*/ appendout('./test/debugout.txt', '\n...grabbing backFirstTargetNode :\n' + backFirstTargetNode);
192
+ // /*DEBUG*/appendout('./test/debugout.txt', '\n...grabbing backFirstTargetNode :\n' + backFirstTargetNode);
193
193
safeCopyDeclarations ( backFirstTargetNode , atRule . parent ) ;
194
194
}
195
195
couldExtend = true ;
@@ -202,26 +202,26 @@ module.exports = postcss.plugin('postcss-extend', function extend() {
202
202
//check if target rule has unresolved extensions, then extend them
203
203
if ( extensionRecursionHandler ( atRule , backFirstTargetNode ) ) {
204
204
//We need to re-evaluate the current atRule, as other classes (once passed over) may now be matching, so re-process and exit.
205
- // /*DEBUG*/ appendout('./test/debugout.txt', '\n!Bumping evaluation of :' + atRule.parent);
205
+ // /*DEBUG*/appendout('./test/debugout.txt', '\n!Bumping evaluation of :' + atRule.parent);
206
206
processExtension ( atRule ) ;
207
207
couldExtend = true ;
208
208
return ;
209
209
}
210
210
if ( backFirstTargetNode . parent === atRule . parent . parent ) {
211
211
//Use Tacking onto exiting selectors instead of new creation
212
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nUtilizing existing brother subclass for extension, as nothing matches: \n' + atRule.parent.selector + ' sub-' + extTgtSub);
212
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nUtilizing existing brother subclass for extension, as nothing matches: \n' + atRule.parent.selector + ' sub-' + extTgtSub);
213
213
selectorRetainer = backFirstTargetNode . selectors ;
214
214
backFirstTargetNode . selector = uniqreq ( selectorRetainer . concat ( formSubSelector ( originSels , extTgtSub ) ) ) . join ( ', ' ) ;
215
215
} else {
216
216
//check for prexisting sub classes before making one
217
217
subTarget = findBrotherSubClass ( atRule . parent , extTgtSub ) ;
218
218
if ( subTarget . bool ) {
219
219
//utilize existing subclass for extension
220
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nUtilizing existing subclass for extension:\n' + subTarget.selector);
220
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nUtilizing existing subclass for extension:\n' + subTarget.selector);
221
221
safeCopyDeclarations ( backFirstTargetNode , subTarget . node ) ;
222
222
} else {
223
223
//create additional nodes below existing for each instance of subs
224
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nUtilizing new subclass for extension, as nothing matches: \n' + atRule.parent.selector + ' sub-' + extTgtSub);
224
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nUtilizing new subclass for extension, as nothing matches: \n' + atRule.parent.selector + ' sub-' + extTgtSub);
225
225
var newNode = postcss . rule ( ) ;
226
226
newNode . semicolon = atRule . semicolon ;
227
227
safeCopyDeclarations ( backFirstTargetNode , newNode ) ;
@@ -237,7 +237,7 @@ module.exports = postcss.plugin('postcss-extend', function extend() {
237
237
} //end of if hasMediaAncestor
238
238
if ( ! couldExtend ) {
239
239
result . warn ( '\'' + atRule . params + '\', has not been defined, so it cannot be extended' , { node : atRule } ) ;
240
- // /*DEBUG*/ appendout('./test/debugout.txt', '\n\'' + atRule.params + '\' has not been defined!!!');
240
+ // /*DEBUG*/appendout('./test/debugout.txt', '\n\'' + atRule.params + '\' has not been defined!!!');
241
241
}
242
242
if ( atRule . parent !== undefined ) {
243
243
if ( ! atRule . parent . nodes . length || atRule . parent . nodes . length === 1 ) {
@@ -287,7 +287,7 @@ module.exports = postcss.plugin('postcss-extend', function extend() {
287
287
288
288
function isBadExtensionPair ( atRule , targetNode ) {
289
289
if ( hasMediaAncestor ( targetNode ) && hasMediaAncestor ( atRule ) && targetNode . parent !== atRule . parent . parent ) {
290
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nMEDIA2MEDIA extention detected, node :\n' + atRule.parent);
290
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nMEDIA2MEDIA extention detected, node :\n' + atRule.parent);
291
291
result . warn ( '@extend was called to extend something in an @media from within another @media, this was safely ignored. For more information see the README under \'Quirks\'' , { node : atRule } ) ;
292
292
return true ;
293
293
}
@@ -317,10 +317,10 @@ module.exports = postcss.plugin('postcss-extend', function extend() {
317
317
nodeOrigin . nodes . forEach ( function ( node ) {
318
318
if ( isBadDefinitionNode ( node ) ) return ;
319
319
if ( nodeDest . some ( function ( decl ) { return decl . prop === node . prop ; } ) ) {
320
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nsafeIgnored : ' + node + ' for ' + nodeDest.selector);
320
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nsafeIgnored : ' + node + ' for ' + nodeDest.selector);
321
321
return ;
322
322
}
323
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nnodeDest Nodes:\n' + nodeDest.nodes);
323
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nnodeDest Nodes:\n' + nodeDest.nodes);
324
324
var clone = node . clone ( ) ;
325
325
//For lack of a better way to analyse how much tabbing is required:
326
326
if ( nodeOrigin . parent === nodeDest . parent ) {
@@ -364,12 +364,12 @@ module.exports = postcss.plugin('postcss-extend', function extend() {
364
364
// Throw this error only once, and only if it's an antipattern
365
365
// Make sure index could be obtained for atRule parent
366
366
if ( css . index ( atRule . parent ) !== - 1 ) {
367
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nANTIPATTERN CSS detected parent at: ' + css.index(atRule.parent) + ' target at: ' + css.index(targetNode) + ' parent :\n' + atRule.parent);
367
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nANTIPATTERN CSS detected parent at: ' + css.index(atRule.parent) + ' target at: ' + css.index(targetNode) + ' parent :\n' + atRule.parent);
368
368
result . warn ( '@extend is being used in an anti-pattern (extending things not yet defined). This is your first and final warning' , { node : atRule } ) ;
369
369
isAntiPatternCSS = true ;
370
370
// If index couldn't be obtained on atRule, check up the chain a step
371
371
} else if ( css . index ( atRule . parent . parent ) !== - 1 && css . index ( atRule . parent . parent ) < css . index ( targetNode ) ) {
372
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nANTIPATTERN CSS detected parent\'s parent at: ' + css.index(atRule.parent.parent) + ' target at: ' + css.index(targetNode) + ' parent :\n' + atRule.parent);
372
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nANTIPATTERN CSS detected parent\'s parent at: ' + css.index(atRule.parent.parent) + ' target at: ' + css.index(targetNode) + ' parent :\n' + atRule.parent);
373
373
result . warn ( '@extend is being used in an anti-pattern (extending things not yet defined). This is your first and final warning' , { node : atRule } ) ;
374
374
isAntiPatternCSS = true ;
375
375
}
@@ -378,33 +378,33 @@ module.exports = postcss.plugin('postcss-extend', function extend() {
378
378
recurseStack . push ( atRule . params ) ;
379
379
while ( recursableRule . bool ) {
380
380
if ( recurseStack . indexOf ( recursableRule . node . params ) === - 1 ) {
381
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nRecursing from ' + atRule.parent.selector + ' on: ' + recursableRule.node.parent + '\n\\/\\/\\/\\/\\/\\/\\/\\/ ' + recurseStack);
381
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nRecursing from ' + atRule.parent.selector + ' on: ' + recursableRule.node.parent + '\n\\/\\/\\/\\/\\/\\/\\/\\/ ' + recurseStack);
382
382
processExtension ( recursableRule . node ) ;
383
- // /*DEBUG*/ appendout('./test/debugout.txt', '\n ^ ^ ^ ^ ^ ^ ^ ^ ' + recurseStack);
383
+ // /*DEBUG*/appendout('./test/debugout.txt', '\n ^ ^ ^ ^ ^ ^ ^ ^ ' + recurseStack);
384
384
// In case of slippage in processExtention recursion, clean up @extend
385
385
if ( recursableRule . node !== undefined ) {
386
- // /*DEBUG*/ appendout('./test/debugout.txt', '\npreventing slippage in recursion by removing resolved :' + recursableRule.node);
386
+ // /*DEBUG*/appendout('./test/debugout.txt', '\npreventing slippage in recursion by removing resolved :' + recursableRule.node);
387
387
recursableRule . node . remove ( ) ;
388
388
}
389
389
recursableRule = findUnresolvedExtendChild ( targetNode ) ;
390
390
} else {
391
391
result . warn ( 'Infinite extension recursion detected' , { node : atRule } ) ;
392
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nInfinite Recursion detected, recurseStack : ' + recurseStack + '\n -- on :\n' + atRule.parent + '\n!!!!!!!!!!!!');
392
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nInfinite Recursion detected, recurseStack : ' + recurseStack + '\n -- on :\n' + atRule.parent + '\n!!!!!!!!!!!!');
393
393
//clean out the recurse stack of duplicates (from early aborts like this) before dropping
394
394
recurseStack = uniqreq ( recurseStack ) ;
395
395
return false ;
396
396
}
397
397
}
398
398
399
- // /*DEBUG*/ appendout('./test/debugout.txt', '\npre-pop recurseStack : ' + recurseStack);
399
+ // /*DEBUG*/appendout('./test/debugout.txt', '\npre-pop recurseStack : ' + recurseStack);
400
400
if ( recurseStack . pop ( ) !== atRule . params && recurseStack . indexOf ( atRule . params ) === - 1 ) {
401
401
result . warn ( 'Detected critically mis-aligned recursion stack! (Please post your CSS in a github issue, this shouldn\'t ever happen!)' , { node : atRule } ) ;
402
- // /*DEBUG*/ appendout('./test/debugout.txt', '\n!!!!!!!!!!!!CRITICALLY MISALIGNED RECURSE STACK\nexpected : ' + atRule.params + '\npost-pop recurseStack : ' + recurseStack);
402
+ // /*DEBUG*/appendout('./test/debugout.txt', '\n!!!!!!!!!!!!CRITICALLY MISALIGNED RECURSE STACK\nexpected : ' + atRule.params + '\npost-pop recurseStack : ' + recurseStack);
403
403
}
404
404
//Empty history if this is top of a recursion (as process preserves detections as it backs-out)
405
405
if ( isTopOfRecurse ) {
406
406
recurseStack = [ ] ;
407
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nrecurseStack dumped, at top');
407
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nrecurseStack dumped, at top');
408
408
}
409
409
return true ;
410
410
}
@@ -422,7 +422,7 @@ module.exports = postcss.plugin('postcss-extend', function extend() {
422
422
if ( node !== nodeOrigin && selectorAccumulator . length === node . selectors . length ) {
423
423
seldiff = seldiff . concat ( selectorAccumulator ) ;
424
424
seldiff = uniqreq ( seldiff ) ;
425
- // /*DEBUG*/ appendout('./test/debugout.txt', '\nseldiff : ' + seldiff + '\n\tBetween:\n' + node.selectors + '\n\tand:\n' + selectorAccumulator);
425
+ // /*DEBUG*/appendout('./test/debugout.txt', '\nseldiff : ' + seldiff + '\n\tBetween:\n' + node.selectors + '\n\tand:\n' + selectorAccumulator);
426
426
if ( seldiff . length === selectorAccumulator . length ) {
427
427
foundNode = node ;
428
428
return true ;
0 commit comments