Skip to content

Commit 84a5154

Browse files
committed
Fix tests
1 parent 1aaf5eb commit 84a5154

File tree

2 files changed

+67
-68
lines changed

2 files changed

+67
-68
lines changed

src/parser.js

Lines changed: 67 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import Universal from './selectors/universal';
1111
import Combinator from './selectors/combinator';
1212
import Nesting from './selectors/nesting';
1313

14-
import sortAsc from './sortAscending';
1514
import tokenize, {FIELDS as TOKEN} from './tokenize';
1615

1716
import * as tokens from './tokenTypes';
@@ -95,23 +94,6 @@ function unescapeProp (node, prop) {
9594
return node;
9695
}
9796

98-
function indexesOf (array, item) {
99-
let i = -1;
100-
const indexes = [];
101-
102-
while ((i = array.indexOf(item, i + 1)) !== -1) {
103-
indexes.push(i);
104-
}
105-
106-
return indexes;
107-
}
108-
109-
function uniqs () {
110-
const list = Array.prototype.concat.apply([], arguments);
111-
112-
return list.filter((item, i) => i === list.indexOf(item));
113-
}
114-
11597
export default class Parser {
11698
constructor (rule, options = {}) {
11799
this.rule = rule;
@@ -818,74 +800,94 @@ export default class Parser {
818800
}
819801

820802
splitWord (namespace, firstCallback) {
803+
// Collect all the relevant tokens together
804+
const tokensList = [this.currToken];
821805
let nextToken = this.nextToken;
822-
let word = this.content();
823806
while (
824807
nextToken &&
825808
~[tokens.dollar, tokens.caret, tokens.equals, tokens.word].indexOf(nextToken[TOKEN.TYPE])
826809
) {
827810
this.position ++;
828-
let current = this.content();
829-
word += current;
830-
if (current.lastIndexOf('\\') === current.length - 1) {
811+
const token = this.currToken;
812+
tokensList.push(token);
813+
if (this.content(token).endsWith('\\')) {
831814
let next = this.nextToken;
832815
if (next && next[TOKEN.TYPE] === tokens.space) {
833-
word += this.requiredSpace(this.content(next));
816+
tokensList.push(next);
834817
this.position ++;
835818
}
836819
}
837820
nextToken = this.nextToken;
838821
}
839-
const hasClass = indexesOf(word, '.').filter(i => word[i - 1] !== '\\');
840-
let hasId = indexesOf(word, '#').filter(i => word[i - 1] !== '\\');
841-
// Eliminate Sass interpolations from the list of id indexes
842-
const interpolations = indexesOf(word, '#{');
843-
if (interpolations.length) {
844-
hasId = hasId.filter(hashIndex => !~interpolations.indexOf(hashIndex));
822+
823+
// Get the content of each token
824+
const tokensContent = tokensList.map(token => {
825+
if (token[TOKEN.TYPE] === tokens.space) {
826+
return this.requiredSpace(token);
827+
}
828+
return this.content(token);
829+
});
830+
831+
// Parse the list of tokens and create a list of new nodes
832+
const nodesToCreate = [];
833+
let inProgressNode;
834+
tokensList.forEach((token, tokenIndex) => {
835+
const content = tokensContent[tokenIndex];
836+
for (let i = 0; i < content.length; i++) {
837+
const char = content[i];
838+
const prevChar = content[i - 1] || (tokenIndex !== 0 ? tokensContent[tokenIndex - 1].slice(-1) : undefined);
839+
const nextChar = content[i + 1] || (tokenIndex !== tokensContent.length - 1 ? tokensContent[tokenIndex + 1][0] : undefined);
840+
841+
if (char === "." && prevChar !== "\\") {
842+
initNode(ClassName);
843+
} else if (char === "#" && prevChar !== "\\" && nextChar !== "{") {
844+
initNode(ID);
845+
} else if (!inProgressNode) {
846+
initNode(Tag, char);
847+
} else {
848+
inProgressNode.value += char;
849+
inProgressNode.endToken = token;
850+
inProgressNode.endIndex = i;
851+
}
852+
853+
function initNode (NodeConstructor, value = "") {
854+
if (inProgressNode) {
855+
nodesToCreate.push(inProgressNode);
856+
}
857+
inProgressNode = {
858+
NodeConstructor,
859+
value,
860+
startToken: token,
861+
endToken: token,
862+
startIndex: i,
863+
endIndex: i,
864+
};
865+
}
866+
}
867+
});
868+
if (inProgressNode) {
869+
nodesToCreate.push(inProgressNode);
845870
}
846-
let indices = sortAsc(uniqs([0, ...hasClass, ...hasId]));
847-
indices.forEach((ind, i) => {
848-
const index = indices[i + 1] || word.length;
849-
const value = word.slice(ind, index);
871+
872+
nodesToCreate.forEach((node, i) => {
850873
if (i === 0 && firstCallback) {
851-
return firstCallback.call(this, value, indices.length);
874+
firstCallback.call(this, node.value, nodesToCreate.length);
875+
return;
852876
}
853-
let node;
854-
const current = this.currToken;
855-
const sourceIndex = current[TOKEN.START_POS] + indices[i];
877+
const {NodeConstructor, value, startToken, endToken, startIndex, endIndex} = node;
878+
const sourceIndex = startToken[TOKEN.START_POS] + startIndex;
856879
const source = getSource(
857-
current[1],
858-
current[2] + ind,
859-
current[3],
860-
current[2] + (index - 1)
880+
startToken[TOKEN.START_LINE],
881+
startToken[TOKEN.START_COL] + startIndex,
882+
endToken[TOKEN.END_LINE],
883+
endToken[TOKEN.START_COL] + endIndex
861884
);
862-
if (~hasClass.indexOf(ind)) {
863-
let classNameOpts = {
864-
value: value.slice(1),
865-
source,
866-
sourceIndex,
867-
};
868-
node = new ClassName(unescapeProp(classNameOpts, "value"));
869-
} else if (~hasId.indexOf(ind)) {
870-
let idOpts = {
871-
value: value.slice(1),
872-
source,
873-
sourceIndex,
874-
};
875-
node = new ID(unescapeProp(idOpts, "value"));
876-
} else {
877-
let tagOpts = {
878-
value,
879-
source,
880-
sourceIndex,
881-
};
882-
unescapeProp(tagOpts, "value");
883-
node = new Tag(tagOpts);
884-
}
885-
this.newNode(node, namespace);
885+
const opts = unescapeProp({value, source, sourceIndex}, "value");
886+
this.newNode(new NodeConstructor(opts), namespace);
886887
// Ensure that the namespace is used only once
887888
namespace = null;
888889
});
890+
889891
this.position ++;
890892
}
891893

src/sortAscending.js

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)