From da7de8f518dcc26f5ff370aced14839235b2c986 Mon Sep 17 00:00:00 2001 From: Luke Page Date: Mon, 4 Mar 2013 10:43:32 +0000 Subject: [PATCH] move extend fully into visitor, bringing back functionality and fixes #1165 --- lib/less/extend-visitor.js | 38 +++++++++++++++++++++++++++++++----- lib/less/tree/extend.js | 32 +++--------------------------- test/css/extend-media.css | 24 +++++++++++++++++++++++ test/css/extend-selector.css | 4 ++-- test/css/extend.css | 2 +- test/less/extend-media.less | 24 +++++++++++++++++++++++ 6 files changed, 87 insertions(+), 37 deletions(-) create mode 100644 test/css/extend-media.css create mode 100644 test/less/extend-media.less diff --git a/lib/less/extend-visitor.js b/lib/less/extend-visitor.js index 933673a42..1767e6ae1 100644 --- a/lib/less/extend-visitor.js +++ b/lib/less/extend-visitor.js @@ -13,11 +13,9 @@ }, visitRule: function (ruleNode, visitArgs) { visitArgs.visitDeeper = false; - return ruleNode; }, visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { visitArgs.visitDeeper = false; - return mixinDefinitionNode; }, visitRuleset: function (rulesetNode, visitArgs) { @@ -38,7 +36,9 @@ // and the ones which apply to an individual extend for(i = 0; i < rulesetNode.selectors.length; i++) { var selector = rulesetNode.selectors[i]; - extendList = selector.extendList.slice(0).concat(allSelectorsExtendList); + extendList = selector.extendList.slice(0).concat(allSelectorsExtendList.map(function(allSelectorsExtend) { + return allSelectorsExtend.clone(); + })); for(j = 0; j < extendList.length; j++) { extend = extendList[j]; extend.findSelfSelectors([[selector]].concat(this.contexts.slice(0))); @@ -82,16 +82,44 @@ }, visitRule: function (ruleNode, visitArgs) { visitArgs.visitDeeper = false; - return ruleNode; }, visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { visitArgs.visitDeeper = false; - return mixinDefinitionNode; + }, + visitSelector: function (selectorNode, visitArgs) { + visitArgs.visitDeeper = false; }, visitRuleset: function (rulesetNode, visitArgs) { if (rulesetNode.root) { return; } + var i, j, k, selector, element, allExtends = this.allExtendsStack[this.allExtendsStack.length-1], selectorsToAdd = []; + if (allExtends.length) { + for(i = 0; i < rulesetNode.selectors.length; i++) { + selector = rulesetNode.selectors[i]; + for(j = 0; j < selector.elements.length; j++) { + element = selector.elements[j]; + for(k = 0; k < allExtends.length; k++) { + if (allExtends[k].selector.elements[0].value === element.value) { + allExtends[k].selfSelectors.forEach(function(selfSelector) { + selfSelector.elements[0] = new tree.Element( + element.combinator, + selfSelector.elements[0].value, + selfSelector.elements[0].index + ); + selectorsToAdd.push(new tree.Selector( + selector.elements + .slice(0, j) + .concat(selfSelector.elements) + .concat(selector.elements.slice(j + 1)) + )); + }); + } + } + } + } + rulesetNode.selectors = rulesetNode.selectors.concat(selectorsToAdd); + } }, visitRulesetOut: function (rulesetNode) { }, diff --git a/lib/less/tree/extend.js b/lib/less/tree/extend.js index dc0274e35..cd3a5715e 100644 --- a/lib/less/tree/extend.js +++ b/lib/less/tree/extend.js @@ -14,6 +14,9 @@ tree.Extend.prototype = { eval: function (env) { return new(tree.Extend)(this.selector.eval(env), this.option, this.index); }, + clone: function (env) { + return new(tree.Extend)(this.selector, this.option, this.index); + }, findSelfSelectors: function (selectors) { var selfSelectors = []; @@ -31,35 +34,6 @@ tree.Extend.prototype = { })([], 0); this.selfSelectors = selfSelectors; - }, - a: function() { - var selfSelectors = findSelfSelectors(selectors || env.selectors), - targetValue = this.selector.elements[0].value; - - env.frames.forEach(function(frame) { - frame.rulesets().forEach(function(rule) { - rule.selectors.forEach(function(selector) { - selector.elements.forEach(function(element, idx) { - if (element.value === targetValue) { - selfSelectors.forEach(function(_selector) { - _selector.elements[0] = new tree.Element( - element.combinator, - _selector.elements[0].value, - _selector.elements[0].index - ); - rule.selectors.push(new tree.Selector( - selector.elements - .slice(0, idx) - .concat(_selector.elements) - .concat(selector.elements.slice(idx + 1)) - )); - }); - } - }); - }); - }); - }); - return this; } }; diff --git a/test/css/extend-media.css b/test/css/extend-media.css new file mode 100644 index 000000000..23bd7b85c --- /dev/null +++ b/test/css/extend-media.css @@ -0,0 +1,24 @@ +.ext1 .ext2, +.all .ext2 { + background: black; +} +@media tv { + .ext1 .ext3, + .tv-lowres .ext3, + .all .ext3 { + color: white; + } + .tv-lowres { + background: blue; + } +} +@media tv and hires { + .ext1 .ext4, + .tv-hires .ext4, + .all .ext4 { + color: green; + } + .tv-hires { + background: red; + } +} diff --git a/test/css/extend-selector.css b/test/css/extend-selector.css index 44ff1e026..eba41ffa9 100644 --- a/test/css/extend-selector.css +++ b/test/css/extend-selector.css @@ -18,10 +18,10 @@ .foo .bar, .foo .baz, .ext1 .ext2 .bar, -.ext1 .ext2 .baz, .ext3 .bar, -.ext3 .baz, .ext4 .bar, +.ext1 .ext2 .baz, +.ext3 .baz, .ext4 .baz { display: none; } diff --git a/test/css/extend.css b/test/css/extend.css index 9ab13ea74..c96459750 100644 --- a/test/css/extend.css +++ b/test/css/extend.css @@ -18,9 +18,9 @@ .foo .bar, .foo .baz, .ext1 .ext2 .bar, -.ext1 .ext2 .baz, .ext3 .bar, .ext4 .bar, +.ext1 .ext2 .baz, .ext3 .baz, .ext4 .baz { display: none; diff --git a/test/less/extend-media.less b/test/less/extend-media.less new file mode 100644 index 000000000..1b22c3faf --- /dev/null +++ b/test/less/extend-media.less @@ -0,0 +1,24 @@ +.ext1 .ext2 { + background: black; +} + +@media tv { + .ext1 .ext3 { + color: white; + } + .tv-lowres :extend(.ext1 all) { + background: blue; + } + @media hires { + .ext1 .ext4 { + color: green; + } + .tv-hires :extend(.ext1 all) { + background: red; + } + } +} + +.all:extend(.ext1 all) { + +} \ No newline at end of file