Skip to content

Commit 1ac77a7

Browse files
committed
feat(list_item_hunter): Re-work algorithm
Now list_item_hunter does almost nothing, transforming the spec syntax into a friendly single value (rather than nested with a period), so that we can ALSO transform listItem data into the same structure - meaning `2` in the json becomes `listItem-two` - which can very easily by looped over by mustache. this change should be further vetted
1 parent c722868 commit 1ac77a7

13 files changed

+288
-702
lines changed

core/lib/buildListItems.js

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,30 @@
11
'use strict';
22

3-
const _ = require('lodash');
3+
let _ = require('lodash'); //eslint-disable-line prefer-const
4+
5+
const items = [
6+
'zero',
7+
'one',
8+
'two',
9+
'three',
10+
'four',
11+
'five',
12+
'six',
13+
'seven',
14+
'eight',
15+
'nine',
16+
'ten',
17+
'eleven',
18+
'twelve',
19+
'thirteen',
20+
'fourteen',
21+
'fifteen',
22+
'sixteen',
23+
'seventeen',
24+
'eighteen',
25+
'nineteen',
26+
'twenty',
27+
];
428

529
module.exports = function(container) {
630
//combine all list items into one structure
@@ -10,17 +34,19 @@ module.exports = function(container) {
1034
list.push(container.listitems[item]);
1135
}
1236
}
13-
container.listItemArray = _.shuffle(list);
37+
const listItemArray = _.shuffle(list);
1438

