|
1 |
| -/* |
2 |
| - * patternlab-node - v0.12.0 - 2015 |
3 |
| - * |
| 1 | +/* |
| 2 | + * patternlab-node - v0.13.0 - 2015 |
| 3 | + * |
4 | 4 | * Brian Muenzenmeyer, and the web community.
|
5 | 5 | * Licensed under the MIT license.
|
6 | 6 | *
|
|
50 | 50 |
|
51 | 51 | function addPattern(pattern, patternlab){
|
52 | 52 | 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 | + } |
54 | 69 | }
|
55 | 70 |
|
56 | 71 | function renderPattern(template, data, partials) {
|
|
70 | 85 | return (supportedPatternFileExtensions.lastIndexOf(extension) != -1);
|
71 | 86 | }
|
72 | 87 |
|
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 | + |
75 | 93 | //extract some information
|
76 |
| - var abspath = file.substring(2); |
77 | 94 | var subdir = path.dirname(path.relative(patternlab.config.patterns.source, file)).replace('\\', '/');
|
78 | 95 | var filename = path.basename(file);
|
| 96 | + var ext = path.extname(filename); |
79 | 97 |
|
80 | 98 | // ignore _underscored patterns, dotfiles, and anything not recognized by
|
81 | 99 | // a loaded pattern engine
|
82 | 100 | if (filename.charAt(0) === '_' ||
|
83 | 101 | filename.charAt(0) === '.' ||
|
| 102 | + (ext === '.json' && filename.indexOf('~') === -1) || |
84 | 103 | !isPatternFile(filename, patternlab)) {
|
85 | 104 | return;
|
86 | 105 | }
|
87 | 106 | console.log('found pattern', file);
|
88 | 107 |
|
89 | 108 | //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 | + } |
91 | 125 |
|
92 | 126 | //see if this file has a state
|
93 | 127 | setState(currentPattern, patternlab);
|
|
96 | 130 | try {
|
97 | 131 | var jsonFilename = patternlab.config.patterns.source + currentPattern.subdir + '/' + currentPattern.fileName + ".json";
|
98 | 132 | 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 | + } |
100 | 136 | }
|
101 | 137 | catch(e) {
|
102 | 138 | }
|
|
105 | 141 | try {
|
106 | 142 | var listJsonFileName = patternlab.config.patterns.source + currentPattern.subdir + '/' + currentPattern.fileName + ".listitems.json";
|
107 | 143 | 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 | + } |
109 | 147 | }
|
110 | 148 | catch(e) {
|
111 | 149 | }
|
112 | 150 |
|
113 | 151 | //add the raw template to memory
|
114 |
| - currentPattern.template = fs.readFileSync(abspath, 'utf8'); |
| 152 | + currentPattern.template = fs.readFileSync(file, 'utf8'); |
115 | 153 |
|
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); |
118 | 156 | }
|
119 | 157 |
|
120 |
| - function processPattern(currentPattern, patternlab, additionalData){ |
| 158 | + function processPatternRecursive(file, patternlab, additionalData){ |
121 | 159 | var lh = require('./lineage_hunter'),
|
122 | 160 | ph = require('./parameter_hunter'),
|
123 | 161 | pph = require('./pseudopattern_hunter'),
|
|
128 | 166 | list_item_hunter = new lih(),
|
129 | 167 | pseudopattern_hunter = new pph();
|
130 | 168 |
|
| 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 | + |
131 | 184 | currentPattern.extendedTemplate = currentPattern.template;
|
132 | 185 |
|
133 | 186 | //find how many partials there may be for the given pattern
|
|
146 | 199 | parameter_hunter.find_parameters(currentPattern, patternlab);
|
147 | 200 |
|
148 | 201 | //do something with the regular old partials
|
149 |
| - for(var i = 0; i < foundPatternPartials.length; i++){ |
| 202 | + for(i = 0; i < foundPatternPartials.length; i++){ |
150 | 203 | 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 |
151 | 219 | var partialPattern = getpatternbykey(partialKey, patternlab);
|
152 | 220 | currentPattern.extendedTemplate = currentPattern.extendedTemplate.replace(foundPatternPartials[i], partialPattern.extendedTemplate);
|
153 | 221 | }
|
|
157 | 225 | //find pattern lineage
|
158 | 226 | lineage_hunter.find_lineage(currentPattern, patternlab);
|
159 | 227 |
|
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 |
| - |
163 | 228 | //add to patternlab object so we can look these up later.
|
164 | 229 | 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); |
165 | 233 | }
|
166 | 234 |
|
167 | 235 | function getpatternbykey(key, patternlab){
|
|
176 | 244 | throw 'Could not find pattern with key ' + key;
|
177 | 245 | }
|
178 | 246 |
|
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){ |
183 | 259 | 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]; |
190 | 271 | }
|
191 | 272 | } catch(e) {
|
192 | 273 | // 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 | + } |
194 | 277 | }
|
195 | 278 | }
|
196 |
| - return obj1; |
| 279 | + return obj2; |
197 | 280 | }
|
198 | 281 |
|
199 | 282 | function buildListItems(patternlab){
|
|
242 | 325 | renderPattern: function(template, data, partials){
|
243 | 326 | return renderPattern(template, data, partials);
|
244 | 327 | },
|
245 |
| - process_pattern_file: function(file, patternlab){ |
246 |
| - processPatternFile(file, patternlab); |
| 328 | + process_pattern_iterative: function(file, patternlab){ |
| 329 | + processPatternIterative(file, patternlab); |
247 | 330 | },
|
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); |
250 | 333 | },
|
251 | 334 | get_pattern_by_key: function(key, patternlab){
|
252 | 335 | return getpatternbykey(key, patternlab);
|
|
0 commit comments