Skip to content
This repository was archived by the owner on Dec 10, 2019. It is now read-only.

Commit 3452046

Browse files
committed
Merge branch 'master' into pattern-engines
Conflicts: builder/object_factory.js builder/pattern_assembler.js builder/pseudopattern_hunter.js
2 parents d022308 + 8a4d4c6 commit 3452046

26 files changed

+483
-85
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ public/fonts/*
88
public/js/*
99
public/images/*
1010
public/patterns/*
11-
config.ini
1211
latest-change.txt
1312
patternlab.json
1413
.sass-cache/*

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
language: node_js
22

33
node_js:
4+
- 4.1
5+
- 4.0
6+
- 0.12
47
- 0.11
5-
- 0.10
68

79
before_install:
810
- phantomjs --version

CHANGELOG

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
THIS CHANGELOG IS AN ATTEMPT TO DOCUMENT CHANGES TO THIS PROJECT.
22

3+
PL-node-v0.13.0
4+
- FIX: Cleanup an old file and an incorrect entry in the .gitignore file
5+
- CHG: Change order of pattern addition and ~variant pattern addition so they build naturally in the menu.
6+
- THX: Thanks @e2tha-e for the flurry of pull requests!
7+
- CHG: Update data merge function to prioritize handle pattern~variant.json files
8+
- THX: Thanks @e2tha-e for finding, fixing, and unit testing the data merge issue.
9+
- ADD: Support for recursive partial inclusion
10+
- THX: Thanks @e2tha-e for making pattern inclusion a lot more robust. Great work!!!
11+
- FIX: Improvements to style guide menu generation and capitalization.
12+
313
PL-node-v0.12.0
414
- ADD: Gulp support arrives with an optional configuration
515
- ADD: Instructions how to install and run with Gulp

Gruntfile.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ module.exports = function(grunt) {
2828
src: './builder/patternlab_grunt.js',
2929
dest: './builder/patternlab_grunt.js'
3030
},
31+
patternlab_gulp: {
32+
src: './builder/patternlab_gulp.js',
33+
dest: './builder/patternlab_gulp.js'
34+
},
3135
parameter_hunter: {
3236
src: './builder/parameter_hunter.js',
3337
dest: './builder/parameter_hunter.js'

builder/lineage_hunter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* patternlab-node - v0.12.0 - 2015
2+
* patternlab-node - v0.13.0 - 2015
33
*
44
* Brian Muenzenmeyer, and the web community.
55
* Licensed under the MIT license.

builder/list_item_hunter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* patternlab-node - v0.12.0 - 2015
2+
* patternlab-node - v0.13.0 - 2015
33
*
44
* Brian Muenzenmeyer, and the web community.
55
* Licensed under the MIT license.

builder/media_hunter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* patternlab-node - v0.12.0 - 2015
2+
* patternlab-node - v0.13.0 - 2015
33
*
44
* Brian Muenzenmeyer, and the web community.
55
* Licensed under the MIT license.

builder/object_factory.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* patternlab-node - v0.12.0 - 2015
2+
* patternlab-node - v0.13.0 - 2015
33
*
44
* Brian Muenzenmeyer, and the web community.
55
* Licensed under the MIT license.
@@ -13,12 +13,16 @@
1313

1414
var PatternEngines = require('pattern_engines/pattern_engines');
1515

16-
var oPattern = function(subdir, filename, data){
16+
var oPattern = function(abspath, subdir, filename, data){
1717
this.fileName = filename.substring(0, filename.indexOf('.'));
18+
this.abspath = abspath;
1819
this.subdir = subdir;
1920
this.name = subdir.replace(/[\/\\]/g, '-') + '-' + this.fileName; //this is the unique name with the subDir
2021
this.jsonFileData = data || {};
21-
this.patternName = this.fileName.substring(this.fileName.indexOf('-') + 1); //this is the display name for the ui
22+
this.patternName = this.fileName.replace(/^\d*\-/, '');
23+
this.patternDisplayName = this.patternName.split('-').reduce(function(val, working){
24+
return val.charAt(0).toUpperCase() + val.slice(1) + ' ' + working.charAt(0).toUpperCase() + working.slice(1);
25+
}, '').trim(); //this is the display name for the ui. strip numeric + hyphen prefixes
2226
this.patternLink = this.name + '/' + this.name + '.html';
2327
this.patternGroup = this.name.substring(this.name.indexOf('-') + 1, this.name.indexOf('-', 4) + 1 - this.name.indexOf('-') + 1);
2428
this.patternSubGroup = subdir.substring(subdir.indexOf('/') + 4);
@@ -39,7 +43,9 @@
3943

4044
var oBucket = function(name){
4145
this.bucketNameLC = name;
42-
this.bucketNameUC = name.charAt(0).toUpperCase() + name.slice(1);
46+
this.bucketNameUC = name.split('-').reduce(function(val, working){
47+
return val.charAt(0).toUpperCase() + val.slice(1) + ' ' + working.charAt(0).toUpperCase() + working.slice(1);
48+
}, '').trim();
4349
this.navItems = [];
4450
this.navItemsIndex = [];
4551
this.patternItems = [];
@@ -48,15 +54,19 @@
4854

4955
var oNavItem = function(name){
5056
this.sectionNameLC = name;
51-
this.sectionNameUC = name.charAt(0).toUpperCase() + name.slice(1);
57+
this.sectionNameUC = name.split('-').reduce(function(val, working){
58+
return val.charAt(0).toUpperCase() + val.slice(1) + ' ' + working.charAt(0).toUpperCase() + working.slice(1);
59+
}, '').trim();
5260
this.navSubItems = [];
5361
this.navSubItemsIndex = [];
5462
};
5563

5664
var oNavSubItem = function(name){
5765
this.patternPath = '';
5866
this.patternPartial = '';
59-
this.patternName = name.charAt(0).toUpperCase() + name.slice(1);
67+
this.patternName = name.split(' ').reduce(function(val, working){
68+
return val.charAt(0).toUpperCase() + val.slice(1) + ' ' + working.charAt(0).toUpperCase() + working.slice(1);
69+
}, '').trim();
6070
};
6171

6272
module.exports = {

builder/parameter_hunter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* patternlab-node - v0.12.0 - 2015
2+
* patternlab-node - v0.13.0 - 2015
33
*
44
* Brian Muenzenmeyer, and the web community.
55
* Licensed under the MIT license.

builder/pattern_assembler.js

Lines changed: 117 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
/*
2-
* patternlab-node - v0.12.0 - 2015
3-
*
1+
/*
2+
* patternlab-node - v0.13.0 - 2015
3+
*
44
* Brian Muenzenmeyer, and the web community.
55
* Licensed under the MIT license.
66
*
@@ -50,7 +50,22 @@
5050

5151
function addPattern(pattern, patternlab){
5252
patternlab.data.link[pattern.patternGroup + '-' + pattern.patternName] = '/patterns/' + pattern.patternLink;
53-
patternlab.patterns.push(pattern);
53+
54+
//only push to array if the array doesn't contain this pattern
55+
var isNew = true;
56+
for(var i = 0; i < patternlab.patterns.length; i++){
57+
//so we need the identifier to be unique, which patterns[i].abspath is
58+
if(pattern.abspath === patternlab.patterns[i].abspath){
59+
//if abspath already exists, overwrite that element
60+
patternlab.patterns[i] = pattern;
61+
isNew = false;
62+
break;
63+
}
64+
}
65+
//if the pattern is new, just push to the array
66+
if(isNew){
67+
patternlab.patterns.push(pattern);
68+
}
5469
}
5570

5671
function renderPattern(template, data, partials) {
@@ -70,24 +85,43 @@
7085
return (supportedPatternFileExtensions.lastIndexOf(extension) != -1);
7186
}
7287

73-
// given a pattern file, figure out what to do with it
74-
function processPatternFile(file, patternlab){
88+
function processPatternIterative(file, patternlab){
89+
var fs = require('fs-extra'),
90+
of = require('./object_factory'),
91+
path = require('path');
92+
7593
//extract some information
76-
var abspath = file.substring(2);
7794
var subdir = path.dirname(path.relative(patternlab.config.patterns.source, file)).replace('\\', '/');
7895
var filename = path.basename(file);
96+
var ext = path.extname(filename);
7997

8098
// ignore _underscored patterns, dotfiles, and anything not recognized by
8199
// a loaded pattern engine
82100
if (filename.charAt(0) === '_' ||
83101
filename.charAt(0) === '.' ||
102+
(ext === '.json' && filename.indexOf('~') === -1) ||
84103
!isPatternFile(filename, patternlab)) {
85104
return;
86105
}
87106
console.log('found pattern', file);
88107

89108
//make a new Pattern Object
90-
var currentPattern = new of.oPattern(subdir, filename);
109+
var currentPattern = new of.oPattern(file, subdir, filename);
110+
111+
//if file is named in the syntax for variants
112+
if(ext === '.json' && filename.indexOf('~') > -1){
113+
//add current pattern to patternlab object with minimal data
114+
//processPatternRecursive() will run find_pseudopatterns() to fill out
115+
//the object in the next diveSync
116+
addPattern(currentPattern, patternlab);
117+
//no need to process further
118+
return;
119+
}
120+
121+
//can ignore all non-mustache files at this point
122+
if(ext !== '.mustache'){
123+
return;
124+
}
91125

92126
//see if this file has a state
93127
setState(currentPattern, patternlab);
@@ -96,7 +130,9 @@
96130
try {
97131
var jsonFilename = patternlab.config.patterns.source + currentPattern.subdir + '/' + currentPattern.fileName + ".json";
98132
currentPattern.jsonFileData = fs.readJSONSync(jsonFilename.substring(2));
99-
console.log('found pattern-specific data.json for ' + currentPattern.key);
133+
if(patternlab.config.debug){
134+
console.log('found pattern-specific data.json for ' + currentPattern.key);
135+
}
100136
}
101137
catch(e) {
102138
}
@@ -105,19 +141,21 @@
105141
try {
106142
var listJsonFileName = patternlab.config.patterns.source + currentPattern.subdir + '/' + currentPattern.fileName + ".listitems.json";
107143
currentPattern.patternSpecificListJson = fs.readJSONSync(listJsonFileName.substring(2));
108-
console.log('found pattern-specific listitems.json for ' + currentPattern.key);
144+
if(patternlab.config.debug){
145+
console.log('found pattern-specific listitems.json for ' + currentPattern.key);
146+
}
109147
}
110148
catch(e) {
111149
}
112150

113151
//add the raw template to memory
114-
currentPattern.template = fs.readFileSync(abspath, 'utf8');
152+
currentPattern.template = fs.readFileSync(file, 'utf8');
115153

116-
//our helper function that does a lot of heavy lifting
117-
processPattern(currentPattern, patternlab);
154+
//add currentPattern to patternlab.patterns array
155+
addPattern(currentPattern, patternlab);
118156
}
119157

120-
function processPattern(currentPattern, patternlab, additionalData){
158+
function processPatternRecursive(file, patternlab, additionalData){
121159
var lh = require('./lineage_hunter'),
122160
ph = require('./parameter_hunter'),
123161
pph = require('./pseudopattern_hunter'),
@@ -128,6 +166,21 @@
128166
list_item_hunter = new lih(),
129167
pseudopattern_hunter = new pph();
130168

169+
//find current pattern in patternlab object using var file as a key
170+
var currentPattern,
171+
i;
172+
173+
for(i = 0; i < patternlab.patterns.length; i++){
174+
if(patternlab.patterns[i].abspath === file){
175+
currentPattern = patternlab.patterns[i];
176+
}
177+
}
178+
179+
//return if processing an ignored file
180+
if(typeof currentPattern === 'undefined'){
181+
return;
182+
}
183+
131184
currentPattern.extendedTemplate = currentPattern.template;
132185

133186
//find how many partials there may be for the given pattern
@@ -146,8 +199,23 @@
146199
parameter_hunter.find_parameters(currentPattern, patternlab);
147200

148201
//do something with the regular old partials
149-
for(var i = 0; i < foundPatternPartials.length; i++){
202+
for(i = 0; i < foundPatternPartials.length; i++){
150203
var partialKey = foundPatternPartials[i].replace(/{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-]+)?(?:(| )\(.*)?([ ])?}}/g, '$2');
204+
var partialPath;
205+
206+
//identify which pattern this partial corresponds to
207+
for(var j = 0; j < patternlab.patterns.length; j++){
208+
if(patternlab.patterns[j].key === partialKey ||
209+
patternlab.patterns[j].abspath.indexOf(partialKey) > -1)
210+
{
211+
partialPath = patternlab.patterns[j].abspath;
212+
}
213+
}
214+
215+
//recurse through nested partials to fill out this extended template.
216+
processPatternRecursive(partialPath, patternlab);
217+
218+
//complete assembly of extended template
151219
var partialPattern = getpatternbykey(partialKey, patternlab);
152220
currentPattern.extendedTemplate = currentPattern.extendedTemplate.replace(foundPatternPartials[i], partialPattern.extendedTemplate);
153221
}
@@ -157,11 +225,11 @@
157225
//find pattern lineage
158226
lineage_hunter.find_lineage(currentPattern, patternlab);
159227

160-
//look for a pseudo pattern by checking if there is a file containing same name, with ~ in it, ending in .json
161-
pseudopattern_hunter.find_pseudopatterns(currentPattern, patternlab);
162-
163228
//add to patternlab object so we can look these up later.
164229
addPattern(currentPattern, patternlab);
230+
231+
//look for a pseudo pattern by checking if there is a file containing same name, with ~ in it, ending in .json
232+
pseudopattern_hunter.find_pseudopatterns(currentPattern, patternlab);
165233
}
166234

167235
function getpatternbykey(key, patternlab){
@@ -176,24 +244,39 @@
176244
throw 'Could not find pattern with key ' + key;
177245
}
178246

179-
180-
var self = this;
181-
function mergeData(obj1, obj2) {
182-
for (var p in obj2) {
247+
/**
248+
* Recursively merge properties of two objects.
249+
*
250+
* @param {Object} obj1 If obj1 has properties obj2 doesn't, add to obj2.
251+
* @param {Object} obj2 This object's properties have priority over obj1.
252+
* @returns {Object} obj2
253+
*/
254+
function mergeData(obj1, obj2){
255+
if(typeof obj2 === 'undefined'){
256+
obj2 = {};
257+
}
258+
for(var p in obj1){
183259
try {
184-
// Property in destination object set; update its value.
185-
if ( obj2[p].constructor == Object ) {
186-
obj1[p] = self.merge_data(obj1[p], obj2[p]);
187-
188-
} else {
189-
obj1[p] = obj2[p];
260+
// Only recurse if obj1[p] is an object.
261+
if(obj1[p].constructor === Object){
262+
// Requires 2 objects as params; create obj2[p] if undefined.
263+
if(typeof obj2[p] === 'undefined'){
264+
obj2[p] = {};
265+
}
266+
obj2[p] = mergeData(obj1[p], obj2[p]);
267+
// Pop when recursion meets a non-object. If obj1[p] is a non-object,
268+
// only copy to undefined obj2[p]. This way, obj2 maintains priority.
269+
} else if(typeof obj2[p] === 'undefined'){
270+
obj2[p] = obj1[p];
190271
}
191272
} catch(e) {
192273
// Property in destination object not set; create it and set its value.
193-
obj1[p] = obj2[p];
274+
if(typeof obj2[p] === 'undefined'){
275+
obj2[p] = obj1[p];
276+
}
194277
}
195278
}
196-
return obj1;
279+
return obj2;
197280
}
198281

199282
function buildListItems(patternlab){
@@ -242,11 +325,11 @@
242325
renderPattern: function(template, data, partials){
243326
return renderPattern(template, data, partials);
244327
},
245-
process_pattern_file: function(file, patternlab){
246-
processPatternFile(file, patternlab);
328+
process_pattern_iterative: function(file, patternlab){
329+
processPatternIterative(file, patternlab);
247330
},
248-
process_pattern: function(pattern, patternlab, additionalData){
249-
processPattern(pattern, patternlab, additionalData);
331+
process_pattern_recursive: function(file, patternlab, additionalData){
332+
processPatternRecursive(file, patternlab, additionalData);
250333
},
251334
get_pattern_by_key: function(key, patternlab){
252335
return getpatternbykey(key, patternlab);

0 commit comments

Comments
 (0)