15-
for (let i = 1; i <= container.listItemArray.length; i++) {
39+
for (let i = 1; i <= listItemArray.length; i++) {
1640
const tempItems = [];
1741
if (i === 1) {
18-
tempItems.push(container.listItemArray[0]);
19-
container.listitems['' + i] = tempItems;
42+
tempItems.push(listItemArray[0]);
43+
container.listitems['listItems-' + items[i]] = tempItems;
44+
delete container.listitems[i];
2045
} else {
2146
for (let c = 1; c <= i; c++) {
22-
tempItems.push(container.listItemArray[c - 1]);
23-
container.listitems['' + i] = tempItems;
47+
tempItems.push(listItemArray[c - 1]);
48+
container.listitems['listItems-' + items[i]] = tempItems;
49+
delete container.listitems[i];
2450
}
2551
}
2652
}

core/lib/list_item_hunter.js

Lines changed: 20 additions & 226 deletions
Original file line numberDiff line numberDiff line change
@@ -1,244 +1,38 @@
11
'use strict';
22

33
const list_item_hunter = function() {
4-
const extend = require('util')._extend;
5-
const _ = require('lodash');
6-
const smh = require('./style_modifier_hunter');
7-
const jsonCopy = require('./json_copy');
8-
const Pattern = require('./object_factory').Pattern;
9-
104
const logger = require('./log');
11-
const parseLink = require('./parseLink');
12-
const getPartial = require('./get');
13-
const render = require('./render');
14-
15-
const style_modifier_hunter = new smh();
16-
const items = [
17-
'zero',
18-
'one',
19-
'two',
20-
'three',
21-
'four',
22-
'five',
23-
'six',
24-
'seven',
25-
'eight',
26-
'nine',
27-
'ten',
28-
'eleven',
29-
'twelve',
30-
'thirteen',
31-
'fourteen',
32-
'fifteen',
33-
'sixteen',
34-
'seventeen',
35-
'eighteen',
36-
'nineteen',
37-
'twenty',
38-
];
395

40-
function processListItemPartials(pattern, patternlab) {
6+
function processListItemPartials(pattern) {
417
//find any listitem blocks
428
const matches = pattern.findListItems();
439

4410
if (matches !== null) {
45-
return matches.reduce((previousMatchPromise, liMatch) => {
11+
return matches.reduce((previousMatchPromise, liMatchStart) => {
4612
return previousMatchPromise.then(() => {
4713
logger.debug(
48-
`found listItem of size ${liMatch} inside ${pattern.patternPartial}`
14+
`found listItem of size ${liMatchStart} inside ${
15+
pattern.patternPartial
16+
}`
4917
);
5018

51-
//find the boundaries of the block
52-
const loopNumberString = liMatch
53-
.split('.')[1]
54-
.split('}')[0]
55-
.trim();
56-
const end = liMatch.replace('#', '/');
57-
const patternBlock = pattern.template
58-
.substring(
59-
pattern.template.indexOf(liMatch) + liMatch.length,
60-
pattern.template.indexOf(end)
61-
)
62-
.trim();
63-
64-
//build arrays that repeat the block, however large we need to
65-
const repeatedBlockTemplate = [];
66-
67-
//what we will eventually replace our template's listitems block with
68-
let repeatedBlockHtml = '';
69-
70-
for (let i = 0; i < items.indexOf(loopNumberString); i++) {
71-
logger.debug(
72-
`list item(s) in pattern ${
73-
pattern.patternPartial
74-
}, adding ${patternBlock} to repeatedBlockTemplate`
75-
);
76-
repeatedBlockTemplate.push(patternBlock);
77-
}
78-
79-
//check for a local listitems.json file
80-
let listData;
81-
try {
82-
listData = jsonCopy(
83-
patternlab.listitems,
84-
'config.paths.source.data listitems'
85-
);
86-
} catch (err) {
87-
logger.warning(
88-
`There was an error parsing JSON for ${pattern.relPath}`
89-
);
90-
logger.warning(err);
91-
}
92-
93-
listData = _.merge(listData, pattern.listitems);
94-
listData = parseLink(
95-
patternlab,
96-
listData,
97-
'listitems.json + any pattern listitems.json'
19+
//we found a listitem match
20+
//replace it's beginning listitems.number with -number
21+
const newStart = liMatchStart.replace('.', '-');
22+
pattern.extendedTemplate = pattern.extendedTemplate.replace(
23+
liMatchStart,
24+
newStart
9825
);
9926

100-
//iterate over each copied block, rendering its contents
101-
const allBlocks = repeatedBlockTemplate.reduce(
102-
(previousPromise, currentBlockTemplate, index) => {
103-
let thisBlockTemplate = currentBlockTemplate;
104-
105-
return previousPromise
106-
.then(() => {
107-
//combine listItem data with pattern data with global data
108-
const itemData =
109-
listData['' + items.indexOf(loopNumberString)]; //this is a property like "2"
110-
let globalData;
111-
let localData;
112-
try {
113-
globalData = jsonCopy(
114-
patternlab.data,
115-
'config.paths.source.data global data'
116-
);
117-
localData = jsonCopy(
118-
pattern.jsonFileData,
119-
`${pattern.patternPartial} data`
120-
);
121-
} catch (err) {
122-
logger.warning(
123-
`There was an error parsing JSON for ${pattern.relPath}`
124-
);
125-
logger.warning(err);
126-
}
127-
128-
let allData = _.merge(globalData, localData);
129-
allData = _.merge(
130-
allData,
131-
itemData !== undefined ? itemData[index] : {}
132-
); //itemData could be undefined if the listblock contains no partial, just markup
133-
allData.link = extend({}, patternlab.data.link);
134-
135-
//check for partials within the repeated block
136-
const foundPartials = Pattern.createEmpty({
137-
template: thisBlockTemplate,
138-
}).findPartials();
139-
140-
let renderPromise = undefined;
141-
142-
if (foundPartials && foundPartials.length > 0) {
143-
for (let j = 0; j < foundPartials.length; j++) {
144-
//get the partial
145-
const partialName = foundPartials[j].match(
146-
/([\w\-\.\/~]+)/g
147-
)[0];
148-
const partialPattern = getPartial(
149-
partialName,
150-
patternlab
151-
);
152-
153-
//create a copy of the partial so as to not pollute it after the get_pattern_by_key call.
154-
let cleanPartialPattern;
155-
try {
156-
cleanPartialPattern = JSON.parse(
157-
JSON.stringify(partialPattern)
158-
);
159-
cleanPartialPattern = jsonCopy(
160-
partialPattern,
161-
`partial pattern ${partialName}`
162-
);
163-
} catch (err) {
164-
logger.warning(
165-
`There was an error parsing JSON for ${
166-
pattern.relPath
167-
}`
168-
);
169-
logger.warning(err);
170-
}
171-
172-
//if we retrieved a pattern we should make sure that its extendedTemplate is reset. looks to fix #356
173-
cleanPartialPattern.extendedTemplate =
174-
cleanPartialPattern.template;
175-
176-
//if partial has style modifier data, replace the styleModifier value
177-
if (foundPartials[j].indexOf(':') > -1) {
178-
style_modifier_hunter.consume_style_modifier(
179-
cleanPartialPattern,
180-
foundPartials[j],
181-
patternlab
182-
);
183-
}
184-
185-
//replace its reference within the block with the extended template
186-
thisBlockTemplate = thisBlockTemplate.replace(
187-
foundPartials[j],
188-
cleanPartialPattern.extendedTemplate
189-
);
190-
}
191-
192-
//render with data
193-
renderPromise = render(
194-
Pattern.createEmpty({ template: thisBlockTemplate }),
195-
allData,
196-
patternlab.partials
197-
);
198-
} else {
199-
//just render with mergedData
200-
renderPromise = render(
201-
Pattern.createEmpty({ template: thisBlockTemplate }),
202-
allData,
203-
patternlab.partials
204-
);
205-
}
206-
207-
return renderPromise
208-
.then(thisBlockHTML => {
209-
//add the rendered HTML to our string
210-
repeatedBlockHtml = repeatedBlockHtml + thisBlockHTML;
211-
})
212-
.catch(reason => {
213-
logger.error(reason);
214-
});
215-
})
216-
.catch(reason => {
217-
logger.error(reason);
218-
});
219-
},
220-
Promise.resolve()
27+
//replace it's ending listitems.number with -number
28+
const liMatchEnd = liMatchStart.replace('#', '/');
29+
const newEnd = liMatchEnd.replace('.', '-');
30+
pattern.extendedTemplate = pattern.extendedTemplate.replace(
31+
liMatchEnd,
32+
newEnd
22133
);
22234

223-
return allBlocks
224-
.then(() => {
225-
//replace the block with our generated HTML
226-
const repeatingBlock = pattern.extendedTemplate.substring(
227-
pattern.extendedTemplate.indexOf(liMatch),
228-
pattern.extendedTemplate.indexOf(end) + end.length
229-
);
230-
pattern.extendedTemplate = pattern.extendedTemplate.replace(
231-
repeatingBlock,
232-
repeatedBlockHtml
233-
);
234-
235-
//update the extendedTemplate in the partials object in case this pattern is consumed later
236-
patternlab.partials[pattern.patternPartial] =
237-
pattern.extendedTemplate;
238-
})
239-
.catch(reason => {
240-
logger.error(reason);
241-
});
35+
return Promise.resolve();
24236
});
24337
}, Promise.resolve());
24438
} else {
@@ -247,8 +41,8 @@ const list_item_hunter = function() {
24741
}
24842

24943
return {
250-
process_list_item_partials: function(pattern, patternlab) {
251-
return processListItemPartials(pattern, patternlab);
44+
process_list_item_partials: function(pattern) {
45+
return processListItemPartials(pattern);
25246
},
25347
};
25448
};

core/lib/patternlab.js

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const packageInfo = require('../../package.json');
1111
const buildListItems = require('./buildListItems');
1212
const dataLoader = require('./data_loader')();
1313
const logger = require('./log');
14+
const parseLink = require('./parseLink');
1415
const processIterative = require('./processIterative');
1516
const processRecursive = require('./processRecursive');
1617
const jsonCopy = require('./json_copy');
@@ -363,13 +364,16 @@ module.exports = class PatternLab {
363364

364365
//render the pattern, but first consolidate any data we may have
365366
let allData;
366-
try {
367-
allData = jsonCopy(this.data, 'config.paths.source.data global data');
368-
} catch (err) {
369-
logger.info('There was an error parsing JSON for ' + pattern.relPath);
370-
logger.info(err);
371-
}
372-
allData = _.merge(allData, pattern.jsonFileData);
367+
368+
let allListItems = _.merge({}, this.listitems, pattern.listitems);
369+
allListItems = parseLink(
370+
this,
371+
allListItems,
372+
'listitems.json + any pattern listitems.json'
373+
);
374+
375+
allData = _.merge({}, this.data, pattern.jsonFileData);
376+
allData = _.merge({}, allData, allListItems);
373377
allData.cacheBuster = this.cacheBuster;
374378

375379
///////////////

0 commit comments

Comments
 (0)