From 74544248e84dd70e686b1a1ec731476ebe1a9b3e Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 25 Aug 2015 16:58:59 -0500 Subject: [PATCH 001/187] Add editorconfig and eslintrc --- .editorconfig | 11 ++++++++ .eslintrc | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 .editorconfig create mode 100644 .eslintrc diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..8951c3929 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +# editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +tab_width = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 000000000..f07e2be6d --- /dev/null +++ b/.eslintrc @@ -0,0 +1,71 @@ +{ + "env": { + "jasmine": true, + "node": true, + "mocha": true, + "browser": true, + "builtin": true + }, + "globals": {}, + "rules": { + "block-scoped-var": 2, + "camelcase": 0, + "curly": [ + 2, + "all" + ], + "dot-notation": [ + 2, + { + "allowKeywords": true + } + ], + "eqeqeq": [ + 2, + "allow-null" + ], + "global-strict": [ + 2, + "never" + ], + "guard-for-in": 2, + "new-cap": 0, + "no-bitwise": 2, + "no-caller": 2, + "no-cond-assign": [ + 2, + "except-parens" + ], + "no-debugger": 2, + "no-empty": 2, + "no-eval": 2, + "no-extend-native": 2, + "no-extra-parens": 0, + "no-irregular-whitespace": 2, + "no-iterator": 2, + "no-loop-func": 2, + "no-multi-str": 2, + "no-new": 2, + "no-proto": 2, + "no-script-url": 2, + "no-sequences": 2, + "no-shadow": 2, + "no-undef": 2, + "no-unused-vars": 2, + "no-with": 2, + "quotes": [ + 0, + "single" + ], + "semi": [ + 0, + "never" + ], + "strict": 2, + "valid-typeof": 2, + "wrap-iife": [ + 2, + "inside" + ] + } +} From 4a9dec622eda58e1b67754fdc59a028855c7ca05 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 25 Aug 2015 17:05:58 -0500 Subject: [PATCH 002/187] Add first draft of pattern engines --- builder/pattern_engines/engine_mustache.js | 36 ++++++++++++++++++++ builder/pattern_engines/pattern_engines.js | 38 ++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 builder/pattern_engines/engine_mustache.js create mode 100644 builder/pattern_engines/pattern_engines.js diff --git a/builder/pattern_engines/engine_mustache.js b/builder/pattern_engines/engine_mustache.js new file mode 100644 index 000000000..fb9dcef71 --- /dev/null +++ b/builder/pattern_engines/engine_mustache.js @@ -0,0 +1,36 @@ +/* + * mustache pattern engine for patternlab-node - v0.10.1 - 2015 + * + * Brian Muenzenmeyer, and the web community. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * + */ + +(function () { + "use strict"; + + var Mustache = require('mustache'); + + var engine_mustache = { + engine: Mustache, + fileExtension: '.mustache', + + // render it + renderPattern: function renderPattern(template, data, partials) { + if (partials) { + return Mustache.render(template, data, partials); + } + return Mustache.render(template, data); + }, + + // find and return any {{> template-name }} within pattern + findPartials: function findPartials(pattern) { + var matches = pattern.template.match(/{{>([ ])?([A-Za-z0-9-]+)(?:\:[A-Za-z0-9-]+)?(?:(| )\(.*)?([ ])?}}/g); + return matches; + } + }; + + module.exports = engine_mustache; +})(); diff --git a/builder/pattern_engines/pattern_engines.js b/builder/pattern_engines/pattern_engines.js new file mode 100644 index 000000000..d290a8dc3 --- /dev/null +++ b/builder/pattern_engines/pattern_engines.js @@ -0,0 +1,38 @@ +/* + * patternlab-node - v0.10.1 - 2015 + * + * Brian Muenzenmeyer, and the web community. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * + */ + +(function () { + 'use strict'; + + // list of supported pattern engines + var supportedPatternEngineNames = [ + 'mustache', + 'handlebars' + ]; + + // hash of all loaded pattern engines, empty at first + var patternEngines = {}; + + // try to load all supported engines + supportedPatternEngineNames.forEach(function (engineName) { + try { + patternEngines[engineName] = require('./engine_' + engineName); + } catch (err) { + console.log(err, 'pattern engine "' + engineName + '" not loaded. Did you install its dependency with npm?'); + } + }); + + patternEngines.getEngineForPattern = function (pattern) { + + }; + + module.exports = patternEngines; + +})(); From 4899cd9db23edafac3bdc710b752ccdbfa1b78bf Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 25 Aug 2015 17:08:20 -0500 Subject: [PATCH 003/187] first batch of changes to migrate from direct dependence on mustache to dependence on pattern engines --- builder/pattern_assembler.js | 67 +++++++++++++++++++-------------- builder/patternlab.js | 23 ++++++----- builder/pseudopattern_hunter.js | 14 +++---- 3 files changed, 56 insertions(+), 48 deletions(-) diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index a024a7dac..2bd1c19ce 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -1,10 +1,10 @@ -/* - * patternlab-node - v0.10.1 - 2015 - * +/* + * patternlab-node - v0.10.1 - 2015 + * * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ @@ -13,7 +13,13 @@ var pattern_assembler = function(){ - //find and return any {{> template-name }} within pattern + var fs = require('fs-extra'), + of = require('./object_factory'), + path = require('path'), + patternEngines = require('./pattern_engines/pattern_engines'); + + // find and return any {{> template-name }} within pattern + // TODO: delete, factored out function findPartials(pattern){ var matches = pattern.template.match(/{{>([ ])?([A-Za-z0-9-]+)(?:\:[A-Za-z0-9-]+)?(?:(| )\(.*)?([ ])?}}/g); return matches; @@ -33,30 +39,37 @@ } function renderPattern(template, data, partials) { + debugger; + // TODO: + // choose an appropriate pattern engine + // call and return result of its renderPattern method + // OR MAYBE: this should just be a method of oPattern + } - var mustache = require('mustache'); - - if(partials) { - return mustache.render(template, data, partials); - } else{ - return mustache.render(template, data); - } + function isPatternFile(filename, patternlab) { + var engineNames = Object.keys(patternEngines); + var supportedPatternFileExtensions = engineNames.map(function (engineName) { + return patternEngines[engineName].fileExtension; + }); + var extension = path.extname(filename); + return (supportedPatternFileExtensions.lastIndexOf(extension) != -1); } + // given a pattern file, figure out what to do with it function processPatternFile(file, patternlab){ - var fs = require('fs-extra'), - of = require('./object_factory'), - path = require('path'); - //extract some information var abspath = file.substring(2); var subdir = path.dirname(path.relative('./source/_patterns', file)).replace('\\', '/'); var filename = path.basename(file); - //ignore _underscored patterns, json (for now), and dotfiles - if(filename.charAt(0) === '_' || path.extname(filename) === '.json' || filename.charAt(0) === '.'){ + // ignore _underscored patterns, dotfiles, and anything not recognized by + // a loaded pattern engine + if (filename.charAt(0) === '_' || + filename.charAt(0) === '.' || + !isPatternFile(filename, patternlab)) { return; } + console.log('found pattern', file); //make a new Pattern Object var currentPattern = new of.oPattern(subdir, filename); @@ -80,17 +93,13 @@ } function processPattern(currentPattern, patternlab, additionalData){ - - var fs = require('fs-extra'), - mustache = require('mustache'), - lh = require('./lineage_hunter'), - ph = require('./parameter_hunter'), - pph = require('./pseudopattern_hunter'), - path = require('path'); + var lh = require('./lineage_hunter'), + ph = require('./parameter_hunter'), + pph = require('./pseudopattern_hunter'); var parameter_hunter = new ph(), - lineage_hunter = new lh(), - pseudopattern_hunter = new pph(); + lineage_hunter = new lh(), + pseudopattern_hunter = new pph(); currentPattern.extendedTemplate = currentPattern.template; diff --git a/builder/patternlab.js b/builder/patternlab.js index 74e4c186f..5452aac7a 100644 --- a/builder/patternlab.js +++ b/builder/patternlab.js @@ -1,10 +1,10 @@ -/* - * patternlab-node - v0.10.1 - 2015 - * +/* + * patternlab-node - v0.10.1 - 2015 + * * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ @@ -15,7 +15,6 @@ var patternlab_engine = function () { fs = require('fs-extra'), extend = require('util')._extend, diveSync = require('diveSync'), - mustache = require('mustache'), glob = require('glob'), of = require('./object_factory'), pa = require('./pattern_assembler'), @@ -27,6 +26,7 @@ var patternlab_engine = function () { patternlab.package = fs.readJSONSync('./package.json'); patternlab.config = fs.readJSONSync('./config.json'); + function getVersion() { console.log(patternlab.package.version); } @@ -67,17 +67,16 @@ var patternlab_engine = function () { entity_encoder = new he(), pattern_exporter = new pe(); - diveSync('./source/_patterns', function(err, file){ + diveSync('./source/_patterns', function(err, filePath){ //log any errors if(err){ console.log(err); return; } - - pattern_assembler.process_pattern_file(file, patternlab); - + pattern_assembler.process_pattern_file(filePath, patternlab); }); - //render all patterns last, so lineageR works + + //render all patterns last, so lineage works patternlab.patterns.forEach(function(pattern, index, patterns){ //render the pattern, but first consolidate any data we may have var allData = JSON.parse(JSON.stringify(patternlab.data)); diff --git a/builder/pseudopattern_hunter.js b/builder/pseudopattern_hunter.js index b2b74a125..77f29868b 100644 --- a/builder/pseudopattern_hunter.js +++ b/builder/pseudopattern_hunter.js @@ -1,10 +1,10 @@ -/* - * patternlab-node - v0.10.1 - 2015 - * +/* + * patternlab-node - v0.10.1 - 2015 + * * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ @@ -48,7 +48,7 @@ variantFileData = pattern_assembler.merge_data(variantFileData, currentPattern.jsonFileData); var variantName = pseudoPatterns[i].substring(pseudoPatterns[i].indexOf('~') + 1).split('.')[0]; - var patternVariant = new of.oPattern(currentPattern.subdir, currentPattern.fileName + '-' + variantName + '.mustache', variantFileData); + var patternVariant = new of.oPattern(currentPattern.subdir, currentPattern.fileName + '-' + variantName + '.mustache', variantFileData); //see if this file has a state pattern_assembler.setPatternState(patternVariant, patternlab); From 30f8000360247f6b06dfcceb150e7fe5d9200c2d Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Fri, 28 Aug 2015 14:44:55 -0500 Subject: [PATCH 004/187] First steps toward a .render() method directly on the oPattern object. The pattern_engines module returns an instance, but I now realize that this is a terrible idea. --- builder/object_factory.js | 19 +++++++++++++------ builder/parameter_hunter.js | 20 ++++++++++---------- builder/pattern_engines/engine_mustache.js | 14 +++++++------- builder/pattern_engines/pattern_engines.js | 21 ++++++++++++--------- 4 files changed, 42 insertions(+), 32 deletions(-) diff --git a/builder/object_factory.js b/builder/object_factory.js index f1809b16e..87b6700c5 100644 --- a/builder/object_factory.js +++ b/builder/object_factory.js @@ -1,16 +1,18 @@ -/* - * patternlab-node - v0.10.1 - 2015 - * +/* + * patternlab-node - v0.10.1 - 2015 + * * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ (function () { "use strict"; + var PatternEngines = require('pattern_engines/pattern_engines'); + var oPattern = function(subdir, filename, data){ this.fileName = filename.substring(0, filename.indexOf('.')); this.subdir = subdir; @@ -29,6 +31,11 @@ this.lineageIndex = []; this.lineageR = []; this.lineageRIndex = []; + this.engine = PatternEngines.getEngineForPattern(this); + }; + // render method on oPatterns; this acts as a proxy for the + oPattern.prototype.render = function (data, partials) { + return this.engine.render(this.template, data, partials); }; var oBucket = function(name){ diff --git a/builder/parameter_hunter.js b/builder/parameter_hunter.js index 0541b211f..09ed0d1a0 100644 --- a/builder/parameter_hunter.js +++ b/builder/parameter_hunter.js @@ -1,10 +1,10 @@ -/* - * patternlab-node - v0.10.1 - 2015 - * +/* + * patternlab-node - v0.10.1 - 2015 + * * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ @@ -14,9 +14,9 @@ var parameter_hunter = function(){ var extend = require('util')._extend, - pa = require('./pattern_assembler'), - mustache = require('mustache'), - pattern_assembler = new pa(); + pa = require('./pattern_asbsembler'), + mustache = require('mustache'), + pattern_assembler = new pa(); function findparameters(pattern, patternlab){ @@ -47,7 +47,7 @@ for (var prop in paramData) { if (existingData.hasOwnProperty(prop)) { existingData[prop] = paramData[prop]; - } + } } //extend pattern data links into link for pattern link shortcuts to work. we do this locally and globally diff --git a/builder/pattern_engines/engine_mustache.js b/builder/pattern_engines/engine_mustache.js index fb9dcef71..90bace478 100644 --- a/builder/pattern_engines/engine_mustache.js +++ b/builder/pattern_engines/engine_mustache.js @@ -1,10 +1,10 @@ -/* - * mustache pattern engine for patternlab-node - v0.10.1 - 2015 - * +/* + * mustache pattern engine for patternlab-node - v0.10.1 - 2015 + * * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ @@ -31,6 +31,6 @@ return matches; } }; - + module.exports = engine_mustache; })(); diff --git a/builder/pattern_engines/pattern_engines.js b/builder/pattern_engines/pattern_engines.js index d290a8dc3..ac65ddc74 100644 --- a/builder/pattern_engines/pattern_engines.js +++ b/builder/pattern_engines/pattern_engines.js @@ -17,22 +17,25 @@ 'handlebars' ]; - // hash of all loaded pattern engines, empty at first - var patternEngines = {}; + // object/hash of all loaded pattern engines, empty at first + function PatternEngines () { + // do nothing + } + PatternEngines.prototype = { + getEngineForPattern: function (pattern) { + console.log('pattern file name: ', pattern.fileName); + return 'mustache'; + } + }; // try to load all supported engines supportedPatternEngineNames.forEach(function (engineName) { try { - patternEngines[engineName] = require('./engine_' + engineName); + PatternEngines[engineName] = require('./engine_' + engineName); } catch (err) { console.log(err, 'pattern engine "' + engineName + '" not loaded. Did you install its dependency with npm?'); } }); - patternEngines.getEngineForPattern = function (pattern) { - - }; - - module.exports = patternEngines; - + module.exports = new PatternEngines(); })(); From 5420ad1716714211d73f9e15bfb166b7f0dcae5e Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Mon, 21 Sep 2015 14:14:21 -0500 Subject: [PATCH 005/187] comment fixups --- builder/pattern_engines/engine_mustache.js | 2 +- builder/pattern_engines/pattern_engines.js | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/builder/pattern_engines/engine_mustache.js b/builder/pattern_engines/engine_mustache.js index 90bace478..1a9fc0ba8 100644 --- a/builder/pattern_engines/engine_mustache.js +++ b/builder/pattern_engines/engine_mustache.js @@ -1,7 +1,7 @@ /* * mustache pattern engine for patternlab-node - v0.10.1 - 2015 * - * Brian Muenzenmeyer, and the web community. + * Geoffrey Pursell, Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. * * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. diff --git a/builder/pattern_engines/pattern_engines.js b/builder/pattern_engines/pattern_engines.js index ac65ddc74..5be883448 100644 --- a/builder/pattern_engines/pattern_engines.js +++ b/builder/pattern_engines/pattern_engines.js @@ -1,7 +1,7 @@ /* * patternlab-node - v0.10.1 - 2015 * - * Brian Muenzenmeyer, and the web community. + * Geoffrey Pursell, Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. * * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. @@ -17,7 +17,13 @@ 'handlebars' ]; - // object/hash of all loaded pattern engines, empty at first + // Object/hash of all loaded pattern engines, empty at first. + // My intention here is to make this return an object that can be used to + // obtain any loaded PatternEngine by addressing them like this: + // + // var PatternEngines = require('pattern_engines/pattern_engines'); + // var Mustache = PatternEngines('mustache'); + // function PatternEngines () { // do nothing } From a2f5cf7a79c190c0ecd8f233bbb42f753ae4b94c Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 27 Oct 2015 10:55:20 -0500 Subject: [PATCH 006/187] fix typos and module path issues --- builder/object_factory.js | 11 ++++++----- builder/parameter_hunter.js | 8 ++++---- builder/patternlab.js | 12 ++++++------ 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/builder/object_factory.js b/builder/object_factory.js index 40cd396b2..5b111979f 100644 --- a/builder/object_factory.js +++ b/builder/object_factory.js @@ -1,6 +1,6 @@ -/* - * patternlab-node - v0.13.0 - 2015 - * +/* + * patternlab-node - v0.13.0 - 2015 + * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. * @@ -11,7 +11,7 @@ (function () { "use strict"; - var PatternEngines = require('pattern_engines/pattern_engines'); + var PatternEngines = require('./pattern_engines/pattern_engines'); var oPattern = function(abspath, subdir, filename, data){ this.fileName = filename.substring(0, filename.indexOf('.')); @@ -36,7 +36,8 @@ this.lineageRIndex = []; this.engine = PatternEngines.getEngineForPattern(this); }; - // render method on oPatterns; this acts as a proxy for the + // render method on oPatterns; this acts as a proxy for the PatternEngine's + // render function oPattern.prototype.render = function (data, partials) { return this.engine.render(this.template, data, partials); }; diff --git a/builder/parameter_hunter.js b/builder/parameter_hunter.js index 974f56f0b..d6b0a338f 100644 --- a/builder/parameter_hunter.js +++ b/builder/parameter_hunter.js @@ -1,6 +1,6 @@ -/* - * patternlab-node - v0.13.0 - 2015 - * +/* + * patternlab-node - v0.13.0 - 2015 + * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. * @@ -14,7 +14,7 @@ var parameter_hunter = function(){ var extend = require('util')._extend, - pa = require('./pattern_asbsembler'), + pa = require('./pattern_assembler'), mustache = require('mustache'), pattern_assembler = new pa(); diff --git a/builder/patternlab.js b/builder/patternlab.js index 2a4fd08a5..da61ffe6b 100644 --- a/builder/patternlab.js +++ b/builder/patternlab.js @@ -1,10 +1,10 @@ -/* - * patternlab-node - v0.13.0 - 2015 - * +/* + * patternlab-node - v0.13.0 - 2015 + * * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ From 6a6db63d7088c0eeebcb2598ad453df138949685 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 27 Oct 2015 10:56:03 -0500 Subject: [PATCH 007/187] make PatternEngines a genuine Object, and set up its method-bearing prototype in the ES5 Object.create style --- builder/pattern_engines/pattern_engines.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/builder/pattern_engines/pattern_engines.js b/builder/pattern_engines/pattern_engines.js index 5be883448..9f4ef2e80 100644 --- a/builder/pattern_engines/pattern_engines.js +++ b/builder/pattern_engines/pattern_engines.js @@ -21,18 +21,15 @@ // My intention here is to make this return an object that can be used to // obtain any loaded PatternEngine by addressing them like this: // - // var PatternEngines = require('pattern_engines/pattern_engines'); - // var Mustache = PatternEngines('mustache'); + // var PatternEngines = require('./pattern_engines/pattern_engines'); + // var Mustache = PatternEngines['mustache']; // - function PatternEngines () { - // do nothing - } - PatternEngines.prototype = { + var PatternEngines = Object.create({ getEngineForPattern: function (pattern) { console.log('pattern file name: ', pattern.fileName); return 'mustache'; } - }; + }); // try to load all supported engines supportedPatternEngineNames.forEach(function (engineName) { @@ -43,5 +40,5 @@ } }); - module.exports = new PatternEngines(); + module.exports = PatternEngines; })(); From f22551bd4464493b7c14aafd721738b2dded67a3 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 27 Oct 2015 10:57:01 -0500 Subject: [PATCH 008/187] temporarily restore mustache-only pattern rendering --- builder/pattern_assembler.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index 80e2ea315..12ad6c2cc 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -1,6 +1,6 @@ -/* - * patternlab-node - v0.13.0 - 2015 - * +/* + * patternlab-node - v0.13.0 - 2015 + * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. * @@ -68,12 +68,19 @@ } } + // template: a string containing the template text, not an oPattern function renderPattern(template, data, partials) { - debugger; // TODO: // choose an appropriate pattern engine // call and return result of its renderPattern method // OR MAYBE: this should just be a method of oPattern + + var mustache = require('mustache'); + if (partials) { + return mustache.render(template, data, partials); + } else { + return mustache.render(template, data); + } } function isPatternFile(filename, patternlab) { From a7236f7b9c9af944d978e871a1da7cc1ac7aa794 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 27 Oct 2015 11:35:02 -0500 Subject: [PATCH 009/187] 'working' renderPattern function --- builder/pattern_assembler.js | 21 ++++++++++----------- builder/pattern_engines/engine_mustache.js | 1 + builder/pattern_engines/pattern_engines.js | 6 +++++- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index 12ad6c2cc..860f46f22 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -68,18 +68,17 @@ } } - // template: a string containing the template text, not an oPattern - function renderPattern(template, data, partials) { - // TODO: - // choose an appropriate pattern engine - // call and return result of its renderPattern method - // OR MAYBE: this should just be a method of oPattern - - var mustache = require('mustache'); - if (partials) { - return mustache.render(template, data, partials); + function renderPattern(pattern, data, partials) { + // if we've been passed a full oPattern, it knows what kind of template it + // is, and how to render itself, so we just call its render method + if (pattern instanceof of.oPattern) { + console.log('rendering full oPattern'); + return pattern.render(pattern, data, partials); } else { - return mustache.render(template, data); + // otherwise, assume it's a plain mustache template string and act + // accordingly + console.log('rendering plain mustache string'); + return patternEngines.mustache.renderPattern(pattern, data, partials); } } diff --git a/builder/pattern_engines/engine_mustache.js b/builder/pattern_engines/engine_mustache.js index 1a9fc0ba8..485a2cf26 100644 --- a/builder/pattern_engines/engine_mustache.js +++ b/builder/pattern_engines/engine_mustache.js @@ -15,6 +15,7 @@ var engine_mustache = { engine: Mustache, + name: 'mustache', fileExtension: '.mustache', // render it diff --git a/builder/pattern_engines/pattern_engines.js b/builder/pattern_engines/pattern_engines.js index 9f4ef2e80..059acaf51 100644 --- a/builder/pattern_engines/pattern_engines.js +++ b/builder/pattern_engines/pattern_engines.js @@ -25,9 +25,13 @@ // var Mustache = PatternEngines['mustache']; // var PatternEngines = Object.create({ - getEngineForPattern: function (pattern) { + getEngineNameForPattern: function (pattern) { console.log('pattern file name: ', pattern.fileName); return 'mustache'; + }, + getEngineForPattern: function (pattern) { + var engineName = this.getEngineNameForPattern(pattern); + return this[engineName]; } }); From fd5e6b6c18cf8926af7c11a0262fbeb0260af3c8 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 27 Oct 2015 11:42:47 -0500 Subject: [PATCH 010/187] start rendering real oPatterns and fix that rendering path --- builder/object_factory.js | 2 +- builder/pattern_assembler.js | 4 ++-- builder/patternlab.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/builder/object_factory.js b/builder/object_factory.js index 5b111979f..c0aed2537 100644 --- a/builder/object_factory.js +++ b/builder/object_factory.js @@ -39,7 +39,7 @@ // render method on oPatterns; this acts as a proxy for the PatternEngine's // render function oPattern.prototype.render = function (data, partials) { - return this.engine.render(this.template, data, partials); + return this.engine.renderPattern(this.template, data, partials); }; var oBucket = function(name){ diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index 860f46f22..4b6543559 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -72,8 +72,8 @@ // if we've been passed a full oPattern, it knows what kind of template it // is, and how to render itself, so we just call its render method if (pattern instanceof of.oPattern) { - console.log('rendering full oPattern'); - return pattern.render(pattern, data, partials); + console.log('rendering full oPattern: ' + pattern.name); + return pattern.render(data, partials); } else { // otherwise, assume it's a plain mustache template string and act // accordingly diff --git a/builder/patternlab.js b/builder/patternlab.js index da61ffe6b..061747cc9 100644 --- a/builder/patternlab.js +++ b/builder/patternlab.js @@ -124,7 +124,7 @@ var patternlab_engine = function () { var allData = JSON.parse(JSON.stringify(patternlab.data)); allData = pattern_assembler.merge_data(allData, pattern.jsonFileData); - pattern.patternPartial = pattern_assembler.renderPattern(pattern.extendedTemplate, allData); + pattern.patternPartial = pattern_assembler.renderPattern(pattern, allData); //add footer info before writing var patternFooter = pattern_assembler.renderPattern(patternlab.footer, pattern); From c4d5080d3da0f528c1928aa63f5d81603ae1d466 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 27 Oct 2015 16:56:44 -0500 Subject: [PATCH 011/187] add file extension to oPattern, update unit test --- builder/object_factory.js | 6 ++++-- test/object_factory_tests.js | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/builder/object_factory.js b/builder/object_factory.js index c0aed2537..799452fcf 100644 --- a/builder/object_factory.js +++ b/builder/object_factory.js @@ -11,10 +11,12 @@ (function () { "use strict"; - var PatternEngines = require('./pattern_engines/pattern_engines'); + var patternEngines = require('./pattern_engines/pattern_engines'); + var path = require('path'); var oPattern = function(abspath, subdir, filename, data){ this.fileName = filename.substring(0, filename.indexOf('.')); + this.fileExtension = path.extname(abspath); this.abspath = abspath; this.subdir = subdir; this.name = subdir.replace(/[\/\\]/g, '-') + '-' + this.fileName; //this is the unique name with the subDir @@ -34,7 +36,7 @@ this.lineageIndex = []; this.lineageR = []; this.lineageRIndex = []; - this.engine = PatternEngines.getEngineForPattern(this); + this.engine = patternEngines.getEngineForPattern(this); }; // render method on oPatterns; this acts as a proxy for the PatternEngine's // render function diff --git a/test/object_factory_tests.js b/test/object_factory_tests.js index 6ce2693a1..dfa7dfc48 100644 --- a/test/object_factory_tests.js +++ b/test/object_factory_tests.js @@ -10,6 +10,7 @@ test.equals(p.abspath, 'source/_patterns/00-atoms/00-global/00-colors.mustache'); test.equals(p.subdir, '00-atoms/00-global'); test.equals(p.fileName, '00-colors'); + test.equals(p.fileExtension, '.mustache'); test.equals(p.jsonFileData.d, 123); test.equals(p.patternName, 'colors'); test.equals(p.patternDisplayName, 'Colors'); From 37bacdcc2c7bf09aa15225747494a23edfff402e Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 27 Oct 2015 16:57:22 -0500 Subject: [PATCH 012/187] Create a new mapping between file extensions and engine names at load time that powers a real implementation of getEngineNameForPattern! --- builder/pattern_engines/pattern_engines.js | 45 ++++++++++++++++++---- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/builder/pattern_engines/pattern_engines.js b/builder/pattern_engines/pattern_engines.js index 059acaf51..aab8efe6c 100644 --- a/builder/pattern_engines/pattern_engines.js +++ b/builder/pattern_engines/pattern_engines.js @@ -8,6 +8,7 @@ * */ + (function () { 'use strict'; @@ -17,6 +18,9 @@ 'handlebars' ]; + // mapping of file extensions to engine names, for lookup use + var engineNameForExtension = {}; + // Object/hash of all loaded pattern engines, empty at first. // My intention here is to make this return an object that can be used to // obtain any loaded PatternEngine by addressing them like this: @@ -25,8 +29,17 @@ // var Mustache = PatternEngines['mustache']; // var PatternEngines = Object.create({ + supportedPatternEngineNames: supportedPatternEngineNames, + getEngineNameForPattern: function (pattern) { - console.log('pattern file name: ', pattern.fileName); + // avoid circular dependency by putting this in here. TODO: is this slow? + var of = require('../object_factory'); + + if (pattern instanceof of.oPattern) { + return engineNameForExtension[pattern.fileExtension]; + } + // otherwise, assume it's a plain mustache template string and act + // accordingly return 'mustache'; }, getEngineForPattern: function (pattern) { @@ -36,13 +49,29 @@ }); // try to load all supported engines - supportedPatternEngineNames.forEach(function (engineName) { - try { - PatternEngines[engineName] = require('./engine_' + engineName); - } catch (err) { - console.log(err, 'pattern engine "' + engineName + '" not loaded. Did you install its dependency with npm?'); - } - }); + (function loadAllEngines() { + supportedPatternEngineNames.forEach(function (engineName) { + try { + PatternEngines[engineName] = require('./engine_' + engineName); + } catch (err) { + console.log(err, 'pattern engine "' + engineName + '" not loaded. Did you install its dependency with npm?'); + } + }); + })(); + + // produce a mapping between file extension and engine name for each of the + // loaded engines + engineNameForExtension = (function () { + var mapping = {}; + + Object.keys(PatternEngines).forEach(function (engineName) { + var extensionForEngine = PatternEngines[engineName].fileExtension; + mapping[extensionForEngine] = engineName; + }); + + return mapping; + })(); + module.exports = PatternEngines; })(); From f54db8356d31f8c912e7805d763a7929225e34da Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 27 Oct 2015 16:58:33 -0500 Subject: [PATCH 013/187] Add unit tests for pattern_engines.js and individual pattern engines --- test/pattern_engines_tests.js | 71 +++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 test/pattern_engines_tests.js diff --git a/test/pattern_engines_tests.js b/test/pattern_engines_tests.js new file mode 100644 index 000000000..f2f8d10cd --- /dev/null +++ b/test/pattern_engines_tests.js @@ -0,0 +1,71 @@ +(function () { + 'use strict'; + + var patternEngines = require('../builder/pattern_engines/pattern_engines'); + var of = require('../builder/object_factory'); + + // the mustache test pattern, stolen from object_factory unit tests + var mustacheTestPattern = new of.oPattern('source/_patterns/00-atoms/00-global/00-colors-alt.mustache', '00-atoms/00-global', '00-colors-alt.mustache', {d: 123}); + var engineNames = Object.keys(patternEngines); + + + exports['patternEngines support functions'] = { + 'getEngineNameForPattern returns "mustache" from test pattern': function (test) { + var engineName = patternEngines.getEngineNameForPattern(mustacheTestPattern); + test.equals(engineName, 'mustache'); + test.done(); + }, + 'getEngineForPattern returns a reference to the mustache engine from test pattern': function (test) { + var engine = patternEngines.getEngineForPattern(mustacheTestPattern); + test.equals(engine, patternEngines.mustache); + test.done(); + } + }; + + // testProps() utility function: given an object, and a hash of expected + // 'property name':'property type' pairs, verify that the object contains each + // expected property, and that each property is of the expected type. + function testProps(object, propTests, test) { + + // function to test each expected property is present and the correct type + function testProp(propName, typeString) { + test.ok(object.hasOwnProperty(propName), '"' + propName + '" prop should be present'); + test.ok(typeof object[propName] === typeString, '"' + propName + '" prop should be of type ' + typeString); + } + + // go over each property test and run it + Object.keys(propTests).forEach(function (propName) { + var propType = propTests[propName]; + testProp(propName, propType); + }); + } + + exports['patternEngines initialization'] = { + 'patternEngines object contains at least the default mustache engine': function (test) { + test.expect(1); + test.ok(patternEngines.hasOwnProperty('mustache')); + test.done(); + } + }; + + // make one big test group for each pattern engine + engineNames.forEach(function (engineName) { + exports[engineName + ' patternEngine'] = { + 'engine contains expected properties and methods': function (test) { + + var propertyTests = { + 'engine': 'object', + 'name': 'string', + 'fileExtension': 'string', + 'renderPattern': 'function', + 'findPartials': 'function' + }; + + test.expect(Object.keys(propertyTests).length * 2); + testProps(patternEngines[engineName], propertyTests, test); + test.done(); + } + }; + }); + +})(); From 5217108de99579925e4e24af83fb3b4d67da5d5f Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Mon, 16 Nov 2015 11:47:29 -0600 Subject: [PATCH 014/187] isPatternFile consolidation and tests --- builder/pattern_assembler.js | 38 ++++++++++++++++----------------- test/pattern_assembler_tests.js | 28 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index 711dafda7..86bd35622 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -1,6 +1,6 @@ -/* - * patternlab-node - v0.14.0 - 2015 - * +/* + * patternlab-node - v0.14.0 - 2015 + * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. * @@ -92,33 +92,31 @@ } } - function isPatternFile(filename, patternlab) { + // ignore _underscored patterns, dotfiles, and anything not recognized by + // a loaded pattern engine + function isPatternFile(filename) { + // skip hidden patterns/files without a second thought + if (filename.charAt(0) === '_' || filename.charAt(0) === '.') { + return false; + } + + // not a hidden pattern, let's dig deeper var engineNames = Object.keys(patternEngines); var supportedPatternFileExtensions = engineNames.map(function (engineName) { return patternEngines[engineName].fileExtension; }); var extension = path.extname(filename); - return (supportedPatternFileExtensions.lastIndexOf(extension) != -1); + return (supportedPatternFileExtensions.lastIndexOf(extension) !== -1); } function processPatternIterative(file, patternlab){ - var fs = require('fs-extra'), - of = require('./object_factory'), - path = require('path'); - //extract some information var subdir = path.dirname(path.relative(patternlab.config.patterns.source, file)).replace('\\', '/'); var filename = path.basename(file); var ext = path.extname(filename); - // ignore _underscored patterns, dotfiles, and anything not recognized by - // a loaded pattern engine - if (filename.charAt(0) === '_' || - filename.charAt(0) === '.' || - (ext === '.json' && filename.indexOf('~') === -1) || - !isPatternFile(filename, patternlab)) { - return; - } + // skip non-pattern files + if (!isPatternFile(filename, patternlab)) { return; } console.log('found pattern', file); //make a new Pattern Object @@ -183,8 +181,7 @@ ph = require('./parameter_hunter'), pph = require('./pseudopattern_hunter'), lih = require('./list_item_hunter'), - smh = require('./style_modifier_hunter'), - path = require('path'); + smh = require('./style_modifier_hunter'); var parameter_hunter = new ph(), lineage_hunter = new lh(), @@ -385,7 +382,8 @@ }, is_object_empty: function(obj){ return isObjectEmpty(obj); - } + }, + is_pattern_file: isPatternFile }; }; diff --git a/test/pattern_assembler_tests.js b/test/pattern_assembler_tests.js index cc4e55333..b532664d1 100644 --- a/test/pattern_assembler_tests.js +++ b/test/pattern_assembler_tests.js @@ -283,6 +283,34 @@ //test that 00-foo.mustache included partial 01-bar.mustache test.equals(fooExtended, 'bar'); + test.done(); + }, + + 'isPatternFile correctly identifies pattern files and rejects non-pattern files': function(test){ + var pattern_assembler = new pa(); + + // each test case + var filenames = { + '00-comment-thread.mustache': true, + '00-comment-thread.fakeextthatdoesntexist': false, + '00-comment-thread': false, + '_00-comment-thread.mustache': false, + '.00-comment-thread.mustache': false, + '00-comment-thread.json': false, + '00-homepage~emergency.json': false + }; + // expect one test per test case + test.expect(Object.keys(filenames).length); + + // loop over each test case and test it + Object.keys(filenames).forEach(function (filename) { + var expectedResult = filenames[filename], + actualResult = pattern_assembler.is_pattern_file(filename), + testMessage = 'isPatternFile should return ' + expectedResult + ' for ' + filename; + test.strictEqual(actualResult, expectedResult, testMessage); + }); + + // done test.done(); } }; From ac54ffb677ba94db95110b0490269f3980f5f2bf Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 17 Nov 2015 12:46:47 -0600 Subject: [PATCH 015/187] We now pass all tests and build "successfully," but pseudo-patterns don't render at all, and are missing in the menu. The quest continues... --- .eslintrc | 2 +- builder/object_factory.js | 25 +++++++++++++++++++--- builder/pattern_assembler.js | 24 ++++++++++++++++----- builder/pattern_engines/pattern_engines.js | 8 +++++-- builder/patternlab.js | 6 +++--- builder/pseudopattern_hunter.js | 17 +++++++++------ builder/util.js | 22 +++++++++++++++++++ test/pattern_engines_tests.js | 9 ++++++++ 8 files changed, 93 insertions(+), 20 deletions(-) create mode 100644 builder/util.js diff --git a/.eslintrc b/.eslintrc index f07e2be6d..1aab4503d 100644 --- a/.eslintrc +++ b/.eslintrc @@ -41,7 +41,7 @@ "no-eval": 2, "no-extend-native": 2, "no-extra-parens": 0, - "no-irregular-whitespace": 2, + "no-irregular-whitespace": 1, "no-iterator": 2, "no-loop-func": 2, "no-multi-str": 2, diff --git a/builder/object_factory.js b/builder/object_factory.js index cd2e533c9..ede4f6a64 100644 --- a/builder/object_factory.js +++ b/builder/object_factory.js @@ -1,6 +1,6 @@ -/* - * patternlab-node - v0.14.0 - 2015 - * +/* + * patternlab-node - v0.14.0 - 2015 + * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. * @@ -14,7 +14,11 @@ var patternEngines = require('./pattern_engines/pattern_engines'); var path = require('path'); + // oPattern properties + var oPattern = function(abspath, subdir, filename, data){ + console.log('new oPattern'); + console.log('absPath:', abspath, 'subdir:', subdir, 'filename:', filename, 'data:', data); this.fileName = filename.substring(0, filename.indexOf('.')); this.fileExtension = path.extname(abspath); this.abspath = abspath; @@ -37,10 +41,22 @@ this.lineageR = []; this.lineageRIndex = []; this.engine = patternEngines.getEngineForPattern(this); + this.isPseudoPattern = false; }; + + // oPattern methods + // render method on oPatterns; this acts as a proxy for the PatternEngine's // render function oPattern.prototype.render = function (data, partials) { + if (this.isPseudoPattern) { + console.log(this.name + ' is a pseudo-pattern'); + } else { + console.log('this is NOT a pseudo-pattern'); + } + // console.log('this does ' + (this.template ? '' : 'NOT ') + 'have template'); + // console.log('this does ' + (this.extendedTemplate ? '' : 'NOT ') + 'have extendedTemplate'); + return this.engine.renderPattern(this.template, data, partials); }; @@ -55,6 +71,7 @@ this.patternItemsIndex = []; }; + var oNavItem = function(name){ this.sectionNameLC = name; this.sectionNameUC = name.split('-').reduce(function(val, working){ @@ -64,6 +81,7 @@ this.navSubItemsIndex = []; }; + var oNavSubItem = function(name){ this.patternPath = ''; this.patternPartial = ''; @@ -72,6 +90,7 @@ }, '').trim(); }; + module.exports = { oPattern: oPattern, oBucket: oBucket, diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index 86bd35622..5efb135e2 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -87,16 +87,20 @@ } else { // otherwise, assume it's a plain mustache template string and act // accordingly - console.log('rendering plain mustache string'); + console.log('rendering plain mustache string:', pattern.substring(0, 20) + '...'); return patternEngines.mustache.renderPattern(pattern, data, partials); } } - // ignore _underscored patterns, dotfiles, and anything not recognized by - // a loaded pattern engine + // ignore _underscored patterns, dotfiles, and anything not recognized by a + // loaded pattern engine. Pseudo-pattern .json files ARE considered to be + // pattern files! function isPatternFile(filename) { // skip hidden patterns/files without a second thought - if (filename.charAt(0) === '_' || filename.charAt(0) === '.') { + var extension = path.extname(filename); + if(filename.charAt(0) === '.' || + filename.charAt(0) === '_' || + (extension === '.json' && filename.indexOf('~') === -1)) { return false; } @@ -105,17 +109,27 @@ var supportedPatternFileExtensions = engineNames.map(function (engineName) { return patternEngines[engineName].fileExtension; }); - var extension = path.extname(filename); return (supportedPatternFileExtensions.lastIndexOf(extension) !== -1); } function processPatternIterative(file, patternlab){ + var fs = require('fs-extra'), + of = require('./object_factory'), + path = require('path'); + //extract some information var subdir = path.dirname(path.relative(patternlab.config.patterns.source, file)).replace('\\', '/'); var filename = path.basename(file); var ext = path.extname(filename); + console.log('processPatternIterative:', 'filename:', filename); + // skip non-pattern files + //ignore dotfiles and non-variant .json files + if(filename.charAt(0) === '.' || (ext === '.json' && filename.indexOf('~') === -1)){ + return; + } + if (!isPatternFile(filename, patternlab)) { return; } console.log('found pattern', file); diff --git a/builder/pattern_engines/pattern_engines.js b/builder/pattern_engines/pattern_engines.js index aab8efe6c..a56ff70e0 100644 --- a/builder/pattern_engines/pattern_engines.js +++ b/builder/pattern_engines/pattern_engines.js @@ -43,8 +43,12 @@ return 'mustache'; }, getEngineForPattern: function (pattern) { - var engineName = this.getEngineNameForPattern(pattern); - return this[engineName]; + if (pattern.isPseudoPattern) { + return this.getEngineForPattern(pattern.basePattern); + } else { + var engineName = this.getEngineNameForPattern(pattern); + return this[engineName]; + } } }); diff --git a/builder/patternlab.js b/builder/patternlab.js index 4cd48c0cb..1b64e990e 100644 --- a/builder/patternlab.js +++ b/builder/patternlab.js @@ -1,6 +1,6 @@ -/* - * patternlab-node - v0.14.0 - 2015 - * +/* + * patternlab-node - v0.14.0 - 2015 + * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. * diff --git a/builder/pseudopattern_hunter.js b/builder/pseudopattern_hunter.js index 92121bb6a..0d04e88c1 100644 --- a/builder/pseudopattern_hunter.js +++ b/builder/pseudopattern_hunter.js @@ -1,6 +1,6 @@ -/* - * patternlab-node - v0.14.0 - 2015 - * +/* + * patternlab-node - v0.14.0 - 2015 + * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. * @@ -20,17 +20,19 @@ pa = require('./pattern_assembler'), lh = require('./lineage_hunter'), of = require('./object_factory'), + patternEngines = require('./pattern_engines/pattern_engines'), mustache = require('mustache'); var pattern_assembler = new pa(); var lineage_hunter = new lh(); - //look for a pseudo pattern by checking if there is a file containing same name, with ~ in it, ending in .json + //look for a pseudo pattern by checking if there is a file containing same + //name, with ~ in it, ending in .json var needle = currentPattern.subdir + '/' + currentPattern.fileName + '~*.json'; var pseudoPatterns = glob.sync(needle, { cwd: 'source/_patterns/', //relative to gruntfile debug: false, - nodir: true, + nodir: true }); if(pseudoPatterns.length > 0){ @@ -47,7 +49,7 @@ //extend any existing data with variant data variantFileData = pattern_assembler.merge_data(currentPattern.jsonFileData, variantFileData); - // GTP: mustache-specific stuff here + // GTP: mustache-specific stuff here var variantName = pseudoPatterns[i].substring(pseudoPatterns[i].indexOf('~') + 1).split('.')[0]; var variantFilePath = 'source/_patterns/' + currentPattern.subdir + '/' + currentPattern.fileName + '~' + variantName + '.json'; var variantFileName = currentPattern.fileName + '-' + variantName + '.'; @@ -59,6 +61,9 @@ //use the same template as the non-variant patternVariant.template = currentPattern.template; patternVariant.extendedTemplate = currentPattern.extendedTemplate; + patternVariant.isPseudoPattern = true; + patternVariant.basePattern = currentPattern; + patternVariant.engine = patternEngines.getEngineForPattern(this); //find pattern lineage lineage_hunter.find_lineage(patternVariant, patternlab); diff --git a/builder/util.js b/builder/util.js new file mode 100644 index 000000000..53ab39a3b --- /dev/null +++ b/builder/util.js @@ -0,0 +1,22 @@ +/* + * patternlab-node - v0.14.0 - 2015 + * + * Brian Muenzenmeyer, Geoffrey Pursell and the web community. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * + */ + +(function () { + var path = require('path'); + + var util = { + // takes a string of the filename or path, and will tell you if it refers to + isPseudoPattern: function () { + + } + }; + + module.exports = util; +}()); diff --git a/test/pattern_engines_tests.js b/test/pattern_engines_tests.js index f2f8d10cd..19f5891dc 100644 --- a/test/pattern_engines_tests.js +++ b/test/pattern_engines_tests.js @@ -6,6 +6,10 @@ // the mustache test pattern, stolen from object_factory unit tests var mustacheTestPattern = new of.oPattern('source/_patterns/00-atoms/00-global/00-colors-alt.mustache', '00-atoms/00-global', '00-colors-alt.mustache', {d: 123}); + var mustacheTestPseudoPatternBasePattern = new of.oPattern('source/_patterns/04-pages/00-homepage.mustache', '04-pages', '00-homepage.mustache', {d: 123}); + var mustacheTestPseudoPattern = new of.oPattern('source/_patterns/04-pages/00-homepage~emergency.json', '04-pages', '00-homepage-emergency.', {d: 123}); + mustacheTestPseudoPattern.isPseudoPattern = true; + mustacheTestPseudoPattern.basePattern = mustacheTestPseudoPatternBasePattern; var engineNames = Object.keys(patternEngines); @@ -19,6 +23,11 @@ var engine = patternEngines.getEngineForPattern(mustacheTestPattern); test.equals(engine, patternEngines.mustache); test.done(); + }, + 'getEngineForPattern returns a reference to the mustache engine from test pseudo-pattern': function (test) { + var engine = patternEngines.getEngineForPattern(mustacheTestPseudoPattern); + test.equals(engine, patternEngines.mustache); + test.done(); } }; From eb52998b97ddeedc3be81a1f5a10bac70f82415f Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 17 Nov 2015 13:33:36 -0600 Subject: [PATCH 016/187] a little progress on the pseudo-pattern problem. They render now, but appear out of order in the nav menu. --- builder/object_factory.js | 5 ++--- builder/pseudopattern_hunter.js | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/builder/object_factory.js b/builder/object_factory.js index ede4f6a64..0f412de33 100644 --- a/builder/object_factory.js +++ b/builder/object_factory.js @@ -17,8 +17,7 @@ // oPattern properties var oPattern = function(abspath, subdir, filename, data){ - console.log('new oPattern'); - console.log('absPath:', abspath, 'subdir:', subdir, 'filename:', filename, 'data:', data); + console.log('NEW OPATTERN. ', 'absPath:', abspath, 'subdir:', subdir, 'filename:', filename, 'data:', data); this.fileName = filename.substring(0, filename.indexOf('.')); this.fileExtension = path.extname(abspath); this.abspath = abspath; @@ -40,8 +39,8 @@ this.lineageIndex = []; this.lineageR = []; this.lineageRIndex = []; - this.engine = patternEngines.getEngineForPattern(this); this.isPseudoPattern = false; + this.engine = patternEngines.getEngineForPattern(this); }; // oPattern methods diff --git a/builder/pseudopattern_hunter.js b/builder/pseudopattern_hunter.js index 0d04e88c1..7615d03d6 100644 --- a/builder/pseudopattern_hunter.js +++ b/builder/pseudopattern_hunter.js @@ -63,7 +63,7 @@ patternVariant.extendedTemplate = currentPattern.extendedTemplate; patternVariant.isPseudoPattern = true; patternVariant.basePattern = currentPattern; - patternVariant.engine = patternEngines.getEngineForPattern(this); + patternVariant.engine = patternVariant.basePattern.engine; //find pattern lineage lineage_hunter.find_lineage(patternVariant, patternlab); From 2cca3cbdc1852147d652be176793ed3c26e33faa Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 17 Nov 2015 16:53:34 -0600 Subject: [PATCH 017/187] eliminate redundant "is this really a pattern" checking --- builder/pattern_assembler.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index 5efb135e2..d8ff037c5 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -125,11 +125,6 @@ console.log('processPatternIterative:', 'filename:', filename); // skip non-pattern files - //ignore dotfiles and non-variant .json files - if(filename.charAt(0) === '.' || (ext === '.json' && filename.indexOf('~') === -1)){ - return; - } - if (!isPatternFile(filename, patternlab)) { return; } console.log('found pattern', file); From 861a1466840b06f420c0599f9b5b1f18285e86fe Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 17 Nov 2015 16:54:07 -0600 Subject: [PATCH 018/187] misc --- builder/pattern_assembler.js | 2 ++ config.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index d8ff037c5..649475168 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -92,6 +92,7 @@ } } + // takes a filename string, not a full path; a basename (plus extension) // ignore _underscored patterns, dotfiles, and anything not recognized by a // loaded pattern engine. Pseudo-pattern .json files ARE considered to be // pattern files! @@ -143,6 +144,7 @@ //can ignore all non-mustache files at this point if(ext !== '.mustache'){ + console.log('==================== FOUND NON-MUSTACHE FILE'); return; } diff --git a/config.json b/config.json index 9ba9f591e..1bdf63495 100644 --- a/config.json +++ b/config.json @@ -9,7 +9,7 @@ ], "ignored-extensions" : ["scss", "DS_Store", "less"], "ignored-directories" : ["scss"], - "debug": false, + "debug": true, "ishControlsVisible": { "s": true, "m": true, From a648ae58d7da96955ce0a6ca7b84f9a7aae8497d Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 17 Nov 2015 16:54:13 -0600 Subject: [PATCH 019/187] fix homepage pattern and its pseudo-pattern not rendering --- builder/object_factory.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/object_factory.js b/builder/object_factory.js index 0f412de33..d90ce4650 100644 --- a/builder/object_factory.js +++ b/builder/object_factory.js @@ -56,7 +56,7 @@ // console.log('this does ' + (this.template ? '' : 'NOT ') + 'have template'); // console.log('this does ' + (this.extendedTemplate ? '' : 'NOT ') + 'have extendedTemplate'); - return this.engine.renderPattern(this.template, data, partials); + return this.engine.renderPattern(this.extendedTemplate, data, partials); }; var oBucket = function(name){ From 7989cfb3c1f5ee7cb00bf84fe1089bdf29f05424 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Wed, 25 Nov 2015 16:06:03 -0600 Subject: [PATCH 020/187] a little more leniency from eslint --- .eslintrc | 1 + 1 file changed, 1 insertion(+) diff --git a/.eslintrc b/.eslintrc index 1aab4503d..61dcc48db 100644 --- a/.eslintrc +++ b/.eslintrc @@ -45,6 +45,7 @@ "no-iterator": 2, "no-loop-func": 2, "no-multi-str": 2, + "no-multi-spaces": 0, "no-new": 2, "no-proto": 2, "no-script-url": 2, From b37e5d729608caffb4d9865db4b99b4748fbd15e Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Wed, 25 Nov 2015 16:08:11 -0600 Subject: [PATCH 021/187] Factor the finders out of pattern_assembler and add them as methods on oPatterns that delegate to PatternEngines. Remove requests to the pattern_assembler functions from hunters and replace them with calls to methods on oPattern. Also add new factory methods for oPatterns to be able to produce empty oPatterns and oPatterns with custom contents, which is useful both for unit testing and other internal use. This helps to cut down on usage of "bare" mustache strings. --- builder/lineage_hunter.js | 15 ++--- builder/list_item_hunter.js | 34 ++++++----- builder/object_factory.js | 50 ++++++++++++++--- builder/pattern_assembler.js | 65 +++++++++------------- builder/pattern_engines/engine_mustache.js | 25 ++++++++- builder/pattern_engines/pattern_engines.js | 14 ++++- 6 files changed, 127 insertions(+), 76 deletions(-) diff --git a/builder/lineage_hunter.js b/builder/lineage_hunter.js index f908fe90f..5109c03ef 100644 --- a/builder/lineage_hunter.js +++ b/builder/lineage_hunter.js @@ -1,10 +1,10 @@ -/* - * patternlab-node - v0.14.0 - 2015 - * +/* + * patternlab-node - v0.14.0 - 2015 + * * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ @@ -19,7 +19,8 @@ var pattern_assembler = new pa(); //find the {{> template-name }} within patterns - var matches = pattern_assembler.find_pattern_partials(pattern); + console.log('===\n', pattern, '\n==='); + var matches = pattern.findPartials(); if(matches !== null){ matches.forEach(function(match, index, matches){ //strip out the template cruft diff --git a/builder/list_item_hunter.js b/builder/list_item_hunter.js index decef1082..ba9f8097c 100644 --- a/builder/list_item_hunter.js +++ b/builder/list_item_hunter.js @@ -1,10 +1,10 @@ -/* - * patternlab-node - v0.14.0 - 2015 - * +/* + * patternlab-node - v0.14.0 - 2015 + * * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ @@ -14,20 +14,23 @@ var list_item_hunter = function(){ var extend = require('util')._extend, - pa = require('./pattern_assembler'), - smh = require('./style_modifier_hunter'), - mustache = require('mustache'), - pattern_assembler = new pa(), - style_modifier_hunter = new smh(), - items = [ 'zero','one','two','three','four','five','six','seven','eight','nine','ten','eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen','twenty']; + pa = require('./pattern_assembler'), + smh = require('./style_modifier_hunter'), + config = require('../config.json'), + of = require('./object_factory'); + + var pattern_assembler = new pa(), + style_modifier_hunter = new smh(), + items = [ 'zero','one','two','three','four','five','six','seven','eight','nine','ten','eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen','twenty']; function processListItemPartials(pattern, patternlab){ //find any listitem blocks - var matches = pattern_assembler.find_list_items(pattern, patternlab); + var matches = pattern.findListItems(); + if(matches !== null){ matches.forEach(function(liMatch, index, matches){ - if(patternlab.config.debug){ + if(config.debug){ console.log('found listItem of size ' + liMatch + ' inside ' + pattern.key); } @@ -39,6 +42,7 @@ var repeatedBlockTemplate = []; var repeatedBlockHtml = ''; for(var i = 0; i < items.indexOf(loopNumberString); i++){ + console.log('adding', patternBlock, 'to repeatedBlockTemplate'); repeatedBlockTemplate.push(patternBlock); } @@ -62,7 +66,7 @@ allData.link = extend({}, patternlab.data.link); //check for partials within the repeated block - var foundPartials = pattern_assembler.find_pattern_partials({ 'template' : thisBlockTemplate }); + var foundPartials = of.oPattern.createEmpty({'template': thisBlockTemplate}).findPartials(); if(foundPartials && foundPartials.length > 0){ diff --git a/builder/object_factory.js b/builder/object_factory.js index d90ce4650..54b910961 100644 --- a/builder/object_factory.js +++ b/builder/object_factory.js @@ -13,11 +13,16 @@ var patternEngines = require('./pattern_engines/pattern_engines'); var path = require('path'); + var fs = require('fs-extra'); + var config = fs.readJSONSync('./config.json'); + var extend = require('util')._extend; // oPattern properties var oPattern = function(abspath, subdir, filename, data){ - console.log('NEW OPATTERN. ', 'absPath:', abspath, 'subdir:', subdir, 'filename:', filename, 'data:', data); + if (config.debug) { + console.log('=== NEW OPATTERN.', '\nabsPath:', abspath, '\nsubdir:', subdir, '\nfilename:', filename, '\ndata:\n', data); + } this.fileName = filename.substring(0, filename.indexOf('.')); this.fileExtension = path.extname(abspath); this.abspath = abspath; @@ -48,16 +53,43 @@ // render method on oPatterns; this acts as a proxy for the PatternEngine's // render function oPattern.prototype.render = function (data, partials) { - if (this.isPseudoPattern) { - console.log(this.name + ' is a pseudo-pattern'); - } else { - console.log('this is NOT a pseudo-pattern'); + if (config.debug && this.isPseudoPattern) { + console.log('===', this.name + ' IS A PSEUDO-PATTERN ==='); } - // console.log('this does ' + (this.template ? '' : 'NOT ') + 'have template'); - // console.log('this does ' + (this.extendedTemplate ? '' : 'NOT ') + 'have extendedTemplate'); - return this.engine.renderPattern(this.extendedTemplate, data, partials); }; + // the finders all delegate to the PatternEngine, which also encapsulates all + // appropriate regexes + oPattern.prototype.findPartials = function () { + return this.engine.findPartials(this); + }; + oPattern.prototype.findPartialsWithStyleModifiers = function () { + return this.engine.findPartialsWithStyleModifiers(this); + }; + oPattern.prototype.findPartialsWithPatternParameters = function () { + return this.engine.findPartialsWithPatternParameters(this); + }; + oPattern.prototype.findListItems = function () { + return this.engine.findListItems(this); + }; + + // oPattern static methods + + // factory: creates an empty oPattern for miscellaneous internal use, such as + // by list_item_hunter + oPattern.createEmpty = function (customProps) { + var pattern = new oPattern('', '', '', null); + return extend(pattern, customProps); + }; + + // factory: creates an oPattern object on-demand from a hash; the hash accepts + // parameters that replace the positional parameters that the oPattern + // constructor takes. + oPattern.create = function (abspath, subdir, filename, data, customProps) { + var newPattern = new oPattern(abspath || '', subdir || '', filename || '', data || null); + return extend(newPattern, customProps); + }; + var oBucket = function(name){ this.bucketNameLC = name; @@ -97,4 +129,4 @@ oNavSubItem: oNavSubItem }; -}()); +})(); diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index 649475168..e488d8a73 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -16,7 +16,8 @@ var fs = require('fs-extra'), of = require('./object_factory'), path = require('path'), - patternEngines = require('./pattern_engines/pattern_engines'); + patternEngines = require('./pattern_engines/pattern_engines'), + config = fs.readJSONSync('./config.json'); function isObjectEmpty(obj) { for(var prop in obj) { @@ -26,29 +27,6 @@ return true; } - // GTP: I need to factor out all these regexes - // returns any patterns that match {{> value:mod }} or {{> value:mod(foo:"bar") }} within the pattern - function findPartialsWithStyleModifiers(pattern){ - var matches = pattern.template.match(/{{>([ ])?([\w\-\.\/~]+)(?!\()(\:[A-Za-z0-9-_]+)+(?:(| )\(.*)?([ ])?}}/g); - return matches; - } - - // returns any patterns that match {{> value(foo:"bar") }} or {{> value:mod(foo:"bar") }} within the pattern - function findPartialsWithPatternParameters(pattern){ - var matches = pattern.template.match(/{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-_]+)?(?:(| )\(.*)+([ ])?}}/g); - return matches; - } - - //find and return any {{> template-name* }} within pattern - function findPartials(pattern){ - var matches = pattern.template.match(/{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-_]+)?(?:(| )\(.*)?([ ])?}}/g); - return matches; - } - - function findListItems(pattern){ - var matches = pattern.template.match(/({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g); - return matches; - } function setState(pattern, patternlab){ if(patternlab.config.patternStates[pattern.patternName]){ @@ -82,12 +60,16 @@ // if we've been passed a full oPattern, it knows what kind of template it // is, and how to render itself, so we just call its render method if (pattern instanceof of.oPattern) { - console.log('rendering full oPattern: ' + pattern.name); + if (config.debug) { + console.log('rendering full oPattern: ' + pattern.name); + } return pattern.render(data, partials); } else { // otherwise, assume it's a plain mustache template string and act // accordingly - console.log('rendering plain mustache string:', pattern.substring(0, 20) + '...'); + if (config.debug) { + console.log('rendering plain mustache string:', pattern.substring(0, 20) + '...'); + } return patternEngines.mustache.renderPattern(pattern, data, partials); } } @@ -106,10 +88,7 @@ } // not a hidden pattern, let's dig deeper - var engineNames = Object.keys(patternEngines); - var supportedPatternFileExtensions = engineNames.map(function (engineName) { - return patternEngines[engineName].fileExtension; - }); + var supportedPatternFileExtensions = patternEngines.getSupportedFileExtensions(); return (supportedPatternFileExtensions.lastIndexOf(extension) !== -1); } @@ -123,11 +102,15 @@ var filename = path.basename(file); var ext = path.extname(filename); - console.log('processPatternIterative:', 'filename:', filename); + if (config.debug) { + console.log('processPatternIterative:', 'filename:', filename); + } // skip non-pattern files if (!isPatternFile(filename, patternlab)) { return; } - console.log('found pattern', file); + if (config.debug) { + console.log('processPatternIterative:', 'found pattern', file); + } //make a new Pattern Object var currentPattern = new of.oPattern(file, subdir, filename); @@ -144,7 +127,9 @@ //can ignore all non-mustache files at this point if(ext !== '.mustache'){ - console.log('==================== FOUND NON-MUSTACHE FILE'); + if (config.debug) { + console.log('==================== FOUND NON-MUSTACHE FILE'); + } return; } @@ -178,10 +163,10 @@ currentPattern.template = fs.readFileSync(file, 'utf8'); //find any stylemodifiers that may be in the current pattern - currentPattern.stylePartials = findPartialsWithStyleModifiers(currentPattern); + currentPattern.stylePartials = currentPattern.findPartialsWithStyleModifiers(); //find any pattern parameters that may be in the current pattern - currentPattern.parameteredPartials = findPartialsWithPatternParameters(currentPattern); + currentPattern.parameteredPartials = currentPattern.findPartialsWithPatternParameters(); //add currentPattern to patternlab.patterns array addPattern(currentPattern, patternlab); @@ -218,7 +203,7 @@ currentPattern.extendedTemplate = currentPattern.template; //find how many partials there may be for the given pattern - var foundPatternPartials = findPartials(currentPattern); + var foundPatternPartials = currentPattern.findPartials(currentPattern); if(foundPatternPartials !== null && foundPatternPartials.length > 0){ @@ -356,16 +341,16 @@ return { find_pattern_partials: function(pattern){ - return findPartials(pattern); + return pattern.findPartials(); }, find_pattern_partials_with_style_modifiers: function(pattern){ - return findPartialsWithStyleModifiers(pattern); + return pattern.findPartialsWithStyleModifiers(); }, find_pattern_partials_with_parameters: function(pattern){ - return findPartialsWithPatternParameters(pattern); + return pattern.findPartialsWithPatternParameters(); }, find_list_items: function(pattern){ - return findListItems(pattern) + return pattern.findListItems(); }, setPatternState: function(pattern, patternlab){ setState(pattern, patternlab); diff --git a/builder/pattern_engines/engine_mustache.js b/builder/pattern_engines/engine_mustache.js index 485a2cf26..23692ae5d 100644 --- a/builder/pattern_engines/engine_mustache.js +++ b/builder/pattern_engines/engine_mustache.js @@ -15,8 +15,14 @@ var engine_mustache = { engine: Mustache, - name: 'mustache', - fileExtension: '.mustache', + engineName: 'mustache', + engineFileExtension: '.mustache', + + // regexes, stored here so they're only compiled once + findPartialsRE: /{{>([ ])?([A-Za-z0-9-]+)(?:\:[A-Za-z0-9-]+)?(?:(| )\(.*)?([ ])?}}/g, + findPartialsWithStyleModifiersRE: /{{>([ ])?([\w\-\.\/~]+)(?!\()(\:[A-Za-z0-9-_]+)+(?:(| )\(.*)?([ ])?}}/g, + findPartialsWithPatternParametersRE: /{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-_]+)?(?:(| )\(.*)+([ ])?}}/g, + findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, // render it renderPattern: function renderPattern(template, data, partials) { @@ -28,7 +34,20 @@ // find and return any {{> template-name }} within pattern findPartials: function findPartials(pattern) { - var matches = pattern.template.match(/{{>([ ])?([A-Za-z0-9-]+)(?:\:[A-Za-z0-9-]+)?(?:(| )\(.*)?([ ])?}}/g); + var matches = pattern.template.match(this.findPartialsRE); + return matches; + }, + findPartialsWithStyleModifiers: function(pattern){ + var matches = pattern.template.match(this.findPartialsWithStyleModifiersRE); + return matches; + }, + // returns any patterns that match {{> value(foo:"bar") }} or {{> value:mod(foo:"bar") }} within the pattern + findPartialsWithPatternParameters: function(pattern){ + var matches = pattern.template.match(this.findPartialsWithPatternParametersRE); + return matches; + }, + findListItems: function(pattern){ + var matches = pattern.template.match(this.findListItemsRE); return matches; } }; diff --git a/builder/pattern_engines/pattern_engines.js b/builder/pattern_engines/pattern_engines.js index a56ff70e0..8a0711f99 100644 --- a/builder/pattern_engines/pattern_engines.js +++ b/builder/pattern_engines/pattern_engines.js @@ -35,7 +35,7 @@ // avoid circular dependency by putting this in here. TODO: is this slow? var of = require('../object_factory'); - if (pattern instanceof of.oPattern) { + if (pattern instanceof of.oPattern && typeof pattern.fileExtension === 'string' && pattern.fileExtension) { return engineNameForExtension[pattern.fileExtension]; } // otherwise, assume it's a plain mustache template string and act @@ -49,6 +49,16 @@ var engineName = this.getEngineNameForPattern(pattern); return this[engineName]; } + }, + getSupportedFileExtensions: function () { + var engineNames = Object.keys(PatternEngines); + return engineNames.map(function (engineName) { + return PatternEngines[engineName].engineFileExtension; + }); + }, + isFileExtensionSupported: function (fileExtension) { + var supportedExtensions = PatternEngines.getSupportedFileExtensions(); + return (supportedExtensions.lastIndexOf(fileExtension) !== -1); } }); @@ -69,7 +79,7 @@ var mapping = {}; Object.keys(PatternEngines).forEach(function (engineName) { - var extensionForEngine = PatternEngines[engineName].fileExtension; + var extensionForEngine = PatternEngines[engineName].engineFileExtension; mapping[extensionForEngine] = engineName; }); From 2c04ac10a46f92daeb8235779001858fc980c56a Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Wed, 25 Nov 2015 16:11:33 -0600 Subject: [PATCH 022/187] Beef up all the unit tests -- use the new oPattern factories rather than faking oPatterns with incomplete object literals. This is a nice way to do it because it gives us a more accurate model of what happens at runtime, but also because we now really need oPatterns to be able to detect PatternEngines based on their file extensions for accurate testing. --- test/lineage_hunter_tests.js | 104 ++++++---------- test/list_item_hunter_tests.js | 86 +++++++------- test/pattern_assembler_tests.js | 204 +++++++++++++++++++------------- test/pattern_engines_tests.js | 21 +++- 4 files changed, 221 insertions(+), 194 deletions(-) diff --git a/test/lineage_hunter_tests.js b/test/lineage_hunter_tests.js index d773f6d6e..7c00ce415 100644 --- a/test/lineage_hunter_tests.js +++ b/test/lineage_hunter_tests.js @@ -2,29 +2,34 @@ "use strict"; var lh = require('../builder/lineage_hunter'); + var of = require('../builder/object_factory'); + var extend = require('util')._extend; + + // fake pattern creators + function createFakeEmptyErrorPattern() { + return new of.oPattern( + '/home/fakeuser/pl/source/_patterns/01-molecules/01-toast/00-error.mustache', // abspath + '01-molecules\\01-toast', // subdir + '00-error.mustache', // filename, + null // data + ); + } exports['lineage hunter '] = { 'test lineage hunter finds lineage' : function(test){ //setup current pattern from what we would have during execution - var currentPattern = { - "name": "02-organisms-00-global-00-header", - "subdir": "02-organisms\\00-global", - "filename": "00-header.mustache", - "data": null, + var currentPattern = new of.oPattern( + '/home/fakeuser/pl/source/_patterns/02-organisms/00-global/00-header.mustache', // abspath + '02-organisms\\00-global', // subdir + '00-header.mustache', // filename, + null // data + ); + extend(currentPattern, { "template": "\r\n
\r\n\t{{> atoms-logo }}\r\n\tSearch\r\n\tMenu\r\n\t{{> molecules-primary-nav }}\r\n\t{{> molecules-search }}\r\n
\r\n\r\n", - "patternPartial": "\r\n
\r\n\"Logo\tSearch\r\n\tMenu\r\n\r\n
\r\n
\r\n\t Search\r\n\t \r\n\t \r\n\t \r\n
\r\n
\r\n\r\n", - "patternName": "header", - "patternLink": "02-organisms-00-global-00-header/02-organisms-00-global-00-header.html", - "patternGroup": "organisms", - "patternSubGroup": "organisms\\00-global", - "flatPatternPath": "02-organisms\\00-global", - "patternState": "", - "lineage": [], - "lineageIndex": [], - "lineageR": [], - "lineageRIndex": [] - }; + "patternPartial": "\r\n
\r\n\"Logo\tSearch\r\n\tMenu\r\n\r\n
\r\n
\r\n\t Search\r\n\t \r\n\t \r\n\t \r\n
\r\n
\r\n\r\n" + }); + var patternlab = { patterns: [ { @@ -97,24 +102,12 @@ 'test lineage hunter finds lineage with spaced pattern parameters' : function(test){ //setup current pattern from what we would have during execution - var currentPattern = { - "name": "01-molecules-01-toast-00-error", - "subdir": "01-molecules\\01-toast", - "filename": "00-error.mustache", - "data": null, + var currentPattern = createFakeEmptyErrorPattern(); + extend(currentPattern, { "template": "{{> atoms-error(message: 'That\'s no moon...') }}", - "patternPartial": "{{> atoms-error(message: 'That\'s no moon...') }}", - "patternName": "error", - "patternLink": "01-molecules-01-toast-00-error/01-molecules-01-toast-00-error.html", - "patternGroup": "molecules", - "patternSubGroup": "molecules\\01-toast", - "flatPatternPath": "01-molecules\\01-toast", - "patternState": "", - "lineage": [], - "lineageIndex": [], - "lineageR": [], - "lineageRIndex": [] - }; + "patternPartial": "{{> atoms-error(message: 'That\'s no moon...') }}" + }); + var patternlab = { patterns: [ { @@ -149,24 +142,12 @@ 'test lineage hunter finds lineage with unspaced pattern parameters' : function(test){ //setup current pattern from what we would have during execution - var currentPattern = { - "name": "01-molecules-01-toast-00-error", - "subdir": "01-molecules\\01-toast", - "filename": "00-error.mustache", - "data": null, + var currentPattern = createFakeEmptyErrorPattern(); + extend(currentPattern, { "template": "{{>atoms-error(message: 'That\'s no moon...')}}", "patternPartial": "{{>atoms-error(message: 'That\'s no moon...')}}", - "patternName": "error", - "patternLink": "01-molecules-01-toast-00-error/01-molecules-01-toast-00-error.html", - "patternGroup": "molecules", - "patternSubGroup": "molecules\\01-toast", - "flatPatternPath": "01-molecules\\01-toast", - "patternState": "", - "lineage": [], - "lineageIndex": [], - "lineageR": [], - "lineageRIndex": [] - }; + }); + var patternlab = { patterns: [ { @@ -203,24 +184,11 @@ 'test lineage hunter does not apply lineage twice' : function(test){ //setup current pattern from what we would have during execution - var currentPattern = { - "name": "01-molecules-01-toast-00-error", - "subdir": "01-molecules\\01-toast", - "filename": "00-error.mustache", - "data": null, + var currentPattern = createFakeEmptyErrorPattern(); + extend(currentPattern, { "template": "{{>atoms-error(message: 'That\'s no moon...')}}", - "patternPartial": "{{>atoms-error(message: 'That\'s no moon...')}}", - "patternName": "error", - "patternLink": "01-molecules-01-toast-00-error/01-molecules-01-toast-00-error.html", - "patternGroup": "molecules", - "patternSubGroup": "molecules\\01-toast", - "flatPatternPath": "01-molecules\\01-toast", - "patternState": "", - "lineage": [], - "lineageIndex": [], - "lineageR": [], - "lineageRIndex": [] - }; + "patternPartial": "{{>atoms-error(message: 'That\'s no moon...')}}" + }); var patternlab = { patterns: [ { @@ -254,7 +222,7 @@ test.equals(JSON.parse(patternlab.patterns[0].lineageR).lineagePattern, 'molecules-error'); test.done(); - }, + } }; diff --git a/test/list_item_hunter_tests.js b/test/list_item_hunter_tests.js index d2de41468..aa0529b74 100644 --- a/test/list_item_hunter_tests.js +++ b/test/list_item_hunter_tests.js @@ -2,17 +2,31 @@ "use strict"; var lih = require('../builder/list_item_hunter'); + var of = require('../builder/object_factory'); + var extend = require('util')._extend; + + // fake pattern creators + function createFakeListPattern(customProps) { + var inputs = { + abspath: '/home/fakeuser/pl/source/_patterns/01-molecules/01-lists/00-list.mustache', + subdir: '01-molecules\\01-lists', + filename: '00-list.mustache', + data: {} + }; + var pattern = new of.oPattern(inputs.abspath, inputs.subdir, inputs.filename, inputs.data); + + return extend(pattern, customProps); + } exports['list_item_hunter'] = { 'process_list_item_partials finds and outputs basic repeating blocks' : function(test){ //arrange //setup current pattern from what we would have during execution - var currentPattern = { - "template": "{{#listItems.two}}{{ title }}{{/listItems.two}}", - "extendedTemplate" : "{{#listItems.two}}{{ title }}{{/listItems.two}}", - "key": "test-patternName", - "jsonFileData" : {} - }; + var currentPattern = createFakeListPattern({ + "template": "{{#listItems.two}}{{ title }}{{/listItems.two}}", + "extendedTemplate": "{{#listItems.two}}{{ title }}{{/listItems.two}}", + "key": "test-patternName" + }); var patternlab = { "listitems": { @@ -51,12 +65,11 @@ 'process_list_item_partials listitems with lowercase name' : function(test){ //arrange //setup current pattern from what we would have during execution - var currentPattern = { - "template": "{{#listitems.two}}{{ title }}{{/listitems.two}}", - "extendedTemplate" : "{{#listitems.two}}{{ title }}{{/listitems.two}}", - "key": "test-patternName", - "jsonFileData" : {} - }; + var currentPattern = createFakeListPattern({ + "template": "{{#listitems.two}}{{ title }}{{/listitems.two}}", + "extendedTemplate" : "{{#listitems.two}}{{ title }}{{/listitems.two}}", + "key": "test-patternName" + }); var patternlab = { "listitems": { @@ -95,12 +108,11 @@ 'process_list_item_partials finds partials and outputs repeated renders' : function(test){ //arrange //setup current pattern from what we would have during execution - var currentPattern = { - "template": "{{#listItems.two}}{{ title }}{{/listItems.two}}", - "extendedTemplate" : "{{#listItems.two}}{{> test-simple }}{{/listItems.two}}", - "key": "test-patternName", - "jsonFileData" : {} - }; + var currentPattern = createFakeListPattern({ + "template": "{{#listItems.two}}{{ title }}{{/listItems.two}}", + "extendedTemplate" : "{{#listItems.two}}{{> test-simple }}{{/listItems.two}}", + "key": "test-patternName" + }); var patternlab = { "listitems": { @@ -145,19 +157,17 @@ }, 'process_list_item_partials finds verbose partials and outputs repeated renders' : function(test){ - var pattern1 = { + var pattern1 = createFakeListPattern({ "template": "{{#listItems.one}}{{> 00-test/00-foo }}{{/listItems.one}}", "extendedTemplate" : "{{#listItems.one}}{{> 00-test/00-foo }}{{/listItems.one}}", - "key": "test-patternName1", - "jsonFileData" : {} - }; + "key": "test-patternName1" + }); - var pattern2 = { + var pattern2 = createFakeListPattern({ "template": "{{#listItems.two}}{{> 00-test/01-bar.mustache }}{{/listItems.two}}", "extendedTemplate" : "{{#listItems.two}}{{> 00-test/01-bar.mustache }}{{/listItems.two}}", - "key": "test-patternName2", - "jsonFileData" : {} - }; + "key": "test-patternName2" + }); var patternlab = { "listitems": { @@ -181,20 +191,16 @@ }, "config": {"debug": false}, "patterns": [ - { - "template": "{{ title }}", - "extendedTemplate" : "{{ title }}", - "subdir": "00-test", - "fileName": "00-foo", - "jsonFileData" : {} - }, - { - "template": "{{ title }}", - "extendedTemplate" : "{{ title }}", - "subdir": "00-test", - "fileName": "01-bar", - "jsonFileData" : {} - } + of.oPattern.create(null, "00-test", "00-foo", null, { + "template": "{{ title }}", + "extendedTemplate": "{{ title }}", + "jsonFileData": {} + }), + of.oPattern.create(null, "00-test", "00-bar", null, { + "template": "{{ title }}", + "extendedTemplate": "{{ title }}", + "jsonFileData": {} + }) ] }; diff --git a/test/pattern_assembler_tests.js b/test/pattern_assembler_tests.js index b532664d1..5ff9d1ab2 100644 --- a/test/pattern_assembler_tests.js +++ b/test/pattern_assembler_tests.js @@ -2,18 +2,22 @@ "use strict"; var pa = require('../builder/pattern_assembler'); + var of = require('../builder/object_factory'); exports['pattern_assembler'] = { 'find_pattern_partials finds partials' : function(test){ + test.expect(3); //setup current pattern from what we would have during execution - var currentPattern = { - "template": "

{{> molecules-comment-header}}

{{> molecules-single-comment(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}
", - }; - - var pattern_assembler = new pa(); - - var results = pattern_assembler.find_pattern_partials(currentPattern); + var currentPattern = new of.oPattern( + '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath + '01-molecules\\00-testing', // subdir + '00-test-mol.mustache', // filename, + null // data + ); + currentPattern.template = "

{{> molecules-comment-header}}

{{> molecules-single-comment(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}
"; + + var results = currentPattern.findPartials(); test.equals(results.length, 2); test.equals(results[0], '{{> molecules-comment-header}}'); test.equals(results[1], '{{> molecules-single-comment(description: \'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.\') }}'); @@ -22,32 +26,38 @@ }, 'find_pattern_partials finds verbose partials' : function(test){ + test.expect(3); //setup current pattern from what we would have during execution - var currentPattern = { - "template": "

{{> 01-molecules/06-components/03-comment-header.mustache }}

{{> 01-molecules/06-components/02-single-comment(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}
", - }; - - var pattern_assembler = new pa(); - - var results = pattern_assembler.find_pattern_partials(currentPattern); + var currentPattern = new of.oPattern( + '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath + '01-molecules\\00-testing', // subdir + '00-test-mol.mustache', // filename, + null // data + ); + currentPattern.template = "

{{> 01-molecules/06-components/03-comment-header.mustache }}

{{> 01-molecules/06-components/02-single-comment(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}
"; + + var results = currentPattern.findPartials(); test.equals(results.length, 2); test.equals(results[0], '{{> 01-molecules/06-components/03-comment-header.mustache }}'); test.equals(results[1], '{{> 01-molecules/06-components/02-single-comment(description: \'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.\') }}'); - test.done(); }, 'find_pattern_partials_with_style_modifiers finds style modifiers' : function(test){ + test.expect(2); //setup current pattern from what we would have during execution - var currentPattern = { - "template": "

{{> molecules-comment-header}}

{{> molecules-single-comment:foo }}
", - }; - var pattern_assembler = new pa(); + var currentPattern = new of.oPattern( + '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath + '01-molecules\\00-testing', // subdir + '00-test-mol.mustache', // filename, + null // data + ); + currentPattern.template = "

{{> molecules-comment-header}}

{{> molecules-single-comment:foo }}
"; - var results = pattern_assembler.find_pattern_partials_with_style_modifiers(currentPattern); + var results = currentPattern.findPartialsWithStyleModifiers(); test.equals(results.length, 1); test.equals(results[0], '{{> molecules-single-comment:foo }}'); @@ -55,15 +65,19 @@ }, 'find_pattern_partials_with_style_modifiers finds style modifiers with parameters present too' : function(test){ + test.expect(2); //setup current pattern from what we would have during execution - var currentPattern = { - "template": "

{{> molecules-comment-header}}

{{> molecules-single-comment:foo(bar:'baz') }}
", - }; - var pattern_assembler = new pa(); + var currentPattern = new of.oPattern( + '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath + '01-molecules\\00-testing', // subdir + '00-test-mol.mustache', // filename, + null // data + ); + currentPattern.template = "

{{> molecules-comment-header}}

{{> molecules-single-comment:foo(bar:'baz') }}
"; - var results = pattern_assembler.find_pattern_partials_with_style_modifiers(currentPattern); + var results = currentPattern.findPartialsWithStyleModifiers(); test.equals(results.length, 1); test.equals(results[0], "{{> molecules-single-comment:foo(bar:'baz') }}"); @@ -71,15 +85,18 @@ }, 'find_pattern_partials_with_style_modifiers finds style modifiers with verbose partials' : function(test){ + test.expect(2); //setup current pattern from what we would have during execution - var currentPattern = { - "template": "

{{> 01-molecules/06-components/molecules-comment-header}}

{{> 01-molecules/06-components/molecules-single-comment:foo }}
", - }; - - var pattern_assembler = new pa(); - - var results = pattern_assembler.find_pattern_partials_with_style_modifiers(currentPattern); + var currentPattern = new of.oPattern( + '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath + '01-molecules\\00-testing', // subdir + '00-test-mol.mustache', // filename, + null // data + ); + currentPattern.template = "

{{> 01-molecules/06-components/molecules-comment-header}}

{{> 01-molecules/06-components/molecules-single-comment:foo }}
"; + + var results = currentPattern.findPartialsWithStyleModifiers(); test.equals(results.length, 1); test.equals(results[0], '{{> 01-molecules/06-components/molecules-single-comment:foo }}'); @@ -87,45 +104,54 @@ }, 'find_pattern_partials_with_style_modifiers finds no style modifiers when only partials present' : function(test){ + test.expect(1); //setup current pattern from what we would have during execution - var currentPattern = { - "template": "

{{> molecules-comment-header}}

{{> molecules-single-comment }}
", - }; - - var pattern_assembler = new pa(); - - var results = pattern_assembler.find_pattern_partials_with_style_modifiers(currentPattern); + var currentPattern = new of.oPattern( + '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath + '01-molecules\\00-testing', // subdir + '00-test-mol.mustache', // filename, + null // data + ); + currentPattern.template = "

{{> molecules-comment-header}}

{{> molecules-single-comment }}
"; + + var results = currentPattern.findPartialsWithStyleModifiers(); test.equals(results, null); test.done(); }, 'find_pattern_partials_with_style_modifiers finds no style modifiers when only partials with pattern parameters present' : function(test){ + test.expect(1); //setup current pattern from what we would have during execution - var currentPattern = { - "template": "

{{> molecules-comment-header}}

{{> molecules-single-comment(foo: 'bar') }}
", - }; - - var pattern_assembler = new pa(); - - var results = pattern_assembler.find_pattern_partials_with_style_modifiers(currentPattern); + var currentPattern = new of.oPattern( + '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath + '01-molecules\\00-testing', // subdir + '00-test-mol.mustache', // filename, + null // data + ); + currentPattern.template = "

{{> molecules-comment-header}}

{{> molecules-single-comment(foo: 'bar') }}
"; + + var results = currentPattern.findPartialsWithStyleModifiers(); test.equals(results, null); test.done(); }, 'find_pattern_partials_with_parameters finds parameters' : function(test){ + test.expect(2); //setup current pattern from what we would have during execution - var currentPattern = { - "template": "

{{> molecules-comment-header}}

{{> molecules-single-comment(bar:'baz') }}
", - }; - - var pattern_assembler = new pa(); - - var results = pattern_assembler.find_pattern_partials_with_parameters(currentPattern); + var currentPattern = new of.oPattern( + '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath + '01-molecules\\00-testing', // subdir + '00-test-mol.mustache', // filename, + null // data + ); + currentPattern.template = "

{{> molecules-comment-header}}

{{> molecules-single-comment(bar:'baz') }}
"; + + var results = currentPattern.findPartialsWithPatternParameters(); test.equals(results.length, 1); test.equals(results[0], "{{> molecules-single-comment(bar:'baz') }}"); @@ -134,76 +160,86 @@ }, 'find_pattern_partials_with_parameters finds parameters when stylemodifiers present too' : function(test){ + test.expect(2); //setup current pattern from what we would have during execution - var currentPattern = { - "template": "

{{> molecules-comment-header}}

{{> molecules-single-comment:foo(bar:'baz') }}
", - }; - - var pattern_assembler = new pa(); - - var results = pattern_assembler.find_pattern_partials_with_parameters(currentPattern); + var currentPattern = new of.oPattern( + '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath + '01-molecules\\00-testing', // subdir + '00-test-mol.mustache', // filename, + null // data + ); + currentPattern.template = "

{{> molecules-comment-header}}

{{> molecules-single-comment:foo(bar:'baz') }}
"; + + var results = currentPattern.findPartialsWithPatternParameters(); test.equals(results.length, 1); test.equals(results[0], "{{> molecules-single-comment:foo(bar:'baz') }}"); test.done(); - }, 'find_pattern_partials_with_parameters finds parameters with verbose partials' : function(test){ + test.expect(2); //setup current pattern from what we would have during execution - var currentPattern = { - "template": "

{{> 01-molecules/06-components/molecules-comment-header}}

{{> 01-molecules/06-components/molecules-single-comment(bar:'baz') }}
", - }; - - var pattern_assembler = new pa(); - - var results = pattern_assembler.find_pattern_partials_with_parameters(currentPattern); + var currentPattern = new of.oPattern( + '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath + '01-molecules\\00-testing', // subdir + '00-test-mol.mustache', // filename, + null // data + ); + currentPattern.template = "

{{> 01-molecules/06-components/molecules-comment-header}}

{{> 01-molecules/06-components/molecules-single-comment(bar:'baz') }}
"; + + var results = currentPattern.findPartialsWithPatternParameters(); test.equals(results.length, 1); test.equals(results[0], "{{> 01-molecules/06-components/molecules-single-comment(bar:'baz') }}"); test.done(); - }, 'find_pattern_partials_with_parameters finds no style modifiers when only partials present' : function(test){ + test.expect(1); //setup current pattern from what we would have during execution - var currentPattern = { - "template": "

{{> molecules-comment-header}}

{{> molecules-single-comment }}
", - }; - - var pattern_assembler = new pa(); - - var results = pattern_assembler.find_pattern_partials_with_parameters(currentPattern); + var currentPattern = new of.oPattern( + '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath + '01-molecules\\00-testing', // subdir + '00-test-mol.mustache', // filename, + null // data + ); + currentPattern.template = "

{{> molecules-comment-header}}

{{> molecules-single-comment }}
"; + + var results = currentPattern.findPartialsWithPatternParameters(); test.equals(results, null); test.done(); }, 'find_pattern_partials_with_parameters finds no style modifiers when only partials with style modifiers present' : function(test){ + test.expect(1); //setup current pattern from what we would have during execution - var currentPattern = { - "template": "

{{> molecules-comment-header}}

{{> molecules-single-comment:foo }}
", - }; - - var pattern_assembler = new pa(); - - var results = pattern_assembler.find_pattern_partials_with_parameters(currentPattern); + var currentPattern = new of.oPattern( + '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath + '01-molecules\\00-testing', // subdir + '00-test-mol.mustache', // filename, + null // data + ); + currentPattern.template = "

{{> molecules-comment-header}}

{{> molecules-single-comment:foo }}
"; + + var results = currentPattern.findPartialsWithPatternParameters(); test.equals(results, null); test.done(); }, 'process_pattern_recursive recursively includes partials' : function(test){ + test.expect(3); //tests inclusion of partial that will be discovered by diveSync later in iteration than parent //prepare to diveSync var diveSync = require('diveSync'); var fs = require('fs-extra'); - var pa = require('../builder/pattern_assembler'); var pattern_assembler = new pa(); var patterns_dir = './test/files/_patterns'; var patternlab = {}; diff --git a/test/pattern_engines_tests.js b/test/pattern_engines_tests.js index 19f5891dc..34eb5228a 100644 --- a/test/pattern_engines_tests.js +++ b/test/pattern_engines_tests.js @@ -19,6 +19,18 @@ test.equals(engineName, 'mustache'); test.done(); }, + 'getEngineNameForPattern returns "mustache" for a plain string template as a backwards compatibility measure': function (test) { + test.expect(1); + test.equals(patternEngines.getEngineNameForPattern('plain text string'), 'mustache'); + test.done(); + }, + 'getEngineNameForPattern returns "mustache" for an artificial empty template': function (test) { + test.expect(1); + var emptyPattern = of.oPattern.createEmpty(); + console.log(emptyPattern); + test.equals(patternEngines.getEngineNameForPattern(emptyPattern), 'mustache'); + test.done(); + }, 'getEngineForPattern returns a reference to the mustache engine from test pattern': function (test) { var engine = patternEngines.getEngineForPattern(mustacheTestPattern); test.equals(engine, patternEngines.mustache); @@ -54,6 +66,11 @@ test.expect(1); test.ok(patternEngines.hasOwnProperty('mustache')); test.done(); + }, + 'patternEngines object reports that it supports the .mustache extension': function (test) { + test.expect(1); + test.ok(patternEngines.isFileExtensionSupported('.mustache')); + test.done(); } }; @@ -64,8 +81,8 @@ var propertyTests = { 'engine': 'object', - 'name': 'string', - 'fileExtension': 'string', + 'engineName': 'string', + 'engineFileExtension': 'string', 'renderPattern': 'function', 'findPartials': 'function' }; From e8f99c11570e8aff93490bd14556b4db1a46b342 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 1 Dec 2015 10:51:41 -0600 Subject: [PATCH 023/187] Remove unused module requires -- that's the last of the direct couplings to mustache! Hooray! --- builder/parameter_hunter.js | 7 +++---- builder/pseudopattern_hunter.js | 4 +--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/builder/parameter_hunter.js b/builder/parameter_hunter.js index ef70bead5..c17da993b 100644 --- a/builder/parameter_hunter.js +++ b/builder/parameter_hunter.js @@ -1,6 +1,6 @@ -/* - * patternlab-node - v0.14.0 - 2015 - * +/* + * patternlab-node - v0.14.0 - 2015 + * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. * @@ -15,7 +15,6 @@ var extend = require('util')._extend, pa = require('./pattern_assembler'), - mustache = require('mustache'), smh = require('./style_modifier_hunter'), style_modifier_hunter = new smh(), pattern_assembler = new pa(); diff --git a/builder/pseudopattern_hunter.js b/builder/pseudopattern_hunter.js index 7615d03d6..c3dc07f20 100644 --- a/builder/pseudopattern_hunter.js +++ b/builder/pseudopattern_hunter.js @@ -19,9 +19,7 @@ fs = require('fs-extra'), pa = require('./pattern_assembler'), lh = require('./lineage_hunter'), - of = require('./object_factory'), - patternEngines = require('./pattern_engines/pattern_engines'), - mustache = require('mustache'); + of = require('./object_factory'); var pattern_assembler = new pa(); var lineage_hunter = new lh(); From 96c88c0fc6bf9aa6dd3670c26a2f68018fac40bf Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 1 Dec 2015 12:39:30 -0600 Subject: [PATCH 024/187] Migrate some things to a nicer object literal syntax; use the oPattern factory in the pseudopattern hunter; misc. code cleanup; hide some debug console.logs behind the flag --- builder/lineage_hunter.js | 5 +++- builder/object_factory.js | 49 +++++++++++++++++++-------------- builder/patternlab.js | 2 -- builder/pseudopattern_hunter.js | 18 ++++++------ test/pattern_engines_tests.js | 1 - 5 files changed, 41 insertions(+), 34 deletions(-) diff --git a/builder/lineage_hunter.js b/builder/lineage_hunter.js index 5109c03ef..cad37184d 100644 --- a/builder/lineage_hunter.js +++ b/builder/lineage_hunter.js @@ -17,9 +17,12 @@ var pa = require('./pattern_assembler'); var pattern_assembler = new pa(); + var config = require('../config.json'); //find the {{> template-name }} within patterns - console.log('===\n', pattern, '\n==='); + if (config.debug) { + console.log('===\n', pattern, '\n==='); + } var matches = pattern.findPartials(); if(matches !== null){ matches.forEach(function(match, index, matches){ diff --git a/builder/object_factory.js b/builder/object_factory.js index 54b910961..1c32a21da 100644 --- a/builder/object_factory.js +++ b/builder/object_factory.js @@ -19,7 +19,7 @@ // oPattern properties - var oPattern = function(abspath, subdir, filename, data){ + var oPattern = function(abspath, subdir, filename, data) { if (config.debug) { console.log('=== NEW OPATTERN.', '\nabsPath:', abspath, '\nsubdir:', subdir, '\nfilename:', filename, '\ndata:\n', data); } @@ -50,27 +50,34 @@ // oPattern methods - // render method on oPatterns; this acts as a proxy for the PatternEngine's - // render function - oPattern.prototype.render = function (data, partials) { - if (config.debug && this.isPseudoPattern) { - console.log('===', this.name + ' IS A PSEUDO-PATTERN ==='); + oPattern.prototype = { + + // render method on oPatterns; this acts as a proxy for the PatternEngine's + // render function + render: function (data, partials) { + if (config.debug && this.isPseudoPattern) { + console.log('===', this.name + ' IS A PSEUDO-PATTERN ==='); + } + return this.engine.renderPattern(this.extendedTemplate, data, partials); + }, + + // the finders all delegate to the PatternEngine, which also encapsulates all + // appropriate regexes + findPartials: function () { + return this.engine.findPartials(this); + }, + + findPartialsWithStyleModifiers: function () { + return this.engine.findPartialsWithStyleModifiers(this); + }, + + findPartialsWithPatternParameters: function () { + return this.engine.findPartialsWithPatternParameters(this); + }, + + findListItems: function () { + return this.engine.findListItems(this); } - return this.engine.renderPattern(this.extendedTemplate, data, partials); - }; - // the finders all delegate to the PatternEngine, which also encapsulates all - // appropriate regexes - oPattern.prototype.findPartials = function () { - return this.engine.findPartials(this); - }; - oPattern.prototype.findPartialsWithStyleModifiers = function () { - return this.engine.findPartialsWithStyleModifiers(this); - }; - oPattern.prototype.findPartialsWithPatternParameters = function () { - return this.engine.findPartialsWithPatternParameters(this); - }; - oPattern.prototype.findListItems = function () { - return this.engine.findListItems(this); }; // oPattern static methods diff --git a/builder/patternlab.js b/builder/patternlab.js index 1b64e990e..40118b799 100644 --- a/builder/patternlab.js +++ b/builder/patternlab.js @@ -13,9 +13,7 @@ var patternlab_engine = function () { var path = require('path'), fs = require('fs-extra'), - extend = require('util')._extend, diveSync = require('diveSync'), - glob = require('glob'), of = require('./object_factory'), pa = require('./pattern_assembler'), mh = require('./media_hunter'), diff --git a/builder/pseudopattern_hunter.js b/builder/pseudopattern_hunter.js index c3dc07f20..82f88a8f3 100644 --- a/builder/pseudopattern_hunter.js +++ b/builder/pseudopattern_hunter.js @@ -47,22 +47,22 @@ //extend any existing data with variant data variantFileData = pattern_assembler.merge_data(currentPattern.jsonFileData, variantFileData); - // GTP: mustache-specific stuff here var variantName = pseudoPatterns[i].substring(pseudoPatterns[i].indexOf('~') + 1).split('.')[0]; var variantFilePath = 'source/_patterns/' + currentPattern.subdir + '/' + currentPattern.fileName + '~' + variantName + '.json'; var variantFileName = currentPattern.fileName + '-' + variantName + '.'; - var patternVariant = new of.oPattern(variantFilePath, currentPattern.subdir, variantFileName, variantFileData); + var patternVariant = of.oPattern.create(variantFilePath, currentPattern.subdir, variantFileName, variantFileData, { + //use the same template as the non-variant + template: currentPattern.template, + extendedTemplate: currentPattern.extendedTemplate, + isPseudoPattern: true, + basePattern: currentPattern, + // use the same template engine as the non-variant + engine: currentPattern.engine + }); //see if this file has a state pattern_assembler.setPatternState(patternVariant, patternlab); - //use the same template as the non-variant - patternVariant.template = currentPattern.template; - patternVariant.extendedTemplate = currentPattern.extendedTemplate; - patternVariant.isPseudoPattern = true; - patternVariant.basePattern = currentPattern; - patternVariant.engine = patternVariant.basePattern.engine; - //find pattern lineage lineage_hunter.find_lineage(patternVariant, patternlab); diff --git a/test/pattern_engines_tests.js b/test/pattern_engines_tests.js index 34eb5228a..21db4b796 100644 --- a/test/pattern_engines_tests.js +++ b/test/pattern_engines_tests.js @@ -27,7 +27,6 @@ 'getEngineNameForPattern returns "mustache" for an artificial empty template': function (test) { test.expect(1); var emptyPattern = of.oPattern.createEmpty(); - console.log(emptyPattern); test.equals(patternEngines.getEngineNameForPattern(emptyPattern), 'mustache'); test.done(); }, From d7a531e1fc975e2aba724909e349518a2a6fed26 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 1 Dec 2015 12:42:17 -0600 Subject: [PATCH 025/187] factor utility functions out of the pattern assembler and put 'em in our utilities module; move isPatternFile into pattern_engines module since that's where the knowledge it needs is concentrated --- builder/list_item_hunter.js | 7 +- builder/parameter_hunter.js | 5 +- builder/pattern_assembler.js | 83 ++-------------------- builder/pattern_engines/pattern_engines.js | 23 ++++++ builder/patternlab.js | 3 +- builder/pseudopattern_hunter.js | 6 +- builder/util.js | 22 ------ builder/utilities.js | 65 +++++++++++++++++ test/pattern_assembler_tests.js | 3 +- 9 files changed, 109 insertions(+), 108 deletions(-) delete mode 100644 builder/util.js create mode 100644 builder/utilities.js diff --git a/builder/list_item_hunter.js b/builder/list_item_hunter.js index ba9f8097c..40c1bdcfa 100644 --- a/builder/list_item_hunter.js +++ b/builder/list_item_hunter.js @@ -16,6 +16,7 @@ var extend = require('util')._extend, pa = require('./pattern_assembler'), smh = require('./style_modifier_hunter'), + plutils = require('./utilities'), config = require('../config.json'), of = require('./object_factory'); @@ -48,7 +49,7 @@ //check for a local listitems.json file var listData = JSON.parse(JSON.stringify(patternlab.listitems)); - listData = pattern_assembler.merge_data(listData, pattern.listitems); + listData = plutils.mergeData(listData, pattern.listitems); //iterate over each copied block, rendering its contents along with pattenlab.listitems[i] for(var i = 0; i < repeatedBlockTemplate.length; i++){ @@ -61,8 +62,8 @@ var globalData = JSON.parse(JSON.stringify(patternlab.data)); var localData = JSON.parse(JSON.stringify(pattern.jsonFileData)); - var allData = pattern_assembler.merge_data(globalData, localData); - allData = pattern_assembler.merge_data(allData, itemData != undefined ? itemData[i] : {}); //itemData could be undefined if the listblock contains no partial, just markup + var allData = plutils.mergeData(globalData, localData); + allData = plutils.mergeData(allData, itemData != undefined ? itemData[i] : {}); //itemData could be undefined if the listblock contains no partial, just markup allData.link = extend({}, patternlab.data.link); //check for partials within the repeated block diff --git a/builder/parameter_hunter.js b/builder/parameter_hunter.js index c17da993b..5ef4f672b 100644 --- a/builder/parameter_hunter.js +++ b/builder/parameter_hunter.js @@ -16,6 +16,7 @@ var extend = require('util')._extend, pa = require('./pattern_assembler'), smh = require('./style_modifier_hunter'), + plutils = require('./utilities'), style_modifier_hunter = new smh(), pattern_assembler = new pa(); @@ -43,8 +44,8 @@ var globalData = JSON.parse(JSON.stringify(patternlab.data)); var localData = JSON.parse(JSON.stringify(pattern.jsonFileData || {})); - var allData = pattern_assembler.merge_data(globalData, localData); - allData = pattern_assembler.merge_data(allData, paramData); + var allData = plutils.mergeData(globalData, localData); + allData = plutils.mergeData(allData, paramData); //if partial has style modifier data, replace the styleModifier value if(pattern.stylePartials && pattern.stylePartials.length > 0){ diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index e488d8a73..f96fd56b5 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -15,19 +15,10 @@ var fs = require('fs-extra'), of = require('./object_factory'), - path = require('path'), + plutils = require('./utilities'), patternEngines = require('./pattern_engines/pattern_engines'), config = fs.readJSONSync('./config.json'); - function isObjectEmpty(obj) { - for(var prop in obj) { - if(obj.hasOwnProperty(prop)) - return false; - } - - return true; - } - function setState(pattern, patternlab){ if(patternlab.config.patternStates[pattern.patternName]){ pattern.patternState = patternlab.config.patternStates[pattern.patternName]; @@ -74,24 +65,6 @@ } } - // takes a filename string, not a full path; a basename (plus extension) - // ignore _underscored patterns, dotfiles, and anything not recognized by a - // loaded pattern engine. Pseudo-pattern .json files ARE considered to be - // pattern files! - function isPatternFile(filename) { - // skip hidden patterns/files without a second thought - var extension = path.extname(filename); - if(filename.charAt(0) === '.' || - filename.charAt(0) === '_' || - (extension === '.json' && filename.indexOf('~') === -1)) { - return false; - } - - // not a hidden pattern, let's dig deeper - var supportedPatternFileExtensions = patternEngines.getSupportedFileExtensions(); - return (supportedPatternFileExtensions.lastIndexOf(extension) !== -1); - } - function processPatternIterative(file, patternlab){ var fs = require('fs-extra'), of = require('./object_factory'), @@ -107,7 +80,7 @@ } // skip non-pattern files - if (!isPatternFile(filename, patternlab)) { return; } + if (!patternEngines.isPatternFile(filename, patternlab)) { return; } if (config.debug) { console.log('processPatternIterative:', 'found pattern', file); } @@ -274,40 +247,7 @@ throw 'Could not find pattern with key ' + key; } - /** - * Recursively merge properties of two objects. - * - * @param {Object} obj1 If obj1 has properties obj2 doesn't, add to obj2. - * @param {Object} obj2 This object's properties have priority over obj1. - * @returns {Object} obj2 - */ - function mergeData(obj1, obj2){ - if(typeof obj2 === 'undefined'){ - obj2 = {}; - } - for(var p in obj1){ - try { - // Only recurse if obj1[p] is an object. - if(obj1[p].constructor === Object){ - // Requires 2 objects as params; create obj2[p] if undefined. - if(typeof obj2[p] === 'undefined'){ - obj2[p] = {}; - } - obj2[p] = mergeData(obj1[p], obj2[p]); - // Pop when recursion meets a non-object. If obj1[p] is a non-object, - // only copy to undefined obj2[p]. This way, obj2 maintains priority. - } else if(typeof obj2[p] === 'undefined'){ - obj2[p] = obj1[p]; - } - } catch(e) { - // Property in destination object not set; create it and set its value. - if(typeof obj2[p] === 'undefined'){ - obj2[p] = obj1[p]; - } - } - } - return obj2; - } + function buildListItems(container){ //combine all list items into one structure @@ -317,7 +257,7 @@ list.push(container.listitems[item]); } } - container.listItemArray = shuffle(list); + container.listItemArray = plutils.shuffle(list); for(var i = 1; i <= container.listItemArray.length; i++){ var tempItems = []; @@ -333,11 +273,7 @@ } } - //http://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array-in-javascript - function shuffle(o){ - for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x); - return o; - } + return { find_pattern_partials: function(pattern){ @@ -370,16 +306,9 @@ get_pattern_by_key: function(key, patternlab){ return getpatternbykey(key, patternlab); }, - merge_data: function(existingData, newData){ - return mergeData(existingData, newData); - }, combine_listItems: function(patternlab){ buildListItems(patternlab); - }, - is_object_empty: function(obj){ - return isObjectEmpty(obj); - }, - is_pattern_file: isPatternFile + } }; }; diff --git a/builder/pattern_engines/pattern_engines.js b/builder/pattern_engines/pattern_engines.js index 8a0711f99..32370f154 100644 --- a/builder/pattern_engines/pattern_engines.js +++ b/builder/pattern_engines/pattern_engines.js @@ -12,6 +12,8 @@ (function () { 'use strict'; + var path = require('path'); + // list of supported pattern engines var supportedPatternEngineNames = [ 'mustache', @@ -42,6 +44,7 @@ // accordingly return 'mustache'; }, + getEngineForPattern: function (pattern) { if (pattern.isPseudoPattern) { return this.getEngineForPattern(pattern.basePattern); @@ -50,15 +53,35 @@ return this[engineName]; } }, + getSupportedFileExtensions: function () { var engineNames = Object.keys(PatternEngines); return engineNames.map(function (engineName) { return PatternEngines[engineName].engineFileExtension; }); }, + isFileExtensionSupported: function (fileExtension) { var supportedExtensions = PatternEngines.getSupportedFileExtensions(); return (supportedExtensions.lastIndexOf(fileExtension) !== -1); + }, + + // takes a filename string, not a full path; a basename (plus extension) + // ignore _underscored patterns, dotfiles, and anything not recognized by a + // loaded pattern engine. Pseudo-pattern .json files ARE considered to be + // pattern files! + isPatternFile: function (filename) { + // skip hidden patterns/files without a second thought + var extension = path.extname(filename); + if(filename.charAt(0) === '.' || + filename.charAt(0) === '_' || + (extension === '.json' && filename.indexOf('~') === -1)) { + return false; + } + + // not a hidden pattern, let's dig deeper + var supportedPatternFileExtensions = PatternEngines.getSupportedFileExtensions(); + return (supportedPatternFileExtensions.lastIndexOf(extension) !== -1); } }); diff --git a/builder/patternlab.js b/builder/patternlab.js index 40118b799..3968b4bc0 100644 --- a/builder/patternlab.js +++ b/builder/patternlab.js @@ -19,6 +19,7 @@ var patternlab_engine = function () { mh = require('./media_hunter'), pe = require('./pattern_exporter'), he = require('html-entities').AllHtmlEntities, + plutils = require('./utilities'), patternlab = {}; patternlab.package = fs.readJSONSync('./package.json'); @@ -120,7 +121,7 @@ var patternlab_engine = function () { patternlab.patterns.forEach(function(pattern, index, patterns){ //render the pattern, but first consolidate any data we may have var allData = JSON.parse(JSON.stringify(patternlab.data)); - allData = pattern_assembler.merge_data(allData, pattern.jsonFileData); + allData = plutils.mergeData(allData, pattern.jsonFileData); pattern.patternPartial = pattern_assembler.renderPattern(pattern, allData); diff --git a/builder/pseudopattern_hunter.js b/builder/pseudopattern_hunter.js index 82f88a8f3..a5ab86bf4 100644 --- a/builder/pseudopattern_hunter.js +++ b/builder/pseudopattern_hunter.js @@ -19,7 +19,8 @@ fs = require('fs-extra'), pa = require('./pattern_assembler'), lh = require('./lineage_hunter'), - of = require('./object_factory'); + of = require('./object_factory'), + plutils = require('./utilities'); var pattern_assembler = new pa(); var lineage_hunter = new lh(); @@ -38,6 +39,7 @@ for(var i = 0; i < pseudoPatterns.length; i++){ if(patternlab.config.debug){ + debugger; console.log('found pseudoPattern variant of ' + currentPattern.key); } @@ -45,7 +47,7 @@ var variantFileData = fs.readJSONSync('source/_patterns/' + pseudoPatterns[i]); //extend any existing data with variant data - variantFileData = pattern_assembler.merge_data(currentPattern.jsonFileData, variantFileData); + variantFileData = plutils.mergeData(currentPattern.jsonFileData, variantFileData); var variantName = pseudoPatterns[i].substring(pseudoPatterns[i].indexOf('~') + 1).split('.')[0]; var variantFilePath = 'source/_patterns/' + currentPattern.subdir + '/' + currentPattern.fileName + '~' + variantName + '.json'; diff --git a/builder/util.js b/builder/util.js deleted file mode 100644 index 53ab39a3b..000000000 --- a/builder/util.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * patternlab-node - v0.14.0 - 2015 - * - * Brian Muenzenmeyer, Geoffrey Pursell and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - -(function () { - var path = require('path'); - - var util = { - // takes a string of the filename or path, and will tell you if it refers to - isPseudoPattern: function () { - - } - }; - - module.exports = util; -}()); diff --git a/builder/utilities.js b/builder/utilities.js new file mode 100644 index 000000000..64d5190ed --- /dev/null +++ b/builder/utilities.js @@ -0,0 +1,65 @@ +/* + * patternlab-node - v0.14.0 - 2015 + * + * Brian Muenzenmeyer, Geoffrey Pursell and the web community. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * + */ + +(function () { + var path = require('path'); + + var util = { + // http://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array-in-javascript + shuffle: function (o) { + for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x); + return o; + }, + + /** + * Recursively merge properties of two objects. + * + * @param {Object} obj1 If obj1 has properties obj2 doesn't, add to obj2. + * @param {Object} obj2 This object's properties have priority over obj1. + * @returns {Object} obj2 + */ + mergeData: function (obj1, obj2) { + if(typeof obj2 === 'undefined'){ + obj2 = {}; + } + for(var p in obj1){ + try { + // Only recurse if obj1[p] is an object. + if(obj1[p].constructor === Object){ + // Requires 2 objects as params; create obj2[p] if undefined. + if(typeof obj2[p] === 'undefined'){ + obj2[p] = {}; + } + obj2[p] = util.mergeData(obj1[p], obj2[p]); + // Pop when recursion meets a non-object. If obj1[p] is a non-object, + // only copy to undefined obj2[p]. This way, obj2 maintains priority. + } else if(typeof obj2[p] === 'undefined'){ + obj2[p] = obj1[p]; + } + } catch(e) { + // Property in destination object not set; create it and set its value. + if(typeof obj2[p] === 'undefined'){ + obj2[p] = obj1[p]; + } + } + } + return obj2; + }, + + isObjectEmpty: function (obj) { + for(var prop in obj) { + if(obj.hasOwnProperty(prop)) { return false; } + } + return true; + } + }; + + module.exports = util; +}()); diff --git a/test/pattern_assembler_tests.js b/test/pattern_assembler_tests.js index 5ff9d1ab2..dab6426da 100644 --- a/test/pattern_assembler_tests.js +++ b/test/pattern_assembler_tests.js @@ -3,6 +3,7 @@ var pa = require('../builder/pattern_assembler'); var of = require('../builder/object_factory'); + var patternEngines = require('../builder/pattern_engines/pattern_engines'); exports['pattern_assembler'] = { 'find_pattern_partials finds partials' : function(test){ @@ -341,7 +342,7 @@ // loop over each test case and test it Object.keys(filenames).forEach(function (filename) { var expectedResult = filenames[filename], - actualResult = pattern_assembler.is_pattern_file(filename), + actualResult = patternEngines.isPatternFile(filename), testMessage = 'isPatternFile should return ' + expectedResult + ' for ' + filename; test.strictEqual(actualResult, expectedResult, testMessage); }); From 0ffb2fe97c98b70591fac5447de7627be07a2ae8 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 1 Dec 2015 17:18:11 -0600 Subject: [PATCH 026/187] have eslint chill out about a couple things --- .eslintrc | 4 +++- builder/list_item_hunter.js | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.eslintrc b/.eslintrc index 61dcc48db..9f090e1e2 100644 --- a/.eslintrc +++ b/.eslintrc @@ -15,7 +15,7 @@ "all" ], "dot-notation": [ - 2, + 1, { "allowKeywords": true } @@ -29,6 +29,7 @@ "never" ], "guard-for-in": 2, + "key-spacing": 1, "new-cap": 0, "no-bitwise": 2, "no-caller": 2, @@ -52,6 +53,7 @@ "no-sequences": 2, "no-shadow": 2, "no-undef": 2, + "no-underscore-dangle": 1, "no-unused-vars": 2, "no-with": 2, "quotes": [ diff --git a/builder/list_item_hunter.js b/builder/list_item_hunter.js index 40c1bdcfa..d2e56f212 100644 --- a/builder/list_item_hunter.js +++ b/builder/list_item_hunter.js @@ -43,7 +43,9 @@ var repeatedBlockTemplate = []; var repeatedBlockHtml = ''; for(var i = 0; i < items.indexOf(loopNumberString); i++){ - console.log('adding', patternBlock, 'to repeatedBlockTemplate'); + if (config.debug) { + console.log('list item(s) in pattern', pattern.patternName, 'adding', patternBlock, 'to repeatedBlockTemplate'); + } repeatedBlockTemplate.push(patternBlock); } From b03bc45f4a6df3666e98bdac12b64b7dc0a98ff1 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 1 Dec 2015 17:21:02 -0600 Subject: [PATCH 027/187] New partial finding regex for Mustache that accounts for regular syntax, verbose syntax, style modifier syntax, pattern parameter syntax, and single and double quoted strings in pattern parameters with escaped quotes. Making this hurt my brain very badly. Update the appropriate unit test with all the test cases used to develop the regex, plus some flown in from other unit tests. --- builder/pattern_engines/engine_mustache.js | 2 +- test/pattern_assembler_tests.js | 45 +++++++++++++++++----- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/builder/pattern_engines/engine_mustache.js b/builder/pattern_engines/engine_mustache.js index 23692ae5d..87be322f2 100644 --- a/builder/pattern_engines/engine_mustache.js +++ b/builder/pattern_engines/engine_mustache.js @@ -19,7 +19,7 @@ engineFileExtension: '.mustache', // regexes, stored here so they're only compiled once - findPartialsRE: /{{>([ ])?([A-Za-z0-9-]+)(?:\:[A-Za-z0-9-]+)?(?:(| )\(.*)?([ ])?}}/g, + findPartialsRE: /{{>\s*((?:\d+-[\w-]+\/)+(\d+-[\w-]+\.\w+)|[A-Za-z0-9-]+)(\:[A-Za-z0-9-]+)?(\(\s*\w+\s*:\s*(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*")\))?\s*}}/g, findPartialsWithStyleModifiersRE: /{{>([ ])?([\w\-\.\/~]+)(?!\()(\:[A-Za-z0-9-_]+)+(?:(| )\(.*)?([ ])?}}/g, findPartialsWithPatternParametersRE: /{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-_]+)?(?:(| )\(.*)+([ ])?}}/g, findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, diff --git a/test/pattern_assembler_tests.js b/test/pattern_assembler_tests.js index dab6426da..a3701dff9 100644 --- a/test/pattern_assembler_tests.js +++ b/test/pattern_assembler_tests.js @@ -7,22 +7,47 @@ exports['pattern_assembler'] = { 'find_pattern_partials finds partials' : function(test){ - test.expect(3); + test.expect(13); //setup current pattern from what we would have during execution - var currentPattern = new of.oPattern( + var currentPattern = of.oPattern.create( '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath '01-molecules\\00-testing', // subdir '00-test-mol.mustache', // filename, - null // data + null, // data + { + template: "{{> molecules-comment-header}}asdfasdf" + + "{{> molecules-comment-header}}" + + "{{> \n molecules-comment-header\n}}" + + "{{> }}" + + "{{> molecules-weird-spacing }}" + + "{{> molecules-ba_d-cha*rs }}" + + "{{> molecules-single-comment(description: 'A life isn\\'t like a garden. Perfect moments can be had, but not preserved, except in memory.') }}" + + '{{> molecules-single-comment(description: "A life is like a \\"garden\\". Perfect moments can be had, but not preserved, except in memory.") }}' + + "{{> molecules-single-comment:foo }}" + + "{{> 01-molecules/06-components/03-comment-header.mustache }}" + + "{{> 01-molecules/06-components/02-single-comment.mustache(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}" + + "{{> molecules-single-comment:foo }}" + + "{{>atoms-error(message: 'That\\'s no moon...')}}" + + '{{>atoms-error(message: \'That\\\'s no moon...\')}}' + } ); - currentPattern.template = "

{{> molecules-comment-header}}

{{> molecules-single-comment(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}
"; var results = currentPattern.findPartials(); - test.equals(results.length, 2); - test.equals(results[0], '{{> molecules-comment-header}}'); - test.equals(results[1], '{{> molecules-single-comment(description: \'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.\') }}'); - + console.log(results); + test.equals(results.length, 12); + test.equals(results[0], "{{> molecules-comment-header}}"); + test.equals(results[1], "{{> molecules-comment-header}}"); + test.equals(results[2], "{{> \n molecules-comment-header\n}}"); + test.equals(results[3], "{{> molecules-weird-spacing }}"); + test.equals(results[4], "{{> molecules-single-comment(description: 'A life isn\\'t like a garden. Perfect moments can be had, but not preserved, except in memory.') }}"); + test.equals(results[5], '{{> molecules-single-comment(description: "A life is like a \\"garden\\". Perfect moments can be had, but not preserved, except in memory.") }}'); + test.equals(results[6], "{{> molecules-single-comment:foo }}"); + test.equals(results[7], "{{> 01-molecules/06-components/03-comment-header.mustache }}"); + test.equals(results[8], "{{> 01-molecules/06-components/02-single-comment.mustache(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}"); + test.equals(results[9], "{{> molecules-single-comment:foo }}"); + test.equals(results[10], "{{>atoms-error(message: 'That\\'s no moon...')}}"); + test.equals(results[11], "{{>atoms-error(message: 'That\\'s no moon...')}}"); test.done(); }, @@ -36,12 +61,12 @@ '00-test-mol.mustache', // filename, null // data ); - currentPattern.template = "

{{> 01-molecules/06-components/03-comment-header.mustache }}

{{> 01-molecules/06-components/02-single-comment(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}
"; + currentPattern.template = "

{{> 01-molecules/06-components/03-comment-header.mustache }}

{{> 01-molecules/06-components/02-single-comment.mustache(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}
"; var results = currentPattern.findPartials(); test.equals(results.length, 2); test.equals(results[0], '{{> 01-molecules/06-components/03-comment-header.mustache }}'); - test.equals(results[1], '{{> 01-molecules/06-components/02-single-comment(description: \'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.\') }}'); + test.equals(results[1], '{{> 01-molecules/06-components/02-single-comment.mustache(description: \'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.\') }}'); test.done(); }, From 882aee28fb1d8c146f71987a23f3c9b121a714b4 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 1 Dec 2015 17:23:22 -0600 Subject: [PATCH 028/187] streamline, DRY out and update unit tests --- test/lineage_hunter_tests.js | 40 ++-- test/list_item_hunter_tests.js | 334 ++++++++++----------------------- 2 files changed, 115 insertions(+), 259 deletions(-) diff --git a/test/lineage_hunter_tests.js b/test/lineage_hunter_tests.js index 7c00ce415..b500cb265 100644 --- a/test/lineage_hunter_tests.js +++ b/test/lineage_hunter_tests.js @@ -104,30 +104,22 @@ //setup current pattern from what we would have during execution var currentPattern = createFakeEmptyErrorPattern(); extend(currentPattern, { - "template": "{{> atoms-error(message: 'That\'s no moon...') }}", - "patternPartial": "{{> atoms-error(message: 'That\'s no moon...') }}" + "template": "{{> atoms-error(message: 'That\\'s no moon...') }}", + "patternPartial": "{{> atoms-error(message: 'That\\'s no moon...') }}" }); var patternlab = { patterns: [ - { - "name": "01-atoms-05-alerts-00-error", - "subdir": "01-atoms\\05-alerts", - "filename": "00-error.mustache", - "data": null, - "template": "

{{message}}

", - "patternPartial": "

{{message}}

", - "patternName": "error", - "patternLink": "01-atoms-05-alerts-00-error/01-atoms-05-alerts-00-error.html", - "patternGroup": "atoms", - "patternSubGroup": "atoms\\05-alerts", - "flatPatternPath": "01-atoms\\05-alerts", - "patternState": "", - "lineage": [], - "lineageIndex": [], - "lineageR": [], - "lineageRIndex": [] - } + of.oPattern.create( + '/home/fakeuser/pl/source/_patterns/00-atoms/05-alerts/00-error.mustache', + '00-atoms\\05-alerts', + '00-error.mustache', + null, + { + "template": "

{{message}}

", + "patternPartial": "

{{message}}

" + } + ) ] }; @@ -144,8 +136,8 @@ //setup current pattern from what we would have during execution var currentPattern = createFakeEmptyErrorPattern(); extend(currentPattern, { - "template": "{{>atoms-error(message: 'That\'s no moon...')}}", - "patternPartial": "{{>atoms-error(message: 'That\'s no moon...')}}", + "template": "{{>atoms-error(message: 'That\\'s no moon...')}}", + "patternPartial": "{{>atoms-error(message: 'That\\'s no moon...')}}", }); var patternlab = { @@ -186,8 +178,8 @@ //setup current pattern from what we would have during execution var currentPattern = createFakeEmptyErrorPattern(); extend(currentPattern, { - "template": "{{>atoms-error(message: 'That\'s no moon...')}}", - "patternPartial": "{{>atoms-error(message: 'That\'s no moon...')}}" + "template": "{{>atoms-error(message: 'That\\'s no moon...')}}", + "patternPartial": "{{>atoms-error(message: 'That\\'s no moon...')}}" }); var patternlab = { patterns: [ diff --git a/test/list_item_hunter_tests.js b/test/list_item_hunter_tests.js index aa0529b74..055790602 100644 --- a/test/list_item_hunter_tests.js +++ b/test/list_item_hunter_tests.js @@ -18,8 +18,29 @@ return extend(pattern, customProps); } + function createFakePatternLab(customProps) { + var pl = { + "listitems": { + "1": [ + { "title": "Foo" } + ], + "2": [ + { "title": "Foo" }, + { "title": "Bar" } + ] + }, + "data": { + "link": {}, + "partials": [] + }, + "config": {"debug": false} + }; + + return extend(pl, customProps); + } + exports['list_item_hunter'] = { - 'process_list_item_partials finds and outputs basic repeating blocks' : function(test){ + 'process_list_item_partials finds and outputs basic repeating blocks': function(test){ //arrange //setup current pattern from what we would have during execution var currentPattern = createFakeListPattern({ @@ -27,30 +48,7 @@ "extendedTemplate": "{{#listItems.two}}{{ title }}{{/listItems.two}}", "key": "test-patternName" }); - - var patternlab = { - "listitems": { - "1": [ - { - "title": "Foo" - } - ], - "2": [ - { - "title": "Foo" - }, - { - "title": "Bar" - } - ] - }, - "data": { - "link": {}, - "partials": [] - }, - "config": {"debug": false} - }; - + var patternlab = createFakePatternLab(); var list_item_hunter = new lih(); //act @@ -70,30 +68,7 @@ "extendedTemplate" : "{{#listitems.two}}{{ title }}{{/listitems.two}}", "key": "test-patternName" }); - - var patternlab = { - "listitems": { - "1": [ - { - "title": "Foo" - } - ], - "2": [ - { - "title": "Foo" - }, - { - "title": "Bar" - } - ] - }, - "data": { - "link": {}, - "partials": [] - }, - "config": {"debug": false} - }; - + var patternlab = createFakePatternLab(); var list_item_hunter = new lih(); //act @@ -105,45 +80,25 @@ test.done(); }, - 'process_list_item_partials finds partials and outputs repeated renders' : function(test){ + 'process_list_item_partials finds partials and outputs repeated renders': function(test){ //arrange //setup current pattern from what we would have during execution var currentPattern = createFakeListPattern({ "template": "{{#listItems.two}}{{ title }}{{/listItems.two}}", - "extendedTemplate" : "{{#listItems.two}}{{> test-simple }}{{/listItems.two}}", + "extendedTemplate": "{{#listItems.two}}{{> test-simple }}{{/listItems.two}}", "key": "test-patternName" }); - var patternlab = { - "listitems": { - "1": [ - { - "title": "Foo" - } - ], - "2": [ - { - "title": "Foo" - }, - { - "title": "Bar" - } - ] - }, - "data": { - "link": {}, - "partials": [] - }, - "config": {"debug": false}, + var patternlab = createFakePatternLab({ "patterns": [ { - "template": "{{ title }}", - "extendedTemplate" : "{{ title }}", - "key": "test-simple", - "jsonFileData" : {} + "template": "{{ title }}", + "extendedTemplate" : "{{ title }}", + "key": "test-simple", + "jsonFileData" : {} } ] - }; + }); var list_item_hunter = new lih(); @@ -169,43 +124,23 @@ "key": "test-patternName2" }); - var patternlab = { - "listitems": { - "1": [ - { - "title": "Foo" - } - ], - "2": [ - { - "title": "Foo" - }, - { - "title": "Bar" - } - ] - }, - "data": { - "link": {}, - "partials": [] - }, - "config": {"debug": false}, + var patternlab = createFakePatternLab({ "patterns": [ - of.oPattern.create(null, "00-test", "00-foo", null, { + of.oPattern.create('/home/fakeuser/pl/source/_patterns/00-atoms/00-test/00-foo.mustache', "00-atoms/00-test", "00-foo.mustache", null, { "template": "{{ title }}", - "extendedTemplate": "{{ title }}", - "jsonFileData": {} + "extendedTemplate": "{{ title }}" }), - of.oPattern.create(null, "00-test", "00-bar", null, { + of.oPattern.create('/home/fakeuser/pl/source/_patterns/00-atoms/00-test/00-bar.mustache', "00-atoms/00-test", "00-bar.mustache", null, { "template": "{{ title }}", - "extendedTemplate": "{{ title }}", - "jsonFileData": {} + "extendedTemplate": "{{ title }}" }) ] - }; + }); var list_item_hunter = new lih(); + debugger; + //act list_item_hunter.process_list_item_partials(pattern1, patternlab); list_item_hunter.process_list_item_partials(pattern2, patternlab); @@ -217,57 +152,31 @@ test.done(); }, - 'process_list_item_partials overwrites listItem property if that property is in local .listitem.json' : function(test){ + 'process_list_item_partials overwrites listItem property if that property is in local .listitem.json': function(test) { //arrange //setup current pattern from what we would have during execution - var currentPattern = { - "template": "{{#listItems.two}}{{ title }}{{/listItems.two}}", - "extendedTemplate" : "{{#listItems.two}}{{> test-simple }}{{/listItems.two}}", - "key": "test-patternName", - "jsonFileData" : {}, - "listitems" : { - "2": [ - { - "title": "One" - }, - { - "title": "Two" - }, - ] - } - }; - - var patternlab = { + var currentPattern = createFakeListPattern({ + "template": "{{#listItems.two}}{{ title }}{{/listItems.two}}", + "extendedTemplate": "{{#listItems.two}}{{> test-simple }}{{/listItems.two}}", + "key": "test-patternName", + "jsonFileData": {}, "listitems": { - "1": [ - { - "title": "Foo" - } - ], "2": [ - { - "title": "Foo" - }, - { - "title": "Bar" - } + { "title": "One" }, + { "title": "Two" } ] - }, - "data": { - "link": {}, - "partials": [] - }, - "config": {"debug": false}, + } + }); + var patternlab = createFakePatternLab({ "patterns": [ - { - "template": "{{ title }}", - "extendedTemplate" : "{{ title }}", - "key": "test-simple", - "jsonFileData" : {} - } + createFakeListPattern({ + "template": "{{ title }}", + "extendedTemplate": "{{ title }}", + "key": "test-simple", + "jsonFileData": {} + }) ] - }; - + }); var list_item_hunter = new lih(); //act @@ -282,54 +191,28 @@ 'process_list_item_partials keeps listItem property if that property is not in local .listitem.json' : function(test){ //arrange //setup current pattern from what we would have during execution - var currentPattern = { - "template": "{{#listItems.one}}{{ title }}{{/listItems.one}}", - "extendedTemplate" : "{{#listItems.one}}{{> test-simple }}{{/listItems.one}}", - "key": "test-patternName", - "jsonFileData" : {}, - "listitems" : { - "2": [ - { - "title": "One" - }, - { - "title": "Two" - }, - ] - } - }; - - var patternlab = { + var currentPattern = createFakeListPattern({ + "template": "{{#listItems.one}}{{ title }}{{/listItems.one}}", + "extendedTemplate": "{{#listItems.one}}{{> test-simple }}{{/listItems.one}}", + "key": "test-patternName", + "jsonFileData": {}, "listitems": { - "1": [ - { - "title": "Foo" - } - ], "2": [ - { - "title": "Foo" - }, - { - "title": "Bar" - } + { "title": "One" }, + { "title": "Two" } ] - }, - "data": { - "link": {}, - "partials": [] - }, - "config": {"debug": false}, + } + }); + var patternlab = createFakePatternLab({ "patterns": [ - { - "template": "{{ title }}", - "extendedTemplate" : "{{ title }}", - "key": "test-simple", - "jsonFileData" : {} - } + createFakeListPattern({ + "template": "{{ title }}", + "extendedTemplate": "{{ title }}", + "key": "test-simple", + "jsonFileData" : {} + }) ] - }; - + }); var list_item_hunter = new lih(); //act @@ -344,53 +227,33 @@ 'process_list_item_partials uses local listItem property if that property is not set globally' : function(test){ //arrange //setup current pattern from what we would have during execution - var currentPattern = { - "template": "{{#listItems.one}}{{ title }}{{/listItems.one}}", - "extendedTemplate" : "{{#listItems.one}}{{> test-simple }}{{/listItems.one}}", - "key": "test-patternName", - "jsonFileData" : {}, - "listitems" : { - "1": [ - { - "title": "One" - } - ], - "2": [ - { - "title": "One" - }, - { - "title": "Two" - }, - ] - } - }; - - var patternlab = { + var currentPattern = createFakeListPattern({ + "template": "{{#listItems.one}}{{ title }}{{/listItems.one}}", + "extendedTemplate": "{{#listItems.one}}{{> test-simple }}{{/listItems.one}}", + "key": "test-patternName", + "jsonFileData": {}, "listitems": { + "1": [ + { "title": "One" } + ], "2": [ - { - "title": "Foo" - }, - { - "title": "Bar" - } + { "title": "One" }, + { "title": "Two" } ] - }, - "data": { - "link": {}, - "partials": [] - }, - "config": {"debug": false}, + } + }); + + var patternlab = createFakePatternLab({ "patterns": [ - { - "template": "{{ title }}", - "extendedTemplate" : "{{ title }}", - "key": "test-simple", - "jsonFileData" : {} - } + createFakeListPattern({ + "template": "{{ title }}", + "extendedTemplate": "{{ title }}", + "key": "test-simple", + "jsonFileData": {} + }) ] - }; + }); + delete patternlab.listitems["1"]; // remove the "1" list var list_item_hunter = new lih(); @@ -398,6 +261,7 @@ list_item_hunter.process_list_item_partials(currentPattern, patternlab); //assert + test.equals(typeof patternlab.listitems["1"], "undefined"); test.equals(currentPattern.extendedTemplate, "One" ); test.done(); @@ -405,4 +269,4 @@ }; -}()); +})(); From fd3c4b5bbe45e9a4972d3106a2e027508b398de5 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Wed, 2 Dec 2015 10:23:53 -0600 Subject: [PATCH 029/187] unit test fixups, plus a tweak to the Mustache partial finder to permit the verbose partial syntax without the .mustache file extension, as per http://patternlab.io/docs/pattern-including.html --- builder/pattern_engines/engine_mustache.js | 2 +- test/lineage_hunter_tests.js | 4 ++-- test/pattern_assembler_tests.js | 15 ++++++++++++--- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/builder/pattern_engines/engine_mustache.js b/builder/pattern_engines/engine_mustache.js index 87be322f2..2ae1970c2 100644 --- a/builder/pattern_engines/engine_mustache.js +++ b/builder/pattern_engines/engine_mustache.js @@ -19,7 +19,7 @@ engineFileExtension: '.mustache', // regexes, stored here so they're only compiled once - findPartialsRE: /{{>\s*((?:\d+-[\w-]+\/)+(\d+-[\w-]+\.\w+)|[A-Za-z0-9-]+)(\:[A-Za-z0-9-]+)?(\(\s*\w+\s*:\s*(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*")\))?\s*}}/g, + findPartialsRE: /{{>\s*((?:\d+-[\w-]+\/)+(\d+-[\w-]+(\.\w+)?)|[A-Za-z0-9-]+)(\:[A-Za-z0-9-]+)?(\(\s*\w+\s*:\s*(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*")\))?\s*}}/g, findPartialsWithStyleModifiersRE: /{{>([ ])?([\w\-\.\/~]+)(?!\()(\:[A-Za-z0-9-_]+)+(?:(| )\(.*)?([ ])?}}/g, findPartialsWithPatternParametersRE: /{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-_]+)?(?:(| )\(.*)+([ ])?}}/g, findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, diff --git a/test/lineage_hunter_tests.js b/test/lineage_hunter_tests.js index b500cb265..f95e92de8 100644 --- a/test/lineage_hunter_tests.js +++ b/test/lineage_hunter_tests.js @@ -137,7 +137,7 @@ var currentPattern = createFakeEmptyErrorPattern(); extend(currentPattern, { "template": "{{>atoms-error(message: 'That\\'s no moon...')}}", - "patternPartial": "{{>atoms-error(message: 'That\\'s no moon...')}}", + "patternPartial": "{{>atoms-error(message: 'That\\'s no moon...')}}" }); var patternlab = { @@ -219,4 +219,4 @@ }; -}()); +})(); diff --git a/test/pattern_assembler_tests.js b/test/pattern_assembler_tests.js index a3701dff9..314530d88 100644 --- a/test/pattern_assembler_tests.js +++ b/test/pattern_assembler_tests.js @@ -7,7 +7,13 @@ exports['pattern_assembler'] = { 'find_pattern_partials finds partials' : function(test){ - test.expect(13); + // NOTES from GTP: + // it's nice to have so much test coverage, but it retrospect, I'm not + // happy with the structure I wound up with in this test; it's too + // difficult to add test cases and test failure reporting is not very + // granular. + + test.expect(14); //setup current pattern from what we would have during execution var currentPattern = of.oPattern.create( @@ -29,13 +35,15 @@ "{{> 01-molecules/06-components/02-single-comment.mustache(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}" + "{{> molecules-single-comment:foo }}" + "{{>atoms-error(message: 'That\\'s no moon...')}}" + - '{{>atoms-error(message: \'That\\\'s no moon...\')}}' + '{{>atoms-error(message: \'That\\\'s no moon...\')}}' + + "{{> 00-atoms/00-global/ }}" + + "{{> 00-atoms/00-global/06-test }}" } ); var results = currentPattern.findPartials(); console.log(results); - test.equals(results.length, 12); + test.equals(results.length, 13); test.equals(results[0], "{{> molecules-comment-header}}"); test.equals(results[1], "{{> molecules-comment-header}}"); test.equals(results[2], "{{> \n molecules-comment-header\n}}"); @@ -48,6 +56,7 @@ test.equals(results[9], "{{> molecules-single-comment:foo }}"); test.equals(results[10], "{{>atoms-error(message: 'That\\'s no moon...')}}"); test.equals(results[11], "{{>atoms-error(message: 'That\\'s no moon...')}}"); + test.equals(results[12], "{{> 00-atoms/00-global/06-test }}"); test.done(); }, From ee6fcfc6500fea4be9a07cd005e7c26d95ca1858 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Thu, 3 Dec 2015 10:18:22 -0600 Subject: [PATCH 030/187] fix for out-of-order pseudopattern bug -- isPatternFile() should return true for a pseudopattern JSON file and it wasn't. In fact, its unit test was lying to us. Lies! Also: implement a proper isPseudoPatternJSON() function in pattern_engines to centralize that logic and write a unit test for it; move isPatternFile unit test to the right file --- builder/pattern_assembler.js | 2 +- builder/pattern_engines/pattern_engines.js | 12 ++++- test/pattern_assembler_tests.js | 34 ++------------ test/pattern_engines_tests.js | 52 +++++++++++++++++++++- 4 files changed, 66 insertions(+), 34 deletions(-) diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index f96fd56b5..f75c70dda 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -89,7 +89,7 @@ var currentPattern = new of.oPattern(file, subdir, filename); //if file is named in the syntax for variants - if(ext === '.json' && filename.indexOf('~') > -1){ + if(patternEngines.isPseudoPatternJSON(filename)){ //add current pattern to patternlab object with minimal data //processPatternRecursive() will run find_pseudopatterns() to fill out //the object in the next diveSync diff --git a/builder/pattern_engines/pattern_engines.js b/builder/pattern_engines/pattern_engines.js index 32370f154..13ef654f0 100644 --- a/builder/pattern_engines/pattern_engines.js +++ b/builder/pattern_engines/pattern_engines.js @@ -66,6 +66,13 @@ return (supportedExtensions.lastIndexOf(fileExtension) !== -1); }, + // given a filename, return a boolean: whether or not the filename indicates + // that the file is pseudopattern JSON + isPseudoPatternJSON: function (filename) { + var extension = path.extname(filename); + return (extension === '.json' && filename.indexOf('~') > -1); + }, + // takes a filename string, not a full path; a basename (plus extension) // ignore _underscored patterns, dotfiles, and anything not recognized by a // loaded pattern engine. Pseudo-pattern .json files ARE considered to be @@ -75,13 +82,14 @@ var extension = path.extname(filename); if(filename.charAt(0) === '.' || filename.charAt(0) === '_' || - (extension === '.json' && filename.indexOf('~') === -1)) { + (extension === '.json' && !PatternEngines.isPseudoPatternJSON(filename))) { return false; } // not a hidden pattern, let's dig deeper var supportedPatternFileExtensions = PatternEngines.getSupportedFileExtensions(); - return (supportedPatternFileExtensions.lastIndexOf(extension) !== -1); + return (supportedPatternFileExtensions.lastIndexOf(extension) !== -1 || + PatternEngines.isPseudoPatternJSON(filename)); } }); diff --git a/test/pattern_assembler_tests.js b/test/pattern_assembler_tests.js index 314530d88..f13545777 100644 --- a/test/pattern_assembler_tests.js +++ b/test/pattern_assembler_tests.js @@ -3,7 +3,6 @@ var pa = require('../builder/pattern_assembler'); var of = require('../builder/object_factory'); - var patternEngines = require('../builder/pattern_engines/pattern_engines'); exports['pattern_assembler'] = { 'find_pattern_partials finds partials' : function(test){ @@ -31,6 +30,9 @@ "{{> molecules-single-comment(description: 'A life isn\\'t like a garden. Perfect moments can be had, but not preserved, except in memory.') }}" + '{{> molecules-single-comment(description: "A life is like a \\"garden\\". Perfect moments can be had, but not preserved, except in memory.") }}' + "{{> molecules-single-comment:foo }}" + + // questionable: is a partial call with a file extension really + // permitted? seems like no, based on + // http://patternlab.io/docs/pattern-including.html "{{> 01-molecules/06-components/03-comment-header.mustache }}" + "{{> 01-molecules/06-components/02-single-comment.mustache(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}" + "{{> molecules-single-comment:foo }}" + @@ -354,35 +356,7 @@ //test that 00-foo.mustache included partial 01-bar.mustache test.equals(fooExtended, 'bar'); - test.done(); - }, - - 'isPatternFile correctly identifies pattern files and rejects non-pattern files': function(test){ - var pattern_assembler = new pa(); - - // each test case - var filenames = { - '00-comment-thread.mustache': true, - '00-comment-thread.fakeextthatdoesntexist': false, - '00-comment-thread': false, - '_00-comment-thread.mustache': false, - '.00-comment-thread.mustache': false, - '00-comment-thread.json': false, - '00-homepage~emergency.json': false - }; - // expect one test per test case - test.expect(Object.keys(filenames).length); - - // loop over each test case and test it - Object.keys(filenames).forEach(function (filename) { - var expectedResult = filenames[filename], - actualResult = patternEngines.isPatternFile(filename), - testMessage = 'isPatternFile should return ' + expectedResult + ' for ' + filename; - test.strictEqual(actualResult, expectedResult, testMessage); - }); - - // done test.done(); } }; -}()); +})(); diff --git a/test/pattern_engines_tests.js b/test/pattern_engines_tests.js index 21db4b796..87810ecf7 100644 --- a/test/pattern_engines_tests.js +++ b/test/pattern_engines_tests.js @@ -39,7 +39,57 @@ var engine = patternEngines.getEngineForPattern(mustacheTestPseudoPattern); test.equals(engine, patternEngines.mustache); test.done(); - } + }, + 'isPseudoPatternJSON correctly identifies pseudo-pattern JSON filenames': function(test) { + // each test case + var filenames = { + '00-homepage~emergency.json': true, + '~emergency.json': true, + '00-homepage~emergency.js': false, + '00-homepage-emergency.js': false, + '00-homepage.hbs': false, + '00-homepage.json': false, + 'greatpic.jpg': false + }; + // expect one test per test case + test.expect(Object.keys(filenames).length); + + // loop over each test case and test it + Object.keys(filenames).forEach(function (filename) { + var expectedResult = filenames[filename], + actualResult = patternEngines.isPseudoPatternJSON(filename), + testMessage = 'isPseudoPatternJSON should return ' + expectedResult + ' for ' + filename; + test.strictEqual(actualResult, expectedResult, testMessage); + }); + + // done + test.done(); + }, + 'isPatternFile correctly identifies pattern files and rejects non-pattern files': function(test){ + // each test case + var filenames = { + '00-comment-thread.mustache': true, + '00-comment-thread.fakeextthatdoesntexist': false, + '00-comment-thread': false, + '_00-comment-thread.mustache': false, + '.00-comment-thread.mustache': false, + '00-comment-thread.json': false, + '00-homepage~emergency.json': true + }; + // expect one test per test case + test.expect(Object.keys(filenames).length); + + // loop over each test case and test it + Object.keys(filenames).forEach(function (filename) { + var expectedResult = filenames[filename], + actualResult = patternEngines.isPatternFile(filename), + testMessage = 'isPatternFile should return ' + expectedResult + ' for ' + filename; + test.strictEqual(actualResult, expectedResult, testMessage); + }); + + // done + test.done(); + } }; // testProps() utility function: given an object, and a hash of expected From 75d90a2b5895f3ba895f916edd04842eeba60d27 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Thu, 3 Dec 2015 11:16:58 -0600 Subject: [PATCH 031/187] Note verbose syntax in unit test --- test/pattern_assembler_tests.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/pattern_assembler_tests.js b/test/pattern_assembler_tests.js index f13545777..86a6072cc 100644 --- a/test/pattern_assembler_tests.js +++ b/test/pattern_assembler_tests.js @@ -14,8 +14,10 @@ test.expect(14); - //setup current pattern from what we would have during execution - var currentPattern = of.oPattern.create( + // setup current pattern from what we would have during execution + // docs on partial syntax are here: + // http://patternlab.io/docs/pattern-including.html + var currentPattern = of.oPattern.create( '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath '01-molecules\\00-testing', // subdir '00-test-mol.mustache', // filename, @@ -30,15 +32,14 @@ "{{> molecules-single-comment(description: 'A life isn\\'t like a garden. Perfect moments can be had, but not preserved, except in memory.') }}" + '{{> molecules-single-comment(description: "A life is like a \\"garden\\". Perfect moments can be had, but not preserved, except in memory.") }}' + "{{> molecules-single-comment:foo }}" + - // questionable: is a partial call with a file extension really - // permitted? seems like no, based on - // http://patternlab.io/docs/pattern-including.html + // verbose partial syntax, introduced in v0.12.0, with file extension "{{> 01-molecules/06-components/03-comment-header.mustache }}" + "{{> 01-molecules/06-components/02-single-comment.mustache(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}" + "{{> molecules-single-comment:foo }}" + "{{>atoms-error(message: 'That\\'s no moon...')}}" + '{{>atoms-error(message: \'That\\\'s no moon...\')}}' + "{{> 00-atoms/00-global/ }}" + + // verbose partial syntax, introduced in v0.12.0, no file extension "{{> 00-atoms/00-global/06-test }}" } ); From ded322443de00925bdd77786af08579bdacbbee6 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Thu, 3 Dec 2015 11:21:03 -0600 Subject: [PATCH 032/187] Fix (?) partial name; unit test now passes --- test/list_item_hunter_tests.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/test/list_item_hunter_tests.js b/test/list_item_hunter_tests.js index 055790602..1f6430d2c 100644 --- a/test/list_item_hunter_tests.js +++ b/test/list_item_hunter_tests.js @@ -113,14 +113,14 @@ 'process_list_item_partials finds verbose partials and outputs repeated renders' : function(test){ var pattern1 = createFakeListPattern({ - "template": "{{#listItems.one}}{{> 00-test/00-foo }}{{/listItems.one}}", - "extendedTemplate" : "{{#listItems.one}}{{> 00-test/00-foo }}{{/listItems.one}}", + "template": "{{#listItems.one}}{{> atoms-foo }}{{/listItems.one}}", + "extendedTemplate" : "{{#listItems.one}}{{> atoms-foo }}{{/listItems.one}}", "key": "test-patternName1" }); var pattern2 = createFakeListPattern({ - "template": "{{#listItems.two}}{{> 00-test/01-bar.mustache }}{{/listItems.two}}", - "extendedTemplate" : "{{#listItems.two}}{{> 00-test/01-bar.mustache }}{{/listItems.two}}", + "template": "{{#listItems.two}}{{> atoms-bar }}{{/listItems.two}}", + "extendedTemplate" : "{{#listItems.two}}{{> atoms-bar }}{{/listItems.two}}", "key": "test-patternName2" }); @@ -139,8 +139,6 @@ var list_item_hunter = new lih(); - debugger; - //act list_item_hunter.process_list_item_partials(pattern1, patternlab); list_item_hunter.process_list_item_partials(pattern2, patternlab); From b2e1a380a3420182f9be683e6460d1dc233dcf5c Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Fri, 4 Dec 2015 11:22:52 -0600 Subject: [PATCH 033/187] Fix the 'process_list_item_partials finds verbose partials and outputs repeated renders' test to actually, you know, test verbose partials --- test/list_item_hunter_tests.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/list_item_hunter_tests.js b/test/list_item_hunter_tests.js index 1f6430d2c..a0e583f36 100644 --- a/test/list_item_hunter_tests.js +++ b/test/list_item_hunter_tests.js @@ -113,14 +113,14 @@ 'process_list_item_partials finds verbose partials and outputs repeated renders' : function(test){ var pattern1 = createFakeListPattern({ - "template": "{{#listItems.one}}{{> atoms-foo }}{{/listItems.one}}", - "extendedTemplate" : "{{#listItems.one}}{{> atoms-foo }}{{/listItems.one}}", + "template": "{{#listItems.one}}{{> 00-atoms/00-test/00-foo.mustache }}{{/listItems.one}}", + "extendedTemplate" : "{{#listItems.one}}{{> 00-atoms/00-test/00-foo.mustache }}{{/listItems.one}}", "key": "test-patternName1" }); var pattern2 = createFakeListPattern({ - "template": "{{#listItems.two}}{{> atoms-bar }}{{/listItems.two}}", - "extendedTemplate" : "{{#listItems.two}}{{> atoms-bar }}{{/listItems.two}}", + "template": "{{#listItems.two}}{{> 00-atoms/00-test/00-bar.mustache }}{{/listItems.two}}", + "extendedTemplate" : "{{#listItems.two}}{{> 00-atoms/00-test/00-bar.mustache }}{{/listItems.two}}", "key": "test-patternName2" }); From bdb0b7bf492e6d9ebd17403f336e7b9f80039533 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Fri, 4 Dec 2015 15:22:10 -0600 Subject: [PATCH 034/187] Factor getPartialKey out of pattern assembler -- it's Mustache-specific --- builder/object_factory.js | 10 +++++++--- builder/pattern_assembler.js | 4 +++- builder/pattern_engines/engine_mustache.js | 16 ++++++++++++---- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/builder/object_factory.js b/builder/object_factory.js index 761cd59f4..6a9f646e4 100644 --- a/builder/object_factory.js +++ b/builder/object_factory.js @@ -1,6 +1,6 @@ -/* - * patternlab-node - v0.15.1 - 2015 - * +/* + * patternlab-node - v0.15.1 - 2015 + * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. * @@ -77,6 +77,10 @@ findListItems: function () { return this.engine.findListItems(this); + }, + + getPartialKey: function (partialString) { + return this.engine.getPartialKey(this, partialString); } }; diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index 66dca48f3..52f975f9b 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -145,6 +145,8 @@ addPattern(currentPattern, patternlab); } + + function processPatternRecursive(file, patternlab, additionalData){ var lh = require('./lineage_hunter'), ph = require('./parameter_hunter'), @@ -192,7 +194,7 @@ //do something with the regular old partials for(i = 0; i < foundPatternPartials.length; i++){ - var partialKey = foundPatternPartials[i].replace(/{{>([ ])?([\w\-\.\/~]+)(:[A-z-_|]+)?(?:\:[A-Za-z0-9-_]+)?(?:(| )\(.*)?([ ])?}}/g, '$2'); + var partialKey = currentPattern.getPartialKey(foundPatternPartials[i]); var partialPath; diff --git a/builder/pattern_engines/engine_mustache.js b/builder/pattern_engines/engine_mustache.js index 3a3a3c9e2..a13043a87 100644 --- a/builder/pattern_engines/engine_mustache.js +++ b/builder/pattern_engines/engine_mustache.js @@ -23,6 +23,7 @@ findPartialsWithStyleModifiersRE: /{{>([ ])?([\w\-\.\/~]+)(?!\()(\:[A-Za-z0-9-_|]+)+(?:(| )\(.*)?([ ])?}}/g, findPartialsWithPatternParametersRE: /{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-_|]+)?(?:(| )\(.*)+([ ])?}}/g, findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, + getPartialKeyRE: /{{>([ ])?([\w\-\.\/~]+)(:[A-z-_|]+)?(?:\:[A-Za-z0-9-_]+)?(?:(| )\(.*)?([ ])?}}/g, // render it renderPattern: function renderPattern(template, data, partials) { @@ -37,18 +38,25 @@ var matches = pattern.template.match(this.findPartialsRE); return matches; }, - findPartialsWithStyleModifiers: function(pattern){ + findPartialsWithStyleModifiers: function(pattern) { var matches = pattern.template.match(this.findPartialsWithStyleModifiersRE); return matches; }, - // returns any patterns that match {{> value(foo:"bar") }} or {{> value:mod(foo:"bar") }} within the pattern - findPartialsWithPatternParameters: function(pattern){ + // returns any patterns that match {{> value(foo:"bar") }} or {{> + // value:mod(foo:"bar") }} within the pattern + findPartialsWithPatternParameters: function(pattern) { var matches = pattern.template.match(this.findPartialsWithPatternParametersRE); return matches; }, - findListItems: function(pattern){ + findListItems: function(pattern) { var matches = pattern.template.match(this.findListItemsRE); return matches; + }, + // given a pattern, and a partial string, tease out the "pattern key" and + // return it. + getPartialKey: function(pattern, partialString) { + var partialKey = partialString.replace(this.getPartialKeyRE, '$2'); + return partialKey; } }; From bb47678cb9a114376fc78afdc47ccedc09ab63fb Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Mon, 7 Dec 2015 15:14:26 -0600 Subject: [PATCH 035/187] Generate the list of supported pattern engines based on the presence to real plugin files rather than a hard-coded list. Also, better organize the PatternEngine setup functions to be cleaner, more functional and more testable --- builder/pattern_engines/pattern_engines.js | 117 ++++++++++++++------- 1 file changed, 81 insertions(+), 36 deletions(-) diff --git a/builder/pattern_engines/pattern_engines.js b/builder/pattern_engines/pattern_engines.js index 13ef654f0..71e68c39b 100644 --- a/builder/pattern_engines/pattern_engines.js +++ b/builder/pattern_engines/pattern_engines.js @@ -13,25 +13,88 @@ 'use strict'; var path = require('path'); + var diveSync = require('diveSync'); + var engineMatcher = /^engine_(.*)\.js/; + var enginesDirectory = __dirname; - // list of supported pattern engines - var supportedPatternEngineNames = [ - 'mustache', - 'handlebars' - ]; + var PatternEngines; // the main export object + var engineNameForExtension; // generated mapping of extension to engine name - // mapping of file extensions to engine names, for lookup use - var engineNameForExtension = {}; - // Object/hash of all loaded pattern engines, empty at first. - // My intention here is to make this return an object that can be used to - // obtain any loaded PatternEngine by addressing them like this: + // free private functions, for internal setup only + + function findSupportedPatternEngineNames() { + var foundPatternEngineNames = []; + + console.log('patternEngines: begin diveSync ===================='); + + // find + diveSync(enginesDirectory, { + recursive: false, + filter: function (filePath, dir) { + var baseName = path.basename(filePath), + engineMatch = baseName.match(engineMatcher); + + if (dir || engineMatch !== null) { return true; } + return false; + } + }, function (err, filePath) { + if (err) { throw err; } + var baseName = path.basename(filePath), + engineMatch = baseName.match(engineMatcher), + foundEngineName = engineMatch[1]; + + console.log('patternEngines: FOUND ENGINE', foundEngineName); + foundPatternEngineNames.push(foundEngineName); + }); + + return foundPatternEngineNames; + } + + // try to load all supported engines + function loadAllEngines(enginesObject) { + enginesObject.supportedPatternEngineNames.forEach(function (engineName) { + try { + enginesObject[engineName] = require('./engine_' + engineName); + } catch (err) { + console.log(err, 'pattern engine "' + engineName + '" not loaded. Did you install its dependency with npm?'); + } + }); + } + + // produce a mapping between file extension and engine name for each of the + // loaded engines + function createFileExtensionToEngineNameMap(enginesObject) { + var mapping = {}; + + Object.keys(enginesObject).forEach(function (engineName) { + var extensionForEngine = enginesObject[engineName].engineFileExtension; + mapping[extensionForEngine] = engineName; + }); + + return mapping; + } + + + // + // PatternEngines: the main export of this module + // + // It's an Object/hash of all loaded pattern engines, empty at first. My + // intention here is to make this return an object that can be used to obtain + // any loaded PatternEngine by addressing them like this: // - // var PatternEngines = require('./pattern_engines/pattern_engines'); - // var Mustache = PatternEngines['mustache']; + // var PatternEngines = require('./pattern_engines/pattern_engines'); + // var Mustache = PatternEngines['mustache']; // - var PatternEngines = Object.create({ - supportedPatternEngineNames: supportedPatternEngineNames, + // Object.create lets us create an object with a specified prototype. We want + // this here because we would like the object's "own properties" to include + // only the engine names so we can easily iterate over them; all the handy + // methods and properites below should therefore be on its prototype. + + PatternEngines = Object.create({ + // build the list of supported pattern engines based on what plugins we have + // in the pattern_engines directory + supportedPatternEngineNames: findSupportedPatternEngineNames(), getEngineNameForPattern: function (pattern) { // avoid circular dependency by putting this in here. TODO: is this slow? @@ -93,30 +156,12 @@ } }); - // try to load all supported engines - (function loadAllEngines() { - supportedPatternEngineNames.forEach(function (engineName) { - try { - PatternEngines[engineName] = require('./engine_' + engineName); - } catch (err) { - console.log(err, 'pattern engine "' + engineName + '" not loaded. Did you install its dependency with npm?'); - } - }); - })(); - - // produce a mapping between file extension and engine name for each of the - // loaded engines - engineNameForExtension = (function () { - var mapping = {}; - Object.keys(PatternEngines).forEach(function (engineName) { - var extensionForEngine = PatternEngines[engineName].engineFileExtension; - mapping[extensionForEngine] = engineName; - }); - - return mapping; - })(); + // load up the engines we found + loadAllEngines(PatternEngines); + // mapping of file extensions to engine names, for lookup use + engineNameForExtension = createFileExtensionToEngineNameMap(PatternEngines); module.exports = PatternEngines; })(); From e4b73e8fcc62dfe9f0505c4553ea017b62756b00 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 8 Dec 2015 09:47:58 -0600 Subject: [PATCH 036/187] further streamline engine loading process and logging --- builder/pattern_engines/pattern_engines.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/builder/pattern_engines/pattern_engines.js b/builder/pattern_engines/pattern_engines.js index 71e68c39b..e00700a56 100644 --- a/builder/pattern_engines/pattern_engines.js +++ b/builder/pattern_engines/pattern_engines.js @@ -21,13 +21,11 @@ var engineNameForExtension; // generated mapping of extension to engine name - // free private functions, for internal setup only + // free "private" functions, for internal setup only function findSupportedPatternEngineNames() { var foundPatternEngineNames = []; - console.log('patternEngines: begin diveSync ===================='); - // find diveSync(enginesDirectory, { recursive: false, @@ -44,7 +42,6 @@ engineMatch = baseName.match(engineMatcher), foundEngineName = engineMatch[1]; - console.log('patternEngines: FOUND ENGINE', foundEngineName); foundPatternEngineNames.push(foundEngineName); }); @@ -53,13 +50,25 @@ // try to load all supported engines function loadAllEngines(enginesObject) { + console.log('\nLoading engines...'); + enginesObject.supportedPatternEngineNames.forEach(function (engineName) { + var notLoaded = false; + try { enginesObject[engineName] = require('./engine_' + engineName); } catch (err) { - console.log(err, 'pattern engine "' + engineName + '" not loaded. Did you install its dependency with npm?'); + // Handle errors loading each pattern engine. This will usually be + // because the engine's renderer hasn't been installed by the end user + // -- we don't include any of them (except mustache) by default as + // depedencies in package.json. + notLoaded = (err.code === 'MODULE_NOT_FOUND'); + } finally { + console.log('-', engineName, 'engine:', + notLoaded ? 'renderer not installed; engine disabled' : 'good to go'); } }); + console.log('Done loading engines.\n'); } // produce a mapping between file extension and engine name for each of the From d80df26d99b3a3cca5fe2d037be81c15b3b78741 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 8 Dec 2015 17:00:03 -0600 Subject: [PATCH 037/187] clean up require()s --- builder/pattern_assembler.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index 52f975f9b..9451b2485 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -12,12 +12,13 @@ "use strict"; var pattern_assembler = function(){ - - var fs = require('fs-extra'), + var path = require('path'), + fs = require('fs-extra'), of = require('./object_factory'), plutils = require('./utilities'), - patternEngines = require('./pattern_engines/pattern_engines'), - config = fs.readJSONSync('./config.json'); + patternEngines = require('./pattern_engines/pattern_engines'); + + var config = fs.readJSONSync('./config.json'); function setState(pattern, patternlab){ if(patternlab.config.patternStates[pattern.patternName]){ @@ -66,10 +67,6 @@ } function processPatternIterative(file, patternlab){ - var fs = require('fs-extra'), - of = require('./object_factory'), - path = require('path'); - //extract some information var subdir = path.dirname(path.relative(patternlab.config.patterns.source, file)).replace('\\', '/'); var filename = path.basename(file); From c7adf8adc3ed915bf2e03e2c464e4a2da6814f1b Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 8 Dec 2015 17:00:19 -0600 Subject: [PATCH 038/187] slight polish to engine loader console output --- builder/pattern_engines/pattern_engines.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/pattern_engines/pattern_engines.js b/builder/pattern_engines/pattern_engines.js index e00700a56..2968de9a8 100644 --- a/builder/pattern_engines/pattern_engines.js +++ b/builder/pattern_engines/pattern_engines.js @@ -68,7 +68,7 @@ notLoaded ? 'renderer not installed; engine disabled' : 'good to go'); } }); - console.log('Done loading engines.\n'); + console.log('...done loading engines.\n'); } // produce a mapping between file extension and engine name for each of the From 5cab80b0a4d89123ba82dadc11e013e455690997 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 8 Dec 2015 17:00:42 -0600 Subject: [PATCH 039/187] clean up eslintrc a bit --- .eslintrc | 3 --- 1 file changed, 3 deletions(-) diff --git a/.eslintrc b/.eslintrc index 9f090e1e2..eb695c29c 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,9 +1,6 @@ { "env": { - "jasmine": true, "node": true, - "mocha": true, - "browser": true, "builtin": true }, "globals": {}, From fe6206b130ce1fc5aee241c94a1ed2e16da0828d Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 8 Dec 2015 17:01:37 -0600 Subject: [PATCH 040/187] make process_pattern_iterative() return the oPattern to make it a little more functional, which seems nice for unit tests; incorporate @sghoweri's fix to the pattern_assembler --- builder/pattern_assembler.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index 9451b2485..a26715351 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -77,7 +77,7 @@ } // skip non-pattern files - if (!patternEngines.isPatternFile(filename, patternlab)) { return; } + if (!patternEngines.isPatternFile(filename, patternlab)) { return null; } if (config.debug) { console.log('processPatternIterative:', 'found pattern', file); } @@ -92,15 +92,15 @@ //the object in the next diveSync addPattern(currentPattern, patternlab); //no need to process further - return; + return currentPattern; } - //can ignore all non-mustache files at this point - if(ext !== '.mustache'){ + //can ignore all non-supported files at this point + if(patternEngines.isFileExtensionSupported(ext) === false){ if (config.debug) { console.log('==================== FOUND NON-MUSTACHE FILE'); } - return; + return currentPattern; } //see if this file has a state @@ -140,6 +140,8 @@ //add currentPattern to patternlab.patterns array addPattern(currentPattern, patternlab); + + return currentPattern; } @@ -297,7 +299,7 @@ return renderPattern(template, data, partials); }, process_pattern_iterative: function(file, patternlab){ - processPatternIterative(file, patternlab); + return processPatternIterative(file, patternlab); }, process_pattern_recursive: function(file, patternlab, additionalData){ processPatternRecursive(file, patternlab, additionalData); From 865b38dc38f85f5a4827caf0517bdf4482e2f077 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 8 Dec 2015 17:05:23 -0600 Subject: [PATCH 041/187] Handlebars engine, plus unit tests and proposed pattern tree for file-based unit testing --- builder/pattern_engines/engine_handlebars.js | 66 ++++++ test/engine_handlebars_tests.js | 205 ++++++++++++++++++ .../00-atoms/00-global/00-foo.hbs | 0 .../00-atoms/00-global/00-helloworld.hbs | 1 + .../00-atoms/00-global/01-helloworlds.hbs | 1 + 5 files changed, 273 insertions(+) create mode 100644 builder/pattern_engines/engine_handlebars.js create mode 100644 test/engine_handlebars_tests.js create mode 100644 test/files/_handlebars-test-patterns/00-atoms/00-global/00-foo.hbs create mode 100644 test/files/_handlebars-test-patterns/00-atoms/00-global/00-helloworld.hbs create mode 100644 test/files/_handlebars-test-patterns/00-atoms/00-global/01-helloworlds.hbs diff --git a/builder/pattern_engines/engine_handlebars.js b/builder/pattern_engines/engine_handlebars.js new file mode 100644 index 000000000..8fe2ff52e --- /dev/null +++ b/builder/pattern_engines/engine_handlebars.js @@ -0,0 +1,66 @@ +/* + * handlebars pattern engine for patternlab-node - v0.15.1 - 2015 + * + * Geoffrey Pursell, Brian Muenzenmeyer, and the web community. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * + */ + +(function () { + "use strict"; + + var Handlebars = require('handlebars'); + + var engine_handlebars = { + engine: Handlebars, + engineName: 'handlebars', + engineFileExtension: '.hbs', + + // regexes, stored here so they're only compiled once + // GTP warning: unchanged copypasta from mustache engine + findPartialsRE: /{{>\s*((?:\d+-[\w-]+\/)+(\d+-[\w-]+(\.\w+)?)|[A-Za-z0-9-]+)(\:[\w-]+)?(\(\s*\w+\s*:\s*(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*")\))?\s*}}/g, + findPartialsWithStyleModifiersRE: /{{>([ ])?([\w\-\.\/~]+)(?!\()(\:[A-Za-z0-9-_|]+)+(?:(| )\(.*)?([ ])?}}/g, + findPartialsWithPatternParametersRE: /{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-_|]+)?(?:(| )\(.*)+([ ])?}}/g, + findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, + getPartialKeyRE: /{{>([ ])?([\w\-\.\/~]+)(:[A-z-_|]+)?(?:\:[A-Za-z0-9-_]+)?(?:(| )\(.*)?([ ])?}}/g, + + // render it + renderPattern: function renderPattern(template, data, partials) { + if (partials) { + Handlebars.registerPartial(partials); + } + var compiled = Handlebars.compile(template); + return compiled(data); + }, + + // find and return any {{> template-name }} within pattern + findPartials: function findPartials(pattern) { + var matches = pattern.template.match(this.findPartialsRE); + return matches; + }, + findPartialsWithStyleModifiers: function(pattern) { + var matches = pattern.template.match(this.findPartialsWithStyleModifiersRE); + return matches; + }, + // returns any patterns that match {{> value(foo:"bar") }} or {{> + // value:mod(foo:"bar") }} within the pattern + findPartialsWithPatternParameters: function(pattern) { + var matches = pattern.template.match(this.findPartialsWithPatternParametersRE); + return matches; + }, + findListItems: function(pattern) { + var matches = pattern.template.match(this.findListItemsRE); + return matches; + }, + // given a pattern, and a partial string, tease out the "pattern key" and + // return it. + getPartialKey: function(pattern, partialString) { + var partialKey = partialString.replace(this.getPartialKeyRE, '$2'); + return partialKey; + } + }; + + module.exports = engine_handlebars; +})(); diff --git a/test/engine_handlebars_tests.js b/test/engine_handlebars_tests.js new file mode 100644 index 000000000..9f2e851e7 --- /dev/null +++ b/test/engine_handlebars_tests.js @@ -0,0 +1,205 @@ +(function () { + "use strict"; + + var path = require('path'); + var pa = require('../builder/pattern_assembler'); + var object_factory = require('../builder/object_factory'); + var testPatternsPath = path.resolve(__dirname, 'files', '_handlebars-test-patterns'); + + // fake pattern lab constructor: + // sets up a fake patternlab object, which is needed by the pattern processing + // apparatus. + function fakePatternLab() { + var fpl = { + partials: {}, + patterns: [], + footer: '', + header: '', + listitems: {}, + listItemArray: [], + data: { + link: {} + }, + config: require('../config.json'), + package: {} + }; + + // patch the pattern source so the pattern assembler can correctly determine + // the "subdir" + fpl.config.patterns.source = './test/files/_handlebars-test-patterns'; + + return fpl; + } + + + exports['engine_handlebars'] = { + 'hello world handlebars pattern renders': function (test) { + test.expect(1); + + var patternPath = path.resolve( + testPatternsPath, + '00-atoms', + '00-global', + '00-helloworld.hbs' + ); + + // do all the normal processing of the pattern + var patternlab = new fakePatternLab(); + var assembler = new pa(); + var helloWorldPattern = assembler.process_pattern_iterative(patternPath, patternlab); + assembler.process_pattern_recursive(patternPath, patternlab); + + test.equals(helloWorldPattern.render(), 'Hello world!\n'); + test.done(); + }, + 'hello worlds handlebars pattern can see the atoms-helloworld partial and renders it twice': function (test) { + test.expect(1); + + // pattern paths + var pattern1Path = path.resolve( + testPatternsPath, + '00-atoms', + '00-global', + '00-helloworld.hbs' + ); + var pattern2Path = path.resolve( + testPatternsPath, + '00-atoms', + '00-global', + '01-helloworlds.hbs' + ); + + // set up environment + var patternlab = new fakePatternLab(); // environment + var assembler = new pa(); + + // do all the normal processing of the pattern + assembler.process_pattern_iterative(pattern1Path, patternlab); + var helloWorldsPattern = assembler.process_pattern_iterative(pattern2Path, patternlab); + assembler.process_pattern_recursive(pattern1Path, patternlab); + assembler.process_pattern_recursive(pattern2Path, patternlab); + + // test + test.equals(helloWorldsPattern.render(), 'Hello world!\n and Hello world!\n\n'); + test.done(); + }, + // GTP warning: unchanged copypasta from mustache engine + 'find_pattern_partials finds partials': function(test){ + // NOTES from GTP: + // it's nice to have so much test coverage, but it retrospect, I'm not + // happy with the structure I wound up with in this test; it's too + // difficult to add test cases and test failure reporting is not very + // granular. + + test.expect(16); + + // setup current pattern from what we would have during execution + // docs on partial syntax are here: + // http://patternlab.io/docs/pattern-including.html + var currentPattern = object_factory.oPattern.create( + '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.hbs', // abspath + '01-molecules\\00-testing', // subdir + '00-test-mol.hbs', // filename, + null, // data + { + template: "{{> molecules-comment-header}}asdfasdf" + + "{{> molecules-comment-header}}" + + "{{> \n molecules-comment-header\n}}" + + "{{> }}" + + "{{> molecules-weird-spacing }}" + + "{{> molecules-ba_d-cha*rs }}" + + "{{> molecules-single-comment(description: 'A life isn\\'t like a garden. Perfect moments can be had, but not preserved, except in memory.') }}" + + '{{> molecules-single-comment(description: "A life is like a \\"garden\\". Perfect moments can be had, but not preserved, except in memory.") }}' + + "{{> molecules-single-comment:foo }}" + + // verbose partial syntax, introduced in v0.12.0, with file extension + "{{> 01-molecules/06-components/03-comment-header.hbs }}" + + "{{> 01-molecules/06-components/02-single-comment.hbs(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}" + + "{{> molecules-single-comment:foo }}" + + "{{>atoms-error(message: 'That\\'s no moon...')}}" + + '{{>atoms-error(message: \'That\\\'s no moon...\')}}' + + "{{> 00-atoms/00-global/ }}" + + // verbose partial syntax, introduced in v0.12.0, no file extension + "{{> 00-atoms/00-global/06-test }}" + + "{{> molecules-single-comment:foo_1 }}" + + "{{> molecules-single-comment:foo-1 }}" + } + ); + + var results = currentPattern.findPartials(); + console.log(results); + test.equals(results.length, 15); + test.equals(results[0], "{{> molecules-comment-header}}"); + test.equals(results[1], "{{> molecules-comment-header}}"); + test.equals(results[2], "{{> \n molecules-comment-header\n}}"); + test.equals(results[3], "{{> molecules-weird-spacing }}"); + test.equals(results[4], "{{> molecules-single-comment(description: 'A life isn\\'t like a garden. Perfect moments can be had, but not preserved, except in memory.') }}"); + test.equals(results[5], '{{> molecules-single-comment(description: "A life is like a \\"garden\\". Perfect moments can be had, but not preserved, except in memory.") }}'); + test.equals(results[6], "{{> molecules-single-comment:foo }}"); + test.equals(results[7], "{{> 01-molecules/06-components/03-comment-header.hbs }}"); + test.equals(results[8], "{{> 01-molecules/06-components/02-single-comment.hbs(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}"); + test.equals(results[9], "{{> molecules-single-comment:foo }}"); + test.equals(results[10], "{{>atoms-error(message: 'That\\'s no moon...')}}"); + test.equals(results[11], "{{>atoms-error(message: 'That\\'s no moon...')}}"); + test.equals(results[12], "{{> 00-atoms/00-global/06-test }}"); + test.equals(results[13], '{{> molecules-single-comment:foo_1 }}'); + test.equals(results[14], '{{> molecules-single-comment:foo-1 }}'); + test.done(); + }, + // GTP warning: unchanged copypasta from mustache engine + 'find_pattern_partials finds verbose partials': function(test){ + test.expect(3); + + //setup current pattern from what we would have during execution + var currentPattern = new object_factory.oPattern( + '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.hbs', // abspath + '01-molecules\\00-testing', // subdir + '00-test-mol.hbs', // filename, + null // data + ); + currentPattern.template = "

{{> 01-molecules/06-components/03-comment-header.hbs }}

{{> 01-molecules/06-components/02-single-comment.hbs(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}
"; + + var results = currentPattern.findPartials(); + test.equals(results.length, 2); + test.equals(results[0], '{{> 01-molecules/06-components/03-comment-header.hbs }}'); + test.equals(results[1], '{{> 01-molecules/06-components/02-single-comment.hbs(description: \'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.\') }}'); + test.done(); + }, + // GTP warning: unchanged copypasta from mustache engine + 'find_pattern_partials_with_parameters finds parameters with verbose partials': function(test){ + test.expect(2); + + //setup current pattern from what we would have during execution + var currentPattern = new object_factory.oPattern( + '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.hbs', // abspath + '01-molecules\\00-testing', // subdir + '00-test-mol.hbs', // filename, + null // data + ); + currentPattern.template = "

{{> 01-molecules/06-components/molecules-comment-header}}

{{> 01-molecules/06-components/molecules-single-comment(bar:'baz') }}
"; + + var results = currentPattern.findPartialsWithPatternParameters(); + test.equals(results.length, 1); + test.equals(results[0], "{{> 01-molecules/06-components/molecules-single-comment(bar:'baz') }}"); + + test.done(); + }, + // GTP warning: unchanged copypasta from mustache engine + 'find_pattern_partials_with_parameters finds no style modifiers when only partials present': function(test){ + test.expect(1); + + //setup current pattern from what we would have during execution + var currentPattern = new object_factory.oPattern( + '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.hbs', // abspath + '01-molecules\\00-testing', // subdir + '00-test-mol.hbs', // filename, + null // data + ); + currentPattern.template = "

{{> molecules-comment-header}}

{{> molecules-single-comment }}
"; + + var results = currentPattern.findPartialsWithPatternParameters(); + test.equals(results, null); + + test.done(); + } + }; +})(); diff --git a/test/files/_handlebars-test-patterns/00-atoms/00-global/00-foo.hbs b/test/files/_handlebars-test-patterns/00-atoms/00-global/00-foo.hbs new file mode 100644 index 000000000..e69de29bb diff --git a/test/files/_handlebars-test-patterns/00-atoms/00-global/00-helloworld.hbs b/test/files/_handlebars-test-patterns/00-atoms/00-global/00-helloworld.hbs new file mode 100644 index 000000000..cd0875583 --- /dev/null +++ b/test/files/_handlebars-test-patterns/00-atoms/00-global/00-helloworld.hbs @@ -0,0 +1 @@ +Hello world! diff --git a/test/files/_handlebars-test-patterns/00-atoms/00-global/01-helloworlds.hbs b/test/files/_handlebars-test-patterns/00-atoms/00-global/01-helloworlds.hbs new file mode 100644 index 000000000..1df8b851d --- /dev/null +++ b/test/files/_handlebars-test-patterns/00-atoms/00-global/01-helloworlds.hbs @@ -0,0 +1 @@ +{{> atoms-helloworld}} and {{> atoms-helloworld}} From c741d185d3ce02956c50897ab7259e1efa8411a4 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 8 Dec 2015 17:11:45 -0600 Subject: [PATCH 042/187] I am now realizing that I called an atom from inside an atom. The SHAME. "hello worlds" promoted to molecule! --- test/engine_handlebars_tests.js | 4 ++-- .../_handlebars-test-patterns/00-atoms/00-global/00-foo.hbs | 0 .../00-atoms/00-global/01-helloworlds.hbs | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) delete mode 100644 test/files/_handlebars-test-patterns/00-atoms/00-global/00-foo.hbs delete mode 100644 test/files/_handlebars-test-patterns/00-atoms/00-global/01-helloworlds.hbs diff --git a/test/engine_handlebars_tests.js b/test/engine_handlebars_tests.js index 9f2e851e7..26ac85576 100644 --- a/test/engine_handlebars_tests.js +++ b/test/engine_handlebars_tests.js @@ -64,9 +64,9 @@ ); var pattern2Path = path.resolve( testPatternsPath, - '00-atoms', + '00-molecules', '00-global', - '01-helloworlds.hbs' + '00-helloworlds.hbs' ); // set up environment diff --git a/test/files/_handlebars-test-patterns/00-atoms/00-global/00-foo.hbs b/test/files/_handlebars-test-patterns/00-atoms/00-global/00-foo.hbs deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/files/_handlebars-test-patterns/00-atoms/00-global/01-helloworlds.hbs b/test/files/_handlebars-test-patterns/00-atoms/00-global/01-helloworlds.hbs deleted file mode 100644 index 1df8b851d..000000000 --- a/test/files/_handlebars-test-patterns/00-atoms/00-global/01-helloworlds.hbs +++ /dev/null @@ -1 +0,0 @@ -{{> atoms-helloworld}} and {{> atoms-helloworld}} From 5302a4da1c88ff386a73203c559d378b3d86635e Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 8 Dec 2015 17:32:02 -0600 Subject: [PATCH 043/187] oops, add molecules directory and pattern --- .../00-molecules/00-global/00-helloworlds.hbs | 1 + 1 file changed, 1 insertion(+) create mode 100644 test/files/_handlebars-test-patterns/00-molecules/00-global/00-helloworlds.hbs diff --git a/test/files/_handlebars-test-patterns/00-molecules/00-global/00-helloworlds.hbs b/test/files/_handlebars-test-patterns/00-molecules/00-global/00-helloworlds.hbs new file mode 100644 index 000000000..1df8b851d --- /dev/null +++ b/test/files/_handlebars-test-patterns/00-molecules/00-global/00-helloworlds.hbs @@ -0,0 +1 @@ +{{> atoms-helloworld}} and {{> atoms-helloworld}} From 5c745c2c04ec4c4115c94538338e3ca27f360979 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 8 Dec 2015 17:32:19 -0600 Subject: [PATCH 044/187] add Handlebars as an npm dependency (for now) --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 8d3953d22..7ba715db5 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "grunt-contrib-copy": "^0.8.2", "grunt-contrib-nodeunit": "^0.4.1", "grunt-contrib-watch": "^0.6.1", + "handlebars": "^4.0.5", "html-entities": "^1.2.0", "matchdep": "^1.0.0", "mustache": "^2.2.0" From 8ac9b6e7d3b76872686198dc2b1f618e838cb719 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Fri, 11 Dec 2015 09:29:57 -0600 Subject: [PATCH 045/187] (mostly?) working handlebars rendering on a real tree -- there's a problem now with patternlab.json having cyclical references that needs to be fixed. --- builder/lineage_hunter.js | 3 - builder/object_factory.js | 9 +- builder/pattern_assembler.js | 14 +- builder/pattern_engines/engine_handlebars.js | 10 +- builder/patternlab.js | 20 +- test/engine_handlebars_tests.js | 183 +++++++------------ 6 files changed, 107 insertions(+), 132 deletions(-) diff --git a/builder/lineage_hunter.js b/builder/lineage_hunter.js index a3f92e8b2..0ee3bda24 100644 --- a/builder/lineage_hunter.js +++ b/builder/lineage_hunter.js @@ -20,9 +20,6 @@ var config = require('../config.json'); //find the {{> template-name }} within patterns - if (config.debug) { - console.log('===\n', pattern, '\n==='); - } var matches = pattern.findPartials(); if(matches !== null){ matches.forEach(function(match, index, matches){ diff --git a/builder/object_factory.js b/builder/object_factory.js index 2c7ef80cf..d929db6e9 100644 --- a/builder/object_factory.js +++ b/builder/object_factory.js @@ -20,9 +20,6 @@ // oPattern properties var oPattern = function(abspath, subdir, filename, data) { - if (config.debug) { - console.log('=== NEW OPATTERN.', '\nabsPath:', abspath, '\nsubdir:', subdir, '\nfilename:', filename, '\ndata:\n', data); - } this.fileName = filename.substring(0, filename.indexOf('.')); this.fileExtension = path.extname(abspath); this.abspath = abspath; @@ -61,6 +58,12 @@ return this.engine.renderPattern(this.extendedTemplate, data, partials); }, + registerPartial: function () { + if (typeof this.engine.registerPartial === 'function') { + this.engine.registerPartial(this); + } + }, + // the finders all delegate to the PatternEngine, which also encapsulates all // appropriate regexes findPartials: function () { diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index 14c00347e..d09b5edae 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -31,6 +31,8 @@ function addPattern(pattern, patternlab){ //add the link to the global object patternlab.data.link[pattern.patternGroup + '-' + pattern.patternName] = '/patterns/' + pattern.patternLink; + if (!patternlab.patternsByKey) { patternlab.patternsByKey = {}; } + if (!patternlab.patternsByAbsPath) { patternlab.patternsByAbsPath = {}; } //only push to array if the array doesn't contain this pattern var isNew = true; @@ -45,7 +47,12 @@ } //if the pattern is new, just push to the array if(isNew){ + // do global registration patternlab.patterns.push(pattern); + patternlab.patternsByKey[pattern.key] = pattern; + patternlab.patternsByAbsPath[pattern.asbpath] = pattern; + // do plugin-specific registration + pattern.registerPartial(); } } @@ -74,14 +81,11 @@ var ext = path.extname(filename); if (config.debug) { - console.log('processPatternIterative:', 'filename:', filename); + console.log('processPatternIterative:', filename); } // skip non-pattern files if (!patternEngines.isPatternFile(filename, patternlab)) { return null; } - if (config.debug) { - console.log('processPatternIterative:', 'found pattern', file); - } //make a new Pattern Object var currentPattern = new of.oPattern(file, subdir, filename); @@ -104,7 +108,7 @@ var jsonFilename = patternlab.config.patterns.source + currentPattern.subdir + '/' + currentPattern.fileName + ".json"; currentPattern.jsonFileData = fs.readJSONSync(jsonFilename.substring(2)); if(patternlab.config.debug){ - console.log('found pattern-specific data.json for ' + currentPattern.key); + console.log('processPatternIterative: found pattern-specific data.json for ' + currentPattern.key); } } catch(e) { diff --git a/builder/pattern_engines/engine_handlebars.js b/builder/pattern_engines/engine_handlebars.js index 8fe2ff52e..9cdd83b13 100644 --- a/builder/pattern_engines/engine_handlebars.js +++ b/builder/pattern_engines/engine_handlebars.js @@ -20,11 +20,11 @@ // regexes, stored here so they're only compiled once // GTP warning: unchanged copypasta from mustache engine - findPartialsRE: /{{>\s*((?:\d+-[\w-]+\/)+(\d+-[\w-]+(\.\w+)?)|[A-Za-z0-9-]+)(\:[\w-]+)?(\(\s*\w+\s*:\s*(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*")\))?\s*}}/g, + // findPartialsRE: /{{>\s*((?:\d+-[\w-]+\/)+(\d+-[\w-]+(\.\w+)?)|[A-Za-z0-9-]+)(\:[\w-]+)?(\(\s*\w+\s*:\s*(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*")\))?\s*}}/g, + findPartialsRE: /{{#?>\s*([\w-\/.]+)(?:.|\s+)*?}}/g, findPartialsWithStyleModifiersRE: /{{>([ ])?([\w\-\.\/~]+)(?!\()(\:[A-Za-z0-9-_|]+)+(?:(| )\(.*)?([ ])?}}/g, findPartialsWithPatternParametersRE: /{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-_|]+)?(?:(| )\(.*)+([ ])?}}/g, findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, - getPartialKeyRE: /{{>([ ])?([\w\-\.\/~]+)(:[A-z-_|]+)?(?:\:[A-Za-z0-9-_]+)?(?:(| )\(.*)?([ ])?}}/g, // render it renderPattern: function renderPattern(template, data, partials) { @@ -35,6 +35,10 @@ return compiled(data); }, + registerPartial: function (oPattern) { + Handlebars.registerPartial(oPattern.key, oPattern.template); + }, + // find and return any {{> template-name }} within pattern findPartials: function findPartials(pattern) { var matches = pattern.template.match(this.findPartialsRE); @@ -57,7 +61,7 @@ // given a pattern, and a partial string, tease out the "pattern key" and // return it. getPartialKey: function(pattern, partialString) { - var partialKey = partialString.replace(this.getPartialKeyRE, '$2'); + var partialKey = partialString.replace(this.findPartialsRE, '$1'); return partialKey; } }; diff --git a/builder/patternlab.js b/builder/patternlab.js index 9185a6516..1d99f09d4 100644 --- a/builder/patternlab.js +++ b/builder/patternlab.js @@ -1,6 +1,6 @@ -/* - * patternlab-node - v1.0.0 - 2015 - * +/* + * patternlab-node - v1.0.0 - 2015 + * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. * @@ -19,6 +19,7 @@ var patternlab_engine = function () { mh = require('./media_hunter'), pe = require('./pattern_exporter'), he = require('html-entities').AllHtmlEntities, + util = require('util'), plutils = require('./utilities'), patternlab = {}; @@ -49,7 +50,10 @@ var patternlab_engine = function () { //debug file can be written by setting flag on config.json if(patternlab.config.debug){ console.log('writing patternlab debug file to ./patternlab.json'); - fs.outputFileSync('./patternlab.json', JSON.stringify(patternlab, null, 3)); + // fs.outputFileSync('./patternlab.json', JSON.stringify(patternlab, null, 3)); + fs.outputFileSync('./patternlab.json', util.inspect(patternlab, { + depth: null + })); } } @@ -114,7 +118,12 @@ var patternlab_engine = function () { } pattern_assembler.process_pattern_recursive(file.substring(2), patternlab); - }); + }); + + if (patternlab.config.debug) { + console.log('pattern keys:', Object.keys(patternlab.patternsByKey)); + console.log('by keys length:', Object.keys(patternlab.patternsByKey).length, 'array length:', patternlab.patterns.length); + } //delete the contents of config.patterns.public before writing if(deletePatternDir){ @@ -145,7 +154,6 @@ var patternlab_engine = function () { //export patterns if necessary pattern_exporter.export_patterns(patternlab); - } function buildFrontEnd(){ diff --git a/test/engine_handlebars_tests.js b/test/engine_handlebars_tests.js index 26ac85576..7a50c1460 100644 --- a/test/engine_handlebars_tests.js +++ b/test/engine_handlebars_tests.js @@ -32,6 +32,35 @@ } + // function for testing sets of partials + function testFindPartials(test, partialTests) { + test.expect(partialTests.length + 1); + + // setup current pattern from what we would have during execution + // docs on partial syntax are here: + // http://patternlab.io/docs/pattern-including.html + var currentPattern = object_factory.oPattern.create( + '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.hbs', // abspath + '01-molecules\\00-testing', // subdir + '00-test-mol.hbs', // filename, + null, // data + { + template: partialTests.join() + } + ); + + // act + var results = currentPattern.findPartials(); + + // assert + test.equals(results.length, partialTests.length); + partialTests.forEach(function(testString, index) { + test.equals(results[index], testString); + }); + + test.done(); + } + exports['engine_handlebars'] = { 'hello world handlebars pattern renders': function (test) { test.expect(1); @@ -83,123 +112,53 @@ test.equals(helloWorldsPattern.render(), 'Hello world!\n and Hello world!\n\n'); test.done(); }, - // GTP warning: unchanged copypasta from mustache engine 'find_pattern_partials finds partials': function(test){ - // NOTES from GTP: - // it's nice to have so much test coverage, but it retrospect, I'm not - // happy with the structure I wound up with in this test; it's too - // difficult to add test cases and test failure reporting is not very - // granular. - - test.expect(16); - - // setup current pattern from what we would have during execution - // docs on partial syntax are here: - // http://patternlab.io/docs/pattern-including.html - var currentPattern = object_factory.oPattern.create( - '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.hbs', // abspath - '01-molecules\\00-testing', // subdir - '00-test-mol.hbs', // filename, - null, // data - { - template: "{{> molecules-comment-header}}asdfasdf" + - "{{> molecules-comment-header}}" + - "{{> \n molecules-comment-header\n}}" + - "{{> }}" + - "{{> molecules-weird-spacing }}" + - "{{> molecules-ba_d-cha*rs }}" + - "{{> molecules-single-comment(description: 'A life isn\\'t like a garden. Perfect moments can be had, but not preserved, except in memory.') }}" + - '{{> molecules-single-comment(description: "A life is like a \\"garden\\". Perfect moments can be had, but not preserved, except in memory.") }}' + - "{{> molecules-single-comment:foo }}" + - // verbose partial syntax, introduced in v0.12.0, with file extension - "{{> 01-molecules/06-components/03-comment-header.hbs }}" + - "{{> 01-molecules/06-components/02-single-comment.hbs(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}" + - "{{> molecules-single-comment:foo }}" + - "{{>atoms-error(message: 'That\\'s no moon...')}}" + - '{{>atoms-error(message: \'That\\\'s no moon...\')}}' + - "{{> 00-atoms/00-global/ }}" + - // verbose partial syntax, introduced in v0.12.0, no file extension - "{{> 00-atoms/00-global/06-test }}" + - "{{> molecules-single-comment:foo_1 }}" + - "{{> molecules-single-comment:foo-1 }}" - } - ); - - var results = currentPattern.findPartials(); - console.log(results); - test.equals(results.length, 15); - test.equals(results[0], "{{> molecules-comment-header}}"); - test.equals(results[1], "{{> molecules-comment-header}}"); - test.equals(results[2], "{{> \n molecules-comment-header\n}}"); - test.equals(results[3], "{{> molecules-weird-spacing }}"); - test.equals(results[4], "{{> molecules-single-comment(description: 'A life isn\\'t like a garden. Perfect moments can be had, but not preserved, except in memory.') }}"); - test.equals(results[5], '{{> molecules-single-comment(description: "A life is like a \\"garden\\". Perfect moments can be had, but not preserved, except in memory.") }}'); - test.equals(results[6], "{{> molecules-single-comment:foo }}"); - test.equals(results[7], "{{> 01-molecules/06-components/03-comment-header.hbs }}"); - test.equals(results[8], "{{> 01-molecules/06-components/02-single-comment.hbs(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}"); - test.equals(results[9], "{{> molecules-single-comment:foo }}"); - test.equals(results[10], "{{>atoms-error(message: 'That\\'s no moon...')}}"); - test.equals(results[11], "{{>atoms-error(message: 'That\\'s no moon...')}}"); - test.equals(results[12], "{{> 00-atoms/00-global/06-test }}"); - test.equals(results[13], '{{> molecules-single-comment:foo_1 }}'); - test.equals(results[14], '{{> molecules-single-comment:foo-1 }}'); - test.done(); + testFindPartials(test, [ + "{{> molecules-comment-header}}", + "{{> molecules-comment-header}}", + "{{> \n molecules-comment-header\n}}", + "{{> molecules-weird-spacing }}", + "{{> molecules-ba_d-cha*rs }}" + ]); }, - // GTP warning: unchanged copypasta from mustache engine 'find_pattern_partials finds verbose partials': function(test){ - test.expect(3); - - //setup current pattern from what we would have during execution - var currentPattern = new object_factory.oPattern( - '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.hbs', // abspath - '01-molecules\\00-testing', // subdir - '00-test-mol.hbs', // filename, - null // data - ); - currentPattern.template = "

{{> 01-molecules/06-components/03-comment-header.hbs }}

{{> 01-molecules/06-components/02-single-comment.hbs(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}
"; - - var results = currentPattern.findPartials(); - test.equals(results.length, 2); - test.equals(results[0], '{{> 01-molecules/06-components/03-comment-header.hbs }}'); - test.equals(results[1], '{{> 01-molecules/06-components/02-single-comment.hbs(description: \'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.\') }}'); - test.done(); + testFindPartials(test, [ + '{{> 01-molecules/06-components/03-comment-header.hbs }}', + "{{> 01-molecules/06-components/02-single-comment.hbs(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}", + '{{> molecules-single-comment:foo }}', + "{{>atoms-error(message: 'That\'s no moon...')}}", + "{{> atoms-error(message: 'That\'s no moon...') }}", + '{{> 00-atoms/00-global/06-test }}' + ]); }, - // GTP warning: unchanged copypasta from mustache engine - 'find_pattern_partials_with_parameters finds parameters with verbose partials': function(test){ - test.expect(2); - - //setup current pattern from what we would have during execution - var currentPattern = new object_factory.oPattern( - '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.hbs', // abspath - '01-molecules\\00-testing', // subdir - '00-test-mol.hbs', // filename, - null // data - ); - currentPattern.template = "

{{> 01-molecules/06-components/molecules-comment-header}}

{{> 01-molecules/06-components/molecules-single-comment(bar:'baz') }}
"; - - var results = currentPattern.findPartialsWithPatternParameters(); - test.equals(results.length, 1); - test.equals(results[0], "{{> 01-molecules/06-components/molecules-single-comment(bar:'baz') }}"); - - test.done(); + 'find_pattern_partials finds simple partials with parameters': function(test){ + testFindPartials(test, [ + "{{> molecules-single-comment(description: 'A life isn\'t like a garden. Perfect moments can be had, but not preserved, except in memory.') }}", + '{{> molecules-single-comment(description:"A life is like a \"garden\". Perfect moments can be had, but not preserved, except in memory.") }}' + ]); }, - // GTP warning: unchanged copypasta from mustache engine - 'find_pattern_partials_with_parameters finds no style modifiers when only partials present': function(test){ - test.expect(1); - - //setup current pattern from what we would have during execution - var currentPattern = new object_factory.oPattern( - '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.hbs', // abspath - '01-molecules\\00-testing', // subdir - '00-test-mol.hbs', // filename, - null // data - ); - currentPattern.template = "

{{> molecules-comment-header}}

{{> molecules-single-comment }}
"; - - var results = currentPattern.findPartialsWithPatternParameters(); - test.equals(results, null); - - test.done(); + 'find_pattern_partials finds simple partials with style modifiers': function(test){ + testFindPartials(test, [ + '{{> molecules-single-comment:foo }}' + ]); + }, + 'find_pattern_partials finds partials with handlebars parameters': function(test){ + testFindPartials(test, [ + '{{> atoms-title title="bravo" headingLevel="2" headingSize="bravo" position="left"}}', + '{{> atoms-title title="bravo"\n headingLevel="2"\n headingSize="bravo"\n position="left"}}', + '{{> atoms-title title="color  midnight blue" headingSize="charlie"}}', + '{{> atoms-input label="city" required=true}}', + '{{> organisms-product-filter filterData}}', + '{{> atoms-input email required=true}}', + '{{> molecules-storycard variants.flex }}', + '{{> myPartial name=../name }}' + ]); + }, + + 'find_pattern_partials finds handlebars block partials': function(test){ + testFindPartials(test, [ + '{{#> myPartial }}' + ]); } }; })(); From 82c76edd33fc669b0cc4f5a00131b71a96f9279e Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Mon, 14 Dec 2015 14:53:22 -0600 Subject: [PATCH 046/187] Fix the circular reference problem in the log file, which occurred when the Handlebars engine was in use. --- builder/patternlab.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/builder/patternlab.js b/builder/patternlab.js index 1d99f09d4..d6ae6a51b 100644 --- a/builder/patternlab.js +++ b/builder/patternlab.js @@ -47,13 +47,21 @@ var patternlab_engine = function () { } function printDebug() { + // A replacer function to pass to stringify below; this is here to prevent + // the debug output from blowing up into a massive fireball of circular + // references. This happens specifically with the Handlebars engine. Remove + // if you like 180MB log files. + function propertyStringReplacer(key, value) { + if (key === 'engine' && value.engineName) { + return '{' + value.engineName + ' engine object}'; + } + return value; + } + //debug file can be written by setting flag on config.json if(patternlab.config.debug){ console.log('writing patternlab debug file to ./patternlab.json'); - // fs.outputFileSync('./patternlab.json', JSON.stringify(patternlab, null, 3)); - fs.outputFileSync('./patternlab.json', util.inspect(patternlab, { - depth: null - })); + fs.outputFileSync('./patternlab.json', JSON.stringify(patternlab, propertyStringReplacer, 3)); } } From 6693ee2d91e9ab1cb51492b138a9144fd4239a24 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Mon, 14 Dec 2015 15:18:58 -0600 Subject: [PATCH 047/187] remove speculative alternate pattern data structures --- builder/pattern_assembler.js | 4 ---- builder/patternlab.js | 4 ---- 2 files changed, 8 deletions(-) diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index d09b5edae..9b9074b03 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -31,8 +31,6 @@ function addPattern(pattern, patternlab){ //add the link to the global object patternlab.data.link[pattern.patternGroup + '-' + pattern.patternName] = '/patterns/' + pattern.patternLink; - if (!patternlab.patternsByKey) { patternlab.patternsByKey = {}; } - if (!patternlab.patternsByAbsPath) { patternlab.patternsByAbsPath = {}; } //only push to array if the array doesn't contain this pattern var isNew = true; @@ -49,8 +47,6 @@ if(isNew){ // do global registration patternlab.patterns.push(pattern); - patternlab.patternsByKey[pattern.key] = pattern; - patternlab.patternsByAbsPath[pattern.asbpath] = pattern; // do plugin-specific registration pattern.registerPartial(); } diff --git a/builder/patternlab.js b/builder/patternlab.js index d6ae6a51b..646ed146d 100644 --- a/builder/patternlab.js +++ b/builder/patternlab.js @@ -128,10 +128,6 @@ var patternlab_engine = function () { pattern_assembler.process_pattern_recursive(file.substring(2), patternlab); }); - if (patternlab.config.debug) { - console.log('pattern keys:', Object.keys(patternlab.patternsByKey)); - console.log('by keys length:', Object.keys(patternlab.patternsByKey).length, 'array length:', patternlab.patterns.length); - } //delete the contents of config.patterns.public before writing if(deletePatternDir){ From a2c6c714e0b98a31302a71a3722ea001dd2dad4a Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Mon, 14 Dec 2015 15:55:13 -0600 Subject: [PATCH 048/187] Add pattern-engines branch to .travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 611cfd7d6..1a080079e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,3 +16,4 @@ branches: only: - master - dev + - pattern-engines From 865a6b2cdc5f46867c3b286380e53a3fa5294f93 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 22 Dec 2015 13:42:39 -0600 Subject: [PATCH 049/187] more eslint chilling --- .eslintrc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.eslintrc b/.eslintrc index eb695c29c..4edaeae26 100644 --- a/.eslintrc +++ b/.eslintrc @@ -22,11 +22,13 @@ "allow-null" ], "global-strict": [ - 2, + 0, "never" ], "guard-for-in": 2, - "key-spacing": 1, + "key-spacing": [ + 0 + ], "new-cap": 0, "no-bitwise": 2, "no-caller": 2, @@ -42,6 +44,7 @@ "no-irregular-whitespace": 1, "no-iterator": 2, "no-loop-func": 2, + "no-mixed-requires": 0, "no-multi-str": 2, "no-multi-spaces": 0, "no-new": 2, @@ -61,7 +64,7 @@ 0, "never" ], - "strict": 2, + "strict": 0, "valid-typeof": 2, "wrap-iife": [ 2, From b933916293acb5f682f1e1c4dc335953ebde8344 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Wed, 6 Jan 2016 09:16:37 -0600 Subject: [PATCH 050/187] unit test: handlebars partials can render JSON values --- test/engine_handlebars_tests.js | 27 +++++++++++++++++-- .../00-global/00-helloworld-withdata.hbs | 2 ++ .../00-global/00-helloworld-withdata.json | 3 +++ .../00-call-atom-with-molecule-data.hbs | 5 ++++ .../00-call-atom-with-molecule-data.json | 6 +++++ 5 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 test/files/_handlebars-test-patterns/00-atoms/00-global/00-helloworld-withdata.hbs create mode 100644 test/files/_handlebars-test-patterns/00-atoms/00-global/00-helloworld-withdata.json create mode 100644 test/files/_handlebars-test-patterns/00-molecules/00-global/00-call-atom-with-molecule-data.hbs create mode 100644 test/files/_handlebars-test-patterns/00-molecules/00-global/00-call-atom-with-molecule-data.json diff --git a/test/engine_handlebars_tests.js b/test/engine_handlebars_tests.js index 7a50c1460..7f350a752 100644 --- a/test/engine_handlebars_tests.js +++ b/test/engine_handlebars_tests.js @@ -101,7 +101,7 @@ // set up environment var patternlab = new fakePatternLab(); // environment var assembler = new pa(); - + // do all the normal processing of the pattern assembler.process_pattern_iterative(pattern1Path, patternlab); var helloWorldsPattern = assembler.process_pattern_iterative(pattern2Path, patternlab); @@ -112,6 +112,29 @@ test.equals(helloWorldsPattern.render(), 'Hello world!\n and Hello world!\n\n'); test.done(); }, + 'handlebars partials can render JSON values': function (test) { + test.expect(1); + + // pattern paths + var pattern1Path = path.resolve( + testPatternsPath, + '00-atoms', + '00-global', + '00-helloworld-withdata.hbs' + ); + + // set up environment + var patternlab = new fakePatternLab(); // environment + var assembler = new pa(); + + // do all the normal processing of the pattern + var helloWorldWithData = assembler.process_pattern_iterative(pattern1Path, patternlab); + assembler.process_pattern_recursive(pattern1Path, patternlab); + + // test + test.equals(helloWorldWithData.render(), 'Hello world!\nYeah, we got the subtitle from the JSON.\n'); + test.done(); + }, 'find_pattern_partials finds partials': function(test){ testFindPartials(test, [ "{{> molecules-comment-header}}", @@ -154,7 +177,7 @@ '{{> myPartial name=../name }}' ]); }, - + 'find_pattern_partials finds handlebars block partials': function(test){ testFindPartials(test, [ '{{#> myPartial }}' diff --git a/test/files/_handlebars-test-patterns/00-atoms/00-global/00-helloworld-withdata.hbs b/test/files/_handlebars-test-patterns/00-atoms/00-global/00-helloworld-withdata.hbs new file mode 100644 index 000000000..3cfaf83c0 --- /dev/null +++ b/test/files/_handlebars-test-patterns/00-atoms/00-global/00-helloworld-withdata.hbs @@ -0,0 +1,2 @@ +Hello world! +{{ subtitle }} diff --git a/test/files/_handlebars-test-patterns/00-atoms/00-global/00-helloworld-withdata.json b/test/files/_handlebars-test-patterns/00-atoms/00-global/00-helloworld-withdata.json new file mode 100644 index 000000000..491238b33 --- /dev/null +++ b/test/files/_handlebars-test-patterns/00-atoms/00-global/00-helloworld-withdata.json @@ -0,0 +1,3 @@ +{ + "subtitle": "Yeah, we got the subtitle from the JSON." +} diff --git a/test/files/_handlebars-test-patterns/00-molecules/00-global/00-call-atom-with-molecule-data.hbs b/test/files/_handlebars-test-patterns/00-molecules/00-global/00-call-atom-with-molecule-data.hbs new file mode 100644 index 000000000..a0766acef --- /dev/null +++ b/test/files/_handlebars-test-patterns/00-molecules/00-global/00-call-atom-with-molecule-data.hbs @@ -0,0 +1,5 @@ +

Call with default JSON environment:

+This is {{> atoms-helloworld-withdata }} + +

Call with passed parameter:

+However, this is {{> atoms-helloworld-withdata otherBlob }} diff --git a/test/files/_handlebars-test-patterns/00-molecules/00-global/00-call-atom-with-molecule-data.json b/test/files/_handlebars-test-patterns/00-molecules/00-global/00-call-atom-with-molecule-data.json new file mode 100644 index 000000000..dc49de353 --- /dev/null +++ b/test/files/_handlebars-test-patterns/00-molecules/00-global/00-call-atom-with-molecule-data.json @@ -0,0 +1,6 @@ +{ + "subtitle": "from the default JSON.", + "otherBlob": { + "subtitle": "from a totally different blob." + } +} From 7a6d9c65ce95b6913d43e7e0a05a7b57f7dbb265 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Wed, 6 Jan 2016 09:17:13 -0600 Subject: [PATCH 051/187] pass unit test 'handlebars partials can render JSON values'; a mechanism for passing the oPattern's jsonData by default was needed, apparently. --- builder/object_factory.js | 8 ++++---- builder/pattern_assembler.js | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/builder/object_factory.js b/builder/object_factory.js index d929db6e9..d5c23f49a 100644 --- a/builder/object_factory.js +++ b/builder/object_factory.js @@ -1,6 +1,6 @@ -/* - * patternlab-node - v1.0.0 - 2015 - * +/* + * patternlab-node - v1.0.0 - 2015 + * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. * @@ -55,7 +55,7 @@ if (config.debug && this.isPseudoPattern) { console.log('===', this.name + ' IS A PSEUDO-PATTERN ==='); } - return this.engine.renderPattern(this.extendedTemplate, data, partials); + return this.engine.renderPattern(this.extendedTemplate, data || this.jsonFileData, partials); }, registerPartial: function () { diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index 9b9074b03..a1b79cfd1 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -101,8 +101,8 @@ //look for a json file for this template try { - var jsonFilename = patternlab.config.patterns.source + currentPattern.subdir + '/' + currentPattern.fileName + ".json"; - currentPattern.jsonFileData = fs.readJSONSync(jsonFilename.substring(2)); + var jsonFilename = path.resolve(patternlab.config.patterns.source, currentPattern.subdir, currentPattern.fileName + ".json"); + currentPattern.jsonFileData = fs.readJSONSync(jsonFilename); if(patternlab.config.debug){ console.log('processPatternIterative: found pattern-specific data.json for ' + currentPattern.key); } From 724396735eeb20c21ddc582094cc7d1786959618 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Thu, 7 Jan 2016 14:04:30 -0600 Subject: [PATCH 052/187] Handlebars (and possibly other engines) need to be excluded from "partial expansion", the process of recursively "manually" rendering partials into the extendedTemplate property of the oPattern, in order to have access to the calling pattern's correct JSON environment. Each engine must indicate if it supports partial expansion (probably no by default). Also, factor out the partial expansion process from the main processPatternRecursively function for clarity and easy conditionalizing, and add a unit test to verify that this works okay. --- builder/pattern_assembler.js | 112 +++++++++---------- builder/pattern_engines/engine_handlebars.js | 4 + builder/pattern_engines/engine_mustache.js | 4 + test/engine_handlebars_tests.js | 31 +++++ 4 files changed, 94 insertions(+), 57 deletions(-) diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index a1b79cfd1..566d5619b 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -139,22 +139,61 @@ + function expandPartials(foundPatternPartials, list_item_hunter, patternlab, currentPattern) { + var smh = require('./style_modifier_hunter'), + ph = require('./parameter_hunter'); + + var style_modifier_hunter = new smh(), + parameter_hunter = new ph(); + + if(patternlab.config.debug){ + console.log('found partials for ' + currentPattern.key); + } + + // determine if the template contains any pattern parameters. if so they + // must be immediately consumed + parameter_hunter.find_parameters(currentPattern, patternlab); + + //do something with the regular old partials + for(var i = 0; i < foundPatternPartials.length; i++){ + var partialKey = currentPattern.getPartialKey(foundPatternPartials[i]); + var partialPath; + + //identify which pattern this partial corresponds to + for(var j = 0; j < patternlab.patterns.length; j++){ + if(patternlab.patterns[j].key === partialKey || + patternlab.patterns[j].abspath.indexOf(partialKey) > -1) + { + partialPath = patternlab.patterns[j].abspath; + } + } + + //recurse through nested partials to fill out this extended template. + processPatternRecursive(partialPath, patternlab); + + //complete assembly of extended template + var partialPattern = getpatternbykey(partialKey, patternlab); + + //if partial has style modifier data, replace the styleModifier value + if(currentPattern.stylePartials && currentPattern.stylePartials.length > 0){ + style_modifier_hunter.consume_style_modifier(partialPattern, foundPatternPartials[i], patternlab); + } + + currentPattern.extendedTemplate = currentPattern.extendedTemplate.replace(foundPatternPartials[i], partialPattern.extendedTemplate); + } + } + function processPatternRecursive(file, patternlab, additionalData){ var lh = require('./lineage_hunter'), - ph = require('./parameter_hunter'), pph = require('./pseudopattern_hunter'), - lih = require('./list_item_hunter'), - smh = require('./style_modifier_hunter'); + lih = require('./list_item_hunter'); - var parameter_hunter = new ph(), - lineage_hunter = new lh(), - list_item_hunter = new lih(), - style_modifier_hunter = new smh(), - pseudopattern_hunter = new pph(); + var lineage_hunter = new lh(), + list_item_hunter = new lih(), + pseudopattern_hunter = new pph(); //find current pattern in patternlab object using var file as a key - var currentPattern, - i; + var currentPattern, i; for(i = 0; i < patternlab.patterns.length; i++){ if(patternlab.patterns[i].abspath === file){ @@ -163,60 +202,19 @@ } //return if processing an ignored file - if(typeof currentPattern === 'undefined'){ - return; - } + if (typeof currentPattern === 'undefined') { return; } currentPattern.extendedTemplate = currentPattern.template; //find how many partials there may be for the given pattern var foundPatternPartials = currentPattern.findPartials(currentPattern); - if(foundPatternPartials !== null && foundPatternPartials.length > 0){ - - if(patternlab.config.debug){ - console.log('found partials for ' + currentPattern.key); - } - - //find any listItem blocks - list_item_hunter.process_list_item_partials(currentPattern, patternlab); - - //determine if the template contains any pattern parameters. if so they must be immediately consumed - parameter_hunter.find_parameters(currentPattern, patternlab); - - //do something with the regular old partials - for(i = 0; i < foundPatternPartials.length; i++){ - var partialKey = currentPattern.getPartialKey(foundPatternPartials[i]); - - var partialPath; - - //identify which pattern this partial corresponds to - for(var j = 0; j < patternlab.patterns.length; j++){ - if(patternlab.patterns[j].key === partialKey || - patternlab.patterns[j].abspath.indexOf(partialKey) > -1) - { - partialPath = patternlab.patterns[j].abspath; - } - } + //find any listItem blocks that within the pattern, even if there are no partials + list_item_hunter.process_list_item_partials(currentPattern, patternlab); - //recurse through nested partials to fill out this extended template. - processPatternRecursive(partialPath, patternlab); - - //complete assembly of extended template - var partialPattern = getpatternbykey(partialKey, patternlab); - - //if partial has style modifier data, replace the styleModifier value - if(currentPattern.stylePartials && currentPattern.stylePartials.length > 0){ - style_modifier_hunter.consume_style_modifier(partialPattern, foundPatternPartials[i], patternlab); - } - - currentPattern.extendedTemplate = currentPattern.extendedTemplate.replace(foundPatternPartials[i], partialPattern.extendedTemplate); - - } - - } else{ - //find any listItem blocks that within the pattern, even if there are no partials - list_item_hunter.process_list_item_partials(currentPattern, patternlab); + // expand any partials present in this pattern; that is, drill down into the template and replace their calls in this template with rendered results + if (currentPattern.engine.expandPartials && (foundPatternPartials !== null && foundPatternPartials.length > 0)) { + expandPartials(foundPatternPartials, list_item_hunter, patternlab, currentPattern); } //find pattern lineage diff --git a/builder/pattern_engines/engine_handlebars.js b/builder/pattern_engines/engine_handlebars.js index 9cdd83b13..06b6f8c7c 100644 --- a/builder/pattern_engines/engine_handlebars.js +++ b/builder/pattern_engines/engine_handlebars.js @@ -18,6 +18,10 @@ engineName: 'handlebars', engineFileExtension: '.hbs', + // partial expansion is only necessary for Mustache templates that have + // style modifiers or pattern parameters (I think) + expandPartials: false, + // regexes, stored here so they're only compiled once // GTP warning: unchanged copypasta from mustache engine // findPartialsRE: /{{>\s*((?:\d+-[\w-]+\/)+(\d+-[\w-]+(\.\w+)?)|[A-Za-z0-9-]+)(\:[\w-]+)?(\(\s*\w+\s*:\s*(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*")\))?\s*}}/g, diff --git a/builder/pattern_engines/engine_mustache.js b/builder/pattern_engines/engine_mustache.js index a13043a87..84b9a3554 100644 --- a/builder/pattern_engines/engine_mustache.js +++ b/builder/pattern_engines/engine_mustache.js @@ -18,6 +18,10 @@ engineName: 'mustache', engineFileExtension: '.mustache', + // partial expansion is only necessary for Mustache templates that have + // style modifiers or pattern parameters (I think) + expandPartials: true, + // regexes, stored here so they're only compiled once findPartialsRE: /{{>\s*((?:\d+-[\w-]+\/)+(\d+-[\w-]+(\.\w+)?)|[A-Za-z0-9-]+)(\:[\w-]+)?(\(\s*\w+\s*:\s*(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*")\))?\s*}}/g, findPartialsWithStyleModifiersRE: /{{>([ ])?([\w\-\.\/~]+)(?!\()(\:[A-Za-z0-9-_|]+)+(?:(| )\(.*)?([ ])?}}/g, diff --git a/test/engine_handlebars_tests.js b/test/engine_handlebars_tests.js index 7f350a752..d400468da 100644 --- a/test/engine_handlebars_tests.js +++ b/test/engine_handlebars_tests.js @@ -135,6 +135,37 @@ test.equals(helloWorldWithData.render(), 'Hello world!\nYeah, we got the subtitle from the JSON.\n'); test.done(); }, + 'handlebars partials use the JSON environment from the calling pattern and can accept passed parameters': function (test) { + test.expect(1); + + // pattern paths + var atomPath = path.resolve( + testPatternsPath, + '00-atoms', + '00-global', + '00-helloworld-withdata.hbs' + ); + var molPath = path.resolve( + testPatternsPath, + '00-molecules', + '00-global', + '00-call-atom-with-molecule-data.hbs' + ); + + // set up environment + var patternlab = new fakePatternLab(); // environment + var assembler = new pa(); + + // do all the normal processing of the pattern + var atom = assembler.process_pattern_iterative(atomPath, patternlab); + var mol = assembler.process_pattern_iterative(molPath, patternlab); + assembler.process_pattern_recursive(atomPath, patternlab); + assembler.process_pattern_recursive(molPath, patternlab); + + // test + test.equals(mol.render(), '

Call with default JSON environment:

\nThis is Hello world!\nfrom the default JSON.\n\n\n

Call with passed parameter:

\nHowever, this is Hello world!\nfrom a totally different blob.\n\n'); + test.done(); + }, 'find_pattern_partials finds partials': function(test){ testFindPartials(test, [ "{{> molecules-comment-header}}", From 7b0a44cf958e9b24a74b287f6b75ed23eaabf2fd Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 12 Jan 2016 13:15:48 -0600 Subject: [PATCH 053/187] factor Mustache-specific findPartialKey out of the lineage hunter and put it in the Mustach engine, where it replaces one that didn't work as well; normalize all references to getPartialKey to findPartialKey; fix the Mustache findPartialsRE to pass the 'pattern_assembler - processPatternRecursive - correctly replaces multiple stylemodifier classes on same partial' unit test. --- builder/lineage_hunter.js | 17 +++---------- builder/object_factory.js | 4 ++-- builder/pattern_assembler.js | 2 +- builder/pattern_engines/engine_handlebars.js | 2 +- builder/pattern_engines/engine_mustache.js | 25 ++++++++++++++++---- 5 files changed, 28 insertions(+), 22 deletions(-) diff --git a/builder/lineage_hunter.js b/builder/lineage_hunter.js index a13907b2a..54c083b69 100644 --- a/builder/lineage_hunter.js +++ b/builder/lineage_hunter.js @@ -23,24 +23,13 @@ var matches = pattern.findPartials(); if(matches !== null){ matches.forEach(function(match, index, matches){ - //strip out the template cruft - var foundPatternKey = match.replace("{{> ", "").replace(" }}", "").replace("{{>", "").replace("}}", ""); - - // remove any potential pattern parameters. this and the above are rather brutish but I didn't want to do a regex at the time - if(foundPatternKey.indexOf('(') > 0){ - foundPatternKey = foundPatternKey.substring(0, foundPatternKey.indexOf('(')); - } - - //remove any potential stylemodifiers. - foundPatternKey = foundPatternKey.split(':')[0]; - //get the ancestorPattern - var ancestorPattern = pattern_assembler.get_pattern_by_key(foundPatternKey, patternlab); + var ancestorPattern = pattern_assembler.get_pattern_by_key(pattern.findPartialKey(match), patternlab); if (ancestorPattern && pattern.lineageIndex.indexOf(ancestorPattern.key) === -1){ - //add it since it didnt exist - pattern.lineageIndex.push(ancestorPattern.key); + pattern.lineageIndex.push(ancestorPattern.key); + //create the more complex patternLineage object too var l = { "lineagePattern": ancestorPattern.key, diff --git a/builder/object_factory.js b/builder/object_factory.js index 2d2e29892..359a3bc58 100644 --- a/builder/object_factory.js +++ b/builder/object_factory.js @@ -82,8 +82,8 @@ return this.engine.findListItems(this); }, - getPartialKey: function (partialString) { - return this.engine.getPartialKey(this, partialString); + findPartialKey: function (partialString) { + return this.engine.findPartialKey(partialString); } }; diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index bc4e10f3c..8c4adcdba 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -156,7 +156,7 @@ //do something with the regular old partials for(var i = 0; i < foundPatternPartials.length; i++){ - var partialKey = currentPattern.getPartialKey(foundPatternPartials[i]); + var partialKey = currentPattern.findPartialKey(foundPatternPartials[i]); var partialPath; //identify which pattern this partial corresponds to diff --git a/builder/pattern_engines/engine_handlebars.js b/builder/pattern_engines/engine_handlebars.js index 06b6f8c7c..4137d31bc 100644 --- a/builder/pattern_engines/engine_handlebars.js +++ b/builder/pattern_engines/engine_handlebars.js @@ -64,7 +64,7 @@ }, // given a pattern, and a partial string, tease out the "pattern key" and // return it. - getPartialKey: function(pattern, partialString) { + findPartialKey: function(pattern, partialString) { var partialKey = partialString.replace(this.findPartialsRE, '$1'); return partialKey; } diff --git a/builder/pattern_engines/engine_mustache.js b/builder/pattern_engines/engine_mustache.js index 84b9a3554..0a472a6d3 100644 --- a/builder/pattern_engines/engine_mustache.js +++ b/builder/pattern_engines/engine_mustache.js @@ -23,11 +23,11 @@ expandPartials: true, // regexes, stored here so they're only compiled once - findPartialsRE: /{{>\s*((?:\d+-[\w-]+\/)+(\d+-[\w-]+(\.\w+)?)|[A-Za-z0-9-]+)(\:[\w-]+)?(\(\s*\w+\s*:\s*(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*")\))?\s*}}/g, + findPartialsRE: /{{>\s*((?:\d+-[\w-]+\/)+(\d+-[\w-]+(\.\w+)?)|[A-Za-z0-9-]+)(\:[\w-]+(?:\|[\w-]+)*)?(\(\s*\w+\s*:\s*(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*")\))?\s*}}/g, findPartialsWithStyleModifiersRE: /{{>([ ])?([\w\-\.\/~]+)(?!\()(\:[A-Za-z0-9-_|]+)+(?:(| )\(.*)?([ ])?}}/g, findPartialsWithPatternParametersRE: /{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-_|]+)?(?:(| )\(.*)+([ ])?}}/g, findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, - getPartialKeyRE: /{{>([ ])?([\w\-\.\/~]+)(:[A-z-_|]+)?(?:\:[A-Za-z0-9-_]+)?(?:(| )\(.*)?([ ])?}}/g, + findPartialKeyRE: /{{>([ ])?([\w\-\.\/~]+)(:[A-z-_|]+)?(?:\:[A-Za-z0-9-_]+)?(?:(| )\(.*)?([ ])?}}/g, // render it renderPattern: function renderPattern(template, data, partials) { @@ -58,9 +58,26 @@ }, // given a pattern, and a partial string, tease out the "pattern key" and // return it. - getPartialKey: function(pattern, partialString) { - var partialKey = partialString.replace(this.getPartialKeyRE, '$2'); + findPartialKey_new: function(partialString) { + var partialKey = partialString.replace(this.findPartialKeyRE, '$2'); return partialKey; + }, + + // GTP: the old implementation works better. We might not need + // this.findPartialKeyRE anymore if it works in all cases! + findPartialKey: function(partialString) { + //strip out the template cruft + var foundPatternKey = partialString.replace("{{> ", "").replace(" }}", "").replace("{{>", "").replace("}}", ""); + + // remove any potential pattern parameters. this and the above are rather brutish but I didn't want to do a regex at the time + if(foundPatternKey.indexOf('(') > 0){ + foundPatternKey = foundPatternKey.substring(0, foundPatternKey.indexOf('(')); + } + + //remove any potential stylemodifiers. + foundPatternKey = foundPatternKey.split(':')[0]; + + return foundPatternKey; } }; From 5dd805234d0050da16f0e6dd4bca4e427c3e8d09 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 12 Jan 2016 13:25:50 -0600 Subject: [PATCH 054/187] fix up some unit tests for the pattern engines branch, wherein we require oPattern objects to have their prototype --- test/lineage_hunter_tests.js | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/test/lineage_hunter_tests.js b/test/lineage_hunter_tests.js index 7a05d5b55..18cb1c5f9 100644 --- a/test/lineage_hunter_tests.js +++ b/test/lineage_hunter_tests.js @@ -105,11 +105,11 @@ 'find_lineage - finds lineage with spaced pattern parameters' : function(test){ //setup current pattern from what we would have during execution - var currentPattern = createFakeEmptyErrorPattern(); - extend(currentPattern, { + var currentPattern = createFakeEmptyErrorPattern(); + extend(currentPattern, { "template": "{{> atoms-error(message: 'That\\'s no moon...') }}", "patternPartial": "{{> atoms-error(message: 'That\\'s no moon...') }}" - }); + }); var patternlab = { patterns: [ @@ -137,8 +137,8 @@ 'find_lineage - finds lineage with unspaced pattern parameters' : function(test){ //setup current pattern from what we would have during execution - var currentPattern = createFakeEmptyErrorPattern(); - extend(currentPattern, { + var currentPattern = createFakeEmptyErrorPattern(); + extend(currentPattern, { "template": "{{>atoms-error(message: 'That\\'s no moon...')}}", "patternPartial": "{{>atoms-error(message: 'That\\'s no moon...')}}" }); @@ -180,7 +180,7 @@ 'find_lineage - finds lineage with spaced styleModifier' : function(test){ //setup current pattern from what we would have during execution - var currentPattern = { + var currentPattern = of.oPattern.createEmpty({ "name": "01-molecules-01-toast-00-error", "subdir": "01-molecules\\01-toast", "filename": "00-error.mustache", @@ -198,10 +198,10 @@ "lineageIndex": [], "lineageR": [], "lineageRIndex": [] - }; + }); var patternlab = { patterns: [ - { + of.oPattern.createEmpty({ "name": "01-atoms-05-alerts-00-error", "subdir": "01-atoms\\05-alerts", "filename": "00-error.mustache", @@ -219,7 +219,7 @@ "lineageIndex": [], "lineageR": [], "lineageRIndex": [] - } + }) ] }; @@ -234,7 +234,7 @@ 'find_lineage - finds lineage with unspaced styleModifier' : function(test){ //setup current pattern from what we would have during execution - var currentPattern = { + var currentPattern = of.oPattern.createEmpty({ "name": "01-molecules-01-toast-00-error", "subdir": "01-molecules\\01-toast", "filename": "00-error.mustache", @@ -252,10 +252,10 @@ "lineageIndex": [], "lineageR": [], "lineageRIndex": [] - }; + }); var patternlab = { patterns: [ - { + of.oPattern.createEmpty({ "name": "01-atoms-05-alerts-00-error", "subdir": "01-atoms\\05-alerts", "filename": "00-error.mustache", @@ -273,7 +273,7 @@ "lineageIndex": [], "lineageR": [], "lineageRIndex": [] - } + }) ] }; @@ -288,7 +288,7 @@ 'find_lineage - finds lineage with fuzzy partial with styleModifier' : function(test){ //setup current pattern from what we would have during execution - var currentPattern = { + var currentPattern = of.oPattern.createEmpty({ "name": "01-molecules-01-toast-00-error", "subdir": "01-molecules\\01-toast", "filename": "00-error.mustache", @@ -306,10 +306,10 @@ "lineageIndex": [], "lineageR": [], "lineageRIndex": [] - }; + }); var patternlab = { patterns: [ - { + of.oPattern.createEmpty({ "name": "01-atoms-05-alerts-00-error", "subdir": "01-atoms\\05-alerts", "filename": "00-error.mustache", @@ -327,7 +327,7 @@ "lineageIndex": [], "lineageR": [], "lineageRIndex": [] - } + }) ] }; From e62a8ed1db521f44997171bb06f0c226aa475411 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 12 Jan 2016 13:26:25 -0600 Subject: [PATCH 055/187] minor fixups --- builder/lineage_hunter.js | 6 +++--- builder/object_factory.js | 6 +++--- config.json | 2 +- test/pattern_assembler_tests.js | 1 - 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/builder/lineage_hunter.js b/builder/lineage_hunter.js index 54c083b69..c10b5e479 100644 --- a/builder/lineage_hunter.js +++ b/builder/lineage_hunter.js @@ -1,6 +1,6 @@ -/* - * patternlab-node - v1.0.1 - 2015 - * +/* + * patternlab-node - v1.0.1 - 2015 + * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. * diff --git a/builder/object_factory.js b/builder/object_factory.js index 359a3bc58..197daec7f 100644 --- a/builder/object_factory.js +++ b/builder/object_factory.js @@ -1,6 +1,6 @@ -/* - * patternlab-node - v1.0.1 - 2015 - * +/* + * patternlab-node - v1.0.1 - 2015 + * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. * diff --git a/config.json b/config.json index 63da4cf86..dfca6c756 100644 --- a/config.json +++ b/config.json @@ -27,7 +27,7 @@ ], "ignored-extensions" : ["scss", "DS_Store", "less"], "ignored-directories" : ["scss"], - "debug": true, + "debug": false, "ishControlsVisible": { "s": true, "m": true, diff --git a/test/pattern_assembler_tests.js b/test/pattern_assembler_tests.js index 7f2aae188..974e0cc53 100644 --- a/test/pattern_assembler_tests.js +++ b/test/pattern_assembler_tests.js @@ -48,7 +48,6 @@ ); var results = currentPattern.findPartials(); - console.log(results); test.equals(results.length, 15); test.equals(results[0], "{{> molecules-comment-header}}"); test.equals(results[1], "{{> molecules-comment-header}}"); From 803d541f6f986981ba88500e82e88450d77b8d76 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 12 Jan 2016 13:29:18 -0600 Subject: [PATCH 056/187] fix handlebars engine's findPartialKey method signature to match new convention -- this method only needs a string --- builder/pattern_engines/engine_handlebars.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/pattern_engines/engine_handlebars.js b/builder/pattern_engines/engine_handlebars.js index 4137d31bc..e9c2dcdf6 100644 --- a/builder/pattern_engines/engine_handlebars.js +++ b/builder/pattern_engines/engine_handlebars.js @@ -64,7 +64,7 @@ }, // given a pattern, and a partial string, tease out the "pattern key" and // return it. - findPartialKey: function(pattern, partialString) { + findPartialKey: function(partialString) { var partialKey = partialString.replace(this.findPartialsRE, '$1'); return partialKey; } From e7d1a1f03d8c3bfc465e9d90eba627321035ce2e Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 12 Jan 2016 13:39:50 -0600 Subject: [PATCH 057/187] minor environment fixes to a LIH unit test -- and with that, we pass again after the last big dev merge! --- test/list_item_hunter_tests.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/list_item_hunter_tests.js b/test/list_item_hunter_tests.js index e05c79938..c169e8726 100644 --- a/test/list_item_hunter_tests.js +++ b/test/list_item_hunter_tests.js @@ -268,6 +268,7 @@ 'process_list_item_partials - correctly ignores bookended partials without a style modifier when the same partial has a style modifier between' : function(test){ //arrange var fs = require('fs-extra'); + var pa = require('../builder/pattern_assembler'); var pattern_assembler = new pa(); var list_item_hunter = new lih(); var patterns_dir = './test/files/_patterns'; @@ -295,12 +296,12 @@ ] }; - var atomPattern = new object_factory.oPattern('test/files/_patterns/00-test/03-styled-atom.mustache', '00-test', '03-styled-atom.mustache'); + var atomPattern = new of.oPattern('test/files/_patterns/00-test/03-styled-atom.mustache', '00-test', '03-styled-atom.mustache'); atomPattern.template = fs.readFileSync(patterns_dir + '/00-test/03-styled-atom.mustache', 'utf8'); atomPattern.extendedTemplate = atomPattern.template; atomPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(atomPattern); - var bookendPattern = new object_factory.oPattern('test/files/_patterns/00-test/11-bookend-listitem.mustache', '00-test', '11-bookend-listitem.mustache'); + var bookendPattern = new of.oPattern('test/files/_patterns/00-test/11-bookend-listitem.mustache', '00-test', '11-bookend-listitem.mustache'); bookendPattern.template = fs.readFileSync(patterns_dir + '/00-test/11-bookend-listitem.mustache', 'utf8'); bookendPattern.extendedTemplate = bookendPattern.template; bookendPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(bookendPattern); From b67abfadb26a843d2d11d6c8bbf8cfe95682465d Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Wed, 20 Jan 2016 09:48:21 -0600 Subject: [PATCH 058/187] get rid of unnecessary remaining direct references to config.json --- builder/lineage_hunter.js | 1 - builder/list_item_hunter.js | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/builder/lineage_hunter.js b/builder/lineage_hunter.js index c10b5e479..d763236ed 100644 --- a/builder/lineage_hunter.js +++ b/builder/lineage_hunter.js @@ -17,7 +17,6 @@ var pa = require('./pattern_assembler'); var pattern_assembler = new pa(); - var config = require('../config.json'); //find the {{> template-name }} within patterns var matches = pattern.findPartials(); diff --git a/builder/list_item_hunter.js b/builder/list_item_hunter.js index ac3703f80..55f4394d7 100644 --- a/builder/list_item_hunter.js +++ b/builder/list_item_hunter.js @@ -17,7 +17,6 @@ pa = require('./pattern_assembler'), smh = require('./style_modifier_hunter'), plutils = require('./utilities'), - config = require('../config.json'), of = require('./object_factory'); var pattern_assembler = new pa(), @@ -31,7 +30,7 @@ if(matches !== null){ matches.forEach(function(liMatch, index, matches){ - if(config.debug){ + if(patternlab.config.debug){ console.log('found listItem of size ' + liMatch + ' inside ' + pattern.key); } @@ -43,7 +42,7 @@ var repeatedBlockTemplate = []; var repeatedBlockHtml = ''; for(var i = 0; i < items.indexOf(loopNumberString); i++){ - if (config.debug) { + if (patternlab.config.debug) { console.log('list item(s) in pattern', pattern.patternName, 'adding', patternBlock, 'to repeatedBlockTemplate'); } repeatedBlockTemplate.push(patternBlock); From 61ef4d78197e33496419c7800421542e71e7126f Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Wed, 20 Jan 2016 10:33:55 -0600 Subject: [PATCH 059/187] Get rid of direct references to config.json --- builder/object_factory.js | 4 ---- builder/pattern_assembler.js | 12 ------------ 2 files changed, 16 deletions(-) diff --git a/builder/object_factory.js b/builder/object_factory.js index 197daec7f..918bba914 100644 --- a/builder/object_factory.js +++ b/builder/object_factory.js @@ -14,7 +14,6 @@ var patternEngines = require('./pattern_engines/pattern_engines'); var path = require('path'); var fs = require('fs-extra'); - var config = fs.readJSONSync('./config.json'); var extend = require('util')._extend; // oPattern properties @@ -52,9 +51,6 @@ // render method on oPatterns; this acts as a proxy for the PatternEngine's // render function render: function (data, partials) { - if (config.debug && this.isPseudoPattern) { - console.log('===', this.name + ' IS A PSEUDO-PATTERN ==='); - } return this.engine.renderPattern(this.extendedTemplate, data || this.jsonFileData, partials); }, diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index 8c4adcdba..5ad635724 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -18,8 +18,6 @@ plutils = require('./utilities'), patternEngines = require('./pattern_engines/pattern_engines'); - var config = fs.readJSONSync('./config.json'); - function setState(pattern, patternlab){ if(patternlab.config.patternStates && patternlab.config.patternStates[pattern.patternName]){ pattern.patternState = patternlab.config.patternStates[pattern.patternName]; @@ -56,16 +54,10 @@ // if we've been passed a full oPattern, it knows what kind of template it // is, and how to render itself, so we just call its render method if (pattern instanceof of.oPattern) { - if (config.debug) { - console.log('rendering full oPattern: ' + pattern.name); - } return pattern.render(data, partials); } else { // otherwise, assume it's a plain mustache template string and act // accordingly - if (config.debug) { - console.log('rendering plain mustache string:', pattern.substring(0, 20) + '...'); - } return patternEngines.mustache.renderPattern(pattern, data, partials); } } @@ -76,10 +68,6 @@ var filename = path.basename(file); var ext = path.extname(filename); - if (config.debug) { - console.log('processPatternIterative:', filename); - } - // skip non-pattern files if (!patternEngines.isPatternFile(filename, patternlab)) { return null; } From a422daa7a8ff2a25e7101c1411d6b129f8509c2c Mon Sep 17 00:00:00 2001 From: e2tha-e Date: Fri, 19 Feb 2016 09:23:32 -0500 Subject: [PATCH 060/187] a parameterized partial finder. comments on partial finding regex --- builder/pattern_engines/engine_mustache.js | 34 ++++-- builder/pattern_engines/util_mustache.js | 134 +++++++++++++++++++++ 2 files changed, 159 insertions(+), 9 deletions(-) create mode 100644 builder/pattern_engines/util_mustache.js diff --git a/builder/pattern_engines/engine_mustache.js b/builder/pattern_engines/engine_mustache.js index 0a472a6d3..aaf9a8ef0 100644 --- a/builder/pattern_engines/engine_mustache.js +++ b/builder/pattern_engines/engine_mustache.js @@ -12,6 +12,7 @@ "use strict"; var Mustache = require('mustache'); + var utilMustache = require('./util_mustache'); var engine_mustache = { engine: Mustache, @@ -23,11 +24,11 @@ expandPartials: true, // regexes, stored here so they're only compiled once - findPartialsRE: /{{>\s*((?:\d+-[\w-]+\/)+(\d+-[\w-]+(\.\w+)?)|[A-Za-z0-9-]+)(\:[\w-]+(?:\|[\w-]+)*)?(\(\s*\w+\s*:\s*(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*")\))?\s*}}/g, - findPartialsWithStyleModifiersRE: /{{>([ ])?([\w\-\.\/~]+)(?!\()(\:[A-Za-z0-9-_|]+)+(?:(| )\(.*)?([ ])?}}/g, - findPartialsWithPatternParametersRE: /{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-_|]+)?(?:(| )\(.*)+([ ])?}}/g, - findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, - findPartialKeyRE: /{{>([ ])?([\w\-\.\/~]+)(:[A-z-_|]+)?(?:\:[A-Za-z0-9-_]+)?(?:(| )\(.*)?([ ])?}}/g, + findPartialsRE: utilMustache.partialsRE, + findPartialsWithStyleModifiersRE: utilMustache.partialsWithStyleModifiersRE, + findPartialsWithPatternParametersRE: utilMustache.partialsWithPatternParametersRE, + findListItemsRE: utilMustache.listItemsRE, + findPartialKeyRE: utilMustache.partialKeyRE, // render it renderPattern: function renderPattern(template, data, partials) { @@ -37,23 +38,38 @@ return Mustache.render(template, data); }, + // find partials based on regex. + // @param {string|object} pattern - either a string or a pattern object. + // @param {object} regex - a JavaScript RegExp object. + // @returns {array} + partialsFinder: function partialsFinder(pattern, regex){ + var matches = []; + + if(typeof pattern === 'string'){ + matches = pattern.match(regex); + } else if(typeof pattern === 'object' && typeof pattern.template === 'string'){ + matches = pattern.template.match(regex); + } + + return matches; + }, // find and return any {{> template-name }} within pattern findPartials: function findPartials(pattern) { - var matches = pattern.template.match(this.findPartialsRE); + var matches = this.partialsFinder(pattern, this.findPartialsRE); return matches; }, findPartialsWithStyleModifiers: function(pattern) { - var matches = pattern.template.match(this.findPartialsWithStyleModifiersRE); + var matches = this.partialsFinder(pattern, this.findPartialsWithStyleModifiersRE); return matches; }, // returns any patterns that match {{> value(foo:"bar") }} or {{> // value:mod(foo:"bar") }} within the pattern findPartialsWithPatternParameters: function(pattern) { - var matches = pattern.template.match(this.findPartialsWithPatternParametersRE); + var matches = this.partialsFinder(pattern, this.findPartialsWithPatternParametersRE); return matches; }, findListItems: function(pattern) { - var matches = pattern.template.match(this.findListItemsRE); + var matches = this.partialsFinder(pattern, this.findListItemsRE); return matches; }, // given a pattern, and a partial string, tease out the "pattern key" and diff --git a/builder/pattern_engines/util_mustache.js b/builder/pattern_engines/util_mustache.js new file mode 100644 index 000000000..93ff40cb1 --- /dev/null +++ b/builder/pattern_engines/util_mustache.js @@ -0,0 +1,134 @@ +/* + * mustache utilities for patternlab-node - v0.10.1 - 2015 + * + * Geoffrey Pursell, Brian Muenzenmeyer, and the web community. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * + */ + +(function () { + 'use strict'; + + // the term "alphanumeric" includes underscores. + + // look for an opening mustache include tag, followed by >=0 whitespaces + var partialsStr = '{{>\\s*'; + // begin 1st exterior group, a mandatory group + // look for >0 of an interior group comprising + // >0 digits, followed by a hyphen, followed by >0 alphanumerics + partialsStr += '((\\d+-[\\w-]+\\/)+'; + // then an interior group comprising + // >0 digits, followed by a hyphen, followed by >0 alphanumerics, + // followed by an optional group of a period followed by >0 alphanumerics + partialsStr += '(\\d+-[\\w-]+(\\.\\w+)?)'; + // if the previous two interior groups are not found, look for any number of + // alphanumerics or hyphens + partialsStr += '|[\\w\\-]+)'; + // end 1st exterior group + // begin 2nd exterior group, an optional group + // look for a colon, followed by >0 alphanumerics or hyphens, + // followed by >=0 interior groups + // comprising a pipe, followed by >0 alphanumerics or hyphens + partialsStr += '(\\:[\\w\\-]+(\\|[\\w\\-]+)*)?'; + // end 2nd exterior group + // begin 3rd exterior group, an optional group + // look for an opening parenthesis, followed by >=0 whitespaces, + // followed by >=0 whitespaces, followed by a colon, followed by >=0 whitespaces + partialsStr += '(\\(\\s*\\w+\\s*:\\s*'; + // followed by an interior group + // comprising a single quote, followed by an interior group comprising + // >0 characters that are not single quotes or backslashes + // or >0 character pairs comprising a backlash, followed by any character + // look for a single quote to termination this pattern + partialsStr += '(\'([^\'\\\\]|\\\\.)*\''; + // if the pattern wrapped in single quotes is not found, look for one wrapped + // in double quotes + // look for a double quote, followed by an interior group comprising + // >0 characters that are not double quotes or backslashes + // or >0 character pairs comprising a backlash, followed by any character + // look for a double quote to termination this pattern + partialsStr += '|"([^"\\\\]|\\\\.)*")'; + // look for a closing parenthesis + partialsStr += '\\))?'; + // end 3rd exterior group + // look for >=0 whitespaces, followed by closing mustache tag + partialsStr += '\\s*}}'; + var partialsRE = new RegExp(partialsStr, 'g'); + + // look for an opening mustache include tag, followed by >=0 whitespaces + var partialsWithStyleModifiersStr = '{{>\\s*'; + // one or more characters comprising any combination of alphanumerics, + // hyphens, periods, slashses, and tildes + partialsWithStyleModifiersStr += '([\\w\\-\\.\\/~]+)'; + // the previous group cannot be followed by an opening parenthesis + partialsWithStyleModifiersStr += '(?!\\()'; + // a colon followed by one or more characters comprising any combination + // of alphanumerics, hyphens, and pipes + partialsWithStyleModifiersStr += '(\\:[\\w\\-\\|]+)'; + // an optional group of characters starting with >=0 whitespaces, followed by + // an opening parenthesis, followed by any number of characters that are not + // closing parentheses, followed by a closing parenthesis + partialsWithStyleModifiersStr += '(\\s*\\([^\\)]*\\))?'; + // look for >=0 whitespaces, followed by closing mustache tag + partialsWithStyleModifiersStr += '\\s*}}'; + var partialsWithStyleModifiersRE = new RegExp(partialsWithStyleModifiersStr, 'g'); + + // look for an opening mustache include tag, followed by >=0 whitespaces + var partialsWithPatternParametersStr = '{{>\\s*'; + // one or more characters comprising any combination of alphanumerics, + // hyphens, periods, slashses, and tildes + partialsWithPatternParametersStr += '([\\w\\-\\.\\/~]+)'; + // an optional group comprising a colon followed by one or more characters + // comprising any combination of alphanumerics, + // hyphens, and pipes + partialsWithPatternParametersStr += '(\\:[\\w\\-\\|]+)?'; + // a group of characters starting with >=0 whitespaces, followed by an opening + // parenthesis, followed by any number of characters that are not closing + // parentheses, followed by a closing parenthesis + partialsWithPatternParametersStr += '(\\s*\\([^\\)]*\\))'; + // look for >=0 whitespaces, followed by closing mustache tag + partialsWithPatternParametersStr += '\\s*}}'; + var partialsWithPatternParametersRE = new RegExp(partialsWithPatternParametersStr, 'g'); + + // look for an opening mustache loop tag, followed by >=0 whitespaces + var listItemsStr = '{{#\\s*'; + // look for the string 'listItems.' or 'listitems.' + listItemsStr += '(list(I|i)tems\\.)'; + // look for a number 1 - 20, spelled out + listItemsStr += '(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)'; + // look for >=0 whitespaces, followed by closing mustache tag + listItemsStr += '\\s*}}'; + var listItemsRE = new RegExp(listItemsStr, 'g'); + + // look for an opening mustache loop tag, followed by >=0 whitespaces + var partialKeyStr = '{{>\\s*'; + // one or more characters comprising any combination of alphanumerics, + // hyphens, periods, slashses, and tildes + partialKeyStr += '([\\w\\-\\.\\/~]+)'; + // an optional group of characters starting with a colon, followed by >0 + // alphanumerics, hyphens, or pipes + partialKeyStr += '(\\:[\\w\\-|]+)?'; + // an optional group of characters starting with a colon, followed by >0 + // alphanumerics or hyphens + partialKeyStr += '(\\:[\\w\\-]+)?'; + // an optional group of characters starting with >=0 whitespaces, followed by + // an opening parenthesis, followed by any number of characters that are not + // closing parentheses, followed by a closing parenthesis + partialKeyStr += '(\\s*\\([^\\)]*\\))?'; + // look for >=0 whitespaces, followed by closing mustache tag + partialKeyStr += '\\s*}}'; + partialKeyStr += '\\s*}}'; + var partialKeyRE = new RegExp(partialKeyStr, 'g'); + + var utilMustache = { + partialsRE: partialsRE, + partialsWithStyleModifiersRE: partialsWithStyleModifiersRE, + partialsWithPatternParametersRE: partialsWithPatternParametersRE, + listItemsRE: listItemsRE, + partialKeyRE: partialKeyRE + }; + + module.exports = utilMustache; +})(); From f9ba2df3cf6c0efd2ed6d3f379dd33ee9efed943 Mon Sep 17 00:00:00 2001 From: e2tha-e Date: Fri, 19 Feb 2016 09:29:21 -0500 Subject: [PATCH 061/187] removing duplicate line --- builder/pattern_engines/.util_mustache.js.swp | Bin 0 -> 16384 bytes builder/pattern_engines/util_mustache.js | 1 - 2 files changed, 1 deletion(-) create mode 100644 builder/pattern_engines/.util_mustache.js.swp diff --git a/builder/pattern_engines/.util_mustache.js.swp b/builder/pattern_engines/.util_mustache.js.swp new file mode 100644 index 0000000000000000000000000000000000000000..dffa7676b7e5cf47a10bfbfc60d8554f020ac069 GIT binary patch literal 16384 zcmeHOU5FdU9iKSOmz}gBg}$_f@j0oa`;g9dOUfO#q13St=NiYC*lDw_S!qYo)T`Oe z&g{vmbqU0wB?&2%LLW*Cq0l7Iml6tnDFjL(kc1@kp~Rt3lDGCPg%TP_>2LN+vn!qM zt~rCjEAD4$cV}n+^ZU>Izh>QBJiD?=@2`KI;Bz-2AK&}>+50|PA&(s(7H> zi?>-&cfFSFPHEnFRI)%e*1C4UoW>egOg4O5DHaIVZY~JVVa4MGc1U&Y1=eVW+;v!x zUcbOZhYQ>vD(+tBg;LqAF021QPI-KJsbt{BWgt}Tg>T+P4j($Ws7W|5v!8zPo=0z7 zKFX1o43rF%43rF%43rF%43rF%4BUVWD1Q%m3gh0BjQu;w_f3WGo0H@FlkbNL*OSBY zt7M>Lpk$zApk$zApk$zApk$zApk$zApk$zA;5uZ$b_i)et}8m>$Nqns|9|=gLjDB2 z20R5=z;}V0fd77;kWYaB0RIHu2d)Ay0lxvh2P^}7fva~B@^e4{CxDxQKio;kbHFn2 zRp8TognR(}4)B3fz&_x;y@dP`cpf+j{QC|<-UMC&E&wyYUvDSmSHKg%eqbN)=i3PR zF|Z8m0p7cnklzEp0GZe&&_3`gpR_#1~)oRDmN2i@aWF}OXNhb48wdq(BE@QC`?z7u@@pdtwBJ4F;K)p6? z;awKHg*R9v#d|7>;-OS{%IHpUPuMQ)1YYPD?!Zec&=VBhhn|YM%n7|+R+b*OtiEL} zSl00TTrH&pa@wxnwIMbOcnbsS4*V_?_+bl&`rOCViS!0;Jl7MsIpzsQF)w=_hGq=6 z<@Nl4NBXlt2@acF*m|_v6ZY7CC@>QdilTnN*0~qTgsYYS%`Wj**j6v|~E7()08~+UctlYY)q`a{2O6J<(G&UK10s znL(Ji{Iy)Wyx3tZ7#KbrIFwz&I^vjW(ONN7I(n?J&PQx)vYu0$mEJv^fxVcq@Hs!k zKUTdqJCn^nqc_J3n=YeIgr0)M^(chuB{LgqoJ$zP=#@1H2;m{_(Z$iaz(o#QU@i{Y zv|AVTbjq!0tUN55)Oy5ynH}Zr2{nb1`k}hhXp*M$a+47h9|~V$vTR5i%fLncS;^Tp zhK>~)kDT@c+xOvt&{!LQlr2fYj$X5EFBH!F$fxNwliY*;ii)XP6>Z7kLJZYdmGNnx zd)RfOnmhxORFj(xX7imY$8`NLgn3m?WY$VtWq(dvk|ooen4L{^(}`2a3tPA&o+hI? zI0|Amb)%x z0V|suQmi+eb$ExXVzifNce;iWwZKFQJx%jE&zsn>F=8f;28p<&HkT6rnM8_5l}$AC zrNfZvvca9j%Wr(DU}n)CLLpmu!60+cW)!2{>@|#8Ae;6;+8NUsQ-3p{JIanEh0{SG z-a?=%>pB&xgpyII5b`Q;T5X4-rR@i;*63wipKSp6qpNx%B77GY;dMRwt-yBZ1A&M2 zqJzJ0+v|)z%7J4N!JhJw~%m^k!;Zr zR#zUOZhTs|q9>TwZU<~YPlthIt~(C_I5f2yGVwzudThXuiA7;32o>09|a5YGu zk|m1zZFsIYlaZ)}ckAf_U0k16;0&-A z_y_X%7XbyF0tj#wdHkzD2RI4L0DnO)e+4)Jd z@Dtz#zyd~^PJFSb#}@30wv)RwN0LSaW(nhOUv44 zZRiSG77CqWgEPmM(!eM>iY~icsujh0sOK%gnPdk#5Xo+i%73Thl&D{(fTsc(}f%!v@VtI&hGr{jpgTiH3^vn(VO^ngA8i+)wX4XR|r=5%FYNA$B zd3513D+cETGRmHaoiq)eze-Xs8d}=&b597tK%x3>3p@eP{fG zx1(=#5P$3D(XXf@-B$M%ok1r;4YDjY%hBvK8II#~6rp{j1IQh`P;V%Vk3yfRt_*oi zdjeh1Of$!$v?-UNq{stNb+c#A5#=l|N5N=xO5J^qZlQn5jgCc?-n zPmVhDjM6&?U?Vlu@g7xXs=0 whitespaces, followed by closing mustache tag partialKeyStr += '\\s*}}'; - partialKeyStr += '\\s*}}'; var partialKeyRE = new RegExp(partialKeyStr, 'g'); var utilMustache = { From 1e94f31d64e9aca6975382f2b9f0c580da30765e Mon Sep 17 00:00:00 2001 From: e2tha-e Date: Fri, 19 Feb 2016 09:29:45 -0500 Subject: [PATCH 062/187] deleting vim .swp file --- builder/pattern_engines/.util_mustache.js.swp | Bin 16384 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 builder/pattern_engines/.util_mustache.js.swp diff --git a/builder/pattern_engines/.util_mustache.js.swp b/builder/pattern_engines/.util_mustache.js.swp deleted file mode 100644 index dffa7676b7e5cf47a10bfbfc60d8554f020ac069..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeHOU5FdU9iKSOmz}gBg}$_f@j0oa`;g9dOUfO#q13St=NiYC*lDw_S!qYo)T`Oe z&g{vmbqU0wB?&2%LLW*Cq0l7Iml6tnDFjL(kc1@kp~Rt3lDGCPg%TP_>2LN+vn!qM zt~rCjEAD4$cV}n+^ZU>Izh>QBJiD?=@2`KI;Bz-2AK&}>+50|PA&(s(7H> zi?>-&cfFSFPHEnFRI)%e*1C4UoW>egOg4O5DHaIVZY~JVVa4MGc1U&Y1=eVW+;v!x zUcbOZhYQ>vD(+tBg;LqAF021QPI-KJsbt{BWgt}Tg>T+P4j($Ws7W|5v!8zPo=0z7 zKFX1o43rF%43rF%43rF%43rF%4BUVWD1Q%m3gh0BjQu;w_f3WGo0H@FlkbNL*OSBY zt7M>Lpk$zApk$zApk$zApk$zApk$zApk$zA;5uZ$b_i)et}8m>$Nqns|9|=gLjDB2 z20R5=z;}V0fd77;kWYaB0RIHu2d)Ay0lxvh2P^}7fva~B@^e4{CxDxQKio;kbHFn2 zRp8TognR(}4)B3fz&_x;y@dP`cpf+j{QC|<-UMC&E&wyYUvDSmSHKg%eqbN)=i3PR zF|Z8m0p7cnklzEp0GZe&&_3`gpR_#1~)oRDmN2i@aWF}OXNhb48wdq(BE@QC`?z7u@@pdtwBJ4F;K)p6? z;awKHg*R9v#d|7>;-OS{%IHpUPuMQ)1YYPD?!Zec&=VBhhn|YM%n7|+R+b*OtiEL} zSl00TTrH&pa@wxnwIMbOcnbsS4*V_?_+bl&`rOCViS!0;Jl7MsIpzsQF)w=_hGq=6 z<@Nl4NBXlt2@acF*m|_v6ZY7CC@>QdilTnN*0~qTgsYYS%`Wj**j6v|~E7()08~+UctlYY)q`a{2O6J<(G&UK10s znL(Ji{Iy)Wyx3tZ7#KbrIFwz&I^vjW(ONN7I(n?J&PQx)vYu0$mEJv^fxVcq@Hs!k zKUTdqJCn^nqc_J3n=YeIgr0)M^(chuB{LgqoJ$zP=#@1H2;m{_(Z$iaz(o#QU@i{Y zv|AVTbjq!0tUN55)Oy5ynH}Zr2{nb1`k}hhXp*M$a+47h9|~V$vTR5i%fLncS;^Tp zhK>~)kDT@c+xOvt&{!LQlr2fYj$X5EFBH!F$fxNwliY*;ii)XP6>Z7kLJZYdmGNnx zd)RfOnmhxORFj(xX7imY$8`NLgn3m?WY$VtWq(dvk|ooen4L{^(}`2a3tPA&o+hI? zI0|Amb)%x z0V|suQmi+eb$ExXVzifNce;iWwZKFQJx%jE&zsn>F=8f;28p<&HkT6rnM8_5l}$AC zrNfZvvca9j%Wr(DU}n)CLLpmu!60+cW)!2{>@|#8Ae;6;+8NUsQ-3p{JIanEh0{SG z-a?=%>pB&xgpyII5b`Q;T5X4-rR@i;*63wipKSp6qpNx%B77GY;dMRwt-yBZ1A&M2 zqJzJ0+v|)z%7J4N!JhJw~%m^k!;Zr zR#zUOZhTs|q9>TwZU<~YPlthIt~(C_I5f2yGVwzudThXuiA7;32o>09|a5YGu zk|m1zZFsIYlaZ)}ckAf_U0k16;0&-A z_y_X%7XbyF0tj#wdHkzD2RI4L0DnO)e+4)Jd z@Dtz#zyd~^PJFSb#}@30wv)RwN0LSaW(nhOUv44 zZRiSG77CqWgEPmM(!eM>iY~icsujh0sOK%gnPdk#5Xo+i%73Thl&D{(fTsc(}f%!v@VtI&hGr{jpgTiH3^vn(VO^ngA8i+)wX4XR|r=5%FYNA$B zd3513D+cETGRmHaoiq)eze-Xs8d}=&b597tK%x3>3p@eP{fG zx1(=#5P$3D(XXf@-B$M%ok1r;4YDjY%hBvK8II#~6rp{j1IQh`P;V%Vk3yfRt_*oi zdjeh1Of$!$v?-UNq{stNb+c#A5#=l|N5N=xO5J^qZlQn5jgCc?-n zPmVhDjM6&?U?Vlu@g7xXs Date: Fri, 19 Feb 2016 09:51:37 -0500 Subject: [PATCH 063/187] comment and character escape update --- builder/pattern_engines/util_mustache.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/builder/pattern_engines/util_mustache.js b/builder/pattern_engines/util_mustache.js index b732ba462..f5403a2de 100644 --- a/builder/pattern_engines/util_mustache.js +++ b/builder/pattern_engines/util_mustache.js @@ -34,21 +34,22 @@ partialsStr += '(\\:[\\w\\-]+(\\|[\\w\\-]+)*)?'; // end 2nd exterior group // begin 3rd exterior group, an optional group - // look for an opening parenthesis, followed by >=0 whitespaces, - // followed by >=0 whitespaces, followed by a colon, followed by >=0 whitespaces - partialsStr += '(\\(\\s*\\w+\\s*:\\s*'; + // look for an opening parenthesis, followed by >=0 whitespaces, followed by + // >0 alphanumerics, followed by >=0 whitespaces, followed by a colon, + // followed by >=0 whitespaces + partialsStr += '(\\(\\s*\\w+\\s*\\:\\s*'; // followed by an interior group // comprising a single quote, followed by an interior group comprising - // >0 characters that are not single quotes or backslashes - // or >0 character pairs comprising a backlash, followed by any character - // look for a single quote to termination this pattern + // >=0 characters that are not single quotes or backslashes + // or >=0 character pairs comprising a backlash, followed by any character. + // look for a single quote to terminate this pattern partialsStr += '(\'([^\'\\\\]|\\\\.)*\''; // if the pattern wrapped in single quotes is not found, look for one wrapped // in double quotes // look for a double quote, followed by an interior group comprising - // >0 characters that are not double quotes or backslashes - // or >0 character pairs comprising a backlash, followed by any character - // look for a double quote to termination this pattern + // >=0 characters that are not double quotes or backslashes + // or >=0 character pairs comprising a backlash, followed by any character. + // look for a double quote to terminate this pattern partialsStr += '|"([^"\\\\]|\\\\.)*")'; // look for a closing parenthesis partialsStr += '\\))?'; From f78713669150764a74fbaa3c0caa33679c941cee Mon Sep 17 00:00:00 2001 From: e2tha-e Date: Mon, 22 Feb 2016 06:16:56 -0500 Subject: [PATCH 064/187] fixing regex for replace operation in findPartialKey_new --- builder/pattern_engines/engine_mustache.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/pattern_engines/engine_mustache.js b/builder/pattern_engines/engine_mustache.js index aaf9a8ef0..cee63b99c 100644 --- a/builder/pattern_engines/engine_mustache.js +++ b/builder/pattern_engines/engine_mustache.js @@ -75,7 +75,7 @@ // given a pattern, and a partial string, tease out the "pattern key" and // return it. findPartialKey_new: function(partialString) { - var partialKey = partialString.replace(this.findPartialKeyRE, '$2'); + var partialKey = partialString.replace(this.findPartialKeyRE, '$1'); return partialKey; }, From 2875322b3dc8fb0375d24893746347e7cea07a5e Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Wed, 24 Feb 2016 11:33:52 -0600 Subject: [PATCH 065/187] Don't run the handlebars tests unless handlebars is installed. --- test/engine_handlebars_tests.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/engine_handlebars_tests.js b/test/engine_handlebars_tests.js index 3a51b2f76..0f4f27ff5 100644 --- a/test/engine_handlebars_tests.js +++ b/test/engine_handlebars_tests.js @@ -1,6 +1,10 @@ (function () { "use strict"; + // don't run these tests unless handlebars is installed + try { var handlebars = require('handlebars'); } + catch (err) { return; } + var path = require('path'); var pa = require('../builder/pattern_assembler'); var object_factory = require('../builder/object_factory'); From 5c4d0653e8b403b765130fd76053f9aac0f87f66 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Fri, 26 Feb 2016 11:07:19 -0600 Subject: [PATCH 066/187] Underscore engine with basic support and unit tests! --- builder/pattern_engines/engine_underscore.js | 93 +++++++++++++++++++ test/engine_underscore_tests.js | 84 +++++++++++++++++ .../00-global/00-helloworld-withdata.json | 3 + .../00-helloworld-withdata.underscore | 2 + .../00-global/00-helloworld.underscore | 1 + .../00-call-atom-with-molecule-data.json | 6 ++ ...00-call-atom-with-molecule-data.underscore | 5 + .../00-global/00-helloworlds.underscore | 1 + test/pattern_engines_tests.js | 24 ++++- 9 files changed, 216 insertions(+), 3 deletions(-) create mode 100644 builder/pattern_engines/engine_underscore.js create mode 100644 test/engine_underscore_tests.js create mode 100644 test/files/_underscore-test-patterns/00-atoms/00-global/00-helloworld-withdata.json create mode 100644 test/files/_underscore-test-patterns/00-atoms/00-global/00-helloworld-withdata.underscore create mode 100644 test/files/_underscore-test-patterns/00-atoms/00-global/00-helloworld.underscore create mode 100644 test/files/_underscore-test-patterns/00-molecules/00-global/00-call-atom-with-molecule-data.json create mode 100644 test/files/_underscore-test-patterns/00-molecules/00-global/00-call-atom-with-molecule-data.underscore create mode 100644 test/files/_underscore-test-patterns/00-molecules/00-global/00-helloworlds.underscore diff --git a/builder/pattern_engines/engine_underscore.js b/builder/pattern_engines/engine_underscore.js new file mode 100644 index 000000000..25a95344b --- /dev/null +++ b/builder/pattern_engines/engine_underscore.js @@ -0,0 +1,93 @@ +/* + * underscore pattern engine for patternlab-node - v0.15.1 - 2015 + * + * Geoffrey Pursell, Brian Muenzenmeyer, and the web community. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * + */ + + +/* + * ENGINE SUPPORT LEVEL: + * + * Basic. We can't call partials from inside underscore templates yet, but we + * can render templates with backing JSON. + * + */ + +(function () { + "use strict"; + + var _ = require('underscore'); + + // extend underscore with partial-ing methods + // HANDLESCORE! UNDERBARS! + _.mixin({ + renderPartial: function(partial, data) { + var data = data || {}; + var compiled = _.template(partial); + return compiled(data); + }, + assignContext: function(viewModel, data) { + return viewModel(data); + } + }); + + var engine_underscore = { + engine: _, + engineName: 'underscore', + engineFileExtension: '.underscore', + + // partial expansion is only necessary for Mustache templates that have + // style modifiers or pattern parameters (I think) + expandPartials: false, + + // regexes, stored here so they're only compiled once + findPartialsRE: /<%= _.renderPartial\((.*?)\).*?%>/g, // TODO, + findPartialsWithStyleModifiersRE: /<%= _.renderPartial\((.*?)\).*?%>/g, // TODO + findPartialsWithPatternParametersRE: /<%= _.renderPartial\((.*?)\).*?%>/g, // TODO + findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, + + // render it + renderPattern: function renderPattern(template, data, partials) { + var compiled = _.template(template); + return compiled(_.extend(data, { + _allData: data, + _partials: partials + })); + }, + + // registerPartial: function (oPattern) { + // debugger; + // _.registerPartial(oPattern.key, oPattern.template); + // }, + + // find and return any {{> template-name }} within pattern + findPartials: function findPartials(pattern) { + var matches = pattern.template.match(this.findPartialsRE); + return matches; + }, + findPartialsWithStyleModifiers: function(pattern) { + return []; + }, + // returns any patterns that match {{> value(foo:"bar") }} or {{> + // value:mod(foo:"bar") }} within the pattern + findPartialsWithPatternParameters: function(pattern) { + return []; + }, + findListItems: function(pattern) { + var matches = pattern.template.match(this.findListItemsRE); + return matches; + }, + // given a pattern, and a partial string, tease out the "pattern key" and + // return it. + findPartialKey: function(partialString) { + var partialKey = partialString.replace(this.findPartialsRE, '$1'); + return partialKey; + } + }; + + module.exports = engine_underscore; +})(); diff --git a/test/engine_underscore_tests.js b/test/engine_underscore_tests.js new file mode 100644 index 000000000..d03779e79 --- /dev/null +++ b/test/engine_underscore_tests.js @@ -0,0 +1,84 @@ +(function () { + "use strict"; + + var path = require('path'); + var pa = require('../builder/pattern_assembler'); + var testPatternsPath = path.resolve(__dirname, 'files', '_underscore-test-patterns'); + + try { + require('underscore'); + } catch (err) { + console.log('underscore renderer not installed; skipping tests'); + return; + } + + // fake pattern lab constructor: + // sets up a fake patternlab object, which is needed by the pattern processing + // apparatus. + function fakePatternLab() { + var fpl = { + partials: {}, + patterns: [], + footer: '', + header: '', + listitems: {}, + listItemArray: [], + data: { + link: {} + }, + config: require('../config.json'), + package: {} + }; + + // patch the pattern source so the pattern assembler can correctly determine + // the "subdir" + fpl.config.paths.source.patterns = testPatternsPath; + + return fpl; + } + + exports['engine_underscore'] = { + 'hello world underscore pattern renders': function (test) { + test.expect(1); + + var patternPath = path.resolve( + testPatternsPath, + '00-atoms', + '00-global', + '00-helloworld.underscore' + ); + + // do all the normal processing of the pattern + var patternlab = new fakePatternLab(); + var assembler = new pa(); + var helloWorldPattern = assembler.process_pattern_iterative(patternPath, patternlab); + assembler.process_pattern_recursive(patternPath, patternlab); + + test.equals(helloWorldPattern.render(), 'Hello world!\n'); + test.done(); + }, + 'underscore partials can render JSON values': function (test) { + test.expect(1); + + // pattern paths + var pattern1Path = path.resolve( + testPatternsPath, + '00-atoms', + '00-global', + '00-helloworld-withdata.underscore' + ); + + // set up environment + var patternlab = new fakePatternLab(); // environment + var assembler = new pa(); + + // do all the normal processing of the pattern + var helloWorldWithData = assembler.process_pattern_iterative(pattern1Path, patternlab); + assembler.process_pattern_recursive(pattern1Path, patternlab); + + // test + test.equals(helloWorldWithData.render(), 'Hello world!\nYeah, we got the subtitle from the JSON.\n'); + test.done(); + } + }; +})(); diff --git a/test/files/_underscore-test-patterns/00-atoms/00-global/00-helloworld-withdata.json b/test/files/_underscore-test-patterns/00-atoms/00-global/00-helloworld-withdata.json new file mode 100644 index 000000000..491238b33 --- /dev/null +++ b/test/files/_underscore-test-patterns/00-atoms/00-global/00-helloworld-withdata.json @@ -0,0 +1,3 @@ +{ + "subtitle": "Yeah, we got the subtitle from the JSON." +} diff --git a/test/files/_underscore-test-patterns/00-atoms/00-global/00-helloworld-withdata.underscore b/test/files/_underscore-test-patterns/00-atoms/00-global/00-helloworld-withdata.underscore new file mode 100644 index 000000000..32c1c7361 --- /dev/null +++ b/test/files/_underscore-test-patterns/00-atoms/00-global/00-helloworld-withdata.underscore @@ -0,0 +1,2 @@ +Hello world! +<%= subtitle %> diff --git a/test/files/_underscore-test-patterns/00-atoms/00-global/00-helloworld.underscore b/test/files/_underscore-test-patterns/00-atoms/00-global/00-helloworld.underscore new file mode 100644 index 000000000..cd0875583 --- /dev/null +++ b/test/files/_underscore-test-patterns/00-atoms/00-global/00-helloworld.underscore @@ -0,0 +1 @@ +Hello world! diff --git a/test/files/_underscore-test-patterns/00-molecules/00-global/00-call-atom-with-molecule-data.json b/test/files/_underscore-test-patterns/00-molecules/00-global/00-call-atom-with-molecule-data.json new file mode 100644 index 000000000..dc49de353 --- /dev/null +++ b/test/files/_underscore-test-patterns/00-molecules/00-global/00-call-atom-with-molecule-data.json @@ -0,0 +1,6 @@ +{ + "subtitle": "from the default JSON.", + "otherBlob": { + "subtitle": "from a totally different blob." + } +} diff --git a/test/files/_underscore-test-patterns/00-molecules/00-global/00-call-atom-with-molecule-data.underscore b/test/files/_underscore-test-patterns/00-molecules/00-global/00-call-atom-with-molecule-data.underscore new file mode 100644 index 000000000..a0766acef --- /dev/null +++ b/test/files/_underscore-test-patterns/00-molecules/00-global/00-call-atom-with-molecule-data.underscore @@ -0,0 +1,5 @@ +

Call with default JSON environment:

+This is {{> atoms-helloworld-withdata }} + +

Call with passed parameter:

+However, this is {{> atoms-helloworld-withdata otherBlob }} diff --git a/test/files/_underscore-test-patterns/00-molecules/00-global/00-helloworlds.underscore b/test/files/_underscore-test-patterns/00-molecules/00-global/00-helloworlds.underscore new file mode 100644 index 000000000..a493205c3 --- /dev/null +++ b/test/files/_underscore-test-patterns/00-molecules/00-global/00-helloworlds.underscore @@ -0,0 +1 @@ +<%= _.template(_partials['atoms-helloworld'])(_data) %> and <%= _.template(_partials['atoms-helloworld'])(_data) %> diff --git a/test/pattern_engines_tests.js b/test/pattern_engines_tests.js index 87810ecf7..f298d1fc0 100644 --- a/test/pattern_engines_tests.js +++ b/test/pattern_engines_tests.js @@ -98,9 +98,27 @@ function testProps(object, propTests, test) { // function to test each expected property is present and the correct type - function testProp(propName, typeString) { + function testProp(propName, types) { + + var possibleTypes; + + // handle "types" being a string or an array of strings + if (types instanceof Array) { + possibleTypes = types; + } else { + // "types" is just a single string, load it into an array; the rest of + // the code expects it! + possibleTypes = [types]; + } + + var isOneOfTheseTypes = possibleTypes.map(function (type) { + return typeof object[propName] === type; + }).reduce(function(isPrevType, isCurrentType) { + return isPrevType || isCurrentType; + }); + test.ok(object.hasOwnProperty(propName), '"' + propName + '" prop should be present'); - test.ok(typeof object[propName] === typeString, '"' + propName + '" prop should be of type ' + typeString); + test.ok(isOneOfTheseTypes, '"' + propName + '" prop should be one of types ' + possibleTypes); } // go over each property test and run it @@ -129,7 +147,7 @@ 'engine contains expected properties and methods': function (test) { var propertyTests = { - 'engine': 'object', + 'engine': ['object', 'function'], 'engineName': 'string', 'engineFileExtension': 'string', 'renderPattern': 'function', From cfa2aafa0acd7e8694dbab0870aa617c37a9ab99 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Fri, 26 Feb 2016 11:07:57 -0600 Subject: [PATCH 067/187] Gulpfile enhancements: auto-watch all supported template types --- gulpfile.js | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index a481efccd..509144074 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -102,8 +102,21 @@ gulp.task('cp:styleguide', function(){ .pipe(browserSync.stream()); }); + // server and watch tasks -gulp.task('connect', ['lab'], function () { + +// watch task utility functions +function getSupportedTemplateExtensions() { + var engines = require('./builder/pattern_engines/pattern_engines'); + return engines.getSupportedFileExtensions(); +} +function getTemplateWatches() { + return getSupportedTemplateExtensions().map(function (dotExtension) { + return path.resolve(paths().source.patterns, '**/*' + dotExtension); + }); +} + +gulp.task('connect', ['lab'], function() { browserSync.init({ server: { baseDir: path.resolve(paths().public.root) @@ -135,19 +148,14 @@ gulp.task('connect', ['lab'], function () { gulp.watch(path.resolve(paths().source.styleguide, '**/*.*'), ['cp:styleguide']); - gulp.watch( - [ - path.resolve(paths().source.patterns, '**/*.mustache'), - path.resolve(paths().source.patterns, '**/*.json'), - path.resolve(paths().source.data, '*.json'), - path.resolve(paths().source.fonts + '/*'), - path.resolve(paths().source.images + '/*'), - path.resolve(paths().source.data + '*.json') - ], - ['lab-pipe'], - function () { browserSync.reload(); } - ); + var patternWatches = [ + path.resolve(paths().source.patterns, '**/*.json'), + path.resolve(paths().source.data, '*.json'), + path.resolve(paths().source.fonts + '/*'), + path.resolve(paths().source.images + '/*') + ].concat(getTemplateWatches()); + gulp.watch(patternWatches, ['lab-pipe'], function () { browserSync.reload(); }); }); //unit test From ad8324dacfd799e6c2a508b47f709b6c6b5a2206 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Fri, 26 Feb 2016 11:08:26 -0600 Subject: [PATCH 068/187] comment on engine support level and cleanup --- builder/pattern_engines/engine_handlebars.js | 28 +++++++++++++------- builder/pattern_engines/engine_mustache.js | 9 +++++++ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/builder/pattern_engines/engine_handlebars.js b/builder/pattern_engines/engine_handlebars.js index e9c2dcdf6..627c1e29e 100644 --- a/builder/pattern_engines/engine_handlebars.js +++ b/builder/pattern_engines/engine_handlebars.js @@ -8,6 +8,16 @@ * */ +/* + * ENGINE SUPPORT LEVEL: + * + * Full. Partial calls and lineage hunting are supported. Handlebars does not + * support the mustache-specific syntax extensions, style modifiers and pattern + * parameters, because their use cases are addressed by the core Handlebars + * feature set. + * + */ + (function () { "use strict"; @@ -23,11 +33,7 @@ expandPartials: false, // regexes, stored here so they're only compiled once - // GTP warning: unchanged copypasta from mustache engine - // findPartialsRE: /{{>\s*((?:\d+-[\w-]+\/)+(\d+-[\w-]+(\.\w+)?)|[A-Za-z0-9-]+)(\:[\w-]+)?(\(\s*\w+\s*:\s*(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*")\))?\s*}}/g, findPartialsRE: /{{#?>\s*([\w-\/.]+)(?:.|\s+)*?}}/g, - findPartialsWithStyleModifiersRE: /{{>([ ])?([\w\-\.\/~]+)(?!\()(\:[A-Za-z0-9-_|]+)+(?:(| )\(.*)?([ ])?}}/g, - findPartialsWithPatternParametersRE: /{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-_|]+)?(?:(| )\(.*)+([ ])?}}/g, findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, // render it @@ -48,15 +54,17 @@ var matches = pattern.template.match(this.findPartialsRE); return matches; }, - findPartialsWithStyleModifiers: function(pattern) { - var matches = pattern.template.match(this.findPartialsWithStyleModifiersRE); - return matches; + findPartialsWithStyleModifiers: function() { + // TODO: make the call to this from oPattern objects conditional on their + // being implemented here. + return []; }, // returns any patterns that match {{> value(foo:"bar") }} or {{> // value:mod(foo:"bar") }} within the pattern - findPartialsWithPatternParameters: function(pattern) { - var matches = pattern.template.match(this.findPartialsWithPatternParametersRE); - return matches; + findPartialsWithPatternParameters: function() { + // TODO: make the call to this from oPattern objects conditional on their + // being implemented here. + return []; }, findListItems: function(pattern) { var matches = pattern.template.match(this.findListItemsRE); diff --git a/builder/pattern_engines/engine_mustache.js b/builder/pattern_engines/engine_mustache.js index cee63b99c..32c1d6c78 100644 --- a/builder/pattern_engines/engine_mustache.js +++ b/builder/pattern_engines/engine_mustache.js @@ -8,6 +8,15 @@ * */ +/* + * ENGINE SUPPORT LEVEL: + * + * Full + extensions. Partial calls and lineage hunting are supported. Style + * modifiers and pattern parameters are used to extend the core feature set of + * Mustache templates. + * + */ + (function () { "use strict"; From fe2ea0066a0925d5e96ed7d16cc774f10b11f045 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Fri, 26 Feb 2016 11:08:55 -0600 Subject: [PATCH 069/187] *temporarily* add template renderers to package.json just so our unit tests actually mean something in Travis/GitHub --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 07023cb6a..7794bc247 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "html-entities": "^1.2.0", "matchdep": "^1.0.0", "mustache": "^2.2.0", - "handlebars": "^4.0.5" + "handlebars": "^4.0.5", + "underscore": "^1.8.3" }, "devDependencies": { "bs-html-injector": "^3.0.0", From 86ae2269127acca2fb3fa49b8d6d8ed9708ff5ef Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Fri, 26 Feb 2016 11:09:30 -0600 Subject: [PATCH 070/187] Don't run handlebars unit tests if handlebars isn't installed --- test/engine_handlebars_tests.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/engine_handlebars_tests.js b/test/engine_handlebars_tests.js index 0f4f27ff5..b0ce74b90 100644 --- a/test/engine_handlebars_tests.js +++ b/test/engine_handlebars_tests.js @@ -10,6 +10,13 @@ var object_factory = require('../builder/object_factory'); var testPatternsPath = path.resolve(__dirname, 'files', '_handlebars-test-patterns'); + try { + require('handlebars'); + } catch (err) { + console.log('handlebars renderer not installed; skipping tests'); + return; + } + // fake pattern lab constructor: // sets up a fake patternlab object, which is needed by the pattern processing // apparatus. From d3df3a38285ef77b5ffa99052605467887787ad0 Mon Sep 17 00:00:00 2001 From: "Ghoweri, Salem (BOS-GEN)" Date: Mon, 29 Feb 2016 18:04:30 -0500 Subject: [PATCH 071/187] Stashing changes - working Twig template includes! --- builder/pattern_engines/engine_twig.js | 86 +++++++++++++++++++ source/_patterns/00-atoms/08-button.twig | 10 +++ source/_patterns/00-atoms/09-image.twig | 5 ++ .../_patterns/01-molecules/media-object.twig | 21 +++++ 4 files changed, 122 insertions(+) create mode 100644 builder/pattern_engines/engine_twig.js create mode 100644 source/_patterns/00-atoms/08-button.twig create mode 100644 source/_patterns/00-atoms/09-image.twig create mode 100644 source/_patterns/01-molecules/media-object.twig diff --git a/builder/pattern_engines/engine_twig.js b/builder/pattern_engines/engine_twig.js new file mode 100644 index 000000000..db6a309c3 --- /dev/null +++ b/builder/pattern_engines/engine_twig.js @@ -0,0 +1,86 @@ +/* + * handlebars pattern engine for patternlab-node - v0.15.1 - 2015 + * + * Geoffrey Pursell, Brian Muenzenmeyer, and the web community. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * + */ + +/* + * ENGINE SUPPORT LEVEL: + * + * Full. Partial calls and lineage hunting are supported. Handlebars does not + * support the mustache-specific syntax extensions, style modifiers and pattern + * parameters, because their use cases are addressed by the core Handlebars + * feature set. + * + */ + +(function () { + "use strict"; + + var Twig = require('twig/twig.js'); + var twig = Twig.twig; + + var engine_twig = { + engine: Twig, + engineName: 'twig', + engineFileExtension: '.twig', + + //Important! Needed for Twig compilation. Can't resolve paths otherwise. + expandPartials: true, + + // regexes, stored here so they're only compiled once + findPartialsRE: /{%([ ]+)?(?:extends|include|embed)(\s\S)(.*)%}/g, + findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, + + // render it + renderPattern: function renderPattern(template, data) { + var template = twig({ + data: template + }).render(data); + + return template; + }, + + // find and return any {{> template-name }} within pattern + findPartials: function findPartials(pattern) { + var matches = pattern.template.match(this.findPartialsRE); + return matches; + }, + findPartialsWithStyleModifiers: function() { + // TODO: make the call to this from oPattern objects conditional on their + // being implemented here. + return []; + }, + // returns any patterns that match {{> value(foo:"bar") }} or {{> + // value:mod(foo:"bar") }} within the pattern + findPartialsWithPatternParameters: function() { + // TODO: make the call to this from oPattern objects conditional on their + // being implemented here. + return []; + }, + findListItems: function(pattern) { + var matches = pattern.template.match(this.findListItemsRE); + return matches; + }, + // given a pattern, and a partial string, tease out the "pattern key" and + // return it. + findPartialKey: function(partialString) { + + // var partialKey = partialString.replace(this.findPartialsRE, '$1'); + var partialKey = partialString.match(/"((?:\\.|[^"\\])*)"/)[0]; + partialKey = partialKey.replace(/"/g, ''); + + return partialKey; + } + + + + + }; + + module.exports = engine_twig; +})(); diff --git a/source/_patterns/00-atoms/08-button.twig b/source/_patterns/00-atoms/08-button.twig new file mode 100644 index 000000000..cf0041685 --- /dev/null +++ b/source/_patterns/00-atoms/08-button.twig @@ -0,0 +1,10 @@ + + +Button diff --git a/source/_patterns/00-atoms/09-image.twig b/source/_patterns/00-atoms/09-image.twig new file mode 100644 index 000000000..01c4af9f8 --- /dev/null +++ b/source/_patterns/00-atoms/09-image.twig @@ -0,0 +1,5 @@ + diff --git a/source/_patterns/01-molecules/media-object.twig b/source/_patterns/01-molecules/media-object.twig new file mode 100644 index 000000000..2cd089f73 --- /dev/null +++ b/source/_patterns/01-molecules/media-object.twig @@ -0,0 +1,21 @@ + + + +
+ {% include "atoms-image" %} +

Media Object body text

+
From e5448f099ee7dc1590cc75f39369eefffe85ec96 Mon Sep 17 00:00:00 2001 From: e2tha-e Date: Tue, 1 Mar 2016 06:58:11 -0500 Subject: [PATCH 072/187] a more accurate docblock --- builder/pattern_engines/engine_mustache.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/builder/pattern_engines/engine_mustache.js b/builder/pattern_engines/engine_mustache.js index 32c1d6c78..3ebaedf00 100644 --- a/builder/pattern_engines/engine_mustache.js +++ b/builder/pattern_engines/engine_mustache.js @@ -47,12 +47,15 @@ return Mustache.render(template, data); }, - // find partials based on regex. - // @param {string|object} pattern - either a string or a pattern object. - // @param {object} regex - a JavaScript RegExp object. - // @returns {array} + /** + * Find partials based on regex. + * + * @param {string|object} pattern Either a string or a pattern object. + * @param {object} regex A JavaScript RegExp object. + * @returns {array|null} An array if a match is found, null if not. + */ partialsFinder: function partialsFinder(pattern, regex){ - var matches = []; + var matches; if(typeof pattern === 'string'){ matches = pattern.match(regex); From 4f6ee8158f51434fe34b96af07fe2983b22da366 Mon Sep 17 00:00:00 2001 From: "Ghoweri, Salem (BOS-GEN)" Date: Tue, 1 Mar 2016 09:33:37 -0500 Subject: [PATCH 073/187] -Adding Grunt dependencies to run the PL Twig engine as well -Fixing Grunt watch task to watch all file deps inside of the _patterns folder vs just mustache and json files -Cleaning up missing Gulp dependencies, Twig Media object example --- Gruntfile.js | 4 ++-- builder/pattern_engines/engine_twig.js | 5 +++-- package.gulp.json | 5 ++++- package.json | 3 ++- source/_patterns/01-molecules/media-object.twig | 12 +++++++++++- 5 files changed, 22 insertions(+), 7 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 06c6cf6d2..74787c4d9 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -80,8 +80,8 @@ module.exports = function(grunt) { files: [ path.resolve(paths().source.css + '**/*.css'), path.resolve(paths().source.styleguide + 'css/*.css'), - path.resolve(paths().source.patterns + '**/*.mustache'), - path.resolve(paths().source.patterns + '**/*.json'), + path.resolve(paths().source.patterns + '**/*'), + // path.resolve(paths().source.patterns + '**/*.json'), path.resolve(paths().source.fonts + '/*'), path.resolve(paths().source.images + '/*'), path.resolve(paths().source.data + '*.json') diff --git a/builder/pattern_engines/engine_twig.js b/builder/pattern_engines/engine_twig.js index db6a309c3..a8357e539 100644 --- a/builder/pattern_engines/engine_twig.js +++ b/builder/pattern_engines/engine_twig.js @@ -34,7 +34,7 @@ // regexes, stored here so they're only compiled once findPartialsRE: /{%([ ]+)?(?:extends|include|embed)(\s\S)(.*)%}/g, - findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, + findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, // TODO // render it renderPattern: function renderPattern(template, data) { @@ -70,7 +70,8 @@ // return it. findPartialKey: function(partialString) { - // var partialKey = partialString.replace(this.findPartialsRE, '$1'); + + //var partialKey = partialString.replace(this.findPartialsRE, '$1'); var partialKey = partialString.match(/"((?:\\.|[^"\\])*)"/)[0]; partialKey = partialKey.replace(/"/g, ''); diff --git a/package.gulp.json b/package.gulp.json index 9130aca63..221f4ea1f 100644 --- a/package.gulp.json +++ b/package.gulp.json @@ -9,7 +9,10 @@ "fs-extra": "^0.26.5", "glob": "^7.0.0", "html-entities": "^1.2.0", - "mustache": "^2.2.1" + "mustache": "^2.2.1", + "handlebars": "^4.0.5", + "twig": "^0.8.8", + "underscore": "^1.8.3", }, "devDependencies": { "browser-sync": "^2.11.1", diff --git a/package.json b/package.json index 7794bc247..b97e3d0d5 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "matchdep": "^1.0.0", "mustache": "^2.2.0", "handlebars": "^4.0.5", - "underscore": "^1.8.3" + "underscore": "^1.8.3", + "twig": "^0.8.8" }, "devDependencies": { "bs-html-injector": "^3.0.0", diff --git a/source/_patterns/01-molecules/media-object.twig b/source/_patterns/01-molecules/media-object.twig index 2cd089f73..532e0c6db 100644 --- a/source/_patterns/01-molecules/media-object.twig +++ b/source/_patterns/01-molecules/media-object.twig @@ -15,7 +15,17 @@ +{% set foo = "world!" %} + +
{% include "atoms-image" %} -

Media Object body text

+ +
+ + {# Testing if we can also pull in non-twig templates without breaking anything (it works!). Good idea though? Eh... #} + {% include "atoms-paragraph" %} + +

Oh, hello {{ foo }}

+
From bbc2c161945ac6f21b74438d5010f82e56a4763a Mon Sep 17 00:00:00 2001 From: "Ghoweri, Salem (BOS-GEN)" Date: Tue, 1 Mar 2016 09:41:11 -0500 Subject: [PATCH 074/187] Re-fixing pattern globbing to watch everything inside of the pattern directory (vs just mustache and json files) --- Gruntfile.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 2dfa9be8a..588f309a7 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -84,8 +84,7 @@ module.exports = function (grunt) { files: [ path.resolve(paths().source.css + '**/*.css'), path.resolve(paths().source.styleguide + 'css/*.css'), - path.resolve(paths().source.patterns + '**/*.mustache'), - path.resolve(paths().source.patterns + '**/*.json'), + path.resolve(paths().source.patterns + '**/*'), path.resolve(paths().source.fonts + '/*'), path.resolve(paths().source.images + '/*'), path.resolve(paths().source.data + '*.json') From ebba8de57e10f2840903652ec9a8667ac4b527bd Mon Sep 17 00:00:00 2001 From: e2tha-e Date: Thu, 3 Mar 2016 06:49:19 -0500 Subject: [PATCH 075/187] updating function name and description --- builder/pattern_engines/engine_mustache.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/builder/pattern_engines/engine_mustache.js b/builder/pattern_engines/engine_mustache.js index 3ebaedf00..d845a069c 100644 --- a/builder/pattern_engines/engine_mustache.js +++ b/builder/pattern_engines/engine_mustache.js @@ -48,13 +48,13 @@ }, /** - * Find partials based on regex. + * Find regex matches within both pattern strings and pattern objects. * * @param {string|object} pattern Either a string or a pattern object. * @param {object} regex A JavaScript RegExp object. * @returns {array|null} An array if a match is found, null if not. */ - partialsFinder: function partialsFinder(pattern, regex){ + patternMatcher: function patternMatcher(pattern, regex){ var matches; if(typeof pattern === 'string'){ @@ -67,21 +67,21 @@ }, // find and return any {{> template-name }} within pattern findPartials: function findPartials(pattern) { - var matches = this.partialsFinder(pattern, this.findPartialsRE); + var matches = this.patternMatcher(pattern, this.findPartialsRE); return matches; }, findPartialsWithStyleModifiers: function(pattern) { - var matches = this.partialsFinder(pattern, this.findPartialsWithStyleModifiersRE); + var matches = this.patternMatcher(pattern, this.findPartialsWithStyleModifiersRE); return matches; }, // returns any patterns that match {{> value(foo:"bar") }} or {{> // value:mod(foo:"bar") }} within the pattern findPartialsWithPatternParameters: function(pattern) { - var matches = this.partialsFinder(pattern, this.findPartialsWithPatternParametersRE); + var matches = this.patternMatcher(pattern, this.findPartialsWithPatternParametersRE); return matches; }, findListItems: function(pattern) { - var matches = this.partialsFinder(pattern, this.findListItemsRE); + var matches = this.patternMatcher(pattern, this.findListItemsRE); return matches; }, // given a pattern, and a partial string, tease out the "pattern key" and From d7a3846a7bd7d3674e6719f88e41e116b40bcc27 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Mon, 7 Mar 2016 13:55:07 -0600 Subject: [PATCH 076/187] move pattern engines and utilities to the new core/lib location and fix stray references to changed paths --- {builder => core/lib}/pattern_engines/engine_handlebars.js | 0 {builder => core/lib}/pattern_engines/engine_mustache.js | 0 {builder => core/lib}/pattern_engines/engine_underscore.js | 0 {builder => core/lib}/pattern_engines/pattern_engines.js | 0 {builder => core/lib}/pattern_engines/util_mustache.js | 0 {builder => core/lib}/utilities.js | 0 gulpfile.js | 2 +- test/engine_handlebars_tests.js | 6 +++--- test/engine_underscore_tests.js | 4 ++-- test/pattern_engines_tests.js | 6 +++--- 10 files changed, 9 insertions(+), 9 deletions(-) rename {builder => core/lib}/pattern_engines/engine_handlebars.js (100%) rename {builder => core/lib}/pattern_engines/engine_mustache.js (100%) rename {builder => core/lib}/pattern_engines/engine_underscore.js (100%) rename {builder => core/lib}/pattern_engines/pattern_engines.js (100%) rename {builder => core/lib}/pattern_engines/util_mustache.js (100%) rename {builder => core/lib}/utilities.js (100%) diff --git a/builder/pattern_engines/engine_handlebars.js b/core/lib/pattern_engines/engine_handlebars.js similarity index 100% rename from builder/pattern_engines/engine_handlebars.js rename to core/lib/pattern_engines/engine_handlebars.js diff --git a/builder/pattern_engines/engine_mustache.js b/core/lib/pattern_engines/engine_mustache.js similarity index 100% rename from builder/pattern_engines/engine_mustache.js rename to core/lib/pattern_engines/engine_mustache.js diff --git a/builder/pattern_engines/engine_underscore.js b/core/lib/pattern_engines/engine_underscore.js similarity index 100% rename from builder/pattern_engines/engine_underscore.js rename to core/lib/pattern_engines/engine_underscore.js diff --git a/builder/pattern_engines/pattern_engines.js b/core/lib/pattern_engines/pattern_engines.js similarity index 100% rename from builder/pattern_engines/pattern_engines.js rename to core/lib/pattern_engines/pattern_engines.js diff --git a/builder/pattern_engines/util_mustache.js b/core/lib/pattern_engines/util_mustache.js similarity index 100% rename from builder/pattern_engines/util_mustache.js rename to core/lib/pattern_engines/util_mustache.js diff --git a/builder/utilities.js b/core/lib/utilities.js similarity index 100% rename from builder/utilities.js rename to core/lib/utilities.js diff --git a/gulpfile.js b/gulpfile.js index 80493a3a4..0907f51be 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -109,7 +109,7 @@ gulp.task('cp:styleguide', function(){ // watch task utility functions function getSupportedTemplateExtensions() { - var engines = require('./builder/pattern_engines/pattern_engines'); + var engines = require('./core/lib/pattern_engines/pattern_engines'); return engines.getSupportedFileExtensions(); } function getTemplateWatches() { diff --git a/test/engine_handlebars_tests.js b/test/engine_handlebars_tests.js index b0ce74b90..b59fd3e88 100644 --- a/test/engine_handlebars_tests.js +++ b/test/engine_handlebars_tests.js @@ -6,8 +6,8 @@ catch (err) { return; } var path = require('path'); - var pa = require('../builder/pattern_assembler'); - var object_factory = require('../builder/object_factory'); + var pa = require('../core/lib/pattern_assembler'); + var object_factory = require('../core/lib/object_factory'); var testPatternsPath = path.resolve(__dirname, 'files', '_handlebars-test-patterns'); try { @@ -31,7 +31,7 @@ data: { link: {} }, - config: require('../config.json'), + config: require('../patternlab-config.json'), package: {} }; diff --git a/test/engine_underscore_tests.js b/test/engine_underscore_tests.js index d03779e79..0bea4b17b 100644 --- a/test/engine_underscore_tests.js +++ b/test/engine_underscore_tests.js @@ -2,7 +2,7 @@ "use strict"; var path = require('path'); - var pa = require('../builder/pattern_assembler'); + var pa = require('../core/lib/pattern_assembler'); var testPatternsPath = path.resolve(__dirname, 'files', '_underscore-test-patterns'); try { @@ -26,7 +26,7 @@ data: { link: {} }, - config: require('../config.json'), + config: require('../patternlab-config.json'), package: {} }; diff --git a/test/pattern_engines_tests.js b/test/pattern_engines_tests.js index f298d1fc0..479cc1ddf 100644 --- a/test/pattern_engines_tests.js +++ b/test/pattern_engines_tests.js @@ -1,8 +1,8 @@ (function () { 'use strict'; - var patternEngines = require('../builder/pattern_engines/pattern_engines'); - var of = require('../builder/object_factory'); + var patternEngines = require('../core/lib/pattern_engines/pattern_engines'); + var of = require('../core/lib/object_factory'); // the mustache test pattern, stolen from object_factory unit tests var mustacheTestPattern = new of.oPattern('source/_patterns/00-atoms/00-global/00-colors-alt.mustache', '00-atoms/00-global', '00-colors-alt.mustache', {d: 123}); @@ -116,7 +116,7 @@ }).reduce(function(isPrevType, isCurrentType) { return isPrevType || isCurrentType; }); - + test.ok(object.hasOwnProperty(propName), '"' + propName + '" prop should be present'); test.ok(isOneOfTheseTypes, '"' + propName + '" prop should be one of types ' + possibleTypes); } From 0a4f6ee30feb32684ff49866b2fbd22776b0caf5 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Mon, 7 Mar 2016 16:25:05 -0600 Subject: [PATCH 077/187] Fix a total misinterpretation of underscore-prefixed patterns: they're not supposed to be completely excluded from processing, they're just supposed to not appear in the nav, styleguide, or view all views. Per http://patternlab.io/docs/pattern-hiding.html --- core/lib/pattern_engines/pattern_engines.js | 3 +-- test/pattern_engines_tests.js | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/core/lib/pattern_engines/pattern_engines.js b/core/lib/pattern_engines/pattern_engines.js index 2968de9a8..c8d7d50ed 100644 --- a/core/lib/pattern_engines/pattern_engines.js +++ b/core/lib/pattern_engines/pattern_engines.js @@ -152,8 +152,7 @@ isPatternFile: function (filename) { // skip hidden patterns/files without a second thought var extension = path.extname(filename); - if(filename.charAt(0) === '.' || - filename.charAt(0) === '_' || + if (filename.charAt(0) === '.' || (extension === '.json' && !PatternEngines.isPseudoPatternJSON(filename))) { return false; } diff --git a/test/pattern_engines_tests.js b/test/pattern_engines_tests.js index 479cc1ddf..60229b357 100644 --- a/test/pattern_engines_tests.js +++ b/test/pattern_engines_tests.js @@ -71,7 +71,7 @@ '00-comment-thread.mustache': true, '00-comment-thread.fakeextthatdoesntexist': false, '00-comment-thread': false, - '_00-comment-thread.mustache': false, + '_00-comment-thread.mustache': true, '.00-comment-thread.mustache': false, '00-comment-thread.json': false, '00-homepage~emergency.json': true From 8eee29a8b929051478875d3be8586428e9df6625 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 8 Mar 2016 13:42:03 -0600 Subject: [PATCH 078/187] tell the linter to chill out about some things --- .eslintrc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.eslintrc b/.eslintrc index d52103feb..6e83375f1 100644 --- a/.eslintrc +++ b/.eslintrc @@ -14,8 +14,8 @@ "eqeqeq": [2, "allow-null"], "global-strict": [0, "never"], "guard-for-in": 2, - "indent": [2, 2, {"SwitchCase": 1, "VariableDeclarator": 1}], - "lines-around-comment": [2, { + "indent": [1, 2, {"SwitchCase": 1, "VariableDeclarator": 1}], + "lines-around-comment": [1, { "beforeBlockComment": true, "beforeLineComment": true, "allowBlockStart": true, From 875f26e650fd35cf7cff6aeb237cc48d85577e86 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 8 Mar 2016 13:42:47 -0600 Subject: [PATCH 079/187] code cleanups and linter appeasement --- core/lib/object_factory.js | 3 +- core/lib/parameter_hunter.js | 358 +++++++------- core/lib/pattern_assembler.js | 115 ++--- core/lib/pattern_engines/engine_handlebars.js | 108 ++--- core/lib/pattern_engines/engine_mustache.js | 179 +++---- core/lib/pattern_engines/engine_underscore.js | 14 +- core/lib/pattern_engines/pattern_engines.js | 288 ++++++------ core/lib/pattern_engines/util_mustache.js | 272 ++++++----- core/lib/pseudopattern_hunter.js | 160 +++---- core/lib/utilities.js | 95 ++-- test/engine_handlebars_tests.js | 438 +++++++++--------- 11 files changed, 1025 insertions(+), 1005 deletions(-) diff --git a/core/lib/object_factory.js b/core/lib/object_factory.js index e6c2c272d..e5713e8fc 100644 --- a/core/lib/object_factory.js +++ b/core/lib/object_factory.js @@ -12,7 +12,6 @@ var patternEngines = require('./pattern_engines/pattern_engines'); var path = require('path'); -var fs = require('fs-extra'); var extend = require('util')._extend; // oPattern properties @@ -25,7 +24,7 @@ var oPattern = function (abspath, subdir, filename, data) { this.name = subdir.replace(/[\/\\]/g, '-') + '-' + this.fileName; //this is the unique name with the subDir this.jsonFileData = data || {}; this.patternName = this.fileName.replace(/^\d*\-/, ''); - this.patternDisplayName = this.patternName.split('-').reduce(function(val, working){ + this.patternDisplayName = this.patternName.split('-').reduce(function (val, working) { return val.charAt(0).toUpperCase() + val.slice(1) + ' ' + working.charAt(0).toUpperCase() + working.slice(1); }, '').trim(); //this is the display name for the ui. strip numeric + hyphen prefixes this.patternLink = this.name + '/' + this.name + '.html'; diff --git a/core/lib/parameter_hunter.js b/core/lib/parameter_hunter.js index d4ca4b640..57a460fe8 100644 --- a/core/lib/parameter_hunter.js +++ b/core/lib/parameter_hunter.js @@ -1,190 +1,190 @@ -/* - * patternlab-node - v1.1.3 - 2016 - * +/* + * patternlab-node - v1.1.3 - 2016 + * * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ - "use strict"; +"use strict"; - var parameter_hunter = function(){ +var parameter_hunter = function () { - var extend = require('util')._extend, - pa = require('./pattern_assembler'), - smh = require('./style_modifier_hunter'), - plutils = require('./utilities'), - style_modifier_hunter = new smh(), - pattern_assembler = new pa(); + var extend = require('util')._extend, + pa = require('./pattern_assembler'), + smh = require('./style_modifier_hunter'), + plutils = require('./utilities'), + style_modifier_hunter = new smh(), + pattern_assembler = new pa(); function paramToJson(pString) { - var paramStringWellFormed = ''; - var paramStringTmp; - var colonPos; - var delimitPos; - var quotePos; + var paramStringWellFormed = ''; + var paramStringTmp; + var colonPos; + var delimitPos; + var quotePos; var paramString = pString; - do { - - //if param key is wrapped in single quotes, replace with double quotes. - paramString = paramString.replace(/(^\s*[\{|\,]\s*)'([^']+)'(\s*\:)/, '$1"$2"$3'); - - //if params key is not wrapped in any quotes, wrap in double quotes. - paramString = paramString.replace(/(^\s*[\{|\,]\s*)([^\s"'\:]+)(\s*\:)/, '$1"$2"$3'); - - //move param key to paramStringWellFormed var. - colonPos = paramString.indexOf(':'); - - //except to prevent infinite loops. - if (colonPos === -1) { - colonPos = paramString.length - 1; - } - else { - colonPos += 1; - } - paramStringWellFormed += paramString.substring(0, colonPos); - paramString = paramString.substring(colonPos, paramString.length).trim(); - - //if param value is wrapped in single quotes, replace with double quotes. - if (paramString[0] === '\'') { - quotePos = paramString.search(/[^\\]'/); - - //except for unclosed quotes to prevent infinite loops. - if (quotePos === -1) { - quotePos = paramString.length - 1; - } - else { - quotePos += 2; - } - - //prepare param value for move to paramStringWellFormed var. - paramStringTmp = paramString.substring(0, quotePos); - - //unescape any escaped single quotes. - paramStringTmp = paramStringTmp.replace(/\\'/g, '\''); - - //escape any double quotes. - paramStringTmp = paramStringTmp.replace(/"/g, '\\"'); - - //replace the delimiting single quotes with double quotes. - paramStringTmp = paramStringTmp.replace(/^'/, '"'); - paramStringTmp = paramStringTmp.replace(/'$/, '"'); - - //move param key to paramStringWellFormed var. - paramStringWellFormed += paramStringTmp; - paramString = paramString.substring(quotePos, paramString.length).trim(); - } - - //if param value is wrapped in double quotes, just move to paramStringWellFormed var. - else if (paramString[0] === '"') { - quotePos = paramString.search(/[^\\]"/); - - //except for unclosed quotes to prevent infinite loops. - if (quotePos === -1) { - quotePos = paramString.length - 1; - } - else { - quotePos += 2; - } - - //move param key to paramStringWellFormed var. - paramStringWellFormed += paramString.substring(0, quotePos); - paramString = paramString.substring(quotePos, paramString.length).trim(); - } - - //if param value is not wrapped in quotes, move everthing up to the delimiting comma to paramStringWellFormed var. - else { - delimitPos = paramString.indexOf(','); - - //except to prevent infinite loops. - if (delimitPos === -1) { - delimitPos = paramString.length - 1; - } - else { - delimitPos += 1; - } - paramStringWellFormed += paramString.substring(0, delimitPos); - paramString = paramString.substring(delimitPos, paramString.length).trim(); - } - - //break at the end. - if (paramString.length === 1) { - paramStringWellFormed += paramString.trim(); - paramString = ''; - break; - } - - } while(paramString); - - return paramStringWellFormed; - } - - function findparameters(pattern, patternlab){ - - if(pattern.parameteredPartials && pattern.parameteredPartials.length > 0){ - - //compile this partial immeadiately, essentially consuming it. + do { + + //if param key is wrapped in single quotes, replace with double quotes. + paramString = paramString.replace(/(^\s*[\{|\,]\s*)'([^']+)'(\s*\:)/, '$1"$2"$3'); + + //if params key is not wrapped in any quotes, wrap in double quotes. + paramString = paramString.replace(/(^\s*[\{|\,]\s*)([^\s"'\:]+)(\s*\:)/, '$1"$2"$3'); + + //move param key to paramStringWellFormed var. + colonPos = paramString.indexOf(':'); + + //except to prevent infinite loops. + if (colonPos === -1) { + colonPos = paramString.length - 1; + } + else { + colonPos += 1; + } + paramStringWellFormed += paramString.substring(0, colonPos); + paramString = paramString.substring(colonPos, paramString.length).trim(); + + //if param value is wrapped in single quotes, replace with double quotes. + if (paramString[0] === '\'') { + quotePos = paramString.search(/[^\\]'/); + + //except for unclosed quotes to prevent infinite loops. + if (quotePos === -1) { + quotePos = paramString.length - 1; + } + else { + quotePos += 2; + } + + //prepare param value for move to paramStringWellFormed var. + paramStringTmp = paramString.substring(0, quotePos); + + //unescape any escaped single quotes. + paramStringTmp = paramStringTmp.replace(/\\'/g, '\''); + + //escape any double quotes. + paramStringTmp = paramStringTmp.replace(/"/g, '\\"'); + + //replace the delimiting single quotes with double quotes. + paramStringTmp = paramStringTmp.replace(/^'/, '"'); + paramStringTmp = paramStringTmp.replace(/'$/, '"'); + + //move param key to paramStringWellFormed var. + paramStringWellFormed += paramStringTmp; + paramString = paramString.substring(quotePos, paramString.length).trim(); + } + + //if param value is wrapped in double quotes, just move to paramStringWellFormed var. + else if (paramString[0] === '"') { + quotePos = paramString.search(/[^\\]"/); + + //except for unclosed quotes to prevent infinite loops. + if (quotePos === -1) { + quotePos = paramString.length - 1; + } + else { + quotePos += 2; + } + + //move param key to paramStringWellFormed var. + paramStringWellFormed += paramString.substring(0, quotePos); + paramString = paramString.substring(quotePos, paramString.length).trim(); + } + + //if param value is not wrapped in quotes, move everthing up to the delimiting comma to paramStringWellFormed var. + else { + delimitPos = paramString.indexOf(','); + + //except to prevent infinite loops. + if (delimitPos === -1) { + delimitPos = paramString.length - 1; + } + else { + delimitPos += 1; + } + paramStringWellFormed += paramString.substring(0, delimitPos); + paramString = paramString.substring(delimitPos, paramString.length).trim(); + } + + //break at the end. + if (paramString.length === 1) { + paramStringWellFormed += paramString.trim(); + paramString = ''; + break; + } + + } while (paramString); + + return paramStringWellFormed; + } + + function findparameters(pattern, patternlab) { + + if (pattern.parameteredPartials && pattern.parameteredPartials.length > 0) { + + //compile this partial immeadiately, essentially consuming it. pattern.parameteredPartials.forEach(function (pMatch) { - //find the partial's name and retrieve it - var partialName = pMatch.match(/([\w\-\.\/~]+)/g)[0]; - var partialPattern = pattern_assembler.get_pattern_by_key(partialName, patternlab); - - //if we retrieved a pattern we should make sure that its extendedTemplate is reset. looks to fix #190 - partialPattern.extendedTemplate = partialPattern.template; - - if(patternlab.config.debug){ - console.log('found patternParameters for ' + partialName); - } - - //strip out the additional data, convert string to JSON. - var leftParen = pMatch.indexOf('('); - var rightParen = pMatch.indexOf(')'); - var paramString = '{' + pMatch.substring(leftParen + 1, rightParen) + '}'; - var paramStringWellFormed = paramToJson(paramString); - - var paramData = {}; - var globalData = {}; - var localData = {}; - - try { - paramData = JSON.parse(paramStringWellFormed); - globalData = JSON.parse(JSON.stringify(patternlab.data)); - localData = JSON.parse(JSON.stringify(pattern.jsonFileData || {})); - } catch(e){ - console.log(e); - } - - var allData = plutils.mergeData(globalData, localData); - allData = plutils.mergeData(allData, paramData); - - //if partial has style modifier data, replace the styleModifier value - if(pattern.stylePartials && pattern.stylePartials.length > 0){ - style_modifier_hunter.consume_style_modifier(partialPattern, pMatch, patternlab); - } - - //extend pattern data links into link for pattern link shortcuts to work. we do this locally and globally - allData.link = extend({}, patternlab.data.link); - - var renderedPartial = pattern_assembler.renderPattern(partialPattern.extendedTemplate, allData, patternlab.partials); - - //remove the parameter from the partial and replace it with the rendered partial + paramData - pattern.extendedTemplate = pattern.extendedTemplate.replace(pMatch, renderedPartial); - - //update the extendedTemplate in the partials object in case this pattern is consumed later - patternlab.partials[pattern.key] = pattern.extendedTemplate; - }); - } - } - - return { - find_parameters: function(pattern, patternlab){ - findparameters(pattern, patternlab); - } - }; - - }; - - module.exports = parameter_hunter; + //find the partial's name and retrieve it + var partialName = pMatch.match(/([\w\-\.\/~]+)/g)[0]; + var partialPattern = pattern_assembler.get_pattern_by_key(partialName, patternlab); + + //if we retrieved a pattern we should make sure that its extendedTemplate is reset. looks to fix #190 + partialPattern.extendedTemplate = partialPattern.template; + + if (patternlab.config.debug) { + console.log('found patternParameters for ' + partialName); + } + + //strip out the additional data, convert string to JSON. + var leftParen = pMatch.indexOf('('); + var rightParen = pMatch.indexOf(')'); + var paramString = '{' + pMatch.substring(leftParen + 1, rightParen) + '}'; + var paramStringWellFormed = paramToJson(paramString); + + var paramData = {}; + var globalData = {}; + var localData = {}; + + try { + paramData = JSON.parse(paramStringWellFormed); + globalData = JSON.parse(JSON.stringify(patternlab.data)); + localData = JSON.parse(JSON.stringify(pattern.jsonFileData || {})); + } catch (e) { + console.log(e); + } + + var allData = plutils.mergeData(globalData, localData); + allData = plutils.mergeData(allData, paramData); + + //if partial has style modifier data, replace the styleModifier value + if (pattern.stylePartials && pattern.stylePartials.length > 0) { + style_modifier_hunter.consume_style_modifier(partialPattern, pMatch, patternlab); + } + + //extend pattern data links into link for pattern link shortcuts to work. we do this locally and globally + allData.link = extend({}, patternlab.data.link); + + var renderedPartial = pattern_assembler.renderPattern(partialPattern.extendedTemplate, allData, patternlab.partials); + + //remove the parameter from the partial and replace it with the rendered partial + paramData + pattern.extendedTemplate = pattern.extendedTemplate.replace(pMatch, renderedPartial); + + //update the extendedTemplate in the partials object in case this pattern is consumed later + patternlab.partials[pattern.key] = pattern.extendedTemplate; + }); + } + } + + return { + find_parameters: function (pattern, patternlab) { + findparameters(pattern, patternlab); + } + }; + +}; + +module.exports = parameter_hunter; diff --git a/core/lib/pattern_assembler.js b/core/lib/pattern_assembler.js index d02b929ac..d095b6392 100644 --- a/core/lib/pattern_assembler.js +++ b/core/lib/pattern_assembler.js @@ -18,6 +18,64 @@ var pattern_assembler = function () { plutils = require('./utilities'), patternEngines = require('./pattern_engines/pattern_engines'); + + // HELPER FUNCTIONS + + function getpatternbykey(key, patternlab) { + + //look for exact key matches + for (var i = 0; i < patternlab.patterns.length; i++) { + if (patternlab.patterns[i].key === key) { + return patternlab.patterns[i]; + } + } + + //else look by verbose syntax + for (var i = 0; i < patternlab.patterns.length; i++) { + switch (key) { + case patternlab.patterns[i].subdir + '/' + patternlab.patterns[i].fileName: + case patternlab.patterns[i].subdir + '/' + patternlab.patterns[i].fileName + '.mustache': + return patternlab.patterns[i]; + } + } + + //return the fuzzy match if all else fails + for (var i = 0; i < patternlab.patterns.length; i++) { + var keyParts = key.split('-'), + keyType = keyParts[0], + keyName = keyParts.slice(1).join('-'); + + if (patternlab.patterns[i].key.split('-')[0] === keyType && patternlab.patterns[i].key.indexOf(keyName) > -1) { + return patternlab.patterns[i]; + } + } + throw 'Could not find pattern with key ' + key; + } + + function buildListItems(container) { + //combine all list items into one structure + var list = []; + for (var item in container.listitems) { + if (container.listitems.hasOwnProperty(item)) { + list.push(container.listitems[item]); + } + } + container.listItemArray = plutils.shuffle(list); + + for (var i = 1; i <= container.listItemArray.length; i++) { + var tempItems = []; + if (i === 1) { + tempItems.push(container.listItemArray[0]); + container.listitems['' + i ] = tempItems; + } else { + for (var c = 1; c <= i; c++) { + tempItems.push(container.listItemArray[c - 1]); + container.listitems['' + i ] = tempItems; + } + } + } + } + function setState(pattern, patternlab) { if (patternlab.config.patternStates && patternlab.config.patternStates[pattern.patternName]) { pattern.patternState = patternlab.config.patternStates[pattern.patternName]; @@ -227,63 +285,6 @@ var pattern_assembler = function () { pseudopattern_hunter.find_pseudopatterns(currentPattern, patternlab); } - function getpatternbykey(key, patternlab) { - - //look for exact key matches - for (var i = 0; i < patternlab.patterns.length; i++) { - if (patternlab.patterns[i].key === key) { - return patternlab.patterns[i]; - } - } - - //else look by verbose syntax - for (var i = 0; i < patternlab.patterns.length; i++) { - switch (key) { - case patternlab.patterns[i].subdir + '/' + patternlab.patterns[i].fileName: - case patternlab.patterns[i].subdir + '/' + patternlab.patterns[i].fileName + '.mustache': - return patternlab.patterns[i]; - } - } - - //return the fuzzy match if all else fails - for (var i = 0; i < patternlab.patterns.length; i++) { - var keyParts = key.split('-'), - keyType = keyParts[0], - keyName = keyParts.slice(1).join('-'); - if (patternlab.patterns[i].key.split('-')[0] === keyType && patternlab.patterns[i].key.indexOf(keyName) > -1) { - return patternlab.patterns[i]; - } - } - throw 'Could not find pattern with key ' + key; - } - - - - function buildListItems(container) { - //combine all list items into one structure - var list = []; - for (var item in container.listitems) { - if (container.listitems.hasOwnProperty(item)) { - list.push(container.listitems[item]); - } - } - container.listItemArray = plutils.shuffle(list); - - for (var i = 1; i <= container.listItemArray.length; i++) { - var tempItems = []; - if (i === 1) { - tempItems.push(container.listItemArray[0]); - container.listitems['' + i ] = tempItems; - } else { - for (var c = 1; c <= i; c++) { - tempItems.push(container.listItemArray[c - 1]); - container.listitems['' + i ] = tempItems; - } - } - } - } - - function parseDataLinksHelper(patternlab, obj, key) { var linkRE, dataObjAsString, linkMatches, expandedLink; diff --git a/core/lib/pattern_engines/engine_handlebars.js b/core/lib/pattern_engines/engine_handlebars.js index 627c1e29e..a986b6972 100644 --- a/core/lib/pattern_engines/engine_handlebars.js +++ b/core/lib/pattern_engines/engine_handlebars.js @@ -18,65 +18,65 @@ * */ -(function () { - "use strict"; +"use strict"; - var Handlebars = require('handlebars'); +var Handlebars = require('handlebars'); - var engine_handlebars = { - engine: Handlebars, - engineName: 'handlebars', - engineFileExtension: '.hbs', +var engine_handlebars = { + engine: Handlebars, + engineName: 'handlebars', + engineFileExtension: '.hbs', - // partial expansion is only necessary for Mustache templates that have - // style modifiers or pattern parameters (I think) - expandPartials: false, + // partial expansion is only necessary for Mustache templates that have + // style modifiers or pattern parameters (I think) + expandPartials: false, - // regexes, stored here so they're only compiled once - findPartialsRE: /{{#?>\s*([\w-\/.]+)(?:.|\s+)*?}}/g, - findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, + // regexes, stored here so they're only compiled once + findPartialsRE: /{{#?>\s*([\w-\/.]+)(?:.|\s+)*?}}/g, + findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, - // render it - renderPattern: function renderPattern(template, data, partials) { - if (partials) { - Handlebars.registerPartial(partials); - } - var compiled = Handlebars.compile(template); - return compiled(data); - }, + // render it + renderPattern: function renderPattern(template, data, partials) { + if (partials) { + Handlebars.registerPartial(partials); + } + var compiled = Handlebars.compile(template); + return compiled(data); + }, - registerPartial: function (oPattern) { - Handlebars.registerPartial(oPattern.key, oPattern.template); - }, + registerPartial: function (oPattern) { + Handlebars.registerPartial(oPattern.key, oPattern.template); + }, - // find and return any {{> template-name }} within pattern - findPartials: function findPartials(pattern) { - var matches = pattern.template.match(this.findPartialsRE); - return matches; - }, - findPartialsWithStyleModifiers: function() { - // TODO: make the call to this from oPattern objects conditional on their - // being implemented here. - return []; - }, - // returns any patterns that match {{> value(foo:"bar") }} or {{> - // value:mod(foo:"bar") }} within the pattern - findPartialsWithPatternParameters: function() { - // TODO: make the call to this from oPattern objects conditional on their - // being implemented here. - return []; - }, - findListItems: function(pattern) { - var matches = pattern.template.match(this.findListItemsRE); - return matches; - }, - // given a pattern, and a partial string, tease out the "pattern key" and - // return it. - findPartialKey: function(partialString) { - var partialKey = partialString.replace(this.findPartialsRE, '$1'); - return partialKey; - } - }; + // find and return any {{> template-name }} within pattern + findPartials: function findPartials(pattern) { + var matches = pattern.template.match(this.findPartialsRE); + return matches; + }, + findPartialsWithStyleModifiers: function () { + // TODO: make the call to this from oPattern objects conditional on their + // being implemented here. + return []; + }, + + // returns any patterns that match {{> value(foo:"bar") }} or {{> + // value:mod(foo:"bar") }} within the pattern + findPartialsWithPatternParameters: function () { + // TODO: make the call to this from oPattern objects conditional on their + // being implemented here. + return []; + }, + findListItems: function (pattern) { + var matches = pattern.template.match(this.findListItemsRE); + return matches; + }, + + // given a pattern, and a partial string, tease out the "pattern key" and + // return it. + findPartialKey: function (partialString) { + var partialKey = partialString.replace(this.findPartialsRE, '$1'); + return partialKey; + } +}; - module.exports = engine_handlebars; -})(); +module.exports = engine_handlebars; diff --git a/core/lib/pattern_engines/engine_mustache.js b/core/lib/pattern_engines/engine_mustache.js index 32c1d6c78..2607d6f4f 100644 --- a/core/lib/pattern_engines/engine_mustache.js +++ b/core/lib/pattern_engines/engine_mustache.js @@ -17,94 +17,95 @@ * */ -(function () { - "use strict"; - - var Mustache = require('mustache'); - var utilMustache = require('./util_mustache'); - - var engine_mustache = { - engine: Mustache, - engineName: 'mustache', - engineFileExtension: '.mustache', - - // partial expansion is only necessary for Mustache templates that have - // style modifiers or pattern parameters (I think) - expandPartials: true, - - // regexes, stored here so they're only compiled once - findPartialsRE: utilMustache.partialsRE, - findPartialsWithStyleModifiersRE: utilMustache.partialsWithStyleModifiersRE, - findPartialsWithPatternParametersRE: utilMustache.partialsWithPatternParametersRE, - findListItemsRE: utilMustache.listItemsRE, - findPartialKeyRE: utilMustache.partialKeyRE, - - // render it - renderPattern: function renderPattern(template, data, partials) { - if (partials) { - return Mustache.render(template, data, partials); - } - return Mustache.render(template, data); - }, - - // find partials based on regex. - // @param {string|object} pattern - either a string or a pattern object. - // @param {object} regex - a JavaScript RegExp object. - // @returns {array} - partialsFinder: function partialsFinder(pattern, regex){ - var matches = []; - - if(typeof pattern === 'string'){ - matches = pattern.match(regex); - } else if(typeof pattern === 'object' && typeof pattern.template === 'string'){ - matches = pattern.template.match(regex); - } - - return matches; - }, - // find and return any {{> template-name }} within pattern - findPartials: function findPartials(pattern) { - var matches = this.partialsFinder(pattern, this.findPartialsRE); - return matches; - }, - findPartialsWithStyleModifiers: function(pattern) { - var matches = this.partialsFinder(pattern, this.findPartialsWithStyleModifiersRE); - return matches; - }, - // returns any patterns that match {{> value(foo:"bar") }} or {{> - // value:mod(foo:"bar") }} within the pattern - findPartialsWithPatternParameters: function(pattern) { - var matches = this.partialsFinder(pattern, this.findPartialsWithPatternParametersRE); - return matches; - }, - findListItems: function(pattern) { - var matches = this.partialsFinder(pattern, this.findListItemsRE); - return matches; - }, - // given a pattern, and a partial string, tease out the "pattern key" and - // return it. - findPartialKey_new: function(partialString) { - var partialKey = partialString.replace(this.findPartialKeyRE, '$1'); - return partialKey; - }, - - // GTP: the old implementation works better. We might not need - // this.findPartialKeyRE anymore if it works in all cases! - findPartialKey: function(partialString) { - //strip out the template cruft - var foundPatternKey = partialString.replace("{{> ", "").replace(" }}", "").replace("{{>", "").replace("}}", ""); - - // remove any potential pattern parameters. this and the above are rather brutish but I didn't want to do a regex at the time - if(foundPatternKey.indexOf('(') > 0){ - foundPatternKey = foundPatternKey.substring(0, foundPatternKey.indexOf('(')); - } - - //remove any potential stylemodifiers. - foundPatternKey = foundPatternKey.split(':')[0]; - - return foundPatternKey; +"use strict"; + +var Mustache = require('mustache'); +var utilMustache = require('./util_mustache'); + +var engine_mustache = { + engine: Mustache, + engineName: 'mustache', + engineFileExtension: '.mustache', + + // partial expansion is only necessary for Mustache templates that have + // style modifiers or pattern parameters (I think) + expandPartials: true, + + // regexes, stored here so they're only compiled once + findPartialsRE: utilMustache.partialsRE, + findPartialsWithStyleModifiersRE: utilMustache.partialsWithStyleModifiersRE, + findPartialsWithPatternParametersRE: utilMustache.partialsWithPatternParametersRE, + findListItemsRE: utilMustache.listItemsRE, + findPartialKeyRE: utilMustache.partialKeyRE, + + // render it + renderPattern: function renderPattern(template, data, partials) { + if (partials) { + return Mustache.render(template, data, partials); } - }; + return Mustache.render(template, data); + }, + + // find partials based on regex. + // @param {string|object} pattern - either a string or a pattern object. + // @param {object} regex - a JavaScript RegExp object. + // @returns {array} + partialsFinder: function partialsFinder(pattern, regex) { + var matches = []; + + if (typeof pattern === 'string') { + matches = pattern.match(regex); + } else if (typeof pattern === 'object' && typeof pattern.template === 'string') { + matches = pattern.template.match(regex); + } + + return matches; + }, + + // find and return any {{> template-name }} within pattern + findPartials: function findPartials(pattern) { + var matches = this.partialsFinder(pattern, this.findPartialsRE); + return matches; + }, + findPartialsWithStyleModifiers: function (pattern) { + var matches = this.partialsFinder(pattern, this.findPartialsWithStyleModifiersRE); + return matches; + }, + + // returns any patterns that match {{> value(foo:"bar") }} or {{> + // value:mod(foo:"bar") }} within the pattern + findPartialsWithPatternParameters: function (pattern) { + var matches = this.partialsFinder(pattern, this.findPartialsWithPatternParametersRE); + return matches; + }, + findListItems: function (pattern) { + var matches = this.partialsFinder(pattern, this.findListItemsRE); + return matches; + }, + + // given a pattern, and a partial string, tease out the "pattern key" and + // return it. + findPartialKey_new: function (partialString) { + var partialKey = partialString.replace(this.findPartialKeyRE, '$1'); + return partialKey; + }, + + // GTP: the old implementation works better. We might not need + // this.findPartialKeyRE anymore if it works in all cases! + findPartialKey: function (partialString) { + //strip out the template cruft + var foundPatternKey = partialString.replace("{{> ", "").replace(" }}", "").replace("{{>", "").replace("}}", ""); + + // remove any potential pattern parameters. this and the above are rather brutish but I didn't want to do a regex at the time + if (foundPatternKey.indexOf('(') > 0) { + foundPatternKey = foundPatternKey.substring(0, foundPatternKey.indexOf('(')); + } + + //remove any potential stylemodifiers. + foundPatternKey = foundPatternKey.split(':')[0]; + + return foundPatternKey; + } +}; - module.exports = engine_mustache; -})(); +module.exports = engine_mustache; diff --git a/core/lib/pattern_engines/engine_underscore.js b/core/lib/pattern_engines/engine_underscore.js index 25a95344b..887c11d57 100644 --- a/core/lib/pattern_engines/engine_underscore.js +++ b/core/lib/pattern_engines/engine_underscore.js @@ -25,12 +25,12 @@ // extend underscore with partial-ing methods // HANDLESCORE! UNDERBARS! _.mixin({ - renderPartial: function(partial, data) { + renderPartial: function (partial, data) { var data = data || {}; var compiled = _.template(partial); return compiled(data); }, - assignContext: function(viewModel, data) { + assignContext: function (viewModel, data) { return viewModel(data); } }); @@ -69,21 +69,23 @@ var matches = pattern.template.match(this.findPartialsRE); return matches; }, - findPartialsWithStyleModifiers: function(pattern) { + findPartialsWithStyleModifiers: function () { return []; }, + // returns any patterns that match {{> value(foo:"bar") }} or {{> // value:mod(foo:"bar") }} within the pattern - findPartialsWithPatternParameters: function(pattern) { + findPartialsWithPatternParameters: function () { return []; }, - findListItems: function(pattern) { + findListItems: function (pattern) { var matches = pattern.template.match(this.findListItemsRE); return matches; }, + // given a pattern, and a partial string, tease out the "pattern key" and // return it. - findPartialKey: function(partialString) { + findPartialKey: function (partialString) { var partialKey = partialString.replace(this.findPartialsRE, '$1'); return partialKey; } diff --git a/core/lib/pattern_engines/pattern_engines.js b/core/lib/pattern_engines/pattern_engines.js index c8d7d50ed..3d9bfbbf2 100644 --- a/core/lib/pattern_engines/pattern_engines.js +++ b/core/lib/pattern_engines/pattern_engines.js @@ -8,168 +8,166 @@ * */ +'use strict'; -(function () { - 'use strict'; +var path = require('path'); +var diveSync = require('diveSync'); +var engineMatcher = /^engine_(.*)\.js/; +var enginesDirectory = __dirname; - var path = require('path'); - var diveSync = require('diveSync'); - var engineMatcher = /^engine_(.*)\.js/; - var enginesDirectory = __dirname; +var PatternEngines; // the main export object +var engineNameForExtension; // generated mapping of extension to engine name - var PatternEngines; // the main export object - var engineNameForExtension; // generated mapping of extension to engine name +// free "private" functions, for internal setup only - // free "private" functions, for internal setup only +function findSupportedPatternEngineNames() { + var foundPatternEngineNames = []; - function findSupportedPatternEngineNames() { - var foundPatternEngineNames = []; - - // find - diveSync(enginesDirectory, { - recursive: false, - filter: function (filePath, dir) { - var baseName = path.basename(filePath), - engineMatch = baseName.match(engineMatcher); - - if (dir || engineMatch !== null) { return true; } - return false; - } - }, function (err, filePath) { - if (err) { throw err; } + // find + diveSync(enginesDirectory, { + recursive: false, + filter: function (filePath, dir) { var baseName = path.basename(filePath), - engineMatch = baseName.match(engineMatcher), - foundEngineName = engineMatch[1]; + engineMatch = baseName.match(engineMatcher); - foundPatternEngineNames.push(foundEngineName); - }); + if (dir || engineMatch !== null) { return true; } + return false; + } + }, function (err, filePath) { + if (err) { throw err; } + var baseName = path.basename(filePath), + engineMatch = baseName.match(engineMatcher), + foundEngineName = engineMatch[1]; - return foundPatternEngineNames; - } + foundPatternEngineNames.push(foundEngineName); + }); - // try to load all supported engines - function loadAllEngines(enginesObject) { - console.log('\nLoading engines...'); - - enginesObject.supportedPatternEngineNames.forEach(function (engineName) { - var notLoaded = false; - - try { - enginesObject[engineName] = require('./engine_' + engineName); - } catch (err) { - // Handle errors loading each pattern engine. This will usually be - // because the engine's renderer hasn't been installed by the end user - // -- we don't include any of them (except mustache) by default as - // depedencies in package.json. - notLoaded = (err.code === 'MODULE_NOT_FOUND'); - } finally { - console.log('-', engineName, 'engine:', - notLoaded ? 'renderer not installed; engine disabled' : 'good to go'); - } - }); - console.log('...done loading engines.\n'); - } + return foundPatternEngineNames; +} + +// try to load all supported engines +function loadAllEngines(enginesObject) { + console.log('\nLoading engines...'); + + enginesObject.supportedPatternEngineNames.forEach(function (engineName) { + var notLoaded = false; + + try { + enginesObject[engineName] = require('./engine_' + engineName); + } catch (err) { + // Handle errors loading each pattern engine. This will usually be + // because the engine's renderer hasn't been installed by the end user + // -- we don't include any of them (except mustache) by default as + // depedencies in package.json. + notLoaded = (err.code === 'MODULE_NOT_FOUND'); + } finally { + console.log('-', engineName, 'engine:', + notLoaded ? 'renderer not installed; engine disabled' : 'good to go'); + } + }); + console.log('...done loading engines.\n'); +} - // produce a mapping between file extension and engine name for each of the - // loaded engines - function createFileExtensionToEngineNameMap(enginesObject) { - var mapping = {}; +// produce a mapping between file extension and engine name for each of the +// loaded engines +function createFileExtensionToEngineNameMap(enginesObject) { + var mapping = {}; - Object.keys(enginesObject).forEach(function (engineName) { - var extensionForEngine = enginesObject[engineName].engineFileExtension; - mapping[extensionForEngine] = engineName; - }); + Object.keys(enginesObject).forEach(function (engineName) { + var extensionForEngine = enginesObject[engineName].engineFileExtension; + mapping[extensionForEngine] = engineName; + }); - return mapping; - } + return mapping; +} + + +// +// PatternEngines: the main export of this module +// +// It's an Object/hash of all loaded pattern engines, empty at first. My +// intention here is to make this return an object that can be used to obtain +// any loaded PatternEngine by addressing them like this: +// +// var PatternEngines = require('./pattern_engines/pattern_engines'); +// var Mustache = PatternEngines['mustache']; +// +// Object.create lets us create an object with a specified prototype. We want +// this here because we would like the object's "own properties" to include +// only the engine names so we can easily iterate over them; all the handy +// methods and properites below should therefore be on its prototype. + +PatternEngines = Object.create({ + // build the list of supported pattern engines based on what plugins we have + // in the pattern_engines directory + supportedPatternEngineNames: findSupportedPatternEngineNames(), + + getEngineNameForPattern: function (pattern) { + // avoid circular dependency by putting this in here. TODO: is this slow? + var of = require('../object_factory'); + + if (pattern instanceof of.oPattern && typeof pattern.fileExtension === 'string' && pattern.fileExtension) { + return engineNameForExtension[pattern.fileExtension]; + } + // otherwise, assume it's a plain mustache template string and act + // accordingly + return 'mustache'; + }, + + getEngineForPattern: function (pattern) { + if (pattern.isPseudoPattern) { + return this.getEngineForPattern(pattern.basePattern); + } else { + var engineName = this.getEngineNameForPattern(pattern); + return this[engineName]; + } + }, - // - // PatternEngines: the main export of this module - // - // It's an Object/hash of all loaded pattern engines, empty at first. My - // intention here is to make this return an object that can be used to obtain - // any loaded PatternEngine by addressing them like this: - // - // var PatternEngines = require('./pattern_engines/pattern_engines'); - // var Mustache = PatternEngines['mustache']; - // - // Object.create lets us create an object with a specified prototype. We want - // this here because we would like the object's "own properties" to include - // only the engine names so we can easily iterate over them; all the handy - // methods and properites below should therefore be on its prototype. - - PatternEngines = Object.create({ - // build the list of supported pattern engines based on what plugins we have - // in the pattern_engines directory - supportedPatternEngineNames: findSupportedPatternEngineNames(), - - getEngineNameForPattern: function (pattern) { - // avoid circular dependency by putting this in here. TODO: is this slow? - var of = require('../object_factory'); - - if (pattern instanceof of.oPattern && typeof pattern.fileExtension === 'string' && pattern.fileExtension) { - return engineNameForExtension[pattern.fileExtension]; - } - // otherwise, assume it's a plain mustache template string and act - // accordingly - return 'mustache'; - }, - - getEngineForPattern: function (pattern) { - if (pattern.isPseudoPattern) { - return this.getEngineForPattern(pattern.basePattern); - } else { - var engineName = this.getEngineNameForPattern(pattern); - return this[engineName]; - } - }, - - getSupportedFileExtensions: function () { - var engineNames = Object.keys(PatternEngines); - return engineNames.map(function (engineName) { - return PatternEngines[engineName].engineFileExtension; - }); - }, - - isFileExtensionSupported: function (fileExtension) { - var supportedExtensions = PatternEngines.getSupportedFileExtensions(); - return (supportedExtensions.lastIndexOf(fileExtension) !== -1); - }, - - // given a filename, return a boolean: whether or not the filename indicates - // that the file is pseudopattern JSON - isPseudoPatternJSON: function (filename) { - var extension = path.extname(filename); - return (extension === '.json' && filename.indexOf('~') > -1); - }, - - // takes a filename string, not a full path; a basename (plus extension) - // ignore _underscored patterns, dotfiles, and anything not recognized by a - // loaded pattern engine. Pseudo-pattern .json files ARE considered to be - // pattern files! - isPatternFile: function (filename) { - // skip hidden patterns/files without a second thought - var extension = path.extname(filename); - if (filename.charAt(0) === '.' || - (extension === '.json' && !PatternEngines.isPseudoPatternJSON(filename))) { - return false; - } - - // not a hidden pattern, let's dig deeper - var supportedPatternFileExtensions = PatternEngines.getSupportedFileExtensions(); - return (supportedPatternFileExtensions.lastIndexOf(extension) !== -1 || - PatternEngines.isPseudoPatternJSON(filename)); + getSupportedFileExtensions: function () { + var engineNames = Object.keys(PatternEngines); + return engineNames.map(function (engineName) { + return PatternEngines[engineName].engineFileExtension; + }); + }, + + isFileExtensionSupported: function (fileExtension) { + var supportedExtensions = PatternEngines.getSupportedFileExtensions(); + return (supportedExtensions.lastIndexOf(fileExtension) !== -1); + }, + + // given a filename, return a boolean: whether or not the filename indicates + // that the file is pseudopattern JSON + isPseudoPatternJSON: function (filename) { + var extension = path.extname(filename); + return (extension === '.json' && filename.indexOf('~') > -1); + }, + + // takes a filename string, not a full path; a basename (plus extension) + // ignore _underscored patterns, dotfiles, and anything not recognized by a + // loaded pattern engine. Pseudo-pattern .json files ARE considered to be + // pattern files! + isPatternFile: function (filename) { + // skip hidden patterns/files without a second thought + var extension = path.extname(filename); + if (filename.charAt(0) === '.' || + (extension === '.json' && !PatternEngines.isPseudoPatternJSON(filename))) { + return false; } - }); + + // not a hidden pattern, let's dig deeper + var supportedPatternFileExtensions = PatternEngines.getSupportedFileExtensions(); + return (supportedPatternFileExtensions.lastIndexOf(extension) !== -1 || + PatternEngines.isPseudoPatternJSON(filename)); + } +}); - // load up the engines we found - loadAllEngines(PatternEngines); +// load up the engines we found +loadAllEngines(PatternEngines); - // mapping of file extensions to engine names, for lookup use - engineNameForExtension = createFileExtensionToEngineNameMap(PatternEngines); +// mapping of file extensions to engine names, for lookup use +engineNameForExtension = createFileExtensionToEngineNameMap(PatternEngines); - module.exports = PatternEngines; -})(); +module.exports = PatternEngines; diff --git a/core/lib/pattern_engines/util_mustache.js b/core/lib/pattern_engines/util_mustache.js index f5403a2de..bbc9468d6 100644 --- a/core/lib/pattern_engines/util_mustache.js +++ b/core/lib/pattern_engines/util_mustache.js @@ -8,127 +8,151 @@ * */ -(function () { - 'use strict'; - - // the term "alphanumeric" includes underscores. - - // look for an opening mustache include tag, followed by >=0 whitespaces - var partialsStr = '{{>\\s*'; - // begin 1st exterior group, a mandatory group - // look for >0 of an interior group comprising - // >0 digits, followed by a hyphen, followed by >0 alphanumerics - partialsStr += '((\\d+-[\\w-]+\\/)+'; - // then an interior group comprising - // >0 digits, followed by a hyphen, followed by >0 alphanumerics, - // followed by an optional group of a period followed by >0 alphanumerics - partialsStr += '(\\d+-[\\w-]+(\\.\\w+)?)'; - // if the previous two interior groups are not found, look for any number of - // alphanumerics or hyphens - partialsStr += '|[\\w\\-]+)'; - // end 1st exterior group - // begin 2nd exterior group, an optional group - // look for a colon, followed by >0 alphanumerics or hyphens, - // followed by >=0 interior groups - // comprising a pipe, followed by >0 alphanumerics or hyphens - partialsStr += '(\\:[\\w\\-]+(\\|[\\w\\-]+)*)?'; - // end 2nd exterior group - // begin 3rd exterior group, an optional group - // look for an opening parenthesis, followed by >=0 whitespaces, followed by - // >0 alphanumerics, followed by >=0 whitespaces, followed by a colon, - // followed by >=0 whitespaces - partialsStr += '(\\(\\s*\\w+\\s*\\:\\s*'; - // followed by an interior group - // comprising a single quote, followed by an interior group comprising - // >=0 characters that are not single quotes or backslashes - // or >=0 character pairs comprising a backlash, followed by any character. - // look for a single quote to terminate this pattern - partialsStr += '(\'([^\'\\\\]|\\\\.)*\''; - // if the pattern wrapped in single quotes is not found, look for one wrapped - // in double quotes - // look for a double quote, followed by an interior group comprising - // >=0 characters that are not double quotes or backslashes - // or >=0 character pairs comprising a backlash, followed by any character. - // look for a double quote to terminate this pattern - partialsStr += '|"([^"\\\\]|\\\\.)*")'; - // look for a closing parenthesis - partialsStr += '\\))?'; - // end 3rd exterior group - // look for >=0 whitespaces, followed by closing mustache tag - partialsStr += '\\s*}}'; - var partialsRE = new RegExp(partialsStr, 'g'); - - // look for an opening mustache include tag, followed by >=0 whitespaces - var partialsWithStyleModifiersStr = '{{>\\s*'; - // one or more characters comprising any combination of alphanumerics, - // hyphens, periods, slashses, and tildes - partialsWithStyleModifiersStr += '([\\w\\-\\.\\/~]+)'; - // the previous group cannot be followed by an opening parenthesis - partialsWithStyleModifiersStr += '(?!\\()'; - // a colon followed by one or more characters comprising any combination - // of alphanumerics, hyphens, and pipes - partialsWithStyleModifiersStr += '(\\:[\\w\\-\\|]+)'; - // an optional group of characters starting with >=0 whitespaces, followed by - // an opening parenthesis, followed by any number of characters that are not - // closing parentheses, followed by a closing parenthesis - partialsWithStyleModifiersStr += '(\\s*\\([^\\)]*\\))?'; - // look for >=0 whitespaces, followed by closing mustache tag - partialsWithStyleModifiersStr += '\\s*}}'; - var partialsWithStyleModifiersRE = new RegExp(partialsWithStyleModifiersStr, 'g'); - - // look for an opening mustache include tag, followed by >=0 whitespaces - var partialsWithPatternParametersStr = '{{>\\s*'; - // one or more characters comprising any combination of alphanumerics, - // hyphens, periods, slashses, and tildes - partialsWithPatternParametersStr += '([\\w\\-\\.\\/~]+)'; - // an optional group comprising a colon followed by one or more characters - // comprising any combination of alphanumerics, - // hyphens, and pipes - partialsWithPatternParametersStr += '(\\:[\\w\\-\\|]+)?'; - // a group of characters starting with >=0 whitespaces, followed by an opening - // parenthesis, followed by any number of characters that are not closing - // parentheses, followed by a closing parenthesis - partialsWithPatternParametersStr += '(\\s*\\([^\\)]*\\))'; - // look for >=0 whitespaces, followed by closing mustache tag - partialsWithPatternParametersStr += '\\s*}}'; - var partialsWithPatternParametersRE = new RegExp(partialsWithPatternParametersStr, 'g'); - - // look for an opening mustache loop tag, followed by >=0 whitespaces - var listItemsStr = '{{#\\s*'; - // look for the string 'listItems.' or 'listitems.' - listItemsStr += '(list(I|i)tems\\.)'; - // look for a number 1 - 20, spelled out - listItemsStr += '(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)'; - // look for >=0 whitespaces, followed by closing mustache tag - listItemsStr += '\\s*}}'; - var listItemsRE = new RegExp(listItemsStr, 'g'); - - // look for an opening mustache loop tag, followed by >=0 whitespaces - var partialKeyStr = '{{>\\s*'; - // one or more characters comprising any combination of alphanumerics, - // hyphens, periods, slashses, and tildes - partialKeyStr += '([\\w\\-\\.\\/~]+)'; - // an optional group of characters starting with a colon, followed by >0 - // alphanumerics, hyphens, or pipes - partialKeyStr += '(\\:[\\w\\-|]+)?'; - // an optional group of characters starting with a colon, followed by >0 - // alphanumerics or hyphens - partialKeyStr += '(\\:[\\w\\-]+)?'; - // an optional group of characters starting with >=0 whitespaces, followed by - // an opening parenthesis, followed by any number of characters that are not - // closing parentheses, followed by a closing parenthesis - partialKeyStr += '(\\s*\\([^\\)]*\\))?'; - // look for >=0 whitespaces, followed by closing mustache tag - partialKeyStr += '\\s*}}'; - var partialKeyRE = new RegExp(partialKeyStr, 'g'); - - var utilMustache = { - partialsRE: partialsRE, - partialsWithStyleModifiersRE: partialsWithStyleModifiersRE, - partialsWithPatternParametersRE: partialsWithPatternParametersRE, - listItemsRE: listItemsRE, - partialKeyRE: partialKeyRE - }; - - module.exports = utilMustache; -})(); +'use strict'; + +// the term "alphanumeric" includes underscores. + +// look for an opening mustache include tag, followed by >=0 whitespaces +var partialsStr = '{{>\\s*'; + +// begin 1st exterior group, a mandatory group +// look for >0 of an interior group comprising +// >0 digits, followed by a hyphen, followed by >0 alphanumerics +partialsStr += '((\\d+-[\\w-]+\\/)+'; + +// then an interior group comprising +// >0 digits, followed by a hyphen, followed by >0 alphanumerics, +// followed by an optional group of a period followed by >0 alphanumerics +partialsStr += '(\\d+-[\\w-]+(\\.\\w+)?)'; + +// if the previous two interior groups are not found, look for any number of +// alphanumerics or hyphens +partialsStr += '|[\\w\\-]+)'; + +// end 1st exterior group +// begin 2nd exterior group, an optional group +// look for a colon, followed by >0 alphanumerics or hyphens, +// followed by >=0 interior groups +// comprising a pipe, followed by >0 alphanumerics or hyphens +partialsStr += '(\\:[\\w\\-]+(\\|[\\w\\-]+)*)?'; + +// end 2nd exterior group +// begin 3rd exterior group, an optional group +// look for an opening parenthesis, followed by >=0 whitespaces, followed by +// >0 alphanumerics, followed by >=0 whitespaces, followed by a colon, +// followed by >=0 whitespaces +partialsStr += '(\\(\\s*\\w+\\s*\\:\\s*'; + +// followed by an interior group +// comprising a single quote, followed by an interior group comprising +// >=0 characters that are not single quotes or backslashes +// or >=0 character pairs comprising a backlash, followed by any character. +// look for a single quote to terminate this pattern +partialsStr += '(\'([^\'\\\\]|\\\\.)*\''; + +// if the pattern wrapped in single quotes is not found, look for one wrapped +// in double quotes +// look for a double quote, followed by an interior group comprising +// >=0 characters that are not double quotes or backslashes +// or >=0 character pairs comprising a backlash, followed by any character. +// look for a double quote to terminate this pattern +partialsStr += '|"([^"\\\\]|\\\\.)*")'; + +// look for a closing parenthesis +partialsStr += '\\))?'; + +// end 3rd exterior group +// look for >=0 whitespaces, followed by closing mustache tag +partialsStr += '\\s*}}'; +var partialsRE = new RegExp(partialsStr, 'g'); + +// look for an opening mustache include tag, followed by >=0 whitespaces +var partialsWithStyleModifiersStr = '{{>\\s*'; + +// one or more characters comprising any combination of alphanumerics, +// hyphens, periods, slashses, and tildes +partialsWithStyleModifiersStr += '([\\w\\-\\.\\/~]+)'; + +// the previous group cannot be followed by an opening parenthesis +partialsWithStyleModifiersStr += '(?!\\()'; + +// a colon followed by one or more characters comprising any combination +// of alphanumerics, hyphens, and pipes +partialsWithStyleModifiersStr += '(\\:[\\w\\-\\|]+)'; + +// an optional group of characters starting with >=0 whitespaces, followed by +// an opening parenthesis, followed by any number of characters that are not +// closing parentheses, followed by a closing parenthesis +partialsWithStyleModifiersStr += '(\\s*\\([^\\)]*\\))?'; + +// look for >=0 whitespaces, followed by closing mustache tag +partialsWithStyleModifiersStr += '\\s*}}'; +var partialsWithStyleModifiersRE = new RegExp(partialsWithStyleModifiersStr, 'g'); + +// look for an opening mustache include tag, followed by >=0 whitespaces +var partialsWithPatternParametersStr = '{{>\\s*'; + +// one or more characters comprising any combination of alphanumerics, +// hyphens, periods, slashses, and tildes +partialsWithPatternParametersStr += '([\\w\\-\\.\\/~]+)'; + +// an optional group comprising a colon followed by one or more characters +// comprising any combination of alphanumerics, +// hyphens, and pipes +partialsWithPatternParametersStr += '(\\:[\\w\\-\\|]+)?'; + +// a group of characters starting with >=0 whitespaces, followed by an opening +// parenthesis, followed by any number of characters that are not closing +// parentheses, followed by a closing parenthesis +partialsWithPatternParametersStr += '(\\s*\\([^\\)]*\\))'; + +// look for >=0 whitespaces, followed by closing mustache tag +partialsWithPatternParametersStr += '\\s*}}'; +var partialsWithPatternParametersRE = new RegExp(partialsWithPatternParametersStr, 'g'); + +// look for an opening mustache loop tag, followed by >=0 whitespaces +var listItemsStr = '{{#\\s*'; + +// look for the string 'listItems.' or 'listitems.' +listItemsStr += '(list(I|i)tems\\.)'; + +// look for a number 1 - 20, spelled out +listItemsStr += '(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)'; + +// look for >=0 whitespaces, followed by closing mustache tag +listItemsStr += '\\s*}}'; +var listItemsRE = new RegExp(listItemsStr, 'g'); + +// look for an opening mustache loop tag, followed by >=0 whitespaces +var partialKeyStr = '{{>\\s*'; + +// one or more characters comprising any combination of alphanumerics, +// hyphens, periods, slashses, and tildes +partialKeyStr += '([\\w\\-\\.\\/~]+)'; + +// an optional group of characters starting with a colon, followed by >0 +// alphanumerics, hyphens, or pipes +partialKeyStr += '(\\:[\\w\\-|]+)?'; + +// an optional group of characters starting with a colon, followed by >0 +// alphanumerics or hyphens +partialKeyStr += '(\\:[\\w\\-]+)?'; + +// an optional group of characters starting with >=0 whitespaces, followed by +// an opening parenthesis, followed by any number of characters that are not +// closing parentheses, followed by a closing parenthesis +partialKeyStr += '(\\s*\\([^\\)]*\\))?'; + +// look for >=0 whitespaces, followed by closing mustache tag +partialKeyStr += '\\s*}}'; +var partialKeyRE = new RegExp(partialKeyStr, 'g'); + +var utilMustache = { + partialsRE: partialsRE, + partialsWithStyleModifiersRE: partialsWithStyleModifiersRE, + partialsWithPatternParametersRE: partialsWithPatternParametersRE, + listItemsRE: listItemsRE, + partialKeyRE: partialKeyRE +}; + +module.exports = utilMustache; diff --git a/core/lib/pseudopattern_hunter.js b/core/lib/pseudopattern_hunter.js index ee10d72b4..69c8cd5d2 100644 --- a/core/lib/pseudopattern_hunter.js +++ b/core/lib/pseudopattern_hunter.js @@ -1,84 +1,84 @@ -/* - * patternlab-node - v1.1.3 - 2016 - * +/* + * patternlab-node - v1.1.3 - 2016 + * * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ - "use strict"; - - var pseudopattern_hunter = function(){ - - function findpseudopatterns(currentPattern, patternlab){ - var glob = require('glob'), - fs = require('fs-extra'), - pa = require('./pattern_assembler'), - lh = require('./lineage_hunter'), - of = require('./object_factory'), - plutils = require('./utilities'), - path = require('path'); - - - var pattern_assembler = new pa(); - var lineage_hunter = new lh(); - var paths = patternlab.config.paths; - - //look for a pseudo pattern by checking if there is a file containing same - //name, with ~ in it, ending in .json - var needle = currentPattern.subdir + '/' + currentPattern.fileName + '~*.json'; - var pseudoPatterns = glob.sync(needle, { - cwd: paths.source.patterns, - debug: false, - nodir: true - }); - - if(pseudoPatterns.length > 0){ - for(var i = 0; i < pseudoPatterns.length; i++){ - if(patternlab.config.debug){ - debugger; - console.log('found pseudoPattern variant of ' + currentPattern.key); - } - - //we want to do everything we normally would here, except instead read the pseudoPattern data - var variantFileData = fs.readJSONSync(path.resolve(paths.source.patterns, pseudoPatterns[i])); - - //extend any existing data with variant data - variantFileData = plutils.mergeData(currentPattern.jsonFileData, variantFileData); - - var variantName = pseudoPatterns[i].substring(pseudoPatterns[i].indexOf('~') + 1).split('.')[0]; - var variantFilePath = path.resolve(paths.source.patterns, currentPattern.subdir, currentPattern.fileName + '~' + variantName + '.json'); - var variantFileName = currentPattern.fileName + '-' + variantName + '.'; - var patternVariant = of.oPattern.create(variantFilePath, currentPattern.subdir, variantFileName, variantFileData, { - //use the same template as the non-variant - template: currentPattern.template, - extendedTemplate: currentPattern.extendedTemplate, - isPseudoPattern: true, - basePattern: currentPattern, - // use the same template engine as the non-variant - engine: currentPattern.engine - }); - - //see if this file has a state - pattern_assembler.setPatternState(patternVariant, patternlab); - - //find pattern lineage - lineage_hunter.find_lineage(patternVariant, patternlab); - - //add to patternlab object so we can look these up later. - pattern_assembler.addPattern(patternVariant, patternlab); - } - } - } - - return { - find_pseudopatterns: function(pattern, patternlab){ - findpseudopatterns(pattern, patternlab); - } - }; - - }; - - module.exports = pseudopattern_hunter; +"use strict"; + +var pseudopattern_hunter = function () { + + function findpseudopatterns(currentPattern, patternlab) { + var glob = require('glob'), + fs = require('fs-extra'), + pa = require('./pattern_assembler'), + lh = require('./lineage_hunter'), + of = require('./object_factory'), + plutils = require('./utilities'), + path = require('path'); + + + var pattern_assembler = new pa(); + var lineage_hunter = new lh(); + var paths = patternlab.config.paths; + + //look for a pseudo pattern by checking if there is a file containing same + //name, with ~ in it, ending in .json + var needle = currentPattern.subdir + '/' + currentPattern.fileName + '~*.json'; + var pseudoPatterns = glob.sync(needle, { + cwd: paths.source.patterns, + debug: false, + nodir: true + }); + + if (pseudoPatterns.length > 0) { + for (var i = 0; i < pseudoPatterns.length; i++) { + if (patternlab.config.debug) { + console.log('found pseudoPattern variant of ' + currentPattern.key); + } + + //we want to do everything we normally would here, except instead read the pseudoPattern data + var variantFileData = fs.readJSONSync(path.resolve(paths.source.patterns, pseudoPatterns[i])); + + //extend any existing data with variant data + variantFileData = plutils.mergeData(currentPattern.jsonFileData, variantFileData); + + var variantName = pseudoPatterns[i].substring(pseudoPatterns[i].indexOf('~') + 1).split('.')[0]; + var variantFilePath = path.resolve(paths.source.patterns, currentPattern.subdir, currentPattern.fileName + '~' + variantName + '.json'); + var variantFileName = currentPattern.fileName + '-' + variantName + '.'; + var patternVariant = of.oPattern.create(variantFilePath, currentPattern.subdir, variantFileName, variantFileData, { + //use the same template as the non-variant + template: currentPattern.template, + extendedTemplate: currentPattern.extendedTemplate, + isPseudoPattern: true, + basePattern: currentPattern, + + // use the same template engine as the non-variant + engine: currentPattern.engine + }); + + //see if this file has a state + pattern_assembler.setPatternState(patternVariant, patternlab); + + //find pattern lineage + lineage_hunter.find_lineage(patternVariant, patternlab); + + //add to patternlab object so we can look these up later. + pattern_assembler.addPattern(patternVariant, patternlab); + } + } + } + + return { + find_pseudopatterns: function (pattern, patternlab) { + findpseudopatterns(pattern, patternlab); + } + }; + +}; + +module.exports = pseudopattern_hunter; diff --git a/core/lib/utilities.js b/core/lib/utilities.js index 64d5190ed..e5295838b 100644 --- a/core/lib/utilities.js +++ b/core/lib/utilities.js @@ -8,58 +8,57 @@ * */ -(function () { - var path = require('path'); +var util = { + // http://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array-in-javascript + shuffle: function (o) { + /*eslint-disable curly*/ + for (var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x); + return o; + }, - var util = { - // http://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array-in-javascript - shuffle: function (o) { - for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x); - return o; - }, - - /** - * Recursively merge properties of two objects. - * - * @param {Object} obj1 If obj1 has properties obj2 doesn't, add to obj2. - * @param {Object} obj2 This object's properties have priority over obj1. - * @returns {Object} obj2 - */ - mergeData: function (obj1, obj2) { - if(typeof obj2 === 'undefined'){ - obj2 = {}; - } - for(var p in obj1){ - try { - // Only recurse if obj1[p] is an object. - if(obj1[p].constructor === Object){ - // Requires 2 objects as params; create obj2[p] if undefined. - if(typeof obj2[p] === 'undefined'){ - obj2[p] = {}; - } - obj2[p] = util.mergeData(obj1[p], obj2[p]); - // Pop when recursion meets a non-object. If obj1[p] is a non-object, - // only copy to undefined obj2[p]. This way, obj2 maintains priority. - } else if(typeof obj2[p] === 'undefined'){ - obj2[p] = obj1[p]; - } - } catch(e) { - // Property in destination object not set; create it and set its value. - if(typeof obj2[p] === 'undefined'){ - obj2[p] = obj1[p]; + /** + * Recursively merge properties of two objects. + * + * @param {Object} obj1 If obj1 has properties obj2 doesn't, add to obj2. + * @param {Object} obj2 This object's properties have priority over obj1. + * @returns {Object} obj2 + */ + mergeData: function (obj1, obj2) { + /*eslint-disable no-param-reassign, guard-for-in*/ + if (typeof obj2 === 'undefined') { + obj2 = {}; + } + for (var p in obj1) { + try { + // Only recurse if obj1[p] is an object. + if (obj1[p].constructor === Object) { + // Requires 2 objects as params; create obj2[p] if undefined. + if (typeof obj2[p] === 'undefined') { + obj2[p] = {}; } + obj2[p] = util.mergeData(obj1[p], obj2[p]); + + // Pop when recursion meets a non-object. If obj1[p] is a non-object, + // only copy to undefined obj2[p]. This way, obj2 maintains priority. + } else if (typeof obj2[p] === 'undefined') { + obj2[p] = obj1[p]; + } + } catch (e) { + // Property in destination object not set; create it and set its value. + if (typeof obj2[p] === 'undefined') { + obj2[p] = obj1[p]; } } - return obj2; - }, + } + return obj2; + }, - isObjectEmpty: function (obj) { - for(var prop in obj) { - if(obj.hasOwnProperty(prop)) { return false; } - } - return true; + isObjectEmpty: function (obj) { + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { return false; } } - }; + return true; + } +}; - module.exports = util; -}()); +module.exports = util; diff --git a/test/engine_handlebars_tests.js b/test/engine_handlebars_tests.js index b59fd3e88..6203a38ce 100644 --- a/test/engine_handlebars_tests.js +++ b/test/engine_handlebars_tests.js @@ -1,231 +1,227 @@ -(function () { - "use strict"; - - // don't run these tests unless handlebars is installed - try { var handlebars = require('handlebars'); } - catch (err) { return; } - - var path = require('path'); - var pa = require('../core/lib/pattern_assembler'); - var object_factory = require('../core/lib/object_factory'); - var testPatternsPath = path.resolve(__dirname, 'files', '_handlebars-test-patterns'); - - try { - require('handlebars'); - } catch (err) { - console.log('handlebars renderer not installed; skipping tests'); - return; - } +"use strict"; + +// don't run these tests unless handlebars is installed +try { var handlebars = require('handlebars'); } +catch (err) { return; } + +var path = require('path'); +var pa = require('../core/lib/pattern_assembler'); +var object_factory = require('../core/lib/object_factory'); +var testPatternsPath = path.resolve(__dirname, 'files', '_handlebars-test-patterns'); + +try { + require('handlebars'); +} catch (err) { + console.log('handlebars renderer not installed; skipping tests'); + return; +} + +// fake pattern lab constructor: +// sets up a fake patternlab object, which is needed by the pattern processing +// apparatus. +function fakePatternLab() { + var fpl = { + partials: {}, + patterns: [], + footer: '', + header: '', + listitems: {}, + listItemArray: [], + data: { + link: {} + }, + config: require('../patternlab-config.json'), + package: {} + }; - // fake pattern lab constructor: - // sets up a fake patternlab object, which is needed by the pattern processing - // apparatus. - function fakePatternLab() { - var fpl = { - partials: {}, - patterns: [], - footer: '', - header: '', - listitems: {}, - listItemArray: [], - data: { - link: {} - }, - config: require('../patternlab-config.json'), - package: {} - }; - - // patch the pattern source so the pattern assembler can correctly determine - // the "subdir" - fpl.config.paths.source.patterns = './test/files/_handlebars-test-patterns'; - - return fpl; - } + // patch the pattern source so the pattern assembler can correctly determine + // the "subdir" + fpl.config.paths.source.patterns = './test/files/_handlebars-test-patterns'; + + return fpl; +} + + +// function for testing sets of partials +function testFindPartials(test, partialTests) { + test.expect(partialTests.length + 1); + + // setup current pattern from what we would have during execution + // docs on partial syntax are here: + // http://patternlab.io/docs/pattern-including.html + var currentPattern = object_factory.oPattern.create( + '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.hbs', // abspath + '01-molecules\\00-testing', // subdir + '00-test-mol.hbs', // filename, + null, // data + { + template: partialTests.join() + } + ); + + // act + var results = currentPattern.findPartials(); + // assert + test.equals(results.length, partialTests.length); + partialTests.forEach(function (testString, index) { + test.equals(results[index], testString); + }); - // function for testing sets of partials - function testFindPartials(test, partialTests) { - test.expect(partialTests.length + 1); - - // setup current pattern from what we would have during execution - // docs on partial syntax are here: - // http://patternlab.io/docs/pattern-including.html - var currentPattern = object_factory.oPattern.create( - '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.hbs', // abspath - '01-molecules\\00-testing', // subdir - '00-test-mol.hbs', // filename, - null, // data - { - template: partialTests.join() - } + test.done(); +} + +exports['engine_handlebars'] = { + 'hello world handlebars pattern renders': function (test) { + test.expect(1); + + var patternPath = path.resolve( + testPatternsPath, + '00-atoms', + '00-global', + '00-helloworld.hbs' + ); + + // do all the normal processing of the pattern + var patternlab = new fakePatternLab(); + var assembler = new pa(); + var helloWorldPattern = assembler.process_pattern_iterative(patternPath, patternlab); + assembler.process_pattern_recursive(patternPath, patternlab); + + test.equals(helloWorldPattern.render(), 'Hello world!\n'); + test.done(); + }, + 'hello worlds handlebars pattern can see the atoms-helloworld partial and renders it twice': function (test) { + test.expect(1); + + // pattern paths + var pattern1Path = path.resolve( + testPatternsPath, + '00-atoms', + '00-global', + '00-helloworld.hbs' + ); + var pattern2Path = path.resolve( + testPatternsPath, + '00-molecules', + '00-global', + '00-helloworlds.hbs' ); - // act - var results = currentPattern.findPartials(); + // set up environment + var patternlab = new fakePatternLab(); // environment + var assembler = new pa(); - // assert - test.equals(results.length, partialTests.length); - partialTests.forEach(function(testString, index) { - test.equals(results[index], testString); - }); + // do all the normal processing of the pattern + assembler.process_pattern_iterative(pattern1Path, patternlab); + var helloWorldsPattern = assembler.process_pattern_iterative(pattern2Path, patternlab); + assembler.process_pattern_recursive(pattern1Path, patternlab); + assembler.process_pattern_recursive(pattern2Path, patternlab); + // test + test.equals(helloWorldsPattern.render(), 'Hello world!\n and Hello world!\n\n'); test.done(); - } + }, + 'handlebars partials can render JSON values': function (test) { + test.expect(1); + + // pattern paths + var pattern1Path = path.resolve( + testPatternsPath, + '00-atoms', + '00-global', + '00-helloworld-withdata.hbs' + ); - exports['engine_handlebars'] = { - 'hello world handlebars pattern renders': function (test) { - test.expect(1); - - var patternPath = path.resolve( - testPatternsPath, - '00-atoms', - '00-global', - '00-helloworld.hbs' - ); - - // do all the normal processing of the pattern - var patternlab = new fakePatternLab(); - var assembler = new pa(); - var helloWorldPattern = assembler.process_pattern_iterative(patternPath, patternlab); - assembler.process_pattern_recursive(patternPath, patternlab); - - test.equals(helloWorldPattern.render(), 'Hello world!\n'); - test.done(); - }, - 'hello worlds handlebars pattern can see the atoms-helloworld partial and renders it twice': function (test) { - test.expect(1); - - // pattern paths - var pattern1Path = path.resolve( - testPatternsPath, - '00-atoms', - '00-global', - '00-helloworld.hbs' - ); - var pattern2Path = path.resolve( - testPatternsPath, - '00-molecules', - '00-global', - '00-helloworlds.hbs' - ); - - // set up environment - var patternlab = new fakePatternLab(); // environment - var assembler = new pa(); - - // do all the normal processing of the pattern - assembler.process_pattern_iterative(pattern1Path, patternlab); - var helloWorldsPattern = assembler.process_pattern_iterative(pattern2Path, patternlab); - assembler.process_pattern_recursive(pattern1Path, patternlab); - assembler.process_pattern_recursive(pattern2Path, patternlab); - - // test - test.equals(helloWorldsPattern.render(), 'Hello world!\n and Hello world!\n\n'); - test.done(); - }, - 'handlebars partials can render JSON values': function (test) { - test.expect(1); - - // pattern paths - var pattern1Path = path.resolve( - testPatternsPath, - '00-atoms', - '00-global', - '00-helloworld-withdata.hbs' - ); - - // set up environment - var patternlab = new fakePatternLab(); // environment - var assembler = new pa(); - - // do all the normal processing of the pattern - var helloWorldWithData = assembler.process_pattern_iterative(pattern1Path, patternlab); - assembler.process_pattern_recursive(pattern1Path, patternlab); - - // test - test.equals(helloWorldWithData.render(), 'Hello world!\nYeah, we got the subtitle from the JSON.\n'); - test.done(); - }, - 'handlebars partials use the JSON environment from the calling pattern and can accept passed parameters': function (test) { - test.expect(1); - - debugger; - - // pattern paths - var atomPath = path.resolve( - testPatternsPath, - '00-atoms', - '00-global', - '00-helloworld-withdata.hbs' - ); - var molPath = path.resolve( - testPatternsPath, - '00-molecules', - '00-global', - '00-call-atom-with-molecule-data.hbs' - ); - - // set up environment - var patternlab = new fakePatternLab(); // environment - var assembler = new pa(); - - // do all the normal processing of the pattern - var atom = assembler.process_pattern_iterative(atomPath, patternlab); - var mol = assembler.process_pattern_iterative(molPath, patternlab); - assembler.process_pattern_recursive(atomPath, patternlab); - assembler.process_pattern_recursive(molPath, patternlab); - - // test - test.equals(mol.render(), '

Call with default JSON environment:

\nThis is Hello world!\nfrom the default JSON.\n\n\n

Call with passed parameter:

\nHowever, this is Hello world!\nfrom a totally different blob.\n\n'); - test.done(); - }, - 'find_pattern_partials finds partials': function(test){ - testFindPartials(test, [ - "{{> molecules-comment-header}}", - "{{> molecules-comment-header}}", - "{{> \n molecules-comment-header\n}}", - "{{> molecules-weird-spacing }}", - "{{> molecules-ba_d-cha*rs }}" - ]); - }, - 'find_pattern_partials finds verbose partials': function(test){ - testFindPartials(test, [ - '{{> 01-molecules/06-components/03-comment-header.hbs }}', - "{{> 01-molecules/06-components/02-single-comment.hbs(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}", - '{{> molecules-single-comment:foo }}', - "{{>atoms-error(message: 'That\'s no moon...')}}", - "{{> atoms-error(message: 'That\'s no moon...') }}", - '{{> 00-atoms/00-global/06-test }}' - ]); - }, - 'find_pattern_partials finds simple partials with parameters': function(test){ - testFindPartials(test, [ - "{{> molecules-single-comment(description: 'A life isn\'t like a garden. Perfect moments can be had, but not preserved, except in memory.') }}", - '{{> molecules-single-comment(description:"A life is like a \"garden\". Perfect moments can be had, but not preserved, except in memory.") }}' - ]); - }, - 'find_pattern_partials finds simple partials with style modifiers': function(test){ - testFindPartials(test, [ - '{{> molecules-single-comment:foo }}' - ]); - }, - 'find_pattern_partials finds partials with handlebars parameters': function(test){ - testFindPartials(test, [ - '{{> atoms-title title="bravo" headingLevel="2" headingSize="bravo" position="left"}}', - '{{> atoms-title title="bravo"\n headingLevel="2"\n headingSize="bravo"\n position="left"}}', - '{{> atoms-title title="color  midnight blue" headingSize="charlie"}}', - '{{> atoms-input label="city" required=true}}', - '{{> organisms-product-filter filterData}}', - '{{> atoms-input email required=true}}', - '{{> molecules-storycard variants.flex }}', - '{{> myPartial name=../name }}' - ]); - }, + // set up environment + var patternlab = new fakePatternLab(); // environment + var assembler = new pa(); - 'find_pattern_partials finds handlebars block partials': function(test){ - testFindPartials(test, [ - '{{#> myPartial }}' - ]); - } - }; -})(); + // do all the normal processing of the pattern + var helloWorldWithData = assembler.process_pattern_iterative(pattern1Path, patternlab); + assembler.process_pattern_recursive(pattern1Path, patternlab); + + // test + test.equals(helloWorldWithData.render(), 'Hello world!\nYeah, we got the subtitle from the JSON.\n'); + test.done(); + }, + 'handlebars partials use the JSON environment from the calling pattern and can accept passed parameters': function (test) { + test.expect(1); + + // pattern paths + var atomPath = path.resolve( + testPatternsPath, + '00-atoms', + '00-global', + '00-helloworld-withdata.hbs' + ); + var molPath = path.resolve( + testPatternsPath, + '00-molecules', + '00-global', + '00-call-atom-with-molecule-data.hbs' + ); + + // set up environment + var patternlab = new fakePatternLab(); // environment + var assembler = new pa(); + + // do all the normal processing of the pattern + var atom = assembler.process_pattern_iterative(atomPath, patternlab); + var mol = assembler.process_pattern_iterative(molPath, patternlab); + assembler.process_pattern_recursive(atomPath, patternlab); + assembler.process_pattern_recursive(molPath, patternlab); + + // test + test.equals(mol.render(), '

Call with default JSON environment:

\nThis is Hello world!\nfrom the default JSON.\n\n\n

Call with passed parameter:

\nHowever, this is Hello world!\nfrom a totally different blob.\n\n'); + test.done(); + }, + 'find_pattern_partials finds partials': function (test) { + testFindPartials(test, [ + "{{> molecules-comment-header}}", + "{{> molecules-comment-header}}", + "{{> \n molecules-comment-header\n}}", + "{{> molecules-weird-spacing }}", + "{{> molecules-ba_d-cha*rs }}" + ]); + }, + 'find_pattern_partials finds verbose partials': function (test) { + testFindPartials(test, [ + '{{> 01-molecules/06-components/03-comment-header.hbs }}', + "{{> 01-molecules/06-components/02-single-comment.hbs(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}", + '{{> molecules-single-comment:foo }}', + "{{>atoms-error(message: 'That\'s no moon...')}}", + "{{> atoms-error(message: 'That\'s no moon...') }}", + '{{> 00-atoms/00-global/06-test }}' + ]); + }, + 'find_pattern_partials finds simple partials with parameters': function (test) { + testFindPartials(test, [ + "{{> molecules-single-comment(description: 'A life isn\'t like a garden. Perfect moments can be had, but not preserved, except in memory.') }}", + '{{> molecules-single-comment(description:"A life is like a \"garden\". Perfect moments can be had, but not preserved, except in memory.") }}' + ]); + }, + 'find_pattern_partials finds simple partials with style modifiers': function (test) { + testFindPartials(test, [ + '{{> molecules-single-comment:foo }}' + ]); + }, + 'find_pattern_partials finds partials with handlebars parameters': function (test) { + testFindPartials(test, [ + '{{> atoms-title title="bravo" headingLevel="2" headingSize="bravo" position="left"}}', + '{{> atoms-title title="bravo"\n headingLevel="2"\n headingSize="bravo"\n position="left"}}', + '{{> atoms-title title="color  midnight blue" headingSize="charlie"}}', + '{{> atoms-input label="city" required=true}}', + '{{> organisms-product-filter filterData}}', + '{{> atoms-input email required=true}}', + '{{> molecules-storycard variants.flex }}', + '{{> myPartial name=../name }}' + ]); + }, + + 'find_pattern_partials finds handlebars block partials': function (test) { + testFindPartials(test, [ + '{{#> myPartial }}' + ]); + } +}; From 1578b0b9a8928cd4b7266d40f3ef769581bbdcd9 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 8 Mar 2016 13:56:11 -0600 Subject: [PATCH 080/187] Clean up code in engine_twig and move to the correct location --- builder/pattern_engines/engine_twig.js | 87 ------------------------- core/lib/pattern_engines/engine_twig.js | 82 +++++++++++++++++++++++ 2 files changed, 82 insertions(+), 87 deletions(-) delete mode 100644 builder/pattern_engines/engine_twig.js create mode 100644 core/lib/pattern_engines/engine_twig.js diff --git a/builder/pattern_engines/engine_twig.js b/builder/pattern_engines/engine_twig.js deleted file mode 100644 index a8357e539..000000000 --- a/builder/pattern_engines/engine_twig.js +++ /dev/null @@ -1,87 +0,0 @@ -/* - * handlebars pattern engine for patternlab-node - v0.15.1 - 2015 - * - * Geoffrey Pursell, Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - -/* - * ENGINE SUPPORT LEVEL: - * - * Full. Partial calls and lineage hunting are supported. Handlebars does not - * support the mustache-specific syntax extensions, style modifiers and pattern - * parameters, because their use cases are addressed by the core Handlebars - * feature set. - * - */ - -(function () { - "use strict"; - - var Twig = require('twig/twig.js'); - var twig = Twig.twig; - - var engine_twig = { - engine: Twig, - engineName: 'twig', - engineFileExtension: '.twig', - - //Important! Needed for Twig compilation. Can't resolve paths otherwise. - expandPartials: true, - - // regexes, stored here so they're only compiled once - findPartialsRE: /{%([ ]+)?(?:extends|include|embed)(\s\S)(.*)%}/g, - findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, // TODO - - // render it - renderPattern: function renderPattern(template, data) { - var template = twig({ - data: template - }).render(data); - - return template; - }, - - // find and return any {{> template-name }} within pattern - findPartials: function findPartials(pattern) { - var matches = pattern.template.match(this.findPartialsRE); - return matches; - }, - findPartialsWithStyleModifiers: function() { - // TODO: make the call to this from oPattern objects conditional on their - // being implemented here. - return []; - }, - // returns any patterns that match {{> value(foo:"bar") }} or {{> - // value:mod(foo:"bar") }} within the pattern - findPartialsWithPatternParameters: function() { - // TODO: make the call to this from oPattern objects conditional on their - // being implemented here. - return []; - }, - findListItems: function(pattern) { - var matches = pattern.template.match(this.findListItemsRE); - return matches; - }, - // given a pattern, and a partial string, tease out the "pattern key" and - // return it. - findPartialKey: function(partialString) { - - - //var partialKey = partialString.replace(this.findPartialsRE, '$1'); - var partialKey = partialString.match(/"((?:\\.|[^"\\])*)"/)[0]; - partialKey = partialKey.replace(/"/g, ''); - - return partialKey; - } - - - - - }; - - module.exports = engine_twig; -})(); diff --git a/core/lib/pattern_engines/engine_twig.js b/core/lib/pattern_engines/engine_twig.js new file mode 100644 index 000000000..249ec67f1 --- /dev/null +++ b/core/lib/pattern_engines/engine_twig.js @@ -0,0 +1,82 @@ +/* + * handlebars pattern engine for patternlab-node - v0.15.1 - 2015 + * + * Geoffrey Pursell, Brian Muenzenmeyer, and the web community. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * + */ + +/* + * ENGINE SUPPORT LEVEL: + * + * Full. Partial calls and lineage hunting are supported. Handlebars does not + * support the mustache-specific syntax extensions, style modifiers and pattern + * parameters, because their use cases are addressed by the core Handlebars + * feature set. + * + */ + +"use strict"; + +var Twig = require('twig/twig.js'); +var twig = Twig.twig; + +var engine_twig = { + engine: Twig, + engineName: 'twig', + engineFileExtension: '.twig', + + //Important! Needed for Twig compilation. Can't resolve paths otherwise. + expandPartials: true, + + // regexes, stored here so they're only compiled once + findPartialsRE: /{%([ ]+)?(?:extends|include|embed)(\s\S)(.*)%}/g, + findPartialKeyRE: /"((?:\\.|[^"\\])*)"/, + findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, // TODO + + // render it + renderPattern: function renderPattern(template, data) { + var result = twig({ + data: template + }).render(data); + + return result; + }, + + // find and return any {{> template-name }} within pattern + findPartials: function findPartials(pattern) { + var matches = pattern.template.match(this.findPartialsRE); + return matches; + }, + findPartialsWithStyleModifiers: function () { + // TODO: make the call to this from oPattern objects conditional on their + // being implemented here. + return []; + }, + + // returns any patterns that match {{> value(foo:"bar") }} or {{> + // value:mod(foo:"bar") }} within the pattern + findPartialsWithPatternParameters: function () { + // TODO: make the call to this from oPattern objects conditional on their + // being implemented here. + return []; + }, + findListItems: function (pattern) { + var matches = pattern.template.match(this.findListItemsRE); + return matches; + }, + + // given a pattern, and a partial string, tease out the "pattern key" and + // return it. + findPartialKey: function (partialString) { + //var partialKey = partialString.replace(this.findPartialsRE, '$1'); + var partialKey = partialString.match(this.findPartialKeyRE)[0]; + partialKey = partialKey.replace(/"/g, ''); + + return partialKey; + } +}; + +module.exports = engine_twig; From 701477b8bf59e285f012ba97b5c2fa174740e163 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Wed, 9 Mar 2016 11:04:51 -0600 Subject: [PATCH 081/187] Tweaks, cleanups and unit tests for the Twig engine. --- core/lib/pattern_engines/engine_twig.js | 14 +- test/engine_twig_tests.js | 217 ++++++++++++++++++ .../00-atoms/00-general}/08-button.twig | 0 .../00-atoms/00-general}/09-image.twig | 0 .../00-general/00-media-object.twig | 3 +- 5 files changed, 226 insertions(+), 8 deletions(-) create mode 100644 test/engine_twig_tests.js rename {source/_patterns/00-atoms => test/files/_twig-test-patterns/00-atoms/00-general}/08-button.twig (100%) rename {source/_patterns/00-atoms => test/files/_twig-test-patterns/00-atoms/00-general}/09-image.twig (100%) rename source/_patterns/01-molecules/media-object.twig => test/files/_twig-test-patterns/00-molecules/00-general/00-media-object.twig (82%) diff --git a/core/lib/pattern_engines/engine_twig.js b/core/lib/pattern_engines/engine_twig.js index 249ec67f1..5e57c18d0 100644 --- a/core/lib/pattern_engines/engine_twig.js +++ b/core/lib/pattern_engines/engine_twig.js @@ -11,16 +11,16 @@ /* * ENGINE SUPPORT LEVEL: * - * Full. Partial calls and lineage hunting are supported. Handlebars does not - * support the mustache-specific syntax extensions, style modifiers and pattern - * parameters, because their use cases are addressed by the core Handlebars - * feature set. + * Full. Partial calls and lineage hunting are supported. Twig does not support + * the mustache-specific syntax extensions, style modifiers and pattern + * parameters, because their use cases are addressed by the core Twig feature + * set. * */ "use strict"; -var Twig = require('twig/twig.js'); +var Twig = require('twig'); var twig = Twig.twig; var engine_twig = { @@ -32,7 +32,7 @@ var engine_twig = { expandPartials: true, // regexes, stored here so they're only compiled once - findPartialsRE: /{%([ ]+)?(?:extends|include|embed)(\s\S)(.*)%}/g, + findPartialsRE: /{%\s*(?:extends|include|embed)\s+('[^']+'|"[^"]+").*?%}/g, findPartialKeyRE: /"((?:\\.|[^"\\])*)"/, findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, // TODO @@ -45,7 +45,7 @@ var engine_twig = { return result; }, - // find and return any {{> template-name }} within pattern + // find and return any {% include 'template-name' %} within pattern findPartials: function findPartials(pattern) { var matches = pattern.template.match(this.findPartialsRE); return matches; diff --git a/test/engine_twig_tests.js b/test/engine_twig_tests.js new file mode 100644 index 000000000..9c6cec4f3 --- /dev/null +++ b/test/engine_twig_tests.js @@ -0,0 +1,217 @@ +"use strict"; +/*eslint-disable dot-notation*/ + +// don't run these tests unless twig is installed +try { var twig = require('twig'); } +catch (err) { return; } + +var path = require('path'); +var pa = require('../core/lib/pattern_assembler'); +var object_factory = require('../core/lib/object_factory'); +var testPatternsPath = path.resolve(__dirname, 'files', '_twig-test-patterns'); + +try { + require('twig'); +} catch (err) { + console.log('twig renderer not installed; skipping tests'); + return; +} + +// fake pattern lab constructor: +// sets up a fake patternlab object, which is needed by the pattern processing +// apparatus. +function fakePatternLab() { + var fpl = { + partials: {}, + patterns: [], + footer: '', + header: '', + listitems: {}, + listItemArray: [], + data: { + link: {} + }, + config: require('../patternlab-config.json'), + package: {} + }; + + // patch the pattern source so the pattern assembler can correctly determine + // the "subdir" + fpl.config.paths.source.patterns = './test/files/_twig-test-patterns'; + + return fpl; +} + + +// function for testing sets of partials +function testFindPartials(test, partialTests) { + test.expect(partialTests.length + 1); + + // setup current pattern from what we would have during execution + // docs on partial syntax are here: + // http://patternlab.io/docs/pattern-including.html + var currentPattern = object_factory.oPattern.create( + '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.twig', // abspath + '01-molecules\\00-testing', // subdir + '00-test-mol.twig', // filename, + null, // data + { + template: partialTests.join() + } + ); + + // act + var results = currentPattern.findPartials(); + + // assert + debugger; + test.equals(results.length, partialTests.length); + partialTests.forEach(function (testString, index) { + test.equals(results[index], testString); + }); + + test.done(); +} + +exports['engine_twig'] = { + 'button twig pattern renders': function (test) { + test.expect(1); + + var patternPath = path.resolve( + testPatternsPath, + '00-atoms', + '00-general', + '08-button.twig' + ); + + var expectedValue = '\n\nButton\n'; + + // do all the normal processing of the pattern + var patternlab = new fakePatternLab(); + var assembler = new pa(); + var helloWorldPattern = assembler.process_pattern_iterative(patternPath, patternlab); + assembler.process_pattern_recursive(patternPath, patternlab); + + test.equals(helloWorldPattern.render(), expectedValue); + test.done(); + }, + 'media object twig pattern can see the atoms-button and atoms-image partials and renders them': function (test) { + test.expect(1); + + // pattern paths + var buttonPatternPath = path.resolve( + testPatternsPath, + '00-atoms', + '00-general', + '08-button.twig' + ); + var imagePatternPath = path.resolve( + testPatternsPath, + '00-atoms', + '00-general', + '09-image.twig' + ); + var mediaObjectPatternPath = path.resolve( + testPatternsPath, + '00-molecules', + '00-general', + '00-media-object.twig' + ); + + var expectedValue = '\n\n\n\n\n
\n \n\n \n\nButton\n\n\n
\n\n \n \n\n

Oh, hello world!

\n
\n
\n'; + + // set up environment + var patternlab = new fakePatternLab(); // environment + var assembler = new pa(); + + // do all the normal processing of the pattern + assembler.process_pattern_iterative(buttonPatternPath, patternlab); + assembler.process_pattern_iterative(imagePatternPath, patternlab); + var mediaObjectPattern = assembler.process_pattern_iterative(mediaObjectPatternPath, patternlab); + assembler.process_pattern_recursive(buttonPatternPath, patternlab); + assembler.process_pattern_recursive(imagePatternPath, patternlab); + assembler.process_pattern_recursive(mediaObjectPatternPath, patternlab); + + // test + test.equals(mediaObjectPattern.render(), expectedValue); + test.done(); + }, + // 'twig partials can render JSON values': function (test) { + // test.expect(1); + + // // pattern paths + // var pattern1Path = path.resolve( + // testPatternsPath, + // '00-atoms', + // '00-global', + // '00-helloworld-withdata.hbs' + // ); + + // // set up environment + // var patternlab = new fakePatternLab(); // environment + // var assembler = new pa(); + + // // do all the normal processing of the pattern + // var helloWorldWithData = assembler.process_pattern_iterative(pattern1Path, patternlab); + // assembler.process_pattern_recursive(pattern1Path, patternlab); + + // // test + // test.equals(helloWorldWithData.render(), 'Hello world!\nYeah, we got the subtitle from the JSON.\n'); + // test.done(); + // }, + // 'twig partials use the JSON environment from the calling pattern and can accept passed parameters': function (test) { + // test.expect(1); + + // // pattern paths + // var atomPath = path.resolve( + // testPatternsPath, + // '00-atoms', + // '00-global', + // '00-helloworld-withdata.hbs' + // ); + // var molPath = path.resolve( + // testPatternsPath, + // '00-molecules', + // '00-global', + // '00-call-atom-with-molecule-data.hbs' + // ); + + // // set up environment + // var patternlab = new fakePatternLab(); // environment + // var assembler = new pa(); + + // // do all the normal processing of the pattern + // var atom = assembler.process_pattern_iterative(atomPath, patternlab); + // var mol = assembler.process_pattern_iterative(molPath, patternlab); + // assembler.process_pattern_recursive(atomPath, patternlab); + // assembler.process_pattern_recursive(molPath, patternlab); + + // // test + // test.equals(mol.render(), '

Call with default JSON environment:

\nThis is Hello world!\nfrom the default JSON.\n\n\n

Call with passed parameter:

\nHowever, this is Hello world!\nfrom a totally different blob.\n\n'); + // test.done(); + // }, + 'find_pattern_partials finds partials': function (test) { + testFindPartials(test, [ + '{% include "atoms-image" %}', + "{% include 'atoms-image' %}", + "{%include 'atoms-image'%}", + "{% include 'molecules-template' only %}", + "{% include 'organisms-sidebar' ignore missing %}", + "{% include 'organisms-sidebar' ignore missing only %}" + ]); + }, + 'find_pattern_partials finds verbose partials': function (test) { + testFindPartials(test, [ + "{% include '01-molecules/06-components/03-comment-header.twig' %}", + "{% include '00-atoms/00-global/06-test' %}" + ]); + }, + 'find_pattern_partials finds partials with twig parameters': function (test) { + testFindPartials(test, [ + "{% include 'molecules-template' with {'foo': 'bar'} %}", + "{% include 'molecules-template' with vars %}", + "{% include 'molecules-template.twig' with {'foo': 'bar'} only %}", + "{% include 'organisms-sidebar' ignore missing with {'foo': 'bar'} %}" + ]); + } +}; diff --git a/source/_patterns/00-atoms/08-button.twig b/test/files/_twig-test-patterns/00-atoms/00-general/08-button.twig similarity index 100% rename from source/_patterns/00-atoms/08-button.twig rename to test/files/_twig-test-patterns/00-atoms/00-general/08-button.twig diff --git a/source/_patterns/00-atoms/09-image.twig b/test/files/_twig-test-patterns/00-atoms/00-general/09-image.twig similarity index 100% rename from source/_patterns/00-atoms/09-image.twig rename to test/files/_twig-test-patterns/00-atoms/00-general/09-image.twig diff --git a/source/_patterns/01-molecules/media-object.twig b/test/files/_twig-test-patterns/00-molecules/00-general/00-media-object.twig similarity index 82% rename from source/_patterns/01-molecules/media-object.twig rename to test/files/_twig-test-patterns/00-molecules/00-general/00-media-object.twig index 532e0c6db..09af05118 100644 --- a/source/_patterns/01-molecules/media-object.twig +++ b/test/files/_twig-test-patterns/00-molecules/00-general/00-media-object.twig @@ -20,11 +20,12 @@
{% include "atoms-image" %} + {% include "atoms-button" %}
{# Testing if we can also pull in non-twig templates without breaking anything (it works!). Good idea though? Eh... #} - {% include "atoms-paragraph" %} + {# GTP: let's not for now. It's messin' up the unit testing. #}

Oh, hello {{ foo }}

From a78b7487505cff7964a4bea09a5dca5766f73a80 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Wed, 9 Mar 2016 11:05:41 -0600 Subject: [PATCH 082/187] oops, debugger statement --- test/engine_twig_tests.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/engine_twig_tests.js b/test/engine_twig_tests.js index 9c6cec4f3..308193d93 100644 --- a/test/engine_twig_tests.js +++ b/test/engine_twig_tests.js @@ -64,7 +64,6 @@ function testFindPartials(test, partialTests) { var results = currentPattern.findPartials(); // assert - debugger; test.equals(results.length, partialTests.length); partialTests.forEach(function (testString, index) { test.equals(results[index], testString); From 4df8007808bd689748a1d48d41233e3571d01f71 Mon Sep 17 00:00:00 2001 From: Evan Lovely Date: Wed, 9 Mar 2016 13:37:13 -0800 Subject: [PATCH 083/187] fixing JSON error in package.gulp.json --- package.gulp.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.gulp.json b/package.gulp.json index 01f789741..a6b6429f7 100644 --- a/package.gulp.json +++ b/package.gulp.json @@ -12,7 +12,7 @@ "mustache": "^2.2.1", "handlebars": "^4.0.5", "twig": "^0.8.8", - "underscore": "^1.8.3", + "underscore": "^1.8.3" }, "devDependencies": { "browser-sync": "^2.11.1", From 8f9cb721ed27983926f024351212e962d4cbd831 Mon Sep 17 00:00:00 2001 From: Evan Lovely Date: Wed, 9 Mar 2016 13:44:30 -0800 Subject: [PATCH 084/187] fixing Travis build error when Grunt trys to load Gulp tasks --- Gruntfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gruntfile.js b/Gruntfile.js index 31b5c605d..0148d8075 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -152,7 +152,7 @@ module.exports = function (grunt) { require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks); //load the patternlab task - grunt.task.loadTasks('./core/lib/'); + require('./core/lib/patternlab_grunt')(grunt); grunt.registerTask('default', ['patternlab', 'copy:main', 'copy:styleguide']); From 6db7cb189f5fe378ecd1eef984fee5bd5c460b2a Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Fri, 11 Mar 2016 10:51:58 -0600 Subject: [PATCH 085/187] fix whitespace in lineage-hunter test --- test/lineage_hunter_tests.js | 765 +++++++++++++++++------------------ 1 file changed, 381 insertions(+), 384 deletions(-) diff --git a/test/lineage_hunter_tests.js b/test/lineage_hunter_tests.js index bd2f1f148..603ab356e 100644 --- a/test/lineage_hunter_tests.js +++ b/test/lineage_hunter_tests.js @@ -1,388 +1,385 @@ -(function () { - "use strict"; - - var lh = require('../core/lib/lineage_hunter'); - var of = require('../core/lib/object_factory'); - var extend = require('util')._extend; - - // fake pattern creators - function createFakeEmptyErrorPattern() { - return new of.oPattern( - '/home/fakeuser/pl/source/_patterns/01-molecules/01-toast/00-error.mustache', // abspath - '01-molecules\\01-toast', // subdir - '00-error.mustache', // filename, +"use strict"; + +var lh = require('../core/lib/lineage_hunter'); +var of = require('../core/lib/object_factory'); +var extend = require('util')._extend; + +// fake pattern creators +function createFakeEmptyErrorPattern() { + return new of.oPattern( + '/home/fakeuser/pl/source/_patterns/01-molecules/01-toast/00-error.mustache', // abspath + '01-molecules\\01-toast', // subdir + '00-error.mustache', // filename, + null // data + ); +} + +exports['lineage hunter '] = { + 'find_lineage - finds lineage' : function (test) { + + //setup current pattern from what we would have during execution + var currentPattern = new of.oPattern( + '/home/fakeuser/pl/source/_patterns/02-organisms/00-global/00-header.mustache', // abspath + '02-organisms\\00-global', // subdir + '00-header.mustache', // filename, null // data ); + extend(currentPattern, { + "template": "\r\n
\r\n\t{{> atoms-logo }}\r\n\tSearch\r\n\tMenu\r\n\t{{> molecules-primary-nav }}\r\n\t{{> molecules-search }}\r\n
\r\n\r\n", + "patternPartial": "\r\n
\r\n\"Logo\tSearch\r\n\tMenu\r\n\r\n
\r\n
\r\n\t Search\r\n\t \r\n\t \r\n\t \r\n
\r\n
\r\n\r\n" + }); + + var patternlab = { + patterns: [ + { + "name": "00-atoms-03-images-00-logo", + "subdir": "00-atoms\\03-images", + "filename": "00-logo.mustache", + "data": null, + "template": "\"Logo", + "patternPartial": "\"Logo", + "patternName": "logo", + "patternLink": "00-atoms-03-images-00-logo/00-atoms-03-images-00-logo.html", + "patternGroup": "atoms", + "patternSubGroup": "atoms\\03-images", + "flatPatternPath": "00-atoms\\03-images", + "key": "atoms-logo", + "patternState": "", + "lineage": [], + "lineageIndex": [], + "lineageR": [], + "lineageRIndex": [] + }, + { + "name": "01-molecules-05-navigation-00-primary-nav", + "subdir": "01-molecules\\05-navigation", + "filename": "00-primary-nav.mustache", + "data": null, + "template": "\r\n", + "patternPartial": "\r\n", + "patternName": "primary-nav", + "patternLink": "01-molecules-05-navigation-00-primary-nav/01-molecules-05-navigation-00-primary-nav.html", + "patternGroup": "molecules", + "patternSubGroup": "molecules\\05-navigation", + "flatPatternPath": "01-molecules\\05-navigation", + "key": "molecules-primary-nav", + "patternState": "", + "lineage": [], + "lineageIndex": [], + "lineageR": [], + "lineageRIndex": [] + }, + { + "name": "01-molecules-04-forms-00-search", + "subdir": "01-molecules\\04-forms", + "filename": "00-search.mustache", + "data": null, + "template": "
\r\n
\r\n\t Search\r\n\t \r\n\t \r\n\t \r\n
\r\n
", + "patternPartial": "
\r\n
\r\n\t Search\r\n\t \r\n\t \r\n\t \r\n
\r\n
", + "patternName": "search", + "patternLink": "01-molecules-04-forms-00-search/01-molecules-04-forms-00-search.html", + "patternGroup": "molecules", + "patternSubGroup": "molecules\\04-forms", + "flatPatternPath": "01-molecules\\04-forms", + "key": "molecules-search", + "patternState": "", + "lineage": [], + "lineageIndex": [], + "lineageR": [], + "lineageRIndex": [] + } + ] + }; + + var lineage_hunter = new lh(); + lineage_hunter.find_lineage(currentPattern, patternlab); + + test.equals(currentPattern.lineageIndex.length, 3); + test.equals(currentPattern.lineageIndex[0], "atoms-logo"); + test.equals(currentPattern.lineageIndex[1], "molecules-primary-nav"); + test.equals(currentPattern.lineageIndex[2], "molecules-search"); + + test.done(); + }, + + 'find_lineage - finds lineage with spaced pattern parameters' : function (test) { + //setup current pattern from what we would have during execution + var currentPattern = createFakeEmptyErrorPattern(); + extend(currentPattern, { + "template": "{{> atoms-error(message: 'That\\'s no moon...') }}", + "patternPartial": "{{> atoms-error(message: 'That\\'s no moon...') }}" + }); + + var patternlab = { + patterns: [ + of.oPattern.create( + '/home/fakeuser/pl/source/_patterns/00-atoms/05-alerts/00-error.mustache', + '00-atoms\\05-alerts', + '00-error.mustache', + null, + { + "template": "

{{message}}

", + "patternPartial": "

{{message}}

" + } + ) + ] + }; + + var lineage_hunter = new lh(); + lineage_hunter.find_lineage(currentPattern, patternlab); + + test.equals(currentPattern.lineageIndex.length, 1); + test.equals(currentPattern.lineageIndex[0], "atoms-error"); + + test.done(); + }, + + 'find_lineage - finds lineage with unspaced pattern parameters' : function (test) { + //setup current pattern from what we would have during execution + var currentPattern = createFakeEmptyErrorPattern(); + extend(currentPattern, { + "template": "{{>atoms-error(message: 'That\\'s no moon...')}}", + "patternPartial": "{{>atoms-error(message: 'That\\'s no moon...')}}" + }); + + var patternlab = { + patterns: [ + { + "name": "01-atoms-05-alerts-00-error", + "subdir": "01-atoms\\05-alerts", + "filename": "00-error.mustache", + "data": null, + "template": "

{{message}}

", + "patternPartial": "

{{message}}

", + "patternName": "error", + "patternLink": "01-atoms-05-alerts-00-error/01-atoms-05-alerts-00-error.html", + "patternGroup": "atoms", + "patternSubGroup": "atoms\\05-alerts", + "flatPatternPath": "01-atoms\\05-alerts", + "key": "atoms-error", + "patternState": "", + "lineage": [], + "lineageIndex": [], + "lineageR": [], + "lineageRIndex": [] + } + ] + }; + + var lineage_hunter = new lh(); + lineage_hunter.find_lineage(currentPattern, patternlab); + + test.equals(currentPattern.lineageIndex.length, 1); + test.equals(currentPattern.lineageIndex[0], "atoms-error"); + test.equals(patternlab.patterns[0].lineageRIndex.length, 1); + test.equals(JSON.parse(patternlab.patterns[0].lineageR).lineagePattern, 'molecules-error'); + + test.done(); + }, + + 'find_lineage - finds lineage with spaced styleModifier' : function (test) { + //setup current pattern from what we would have during execution + var currentPattern = of.oPattern.createEmpty({ + "name": "01-molecules-01-toast-00-error", + "subdir": "01-molecules\\01-toast", + "filename": "00-error.mustache", + "data": null, + "template": "{{> atoms-error:foo }}", + "patternPartial": "{{> atoms-error:foo }}", + "patternName": "error", + "patternLink": "01-molecules-01-toast-00-error/01-molecules-01-toast-00-error.html", + "patternGroup": "molecules", + "patternSubGroup": "molecules\\01-toast", + "flatPatternPath": "01-molecules\\01-toast", + "key": "molecules-error", + "patternState": "", + "lineage": [], + "lineageIndex": [], + "lineageR": [], + "lineageRIndex": [] + }); + var patternlab = { + patterns: [ + of.oPattern.createEmpty({ + "name": "01-atoms-05-alerts-00-error", + "subdir": "01-atoms\\05-alerts", + "filename": "00-error.mustache", + "data": null, + "template": "

{{message}}

", + "patternPartial": "

{{message}}

", + "patternName": "error", + "patternLink": "01-atoms-05-alerts-00-error/01-atoms-05-alerts-00-error.html", + "patternGroup": "atoms", + "patternSubGroup": "atoms\\05-alerts", + "flatPatternPath": "01-atoms\\05-alerts", + "key": "atoms-error", + "patternState": "", + "lineage": [], + "lineageIndex": [], + "lineageR": [], + "lineageRIndex": [] + }) + ] + }; + + var lineage_hunter = new lh(); + lineage_hunter.find_lineage(currentPattern, patternlab); + + test.equals(currentPattern.lineageIndex.length, 1); + test.equals(currentPattern.lineageIndex[0], "atoms-error"); + + test.done(); + }, + + 'find_lineage - finds lineage with unspaced styleModifier' : function (test) { + //setup current pattern from what we would have during execution + var currentPattern = of.oPattern.createEmpty({ + "name": "01-molecules-01-toast-00-error", + "subdir": "01-molecules\\01-toast", + "filename": "00-error.mustache", + "data": null, + "template": "{{> atoms-error:foo }}", + "patternPartial": "{{>atoms-error:foo}}", + "patternName": "error", + "patternLink": "01-molecules-01-toast-00-error/01-molecules-01-toast-00-error.html", + "patternGroup": "molecules", + "patternSubGroup": "molecules\\01-toast", + "flatPatternPath": "01-molecules\\01-toast", + "key": "molecules-error", + "patternState": "", + "lineage": [], + "lineageIndex": [], + "lineageR": [], + "lineageRIndex": [] + }); + var patternlab = { + patterns: [ + of.oPattern.createEmpty({ + "name": "01-atoms-05-alerts-00-error", + "subdir": "01-atoms\\05-alerts", + "filename": "00-error.mustache", + "data": null, + "template": "

{{message}}

", + "patternPartial": "

{{message}}

", + "patternName": "error", + "patternLink": "01-atoms-05-alerts-00-error/01-atoms-05-alerts-00-error.html", + "patternGroup": "atoms", + "patternSubGroup": "atoms\\05-alerts", + "flatPatternPath": "01-atoms\\05-alerts", + "key": "atoms-error", + "patternState": "", + "lineage": [], + "lineageIndex": [], + "lineageR": [], + "lineageRIndex": [] + }) + ] + }; + + var lineage_hunter = new lh(); + lineage_hunter.find_lineage(currentPattern, patternlab); + + test.equals(currentPattern.lineageIndex.length, 1); + test.equals(currentPattern.lineageIndex[0], "atoms-error"); + + test.done(); + }, + + 'find_lineage - finds lineage with fuzzy partial with styleModifier' : function (test) { + //setup current pattern from what we would have during execution + var currentPattern = of.oPattern.createEmpty({ + "name": "01-molecules-01-toast-00-error", + "subdir": "01-molecules\\01-toast", + "filename": "00-error.mustache", + "data": null, + "template": "{{> atoms-e:foo }}", + "patternPartial": "{{>atoms-e:foo}}", + "patternName": "error", + "patternLink": "01-molecules-01-toast-00-error/01-molecules-01-toast-00-error.html", + "patternGroup": "molecules", + "patternSubGroup": "molecules\\01-toast", + "flatPatternPath": "01-molecules\\01-toast", + "key": "molecules-error", + "patternState": "", + "lineage": [], + "lineageIndex": [], + "lineageR": [], + "lineageRIndex": [] + }); + var patternlab = { + patterns: [ + of.oPattern.createEmpty({ + "name": "01-atoms-05-alerts-00-error", + "subdir": "01-atoms\\05-alerts", + "filename": "00-error.mustache", + "data": null, + "template": "

{{message}}

", + "patternPartial": "

{{message}}

", + "patternName": "error", + "patternLink": "01-atoms-05-alerts-00-error/01-atoms-05-alerts-00-error.html", + "patternGroup": "atoms", + "patternSubGroup": "atoms\\05-alerts", + "flatPatternPath": "01-atoms\\05-alerts", + "key": "atoms-error", + "patternState": "", + "lineage": [], + "lineageIndex": [], + "lineageR": [], + "lineageRIndex": [] + }) + ] + }; + + var lineage_hunter = new lh(); + lineage_hunter.find_lineage(currentPattern, patternlab); + + test.equals(currentPattern.lineageIndex.length, 1); + test.equals(currentPattern.lineageIndex[0], "atoms-error"); + + test.done(); + }, + + 'find_lineage - does not apply lineage twice' : function (test) { + //setup current pattern from what we would have during execution + var currentPattern = createFakeEmptyErrorPattern(); + extend(currentPattern, { + "template": "{{>atoms-error(message: 'That\\'s no moon...')}}", + "patternPartial": "{{>atoms-error(message: 'That\\'s no moon...')}}" + }); + var patternlab = { + patterns: [ + { + "name": "01-atoms-05-alerts-00-error", + "subdir": "01-atoms\\05-alerts", + "filename": "00-error.mustache", + "data": null, + "template": "

{{message}}

", + "patternPartial": "

{{message}}

", + "patternName": "error", + "patternLink": "01-atoms-05-alerts-00-error/01-atoms-05-alerts-00-error.html", + "patternGroup": "atoms", + "patternSubGroup": "atoms\\05-alerts", + "flatPatternPath": "01-atoms\\05-alerts", + "key": "atoms-error", + "patternState": "", + "lineage": [], + "lineageIndex": [], + "lineageR": [], + "lineageRIndex": [] + } + ] + }; + + var lineage_hunter = new lh(); + lineage_hunter.find_lineage(currentPattern, patternlab); + lineage_hunter.find_lineage(currentPattern, patternlab); + + test.equals(currentPattern.lineageIndex.length, 1); + test.equals(currentPattern.lineageIndex[0], "atoms-error"); + test.equals(patternlab.patterns[0].lineageRIndex.length, 1); + test.equals(JSON.parse(patternlab.patterns[0].lineageR).lineagePattern, 'molecules-error'); + + test.done(); } - exports['lineage hunter '] = { - 'find_lineage - finds lineage' : function(test){ - - //setup current pattern from what we would have during execution - var currentPattern = new of.oPattern( - '/home/fakeuser/pl/source/_patterns/02-organisms/00-global/00-header.mustache', // abspath - '02-organisms\\00-global', // subdir - '00-header.mustache', // filename, - null // data - ); - extend(currentPattern, { - "template": "\r\n
\r\n\t{{> atoms-logo }}\r\n\tSearch\r\n\tMenu\r\n\t{{> molecules-primary-nav }}\r\n\t{{> molecules-search }}\r\n
\r\n\r\n", - "patternPartial": "\r\n
\r\n\"Logo\tSearch\r\n\tMenu\r\n\r\n
\r\n
\r\n\t Search\r\n\t \r\n\t \r\n\t \r\n
\r\n
\r\n\r\n" - }); - - var patternlab = { - patterns: [ - { - "name": "00-atoms-03-images-00-logo", - "subdir": "00-atoms\\03-images", - "filename": "00-logo.mustache", - "data": null, - "template": "\"Logo", - "patternPartial": "\"Logo", - "patternName": "logo", - "patternLink": "00-atoms-03-images-00-logo/00-atoms-03-images-00-logo.html", - "patternGroup": "atoms", - "patternSubGroup": "atoms\\03-images", - "flatPatternPath": "00-atoms\\03-images", - "key": "atoms-logo", - "patternState": "", - "lineage": [], - "lineageIndex": [], - "lineageR": [], - "lineageRIndex": [] - }, - { - "name": "01-molecules-05-navigation-00-primary-nav", - "subdir": "01-molecules\\05-navigation", - "filename": "00-primary-nav.mustache", - "data": null, - "template": "\r\n", - "patternPartial": "\r\n", - "patternName": "primary-nav", - "patternLink": "01-molecules-05-navigation-00-primary-nav/01-molecules-05-navigation-00-primary-nav.html", - "patternGroup": "molecules", - "patternSubGroup": "molecules\\05-navigation", - "flatPatternPath": "01-molecules\\05-navigation", - "key": "molecules-primary-nav", - "patternState": "", - "lineage": [], - "lineageIndex": [], - "lineageR": [], - "lineageRIndex": [] - }, - { - "name": "01-molecules-04-forms-00-search", - "subdir": "01-molecules\\04-forms", - "filename": "00-search.mustache", - "data": null, - "template": "
\r\n
\r\n\t Search\r\n\t \r\n\t \r\n\t \r\n
\r\n
", - "patternPartial": "
\r\n
\r\n\t Search\r\n\t \r\n\t \r\n\t \r\n
\r\n
", - "patternName": "search", - "patternLink": "01-molecules-04-forms-00-search/01-molecules-04-forms-00-search.html", - "patternGroup": "molecules", - "patternSubGroup": "molecules\\04-forms", - "flatPatternPath": "01-molecules\\04-forms", - "key": "molecules-search", - "patternState": "", - "lineage": [], - "lineageIndex": [], - "lineageR": [], - "lineageRIndex": [] - } - ] - }; - - var lineage_hunter = new lh(); - lineage_hunter.find_lineage(currentPattern, patternlab); - - test.equals(currentPattern.lineageIndex.length, 3); - test.equals(currentPattern.lineageIndex[0], "atoms-logo"); - test.equals(currentPattern.lineageIndex[1], "molecules-primary-nav"); - test.equals(currentPattern.lineageIndex[2], "molecules-search"); - - test.done(); - }, - - 'find_lineage - finds lineage with spaced pattern parameters' : function(test){ - //setup current pattern from what we would have during execution - var currentPattern = createFakeEmptyErrorPattern(); - extend(currentPattern, { - "template": "{{> atoms-error(message: 'That\\'s no moon...') }}", - "patternPartial": "{{> atoms-error(message: 'That\\'s no moon...') }}" - }); - - var patternlab = { - patterns: [ - of.oPattern.create( - '/home/fakeuser/pl/source/_patterns/00-atoms/05-alerts/00-error.mustache', - '00-atoms\\05-alerts', - '00-error.mustache', - null, - { - "template": "

{{message}}

", - "patternPartial": "

{{message}}

" - } - ) - ] - }; - - var lineage_hunter = new lh(); - lineage_hunter.find_lineage(currentPattern, patternlab); - - test.equals(currentPattern.lineageIndex.length, 1); - test.equals(currentPattern.lineageIndex[0], "atoms-error"); - - test.done(); - }, - - 'find_lineage - finds lineage with unspaced pattern parameters' : function(test){ - //setup current pattern from what we would have during execution - var currentPattern = createFakeEmptyErrorPattern(); - extend(currentPattern, { - "template": "{{>atoms-error(message: 'That\\'s no moon...')}}", - "patternPartial": "{{>atoms-error(message: 'That\\'s no moon...')}}" - }); - - var patternlab = { - patterns: [ - { - "name": "01-atoms-05-alerts-00-error", - "subdir": "01-atoms\\05-alerts", - "filename": "00-error.mustache", - "data": null, - "template": "

{{message}}

", - "patternPartial": "

{{message}}

", - "patternName": "error", - "patternLink": "01-atoms-05-alerts-00-error/01-atoms-05-alerts-00-error.html", - "patternGroup": "atoms", - "patternSubGroup": "atoms\\05-alerts", - "flatPatternPath": "01-atoms\\05-alerts", - "key": "atoms-error", - "patternState": "", - "lineage": [], - "lineageIndex": [], - "lineageR": [], - "lineageRIndex": [] - } - ] - }; - - var lineage_hunter = new lh(); - lineage_hunter.find_lineage(currentPattern, patternlab); - - test.equals(currentPattern.lineageIndex.length, 1); - test.equals(currentPattern.lineageIndex[0], "atoms-error"); - test.equals(patternlab.patterns[0].lineageRIndex.length, 1); - test.equals(JSON.parse(patternlab.patterns[0].lineageR).lineagePattern, 'molecules-error'); - - test.done(); - }, - - 'find_lineage - finds lineage with spaced styleModifier' : function(test){ - //setup current pattern from what we would have during execution - var currentPattern = of.oPattern.createEmpty({ - "name": "01-molecules-01-toast-00-error", - "subdir": "01-molecules\\01-toast", - "filename": "00-error.mustache", - "data": null, - "template": "{{> atoms-error:foo }}", - "patternPartial": "{{> atoms-error:foo }}", - "patternName": "error", - "patternLink": "01-molecules-01-toast-00-error/01-molecules-01-toast-00-error.html", - "patternGroup": "molecules", - "patternSubGroup": "molecules\\01-toast", - "flatPatternPath": "01-molecules\\01-toast", - "key": "molecules-error", - "patternState": "", - "lineage": [], - "lineageIndex": [], - "lineageR": [], - "lineageRIndex": [] - }); - var patternlab = { - patterns: [ - of.oPattern.createEmpty({ - "name": "01-atoms-05-alerts-00-error", - "subdir": "01-atoms\\05-alerts", - "filename": "00-error.mustache", - "data": null, - "template": "

{{message}}

", - "patternPartial": "

{{message}}

", - "patternName": "error", - "patternLink": "01-atoms-05-alerts-00-error/01-atoms-05-alerts-00-error.html", - "patternGroup": "atoms", - "patternSubGroup": "atoms\\05-alerts", - "flatPatternPath": "01-atoms\\05-alerts", - "key": "atoms-error", - "patternState": "", - "lineage": [], - "lineageIndex": [], - "lineageR": [], - "lineageRIndex": [] - }) - ] - }; - - var lineage_hunter = new lh(); - lineage_hunter.find_lineage(currentPattern, patternlab); - - test.equals(currentPattern.lineageIndex.length, 1); - test.equals(currentPattern.lineageIndex[0], "atoms-error"); - - test.done(); - }, - - 'find_lineage - finds lineage with unspaced styleModifier' : function(test){ - //setup current pattern from what we would have during execution - var currentPattern = of.oPattern.createEmpty({ - "name": "01-molecules-01-toast-00-error", - "subdir": "01-molecules\\01-toast", - "filename": "00-error.mustache", - "data": null, - "template": "{{> atoms-error:foo }}", - "patternPartial": "{{>atoms-error:foo}}", - "patternName": "error", - "patternLink": "01-molecules-01-toast-00-error/01-molecules-01-toast-00-error.html", - "patternGroup": "molecules", - "patternSubGroup": "molecules\\01-toast", - "flatPatternPath": "01-molecules\\01-toast", - "key": "molecules-error", - "patternState": "", - "lineage": [], - "lineageIndex": [], - "lineageR": [], - "lineageRIndex": [] - }); - var patternlab = { - patterns: [ - of.oPattern.createEmpty({ - "name": "01-atoms-05-alerts-00-error", - "subdir": "01-atoms\\05-alerts", - "filename": "00-error.mustache", - "data": null, - "template": "

{{message}}

", - "patternPartial": "

{{message}}

", - "patternName": "error", - "patternLink": "01-atoms-05-alerts-00-error/01-atoms-05-alerts-00-error.html", - "patternGroup": "atoms", - "patternSubGroup": "atoms\\05-alerts", - "flatPatternPath": "01-atoms\\05-alerts", - "key": "atoms-error", - "patternState": "", - "lineage": [], - "lineageIndex": [], - "lineageR": [], - "lineageRIndex": [] - }) - ] - }; - - var lineage_hunter = new lh(); - lineage_hunter.find_lineage(currentPattern, patternlab); - - test.equals(currentPattern.lineageIndex.length, 1); - test.equals(currentPattern.lineageIndex[0], "atoms-error"); - - test.done(); - }, - - 'find_lineage - finds lineage with fuzzy partial with styleModifier' : function(test){ - //setup current pattern from what we would have during execution - var currentPattern = of.oPattern.createEmpty({ - "name": "01-molecules-01-toast-00-error", - "subdir": "01-molecules\\01-toast", - "filename": "00-error.mustache", - "data": null, - "template": "{{> atoms-e:foo }}", - "patternPartial": "{{>atoms-e:foo}}", - "patternName": "error", - "patternLink": "01-molecules-01-toast-00-error/01-molecules-01-toast-00-error.html", - "patternGroup": "molecules", - "patternSubGroup": "molecules\\01-toast", - "flatPatternPath": "01-molecules\\01-toast", - "key": "molecules-error", - "patternState": "", - "lineage": [], - "lineageIndex": [], - "lineageR": [], - "lineageRIndex": [] - }); - var patternlab = { - patterns: [ - of.oPattern.createEmpty({ - "name": "01-atoms-05-alerts-00-error", - "subdir": "01-atoms\\05-alerts", - "filename": "00-error.mustache", - "data": null, - "template": "

{{message}}

", - "patternPartial": "

{{message}}

", - "patternName": "error", - "patternLink": "01-atoms-05-alerts-00-error/01-atoms-05-alerts-00-error.html", - "patternGroup": "atoms", - "patternSubGroup": "atoms\\05-alerts", - "flatPatternPath": "01-atoms\\05-alerts", - "key": "atoms-error", - "patternState": "", - "lineage": [], - "lineageIndex": [], - "lineageR": [], - "lineageRIndex": [] - }) - ] - }; - - var lineage_hunter = new lh(); - lineage_hunter.find_lineage(currentPattern, patternlab); - - test.equals(currentPattern.lineageIndex.length, 1); - test.equals(currentPattern.lineageIndex[0], "atoms-error"); - - test.done(); - }, - - 'find_lineage - does not apply lineage twice' : function(test){ - //setup current pattern from what we would have during execution - var currentPattern = createFakeEmptyErrorPattern(); - extend(currentPattern, { - "template": "{{>atoms-error(message: 'That\\'s no moon...')}}", - "patternPartial": "{{>atoms-error(message: 'That\\'s no moon...')}}" - }); - var patternlab = { - patterns: [ - { - "name": "01-atoms-05-alerts-00-error", - "subdir": "01-atoms\\05-alerts", - "filename": "00-error.mustache", - "data": null, - "template": "

{{message}}

", - "patternPartial": "

{{message}}

", - "patternName": "error", - "patternLink": "01-atoms-05-alerts-00-error/01-atoms-05-alerts-00-error.html", - "patternGroup": "atoms", - "patternSubGroup": "atoms\\05-alerts", - "flatPatternPath": "01-atoms\\05-alerts", - "key": "atoms-error", - "patternState": "", - "lineage": [], - "lineageIndex": [], - "lineageR": [], - "lineageRIndex": [] - } - ] - }; - - var lineage_hunter = new lh(); - lineage_hunter.find_lineage(currentPattern, patternlab); - lineage_hunter.find_lineage(currentPattern, patternlab); - - test.equals(currentPattern.lineageIndex.length, 1); - test.equals(currentPattern.lineageIndex[0], "atoms-error"); - test.equals(patternlab.patterns[0].lineageRIndex.length, 1); - test.equals(JSON.parse(patternlab.patterns[0].lineageR).lineagePattern, 'molecules-error'); - - test.done(); - } - - }; - -})(); +}; From 3df94204d65dc9ed1e8836acf172d59733b8db7d Mon Sep 17 00:00:00 2001 From: e2tha-e Date: Wed, 16 Mar 2016 06:29:53 -0400 Subject: [PATCH 086/187] updating function name and docblock --- core/lib/pattern_engines/engine_mustache.js | 23 ++++++++++++--------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/core/lib/pattern_engines/engine_mustache.js b/core/lib/pattern_engines/engine_mustache.js index 2607d6f4f..2f48f3cf9 100644 --- a/core/lib/pattern_engines/engine_mustache.js +++ b/core/lib/pattern_engines/engine_mustache.js @@ -46,12 +46,15 @@ var engine_mustache = { return Mustache.render(template, data); }, - // find partials based on regex. - // @param {string|object} pattern - either a string or a pattern object. - // @param {object} regex - a JavaScript RegExp object. - // @returns {array} - partialsFinder: function partialsFinder(pattern, regex) { - var matches = []; + /** + * Find regex matches within both pattern strings and pattern objects. + * + * @param {string|object} pattern Either a string or a pattern object. + * @param {object} regex A JavaScript RegExp object. + * @returns {array|null} An array if a match is found, null if not. + */ + patternMatcher: function patternMatcher(pattern, regex) { + var matches; if (typeof pattern === 'string') { matches = pattern.match(regex); @@ -64,22 +67,22 @@ var engine_mustache = { // find and return any {{> template-name }} within pattern findPartials: function findPartials(pattern) { - var matches = this.partialsFinder(pattern, this.findPartialsRE); + var matches = this.patternMatcher(pattern, this.findPartialsRE); return matches; }, findPartialsWithStyleModifiers: function (pattern) { - var matches = this.partialsFinder(pattern, this.findPartialsWithStyleModifiersRE); + var matches = this.patternMatcher(pattern, this.findPartialsWithStyleModifiersRE); return matches; }, // returns any patterns that match {{> value(foo:"bar") }} or {{> // value:mod(foo:"bar") }} within the pattern findPartialsWithPatternParameters: function (pattern) { - var matches = this.partialsFinder(pattern, this.findPartialsWithPatternParametersRE); + var matches = this.patternMatcher(pattern, this.findPartialsWithPatternParametersRE); return matches; }, findListItems: function (pattern) { - var matches = this.partialsFinder(pattern, this.findListItemsRE); + var matches = this.patternMatcher(pattern, this.findListItemsRE); return matches; }, From 7f4d92d26cd2e342e94a786e629f4fb3a51fdce5 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Thu, 17 Mar 2016 14:32:19 -0500 Subject: [PATCH 087/187] Change underscore engine extension to html --- core/lib/pattern_engines/engine_underscore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/lib/pattern_engines/engine_underscore.js b/core/lib/pattern_engines/engine_underscore.js index 887c11d57..2496a4167 100644 --- a/core/lib/pattern_engines/engine_underscore.js +++ b/core/lib/pattern_engines/engine_underscore.js @@ -38,7 +38,7 @@ var engine_underscore = { engine: _, engineName: 'underscore', - engineFileExtension: '.underscore', + engineFileExtension: '.html', // partial expansion is only necessary for Mustache templates that have // style modifiers or pattern parameters (I think) From b66de48b08499245438f123961f62ab0c6648cb8 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Thu, 17 Mar 2016 14:49:51 -0500 Subject: [PATCH 088/187] rename underscore test templates to .html --- ...helloworld-withdata.underscore => 00-helloworld-withdata.html} | 0 .../00-global/{00-helloworld.underscore => 00-helloworld.html} | 0 ...ecule-data.underscore => 00-call-atom-with-molecule-data.html} | 0 .../00-global/{00-helloworlds.underscore => 00-helloworlds.html} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename test/files/_underscore-test-patterns/00-atoms/00-global/{00-helloworld-withdata.underscore => 00-helloworld-withdata.html} (100%) rename test/files/_underscore-test-patterns/00-atoms/00-global/{00-helloworld.underscore => 00-helloworld.html} (100%) rename test/files/_underscore-test-patterns/00-molecules/00-global/{00-call-atom-with-molecule-data.underscore => 00-call-atom-with-molecule-data.html} (100%) rename test/files/_underscore-test-patterns/00-molecules/00-global/{00-helloworlds.underscore => 00-helloworlds.html} (100%) diff --git a/test/files/_underscore-test-patterns/00-atoms/00-global/00-helloworld-withdata.underscore b/test/files/_underscore-test-patterns/00-atoms/00-global/00-helloworld-withdata.html similarity index 100% rename from test/files/_underscore-test-patterns/00-atoms/00-global/00-helloworld-withdata.underscore rename to test/files/_underscore-test-patterns/00-atoms/00-global/00-helloworld-withdata.html diff --git a/test/files/_underscore-test-patterns/00-atoms/00-global/00-helloworld.underscore b/test/files/_underscore-test-patterns/00-atoms/00-global/00-helloworld.html similarity index 100% rename from test/files/_underscore-test-patterns/00-atoms/00-global/00-helloworld.underscore rename to test/files/_underscore-test-patterns/00-atoms/00-global/00-helloworld.html diff --git a/test/files/_underscore-test-patterns/00-molecules/00-global/00-call-atom-with-molecule-data.underscore b/test/files/_underscore-test-patterns/00-molecules/00-global/00-call-atom-with-molecule-data.html similarity index 100% rename from test/files/_underscore-test-patterns/00-molecules/00-global/00-call-atom-with-molecule-data.underscore rename to test/files/_underscore-test-patterns/00-molecules/00-global/00-call-atom-with-molecule-data.html diff --git a/test/files/_underscore-test-patterns/00-molecules/00-global/00-helloworlds.underscore b/test/files/_underscore-test-patterns/00-molecules/00-global/00-helloworlds.html similarity index 100% rename from test/files/_underscore-test-patterns/00-molecules/00-global/00-helloworlds.underscore rename to test/files/_underscore-test-patterns/00-molecules/00-global/00-helloworlds.html From ba1b2327fe9fbff4099e520a59de15560e3646c1 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Thu, 17 Mar 2016 14:54:43 -0500 Subject: [PATCH 089/187] fix underscore unit tests --- test/engine_underscore_tests.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/engine_underscore_tests.js b/test/engine_underscore_tests.js index 0bea4b17b..a4f5eff80 100644 --- a/test/engine_underscore_tests.js +++ b/test/engine_underscore_tests.js @@ -45,7 +45,7 @@ testPatternsPath, '00-atoms', '00-global', - '00-helloworld.underscore' + '00-helloworld.html' ); // do all the normal processing of the pattern @@ -65,7 +65,7 @@ testPatternsPath, '00-atoms', '00-global', - '00-helloworld-withdata.underscore' + '00-helloworld-withdata.html' ); // set up environment From d63e274c4a5670b51a644cab2bf2bea05ae6c6a1 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 22 Mar 2016 17:12:37 -0500 Subject: [PATCH 090/187] Handle undefined variables in underscore templates --- core/lib/pattern_engines/engine_underscore.js | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/core/lib/pattern_engines/engine_underscore.js b/core/lib/pattern_engines/engine_underscore.js index 2496a4167..2965e92ec 100644 --- a/core/lib/pattern_engines/engine_underscore.js +++ b/core/lib/pattern_engines/engine_underscore.js @@ -53,10 +53,24 @@ // render it renderPattern: function renderPattern(template, data, partials) { var compiled = _.template(template); - return compiled(_.extend(data, { - _allData: data, - _partials: partials - })); + var renderedHTML; + + // This try-catch is necessary because references to undefined variables + // in underscore templates are eval()ed directly as javascript, and as + // such will throw very real exceptions that will shatter the whole build + // process if we don't handle them. + try { + renderedHTML = compiled(_.extend(data || {}, { + _allData: data, + _partials: partials + })); + } catch (e) { + var errorMessage = "WARNING: the underscore template " + template.fileName + " threw an exception; it probably just tried to reference an undefined variable. Is this pattern maybe missing a .json file?"; + console.log(errorMessage, e); + renderedHTML = "

Error in underscore template

" + errorMessage; + } + + return renderedHTML; }, // registerPartial: function (oPattern) { From 70e5330443a215e9199212f032b0b440133dd942 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Thu, 24 Mar 2016 14:26:15 -0500 Subject: [PATCH 091/187] factor out the UI Builder into its own module -- just get it working for now. --- core/lib/patternlab.js | 371 +--------------------------------------- core/lib/ui_builder.js | 378 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 386 insertions(+), 363 deletions(-) create mode 100644 core/lib/ui_builder.js diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 3b37e8abb..77260cf71 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -1,10 +1,10 @@ -/* - * patternlab-node - v1.2.0 - 2016 - * +/* + * patternlab-node - v1.2.0 - 2016 + * * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ @@ -14,13 +14,11 @@ var patternlab_engine = function (config) { var path = require('path'), fs = require('fs-extra'), diveSync = require('diveSync'), - of = require('./object_factory'), pa = require('./pattern_assembler'), - mh = require('./media_hunter'), pe = require('./pattern_exporter'), lh = require('./lineage_hunter'), + buildFrontEnd = require('./ui_builder'), he = require('html-entities').AllHtmlEntities, - util = require('util'), plutils = require('./utilities'), patternlab = {}; @@ -238,360 +236,7 @@ var patternlab_engine = function (config) { pattern_exporter.export_patterns(patternlab); } - function buildFrontEnd() { - var pattern_assembler = new pa(), - media_hunter = new mh(), - styleGuideExcludes = patternlab.config.styleGuideExcludes, - styleguidePatterns = [], - i; - - patternlab.buckets = []; - patternlab.bucketIndex = []; - patternlab.patternPaths = {}; - patternlab.viewAllPaths = {}; - - //sort all patterns explicitly. - patternlab.patterns = patternlab.patterns.sort(function (a, b) { - if (a.name > b.name) { - return 1; - } - if (a.name < b.name) { - return -1; - } - - // a must be equal to b - return 0; - }); - - //find mediaQueries - media_hunter.find_media_queries('./source/css', patternlab); - - // check if patterns are excluded, if not add them to styleguidePatterns - if (styleGuideExcludes && styleGuideExcludes.length) { - for (i = 0; i < patternlab.patterns.length; i++) { - - // skip underscore-prefixed files - if (isPatternExcluded(patternlab.patterns[i])) { - if (patternlab.config.debug) { - console.log('Omitting ' + patternlab.patterns[i].key + " from styleguide pattern exclusion."); - } - continue; - } - - var key = patternlab.patterns[i].key; - var typeKey = key.substring(0, key.indexOf('-')); - var isExcluded = (styleGuideExcludes.indexOf(typeKey) > -1); - if (!isExcluded) { - styleguidePatterns.push(patternlab.patterns[i]); - } - } - } else { - styleguidePatterns = patternlab.patterns; - } - - //also add the cachebuster value. slight chance this could collide with a user that has defined cacheBuster as a value - patternlab.data.cacheBuster = patternlab.cacheBuster; - - //get the main page head and foot - var mainPageHead = patternlab.userHead.extendedTemplate.replace('{% pattern-lab-head %}', patternlab.header); - var mainPageHeadHtml = pattern_assembler.renderPattern(mainPageHead, patternlab.data); - var mainPageFoot = patternlab.userFoot.extendedTemplate.replace('{% pattern-lab-foot %}', patternlab.footer); - var mainPageFootHtml = pattern_assembler.renderPattern(mainPageFoot, patternlab.data); - - //build the styleguide - var styleguideTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/styleguide.mustache'), 'utf8'), - styleguideHtml = pattern_assembler.renderPattern(styleguideTemplate, {partials: styleguidePatterns, cacheBuster: patternlab.cacheBuster}); - - fs.outputFileSync(path.resolve(paths.public.styleguide, 'html/styleguide.html'), mainPageHeadHtml + styleguideHtml + mainPageFootHtml); - - //build the viewall pages - var prevSubdir = '', - prevGroup = '', - i; - - for (i = 0; i < patternlab.patterns.length; i++) { - // skip underscore-prefixed files - if (isPatternExcluded(patternlab.patterns[i])) { - if (patternlab.config.debug) { - console.log('Omitting ' + patternlab.patterns[i].key + " from view all rendering."); - } - continue; - } - - var pattern = patternlab.patterns[i]; - - //create the view all for the section - // check if the current section is different from the previous one - if (pattern.patternGroup !== prevGroup) { - prevGroup = pattern.patternGroup; - - var viewAllPatterns = [], - patternPartial = "viewall-" + pattern.patternGroup, - j; - - for (j = 0; j < patternlab.patterns.length; j++) { - if (patternlab.patterns[j].patternGroup === pattern.patternGroup) { - //again, skip any sibling patterns to the current one that may have underscores - if (isPatternExcluded(patternlab.patterns[j])) { - if (patternlab.config.debug) { - console.log('Omitting ' + patternlab.patterns[j].key + " from view all sibling rendering."); - } - continue; - } - - viewAllPatterns.push(patternlab.patterns[j]); - } - } - - var viewAllTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/viewall.mustache'), 'utf8'); - var viewAllHtml = pattern_assembler.renderPattern(viewAllTemplate, {partials: viewAllPatterns, patternPartial: patternPartial, cacheBuster: patternlab.cacheBuster }); - fs.outputFileSync(paths.public.patterns + pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length) + '/index.html', mainPageHead + viewAllHtml + mainPageFoot); - } - - //create the view all for the subsection - // check if the current sub section is different from the previous one - if (pattern.subdir !== prevSubdir) { - prevSubdir = pattern.subdir; - - viewAllPatterns = []; - patternPartial = "viewall-" + pattern.patternGroup + "-" + pattern.patternSubGroup; - - for (j = 0; j < patternlab.patterns.length; j++) { - if (patternlab.patterns[j].subdir === pattern.subdir) { - //again, skip any sibling patterns to the current one that may have underscores - if (isPatternExcluded(patternlab.patterns[j])) { - if (patternlab.config.debug) { - console.log('Omitting ' + patternlab.patterns[j].key + " from view all sibling rendering."); - } - continue; - } - - viewAllPatterns.push(patternlab.patterns[j]); - } - } - - var viewAllTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/viewall.mustache'), 'utf8'); - var viewAllHtml = pattern_assembler.renderPattern(viewAllTemplate, {partials: viewAllPatterns, patternPartial: patternPartial, cacheBuster: patternlab.cacheBuster}); - fs.outputFileSync(paths.public.patterns + pattern.flatPatternPath + '/index.html', mainPageHeadHtml + viewAllHtml + mainPageFootHtml); - } - } - - //build the patternlab website - var patternlabSiteTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/index.mustache'), 'utf8'); - - //loop through all patterns.to build the navigation - //todo: refactor this someday - for (i = 0; i < patternlab.patterns.length; i++) { - - pattern = patternlab.patterns[i]; - var bucketName = pattern.name.replace(/\\/g, '-').split('-')[1]; - - //check if the bucket already exists - var bucketIndex = patternlab.bucketIndex.indexOf(bucketName); - if (bucketIndex === -1) { - - // skip underscore-prefixed files. don't create a bucket on account of an underscored pattern - if (isPatternExcluded(pattern)) { - continue; - } - - //add the bucket - var bucket = new of.oBucket(bucketName); - - //add patternPath and viewAllPath - patternlab.patternPaths[bucketName] = {}; - patternlab.viewAllPaths[bucketName] = {}; - //get the navItem - var navItemName = pattern.subdir.split('/').pop(); - navItemName = navItemName.replace(/(\d).(-)/g, ''); - - //get the navSubItem - var navSubItemName = pattern.patternName.replace(/-/g, ' '); - - //test whether the pattern struture is flat or not - usually due to a template or page - var flatPatternItem = false; - if (navItemName === bucketName) { - flatPatternItem = true; - } - - //assume the navItem does not exist. - var navItem = new of.oNavItem(navItemName); - - //assume the navSubItem does not exist. - var navSubItem = new of.oNavSubItem(navSubItemName); - navSubItem.patternPath = pattern.patternLink; - navSubItem.patternPartial = bucketName + "-" + pattern.patternName; //add the hyphenated name - - //add the patternState if it exists - if (pattern.patternState) { - navSubItem.patternState = pattern.patternState; - } - - //if it is flat - we should not add the pattern to patternPaths - if (flatPatternItem) { - - bucket.patternItems.push(navSubItem); - - //add to patternPaths - addToPatternPaths(bucketName, pattern); - - } else { - - bucket.navItems.push(navItem); - bucket.navItemsIndex.push(navItemName); - navItem.navSubItems.push(navSubItem); - navItem.navSubItemsIndex.push(navSubItemName); - - //add to patternPaths - addToPatternPaths(bucketName, pattern); - - //add the navViewAllItem - var navViewAllItem = new of.oNavSubItem("View All"); - navViewAllItem.patternPath = pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length) + "/index.html"; - navViewAllItem.patternPartial = "viewall-" + pattern.patternGroup; - - bucket.patternItems.push(navViewAllItem); - patternlab.viewAllPaths[bucketName].viewall = pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length); - - } - - //add the bucket. - patternlab.buckets.push(bucket); - patternlab.bucketIndex.push(bucketName); - - //done - - } else { - //find the bucket - bucket = patternlab.buckets[bucketIndex]; - - //get the navItem - //if there is one or more slashes in the subdir, get everything after - //the last slash. if no slash, get the whole subdir string and strip - //any numeric + hyphen prefix - navItemName = pattern.subdir.split('/').pop().replace(/^\d*\-/, ''); - - //get the navSubItem - navSubItemName = pattern.patternName.replace(/-/g, ' '); - - //assume the navSubItem does not exist. - navSubItem = new of.oNavSubItem(navSubItemName); - navSubItem.patternPath = pattern.patternLink; - navSubItem.patternPartial = bucketName + "-" + pattern.patternName; //add the hyphenated name - - //add the patternState if it exists - if (pattern.patternState) { - navSubItem.patternState = pattern.patternState; - } - - //test whether the pattern struture is flat or not - usually due to a template or page - flatPatternItem = false; - if (navItemName === bucketName) { - flatPatternItem = true; - } - - //if it is flat - we should not add the pattern to patternPaths - if (flatPatternItem) { - - // skip underscore-prefixed files - if (isPatternExcluded(pattern)) { - continue; - } - - //add the navItem to patternItems - bucket.patternItems.push(navSubItem); - - //add to patternPaths - addToPatternPaths(bucketName, pattern); - - } else { - - // only do this if pattern is included - if (!isPatternExcluded(pattern)) { - //check to see if navItem exists - var navItemIndex = bucket.navItemsIndex.indexOf(navItemName); - if (navItemIndex === -1) { - navItem = new of.oNavItem(navItemName); - - //add the navItem and navSubItem - navItem.navSubItems.push(navSubItem); - navItem.navSubItemsIndex.push(navSubItemName); - bucket.navItems.push(navItem); - bucket.navItemsIndex.push(navItemName); - - } else { - //add the navSubItem - navItem = bucket.navItems[navItemIndex]; - navItem.navSubItems.push(navSubItem); - navItem.navSubItemsIndex.push(navSubItemName); - } - } - - //check if we are moving to a new sub section in the next loop - if (!patternlab.patterns[i + 1] || pattern.patternSubGroup !== patternlab.patterns[i + 1].patternSubGroup) { - - //add the navViewAllSubItem - var navViewAllSubItem = new of.oNavSubItem(""); - navViewAllSubItem.patternName = "View All"; - navViewAllSubItem.patternPath = pattern.flatPatternPath + "/index.html"; - navViewAllSubItem.patternPartial = "viewall-" + pattern.patternGroup + "-" + pattern.patternSubGroup; - - navItem.navSubItems.push(navViewAllSubItem); - navItem.navSubItemsIndex.push("View All"); - } - - // just add to patternPaths - addToPatternPaths(bucketName, pattern); - } - - } - - patternlab.viewAllPaths[bucketName][pattern.patternSubGroup] = pattern.flatPatternPath; - - } - - //the patternlab site requires a lot of partials to be rendered. - //patternNav - var patternNavTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/patternNav.mustache'), 'utf8'); - var patternNavPartialHtml = pattern_assembler.renderPattern(patternNavTemplate, patternlab); - - //ishControls - var ishControlsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/ishControls.mustache'), 'utf8'); - patternlab.config.mqs = patternlab.mediaQueries; - var ishControlsPartialHtml = pattern_assembler.renderPattern(ishControlsTemplate, patternlab.config); - - //patternPaths - var patternPathsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/patternPaths.mustache'), 'utf8'); - var patternPathsPartialHtml = pattern_assembler.renderPattern(patternPathsTemplate, {'patternPaths': JSON.stringify(patternlab.patternPaths)}); - - //viewAllPaths - var viewAllPathsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/viewAllPaths.mustache'), 'utf8'); - var viewAllPathsPartialHtml = pattern_assembler.renderPattern(viewAllPathsTemplate, {'viewallpaths': JSON.stringify(patternlab.viewAllPaths)}); - - //render the patternlab template, with all partials - var patternlabSiteHtml = pattern_assembler.renderPattern(patternlabSiteTemplate, { - defaultPattern: patternlab.config.defaultPattern || 'all', - cacheBuster: patternlab.cacheBuster - }, { - 'ishControls': ishControlsPartialHtml, - 'patternNav': patternNavPartialHtml, - 'patternPaths': patternPathsPartialHtml, - 'viewAllPaths': viewAllPathsPartialHtml - }); - fs.outputFileSync(path.resolve(paths.public.root, 'index.html'), patternlabSiteHtml); - } - - function addToPatternPaths(bucketName, pattern) { - //this is messy, could use a refactor. - patternlab.patternPaths[bucketName][pattern.patternName] = pattern.subdir.replace(/\\/g, '/') + "/" + pattern.fileName; - } - - //todo: refactor this as a method on the pattern object itself once we merge dev with pattern-engines branch - function isPatternExcluded(pattern) { - // returns whether or not the first character of the pattern filename is an underscore, or excluded - return pattern.fileName.charAt(0) === '_'; - } return { version: function () { @@ -599,7 +244,7 @@ var patternlab_engine = function (config) { }, build: function (deletePatternDir) { buildPatterns(deletePatternDir); - buildFrontEnd(); + buildFrontEnd(patternlab); printDebug(); }, help: function () { diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js new file mode 100644 index 000000000..c6901002a --- /dev/null +++ b/core/lib/ui_builder.js @@ -0,0 +1,378 @@ +/* + * patternlab-node - v1.2.0 - 2016 + * + * Brian Muenzenmeyer, Geoffrey Pursell, and the web community. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * + */ + +"use strict"; + + +// PRIVATE FUNCTIONS + +function addToPatternPaths(patternlab, bucketName, pattern) { + //this is messy, could use a refactor. + patternlab.patternPaths[bucketName][pattern.patternName] = pattern.subdir.replace(/\\/g, '/') + "/" + pattern.fileName; +} + +//todo: refactor this as a method on the pattern object itself once we merge dev with pattern-engines branch +function isPatternExcluded(pattern) { + // returns whether or not the first character of the pattern filename is an underscore, or excluded + return pattern.fileName.charAt(0) === '_'; +} + + +// MAIN BUILDER FUNCTION + +function buildFrontEnd(patternlab) { + var path = require('path'); + var fs = require('fs-extra'); + var pa = require('./pattern_assembler'); + var of = require('./object_factory'); + var mh = require('./media_hunter'); + var pattern_assembler = new pa(); + var media_hunter = new mh(); + var styleGuideExcludes = patternlab.config.styleGuideExcludes; + var styleguidePatterns = []; + var paths = patternlab.config.paths; + var i; + + patternlab.buckets = []; + patternlab.bucketIndex = []; + patternlab.patternPaths = {}; + patternlab.viewAllPaths = {}; + + //sort all patterns explicitly. + patternlab.patterns = patternlab.patterns.sort(function (a, b) { + if (a.name > b.name) { + return 1; + } + if (a.name < b.name) { + return -1; + } + + // a must be equal to b + return 0; + }); + + //find mediaQueries + media_hunter.find_media_queries('./source/css', patternlab); + + // check if patterns are excluded, if not add them to styleguidePatterns + if (styleGuideExcludes && styleGuideExcludes.length) { + for (i = 0; i < patternlab.patterns.length; i++) { + + // skip underscore-prefixed files + if (isPatternExcluded(patternlab.patterns[i])) { + if (patternlab.config.debug) { + console.log('Omitting ' + patternlab.patterns[i].key + " from styleguide pattern exclusion."); + } + continue; + } + + var key = patternlab.patterns[i].key; + var typeKey = key.substring(0, key.indexOf('-')); + var isExcluded = (styleGuideExcludes.indexOf(typeKey) > -1); + if (!isExcluded) { + styleguidePatterns.push(patternlab.patterns[i]); + } + } + } else { + styleguidePatterns = patternlab.patterns; + } + + //also add the cachebuster value. slight chance this could collide with a user that has defined cacheBuster as a value + patternlab.data.cacheBuster = patternlab.cacheBuster; + + //get the main page head and foot + var mainPageHead = patternlab.userHead.extendedTemplate.replace('{% pattern-lab-head %}', patternlab.header); + var mainPageHeadHtml = pattern_assembler.renderPattern(mainPageHead, patternlab.data); + var mainPageFoot = patternlab.userFoot.extendedTemplate.replace('{% pattern-lab-foot %}', patternlab.footer); + var mainPageFootHtml = pattern_assembler.renderPattern(mainPageFoot, patternlab.data); + + //build the styleguide + var styleguideTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/styleguide.mustache'), 'utf8'); + var styleguideHtml = pattern_assembler.renderPattern(styleguideTemplate, {partials: styleguidePatterns, cacheBuster: patternlab.cacheBuster}); + + fs.outputFileSync(path.resolve(paths.public.styleguide, 'html/styleguide.html'), mainPageHeadHtml + styleguideHtml + mainPageFootHtml); + + //build the viewall pages + var prevSubdir = ''; + var prevGroup = ''; + var i; + + for (i = 0; i < patternlab.patterns.length; i++) { + // skip underscore-prefixed files + if (isPatternExcluded(patternlab.patterns[i])) { + if (patternlab.config.debug) { + console.log('Omitting ' + patternlab.patterns[i].key + " from view all rendering."); + } + continue; + } + + var pattern = patternlab.patterns[i]; + + //create the view all for the section + // check if the current section is different from the previous one + if (pattern.patternGroup !== prevGroup) { + prevGroup = pattern.patternGroup; + + var viewAllPatterns = []; + var patternPartial = "viewall-" + pattern.patternGroup; + var j; + + for (j = 0; j < patternlab.patterns.length; j++) { + if (patternlab.patterns[j].patternGroup === pattern.patternGroup) { + //again, skip any sibling patterns to the current one that may have underscores + if (isPatternExcluded(patternlab.patterns[j])) { + if (patternlab.config.debug) { + console.log('Omitting ' + patternlab.patterns[j].key + " from view all sibling rendering."); + } + continue; + } + + viewAllPatterns.push(patternlab.patterns[j]); + } + } + + var viewAllTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/viewall.mustache'), 'utf8'); + var viewAllHtml = pattern_assembler.renderPattern(viewAllTemplate, {partials: viewAllPatterns, patternPartial: patternPartial, cacheBuster: patternlab.cacheBuster }); + fs.outputFileSync(paths.public.patterns + pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length) + '/index.html', mainPageHead + viewAllHtml + mainPageFoot); + } + + //create the view all for the subsection + // check if the current sub section is different from the previous one + if (pattern.subdir !== prevSubdir) { + prevSubdir = pattern.subdir; + + viewAllPatterns = []; + patternPartial = "viewall-" + pattern.patternGroup + "-" + pattern.patternSubGroup; + + for (j = 0; j < patternlab.patterns.length; j++) { + if (patternlab.patterns[j].subdir === pattern.subdir) { + //again, skip any sibling patterns to the current one that may have underscores + if (isPatternExcluded(patternlab.patterns[j])) { + if (patternlab.config.debug) { + console.log('Omitting ' + patternlab.patterns[j].key + " from view all sibling rendering."); + } + continue; + } + + viewAllPatterns.push(patternlab.patterns[j]); + } + } + + var viewAllTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/viewall.mustache'), 'utf8'); + var viewAllHtml = pattern_assembler.renderPattern(viewAllTemplate, {partials: viewAllPatterns, patternPartial: patternPartial, cacheBuster: patternlab.cacheBuster}); + fs.outputFileSync(paths.public.patterns + pattern.flatPatternPath + '/index.html', mainPageHeadHtml + viewAllHtml + mainPageFootHtml); + } + } + + //build the patternlab website + var patternlabSiteTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/index.mustache'), 'utf8'); + + //loop through all patterns.to build the navigation + //todo: refactor this someday + for (i = 0; i < patternlab.patterns.length; i++) { + + pattern = patternlab.patterns[i]; + var bucketName = pattern.name.replace(/\\/g, '-').split('-')[1]; + + //check if the bucket already exists + var bucketIndex = patternlab.bucketIndex.indexOf(bucketName); + if (bucketIndex === -1) { + + // skip underscore-prefixed files. don't create a bucket on account of an underscored pattern + if (isPatternExcluded(pattern)) { + continue; + } + + //add the bucket + var bucket = new of.oBucket(bucketName); + + //add patternPath and viewAllPath + patternlab.patternPaths[bucketName] = {}; + patternlab.viewAllPaths[bucketName] = {}; + + //get the navItem + var navItemName = pattern.subdir.split('/').pop(); + navItemName = navItemName.replace(/(\d).(-)/g, ''); + + //get the navSubItem + var navSubItemName = pattern.patternName.replace(/-/g, ' '); + + //test whether the pattern struture is flat or not - usually due to a template or page + var flatPatternItem = false; + if (navItemName === bucketName) { + flatPatternItem = true; + } + + //assume the navItem does not exist. + var navItem = new of.oNavItem(navItemName); + + //assume the navSubItem does not exist. + var navSubItem = new of.oNavSubItem(navSubItemName); + navSubItem.patternPath = pattern.patternLink; + navSubItem.patternPartial = bucketName + "-" + pattern.patternName; //add the hyphenated name + + //add the patternState if it exists + if (pattern.patternState) { + navSubItem.patternState = pattern.patternState; + } + + //if it is flat - we should not add the pattern to patternPaths + if (flatPatternItem) { + + bucket.patternItems.push(navSubItem); + + //add to patternPaths + addToPatternPaths(patternlab, bucketName, pattern); + + } else { + + bucket.navItems.push(navItem); + bucket.navItemsIndex.push(navItemName); + navItem.navSubItems.push(navSubItem); + navItem.navSubItemsIndex.push(navSubItemName); + + //add to patternPaths + addToPatternPaths(patternlab, bucketName, pattern); + + //add the navViewAllItem + var navViewAllItem = new of.oNavSubItem("View All"); + navViewAllItem.patternPath = pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length) + "/index.html"; + navViewAllItem.patternPartial = "viewall-" + pattern.patternGroup; + + bucket.patternItems.push(navViewAllItem); + patternlab.viewAllPaths[bucketName].viewall = pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length); + + } + + //add the bucket. + patternlab.buckets.push(bucket); + patternlab.bucketIndex.push(bucketName); + + //done + + } else { + //find the bucket + bucket = patternlab.buckets[bucketIndex]; + + //get the navItem + //if there is one or more slashes in the subdir, get everything after + //the last slash. if no slash, get the whole subdir string and strip + //any numeric + hyphen prefix + navItemName = pattern.subdir.split('/').pop().replace(/^\d*\-/, ''); + + //get the navSubItem + navSubItemName = pattern.patternName.replace(/-/g, ' '); + + //assume the navSubItem does not exist. + navSubItem = new of.oNavSubItem(navSubItemName); + navSubItem.patternPath = pattern.patternLink; + navSubItem.patternPartial = bucketName + "-" + pattern.patternName; //add the hyphenated name + + //add the patternState if it exists + if (pattern.patternState) { + navSubItem.patternState = pattern.patternState; + } + + //test whether the pattern struture is flat or not - usually due to a template or page + flatPatternItem = false; + if (navItemName === bucketName) { + flatPatternItem = true; + } + + //if it is flat - we should not add the pattern to patternPaths + if (flatPatternItem) { + + // skip underscore-prefixed files + if (isPatternExcluded(pattern)) { + continue; + } + + //add the navItem to patternItems + bucket.patternItems.push(navSubItem); + + //add to patternPaths + addToPatternPaths(patternlab, bucketName, pattern); + + } else { + + // only do this if pattern is included + if (!isPatternExcluded(pattern)) { + //check to see if navItem exists + var navItemIndex = bucket.navItemsIndex.indexOf(navItemName); + if (navItemIndex === -1) { + navItem = new of.oNavItem(navItemName); + + //add the navItem and navSubItem + navItem.navSubItems.push(navSubItem); + navItem.navSubItemsIndex.push(navSubItemName); + bucket.navItems.push(navItem); + bucket.navItemsIndex.push(navItemName); + + } else { + //add the navSubItem + navItem = bucket.navItems[navItemIndex]; + navItem.navSubItems.push(navSubItem); + navItem.navSubItemsIndex.push(navSubItemName); + } + } + + //check if we are moving to a new sub section in the next loop + if (!patternlab.patterns[i + 1] || pattern.patternSubGroup !== patternlab.patterns[i + 1].patternSubGroup) { + + //add the navViewAllSubItem + var navViewAllSubItem = new of.oNavSubItem(""); + navViewAllSubItem.patternName = "View All"; + navViewAllSubItem.patternPath = pattern.flatPatternPath + "/index.html"; + navViewAllSubItem.patternPartial = "viewall-" + pattern.patternGroup + "-" + pattern.patternSubGroup; + + navItem.navSubItems.push(navViewAllSubItem); + navItem.navSubItemsIndex.push("View All"); + } + + // just add to patternPaths + addToPatternPaths(patternlab, bucketName, pattern); + } + } + + patternlab.viewAllPaths[bucketName][pattern.patternSubGroup] = pattern.flatPatternPath; + } + + //the patternlab site requires a lot of partials to be rendered. + //patternNav + var patternNavTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/patternNav.mustache'), 'utf8'); + var patternNavPartialHtml = pattern_assembler.renderPattern(patternNavTemplate, patternlab); + + //ishControls + var ishControlsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/ishControls.mustache'), 'utf8'); + patternlab.config.mqs = patternlab.mediaQueries; + var ishControlsPartialHtml = pattern_assembler.renderPattern(ishControlsTemplate, patternlab.config); + + //patternPaths + var patternPathsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/patternPaths.mustache'), 'utf8'); + var patternPathsPartialHtml = pattern_assembler.renderPattern(patternPathsTemplate, {'patternPaths': JSON.stringify(patternlab.patternPaths)}); + + //viewAllPaths + var viewAllPathsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/viewAllPaths.mustache'), 'utf8'); + var viewAllPathsPartialHtml = pattern_assembler.renderPattern(viewAllPathsTemplate, {'viewallpaths': JSON.stringify(patternlab.viewAllPaths)}); + + //render the patternlab template, with all partials + var patternlabSiteHtml = pattern_assembler.renderPattern(patternlabSiteTemplate, { + defaultPattern: patternlab.config.defaultPattern || 'all', + cacheBuster: patternlab.cacheBuster + }, { + 'ishControls': ishControlsPartialHtml, + 'patternNav': patternNavPartialHtml, + 'patternPaths': patternPathsPartialHtml, + 'viewAllPaths': viewAllPathsPartialHtml + }); + fs.outputFileSync(path.resolve(paths.public.root, 'index.html'), patternlabSiteHtml); +} + +module.exports = buildFrontEnd; From 3febce8444e340722a3cff93eb8612a9513c68a2 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Thu, 24 Mar 2016 14:39:06 -0500 Subject: [PATCH 092/187] factor out assembleStyleguidePatterns() --- core/lib/ui_builder.js | 54 +++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index c6901002a..dc3c15d3f 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -24,6 +24,37 @@ function isPatternExcluded(pattern) { return pattern.fileName.charAt(0) === '_'; } +// Returns the array of patterns to be rendered in the styleguide view and +// linked to in the pattern navigation. Checks if patterns are excluded. +function assembleStyleguidePatterns(patternlab) { + var styleguideExcludes = patternlab.config.styleGuideExcludes; + var styleguidePatterns = []; + + if (styleguideExcludes && styleguideExcludes.length) { + for (var i = 0; i < patternlab.patterns.length; i++) { + + // skip underscore-prefixed files + if (isPatternExcluded(patternlab.patterns[i])) { + if (patternlab.config.debug) { + console.log('Omitting ' + patternlab.patterns[i].key + " from styleguide pattern exclusion."); + } + continue; + } + + var key = patternlab.patterns[i].key; + var typeKey = key.substring(0, key.indexOf('-')); + var isExcluded = (styleguideExcludes.indexOf(typeKey) > -1); + if (!isExcluded) { + styleguidePatterns.push(patternlab.patterns[i]); + } + } + } else { + styleguidePatterns = patternlab.patterns; + } + + return styleguidePatterns; +} + // MAIN BUILDER FUNCTION @@ -35,7 +66,6 @@ function buildFrontEnd(patternlab) { var mh = require('./media_hunter'); var pattern_assembler = new pa(); var media_hunter = new mh(); - var styleGuideExcludes = patternlab.config.styleGuideExcludes; var styleguidePatterns = []; var paths = patternlab.config.paths; var i; @@ -62,27 +92,7 @@ function buildFrontEnd(patternlab) { media_hunter.find_media_queries('./source/css', patternlab); // check if patterns are excluded, if not add them to styleguidePatterns - if (styleGuideExcludes && styleGuideExcludes.length) { - for (i = 0; i < patternlab.patterns.length; i++) { - - // skip underscore-prefixed files - if (isPatternExcluded(patternlab.patterns[i])) { - if (patternlab.config.debug) { - console.log('Omitting ' + patternlab.patterns[i].key + " from styleguide pattern exclusion."); - } - continue; - } - - var key = patternlab.patterns[i].key; - var typeKey = key.substring(0, key.indexOf('-')); - var isExcluded = (styleGuideExcludes.indexOf(typeKey) > -1); - if (!isExcluded) { - styleguidePatterns.push(patternlab.patterns[i]); - } - } - } else { - styleguidePatterns = patternlab.patterns; - } + styleguidePatterns = assembleStyleguidePatterns(patternlab); //also add the cachebuster value. slight chance this could collide with a user that has defined cacheBuster as a value patternlab.data.cacheBuster = patternlab.cacheBuster; From a6822962781d521de97ee637104947f3834da2bf Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Thu, 24 Mar 2016 14:51:15 -0500 Subject: [PATCH 093/187] factor out buildViewAllPages() --- core/lib/ui_builder.js | 109 +++++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 52 deletions(-) diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index dc3c15d3f..235e3499a 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -10,6 +10,8 @@ "use strict"; +var path = require('path'); +var fs = require('fs-extra'); // PRIVATE FUNCTIONS @@ -58,58 +60,8 @@ function assembleStyleguidePatterns(patternlab) { // MAIN BUILDER FUNCTION -function buildFrontEnd(patternlab) { - var path = require('path'); - var fs = require('fs-extra'); - var pa = require('./pattern_assembler'); - var of = require('./object_factory'); - var mh = require('./media_hunter'); - var pattern_assembler = new pa(); - var media_hunter = new mh(); - var styleguidePatterns = []; +function buildViewAllPages(mainPageHead, mainPageFoot, mainPageHeadHtml, mainPageFootHtml, pattern_assembler, patternlab) { var paths = patternlab.config.paths; - var i; - - patternlab.buckets = []; - patternlab.bucketIndex = []; - patternlab.patternPaths = {}; - patternlab.viewAllPaths = {}; - - //sort all patterns explicitly. - patternlab.patterns = patternlab.patterns.sort(function (a, b) { - if (a.name > b.name) { - return 1; - } - if (a.name < b.name) { - return -1; - } - - // a must be equal to b - return 0; - }); - - //find mediaQueries - media_hunter.find_media_queries('./source/css', patternlab); - - // check if patterns are excluded, if not add them to styleguidePatterns - styleguidePatterns = assembleStyleguidePatterns(patternlab); - - //also add the cachebuster value. slight chance this could collide with a user that has defined cacheBuster as a value - patternlab.data.cacheBuster = patternlab.cacheBuster; - - //get the main page head and foot - var mainPageHead = patternlab.userHead.extendedTemplate.replace('{% pattern-lab-head %}', patternlab.header); - var mainPageHeadHtml = pattern_assembler.renderPattern(mainPageHead, patternlab.data); - var mainPageFoot = patternlab.userFoot.extendedTemplate.replace('{% pattern-lab-foot %}', patternlab.footer); - var mainPageFootHtml = pattern_assembler.renderPattern(mainPageFoot, patternlab.data); - - //build the styleguide - var styleguideTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/styleguide.mustache'), 'utf8'); - var styleguideHtml = pattern_assembler.renderPattern(styleguideTemplate, {partials: styleguidePatterns, cacheBuster: patternlab.cacheBuster}); - - fs.outputFileSync(path.resolve(paths.public.styleguide, 'html/styleguide.html'), mainPageHeadHtml + styleguideHtml + mainPageFootHtml); - - //build the viewall pages var prevSubdir = ''; var prevGroup = ''; var i; @@ -180,6 +132,59 @@ function buildFrontEnd(patternlab) { fs.outputFileSync(paths.public.patterns + pattern.flatPatternPath + '/index.html', mainPageHeadHtml + viewAllHtml + mainPageFootHtml); } } +} + +function buildFrontEnd(patternlab) { + var pa = require('./pattern_assembler'); + var of = require('./object_factory'); + var mh = require('./media_hunter'); + var pattern_assembler = new pa(); + var media_hunter = new mh(); + var styleguidePatterns = []; + var paths = patternlab.config.paths; + var i; + + patternlab.buckets = []; + patternlab.bucketIndex = []; + patternlab.patternPaths = {}; + patternlab.viewAllPaths = {}; + + //sort all patterns explicitly. + patternlab.patterns = patternlab.patterns.sort(function (a, b) { + if (a.name > b.name) { + return 1; + } + if (a.name < b.name) { + return -1; + } + + // a must be equal to b + return 0; + }); + + //find mediaQueries + media_hunter.find_media_queries('./source/css', patternlab); + + // check if patterns are excluded, if not add them to styleguidePatterns + styleguidePatterns = assembleStyleguidePatterns(patternlab); + + //also add the cachebuster value. slight chance this could collide with a user that has defined cacheBuster as a value + patternlab.data.cacheBuster = patternlab.cacheBuster; + + //get the main page head and foot + var mainPageHead = patternlab.userHead.extendedTemplate.replace('{% pattern-lab-head %}', patternlab.header); + var mainPageHeadHtml = pattern_assembler.renderPattern(mainPageHead, patternlab.data); + var mainPageFoot = patternlab.userFoot.extendedTemplate.replace('{% pattern-lab-foot %}', patternlab.footer); + var mainPageFootHtml = pattern_assembler.renderPattern(mainPageFoot, patternlab.data); + + //build the styleguide + var styleguideTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/styleguide.mustache'), 'utf8'); + var styleguideHtml = pattern_assembler.renderPattern(styleguideTemplate, {partials: styleguidePatterns, cacheBuster: patternlab.cacheBuster}); + + fs.outputFileSync(path.resolve(paths.public.styleguide, 'html/styleguide.html'), mainPageHeadHtml + styleguideHtml + mainPageFootHtml); + + //build the viewall pages + buildViewAllPages(mainPageHead, mainPageFoot, mainPageHeadHtml, mainPageFootHtml, pattern_assembler, patternlab); //build the patternlab website var patternlabSiteTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/index.mustache'), 'utf8'); @@ -188,7 +193,7 @@ function buildFrontEnd(patternlab) { //todo: refactor this someday for (i = 0; i < patternlab.patterns.length; i++) { - pattern = patternlab.patterns[i]; + var pattern = patternlab.patterns[i]; var bucketName = pattern.name.replace(/\\/g, '-').split('-')[1]; //check if the bucket already exists From 44b7319cd18016735946c7ac0357dee57f7c53db Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Thu, 24 Mar 2016 14:55:49 -0500 Subject: [PATCH 094/187] factor out buildNavigation() --- core/lib/ui_builder.js | 275 +++++++++++++++++++++-------------------- 1 file changed, 140 insertions(+), 135 deletions(-) diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index 235e3499a..5597e61ca 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -12,6 +12,8 @@ var path = require('path'); var fs = require('fs-extra'); +var of = require('./object_factory'); + // PRIVATE FUNCTIONS @@ -57,141 +59,8 @@ function assembleStyleguidePatterns(patternlab) { return styleguidePatterns; } - -// MAIN BUILDER FUNCTION - -function buildViewAllPages(mainPageHead, mainPageFoot, mainPageHeadHtml, mainPageFootHtml, pattern_assembler, patternlab) { - var paths = patternlab.config.paths; - var prevSubdir = ''; - var prevGroup = ''; - var i; - - for (i = 0; i < patternlab.patterns.length; i++) { - // skip underscore-prefixed files - if (isPatternExcluded(patternlab.patterns[i])) { - if (patternlab.config.debug) { - console.log('Omitting ' + patternlab.patterns[i].key + " from view all rendering."); - } - continue; - } - - var pattern = patternlab.patterns[i]; - - //create the view all for the section - // check if the current section is different from the previous one - if (pattern.patternGroup !== prevGroup) { - prevGroup = pattern.patternGroup; - - var viewAllPatterns = []; - var patternPartial = "viewall-" + pattern.patternGroup; - var j; - - for (j = 0; j < patternlab.patterns.length; j++) { - if (patternlab.patterns[j].patternGroup === pattern.patternGroup) { - //again, skip any sibling patterns to the current one that may have underscores - if (isPatternExcluded(patternlab.patterns[j])) { - if (patternlab.config.debug) { - console.log('Omitting ' + patternlab.patterns[j].key + " from view all sibling rendering."); - } - continue; - } - - viewAllPatterns.push(patternlab.patterns[j]); - } - } - - var viewAllTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/viewall.mustache'), 'utf8'); - var viewAllHtml = pattern_assembler.renderPattern(viewAllTemplate, {partials: viewAllPatterns, patternPartial: patternPartial, cacheBuster: patternlab.cacheBuster }); - fs.outputFileSync(paths.public.patterns + pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length) + '/index.html', mainPageHead + viewAllHtml + mainPageFoot); - } - - //create the view all for the subsection - // check if the current sub section is different from the previous one - if (pattern.subdir !== prevSubdir) { - prevSubdir = pattern.subdir; - - viewAllPatterns = []; - patternPartial = "viewall-" + pattern.patternGroup + "-" + pattern.patternSubGroup; - - for (j = 0; j < patternlab.patterns.length; j++) { - if (patternlab.patterns[j].subdir === pattern.subdir) { - //again, skip any sibling patterns to the current one that may have underscores - if (isPatternExcluded(patternlab.patterns[j])) { - if (patternlab.config.debug) { - console.log('Omitting ' + patternlab.patterns[j].key + " from view all sibling rendering."); - } - continue; - } - - viewAllPatterns.push(patternlab.patterns[j]); - } - } - - var viewAllTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/viewall.mustache'), 'utf8'); - var viewAllHtml = pattern_assembler.renderPattern(viewAllTemplate, {partials: viewAllPatterns, patternPartial: patternPartial, cacheBuster: patternlab.cacheBuster}); - fs.outputFileSync(paths.public.patterns + pattern.flatPatternPath + '/index.html', mainPageHeadHtml + viewAllHtml + mainPageFootHtml); - } - } -} - -function buildFrontEnd(patternlab) { - var pa = require('./pattern_assembler'); - var of = require('./object_factory'); - var mh = require('./media_hunter'); - var pattern_assembler = new pa(); - var media_hunter = new mh(); - var styleguidePatterns = []; - var paths = patternlab.config.paths; - var i; - - patternlab.buckets = []; - patternlab.bucketIndex = []; - patternlab.patternPaths = {}; - patternlab.viewAllPaths = {}; - - //sort all patterns explicitly. - patternlab.patterns = patternlab.patterns.sort(function (a, b) { - if (a.name > b.name) { - return 1; - } - if (a.name < b.name) { - return -1; - } - - // a must be equal to b - return 0; - }); - - //find mediaQueries - media_hunter.find_media_queries('./source/css', patternlab); - - // check if patterns are excluded, if not add them to styleguidePatterns - styleguidePatterns = assembleStyleguidePatterns(patternlab); - - //also add the cachebuster value. slight chance this could collide with a user that has defined cacheBuster as a value - patternlab.data.cacheBuster = patternlab.cacheBuster; - - //get the main page head and foot - var mainPageHead = patternlab.userHead.extendedTemplate.replace('{% pattern-lab-head %}', patternlab.header); - var mainPageHeadHtml = pattern_assembler.renderPattern(mainPageHead, patternlab.data); - var mainPageFoot = patternlab.userFoot.extendedTemplate.replace('{% pattern-lab-foot %}', patternlab.footer); - var mainPageFootHtml = pattern_assembler.renderPattern(mainPageFoot, patternlab.data); - - //build the styleguide - var styleguideTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/styleguide.mustache'), 'utf8'); - var styleguideHtml = pattern_assembler.renderPattern(styleguideTemplate, {partials: styleguidePatterns, cacheBuster: patternlab.cacheBuster}); - - fs.outputFileSync(path.resolve(paths.public.styleguide, 'html/styleguide.html'), mainPageHeadHtml + styleguideHtml + mainPageFootHtml); - - //build the viewall pages - buildViewAllPages(mainPageHead, mainPageFoot, mainPageHeadHtml, mainPageFootHtml, pattern_assembler, patternlab); - - //build the patternlab website - var patternlabSiteTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/index.mustache'), 'utf8'); - - //loop through all patterns.to build the navigation - //todo: refactor this someday - for (i = 0; i < patternlab.patterns.length; i++) { +function buildNavigation(patternlab) { + for (var i = 0; i < patternlab.patterns.length; i++) { var pattern = patternlab.patterns[i]; var bucketName = pattern.name.replace(/\\/g, '-').split('-')[1]; @@ -358,6 +227,142 @@ function buildFrontEnd(patternlab) { patternlab.viewAllPaths[bucketName][pattern.patternSubGroup] = pattern.flatPatternPath; } + return bucketIndex; +} + + +// MAIN BUILDER FUNCTION + +function buildViewAllPages(mainPageHead, mainPageFoot, mainPageHeadHtml, mainPageFootHtml, pattern_assembler, patternlab) { + var paths = patternlab.config.paths; + var prevSubdir = ''; + var prevGroup = ''; + var i; + + for (i = 0; i < patternlab.patterns.length; i++) { + // skip underscore-prefixed files + if (isPatternExcluded(patternlab.patterns[i])) { + if (patternlab.config.debug) { + console.log('Omitting ' + patternlab.patterns[i].key + " from view all rendering."); + } + continue; + } + + var pattern = patternlab.patterns[i]; + + //create the view all for the section + // check if the current section is different from the previous one + if (pattern.patternGroup !== prevGroup) { + prevGroup = pattern.patternGroup; + + var viewAllPatterns = []; + var patternPartial = "viewall-" + pattern.patternGroup; + var j; + + for (j = 0; j < patternlab.patterns.length; j++) { + if (patternlab.patterns[j].patternGroup === pattern.patternGroup) { + //again, skip any sibling patterns to the current one that may have underscores + if (isPatternExcluded(patternlab.patterns[j])) { + if (patternlab.config.debug) { + console.log('Omitting ' + patternlab.patterns[j].key + " from view all sibling rendering."); + } + continue; + } + + viewAllPatterns.push(patternlab.patterns[j]); + } + } + + var viewAllTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/viewall.mustache'), 'utf8'); + var viewAllHtml = pattern_assembler.renderPattern(viewAllTemplate, {partials: viewAllPatterns, patternPartial: patternPartial, cacheBuster: patternlab.cacheBuster }); + fs.outputFileSync(paths.public.patterns + pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length) + '/index.html', mainPageHead + viewAllHtml + mainPageFoot); + } + + //create the view all for the subsection + // check if the current sub section is different from the previous one + if (pattern.subdir !== prevSubdir) { + prevSubdir = pattern.subdir; + + viewAllPatterns = []; + patternPartial = "viewall-" + pattern.patternGroup + "-" + pattern.patternSubGroup; + + for (j = 0; j < patternlab.patterns.length; j++) { + if (patternlab.patterns[j].subdir === pattern.subdir) { + //again, skip any sibling patterns to the current one that may have underscores + if (isPatternExcluded(patternlab.patterns[j])) { + if (patternlab.config.debug) { + console.log('Omitting ' + patternlab.patterns[j].key + " from view all sibling rendering."); + } + continue; + } + + viewAllPatterns.push(patternlab.patterns[j]); + } + } + + var viewAllTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/viewall.mustache'), 'utf8'); + var viewAllHtml = pattern_assembler.renderPattern(viewAllTemplate, {partials: viewAllPatterns, patternPartial: patternPartial, cacheBuster: patternlab.cacheBuster}); + fs.outputFileSync(paths.public.patterns + pattern.flatPatternPath + '/index.html', mainPageHeadHtml + viewAllHtml + mainPageFootHtml); + } + } +} + +function buildFrontEnd(patternlab) { + var pa = require('./pattern_assembler'); + var mh = require('./media_hunter'); + var pattern_assembler = new pa(); + var media_hunter = new mh(); + var styleguidePatterns = []; + var paths = patternlab.config.paths; + + patternlab.buckets = []; + patternlab.bucketIndex = []; + patternlab.patternPaths = {}; + patternlab.viewAllPaths = {}; + + //sort all patterns explicitly. + patternlab.patterns = patternlab.patterns.sort(function (a, b) { + if (a.name > b.name) { + return 1; + } + if (a.name < b.name) { + return -1; + } + + // a must be equal to b + return 0; + }); + + //find mediaQueries + media_hunter.find_media_queries('./source/css', patternlab); + + // check if patterns are excluded, if not add them to styleguidePatterns + styleguidePatterns = assembleStyleguidePatterns(patternlab); + + //also add the cachebuster value. slight chance this could collide with a user that has defined cacheBuster as a value + patternlab.data.cacheBuster = patternlab.cacheBuster; + + //get the main page head and foot + var mainPageHead = patternlab.userHead.extendedTemplate.replace('{% pattern-lab-head %}', patternlab.header); + var mainPageHeadHtml = pattern_assembler.renderPattern(mainPageHead, patternlab.data); + var mainPageFoot = patternlab.userFoot.extendedTemplate.replace('{% pattern-lab-foot %}', patternlab.footer); + var mainPageFootHtml = pattern_assembler.renderPattern(mainPageFoot, patternlab.data); + + //build the styleguide + var styleguideTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/styleguide.mustache'), 'utf8'); + var styleguideHtml = pattern_assembler.renderPattern(styleguideTemplate, {partials: styleguidePatterns, cacheBuster: patternlab.cacheBuster}); + + fs.outputFileSync(path.resolve(paths.public.styleguide, 'html/styleguide.html'), mainPageHeadHtml + styleguideHtml + mainPageFootHtml); + + //build the viewall pages + buildViewAllPages(mainPageHead, mainPageFoot, mainPageHeadHtml, mainPageFootHtml, pattern_assembler, patternlab); + + //build the patternlab website + var patternlabSiteTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/index.mustache'), 'utf8'); + + //loop through all patterns.to build the navigation + //todo: refactor this someday + buildNavigation(patternlab); //the patternlab site requires a lot of partials to be rendered. //patternNav From 110452d98e60fcda8f023cef858d6be246661f50 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Thu, 24 Mar 2016 14:56:16 -0500 Subject: [PATCH 095/187] comment placement adjustment to not lie --- core/lib/ui_builder.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index 5597e61ca..c153cdd32 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -230,9 +230,6 @@ function buildNavigation(patternlab) { return bucketIndex; } - -// MAIN BUILDER FUNCTION - function buildViewAllPages(mainPageHead, mainPageFoot, mainPageHeadHtml, mainPageFootHtml, pattern_assembler, patternlab) { var paths = patternlab.config.paths; var prevSubdir = ''; @@ -307,6 +304,9 @@ function buildViewAllPages(mainPageHead, mainPageFoot, mainPageHeadHtml, mainPag } } + +// MAIN BUILDER FUNCTION + function buildFrontEnd(patternlab) { var pa = require('./pattern_assembler'); var mh = require('./media_hunter'); From 590843e955d0023ae95fded47b0d3e877883cb97 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Thu, 24 Mar 2016 15:04:12 -0500 Subject: [PATCH 096/187] factor out sortPatterns() --- core/lib/ui_builder.js | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index c153cdd32..705afb9ec 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -304,6 +304,20 @@ function buildViewAllPages(mainPageHead, mainPageFoot, mainPageHeadHtml, mainPag } } +function sortPatterns(patternsArray) { + return patternsArray.sort(function (a, b) { + if (a.name > b.name) { + return 1; + } + if (a.name < b.name) { + return -1; + } + + // a must be equal to b + return 0; + }); +} + // MAIN BUILDER FUNCTION @@ -321,17 +335,7 @@ function buildFrontEnd(patternlab) { patternlab.viewAllPaths = {}; //sort all patterns explicitly. - patternlab.patterns = patternlab.patterns.sort(function (a, b) { - if (a.name > b.name) { - return 1; - } - if (a.name < b.name) { - return -1; - } - - // a must be equal to b - return 0; - }); + patternlab.patterns = sortPatterns(patternlab.patterns); //find mediaQueries media_hunter.find_media_queries('./source/css', patternlab); From ea10c07733c2be1c121ef300e87c0cadd24e50e5 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Thu, 24 Mar 2016 15:07:21 -0500 Subject: [PATCH 097/187] comments --- core/lib/ui_builder.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index 705afb9ec..e9dd9398f 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -346,7 +346,7 @@ function buildFrontEnd(patternlab) { //also add the cachebuster value. slight chance this could collide with a user that has defined cacheBuster as a value patternlab.data.cacheBuster = patternlab.cacheBuster; - //get the main page head and foot + //get the main page head and foot and render them var mainPageHead = patternlab.userHead.extendedTemplate.replace('{% pattern-lab-head %}', patternlab.header); var mainPageHeadHtml = pattern_assembler.renderPattern(mainPageHead, patternlab.data); var mainPageFoot = patternlab.userFoot.extendedTemplate.replace('{% pattern-lab-foot %}', patternlab.footer); @@ -366,9 +366,11 @@ function buildFrontEnd(patternlab) { //loop through all patterns.to build the navigation //todo: refactor this someday + //GTP: totally doing that right now buildNavigation(patternlab); - //the patternlab site requires a lot of partials to be rendered. + //the patternlab site requires a lot of partials to be rendered! + //patternNav var patternNavTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/patternNav.mustache'), 'utf8'); var patternNavPartialHtml = pattern_assembler.renderPattern(patternNavTemplate, patternlab); From 15ff8ab29fc4ec51cb06aa71af88f37b1fbc5b06 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Fri, 25 Mar 2016 13:48:17 -0500 Subject: [PATCH 098/187] factor out pattern exclusion from buildNavigation() --- core/lib/ui_builder.js | 51 +++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index e9dd9398f..ed2b04934 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -65,15 +65,14 @@ function buildNavigation(patternlab) { var pattern = patternlab.patterns[i]; var bucketName = pattern.name.replace(/\\/g, '-').split('-')[1]; + // skip underscore-prefixed files. don't create a bucket on account of an underscored pattern + if (isPatternExcluded(pattern)) { + continue; + } + //check if the bucket already exists var bucketIndex = patternlab.bucketIndex.indexOf(bucketName); if (bucketIndex === -1) { - - // skip underscore-prefixed files. don't create a bucket on account of an underscored pattern - if (isPatternExcluded(pattern)) { - continue; - } - //add the bucket var bucket = new of.oBucket(bucketName); @@ -172,12 +171,6 @@ function buildNavigation(patternlab) { //if it is flat - we should not add the pattern to patternPaths if (flatPatternItem) { - - // skip underscore-prefixed files - if (isPatternExcluded(pattern)) { - continue; - } - //add the navItem to patternItems bucket.patternItems.push(navSubItem); @@ -187,24 +180,22 @@ function buildNavigation(patternlab) { } else { // only do this if pattern is included - if (!isPatternExcluded(pattern)) { - //check to see if navItem exists - var navItemIndex = bucket.navItemsIndex.indexOf(navItemName); - if (navItemIndex === -1) { - navItem = new of.oNavItem(navItemName); - - //add the navItem and navSubItem - navItem.navSubItems.push(navSubItem); - navItem.navSubItemsIndex.push(navSubItemName); - bucket.navItems.push(navItem); - bucket.navItemsIndex.push(navItemName); - - } else { - //add the navSubItem - navItem = bucket.navItems[navItemIndex]; - navItem.navSubItems.push(navSubItem); - navItem.navSubItemsIndex.push(navSubItemName); - } + //check to see if navItem exists + var navItemIndex = bucket.navItemsIndex.indexOf(navItemName); + if (navItemIndex === -1) { + navItem = new of.oNavItem(navItemName); + + //add the navItem and navSubItem + navItem.navSubItems.push(navSubItem); + navItem.navSubItemsIndex.push(navSubItemName); + bucket.navItems.push(navItem); + bucket.navItemsIndex.push(navItemName); + + } else { + //add the navSubItem + navItem = bucket.navItems[navItemIndex]; + navItem.navSubItems.push(navSubItem); + navItem.navSubItemsIndex.push(navSubItemName); } //check if we are moving to a new sub section in the next loop From 7f78ae535e51ece58d9101e5e373e4c73ec57749 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Fri, 25 Mar 2016 15:55:28 -0500 Subject: [PATCH 099/187] factor out variable declarations and nav item name getting --- core/lib/ui_builder.js | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index ed2b04934..220143084 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -70,6 +70,22 @@ function buildNavigation(patternlab) { continue; } + var navItemName; + var navSubItemName; + var flatPatternItem; + var navItem; + var navSubItem; + var navViewAllItem; + + //get the navItem + //if there is one or more slashes in the subdir, get everything after + //the last slash. if no slash, get the whole subdir string and strip + //any numeric + hyphen prefix + navItemName = pattern.subdir.split('/').pop().replace(/^\d*\-/, ''); + //get the navSubItem + navSubItemName = pattern.patternName.replace(/-/g, ' '); + + //check if the bucket already exists var bucketIndex = patternlab.bucketIndex.indexOf(bucketName); if (bucketIndex === -1) { @@ -80,24 +96,17 @@ function buildNavigation(patternlab) { patternlab.patternPaths[bucketName] = {}; patternlab.viewAllPaths[bucketName] = {}; - //get the navItem - var navItemName = pattern.subdir.split('/').pop(); - navItemName = navItemName.replace(/(\d).(-)/g, ''); - - //get the navSubItem - var navSubItemName = pattern.patternName.replace(/-/g, ' '); - //test whether the pattern struture is flat or not - usually due to a template or page - var flatPatternItem = false; + flatPatternItem = false; if (navItemName === bucketName) { flatPatternItem = true; } //assume the navItem does not exist. - var navItem = new of.oNavItem(navItemName); + navItem = new of.oNavItem(navItemName); //assume the navSubItem does not exist. - var navSubItem = new of.oNavSubItem(navSubItemName); + navSubItem = new of.oNavSubItem(navSubItemName); navSubItem.patternPath = pattern.patternLink; navSubItem.patternPartial = bucketName + "-" + pattern.patternName; //add the hyphenated name @@ -125,7 +134,7 @@ function buildNavigation(patternlab) { addToPatternPaths(patternlab, bucketName, pattern); //add the navViewAllItem - var navViewAllItem = new of.oNavSubItem("View All"); + navViewAllItem = new of.oNavSubItem("View All"); navViewAllItem.patternPath = pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length) + "/index.html"; navViewAllItem.patternPartial = "viewall-" + pattern.patternGroup; @@ -144,15 +153,6 @@ function buildNavigation(patternlab) { //find the bucket bucket = patternlab.buckets[bucketIndex]; - //get the navItem - //if there is one or more slashes in the subdir, get everything after - //the last slash. if no slash, get the whole subdir string and strip - //any numeric + hyphen prefix - navItemName = pattern.subdir.split('/').pop().replace(/^\d*\-/, ''); - - //get the navSubItem - navSubItemName = pattern.patternName.replace(/-/g, ' '); - //assume the navSubItem does not exist. navSubItem = new of.oNavSubItem(navSubItemName); navSubItem.patternPath = pattern.patternLink; From ff36df959e47c89518a8fc8b62aee35afcf6733f Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Fri, 25 Mar 2016 15:59:15 -0500 Subject: [PATCH 100/187] factor out navSubItem creation --- core/lib/ui_builder.js | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index 220143084..b413816ee 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -77,14 +77,21 @@ function buildNavigation(patternlab) { var navSubItem; var navViewAllItem; - //get the navItem + //get the navItem. //if there is one or more slashes in the subdir, get everything after //the last slash. if no slash, get the whole subdir string and strip //any numeric + hyphen prefix navItemName = pattern.subdir.split('/').pop().replace(/^\d*\-/, ''); + //get the navSubItem navSubItemName = pattern.patternName.replace(/-/g, ' '); + //assume the navSubItem does not exist. + navSubItem = new of.oNavSubItem(navSubItemName); + navSubItem.patternPath = pattern.patternLink; + navSubItem.patternPartial = bucketName + "-" + pattern.patternName; //add the hyphenated name + + //check if the bucket already exists var bucketIndex = patternlab.bucketIndex.indexOf(bucketName); @@ -105,11 +112,6 @@ function buildNavigation(patternlab) { //assume the navItem does not exist. navItem = new of.oNavItem(navItemName); - //assume the navSubItem does not exist. - navSubItem = new of.oNavSubItem(navSubItemName); - navSubItem.patternPath = pattern.patternLink; - navSubItem.patternPartial = bucketName + "-" + pattern.patternName; //add the hyphenated name - //add the patternState if it exists if (pattern.patternState) { navSubItem.patternState = pattern.patternState; @@ -153,11 +155,6 @@ function buildNavigation(patternlab) { //find the bucket bucket = patternlab.buckets[bucketIndex]; - //assume the navSubItem does not exist. - navSubItem = new of.oNavSubItem(navSubItemName); - navSubItem.patternPath = pattern.patternLink; - navSubItem.patternPartial = bucketName + "-" + pattern.patternName; //add the hyphenated name - //add the patternState if it exists if (pattern.patternState) { navSubItem.patternState = pattern.patternState; From e21598f685f63ab17805c9451a2b74a2c268cca8 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sun, 27 Mar 2016 15:08:54 -0500 Subject: [PATCH 101/187] remove gulpfile and gulp json remove source directory --- gulpfile.js | 193 - package.gulp.json | 49 - source/_data/annotations.js | 109 - source/_data/data.json | 93 - source/_data/listitems.json | 782 -- .../00-atoms/00-meta/_00-head.mustache | 15 - .../00-atoms/00-meta/_01-foot.mustache | 7 - .../00-atoms/01-global/00-colors.mustache | 38 - .../00-atoms/01-global/01-fonts.mustache | 6 - .../00-atoms/01-global/02-animations.mustache | 3 - .../00-atoms/01-global/03-visibility.mustache | 11 - .../00-atoms/02-text/00-headings.mustache | 6 - .../00-atoms/02-text/01-subheadings.mustache | 6 - .../02-text/02-headings-with-links.mustache | 6 - .../00-atoms/02-text/03-paragraph.mustache | 1 - .../00-atoms/02-text/04-blockquote.mustache | 3 - .../02-text/05-inline-elements.mustache | 41 - .../00-atoms/02-text/06-time.mustache | 1 - .../02-text/07-preformatted-text.mustache | 9 - .../02-text/08-emphasis-colors.mustache | 4 - .../_patterns/00-atoms/02-text/09-hr.mustache | 1 - .../00-atoms/02-text/10-caption.mustache | 1 - .../00-atoms/03-lists/00-unordered.mustache | 14 - .../00-atoms/03-lists/01-ordered.mustache | 14 - .../00-atoms/03-lists/02-definition.mustache | 10 - .../00-atoms/04-images/00-logo.mustache | 1 - .../04-images/01-landscape-4x3.mustache | 1 - .../04-images/02-landscape-16x9.mustache | 1 - .../00-atoms/04-images/03-square.mustache | 1 - .../00-atoms/04-images/04-avatar.mustache | 1 - .../00-atoms/04-images/05-icons.mustache | 12 - .../04-images/06-loading-icon.mustache | 1 - .../00-atoms/04-images/07-favicon.mustache | 2 - .../00-atoms/05-forms/00-text-fields.mustache | 38 - .../00-atoms/05-forms/01-select-menu.mustache | 12 - .../00-atoms/05-forms/02-checkbox.mustache | 10 - .../05-forms/03-radio-buttons.mustache | 10 - .../05-forms/04-html5-inputs.mustache | 10 - .../00-atoms/06-buttons/00-buttons.mustache | 4 - .../00-atoms/07-tables/00-table.mustache | 50 - .../00-atoms/08-media/00-video.mustache | 6 - .../00-atoms/08-media/01-audio.mustache | 4 - .../00-text/00-byline-author-only.mustache | 1 - .../00-text/01-byline-author-time.mustache | 1 - .../01-molecules/00-text/02-address.mustache | 11 - .../00-text/03-heading-group.mustache | 4 - .../04-blockquote-with-citation.mustache | 4 - .../00-text/05-intro-text.mustache | 1 - .../00-text/06-pullquote.mustache | 3 - .../01-molecules/01-layout/00-one-up.mustache | 7 - .../01-molecules/01-layout/01-two-up.mustache | 7 - .../01-layout/02-three-up.mustache | 8 - .../01-layout/03-four-up.mustache | 9 - .../02-blocks/00-media-block.mustache | 11 - .../02-blocks/01-headline-byline.mustache | 6 - .../02-blocks/02-block-hero.mustache | 10 - .../03-block-thumb-headline.mustache | 10 - .../02-blocks/04-headline-only.mustache | 5 - .../02-blocks/05-inset-block.mustache | 10 - .../03-media/00-figure-with-caption.mustache | 4 - .../01-molecules/03-media/_map.mustache | 1 - .../01-molecules/04-forms/00-search.mustache | 11 - .../04-forms/01-comment-form.mustache | 20 - .../04-forms/02-newsletter.mustache | 10 - .../05-navigation/00-primary-nav.mustache | 8 - .../05-navigation/01-footer-nav.mustache | 6 - .../05-navigation/02-breadcrumbs.mustache | 7 - .../05-navigation/03-pagination.mustache | 9 - .../05-navigation/04-tabs.mustache | 7 - .../06-components/00-social-share.mustache | 8 - .../06-components/01-accordion.mustache | 19 - .../06-components/02-single-comment.mustache | 9 - .../07-messaging/00-alert.mustache | 3 - .../02-organisms/00-global/00-header.mustache | 9 - .../02-organisms/00-global/01-footer.mustache | 7 - .../01-article/00-article-body.mustache | 26 - .../02-comments/00-comment-thread.mustache | 12 - .../02-comments/01-sticky-comment.mustache | 9 - .../03-components/00-carousel.mustache | 10 - .../04-sections/00-latest-posts.mustache | 11 - .../04-sections/01-recent-tweets.mustache | 12 - .../04-sections/02-related-posts.mustache | 11 - .../03-templates/00-homepage.mustache | 40 - .../_patterns/03-templates/01-blog.mustache | 17 - .../03-templates/02-article.mustache | 25 - source/_patterns/04-pages/00-homepage.json | 134 - .../_patterns/04-pages/00-homepage.mustache | 1 - .../04-pages/00-homepage~emergency.json | 8 - source/_patterns/04-pages/01-blog.json | 84 - source/_patterns/04-pages/01-blog.mustache | 25 - source/_patterns/04-pages/02-article.json | 26 - source/_patterns/04-pages/02-article.mustache | 1 - source/css/style.css | 1422 --- source/favicon.ico | Bin 32988 -> 0 bytes source/fonts/icons.dev.svg | 103 - source/fonts/icons.eot | Bin 4372 -> 0 bytes source/fonts/icons.svg | 103 - source/fonts/icons.ttf | Bin 4216 -> 0 bytes source/fonts/icons.woff | Bin 6176 -> 0 bytes source/images/ajax-loader.gif | Bin 673 -> 0 bytes source/images/favicon_16x16.jpg | Bin 311 -> 0 bytes source/images/favicon_32x32.jpg | Bin 320 -> 0 bytes source/images/fpo_16x9.png | Bin 15324 -> 0 bytes source/images/fpo_4x3.png | Bin 15854 -> 0 bytes source/images/fpo_avatar.png | Bin 3217 -> 0 bytes source/images/fpo_square.png | Bin 8694 -> 0 bytes source/images/logo.png | Bin 1931 -> 0 bytes .../sample/landscape-16x9-mountains.jpg | Bin 78249 -> 0 bytes source/images/sample/thumb-square-fire.jpg | Bin 72783 -> 0 bytes source/images/sample/thumb-square-gear.jpg | Bin 146848 -> 0 bytes source/images/sample/thumb-square-ivy.jpg | Bin 76319 -> 0 bytes source/images/sample/thumb-square-river.jpg | Bin 50522 -> 0 bytes .../images/sample/thumb-square-yosemite.jpg | Bin 84720 -> 0 bytes source/images/sample/tout-4x3-climber.jpg | Bin 114565 -> 0 bytes source/images/sample/tout-4x3-climbers.jpg | Bin 85295 -> 0 bytes source/images/sample/tout-4x3-stream.jpg | Bin 98049 -> 0 bytes source/js/fitvids.js | 77 - source/js/init.js | 26 - source/js/jquery-2.0.0b2.js | 8690 ----------------- source/js/modernizr.js | 4 - 120 files changed, 12710 deletions(-) delete mode 100644 gulpfile.js delete mode 100644 package.gulp.json delete mode 100644 source/_data/annotations.js delete mode 100644 source/_data/data.json delete mode 100644 source/_data/listitems.json delete mode 100644 source/_patterns/00-atoms/00-meta/_00-head.mustache delete mode 100644 source/_patterns/00-atoms/00-meta/_01-foot.mustache delete mode 100644 source/_patterns/00-atoms/01-global/00-colors.mustache delete mode 100644 source/_patterns/00-atoms/01-global/01-fonts.mustache delete mode 100644 source/_patterns/00-atoms/01-global/02-animations.mustache delete mode 100644 source/_patterns/00-atoms/01-global/03-visibility.mustache delete mode 100644 source/_patterns/00-atoms/02-text/00-headings.mustache delete mode 100644 source/_patterns/00-atoms/02-text/01-subheadings.mustache delete mode 100644 source/_patterns/00-atoms/02-text/02-headings-with-links.mustache delete mode 100644 source/_patterns/00-atoms/02-text/03-paragraph.mustache delete mode 100644 source/_patterns/00-atoms/02-text/04-blockquote.mustache delete mode 100644 source/_patterns/00-atoms/02-text/05-inline-elements.mustache delete mode 100644 source/_patterns/00-atoms/02-text/06-time.mustache delete mode 100644 source/_patterns/00-atoms/02-text/07-preformatted-text.mustache delete mode 100644 source/_patterns/00-atoms/02-text/08-emphasis-colors.mustache delete mode 100644 source/_patterns/00-atoms/02-text/09-hr.mustache delete mode 100644 source/_patterns/00-atoms/02-text/10-caption.mustache delete mode 100644 source/_patterns/00-atoms/03-lists/00-unordered.mustache delete mode 100644 source/_patterns/00-atoms/03-lists/01-ordered.mustache delete mode 100644 source/_patterns/00-atoms/03-lists/02-definition.mustache delete mode 100644 source/_patterns/00-atoms/04-images/00-logo.mustache delete mode 100644 source/_patterns/00-atoms/04-images/01-landscape-4x3.mustache delete mode 100644 source/_patterns/00-atoms/04-images/02-landscape-16x9.mustache delete mode 100644 source/_patterns/00-atoms/04-images/03-square.mustache delete mode 100644 source/_patterns/00-atoms/04-images/04-avatar.mustache delete mode 100644 source/_patterns/00-atoms/04-images/05-icons.mustache delete mode 100644 source/_patterns/00-atoms/04-images/06-loading-icon.mustache delete mode 100644 source/_patterns/00-atoms/04-images/07-favicon.mustache delete mode 100644 source/_patterns/00-atoms/05-forms/00-text-fields.mustache delete mode 100644 source/_patterns/00-atoms/05-forms/01-select-menu.mustache delete mode 100644 source/_patterns/00-atoms/05-forms/02-checkbox.mustache delete mode 100644 source/_patterns/00-atoms/05-forms/03-radio-buttons.mustache delete mode 100644 source/_patterns/00-atoms/05-forms/04-html5-inputs.mustache delete mode 100644 source/_patterns/00-atoms/06-buttons/00-buttons.mustache delete mode 100644 source/_patterns/00-atoms/07-tables/00-table.mustache delete mode 100644 source/_patterns/00-atoms/08-media/00-video.mustache delete mode 100644 source/_patterns/00-atoms/08-media/01-audio.mustache delete mode 100644 source/_patterns/01-molecules/00-text/00-byline-author-only.mustache delete mode 100644 source/_patterns/01-molecules/00-text/01-byline-author-time.mustache delete mode 100644 source/_patterns/01-molecules/00-text/02-address.mustache delete mode 100644 source/_patterns/01-molecules/00-text/03-heading-group.mustache delete mode 100644 source/_patterns/01-molecules/00-text/04-blockquote-with-citation.mustache delete mode 100644 source/_patterns/01-molecules/00-text/05-intro-text.mustache delete mode 100644 source/_patterns/01-molecules/00-text/06-pullquote.mustache delete mode 100644 source/_patterns/01-molecules/01-layout/00-one-up.mustache delete mode 100644 source/_patterns/01-molecules/01-layout/01-two-up.mustache delete mode 100644 source/_patterns/01-molecules/01-layout/02-three-up.mustache delete mode 100644 source/_patterns/01-molecules/01-layout/03-four-up.mustache delete mode 100644 source/_patterns/01-molecules/02-blocks/00-media-block.mustache delete mode 100644 source/_patterns/01-molecules/02-blocks/01-headline-byline.mustache delete mode 100644 source/_patterns/01-molecules/02-blocks/02-block-hero.mustache delete mode 100644 source/_patterns/01-molecules/02-blocks/03-block-thumb-headline.mustache delete mode 100644 source/_patterns/01-molecules/02-blocks/04-headline-only.mustache delete mode 100644 source/_patterns/01-molecules/02-blocks/05-inset-block.mustache delete mode 100644 source/_patterns/01-molecules/03-media/00-figure-with-caption.mustache delete mode 100644 source/_patterns/01-molecules/03-media/_map.mustache delete mode 100644 source/_patterns/01-molecules/04-forms/00-search.mustache delete mode 100644 source/_patterns/01-molecules/04-forms/01-comment-form.mustache delete mode 100644 source/_patterns/01-molecules/04-forms/02-newsletter.mustache delete mode 100644 source/_patterns/01-molecules/05-navigation/00-primary-nav.mustache delete mode 100644 source/_patterns/01-molecules/05-navigation/01-footer-nav.mustache delete mode 100644 source/_patterns/01-molecules/05-navigation/02-breadcrumbs.mustache delete mode 100644 source/_patterns/01-molecules/05-navigation/03-pagination.mustache delete mode 100644 source/_patterns/01-molecules/05-navigation/04-tabs.mustache delete mode 100644 source/_patterns/01-molecules/06-components/00-social-share.mustache delete mode 100644 source/_patterns/01-molecules/06-components/01-accordion.mustache delete mode 100644 source/_patterns/01-molecules/06-components/02-single-comment.mustache delete mode 100644 source/_patterns/01-molecules/07-messaging/00-alert.mustache delete mode 100644 source/_patterns/02-organisms/00-global/00-header.mustache delete mode 100644 source/_patterns/02-organisms/00-global/01-footer.mustache delete mode 100644 source/_patterns/02-organisms/01-article/00-article-body.mustache delete mode 100644 source/_patterns/02-organisms/02-comments/00-comment-thread.mustache delete mode 100644 source/_patterns/02-organisms/02-comments/01-sticky-comment.mustache delete mode 100644 source/_patterns/02-organisms/03-components/00-carousel.mustache delete mode 100644 source/_patterns/02-organisms/04-sections/00-latest-posts.mustache delete mode 100644 source/_patterns/02-organisms/04-sections/01-recent-tweets.mustache delete mode 100644 source/_patterns/02-organisms/04-sections/02-related-posts.mustache delete mode 100644 source/_patterns/03-templates/00-homepage.mustache delete mode 100644 source/_patterns/03-templates/01-blog.mustache delete mode 100644 source/_patterns/03-templates/02-article.mustache delete mode 100644 source/_patterns/04-pages/00-homepage.json delete mode 100644 source/_patterns/04-pages/00-homepage.mustache delete mode 100644 source/_patterns/04-pages/00-homepage~emergency.json delete mode 100644 source/_patterns/04-pages/01-blog.json delete mode 100644 source/_patterns/04-pages/01-blog.mustache delete mode 100644 source/_patterns/04-pages/02-article.json delete mode 100644 source/_patterns/04-pages/02-article.mustache delete mode 100644 source/css/style.css delete mode 100644 source/favicon.ico delete mode 100644 source/fonts/icons.dev.svg delete mode 100644 source/fonts/icons.eot delete mode 100644 source/fonts/icons.svg delete mode 100644 source/fonts/icons.ttf delete mode 100644 source/fonts/icons.woff delete mode 100644 source/images/ajax-loader.gif delete mode 100644 source/images/favicon_16x16.jpg delete mode 100644 source/images/favicon_32x32.jpg delete mode 100644 source/images/fpo_16x9.png delete mode 100644 source/images/fpo_4x3.png delete mode 100644 source/images/fpo_avatar.png delete mode 100644 source/images/fpo_square.png delete mode 100644 source/images/logo.png delete mode 100644 source/images/sample/landscape-16x9-mountains.jpg delete mode 100644 source/images/sample/thumb-square-fire.jpg delete mode 100644 source/images/sample/thumb-square-gear.jpg delete mode 100644 source/images/sample/thumb-square-ivy.jpg delete mode 100644 source/images/sample/thumb-square-river.jpg delete mode 100644 source/images/sample/thumb-square-yosemite.jpg delete mode 100644 source/images/sample/tout-4x3-climber.jpg delete mode 100644 source/images/sample/tout-4x3-climbers.jpg delete mode 100644 source/images/sample/tout-4x3-stream.jpg delete mode 100644 source/js/fitvids.js delete mode 100644 source/js/init.js delete mode 100644 source/js/jquery-2.0.0b2.js delete mode 100644 source/js/modernizr.js diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index 0907f51be..000000000 --- a/gulpfile.js +++ /dev/null @@ -1,193 +0,0 @@ -// Special thanks to oscar-g (https://github.com/oscar-g) for starting this at -// https://github.com/oscar-g/patternlab-node/tree/dev-gulp - -var pkg = require('./package.json'), - gulp = require('gulp'), - path = require('path'), - eol = require('os').EOL, - del = require('del'), - strip_banner = require('gulp-strip-banner'), - header = require('gulp-header'), - nodeunit = require('gulp-nodeunit'), - eslint = require('gulp-eslint'), - browserSync = require('browser-sync').create(); - -require('gulp-load')(gulp); -var banner = [ '/** ', - ' * <%= pkg.name %> - v<%= pkg.version %> - <%= today %>', - ' * ', - ' * <%= pkg.author %>, and the web community.', - ' * Licensed under the <%= pkg.license %> license.', - ' * ', - ' * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice.', - ' * ', ' **/'].join(eol); - -function paths() { - return require('./patternlab-config.json').paths; -} - -//load patternlab-node tasks -gulp.loadTasks(__dirname + '/core/lib/patternlab_gulp.js'); - -//clean patterns dir -gulp.task('clean', function(cb){ - del.sync([path.resolve(paths().public.patterns, '*')], {force: true}); - cb(); -}); - -//build the banner -gulp.task('banner', function(){ - return gulp.src([ - './core/lib/patternlab.js', - './core/lib/object_factory.js', - './core/lib/lineage_hunter.js', - './core/lib/media_hunter.js', - './core/lib/patternlab_grunt.js', - './core/lib/patternlab_gulp.js', - './core/lib/parameter_hunter.js', - './core/lib/pattern_exporter.js', - './core/lib/pattern_assembler.js', - './core/lib/pseudopattern_hunter.js', - './core/lib/list_item_hunter.js', - './core/lib/style_modifier_hunter.js' - ]) - .pipe(strip_banner()) - .pipe(header( banner, { - pkg : pkg, - today : new Date().getFullYear() } - )) - .pipe(gulp.dest('./core/lib')); -}); - - -// COPY TASKS - -// JS copy -gulp.task('cp:js', function(){ - return gulp.src('**/*.js', {cwd: path.resolve(paths().source.js)} ) - .pipe(gulp.dest(path.resolve(paths().public.js))); -}); - -// Images copy -gulp.task('cp:img', function(){ - return gulp.src( - [ '**/*.gif', '**/*.png', '**/*.jpg', '**/*.jpeg' ], - {cwd: path.resolve(paths().source.images)} ) - .pipe(gulp.dest(path.resolve(paths().public.images))); -}); - -// Fonts copy -gulp.task('cp:font', function(){ - return gulp.src('*', {cwd: path.resolve(paths().source.fonts)}) - .pipe(gulp.dest(path.resolve(paths().public.fonts))); -}); - -// Data copy -gulp.task('cp:data', function(){ - return gulp.src('annotations.js', {cwd: path.resolve(paths().source.data)}) - .pipe(gulp.dest(path.resolve(paths().public.data))); -}); - -// CSS Copy -gulp.task('cp:css', function(){ - return gulp.src(path.resolve(paths().source.css, 'style.css')) - .pipe(gulp.dest(path.resolve(paths().public.css))) - .pipe(browserSync.stream()); -}); - -// Styleguide Copy -gulp.task('cp:styleguide', function(){ - return gulp.src( - ['**/*'], - {cwd: path.resolve(paths().source.styleguide)}) - .pipe(gulp.dest(path.resolve(paths().public.styleguide))) - .pipe(browserSync.stream()); -}); - - -// server and watch tasks - -// watch task utility functions -function getSupportedTemplateExtensions() { - var engines = require('./core/lib/pattern_engines/pattern_engines'); - return engines.getSupportedFileExtensions(); -} -function getTemplateWatches() { - return getSupportedTemplateExtensions().map(function (dotExtension) { - return path.resolve(paths().source.patterns, '**/*' + dotExtension); - }); -} - -gulp.task('connect', ['lab'], function() { - browserSync.init({ - server: { - baseDir: path.resolve(paths().public.root) - }, - snippetOptions: { - // Ignore all HTML files within the templates folder - blacklist: ['/index.html', '/', '/?*'] - }, - notify: { - styles: [ - 'display: none', - 'padding: 15px', - 'font-family: sans-serif', - 'position: fixed', - 'font-size: 1em', - 'z-index: 9999', - 'bottom: 0px', - 'right: 0px', - 'border-top-left-radius: 5px', - 'background-color: #1B2032', - 'opacity: 0.4', - 'margin: 0', - 'color: white', - 'text-align: center' - ] - } - }); - gulp.watch(path.resolve(paths().source.css, '**/*.css'), ['cp:css']); - - gulp.watch(path.resolve(paths().source.styleguide, '**/*.*'), ['cp:styleguide']); - - var patternWatches = [ - path.resolve(paths().source.patterns, '**/*.json'), - path.resolve(paths().source.data, '*.json'), - path.resolve(paths().source.fonts + '/*'), - path.resolve(paths().source.images + '/*') - ].concat(getTemplateWatches()); - - gulp.watch(patternWatches, ['lab-pipe'], function () { browserSync.reload(); }); -}); - -//lint -gulp.task('eslint', function () { - return gulp.src(['./core/lib/*.js', '!node_modules/**']) - .pipe(eslint()) - .pipe(eslint.format()) - .pipe(eslint.failAfterError()); -}); - -//unit test -gulp.task('nodeunit', function(){ - return gulp.src('./test/**/*_tests.js') - .pipe(nodeunit()); -}); - - -gulp.task('lab-pipe', ['lab'], function(cb){ - cb(); - browserSync.reload(); -}); - -gulp.task('default', ['lab']); - -gulp.task('assets', ['cp:js', 'cp:img', 'cp:font', 'cp:data', 'cp:css', 'cp:styleguide' ]); -gulp.task('prelab', ['clean', 'assets']); -gulp.task('lab', ['prelab', 'patternlab'], function(cb){cb();}); -gulp.task('patterns', ['patternlab:only_patterns']); -gulp.task('serve', ['lab', 'connect']); -gulp.task('build', ['eslint', 'nodeunit', 'banner']); - -gulp.task('version', ['patternlab:version']); -gulp.task('help', ['patternlab:help']); diff --git a/package.gulp.json b/package.gulp.json deleted file mode 100644 index cf91530e8..000000000 --- a/package.gulp.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "patternlab-node", - "description": "Pattern Lab is a collection of tools to help you create atomic design systems. This is the node command line interface (CLI).", - "version": "1.2.0", - "main": "./core/lib/patternlab.js", - "dependencies": { - "del": "^2.2.0", - "diveSync": "^0.3.0", - "fs-extra": "^0.26.5", - "glob": "^7.0.0", - "html-entities": "^1.2.0", - "mustache": "^2.2.1", - "handlebars": "^4.0.5", - "twig": "^0.8.8", - "underscore": "^1.8.3" - }, - "devDependencies": { - "browser-sync": "^2.11.1", - "gulp": "^3.9.0", - "gulp-connect": "^2.3.1", - "gulp-copy": "0.0.2", - "gulp-eslint": "^2.0.0", - "gulp-header": "^1.7.1", - "gulp-load": "^0.1.1", - "gulp-nodeunit": "0.0.5", - "gulp-strip-banner": "0.0.2" - }, - "keywords": [ - "Pattern Lab", - "Atomic Web Design", - "Node", - "Grunt", - "Gulp", - "Javascript" - ], - "repository": { - "type": "git", - "url": "git://github.com/pattern-lab/patternlab-node.git" - }, - "bugs": "https://github.com/pattern-lab/patternlab-node/issues", - "author": "Brian Muenzenmeyer", - "license": "MIT", - "scripts": { - "test": "grunt travis --verbose" - }, - "engines": { - "node": ">=0.1" - } -} diff --git a/source/_data/annotations.js b/source/_data/annotations.js deleted file mode 100644 index fc8209531..000000000 --- a/source/_data/annotations.js +++ /dev/null @@ -1,109 +0,0 @@ -var comments = { -"comments" : [ - { - "el": "header[role=banner]", - "title" : "Masthead", - "comment": "The main header of the site doesn't take up too much screen real estate in order to keep the focus on the core content. It's using a linear CSS gradient instead of a background image to give greater design flexibility and reduce HTTP requests." - }, - { - "el": ".logo", - "title" : "Logo", - "comment": "The logo image is an SVG file, which ensures that the logo displays crisply even on high resolution displays. A PNG fallback is provided for browsers that don't support SVG images.

Further reading: Optimizing Web Experiences for High Resolution Screens

" - }, - { - "el": "#nav", - "title" : "Navigation", - "comment": "

Navigation for adaptive web experiences can be tricky. Top navigations are typical on desktop sites, but mobile screen sizes don't give us the luxury of space. We're dealing with this situation by creating a simple menu anchor that toggles the main navigation on small screens. This is just one method. Bagcheck and Contents Magazine add an anchor in the header that jumps users to the navigation which is placed in the footer. This solution works well because it doesn't require any Javascript in order to work. Other methods exist too. For example, ESPN's mobile navigation overlays the main content of the page.

The nav is only hidden when a certain level of javascript is supported in order to ensure that users with little/poor javascript support can still access the navigation. Once the screen size is large enough to accommodate the nav, we show the main navigation links and hide the menu anchor.

See also: Responsive Navigation Patterns

" - }, - { - "el": "input[type=search]", - "title" : "Search", - "comment": "

Search is an incredibly important priority, especially for mobile. It is a great idea to give users the ability to jump directly to what they are looking for without forcing them to wade through your site's navigation. Check out the Burton and Yelp mobile sites for great examples of experiences that prioritize search.

We're also using the HTML5 search input type, which is great for mobile devices that can bring up the appropriate virtual keyboard for many smartphones. And like the main header navigation, we're hiding the search form on small screens to save space. Clicking the search anchor toggles the form.

" - }, - { - "el": "#product-img nav", - "title" : "Image Navigation", - "comment": "

Instead of providing bullets, pagination or text-based image navigation, it's good e-commerce practice to show a preview of the various product views. By default the images simply link through to their larger counterparts, and if adequate javascript support exists, the images get loaded into the main image container.

" - }, - { - "el": "#img-container", - "title" : "Product Image", - "comment": "

The product image is the focal point of the page for good reason. It's typically what the user is there to see. The default markup simply includes the main product image, but that gets replaced with an image gallery if adequate javascript support exists.

We're also using Modernizr to detect if the browser supports touch events and if it does, we load in an excellent lightweight script called Swipe.js to create a touch-friendly image carousel. This allows users to swipe between product photos in a touch-friendly way. Because gestures are invisible, they might get overlooked, but clicking on the image navigation thumbnails animates the slideshow and hints to the user gestural interaction is available.

" - }, - { - "el": ".product-main header", - "title" : "Product Overview", - "comment": "The product overview appears in the markup before the image container in order to provide the user with the product name, how much it costs and how popular it is. Providing this information as soon as possible can help the user determine whether or not this is the product they're looking for without having to wait for the rest of the page to load." - }, - { - "el": ".star", - "title" : "Rating Stars", - "comment": "

We're using HTML special characters to display the product rating stars. We're using HTML characters instead of images to reduce the amount of images we're requesting and also maintaining crispness on high resolution screens. Not every device supports HTML special characters (Blackberry <=5.0 for example), but support is strong enough and the benefits are many.

See also: Optimizing Web Experiences for High Resolution Screens

" - }, - { - "el": ".review-count", - "title" : "Review Count", - "comment": "This is a simple anchor link that points to the review section of the page. This may seem like a small detail, but consider a mobile use case. Users can be in stores looking at the physical product, and 79% of smartphone consumers use their phones to help with shopping. They might be interested in buying in-store but turn to their phones to verify its popularity and quality. Making it easy for uses to read product reviews on small screens can help drive more sales, both online and offline.

While not incorporated yet, it would be easy to load the reviews for small screens on demand, thereby saving a step.

" - }, - { - "el": ".qty-field", - "title" : "Quantity Field", - "comment": "We're using the HTML5 number input type, which brings up the appropriate virtual keyboard for many mobile browsers. To increase usability, the input labels are using the \"for\" attribute, which focuses the cursor in the form field when clicked. However, iOS doesn't honor \"for\" default functionality, so we're adding \"cursor: pointer\" to the labels to get Mobile Safari to behave properly." - }, - { - "el": ".size-field", - "title" : "Size Dropdown", - "comment": "We're using a basic select menu to choose the size, which is commonplace for any e-commerce site. Select menus can be especially difficult to style and can vary greatly in behavior between platforms. Keep this in mind when creating " - }, - { - "el": ".submit-form", - "title" : "Add to Cart button", - "comment": "The add to cart button is the primary user action on the page. That's why it's large and in charge and very prominently placed on the page. The button is using box-shadows and rounded corners to create an attractive button that will hopefully get plenty of clicks." - }, - { - "el": ".share-btn", - "title" : "Share button", - "comment": "It seems like everything has a share button on it these days. And for good reason. Sharing content and products on social networks can be a great way to increase exposure. However, tacking on tons of social widgets adds a lot of overhead, which can be extremely detrimental to the site's performance. Including a simple share link that loads the heavy widgets only when requested is one way to keep pages fast and social. Check out Target's mobile site for an example of a site that isolates share functionality in a separate page fragment." - }, - { - "el": ".find-nearby", - "title" : "Geolocation", - "comment": "One of the most important aspects of the mobile context is location. We carry our mobile devices with us everywhere. Using geolocation we can tap into the user's location to deliver an enhanced experience. In this case we're giving them a chance to check out what stores nearby might sell this product. The geolocation API is well supported in mobile browsers as well as desktop browsers. We're using Modernizr to detect for geolocation support and if its support, we ask the user for their latitude and longitude. If the browser does not support geolocation, the default experience could take the user to a simple web form asking for a ZIP code. Check out Tiffany's mobile site store locator for an example of geolocation in action." - }, - { - "el": "#p-desc", - "title" : "Product Description", - "comment": "A product description is an essential part of any e-commerce experience. Descriptions offer tangible details that inform and persuade, and the tone can help support the physical product. Provide relevant information clearly and concisely. Check out the Android design guide for some tips on how to keep copy short and extremely effective." - }, - { - "el": "#related-products", - "title" : "Related Products", - "comment": "

Related products are obviously an important aspect of e-commerce sites as they drive awareness of other similar products and can lead to more purchases. However, including a lot of auxiliary content can bog down the site performance, which is especially crucial on mobile. On slow connections, the presence of this extra content might slow down the user experience enough that the user gives up.

We're handling the issue by conditionally loading the auxiliary content.

By default, the related item link simply clicks through to an HTML fragment containing the related products. The content is still accessible, even on devices with poor or no javascript support. When the user clicks on the related products on small screens, the content gets dynamically loaded inline and the link becomes a toggler for the content. Once the experience reaches a certain width breakpoint, we then load in the content. However, screen size != fast connection, so we should keep our eyes on the emerging navigator.connection to better gauge real connection speed.

See also: An Ajax-Include Pattern for Modular Content

All these wonderful t-shirts are retired/rejected Busted Tees, graciously donated to this demo by Will Schneider.

" - }, - { - "el": "#reviews", - "title" : "Reviews", - "comment": "Reviews are incredibly influential on a user's decision to purchase a product or pass on it. Also, because we carry our mobile phones with us everywhere, we use them to inform our in-store purchased. 70% of smartphone owners use them while in brick and mortar stores, and often times they're looking for reviews to give them the green light to buy.

Only the primary product content gets loaded by default, and the reviews exist as their own separate HTML fragment. The reviews remain accessible and don't get loaded until we conditionally load them when the screen is large enough or small screen users click the reviews link. This keeps things nimble while still providing access to the valuable reviews.

See also: An Ajax-Include Pattern for Modular Content

" - }, - { - "el": "#p-reviews .btn", - "title" : "More Reviews Button", - "comment": "

All reviews aren't loaded by default in order to keep the site performance in top shape. Ultimately, this button could be replaced with a lazy-loading solution to remove the need for the button.

" - }, - { - "el": ".footer .nav", - "title" : "Footer Nav", - "comment": "

Repetition of elements isn't a bad thing, especially with potentially long scrolling pages on mobile. Providing access to the main site navigation is a good way for the user to jump off to another section and avoids leaving them with a dead end. Also, some mobile sites like Bagcheck and Contents Magazine keep the primary navigation at the footer and simply link to it with an anchor in the header. That way the nav stays accessible but the focus stays on on the core page content.

" - }, - { - "el": ".tel", - "title" : "Customer Service Number", - "comment": "

We sometimes forget that mobile phones can make phone calls. Whether a user is having trouble with the site or simply has some questions about the product he's about to buy, it's a smart decision to provide a clickable phone number to facilitate that call. What happens when desktops and other non-phone devices click on the tel link? Well, some devices (like iPads and other tablets) ask the user if they'd like to add the number to their contact list, other desktops open 3rd party VoIP programs like Skype, and others simply give an error message.

" - }, - { - "el": ".top", - "title" : "Back to Top Link", - "comment": "

Back to top links are simple yet underrated. They provide users with an easy way back up to the top of the page with minimum effort. This is especially helpful on mobile devices, which tend to have long scrolling pages.

We're using an HTML character for the back to top arrow in order to reduce image elements and keep things looking crisp on high res displays.

" - } -] -}; \ No newline at end of file diff --git a/source/_data/data.json b/source/_data/data.json deleted file mode 100644 index 3c79fac4a..000000000 --- a/source/_data/data.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "title" : "Pattern Lab", - "htmlClass": "pl", - "bodyClass": "body", - "img": { - "landscape-4x3": { - "src": "../../images/fpo_4x3.png", - "alt": "4x3 Image" - }, - "landscape-16x9": { - "src": "../../images/fpo_16x9.png", - "alt": "16x9 Image" - }, - "square": { - "src": "../../images/fpo_square.png", - "alt": "Square Thumbnail" - }, - "avatar" : { - "src" : "../../images/fpo_avatar.png", - "alt" : "Person Name" - }, - "rectangle": { - "src": "http://placeimg.com/400/300/tech", - "alt": "Rectangle" - } - }, - "headline" : { - "short" : "Lorem ipsum dolor sit (37 characters)", - "medium" : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. (72 characters)" - }, - "excerpt" : { - "short" : "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam", - "medium" : "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", - "long" : "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - }, - "description" : "So, setting about it as methodically as men might smoke out a wasps' nest, the Martians spread this strange stifling vapour over the Londonward country. The horns of the crescent slowly moved apart, until at last they formed a line from Hanwell to Coombe and Malden. All night through their destructive tubes advanced.", - "url" : "#", - "name" : { - "first": "Lacy", - "firsti": "L", - "middle": "Tommie", - "middlei": "T", - "last": "Way", - "lasti": "W" - }, - "year" : { - "long": "2013", - "short": "13" - }, - "month" : { - "long": "February", - "short": "Feb", - "digit": "02" - }, - "dayofweek" : { - "long": "Monday", - "short": "Mon" - }, - "day" : { - "long": "10", - "short": "10", - "ordinal": "th" - }, - "hour" : { - "long": "01", - "short": "1", - "military": "13", - "ampm": "pm" - }, - "minute" : { - "long": "20", - "short": "20" - }, - "seconds" : "31", - "author" : { - "first-name": "Author", - "last-name": "Name" - }, - "hero": true, - "emergency" : false, - "touts" : [ - { }, - { }, - { } - ], - "latest-posts" : [ - { }, - { }, - { }, - { }, - { } - ] -} diff --git a/source/_data/listitems.json b/source/_data/listitems.json deleted file mode 100644 index ebda01757..000000000 --- a/source/_data/listitems.json +++ /dev/null @@ -1,782 +0,0 @@ -{ - "1": { - "title": "Nullizzle shizznit velizzle, hizzle, suscipit own yo', gravida vizzle, arcu.", - "img": { - "avatar": { - "src": "http://placeimg.com/100/100/people", - "alt": "Avatar" - }, - "square": { - "src": "http://placeimg.com/300/300/nature", - "alt": "Square" - }, - "rectangle": { - "src": "http://placeimg.com/400/300/tech", - "alt": "Rectangle" - } - }, - "headline": { - "short": "Lorizzle pimpin' dolizzle sit amet I", - "medium": "Rizzle adipiscing elizzle. Nullam sapien velizzle, shit volutpizzle, my" - }, - "excerpt": { - "short": "Shizz fo shizzle mah nizzle fo rizzle, mah home g-dizzle, gravida vizzle, arcu. Pellentesque crunk tortizzle. Sed erizzle. Black izzle sheezy telliv.", - "medium": "Izzle crazy tempizzle sizzle. We gonna chung gangsta get down get down fo shizzle turpizzle. Away break it down black. Pellentesque bling bling rhoncus fo shizzle. In hac the bizzle platea dictumst. Black dapibizzle. Crackalackin.", - "long": "Curabitizzle fo shizzle diam quizzle nisi nizzle mollizzle. Suspendisse boofron. Morbi odio. Sure pizzle. Crazy orci. Shut the shizzle up maurizzle get down get down, check out this a, go to hizzle sit amizzle, malesuada izzle, pede. Pellentesque gravida. Vestibulizzle check it out mi, volutpat izzle, shiz sed, shiznit sempizzle, da bomb. Funky fresh in ipsum. Da bomb volutpat felis vizzle daahng dawg. Crizzle quis dope izzle fo shizzle my ni." - }, - "description": "Fizzle crazy tortor. Sed rizzle. Ass pimpin' dolor dapibizzle turpis tempizzle fo shizzle my nizzle. Maurizzle pellentesque its fo rizzle izzle turpis. Get down get down we gonna chung nizzle. Shizzlin dizzle eleifend rhoncizzle break it down. In yo ghetto platea dictumst. Bling bling dapibizzle. Curabitur break yo neck, yall fo, pretizzle eu, go to hizzle dope, own yo' vitae, nunc. Bizzle suscipizzle. Ass semper velit sizzle fo.", - "url": "http://lorizzle.nl/", - "name": { - "first": "Junius", - "firsti": "J", - "middle": "Marius", - "middlei": "M", - "last": "Koolen", - "lasti": "K" - }, - "year": { - "long": "2013", - "short": "13" - }, - "month": { - "long": "January", - "short": "Jan", - "digit": "01" - }, - "dayofweek": { - "long": "Sunday", - "short": "Sun" - }, - "day": { - "long": "01", - "short": "1", - "ordinal": "st" - }, - "hour": { - "long": "06", - "short": "6", - "military": "06", - "ampm": "am" - }, - "minute": { - "long": "20", - "short": "20" - }, - "seconds": "31" - }, - "2": { - "title": "Veggies sunt bona vobis, proinde vos postulo", - "img": { - "avatar": { - "src": "http://placeimg.com/100/100/nature", - "alt": "Avatar" - }, - "square": { - "src": "http://placeimg.com/300/300/tech", - "alt": "Square" - }, - "rectangle": { - "src": "http://placeimg.com/400/300/people", - "alt": "Rectangle" - } - }, - "headline": { - "short": "Veggies sunt bona vobis, proinde vos", - "medium": "Postulo esse magis azuki bean burdock brussels sprout quandong komatsun" - }, - "excerpt": { - "short": "A fava bean collard greens endive tomatillo lotus root okra winter purslane zucchini parsley spinach artichoke. Brussels sprout pea turnip catsear.", - "medium": "Bush tomato gumbo potato garbanzo ricebean burdock daikon coriander kale quandong. Bok choy celery leek avocado shallot horseradish aubergine parsley. Bok choy bell pepper kale celery desert raisin kakadu plum bok choy bunya nuts.", - "long": "Spinach tigernut. Corn cucumber grape black-eyed pea asparagus spinach avocado dulse bunya nuts epazote celery desert raisin celtuce burdock plantain yarrow napa cabbage. Plantain okra seakale endive tigernut pea sprouts asparagus corn chard peanut beet greens groundnut radicchio carrot coriander gumbo gram celtuce. Jícama nori bamboo shoot collard greens okra radicchio tomato. Catsear mustard corn tigernut celery kale water spinach bok choy." - }, - "description": "Mung bean squash sorrel taro coriander collard greens gumbo bitterleaf tomato. Taro water chestnut celtuce turnip yarrow celery endive scallion black-eyed pea onion. Aubergine dulse turnip greens mustard salsify garlic soybean parsley bitterleaf desert raisin courgette.", - "url": "http://veggieipsum.com", - "name": { - "first": "Siguror", - "firsti": "S", - "middle": "Aron", - "middlei": "A", - "last": "Hanigan", - "lasti": "H" - }, - "year": { - "long": "2013", - "short": "13" - }, - "month": { - "long": "February", - "short": "Feb", - "digit": "02" - }, - "dayofweek": { - "long": "Monday", - "short": "Mon" - }, - "day": { - "long": "10", - "short": "10", - "ordinal": "th" - }, - "hour": { - "long": "01", - "short": "1", - "military": "13", - "ampm": "pm" - }, - "minute": { - "long": "20", - "short": "20" - }, - "seconds": "31" - }, - "3": { - "title": "Bacon ipsum dolor sit amet turducken strip steak beef ribs shank", - "img": { - "avatar": { - "src": "http://placeimg.com/100/100/tech", - "alt": "Avatar" - }, - "square": { - "src": "http://placeimg.com/300/300/people", - "alt": "Square" - }, - "rectangle": { - "src": "http://placeimg.com/400/300/nature", - "alt": "Rectangle" - } - }, - "headline": { - "short": "Bacon ipsum dolor sit amet spare rib", - "medium": "Tongue pancetta short ribs bacon. Kielbasa ball tip cow bresaola, capic" - }, - "excerpt": { - "short": "Tail jerky rump shoulder t-bone meatball meatloaf salami. Filet mignon shank t-bone venison, ham hock ribeye drumstick bresaola kielbasa. Frankfurter.", - "medium": "Doner biltong turducken leberkas. Rump swine pork loin ribeye ball tip meatloaf, pork chop ground round pig pancetta cow biltong brisket. Beef corned beef beef ribs, bacon pork belly sausage meatball boudin doner ham hock. Swine gro.", - "long": "Und round meatball, bacon pig leberkas corned beef tongue shoulder. Drumstick pork loin prosciutto ball tip shank pancetta spare ribs jowl pastrami. Frankfurter boudin filet mignon ribeye. Pig hamburger strip steak ham turducken prosciutto bresaola ground round pancetta frankfurter jowl. Frankfurter tongue brisket tenderloin, beef ribs pastrami biltong tail bresaola flank. Biltong pork chop beef boudin hamburger bacon. Capicola bresaola sausage." - }, - "description": "Boudin sausage jerky pastrami ground round salami biltong. Sausage fatback strip steak doner pork loin, pork belly drumstick ham short loin hamburger shankle. Short ribs sirloin rump tri-tip beef biltong. Meatball pig salami, jowl pork loin fatback short loin drumstick andouille.", - "url": "http://baconipsum.com/", - "name": { - "first": "Teun", - "firsti": "T", - "middle": "Jodocus", - "middlei": "J", - "last": "Richard", - "lasti": "R" - }, - "year": { - "long": "2013", - "short": "13" - }, - "month": { - "long": "March", - "short": "Mar", - "digit": "03" - }, - "dayofweek": { - "long": "Tuesday", - "short": "Tue" - }, - "day": { - "long": "22", - "short": "22", - "ordinal": "nd" - }, - "hour": { - "long": "04", - "short": "4", - "military": "16", - "ampm": "pm" - }, - "minute": { - "long": "45", - "short": "45" - }, - "seconds": "11" - }, - "4": { - "title": "Whatever swag accusamus occupy, gentrify butcher tote bag", - "img": { - "avatar": { - "src": "http://placeimg.com/100/100/animals", - "alt": "Avatar" - }, - "square": { - "src": "http://placeimg.com/300/300/arch", - "alt": "Square" - }, - "rectangle": { - "src": "http://placeimg.com/400/300/people/grayscale", - "alt": "Rectangle" - } - }, - "headline": { - "short": "Nesciunt sunt cillum keytar Pitchfork", - "medium": "Tote bag mixtape PBR Helvetica scenester forage four loko. Irure Tonx" - }, - "excerpt": { - "short": "Golf quis +1, Wes Anderson church-key lo-fi keffiyeh selvage culpa authentic Brooklyn fap chambray. Id synth yr, 3 wolf moon locavore +1 mixtape do.", - "medium": "Sed single-origin coffee anim eu. Bicycle rights Neutra Truffaut pop-up. Paleo hella irure meh Banksy, Wes Anderson typewriter VHS jean shorts yr. Eiusmod officia banjo Thundercats, odio laborum magna deep v cornhole nostrud kitsch.", - "long": "Tattooed Williamsburg. Jean shorts proident kogi laboris. Non tote bag pariatur elit slow-carb, Vice irure eu Echo Park ea aliqua chillwave. Cornhole Etsy quinoa Pinterest cardigan. Excepteur quis forage, Blue Bottle keffiyeh velit hoodie direct trade typewriter Etsy. Fingerstache squid non, sriracha drinking vinegar Shoreditch pork belly. Paleo sartorial mollit 3 wolf moon chambray whatever, sed tote bag small batch freegan. Master cleanse." - }, - "description": "Fanny pack ullamco et veniam semiotics. Shoreditch PBR reprehenderit cliche, magna Tonx aesthetic. Narwhal photo booth DIY aute post-ironic anim. Vice cliche brunch est before they sold out fap, street art Odd Future fashion axe messenger bag nihil Tonx tattooed. Nihil hashtag incididunt, do eu art party Banksy jean shorts four loko typewriter.", - "url": "http://hipsteripsum.me/", - "name": { - "first": "Duane", - "firsti": "D", - "middle": "Edvin", - "middlei": "E", - "last": "Wilms", - "lasti": "W" - }, - "year": { - "long": "2013", - "short": "13" - }, - "month": { - "long": "April", - "short": "Apr", - "digit": "04" - }, - "dayofweek": { - "long": "Wednesday", - "short": "Wed" - }, - "day": { - "long": "13", - "short": "13", - "ordinal": "th" - }, - "hour": { - "long": "10", - "short": "10", - "military": "10", - "ampm": "am" - }, - "minute": { - "long": "14", - "short": "14" - }, - "seconds": "52" - }, - "5": { - "title": "Marshall McLuhan Colbert bump backpack journalist vast wasteland Romenesko CPM", - "img": { - "avatar": { - "src": "http://placeimg.com/100/100/people/grayscale", - "alt": "Avatar" - }, - "square": { - "src": "http://placeimg.com/300/300/animals", - "alt": "Square" - }, - "rectangle": { - "src": "http://placeimg.com/400/300/arch", - "alt": "Rectangle" - } - }, - "headline": { - "short": "Blog meme masthead DocumentCloud Fou", - "medium": "Square tabloid Andy Carvin stupid commenters, Nick Denton mathewi semip" - }, - "excerpt": { - "short": "I love the Weather & Opera section Groupon copyright in the slot, Journal Register open newsroom analytics future totally blowing up on Twitter AOL.", - "medium": "CTR mthomps Flipboard do what you do best and link to the rest Buttry media bias Journal Register RT, newspaper strike do what you do best and link to the rest semipermeable learnings cognitive surplus mathewi, Encyclo Google News.", - "long": "Pulse mathewi Project Thunderdome digital first. HuffPo social media optimization try PR dying the notion of the public monetization data visualization audience atomization overcome community, libel lawyer twitterati should isn't a business model fair use innovation Facebook AOL, Walter Cronkite died for your sins horse-race coverage crowdfunding Patch but what's the business model rubber cement horse-race coverage. Lucius Nieman content farm." - }, - "description": "Like button audience atomization overcome Colbert bump Free Darko inverted pyramid we will make them pay, digital circulation strategy Like button totally blowing up on Twitter church of the savvy. Pictures of Goats section open source discuss Frontline analog thinking filters paidContent.", - "url": "http://www.niemanlab.org/journo-ipsum/", - "name": { - "first": "Frans", - "firsti": "F", - "middle": "Fabius", - "middlei": "F", - "last": "Keegan", - "lasti": "K" - }, - "year": { - "long": "2013", - "short": "13" - }, - "month": { - "long": "May", - "short": "May", - "digit": "05" - }, - "dayofweek": { - "long": "Thursday", - "short": "Thu" - }, - "day": { - "long": "26", - "short": "26", - "ordinal": "th" - }, - "hour": { - "long": "06", - "short": "6", - "military": "18", - "ampm": "pm" - }, - "minute": { - "long": "37", - "short": "37" - }, - "seconds": "24" - }, - "6": { - "title": "Thunder, thunder, thundercats, Ho!", - "img": { - "avatar": { - "src": "http://placeimg.com/100/100/arch", - "alt": "Avatar" - }, - "square": { - "src": "http://placeimg.com/300/300/animals", - "alt": "Square" - }, - "rectangle": { - "src": "http://placeimg.com/400/300/people/grayscale", - "alt": "Rectangle" - } - }, - "headline": { - "short": "Hong Kong Phooey, number one super g", - "medium": "Hong Kong Phooey, quicker than the human eye. He's got style, a groovy" - }, - "excerpt": { - "short": "Style, and a car that just won't stop. When the going gets tough, he's really rough, with a Hong Kong Phooey chop (Hi-Ya!). Hong Kong Phooey, number.", - "medium": "One super guy. Hong Kong Phooey, quicker than the human eye. Hong Kong Phooey, he's fan-riffic! One for all and all for one, Muskehounds are always ready. One for all and all for one, helping everybody. One for all and all for one.", - "long": "It's a pretty story. Sharing everything with fun, that's the way to be. One for all and all for one, Muskehounds are always ready. One for all and all for one, helping everybody. One for all and all for one, can sound pretty corny. If you've got a problem chum, think how it could be. This is my boss, Jonathan Hart, a self-made millionaire, he's quite a guy. This is Mrs H., she's gorgeous, she's one lady who knows how to take care of herself." - }, - "description": "Beats all you've ever saw, been in trouble with the law since the day they was born. Straight'nin' the curve, flat'nin' the hills. Someday the mountain might get 'em, but the law never will. Makin' their way, the only way they know how, that's just a little bit more than the law will allow. Just good ol' boys, wouldn't change if they could, fightin' the system like a true modern day Robin Hood.", - "url": "http://www.malevole.com/mv/misc/text/", - "name": { - "first": "Fergus", - "firsti": "F", - "middle": "Jon", - "middlei": "J", - "last": "Althuis", - "lasti": "A" - }, - "year": { - "long": "2013", - "short": "13" - }, - "month": { - "long": "June", - "short": "Jun", - "digit": "06" - }, - "dayofweek": { - "long": "Friday", - "short": "Fri" - }, - "day": { - "long": "08", - "short": "8", - "ordinal": "th" - }, - "hour": { - "long": "11", - "short": "11", - "military": "23", - "ampm": "pm" - }, - "minute": { - "long": "37", - "short": "37" - }, - "seconds": "33" - }, - "7": { - "title": "Yeah, I like animals better than people sometimes", - "img": { - "avatar": { - "src": "http://placeimg.com/100/100/any", - "alt": "Avatar" - }, - "square": { - "src": "http://placeimg.com/300/300/any", - "alt": "Square" - }, - "rectangle": { - "src": "http://placeimg.com/400/300/any", - "alt": "Rectangle" - } - }, - "headline": { - "short": "Now that we know who you are, I know", - "medium": "Who I am. I'm not a mistake! It all makes sense! In a comic, you know" - }, - "excerpt": { - "short": "How you can tell who the arch-villain's going to be? He's the exact opposite of the hero. And most times they're friends, like you and me! I should've known way back when... You know why, David? Because of the kids. They called me.", - "medium": "The lysine contingency - it's intended to prevent the spread of the animals is case they ever got off the island. Dr. Wu inserted a gene that makes a single faulty enzyme in protein metabolism. The animals can't manufacture the amin.", - "long": "Do you see any Teletubbies in here? Do you see a slender plastic tag clipped to my shirt with my name printed on it? Do you see a little Asian child with a blank expression on his face sitting outside on a mechanical helicopter that shakes when you put quarters in it? No? Well, that's what you see at a toy store. And you must think you're in a toy store, because you're here shopping for an infant named Jeb. Acid lysine. Unless they're." - }, - "description": "Especially dogs. Dogs are the best. Every time you come home, they act like they haven't seen you in a year. And the good thing about dogs... is they got different dogs for different people. Like pit bulls. The dog of dogs. Pit bull can be the right man's best friend... or the wrong man's worst enemy. You going to give me a dog for a pet, give me a pit bull.", - "url": "http://slipsum.com/lite/", - "name": { - "first": "Bertil", - "firsti": "B", - "middle": "Pier", - "middlei": "P", - "last": "Aaij", - "lasti": "A" - }, - "year": { - "long": "2013", - "short": "13" - }, - "month": { - "long": "July", - "short": "Jul", - "digit": "07" - }, - "dayofweek": { - "long": "Saturday", - "short": "Sat" - }, - "day": { - "long": "22", - "short": "22", - "ordinal": "nd" - }, - "hour": { - "long": "11", - "short": "11", - "military": "11", - "ampm": "am" - }, - "minute": { - "long": "12", - "short": "12" - }, - "seconds": "47" - }, - "8": { - "title": "Webtwo ipsum dolor sit amet, eskobo chumby doostang bebo", - "img": { - "avatar": { - "src": "http://placeimg.com/100/100/any/grayscale", - "alt": "Avatar" - }, - "square": { - "src": "http://placeimg.com/300/300/any/grayscale", - "alt": "Square" - }, - "rectangle": { - "src": "http://placeimg.com/400/300/any/grayscale", - "alt": "Rectangle" - } - }, - "headline": { - "short": "Webtwo ipsum dolor sit amet, eskobo", - "medium": "Chumby doostang bebo. Wakoopa oooj geni zoho loopt eskobo sifteo chart" - }, - "excerpt": { - "short": "Dropio, chumby waze dopplr plugg oooj yammer jibjab imvu yuntaa knewton, mobly trulia airbnb bitly chegg tivo empressr knewton. Plickers spock voxy.", - "medium": "Zooomr kippt voxy zinch appjet napster trulia, zappos wufoo zapier spotify mzinga jaiku fleck, disqus lijit voxy voki yoono. Dogster elgg jibjab xobni kazaa bebo udemy sifteo kiko, elgg knewton skype mog octopart zoodles kazaa udem.", - "long": "Appjet spock handango empressr lijit palantir weebly dropio jibjab revver kaboodle spotify orkut mobly chegg akismet, handango ebay woopra revver joukuu kosmix unigo oooooc wufoo zanga kno zinch spock knewton. Balihoo greplin bebo squidoo skype kaboodle meebo disqus joost gooru, zlio tumblr edmodo palantir eskobo shopify kiko gsnap. Greplin balihoo chartly plugg imeem diigo trulia plickers qeyno wikia akismet, palantir grockit prezi jabber zo." - }, - "description": "Wufoo diigo grockit sifteo divvyshot, unigo zooomr revver. Edmodo appjet joyent skype bubbli jajah zoodles joukuu xobni hojoki edmodo appjet, mozy mzinga akismet yuntaa joost yuntaa geni tivo insala yoono chumby, grockit sococo loopt zanga etsy cloudera koofers empressr jiglu blippy. Omgpop lanyrd joukuu sococo zimbra airbnb movity jibjab, foodzie.", - "url": "http://web20ipsum.com", - "name": { - "first": "Freyr", - "firsti": "F", - "middle": "Ninian", - "middlei": "N", - "last": "Hines", - "lasti": "H" - }, - "year": { - "long": "2013", - "short": "13" - }, - "month": { - "long": "August", - "short": "Aug", - "digit": "08" - }, - "dayofweek": { - "long": "Sunday", - "short": "Sun" - }, - "day": { - "long": "31", - "short": "31", - "ordinal": "st" - }, - "hour": { - "long": "03", - "short": "3", - "military": "15", - "ampm": "pm" - }, - "minute": { - "long": "42", - "short": "42" - }, - "seconds": "21" - }, - "9": { - "title": "Rebel Mission to Ord Mantell", - "img": { - "avatar": { - "src": "http://placeimg.com/100/100/any/sepia", - "alt": "Avatar" - }, - "square": { - "src": "http://placeimg.com/300/300/any/sepia", - "alt": "Square" - }, - "rectangle": { - "src": "http://placeimg.com/400/300/any/sepia", - "alt": "Rectangle" - } - }, - "headline": { - "short": "All right. Well, take care of yourself, Han", - "medium": "You don't believe in the Force, do you? The Force is strong with this one" - }, - "excerpt": { - "short": "I'm trying not to, kid. I find your lack of faith disturbing. You are a part of the Rebel Alliance and a traitor! Take her away! I want to come with.", - "medium": "I'm surprised you had the courage to take the responsibility yourself. Don't be too proud of this technological terror you've constructed. The ability to destroy a planet is insignificant next to the power of the Force. You don't be.", - "long": "A tremor in the Force. The last time I felt it was in the presence of my old master. You don't believe in the Force, do you? I have traced the Rebel spies to her. Now she is my only link to finding their secret base. A tremor in the Force. The last time I felt it was in the presence of my old master. I'm trying not to, kid. The more you tighten your grip, Tarkin, the more star systems will slip through your fingers. There's nothing for me here." - }, - "description": "I find your lack of faith disturbing. A tremor in the Force. The last time I felt it was in the presence of my old master. Don't act so surprised, Your Highness. You weren't on any mercy mission this time. Several transmissions were beamed to this ship by Rebel spies. I want to know what happened to the plans they sent you. The plans you refer to will soon be back in our hands.", - "url": "http://chrisvalleskey.com/fillerama/", - "name": { - "first": "Jacobus", - "firsti": "J", - "middle": "Domitianus", - "middlei": "D", - "last": "Sneiders", - "lasti": "S" - }, - "year": { - "long": "2013", - "short": "13" - }, - "month": { - "long": "September", - "short": "Sep", - "digit": "09" - }, - "dayofweek": { - "long": "Monday", - "short": "Mon" - }, - "day": { - "long": "04", - "short": "4", - "ordinal": "th" - }, - "hour": { - "long": "09", - "short": "9", - "military": "09", - "ampm": "am" - }, - "minute": { - "long": "04", - "short": "4" - }, - "seconds": "37" - }, - "10": { - "title": "Help, help, I'm being repressed!", - "img": { - "avatar": { - "src": "http://placeimg.com/100/100/tech/grayscale", - "alt": "Avatar" - }, - "square": { - "src": "http://placeimg.com/300/300/nature/grayscale", - "alt": "Square" - }, - "rectangle": { - "src": "http://placeimg.com/400/300/arch/grayscale", - "alt": "Rectangle" - } - }, - "headline": { - "short": "The swallow may fly south with the sun", - "medium": "On second thoughts, let's not go there. It is a silly place. You don't" - }, - "excerpt": { - "short": "The swallow may fly south with the sun, and the house martin or the plover may seek warmer climes in winter, yet these are not strangers to our land.", - "medium": "The Knights Who Say Ni demand a sacrifice! Found them? In Mercia?! The coconut's tropical! Where'd you get the coconuts? Why do you think that she is a witch? I am your king. You don't vote for kings. But you are dressed as one. Oh, ow!", - "long": "Well, I didn't vote for you. Burn her! Be quiet! He hasn't got shit all over him. Where'd you get the coconuts? The swallow may fly south with the sun, and the house martin or the plover may seek warmer climes in winter, yet these are not strangers to our land. No! Yes, yes. A bit. But she's got a wart. Shut up! Will you shut up?! I have to push the pram a lot. Now, look here, my good man. Frighten us, English pig-dogs! Go and boil your bottoms." - }, - "description": "The Knights Who Say Ni demand a sacrifice! …Are you suggesting that coconuts migrate? Knights of Ni, we are but simple travelers who seek the enchanter who lives beyond these woods. You don't frighten us, English pig-dogs! Go and boil your bottoms, sons of a silly person! I blow my nose at you, so-called Ah-thoor Keeng, you and all your silly English K-n-n-n-n-n-n-n-niggits!", - "url": "http://chrisvalleskey.com/fillerama/", - "name": { - "first": "Plinius", - "firsti": "P", - "middle": "Varinius", - "middlei": "V", - "last": "Sloane", - "lasti": "S" - }, - "year": { - "long": "2013", - "short": "13" - }, - "month": { - "long": "October", - "short": "Oct", - "digit": "10" - }, - "dayofweek": { - "long": "Tuesday", - "short": "Tue" - }, - "day": { - "long": "25", - "short": "25", - "ordinal": "th" - }, - "hour": { - "long": "03", - "short": "3", - "military": "03", - "ampm": "am" - }, - "minute": { - "long": "51", - "short": "51" - }, - "second": "19" - }, - "11": { - "title": "Danish danish candy canes bonbon cheesecake danish marzipan", - "img": { - "avatar": { - "src": "http://placeimg.com/100/100/tech/sepia", - "alt": "Avatar" - }, - "square": { - "src": "http://placeimg.com/300/300/animals/sepia", - "alt": "Square" - }, - "rectangle": { - "src": "http://placeimg.com/400/300/arch/sepia", - "alt": "Rectangle" - } - }, - "headline": { - "short": "Carrot cake fruitcake dessert apple", - "medium": "Pie powder lemon drops sesame snaps cake brownie. Biscuit ice cream gin" - }, - "excerpt": { - "short": "Bread cotton candy marzipan. Baker too go gingerbread topping cupcake donut. Fruitcake marzipan bear claw tart toffee candy cheesecake. Lemon drops.", - "medium": "Cupcake chupa chups pudding gummies. Unerdwear.com cupcake candy soufflé sesame snaps macaroon sesame snaps. Tart dragée muffin. Sweet roll gummi bears caramels fruitcake candy cake. Cotton candy carrot cake tart cotton candy. Jelly.", - "long": "Gingerbread candy icing pastry cake bonbon fruitcake donut. Powder liquorice dessert tart croissant cake. Dessert chocolate cake sweet roll candy candy sesame snaps tiramisu ice cream. Candy candy canes marzipan biscuit cupcake pie pudding. Donut cotton candy muffin. Pastry bear claw icing halvah. Gingerbread cotton candy sweet roll toffee chocolate jujubes. Wafer jujubes danish ice cream lemon drops wafer. Sesame snaps cupcake gummies browni." - }, - "description": "Sugar plum wafer soufflé ice cream. Wafer topping biscuit pie gummi bears topping. Gummies toffee powder applicake oat cake cookie. Bear claw candy tootsie roll fruitcake danish applicake candy canes macaroon. Liquorice tiramisu danish cotton candy gummies. Tiramisu dessert gummi bears macaroon sweet roll jelly-o gummi bears marzipan.", - "url": "http://cupcakeipsum.com/", - "name": { - "first": "Matthias", - "firsti": "M", - "middle": "Brady", - "middlei": "B", - "last": "Macguinness", - "lasti": "M" - }, - "year": { - "long": "2013", - "short": "13" - }, - "month": { - "long": "November", - "short": "Nov", - "digit": "11" - }, - "dayofweek": { - "long": "Wednesday", - "short": "Wed" - }, - "day": { - "long": "19", - "short": "19", - "ordinal": "th" - }, - "hour": { - "long": "11", - "short": "11", - "military": "23", - "ampm": "pm" - }, - "minute": { - "long": "55", - "short": "55" - }, - "seconds": "12" - }, - "12": { - "title": "Cottage cheese brie lancashire. Boursin when the cheese comes out.", - "img": { - "avatar": { - "src": "http://placeimg.com/100/100/people/sepia", - "alt": "Avatar" - }, - "square": { - "src": "http://placeimg.com/300/300/people/sepia", - "alt": "Square" - }, - "rectangle": { - "src": "http://placeimg.com/400/300/people/sepia", - "alt": "Rectangle" - } - }, - "headline": { - "short": "Cauliflower cheese cream cheese baby", - "medium": "Lancashire cheesy feet rubber cheese cheese and wine gouda the big chee" - }, - "excerpt": { - "short": "Queso fromage. Taleggio boursin bavarian bergkase cream cheese when the cheese comes out everybody's happy port-salut halloumi pecorino. Caerphilly cut the cheese manchego camembert de normandie goat melted cheese cheese and biscuit.", - "medium": "Pecorino queso lancashire. Manchego lancashire cheesy feet emmental babybel cheese strings dolcelatte bavarian bergkase. Ricotta cheese slices cheesy grin cow cheesecake smelly cheese mascarpone lancashire. Cow say cheese babybel do.", - "long": "Cheesy grin macaroni cheese airedale. Fromage frais airedale cheese and wine brie cow swiss swiss mozzarella. Emmental cheese triangles edam rubber cheese pepper jack ricotta airedale airedale. Brie parmesan smelly cheese cheese strings stinking bishop cheese strings taleggio. Bocconcini blue castello gouda. Everyone loves caerphilly rubber cheese halloumi smelly cheese melted cheese melted cheese bavarian bergkase. Rubber cheese ricotta emm." - }, - "description": "Queso caerphilly cheesecake. Parmesan chalk and cheese port-salut port-salut babybel cottage cheese cheesy grin pepper jack. Croque monsieur paneer st. agur blue cheese emmental airedale monterey jack bavarian bergkase cheese triangles. Halloumi parmesan.", - "url": "http://www.cheeseipsum.co.uk/", - "name": { - "first": "Aquila", - "firsti": "A", - "middle": "Gaius", - "middlei": "G", - "last": "Achterkamp", - "lasti": "A" - }, - "year": { - "long": "2013", - "short": "13" - }, - "month": { - "long": "December", - "short": "Dec", - "digit": "12" - }, - "dayofweek": { - "long": "Thursday", - "short": "Thu" - }, - "day": { - "long": "28", - "short": "28", - "ordinal": "th" - }, - "hour": { - "long": "08", - "short": "8", - "military": "08", - "ampm": "am" - }, - "minute": { - "long": "34", - "short": "34" - }, - "seconds": "56" - } -} diff --git a/source/_patterns/00-atoms/00-meta/_00-head.mustache b/source/_patterns/00-atoms/00-meta/_00-head.mustache deleted file mode 100644 index a751d06a2..000000000 --- a/source/_patterns/00-atoms/00-meta/_00-head.mustache +++ /dev/null @@ -1,15 +0,0 @@ - - - - {{ title }} - - - - - - - {% pattern-lab-head %} - - - - diff --git a/source/_patterns/00-atoms/00-meta/_01-foot.mustache b/source/_patterns/00-atoms/00-meta/_01-foot.mustache deleted file mode 100644 index 10e69fba6..000000000 --- a/source/_patterns/00-atoms/00-meta/_01-foot.mustache +++ /dev/null @@ -1,7 +0,0 @@ - - -{% pattern-lab-foot %} - - - - diff --git a/source/_patterns/00-atoms/01-global/00-colors.mustache b/source/_patterns/00-atoms/01-global/00-colors.mustache deleted file mode 100644 index 7f2653f8d..000000000 --- a/source/_patterns/00-atoms/01-global/00-colors.mustache +++ /dev/null @@ -1,38 +0,0 @@ -
    -
  • - - #ff0000 -
  • -
  • - - #00ff00 -
  • -
  • - - #0000ff -
  • -
  • - - #ffff00 -
  • -
  • - - #00ffff -
  • -
  • - - #ff00ff -
  • -
  • - - #ffffff -
  • -
  • - - #808080 -
  • -
  • - - #000000 -
  • -
\ No newline at end of file diff --git a/source/_patterns/00-atoms/01-global/01-fonts.mustache b/source/_patterns/00-atoms/01-global/01-fonts.mustache deleted file mode 100644 index 26b4b7bb5..000000000 --- a/source/_patterns/00-atoms/01-global/01-fonts.mustache +++ /dev/null @@ -1,6 +0,0 @@ -

Primary font: "HelveticaNeue", "Helvetica", "Arial", sans-serif;

-

Primary font italic: "HelveticaNeue", "Helvetica", "Arial", sans-serif;

-

Primary font bold: "HelveticaNeue", "Helvetica", "Arial", sans-serif;

-

Secondary font: Georgia, Times, "Times New Roman", serif;

-

Secondary font italic: Georgia, Times, "Times New Roman", serif;

-

Secondary font bold: Georgia, Times, "Times New Roman", serif;

\ No newline at end of file diff --git a/source/_patterns/00-atoms/01-global/02-animations.mustache b/source/_patterns/00-atoms/01-global/02-animations.mustache deleted file mode 100644 index 7d3074575..000000000 --- a/source/_patterns/00-atoms/01-global/02-animations.mustache +++ /dev/null @@ -1,3 +0,0 @@ -
Fade: Duration: 0.3s Easing: ease-out (Hover to see effect)
- -
Movement: Duration: 0.8s Easing: ease-in-out; (Hover to see effect)
\ No newline at end of file diff --git a/source/_patterns/00-atoms/01-global/03-visibility.mustache b/source/_patterns/00-atoms/01-global/03-visibility.mustache deleted file mode 100644 index 13e602122..000000000 --- a/source/_patterns/00-atoms/01-global/03-visibility.mustache +++ /dev/null @@ -1,11 +0,0 @@ -

This text is hidden on smaller screens

- -

This text is only visible on smaller screens

- -

This text is hidden on medium screens only

- -

This text is only visible on medium screens

- -

This text is hidden on large screens

- -

This text is only visible on large screens

\ No newline at end of file diff --git a/source/_patterns/00-atoms/02-text/00-headings.mustache b/source/_patterns/00-atoms/02-text/00-headings.mustache deleted file mode 100644 index 43f648c7f..000000000 --- a/source/_patterns/00-atoms/02-text/00-headings.mustache +++ /dev/null @@ -1,6 +0,0 @@ -

Heading Level 1

-

Heading Level 2

-

Heading Level 3

-

Heading Level 4

-
Heading Level 5
-
Heading Level 6
\ No newline at end of file diff --git a/source/_patterns/00-atoms/02-text/01-subheadings.mustache b/source/_patterns/00-atoms/02-text/01-subheadings.mustache deleted file mode 100644 index 367c09a82..000000000 --- a/source/_patterns/00-atoms/02-text/01-subheadings.mustache +++ /dev/null @@ -1,6 +0,0 @@ -

Subheading Level 1

-

Subheading Level 2

-

Subheading Level 3

-

Subheading Level 4

-
Subheading Level 5
-
Subheading Level 6
\ No newline at end of file diff --git a/source/_patterns/00-atoms/02-text/02-headings-with-links.mustache b/source/_patterns/00-atoms/02-text/02-headings-with-links.mustache deleted file mode 100644 index 9540d4c23..000000000 --- a/source/_patterns/00-atoms/02-text/02-headings-with-links.mustache +++ /dev/null @@ -1,6 +0,0 @@ -

Heading 1 with link

-

Heading 2 with link

-

Heading 3 with link

-

Heading 4 with link

-
Heading 5 with link
-
Heading 6 with link
\ No newline at end of file diff --git a/source/_patterns/00-atoms/02-text/03-paragraph.mustache b/source/_patterns/00-atoms/02-text/03-paragraph.mustache deleted file mode 100644 index 01534936d..000000000 --- a/source/_patterns/00-atoms/02-text/03-paragraph.mustache +++ /dev/null @@ -1 +0,0 @@ -

{{ description }}

\ No newline at end of file diff --git a/source/_patterns/00-atoms/02-text/04-blockquote.mustache b/source/_patterns/00-atoms/02-text/04-blockquote.mustache deleted file mode 100644 index 2f11319b3..000000000 --- a/source/_patterns/00-atoms/02-text/04-blockquote.mustache +++ /dev/null @@ -1,3 +0,0 @@ -
-

A block quotation (also known as a long quotation or extract) is a quotation in a written document, that is set off from the main text as a paragraph, or block of text, and typically distinguished visually using indentation and a different typeface or smaller size quotation.

-
\ No newline at end of file diff --git a/source/_patterns/00-atoms/02-text/05-inline-elements.mustache b/source/_patterns/00-atoms/02-text/05-inline-elements.mustache deleted file mode 100644 index 0dff45f58..000000000 --- a/source/_patterns/00-atoms/02-text/05-inline-elements.mustache +++ /dev/null @@ -1,41 +0,0 @@ -
-

This is a text link

- -

Strong is used to indicate strong importance

- -

This text has added emphasis

- -

The b element is stylistically different text from normal text, without any special importance

- -

The i element is text that is set off from the normal text

- -

The u element is text with an unarticulated, though explicitly rendered, non-textual annotation

- -

This text is deleted and This text is inserted

- -

This text has a strikethrough

- -

Superscript®

- -

Subscript for things like H2O

- -

This small text is small for for fine print, etc.

- -

Abbreviation: HTML

- -

Keybord input: Cmd

- -

This text is a short inline quotation

- -

This is a citation

- -

The dfn element indicates a definition.

- -

The mark element indicates a highlight

- -

This is what inline code looks like.

- -

This is sample output from a computer program

- -

The variable element, such as x = y

-
diff --git a/source/_patterns/00-atoms/02-text/06-time.mustache b/source/_patterns/00-atoms/02-text/06-time.mustache deleted file mode 100644 index 26cecc136..000000000 --- a/source/_patterns/00-atoms/02-text/06-time.mustache +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/source/_patterns/00-atoms/02-text/07-preformatted-text.mustache b/source/_patterns/00-atoms/02-text/07-preformatted-text.mustache deleted file mode 100644 index 70de25e11..000000000 --- a/source/_patterns/00-atoms/02-text/07-preformatted-text.mustache +++ /dev/null @@ -1,9 +0,0 @@ -
  	
-P R E F O R M A T T E D T E X T
-! " # $ % & ' ( ) * + , - . /
-0 1 2 3 4 5 6 7 8 9 : ; < = > ?
-@ A B C D E F G H I J K L M N O
-P Q R S T U V W X Y Z [ \ ] ^ _
-` a b c d e f g h i j k l m n o
-p q r s t u v w x y z { | } ~ 
-
\ No newline at end of file diff --git a/source/_patterns/00-atoms/02-text/08-emphasis-colors.mustache b/source/_patterns/00-atoms/02-text/08-emphasis-colors.mustache deleted file mode 100644 index b2fae06d2..000000000 --- a/source/_patterns/00-atoms/02-text/08-emphasis-colors.mustache +++ /dev/null @@ -1,4 +0,0 @@ -

This is what error text looks like

-

This is what valid text looks like

-

This is what warning text looks like

-

This is what information text looks like.

\ No newline at end of file diff --git a/source/_patterns/00-atoms/02-text/09-hr.mustache b/source/_patterns/00-atoms/02-text/09-hr.mustache deleted file mode 100644 index 1d6667d2e..000000000 --- a/source/_patterns/00-atoms/02-text/09-hr.mustache +++ /dev/null @@ -1 +0,0 @@ -
\ No newline at end of file diff --git a/source/_patterns/00-atoms/02-text/10-caption.mustache b/source/_patterns/00-atoms/02-text/10-caption.mustache deleted file mode 100644 index 204437d16..000000000 --- a/source/_patterns/00-atoms/02-text/10-caption.mustache +++ /dev/null @@ -1 +0,0 @@ -

A caption can be applied to an image, quote, form field, etc.

\ No newline at end of file diff --git a/source/_patterns/00-atoms/03-lists/00-unordered.mustache b/source/_patterns/00-atoms/03-lists/00-unordered.mustache deleted file mode 100644 index 3f9de349f..000000000 --- a/source/_patterns/00-atoms/03-lists/00-unordered.mustache +++ /dev/null @@ -1,14 +0,0 @@ -
-
    -
  • This is a list item in an unordered list
  • -
  • An unordered list is a list in which the sequence of items is not important. Sometimes, an unordered list is a bulleted list. And this is a long list item in an unordered list that can wrap onto a new line.
  • -
  • - Lists can be nested inside of each other -
      -
    • This is a nested list item
    • -
    • This is another nested list item in an unordered list
    • -
    -
  • -
  • This is the last list item
  • -
-
\ No newline at end of file diff --git a/source/_patterns/00-atoms/03-lists/01-ordered.mustache b/source/_patterns/00-atoms/03-lists/01-ordered.mustache deleted file mode 100644 index e206c7b10..000000000 --- a/source/_patterns/00-atoms/03-lists/01-ordered.mustache +++ /dev/null @@ -1,14 +0,0 @@ -
-
    -
  1. This is a list item in an ordered list
  2. -
  3. An ordered list is a list in which the sequence of items is important. An ordered list does not necessarily contain sequence characters.
  4. -
  5. - Lists can be nested inside of each other -
      -
    1. This is a nested list item
    2. -
    3. This is another nested list item in an ordered list
    4. -
    -
  6. -
  7. This is the last list item
  8. -
-
\ No newline at end of file diff --git a/source/_patterns/00-atoms/03-lists/02-definition.mustache b/source/_patterns/00-atoms/03-lists/02-definition.mustache deleted file mode 100644 index 0488e0812..000000000 --- a/source/_patterns/00-atoms/03-lists/02-definition.mustache +++ /dev/null @@ -1,10 +0,0 @@ -
-
Definition List
-
A number of connected items or names written or printed consecutively, typically one below the other.
-
This is a term.
-
This is the definition of that term, which both live in a dl.
-
Here is another term.
-
And it gets a definition too, which is this line.
-
Here is term that shares a definition with the term below.
-
And it gets a definition too, which is this line.
-
\ No newline at end of file diff --git a/source/_patterns/00-atoms/04-images/00-logo.mustache b/source/_patterns/00-atoms/04-images/00-logo.mustache deleted file mode 100644 index 2fb6751c3..000000000 --- a/source/_patterns/00-atoms/04-images/00-logo.mustache +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/source/_patterns/00-atoms/04-images/01-landscape-4x3.mustache b/source/_patterns/00-atoms/04-images/01-landscape-4x3.mustache deleted file mode 100644 index cf874ee9d..000000000 --- a/source/_patterns/00-atoms/04-images/01-landscape-4x3.mustache +++ /dev/null @@ -1 +0,0 @@ -{{ img.landscape-4x3.alt }} \ No newline at end of file diff --git a/source/_patterns/00-atoms/04-images/02-landscape-16x9.mustache b/source/_patterns/00-atoms/04-images/02-landscape-16x9.mustache deleted file mode 100644 index 9efc5eeb3..000000000 --- a/source/_patterns/00-atoms/04-images/02-landscape-16x9.mustache +++ /dev/null @@ -1 +0,0 @@ -{{ img.landscape-16x9.alt }} \ No newline at end of file diff --git a/source/_patterns/00-atoms/04-images/03-square.mustache b/source/_patterns/00-atoms/04-images/03-square.mustache deleted file mode 100644 index 805cce5f2..000000000 --- a/source/_patterns/00-atoms/04-images/03-square.mustache +++ /dev/null @@ -1 +0,0 @@ -{{ img.square.alt }} \ No newline at end of file diff --git a/source/_patterns/00-atoms/04-images/04-avatar.mustache b/source/_patterns/00-atoms/04-images/04-avatar.mustache deleted file mode 100644 index 6b79ad0c5..000000000 --- a/source/_patterns/00-atoms/04-images/04-avatar.mustache +++ /dev/null @@ -1 +0,0 @@ -Avatar \ No newline at end of file diff --git a/source/_patterns/00-atoms/04-images/05-icons.mustache b/source/_patterns/00-atoms/04-images/05-icons.mustache deleted file mode 100644 index 4e2512348..000000000 --- a/source/_patterns/00-atoms/04-images/05-icons.mustache +++ /dev/null @@ -1,12 +0,0 @@ -
    -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • - -
  • -
\ No newline at end of file diff --git a/source/_patterns/00-atoms/04-images/06-loading-icon.mustache b/source/_patterns/00-atoms/04-images/06-loading-icon.mustache deleted file mode 100644 index 9a10165ab..000000000 --- a/source/_patterns/00-atoms/04-images/06-loading-icon.mustache +++ /dev/null @@ -1 +0,0 @@ -Loading \ No newline at end of file diff --git a/source/_patterns/00-atoms/04-images/07-favicon.mustache b/source/_patterns/00-atoms/04-images/07-favicon.mustache deleted file mode 100644 index 07e985d37..000000000 --- a/source/_patterns/00-atoms/04-images/07-favicon.mustache +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/source/_patterns/00-atoms/05-forms/00-text-fields.mustache b/source/_patterns/00-atoms/05-forms/00-text-fields.mustache deleted file mode 100644 index 90cbb7747..000000000 --- a/source/_patterns/00-atoms/05-forms/00-text-fields.mustache +++ /dev/null @@ -1,38 +0,0 @@ -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
\ No newline at end of file diff --git a/source/_patterns/00-atoms/05-forms/01-select-menu.mustache b/source/_patterns/00-atoms/05-forms/01-select-menu.mustache deleted file mode 100644 index 760c9199a..000000000 --- a/source/_patterns/00-atoms/05-forms/01-select-menu.mustache +++ /dev/null @@ -1,12 +0,0 @@ -
-
- - -
-
\ No newline at end of file diff --git a/source/_patterns/00-atoms/05-forms/02-checkbox.mustache b/source/_patterns/00-atoms/05-forms/02-checkbox.mustache deleted file mode 100644 index 017a8dc5c..000000000 --- a/source/_patterns/00-atoms/05-forms/02-checkbox.mustache +++ /dev/null @@ -1,10 +0,0 @@ -
-
- Checkbox * -
    -
  • -
  • -
  • -
-
-
\ No newline at end of file diff --git a/source/_patterns/00-atoms/05-forms/03-radio-buttons.mustache b/source/_patterns/00-atoms/05-forms/03-radio-buttons.mustache deleted file mode 100644 index 68c83eaeb..000000000 --- a/source/_patterns/00-atoms/05-forms/03-radio-buttons.mustache +++ /dev/null @@ -1,10 +0,0 @@ -
-
- Radio -
    -
  • -
  • -
  • -
-
-
\ No newline at end of file diff --git a/source/_patterns/00-atoms/05-forms/04-html5-inputs.mustache b/source/_patterns/00-atoms/05-forms/04-html5-inputs.mustache deleted file mode 100644 index 99c22cce7..000000000 --- a/source/_patterns/00-atoms/05-forms/04-html5-inputs.mustache +++ /dev/null @@ -1,10 +0,0 @@ -
-
-
-
-
-
-
-
-
-
\ No newline at end of file diff --git a/source/_patterns/00-atoms/06-buttons/00-buttons.mustache b/source/_patterns/00-atoms/06-buttons/00-buttons.mustache deleted file mode 100644 index bdbeec360..000000000 --- a/source/_patterns/00-atoms/06-buttons/00-buttons.mustache +++ /dev/null @@ -1,4 +0,0 @@ -

Button

-

Alternate Button

-

Disabled Button

-

Text Button

\ No newline at end of file diff --git a/source/_patterns/00-atoms/07-tables/00-table.mustache b/source/_patterns/00-atoms/07-tables/00-table.mustache deleted file mode 100644 index 7df555fe7..000000000 --- a/source/_patterns/00-atoms/07-tables/00-table.mustache +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table Heading 1Table Heading 2Table Heading 3Table Heading 3Table Heading 4
Table Footer 1Table Footer 2Table Footer 3Table Footer 3Table Footer 4
Table Cell 1Table Cell 2Table Cell 3Table Cell 4Table Cell 5
Table Cell 1Table Cell 2Table Cell 3Table Cell 4Table Cell 5
Table Cell 1Table Cell 2Table Cell 3Table Cell 4Table Cell 5
Table Cell 1Table Cell 2Table Cell 3Table Cell 4Table Cell 5
\ No newline at end of file diff --git a/source/_patterns/00-atoms/08-media/00-video.mustache b/source/_patterns/00-atoms/08-media/00-video.mustache deleted file mode 100644 index f28fcd7fc..000000000 --- a/source/_patterns/00-atoms/08-media/00-video.mustache +++ /dev/null @@ -1,6 +0,0 @@ - \ No newline at end of file diff --git a/source/_patterns/00-atoms/08-media/01-audio.mustache b/source/_patterns/00-atoms/08-media/01-audio.mustache deleted file mode 100644 index 91c82135e..000000000 --- a/source/_patterns/00-atoms/08-media/01-audio.mustache +++ /dev/null @@ -1,4 +0,0 @@ - \ No newline at end of file diff --git a/source/_patterns/01-molecules/00-text/00-byline-author-only.mustache b/source/_patterns/01-molecules/00-text/00-byline-author-only.mustache deleted file mode 100644 index 08366cabe..000000000 --- a/source/_patterns/01-molecules/00-text/00-byline-author-only.mustache +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/source/_patterns/01-molecules/00-text/01-byline-author-time.mustache b/source/_patterns/01-molecules/00-text/01-byline-author-time.mustache deleted file mode 100644 index 5d61bc716..000000000 --- a/source/_patterns/01-molecules/00-text/01-byline-author-time.mustache +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/source/_patterns/01-molecules/00-text/02-address.mustache b/source/_patterns/01-molecules/00-text/02-address.mustache deleted file mode 100644 index a13ea79fc..000000000 --- a/source/_patterns/01-molecules/00-text/02-address.mustache +++ /dev/null @@ -1,11 +0,0 @@ -
-
Company Name
-
-
1234 Main St.
- Anywhere, - 101010, - CA -
U.S.A
-
-
+1.888.123.4567
-
\ No newline at end of file diff --git a/source/_patterns/01-molecules/00-text/03-heading-group.mustache b/source/_patterns/01-molecules/00-text/03-heading-group.mustache deleted file mode 100644 index bf18f5ac4..000000000 --- a/source/_patterns/01-molecules/00-text/03-heading-group.mustache +++ /dev/null @@ -1,4 +0,0 @@ -
-

This is the heading group's main heading

-

This is the heading group's subheading

-
\ No newline at end of file diff --git a/source/_patterns/01-molecules/00-text/04-blockquote-with-citation.mustache b/source/_patterns/01-molecules/00-text/04-blockquote-with-citation.mustache deleted file mode 100644 index b9b6c98fc..000000000 --- a/source/_patterns/01-molecules/00-text/04-blockquote-with-citation.mustache +++ /dev/null @@ -1,4 +0,0 @@ -
-

A block quotation (also known as a long quotation or extract) is a quotation in a written document, that is set off from the main text as a paragraph, or block of text, and typically distinguished visually using indentation and a different typeface or smaller size quotation.

- Quote Source -
\ No newline at end of file diff --git a/source/_patterns/01-molecules/00-text/05-intro-text.mustache b/source/_patterns/01-molecules/00-text/05-intro-text.mustache deleted file mode 100644 index b2b1bdef8..000000000 --- a/source/_patterns/01-molecules/00-text/05-intro-text.mustache +++ /dev/null @@ -1 +0,0 @@ -

The intro text may be a lead-in to the passage of text, or it may just be used to create a visual distinction between the rest of the passage of text.

\ No newline at end of file diff --git a/source/_patterns/01-molecules/00-text/06-pullquote.mustache b/source/_patterns/01-molecules/00-text/06-pullquote.mustache deleted file mode 100644 index dba015d32..000000000 --- a/source/_patterns/01-molecules/00-text/06-pullquote.mustache +++ /dev/null @@ -1,3 +0,0 @@ -
-

A pull quote is a quotation or excerpt from an article

-
\ No newline at end of file diff --git a/source/_patterns/01-molecules/01-layout/00-one-up.mustache b/source/_patterns/01-molecules/01-layout/00-one-up.mustache deleted file mode 100644 index eb58a0e24..000000000 --- a/source/_patterns/01-molecules/01-layout/00-one-up.mustache +++ /dev/null @@ -1,7 +0,0 @@ -
- -
-
1/1
-
- -
\ No newline at end of file diff --git a/source/_patterns/01-molecules/01-layout/01-two-up.mustache b/source/_patterns/01-molecules/01-layout/01-two-up.mustache deleted file mode 100644 index ff1553aee..000000000 --- a/source/_patterns/01-molecules/01-layout/01-two-up.mustache +++ /dev/null @@ -1,7 +0,0 @@ -
- -
-
1/2
-
1/2
-
-
\ No newline at end of file diff --git a/source/_patterns/01-molecules/01-layout/02-three-up.mustache b/source/_patterns/01-molecules/01-layout/02-three-up.mustache deleted file mode 100644 index d68fb4854..000000000 --- a/source/_patterns/01-molecules/01-layout/02-three-up.mustache +++ /dev/null @@ -1,8 +0,0 @@ -
- -
-
1/3
-
1/3
-
1/3
-
-
\ No newline at end of file diff --git a/source/_patterns/01-molecules/01-layout/03-four-up.mustache b/source/_patterns/01-molecules/01-layout/03-four-up.mustache deleted file mode 100644 index f7351c023..000000000 --- a/source/_patterns/01-molecules/01-layout/03-four-up.mustache +++ /dev/null @@ -1,9 +0,0 @@ -
- -
-
1/4
-
1/4
-
1/4
-
1/4
-
-
\ No newline at end of file diff --git a/source/_patterns/01-molecules/02-blocks/00-media-block.mustache b/source/_patterns/01-molecules/02-blocks/00-media-block.mustache deleted file mode 100644 index a82a8ed50..000000000 --- a/source/_patterns/01-molecules/02-blocks/00-media-block.mustache +++ /dev/null @@ -1,11 +0,0 @@ - \ No newline at end of file diff --git a/source/_patterns/01-molecules/02-blocks/01-headline-byline.mustache b/source/_patterns/01-molecules/02-blocks/01-headline-byline.mustache deleted file mode 100644 index e6416f8a2..000000000 --- a/source/_patterns/01-molecules/02-blocks/01-headline-byline.mustache +++ /dev/null @@ -1,6 +0,0 @@ - \ No newline at end of file diff --git a/source/_patterns/01-molecules/02-blocks/02-block-hero.mustache b/source/_patterns/01-molecules/02-blocks/02-block-hero.mustache deleted file mode 100644 index c685176f8..000000000 --- a/source/_patterns/01-molecules/02-blocks/02-block-hero.mustache +++ /dev/null @@ -1,10 +0,0 @@ - \ No newline at end of file diff --git a/source/_patterns/01-molecules/02-blocks/03-block-thumb-headline.mustache b/source/_patterns/01-molecules/02-blocks/03-block-thumb-headline.mustache deleted file mode 100644 index 9e13fb90d..000000000 --- a/source/_patterns/01-molecules/02-blocks/03-block-thumb-headline.mustache +++ /dev/null @@ -1,10 +0,0 @@ - \ No newline at end of file diff --git a/source/_patterns/01-molecules/02-blocks/04-headline-only.mustache b/source/_patterns/01-molecules/02-blocks/04-headline-only.mustache deleted file mode 100644 index 5c0daded8..000000000 --- a/source/_patterns/01-molecules/02-blocks/04-headline-only.mustache +++ /dev/null @@ -1,5 +0,0 @@ - \ No newline at end of file diff --git a/source/_patterns/01-molecules/02-blocks/05-inset-block.mustache b/source/_patterns/01-molecules/02-blocks/05-inset-block.mustache deleted file mode 100644 index e850e479d..000000000 --- a/source/_patterns/01-molecules/02-blocks/05-inset-block.mustache +++ /dev/null @@ -1,10 +0,0 @@ - \ No newline at end of file diff --git a/source/_patterns/01-molecules/03-media/00-figure-with-caption.mustache b/source/_patterns/01-molecules/03-media/00-figure-with-caption.mustache deleted file mode 100644 index 98e2b4435..000000000 --- a/source/_patterns/01-molecules/03-media/00-figure-with-caption.mustache +++ /dev/null @@ -1,4 +0,0 @@ -
- {{> atoms-landscape-4x3 }} -
This is an example of an image with a caption. Photo captions, also known as cutlines, are a few lines of text used to explain or elaborate on published photographs.
-
\ No newline at end of file diff --git a/source/_patterns/01-molecules/03-media/_map.mustache b/source/_patterns/01-molecules/03-media/_map.mustache deleted file mode 100644 index 333879b6a..000000000 --- a/source/_patterns/01-molecules/03-media/_map.mustache +++ /dev/null @@ -1 +0,0 @@ - diff --git a/source/_patterns/01-molecules/04-forms/00-search.mustache b/source/_patterns/01-molecules/04-forms/00-search.mustache deleted file mode 100644 index aa276315f..000000000 --- a/source/_patterns/01-molecules/04-forms/00-search.mustache +++ /dev/null @@ -1,11 +0,0 @@ -
-
- Search - - - -
-
\ No newline at end of file diff --git a/source/_patterns/01-molecules/04-forms/01-comment-form.mustache b/source/_patterns/01-molecules/04-forms/01-comment-form.mustache deleted file mode 100644 index 43d6cb368..000000000 --- a/source/_patterns/01-molecules/04-forms/01-comment-form.mustache +++ /dev/null @@ -1,20 +0,0 @@ -
-
-
- - -
-
- - -
-
- - -
-
- - -
-
-
\ No newline at end of file diff --git a/source/_patterns/01-molecules/04-forms/02-newsletter.mustache b/source/_patterns/01-molecules/04-forms/02-newsletter.mustache deleted file mode 100644 index e23b2d5ae..000000000 --- a/source/_patterns/01-molecules/04-forms/02-newsletter.mustache +++ /dev/null @@ -1,10 +0,0 @@ - \ No newline at end of file diff --git a/source/_patterns/01-molecules/05-navigation/00-primary-nav.mustache b/source/_patterns/01-molecules/05-navigation/00-primary-nav.mustache deleted file mode 100644 index 226cfd40c..000000000 --- a/source/_patterns/01-molecules/05-navigation/00-primary-nav.mustache +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/source/_patterns/01-molecules/05-navigation/01-footer-nav.mustache b/source/_patterns/01-molecules/05-navigation/01-footer-nav.mustache deleted file mode 100644 index 182633b78..000000000 --- a/source/_patterns/01-molecules/05-navigation/01-footer-nav.mustache +++ /dev/null @@ -1,6 +0,0 @@ - \ No newline at end of file diff --git a/source/_patterns/01-molecules/05-navigation/02-breadcrumbs.mustache b/source/_patterns/01-molecules/05-navigation/02-breadcrumbs.mustache deleted file mode 100644 index 7d2eb525b..000000000 --- a/source/_patterns/01-molecules/05-navigation/02-breadcrumbs.mustache +++ /dev/null @@ -1,7 +0,0 @@ - \ No newline at end of file diff --git a/source/_patterns/01-molecules/05-navigation/03-pagination.mustache b/source/_patterns/01-molecules/05-navigation/03-pagination.mustache deleted file mode 100644 index b23a01ab1..000000000 --- a/source/_patterns/01-molecules/05-navigation/03-pagination.mustache +++ /dev/null @@ -1,9 +0,0 @@ -
    -
  1. 1
  2. -
  3. 2
  4. -
  5. 3
  6. -
  7. 4
  8. -
  9. 5
  10. -
  11. 6
  12. -
  13. 7
  14. -
\ No newline at end of file diff --git a/source/_patterns/01-molecules/05-navigation/04-tabs.mustache b/source/_patterns/01-molecules/05-navigation/04-tabs.mustache deleted file mode 100644 index 341817d40..000000000 --- a/source/_patterns/01-molecules/05-navigation/04-tabs.mustache +++ /dev/null @@ -1,7 +0,0 @@ -
- -
\ No newline at end of file diff --git a/source/_patterns/01-molecules/06-components/00-social-share.mustache b/source/_patterns/01-molecules/06-components/00-social-share.mustache deleted file mode 100644 index 71694aed1..000000000 --- a/source/_patterns/01-molecules/06-components/00-social-share.mustache +++ /dev/null @@ -1,8 +0,0 @@ - \ No newline at end of file diff --git a/source/_patterns/01-molecules/06-components/01-accordion.mustache b/source/_patterns/01-molecules/06-components/01-accordion.mustache deleted file mode 100644 index 253962dcb..000000000 --- a/source/_patterns/01-molecules/06-components/01-accordion.mustache +++ /dev/null @@ -1,19 +0,0 @@ -
- -
\ No newline at end of file diff --git a/source/_patterns/01-molecules/06-components/02-single-comment.mustache b/source/_patterns/01-molecules/06-components/02-single-comment.mustache deleted file mode 100644 index a7f56279a..000000000 --- a/source/_patterns/01-molecules/06-components/02-single-comment.mustache +++ /dev/null @@ -1,9 +0,0 @@ -
  • -
    - {{> atoms-avatar }} -

    {{name.first}} {{name.last}}

    -
    -
    -

    {{description}}

    -
    -
  • \ No newline at end of file diff --git a/source/_patterns/01-molecules/07-messaging/00-alert.mustache b/source/_patterns/01-molecules/07-messaging/00-alert.mustache deleted file mode 100644 index b5e479b31..000000000 --- a/source/_patterns/01-molecules/07-messaging/00-alert.mustache +++ /dev/null @@ -1,3 +0,0 @@ -
    - {{ excerpt.short }} -
    \ No newline at end of file diff --git a/source/_patterns/02-organisms/00-global/00-header.mustache b/source/_patterns/02-organisms/00-global/00-header.mustache deleted file mode 100644 index 24f265149..000000000 --- a/source/_patterns/02-organisms/00-global/00-header.mustache +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/source/_patterns/02-organisms/00-global/01-footer.mustache b/source/_patterns/02-organisms/00-global/01-footer.mustache deleted file mode 100644 index f82a69c5d..000000000 --- a/source/_patterns/02-organisms/00-global/01-footer.mustache +++ /dev/null @@ -1,7 +0,0 @@ - -
    -
    - -
    -
    - diff --git a/source/_patterns/02-organisms/01-article/00-article-body.mustache b/source/_patterns/02-organisms/01-article/00-article-body.mustache deleted file mode 100644 index 7e95f0494..000000000 --- a/source/_patterns/02-organisms/01-article/00-article-body.mustache +++ /dev/null @@ -1,26 +0,0 @@ -

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer fringilla sem a urna porttitor fringilla. Nulla eget justo felis.

    - -

    Aliquam erat volutpat. Mauris vulputate scelerisque feugiat. Cras a erat a diam venenatis aliquam. Sed tempus, purus ac pretium varius, risus orci sagittis purus, quis auctor libero magna nec magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Maecenas eros dolor, rutrum eu sollicitudin eu, commodo at leo. Suspendisse potenti. Sed eu nibh sit amet quam auctor feugiat vel et risus. Maecenas eu urna adipiscing neque dictum mollis suscipit in augue. Praesent pulvinar condimentum sagittis. Maecenas laoreet neque non eros consectetur fringilla. Donec vitae risus leo, vitae pharetra ipsum. Sed placerat eros eget elit iaculis semper. Aliquam congue blandit orci ac pretium.

    - -{{> atoms-landscape-16x9 }} - -

    Aliquam ultrices cursus mauris, eget volutpat justo mattis nec. Sed a orci turpis. Aliquam aliquet placerat dui, consectetur tincidunt leo tristique et. Vivamus enim nisi, blandit a venenatis quis, convallis et arcu. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris libero sapien, placerat in sodales eu, tempor quis dui. Vivamus egestas faucibus pulvinar. Maecenas eget diam nunc. Phasellus at sem eros, ac suscipit neque. Phasellus sollicitudin libero a odio dignissim scelerisque. Aliquam purus nulla, tempor eget ullamcorper quis, rhoncus non dui. -

    - -{{> atoms-blockquote }} - -

    Cras at fringilla ipsum. Donec nec libero eget est blandit dignissim a eu ante. Morbi augue nulla, luctus eu sagittis vel, malesuada ut felis. Aliquam erat volutpat. Morbi malesuada augue ac massa hendrerit fermentum. Integer scelerisque lacus a dolor convallis lobortis. Curabitur mollis ante in massa ultricies dignissim. -

    - -{{> atoms-unordered }} - -{{> atoms-ordered }} - -

    Donec posuere fringilla nunc, vitae venenatis diam scelerisque vel. Nullam vitae mauris magna. Mauris et diam quis justo volutpat tincidunt congue nec magna. Curabitur vitae orci elit. Ut mollis massa id magna vestibulum consequat. Proin rutrum lectus justo, sit amet tincidunt est. Vivamus vitae lacinia risus. -

    - -{{> molecules-pullquote }} - -

    Donec venenatis imperdiet tortor, vitae blandit odio interdum ut. Integer orci metus, lobortis id lacinia eget, rutrum vitae justo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In pretium fermentum justo nec pharetra. Maecenas eget dapibus justo. Ut quis est risus. Nullam et eros at odio commodo venenatis quis et augue. Sed sed augue at tortor porttitor hendrerit nec ut nibh. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Proin sollicitudin enim consectetur mi commodo quis cursus ante pretium. Nunc gravida cursus nisi in gravida. Suspendisse eget tortor sed urna consequat tincidunt. Etiam eget convallis lectus. Suspendisse cursus rutrum massa ac faucibus. -

    -

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis, suscipit repellendus nulla accusantium deserunt sed explicabo voluptate sapiente ratione inventore molestiae nihil earum repellat quia odit vitae perspiciatis aliquam amet?

    \ No newline at end of file diff --git a/source/_patterns/02-organisms/02-comments/00-comment-thread.mustache b/source/_patterns/02-organisms/02-comments/00-comment-thread.mustache deleted file mode 100644 index 6e150a137..000000000 --- a/source/_patterns/02-organisms/02-comments/00-comment-thread.mustache +++ /dev/null @@ -1,12 +0,0 @@ -
    -
    -

    59 Comments

    - {{> molecules-comment-form }} -
      - {{#listItems.five}} - {{> molecules-single-comment }} - {{/listItems.five}} -
    -
    - {{> molecules-pagination }} -
    \ No newline at end of file diff --git a/source/_patterns/02-organisms/02-comments/01-sticky-comment.mustache b/source/_patterns/02-organisms/02-comments/01-sticky-comment.mustache deleted file mode 100644 index ac0b28dc4..000000000 --- a/source/_patterns/02-organisms/02-comments/01-sticky-comment.mustache +++ /dev/null @@ -1,9 +0,0 @@ -
    -
    -

    Selected Comments

    -
      - {{> molecules-single-comment(description: 'We are all in the gutter, but some of us are looking at the stars.') }} - {{> molecules-single-comment(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }} -
    -
    -
    diff --git a/source/_patterns/02-organisms/03-components/00-carousel.mustache b/source/_patterns/02-organisms/03-components/00-carousel.mustache deleted file mode 100644 index 4e8641ec8..000000000 --- a/source/_patterns/02-organisms/03-components/00-carousel.mustache +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - - - - - {{> patternPaths }} - {{> viewAllPaths }} - - - - - - - - diff --git a/core/templates-bak/pattern-header-footer/README.txt b/core/templates-bak/pattern-header-footer/README.txt deleted file mode 100644 index 6c5a981ab..000000000 --- a/core/templates-bak/pattern-header-footer/README.txt +++ /dev/null @@ -1 +0,0 @@ -This is not a real pattern. It's simply the header and footer that patterns get sandwiched between when they're processed by the builder. \ No newline at end of file diff --git a/core/templates-bak/pattern-header-footer/footer-pattern.html b/core/templates-bak/pattern-header-footer/footer-pattern.html deleted file mode 100644 index 20caf0102..000000000 --- a/core/templates-bak/pattern-header-footer/footer-pattern.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - diff --git a/core/templates-bak/pattern-header-footer/footer.html b/core/templates-bak/pattern-header-footer/footer.html deleted file mode 100644 index b865c85ab..000000000 --- a/core/templates-bak/pattern-header-footer/footer.html +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/core/templates-bak/pattern-header-footer/header.html b/core/templates-bak/pattern-header-footer/header.html deleted file mode 100644 index ebe81993e..000000000 --- a/core/templates-bak/pattern-header-footer/header.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/core/templates-bak/styleguide.mustache b/core/templates-bak/styleguide.mustache deleted file mode 100644 index b9a63debe..000000000 --- a/core/templates-bak/styleguide.mustache +++ /dev/null @@ -1,48 +0,0 @@ - - - - - diff --git a/core/templates-bak/viewall.mustache b/core/templates-bak/viewall.mustache deleted file mode 100644 index e22a33833..000000000 --- a/core/templates-bak/viewall.mustache +++ /dev/null @@ -1,49 +0,0 @@ - - -
    - - -
    - {{# partials }} -
    -

    {{ patternDisplayName }}

    -
    - {{{ patternPartial }}} - -
    -
    - {{/ partials }} -
    - -
    - - - From 90d38fe1a18fe0de4a7fa385ee89d5bb0381263c Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Wed, 6 Apr 2016 00:34:58 -0500 Subject: [PATCH 113/187] navigation working along with pattern-extra toggle --- core/lib/patternlab.js | 40 +++++++++++++++------- core/lib/ui_builder.js | 78 ++++++++++++++++-------------------------- 2 files changed, 58 insertions(+), 60 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index f537eeb2e..d7c19baf5 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -81,7 +81,6 @@ var patternlab_engine = function (config) { patternlab.data = fs.readJSONSync(path.resolve(paths.source.data, 'data.json')); patternlab.listitems = fs.readJSONSync(path.resolve(paths.source.data, 'listitems.json')); patternlab.header = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/general-header.mustache'), 'utf8'); - //patternlab.footerPattern = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/pattern-header-footer/footer-pattern.html'), 'utf8'); patternlab.footer = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/general-footer.mustache'), 'utf8'); patternlab.patternSection = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/patternSection.mustache'), 'utf8'); patternlab.patternSectionSubType = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/patternSectionSubtype.mustache'), 'utf8'); @@ -186,6 +185,11 @@ var patternlab_engine = function (config) { head = patternlab.header; } + //set the pattern-specific header by compiling the general-header with data, and then adding it to the meta header + patternlab.data.patternLabHead = pattern_assembler.renderPattern(patternlab.header, { + cacheBuster: patternlab.cacheBuster + }); + //render all patterns last, so lineageR works patternlab.patterns.forEach(function (pattern) { @@ -208,28 +212,40 @@ var patternlab_engine = function (config) { var allData = JSON.parse(JSON.stringify(patternlab.data)); allData = plutils.mergeData(allData, pattern.jsonFileData); - //also add the cachebuster value. slight chance this could collide with a user that has defined cacheBuster as a value - allData.cacheBuster = patternlab.cacheBuster; - pattern.cacheBuster = patternlab.cacheBuster; - - //render the pattern-specific header - var headHtml = pattern_assembler.renderPattern(pattern.header, allData); + var headHTML = pattern_assembler.renderPattern(patternlab.userHead, allData); //render the extendedTemplate with all data pattern.patternPartialCode = pattern_assembler.renderPattern(pattern, allData); - //set the pattern-specific footer if necessary - var userFooter = patternlab.userFoot.extendedTemplate.replace('{% pattern-lab-foot %}', patternlab.footerPattern + patternlab.footer); - pattern.footer = pattern_assembler.renderPattern(userFooter, {patternData: JSON.stringify(pattern)}); + //set the pattern-specific footer by compiling the general-footer with data, and then adding it to the meta footer + var footerPartial = pattern_assembler.renderPattern(patternlab.footer, { + patternData: JSON.stringify({ + cssEnabled: false, + lineage: pattern.lineage, + lineageR: pattern.lineageR, + patternBreadcrumb: 'TODO', + patternExtension: pattern.fileExtension, + patternName: pattern.patternName, + patternPartial: pattern.patternPartial, + patternState: pattern.patternState, + extraOutput: {} + }), + cacheBuster: patternlab.cacheBuster + }); + + var footerHTML = pattern_assembler.renderPattern(patternlab.userFoot, { + patternLabFoot : footerPartial + }); //write the compiled template to the public patterns directory - fs.outputFileSync(paths.public.patterns + pattern.patternLink, headHtml + pattern.patternPartialCode + pattern.footer); + var patternPage = headHTML + pattern.patternPartialCode + footerHTML; + fs.outputFileSync(paths.public.patterns + pattern.patternLink, patternPage); //write the mustache file too fs.outputFileSync(paths.public.patterns + pattern.patternLink.replace('.html', '.mustache'), entity_encoder.encode(pattern.template)); //write the encoded version too - fs.outputFileSync(paths.public.patterns + pattern.patternLink.replace('.html', '.escaped.html'), entity_encoder.encode(pattern.patternPartialCode)); + fs.outputFileSync(paths.public.patterns + pattern.patternLink.replace('.html', '.escaped.html'), entity_encoder.encode(patternPage)); }); //export patterns if necessary diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index 48aa0b1d3..754820b6b 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -53,7 +53,16 @@ function assembleStyleguidePatterns(patternlab) { } } } else { - styleguidePatterns = patternlab.patterns; + for (i = 0; i < patternlab.patterns.length; i++) { + // skip underscore-prefixed files + if (isPatternExcluded(patternlab.patterns[i])) { + if (patternlab.config.debug) { + console.log('Omitting ' + patternlab.patterns[i].patternPartial + " from styleguide pattern exclusion."); + } + continue; + } + styleguidePatterns.push(patternlab.patterns[i]); + } } return styleguidePatterns; @@ -211,7 +220,7 @@ function buildNavigation(patternlab) { return patternTypeIndex; } -function buildViewAllPages(mainPageHead, mainPageFoot, mainPageHeadHtml, mainPageFootHtml, pattern_assembler, patternlab) { +function buildViewAllPages(mainPageHeadHtml, mainPageFootHtml, pattern_assembler, patternlab) { var paths = patternlab.config.paths; var prevSubdir = ''; var prevGroup = ''; @@ -261,7 +270,7 @@ function buildViewAllPages(mainPageHead, mainPageFoot, mainPageHeadHtml, mainPag patternSection: patternlab.patternSection, patternSectionSubType: patternlab.patternSectionSubType }); - fs.outputFileSync(paths.public.patterns + pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length) + '/index.html', mainPageHead + viewAllHtml + mainPageFoot); + fs.outputFileSync(paths.public.patterns + pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length) + '/index.html', mainPageHeadHtml + viewAllHtml + mainPageFootHtml); } //create the view all for the subsection @@ -340,14 +349,22 @@ function buildFrontEnd(patternlab) { // check if patterns are excluded, if not add them to styleguidePatterns styleguidePatterns = assembleStyleguidePatterns(patternlab); - //also add the cachebuster value. slight chance this could collide with a user that has defined cacheBuster as a value - patternlab.data.cacheBuster = patternlab.cacheBuster; + //set the pattern-specific header by compiling the general-header with data, and then adding it to the meta header + var headerPartial = pattern_assembler.renderPattern(patternlab.header, { + cacheBuster: patternlab.cacheBuster + }); + var headerHTML = pattern_assembler.renderPattern(patternlab.userHead, { + patternLabHead : headerPartial + }); - //get the main page head and foot and render them - var mainPageHead = patternlab.userHead.extendedTemplate.replace('{% pattern-lab-head %}', patternlab.header); - var mainPageHeadHtml = pattern_assembler.renderPattern(mainPageHead, patternlab.data); - var mainPageFoot = patternlab.userFoot.extendedTemplate.replace('{% pattern-lab-foot %}', patternlab.footer); - var mainPageFootHtml = pattern_assembler.renderPattern(mainPageFoot, {patternData: JSON.stringify(patternlab.data)}); + //set the pattern-specific footer by compiling the general-footer with data, and then adding it to the meta footer + var footerPartial = pattern_assembler.renderPattern(patternlab.footer, { + patternData: '{}', + cacheBuster: patternlab.cacheBuster + }); + var footerHTML = pattern_assembler.renderPattern(patternlab.userFoot, { + patternLabFoot : footerPartial + }); //build the styleguide var styleguideTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'viewall.mustache'), 'utf8'); @@ -360,47 +377,14 @@ function buildFrontEnd(patternlab) { patternSectionSubType: patternlab.patternSectionSubType }); - fs.outputFileSync(path.resolve(paths.public.styleguide, 'html/styleguide.html'), mainPageHeadHtml + styleguideHtml + mainPageFootHtml); + fs.outputFileSync(path.resolve(paths.public.styleguide, 'html/styleguide.html'), headerHTML + styleguideHtml + footerHTML); //build the viewall pages - buildViewAllPages(mainPageHead, mainPageFoot, mainPageHeadHtml, mainPageFootHtml, pattern_assembler, patternlab); + buildViewAllPages(headerHTML, footerHTML, pattern_assembler, patternlab); //build the patternlab website - // - - //loop through all patterns.to build the navigation - //todo: refactor this someday - //GTP: totally doing that right now buildNavigation(patternlab); - //the patternlab site requires a lot of partials to be rendered! - - //patternNav - //TODO: this file was moved to client side hogam rendering - //var patternNavTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/patternNav.mustache'), 'utf8'); - //var patternNavPartialHtml = pattern_assembler.renderPattern(patternNavTemplate, patternlab); - - //ishControls - //TODO: this file was moved to client side hogan rendering - //var ishControlsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/ishControls.mustache'), 'utf8'); - //patternlab.config.mqs = patternlab.mediaQueries; - //var ishControlsPartialHtml = pattern_assembler.renderPattern(ishControlsTemplate, patternlab.config); - - //TODO: write these two things to patternlab-data.js ala https://github.com/pattern-lab/patternlab-php-core/blob/c2c4bc6a8bda2b2f9c08b197669ebc94c025e7c6/src/PatternLab/Builder.php#L199 - //patternPaths - //var patternPathsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/patternPaths.mustache'), 'utf8'); - //var patternPathsPartialHtml = pattern_assembler.renderPattern(patternPathsTemplate, {'patternPaths': JSON.stringify(patternlab.patternPaths)}); - - //viewAllPaths - //var viewAllPathsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/viewAllPaths.mustache'), 'utf8'); - //var viewAllPathsPartialHtml = pattern_assembler.renderPattern(viewAllPathsTemplate, {'viewallpaths': JSON.stringify(patternlab.viewAllPaths)}); - - //render the patternlab template, with all partials - //var patternlabSiteHtml = pattern_assembler.renderPattern(patternlabSiteTemplate, { - // defaultPattern: patternlab.config.defaultPattern || 'all', - // cacheBuster: patternlab.cacheBuster - //}); - //move the index file from its asset location into public root var patternlabSiteHtml = fs.readFileSync(path.resolve(paths.source.styleguide, 'html/index.html'), 'utf8'); fs.outputFileSync(path.resolve(paths.public.root, 'index.html'), patternlabSiteHtml); @@ -418,15 +402,13 @@ function buildFrontEnd(patternlab) { output += 'var navItems = {"patternTypes": ' + JSON.stringify(patternlab.patternTypes) + '};' + eol; //patternPaths - output += 'var patternPaths = {"patternPaths":' + JSON.stringify(patternlab.patternPaths) + '};' + eol; + output += 'var patternPaths = ' + JSON.stringify(patternlab.patternPaths) + ';' + eol; //viewAllPaths output += 'var viewAllPaths = {"viewAllPaths":' + JSON.stringify(patternlab.viewAllPaths) + '};' + eol; //plugins someday output += 'var plugins = [];' + eol; - //TODO - console.log(path.resolve(paths.public.data)); fs.outputFileSync(path.resolve(paths.public.data, 'patternlab-data.js'), output); //annotations From c7f80eeebb424438d749b83ba3a7da051dadc24f Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sat, 9 Apr 2016 00:36:54 -0500 Subject: [PATCH 114/187] Working navigation, also slightly more dry. Fixes #10 --- core/lib/patternlab.js | 1 + core/lib/ui_builder.js | 75 ++++++++++++++++++++++++++---------------- 2 files changed, 47 insertions(+), 29 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index d7c19baf5..204ec394c 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -84,6 +84,7 @@ var patternlab_engine = function (config) { patternlab.footer = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/general-footer.mustache'), 'utf8'); patternlab.patternSection = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/patternSection.mustache'), 'utf8'); patternlab.patternSectionSubType = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/patternSectionSubtype.mustache'), 'utf8'); + patternlab.viewAll = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'viewall.mustache'), 'utf8'); patternlab.patterns = []; patternlab.partials = {}; patternlab.data.link = {}; diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index 754820b6b..0ebde454c 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -13,6 +13,8 @@ var path = require('path'); var fs = require('fs-extra'); var of = require('./object_factory'); +var pa = require('./pattern_assembler'); +var pattern_assembler = new pa(); var eol = require('os').EOL; // PRIVATE FUNCTIONS @@ -99,8 +101,7 @@ function buildNavigation(patternlab) { //assume the patternSubTypeItem does not exist. patternSubTypeItem = new of.oPatternSubTypeItem(patternSubTypeItemName); patternSubTypeItem.patternPath = pattern.patternLink; - //todo: isnt this just the pattern.patternPartial? - patternSubTypeItem.patternPartial = patternTypeName + "-" + pattern.patternName; //add the hyphenated name + patternSubTypeItem.patternPartial = pattern.patternPartial; //check if the patternType already exists var patternTypeIndex = patternlab.patternTypeIndex.indexOf(patternTypeName); @@ -219,8 +220,34 @@ function buildNavigation(patternlab) { } return patternTypeIndex; } +function buildFooterHTML(patternlab, patternPartial){ + //set the pattern-specific footer by compiling the general-footer with data, and then adding it to the meta footer + var footerPartial = pattern_assembler.renderPattern(patternlab.footer, { + patternData: JSON.stringify({ + patternPartial: patternPartial, + }), + cacheBuster: patternlab.cacheBuster + }); + var footerHTML = pattern_assembler.renderPattern(patternlab.userFoot, { + patternLabFoot : footerPartial + }); + return footerHTML; +} + +function buildViewAllHTML(patternlab, patterns, patternPartial){ + var viewAllHTML = pattern_assembler.renderPattern(patternlab.viewAll, + { + partials: patterns, + patternPartial: patternPartial, + cacheBuster: patternlab.cacheBuster + }, { + patternSection: patternlab.patternSection, + patternSectionSubType: patternlab.patternSectionSubType + }); + return viewAllHTML; +} -function buildViewAllPages(mainPageHeadHtml, mainPageFootHtml, pattern_assembler, patternlab) { +function buildViewAllPages(mainPageHeadHtml, patternlab) { var paths = patternlab.config.paths; var prevSubdir = ''; var prevGroup = ''; @@ -260,17 +287,13 @@ function buildViewAllPages(mainPageHeadHtml, mainPageFootHtml, pattern_assembler } } - var viewAllTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'viewall.mustache'), 'utf8'); - var viewAllHtml = pattern_assembler.renderPattern(viewAllTemplate, - { - partials: viewAllPatterns, - patternPartial: patternPartial, - cacheBuster: patternlab.cacheBuster - }, { - patternSection: patternlab.patternSection, - patternSectionSubType: patternlab.patternSectionSubType - }); - fs.outputFileSync(paths.public.patterns + pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length) + '/index.html', mainPageHeadHtml + viewAllHtml + mainPageFootHtml); + //render the footer needed for the viewall template + var footerHTML = buildFooterHTML(patternlab, patternPartial); + + //render the viewall template + var viewAllHTML = buildViewAllHTML(patternlab, viewAllPatterns, patternPartial); + + fs.outputFileSync(paths.public.patterns + pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length) + '/index.html', mainPageHeadHtml + viewAllHTML + footerHTML); } //create the view all for the subsection @@ -295,17 +318,13 @@ function buildViewAllPages(mainPageHeadHtml, mainPageFootHtml, pattern_assembler } } - var viewAllTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'viewall.mustache'), 'utf8'); - var viewAllHtml = pattern_assembler.renderPattern(viewAllTemplate, - { - partials: viewAllPatterns, - patternPartial: patternPartial, - cacheBuster: patternlab.cacheBuster}, - { - patternSection: patternlab.patternSection, - patternSectionSubType: patternlab.patternSectionSubType - }); - fs.outputFileSync(paths.public.patterns + pattern.flatPatternPath + '/index.html', mainPageHeadHtml + viewAllHtml + mainPageFootHtml); + //render the footer needed for the viewall template + var footerHTML = buildFooterHTML(patternlab, patternPartial); + + //render the viewall template + var viewAllHTML = buildViewAllHTML(patternlab, viewAllPatterns, patternPartial); + + fs.outputFileSync(paths.public.patterns + pattern.flatPatternPath + '/index.html', mainPageHeadHtml + viewAllHTML + footerHTML); } } } @@ -328,9 +347,7 @@ function sortPatterns(patternsArray) { // MAIN BUILDER FUNCTION function buildFrontEnd(patternlab) { - var pa = require('./pattern_assembler'); var mh = require('./media_hunter'); - var pattern_assembler = new pa(); var media_hunter = new mh(); var styleguidePatterns = []; var paths = patternlab.config.paths; @@ -380,7 +397,7 @@ function buildFrontEnd(patternlab) { fs.outputFileSync(path.resolve(paths.public.styleguide, 'html/styleguide.html'), headerHTML + styleguideHtml + footerHTML); //build the viewall pages - buildViewAllPages(headerHTML, footerHTML, pattern_assembler, patternlab); + buildViewAllPages(headerHTML, patternlab); //build the patternlab website buildNavigation(patternlab); @@ -405,7 +422,7 @@ function buildFrontEnd(patternlab) { output += 'var patternPaths = ' + JSON.stringify(patternlab.patternPaths) + ';' + eol; //viewAllPaths - output += 'var viewAllPaths = {"viewAllPaths":' + JSON.stringify(patternlab.viewAllPaths) + '};' + eol; + output += 'var viewAllPaths = ' + JSON.stringify(patternlab.viewAllPaths) + ';' + eol; //plugins someday output += 'var plugins = [];' + eol; From 8f15a566f338ae7f06e143085470718e3e0b968f Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sun, 10 Apr 2016 22:50:19 -0500 Subject: [PATCH 115/187] added encoded patternPartialCode to pattern --- core/lib/patternlab.js | 1 + 1 file changed, 1 insertion(+) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 204ec394c..ef7fcc109 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -217,6 +217,7 @@ var patternlab_engine = function (config) { //render the extendedTemplate with all data pattern.patternPartialCode = pattern_assembler.renderPattern(pattern, allData); + pattern.patternPartialCodeE = entity_encoder.encode(pattern.patternPartialCode); //set the pattern-specific footer by compiling the general-footer with data, and then adding it to the meta footer var footerPartial = pattern_assembler.renderPattern(patternlab.footer, { From d586191803b01457ada66ef5237c072ab0ffc25a Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sun, 10 Apr 2016 23:26:06 -0500 Subject: [PATCH 116/187] re-changing references in lineage_hunter due to a merge error on my part --- core/lib/lineage_hunter.js | 24 ++++++++++++------------ core/lib/patternlab.js | 12 ++++++++++-- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/core/lib/lineage_hunter.js b/core/lib/lineage_hunter.js index f54f70f4f..e8e5073c2 100644 --- a/core/lib/lineage_hunter.js +++ b/core/lib/lineage_hunter.js @@ -23,15 +23,15 @@ var lineage_hunter = function () { if (matches !== null) { matches.forEach(function (match) { //get the ancestorPattern - var ancestorPattern = pattern_assembler.get_pattern_by_key(pattern.findPartialKey(match), patternlab); + var ancestorPattern = pattern_assembler.findPartial(pattern.findPartial(match), patternlab); - if (ancestorPattern && pattern.lineageIndex.indexOf(ancestorPattern.key) === -1) { + if (ancestorPattern && pattern.lineageIndex.indexOf(ancestorPattern.patternPartial) === -1) { //add it since it didnt exist - pattern.lineageIndex.push(ancestorPattern.key); + pattern.lineageIndex.push(ancestorPattern.patternPartial); //create the more complex patternLineage object too var l = { - "lineagePattern": ancestorPattern.key, + "lineagePattern": ancestorPattern.patternPartial, "lineagePath": "../../patterns/" + ancestorPattern.patternLink }; if (ancestorPattern.patternState) { @@ -41,12 +41,12 @@ var lineage_hunter = function () { pattern.lineage.push(l); //also, add the lineageR entry if it doesn't exist - if (ancestorPattern.lineageRIndex.indexOf(pattern.key) === -1) { - ancestorPattern.lineageRIndex.push(pattern.key); + if (ancestorPattern.lineageRIndex.indexOf(pattern.patternPartial) === -1) { + ancestorPattern.lineageRIndex.push(pattern.patternPartial); //create the more complex patternLineage object in reverse var lr = { - "lineagePattern": pattern.key, + "lineagePattern": pattern.patternPartial, "lineagePath": "../../patterns/" + pattern.patternLink }; if (pattern.patternState) { @@ -64,14 +64,14 @@ var lineage_hunter = function () { // if the request came from the past, apply target pattern state to current pattern lineage if (direction === 'fromPast') { for (var i = 0; i < pattern.lineageIndex.length; i++) { - if (pattern.lineageIndex[i] === targetPattern.key) { + if (pattern.lineageIndex[i] === targetPattern.patternPartial) { pattern.lineage[i].lineageState = targetPattern.patternState; } } } else { //the request came from the future, apply target pattern state to current pattern reverse lineage for (var i = 0; i < pattern.lineageRIndex.length; i++) { - if (pattern.lineageRIndex[i] === targetPattern.key) { + if (pattern.lineageRIndex[i] === targetPattern.patternPartial) { pattern.lineageR[i].lineageState = targetPattern.patternState; } } @@ -93,7 +93,7 @@ var lineage_hunter = function () { //find all lineage - patterns being consumed by this one for (var h = 0; h < pattern.lineageIndex.length; h++) { - var lineagePattern = pattern_assembler.get_pattern_by_key(pattern.lineageIndex[h], patternlab); + var lineagePattern = pattern_assembler.findPartial(pattern.lineageIndex[h], patternlab); setPatternState('fromFuture', lineagePattern, pattern); } } @@ -103,7 +103,7 @@ var lineage_hunter = function () { //find all reverse lineage - that is, patterns consuming this one for (var j = 0; j < pattern.lineageRIndex.length; j++) { - var lineageRPattern = pattern_assembler.get_pattern_by_key(pattern.lineageRIndex[j], patternlab); + var lineageRPattern = pattern_assembler.findPartial(pattern.lineageRIndex[j], patternlab); //only set patternState if pattern.patternState "is less than" the lineageRPattern.patternstate //this makes patternlab apply the lowest common ancestor denominator @@ -111,7 +111,7 @@ var lineage_hunter = function () { < patternlab.config.patternStateCascade.indexOf(lineageRPattern.patternState)) { if (patternlab.config.debug) { - console.log('Found a lower common denominator pattern state: ' + pattern.patternState + ' on ' + pattern.key + '. Setting reverse lineage pattern ' + lineageRPattern.key + ' from ' + lineageRPattern.patternState); + console.log('Found a lower common denominator pattern state: ' + pattern.patternState + ' on ' + pattern.patternPartial + '. Setting reverse lineage pattern ' + lineageRPattern.patternPartial + ' from ' + lineageRPattern.patternState); } lineageRPattern.patternState = pattern.patternState; diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 9f14ac574..7e0f6e5f0 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -78,8 +78,16 @@ var patternlab_engine = function (config) { } function buildPatterns(deletePatternDir) { - patternlab.data = fs.readJSONSync(path.resolve(paths.source.data, 'data.json')); - patternlab.listitems = fs.readJSONSync(path.resolve(paths.source.data, 'listitems.json')); + try{ + patternlab.data = fs.readJSONSync(path.resolve(paths.source.data, 'data.json')); + } catch(ex){ + patternlab.data = {}; + } + try{ + patternlab.listitems = fs.readJSONSync(path.resolve(paths.source.data, 'listitems.json')); + } catch(ex){ + patternlab.listitems = {}; + } patternlab.header = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/general-header.mustache'), 'utf8'); patternlab.footer = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/general-footer.mustache'), 'utf8'); patternlab.patternSection = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/patternSection.mustache'), 'utf8'); From 6e1748ef9874610afb30b7328eab56c18e121c16 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Mon, 11 Apr 2016 00:33:15 -0500 Subject: [PATCH 117/187] all unit tests passing --- test/engine_underscore_tests.js | 5 +++-- test/lineage_hunter_tests.js | 10 ++++----- test/object_factory_tests.js | 22 +++++++++--------- test/pattern_assembler_tests.js | 40 ++++++++++++++++++++++----------- 4 files changed, 46 insertions(+), 31 deletions(-) diff --git a/test/engine_underscore_tests.js b/test/engine_underscore_tests.js index a4f5eff80..c7db11d66 100644 --- a/test/engine_underscore_tests.js +++ b/test/engine_underscore_tests.js @@ -4,6 +4,7 @@ var path = require('path'); var pa = require('../core/lib/pattern_assembler'); var testPatternsPath = path.resolve(__dirname, 'files', '_underscore-test-patterns'); + var eol = require('os').EOL; try { require('underscore'); @@ -54,7 +55,7 @@ var helloWorldPattern = assembler.process_pattern_iterative(patternPath, patternlab); assembler.process_pattern_recursive(patternPath, patternlab); - test.equals(helloWorldPattern.render(), 'Hello world!\n'); + test.equals(helloWorldPattern.render(), 'Hello world!' + eol); test.done(); }, 'underscore partials can render JSON values': function (test) { @@ -77,7 +78,7 @@ assembler.process_pattern_recursive(pattern1Path, patternlab); // test - test.equals(helloWorldWithData.render(), 'Hello world!\nYeah, we got the subtitle from the JSON.\n'); + test.equals(helloWorldWithData.render(), 'Hello world!' + eol + 'Yeah, we got the subtitle from the JSON.' + eol); test.done(); } }; diff --git a/test/lineage_hunter_tests.js b/test/lineage_hunter_tests.js index 9f85a239e..64431c91e 100644 --- a/test/lineage_hunter_tests.js +++ b/test/lineage_hunter_tests.js @@ -50,7 +50,7 @@ exports['lineage hunter '] = { ); extend(currentPattern, { "template": "\r\n
    \r\n\t{{> atoms-logo }}\r\n\tSearch\r\n\tMenu\r\n\t{{> molecules-primary-nav }}\r\n\t{{> molecules-search }}\r\n
    \r\n\r\n", - "patternPartial": "\r\n
    \r\n\"Logo\tSearch\r\n\tMenu\r\n\r\n
    \r\n
    \r\n\t Search\r\n\t \r\n\t \r\n\t \r\n
    \r\n
    \r\n\r\n" + "patternPartialCode": "\r\n
    \r\n\"Logo\tSearch\r\n\tMenu\r\n\r\n
    \r\n
    \r\n\t Search\r\n\t \r\n\t \r\n\t \r\n
    \r\n
    \r\n\r\n" }); var patternlab = { @@ -131,7 +131,7 @@ exports['lineage hunter '] = { var currentPattern = createFakeEmptyErrorPattern(); extend(currentPattern, { "template": "{{> atoms-error(message: 'That\\'s no moon...') }}", - "patternPartial": "{{> atoms-error(message: 'That\\'s no moon...') }}" + "patternPartialCode": "{{> atoms-error(message: 'That\\'s no moon...') }}" }); var patternlab = { @@ -143,7 +143,7 @@ exports['lineage hunter '] = { null, { "template": "

    {{message}}

    ", - "patternPartial": "

    {{message}}

    " + "patternPartialCode": "

    {{message}}

    " } ) ] @@ -163,7 +163,7 @@ exports['lineage hunter '] = { var currentPattern = createFakeEmptyErrorPattern(); extend(currentPattern, { "template": "{{>atoms-error(message: 'That\\'s no moon...')}}", - "patternPartial": "{{>atoms-error(message: 'That\\'s no moon...')}}" + "patternPartialCode": "{{>atoms-error(message: 'That\\'s no moon...')}}" }); var patternlab = { @@ -368,7 +368,7 @@ exports['lineage hunter '] = { var currentPattern = createFakeEmptyErrorPattern(); extend(currentPattern, { "template": "{{>atoms-error(message: 'That\\'s no moon...')}}", - "patternPartial": "{{>atoms-error(message: 'That\\'s no moon...')}}" + "patternPartialCode": "{{>atoms-error(message: 'That\\'s no moon...')}}" }); var patternlab = { patterns: [ diff --git a/test/object_factory_tests.js b/test/object_factory_tests.js index 5654e31ca..8f29e1c12 100644 --- a/test/object_factory_tests.js +++ b/test/object_factory_tests.js @@ -60,33 +60,33 @@ } }; - exports['oNavItem initialization'] = { - 'test oNavItem initializes correctly' : function(test){ - var ni = new of.oNavItem('test'); + exports['oPatternSubType initialization'] = { + 'test oPatternSubType initializes correctly' : function(test){ + var ni = new of.oPatternSubType('test'); test.equals(ni.patternSubtypeLC, 'test'); test.equals(ni.patternSubtypeUC, 'Test'); test.equals(ni.patternSubtypeItems.length, 0); test.equals(ni.patternSubtypeItemsIndex.length, 0); test.done(); }, - 'test oNavItem correctly capitalizes sectionNameUC' : function(test){ - var ni = new of.oNavItem('global-concepts'); + 'test oPatternSubType correctly capitalizes sectionNameUC' : function(test){ + var ni = new of.oPatternSubType('global-concepts'); test.equals(ni.patternSubtypeLC, 'global-concepts'); test.equals(ni.patternSubtypeUC, 'Global Concepts'); test.done(); } }; - exports['oSubNavItem initialization'] = { - 'test oSubNavItem initializes correctly' : function(test){ - var sni = new of.oNavSubItem('test'); + exports['oPatternSubTypeItem initialization'] = { + 'test oPatternSubTypeItem initializes correctly' : function(test){ + var sni = new of.oPatternSubTypeItem('test'); test.equals(sni.patternName, 'Test'); test.equals(sni.patternPath, ''); - test.equals(sni.patternPartial, ''); + test.equals(sni.patternPartialCode, ''); test.done(); }, - 'test oSubNavItem capitalizes patternName' : function(test){ - var sni = new of.oNavSubItem('nav button'); + 'test oPatternSubTypeItem capitalizes patternName' : function(test){ + var sni = new of.oPatternSubTypeItem('nav button'); test.equals(sni.patternName, 'Nav Button'); test.done(); } diff --git a/test/pattern_assembler_tests.js b/test/pattern_assembler_tests.js index 7879d7bf6..50cbb9e7d 100644 --- a/test/pattern_assembler_tests.js +++ b/test/pattern_assembler_tests.js @@ -279,10 +279,14 @@ patternlab.config = fs.readJSONSync('./patternlab-config.json'); patternlab.config.paths.source.patterns = patterns_dir; - patternlab.data = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'data.json')); - patternlab.listitems = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'listitems.json')); - patternlab.header = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'templates/pattern-header-footer/header.html'), 'utf8'); - patternlab.footer = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'templates/pattern-header-footer/footer.html'), 'utf8'); + //patternlab.data = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'data.json')); + patternlab.data = {}; + //patternlab.listitems = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'listitems.json')); + patternlab.listitems = {}; + //patternlab.header = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'templates/pattern-header-footer/header.html'), 'utf8'); + patternlab.header = ''; + //patternlab.footer = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'templates/pattern-header-footer/footer.html'), 'utf8'); + patternlab.footer = ''; patternlab.patterns = []; patternlab.data.link = {}; patternlab.partials = {}; @@ -610,10 +614,14 @@ patternlab.config = fs.readJSONSync('./patternlab-config.json'); patternlab.config.paths.source.patterns = patterns_dir; - patternlab.data = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'data.json')); - patternlab.listitems = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'listitems.json')); - patternlab.header = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'templates/pattern-header-footer/header.html'), 'utf8'); - patternlab.footer = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'templates/pattern-header-footer/footer.html'), 'utf8'); + //patternlab.data = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'data.json')); + patternlab.data = {}; + //patternlab.listitems = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'listitems.json')); + patternlab.listitems = {}; + //patternlab.header = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'templates/pattern-header-footer/header.html'), 'utf8'); + patternlab.header = ''; + //patternlab.footer = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'templates/pattern-header-footer/footer.html'), 'utf8'); + patternlab.footer = ''; patternlab.patterns = []; patternlab.data.link = {}; patternlab.partials = {}; @@ -661,7 +669,7 @@ patternlab.config.patternStates["pages-homepage-emergency"] = "inprogress"; var pattern = { - key: "pages-homepage-emergency" + patternPartial: "pages-homepage-emergency" }; //act @@ -702,10 +710,14 @@ //THIS IS BAD patternlab.config = fs.readJSONSync('./patternlab-config.json'); patternlab.config.paths.source.patterns = patterns_dir; - patternlab.data = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'data.json')); - patternlab.listitems = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'listitems.json')); - patternlab.header = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'templates/pattern-header-footer/header.html'), 'utf8'); - patternlab.footer = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'templates/pattern-header-footer/footer.html'), 'utf8'); + patternlab.data = {}; + patternlab.listitems = {}; + patternlab.header = {}; + patternlab.footer = {}; + //patternlab.data = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'data.json')); + //patternlab.listitems = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'listitems.json')); + //patternlab.header = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'templates/pattern-header-footer/header.html'), 'utf8'); + //patternlab.footer = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'templates/pattern-header-footer/footer.html'), 'utf8'); patternlab.patterns = []; patternlab.data.link = {}; patternlab.partials = {}; @@ -813,6 +825,7 @@ patternlab.patterns = []; patternlab.partials = {}; patternlab.data = {link: {}}; + patternlab.config = { debug: false }; var pattern = new object_factory.oPattern('test/files/_patterns/00-test/01-bar.mustache', '00-test', '01-bar.mustache'); pattern.extendedTemplate = 'barExtended'; @@ -834,6 +847,7 @@ patternlab.patterns = []; patternlab.partials = {}; patternlab.data = {link: {}}; + patternlab.config = { debug: false }; var pattern = new object_factory.oPattern('test/files/_patterns/00-test/01-bar.mustache', '00-test', '01-bar.mustache'); pattern.extendedTemplate = undefined; From 14b1940e500a00324b3c9c67452604fbbc67f83f Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Mon, 11 Apr 2016 00:40:22 -0500 Subject: [PATCH 118/187] code cleanup --- core/lib/pattern_assembler.js | 89 +++++++++++++++++------------------ core/lib/patternlab.js | 8 ++-- core/lib/ui_builder.js | 9 ++-- 3 files changed, 53 insertions(+), 53 deletions(-) diff --git a/core/lib/pattern_assembler.js b/core/lib/pattern_assembler.js index 6aa734b25..946fe022b 100644 --- a/core/lib/pattern_assembler.js +++ b/core/lib/pattern_assembler.js @@ -197,52 +197,6 @@ var pattern_assembler = function () { return currentPattern; } - - - function expandPartials(foundPatternPartials, list_item_hunter, patternlab, currentPattern) { - var smh = require('./style_modifier_hunter'), - ph = require('./parameter_hunter'); - - var style_modifier_hunter = new smh(), - parameter_hunter = new ph(); - - if (patternlab.config.debug) { - console.log('found partials for ' + currentPattern.patternPartial); - } - - // determine if the template contains any pattern parameters. if so they - // must be immediately consumed - parameter_hunter.find_parameters(currentPattern, patternlab); - - //do something with the regular old partials - for (var i = 0; i < foundPatternPartials.length; i++) { - var partial = currentPattern.findPartial(foundPatternPartials[i]); - var partialPath; - - //identify which pattern this partial corresponds to - for (var j = 0; j < patternlab.patterns.length; j++) { - if (patternlab.patterns[j].patternPartial === partial || - patternlab.patterns[j].abspath.indexOf(partial) > -1) - { - partialPath = patternlab.patterns[j].abspath; - } - } - - //recurse through nested partials to fill out this extended template. - processPatternRecursive(partialPath, patternlab); - - //complete assembly of extended template - var partialPattern = getPartial(partial, patternlab); - - //if partial has style modifier data, replace the styleModifier value - if (currentPattern.stylePartials && currentPattern.stylePartials.length > 0) { - style_modifier_hunter.consume_style_modifier(partialPattern, foundPatternPartials[i], patternlab); - } - - currentPattern.extendedTemplate = currentPattern.extendedTemplate.replace(foundPatternPartials[i], partialPattern.extendedTemplate); - } - } - function processPatternRecursive(file, patternlab) { var lh = require('./lineage_hunter'), pph = require('./pseudopattern_hunter'), @@ -293,6 +247,49 @@ var pattern_assembler = function () { pseudopattern_hunter.find_pseudopatterns(currentPattern, patternlab); } + function expandPartials(foundPatternPartials, list_item_hunter, patternlab, currentPattern) { + var smh = require('./style_modifier_hunter'), + ph = require('./parameter_hunter'); + + var style_modifier_hunter = new smh(), + parameter_hunter = new ph(); + + if (patternlab.config.debug) { + console.log('found partials for ' + currentPattern.patternPartial); + } + + // determine if the template contains any pattern parameters. if so they + // must be immediately consumed + parameter_hunter.find_parameters(currentPattern, patternlab); + + //do something with the regular old partials + for (var i = 0; i < foundPatternPartials.length; i++) { + var partial = currentPattern.findPartial(foundPatternPartials[i]); + var partialPath; + + //identify which pattern this partial corresponds to + for (var j = 0; j < patternlab.patterns.length; j++) { + if (patternlab.patterns[j].patternPartial === partial || + patternlab.patterns[j].abspath.indexOf(partial) > -1) + { + partialPath = patternlab.patterns[j].abspath; + } + } + + //recurse through nested partials to fill out this extended template. + processPatternRecursive(partialPath, patternlab); + + //complete assembly of extended template + var partialPattern = getPartial(partial, patternlab); + + //if partial has style modifier data, replace the styleModifier value + if (currentPattern.stylePartials && currentPattern.stylePartials.length > 0) { + style_modifier_hunter.consume_style_modifier(partialPattern, foundPatternPartials[i], patternlab); + } + + currentPattern.extendedTemplate = currentPattern.extendedTemplate.replace(foundPatternPartials[i], partialPattern.extendedTemplate); + } + } function parseDataLinksHelper(patternlab, obj, key) { var linkRE, dataObjAsString, linkMatches, expandedLink; diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 7e0f6e5f0..84a1043c0 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -78,14 +78,14 @@ var patternlab_engine = function (config) { } function buildPatterns(deletePatternDir) { - try{ + try { patternlab.data = fs.readJSONSync(path.resolve(paths.source.data, 'data.json')); - } catch(ex){ + } catch (ex) { patternlab.data = {}; } - try{ + try { patternlab.listitems = fs.readJSONSync(path.resolve(paths.source.data, 'listitems.json')); - } catch(ex){ + } catch (ex) { patternlab.listitems = {}; } patternlab.header = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/general-header.mustache'), 'utf8'); diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index 0ebde454c..5e7d021d8 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -74,6 +74,7 @@ function buildNavigation(patternlab) { for (var i = 0; i < patternlab.patterns.length; i++) { var pattern = patternlab.patterns[i]; + //todo: check if this is already available var patternTypeName = pattern.name.replace(/\\/g, '-').split('-')[1]; @@ -220,7 +221,8 @@ function buildNavigation(patternlab) { } return patternTypeIndex; } -function buildFooterHTML(patternlab, patternPartial){ + +function buildFooterHTML(patternlab, patternPartial) { //set the pattern-specific footer by compiling the general-footer with data, and then adding it to the meta footer var footerPartial = pattern_assembler.renderPattern(patternlab.footer, { patternData: JSON.stringify({ @@ -234,7 +236,7 @@ function buildFooterHTML(patternlab, patternPartial){ return footerHTML; } -function buildViewAllHTML(patternlab, patterns, patternPartial){ +function buildViewAllHTML(patternlab, patterns, patternPartial) { var viewAllHTML = pattern_assembler.renderPattern(patternlab.viewAll, { partials: patterns, @@ -408,13 +410,14 @@ function buildFrontEnd(patternlab) { //write out the data var output = ''; + //config output += 'var config = ' + JSON.stringify(patternlab.config) + ';\n'; //ishControls output += 'var ishControls = {"ishControlsHide":' + JSON.stringify(patternlab.config.ishControlsHide) + '};' + eol; - //todo add media queries to this + //todo add media queries to this //navItems output += 'var navItems = {"patternTypes": ' + JSON.stringify(patternlab.patternTypes) + '};' + eol; From ecf2aeb0b4845efca048f7c55fea84372fb0df58 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Mon, 11 Apr 2016 00:49:15 -0500 Subject: [PATCH 119/187] put some basic error handling around template and file loading --- core/lib/patternlab.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 84a1043c0..719940c63 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -81,18 +81,26 @@ var patternlab_engine = function (config) { try { patternlab.data = fs.readJSONSync(path.resolve(paths.source.data, 'data.json')); } catch (ex) { + console.log('missing ' + paths.source.data + '/data.json Pattern Lab may not work without this file.'); patternlab.data = {}; } try { patternlab.listitems = fs.readJSONSync(path.resolve(paths.source.data, 'listitems.json')); } catch (ex) { + console.log('missing ' + paths.source.data + '/listitems.json Pattern Lab may not work without this file.'); patternlab.listitems = {}; } - patternlab.header = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/general-header.mustache'), 'utf8'); - patternlab.footer = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/general-footer.mustache'), 'utf8'); - patternlab.patternSection = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/patternSection.mustache'), 'utf8'); - patternlab.patternSectionSubType = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/patternSectionSubtype.mustache'), 'utf8'); - patternlab.viewAll = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'viewall.mustache'), 'utf8'); + try { + + patternlab.header = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/general-header.mustache'), 'utf8'); + patternlab.footer = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/general-footer.mustache'), 'utf8'); + patternlab.patternSection = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/patternSection.mustache'), 'utf8'); + patternlab.patternSectionSubType = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/patternSectionSubtype.mustache'), 'utf8'); + patternlab.viewAll = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'viewall.mustache'), 'utf8'); + } catch (ex) { + console.log(ex); + console.log('missing an essential file from ' + paths.source.patternlabFiles + '. Pattern Lab may not work without this file.'); + } patternlab.patterns = []; patternlab.partials = {}; patternlab.data.link = {}; From 549f270b18e0ec5046e13e81a3636a3e2bbd504f Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Mon, 11 Apr 2016 00:55:15 -0500 Subject: [PATCH 120/187] remove patternlab from the travis run eslint and nodeunit should cover core --- Gruntfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gruntfile.js b/Gruntfile.js index d6bebb182..03349ab4a 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -158,7 +158,7 @@ module.exports = function (grunt) { grunt.registerTask('default', ['patternlab', 'copy:main', 'copy:styleguide']); //travis CI task - grunt.registerTask('travis', ['nodeunit', 'eslint', 'patternlab']); + grunt.registerTask('travis', ['nodeunit', 'eslint']); grunt.registerTask('serve', ['patternlab', 'copy:main', 'copy:styleguide', 'browserSync', 'watch:all']); From faa09d62ca488bd671939323d431fb38a6abc687 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Mon, 11 Apr 2016 11:11:56 -0500 Subject: [PATCH 121/187] delete included engines --- core/lib/pattern_engines/engine_handlebars.js | 82 --------- core/lib/pattern_engines/engine_mustache.js | 114 ------------- core/lib/pattern_engines/engine_twig.js | 82 --------- core/lib/pattern_engines/engine_underscore.js | 109 ------------ core/lib/pattern_engines/util_mustache.js | 158 ------------------ 5 files changed, 545 deletions(-) delete mode 100644 core/lib/pattern_engines/engine_handlebars.js delete mode 100644 core/lib/pattern_engines/engine_mustache.js delete mode 100644 core/lib/pattern_engines/engine_twig.js delete mode 100644 core/lib/pattern_engines/engine_underscore.js delete mode 100644 core/lib/pattern_engines/util_mustache.js diff --git a/core/lib/pattern_engines/engine_handlebars.js b/core/lib/pattern_engines/engine_handlebars.js deleted file mode 100644 index e22573e78..000000000 --- a/core/lib/pattern_engines/engine_handlebars.js +++ /dev/null @@ -1,82 +0,0 @@ -/* - * handlebars pattern engine for patternlab-node - v0.15.1 - 2015 - * - * Geoffrey Pursell, Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - -/* - * ENGINE SUPPORT LEVEL: - * - * Full. Partial calls and lineage hunting are supported. Handlebars does not - * support the mustache-specific syntax extensions, style modifiers and pattern - * parameters, because their use cases are addressed by the core Handlebars - * feature set. - * - */ - -"use strict"; - -var Handlebars = require('handlebars'); - -var engine_handlebars = { - engine: Handlebars, - engineName: 'handlebars', - engineFileExtension: '.hbs', - - // partial expansion is only necessary for Mustache templates that have - // style modifiers or pattern parameters (I think) - expandPartials: false, - - // regexes, stored here so they're only compiled once - findPartialsRE: /{{#?>\s*([\w-\/.]+)(?:.|\s+)*?}}/g, - findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, - - // render it - renderPattern: function renderPattern(pattern, data, partials) { - if (partials) { - Handlebars.registerPartial(partials); - } - var compiled = Handlebars.compile(pattern.extendedTemplate); - return compiled(data); - }, - - registerPartial: function (oPattern) { - Handlebars.registerPartial(oPattern.key, oPattern.template); - }, - - // find and return any {{> template-name }} within pattern - findPartials: function findPartials(pattern) { - var matches = pattern.template.match(this.findPartialsRE); - return matches; - }, - findPartialsWithStyleModifiers: function () { - // TODO: make the call to this from oPattern objects conditional on their - // being implemented here. - return []; - }, - - // returns any patterns that match {{> value(foo:"bar") }} or {{> - // value:mod(foo:"bar") }} within the pattern - findPartialsWithPatternParameters: function () { - // TODO: make the call to this from oPattern objects conditional on their - // being implemented here. - return []; - }, - findListItems: function (pattern) { - var matches = pattern.template.match(this.findListItemsRE); - return matches; - }, - - // given a pattern, and a partial string, tease out the "pattern key" and - // return it. - findPartialKey: function (partialString) { - var partialKey = partialString.replace(this.findPartialsRE, '$1'); - return partialKey; - } -}; - -module.exports = engine_handlebars; diff --git a/core/lib/pattern_engines/engine_mustache.js b/core/lib/pattern_engines/engine_mustache.js deleted file mode 100644 index e6659a5cb..000000000 --- a/core/lib/pattern_engines/engine_mustache.js +++ /dev/null @@ -1,114 +0,0 @@ -/* - * mustache pattern engine for patternlab-node - v0.10.1 - 2015 - * - * Geoffrey Pursell, Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - -/* - * ENGINE SUPPORT LEVEL: - * - * Full + extensions. Partial calls and lineage hunting are supported. Style - * modifiers and pattern parameters are used to extend the core feature set of - * Mustache templates. - * - */ - -"use strict"; - -var Mustache = require('mustache'); -var utilMustache = require('./util_mustache'); - -var engine_mustache = { - engine: Mustache, - engineName: 'mustache', - engineFileExtension: '.mustache', - - // partial expansion is only necessary for Mustache templates that have - // style modifiers or pattern parameters (I think) - expandPartials: true, - - // regexes, stored here so they're only compiled once - findPartialsRE: utilMustache.partialsRE, - findPartialsWithStyleModifiersRE: utilMustache.partialsWithStyleModifiersRE, - findPartialsWithPatternParametersRE: utilMustache.partialsWithPatternParametersRE, - findListItemsRE: utilMustache.listItemsRE, - findPartialKeyRE: utilMustache.partialKeyRE, - - // render it - renderPattern: function renderPattern(pattern, data, partials) { - if (partials) { - return Mustache.render(pattern.extendedTemplate, data, partials); - } - return Mustache.render(pattern.extendedTemplate, data); - }, - - /** - * Find regex matches within both pattern strings and pattern objects. - * - * @param {string|object} pattern Either a string or a pattern object. - * @param {object} regex A JavaScript RegExp object. - * @returns {array|null} An array if a match is found, null if not. - */ - patternMatcher: function patternMatcher(pattern, regex) { - var matches; - - if (typeof pattern === 'string') { - matches = pattern.match(regex); - } else if (typeof pattern === 'object' && typeof pattern.template === 'string') { - matches = pattern.template.match(regex); - } - - return matches; - }, - - // find and return any {{> template-name }} within pattern - findPartials: function findPartials(pattern) { - var matches = this.patternMatcher(pattern, this.findPartialsRE); - return matches; - }, - findPartialsWithStyleModifiers: function (pattern) { - var matches = this.patternMatcher(pattern, this.findPartialsWithStyleModifiersRE); - return matches; - }, - - // returns any patterns that match {{> value(foo:"bar") }} or {{> - // value:mod(foo:"bar") }} within the pattern - findPartialsWithPatternParameters: function (pattern) { - var matches = this.patternMatcher(pattern, this.findPartialsWithPatternParametersRE); - return matches; - }, - findListItems: function (pattern) { - var matches = this.patternMatcher(pattern, this.findListItemsRE); - return matches; - }, - - // given a pattern, and a partial string, tease out the "pattern key" and - // return it. - findPartialKey_new: function (partialString) { - var partialKey = partialString.replace(this.findPartialKeyRE, '$1'); - return partialKey; - }, - - // GTP: the old implementation works better. We might not need - // this.findPartialKeyRE anymore if it works in all cases! - findPartialKey: function (partialString) { - //strip out the template cruft - var foundPatternKey = partialString.replace("{{> ", "").replace(" }}", "").replace("{{>", "").replace("}}", ""); - - // remove any potential pattern parameters. this and the above are rather brutish but I didn't want to do a regex at the time - if (foundPatternKey.indexOf('(') > 0) { - foundPatternKey = foundPatternKey.substring(0, foundPatternKey.indexOf('(')); - } - - //remove any potential stylemodifiers. - foundPatternKey = foundPatternKey.split(':')[0]; - - return foundPatternKey; - } -}; - -module.exports = engine_mustache; diff --git a/core/lib/pattern_engines/engine_twig.js b/core/lib/pattern_engines/engine_twig.js deleted file mode 100644 index 7a7da0379..000000000 --- a/core/lib/pattern_engines/engine_twig.js +++ /dev/null @@ -1,82 +0,0 @@ -/* - * handlebars pattern engine for patternlab-node - v0.15.1 - 2015 - * - * Geoffrey Pursell, Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - -/* - * ENGINE SUPPORT LEVEL: - * - * Full. Partial calls and lineage hunting are supported. Twig does not support - * the mustache-specific syntax extensions, style modifiers and pattern - * parameters, because their use cases are addressed by the core Twig feature - * set. - * - */ - -"use strict"; - -var Twig = require('twig'); -var twig = Twig.twig; - -var engine_twig = { - engine: Twig, - engineName: 'twig', - engineFileExtension: '.twig', - - //Important! Needed for Twig compilation. Can't resolve paths otherwise. - expandPartials: true, - - // regexes, stored here so they're only compiled once - findPartialsRE: /{%\s*(?:extends|include|embed)\s+('[^']+'|"[^"]+").*?%}/g, - findPartialKeyRE: /"((?:\\.|[^"\\])*)"/, - findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, // TODO - - // render it - renderPattern: function renderPattern(pattern, data) { - var result = twig({ - data: pattern.extendedTemplate - }).render(data); - - return result; - }, - - // find and return any {% include 'template-name' %} within pattern - findPartials: function findPartials(pattern) { - var matches = pattern.template.match(this.findPartialsRE); - return matches; - }, - findPartialsWithStyleModifiers: function () { - // TODO: make the call to this from oPattern objects conditional on their - // being implemented here. - return []; - }, - - // returns any patterns that match {{> value(foo:"bar") }} or {{> - // value:mod(foo:"bar") }} within the pattern - findPartialsWithPatternParameters: function () { - // TODO: make the call to this from oPattern objects conditional on their - // being implemented here. - return []; - }, - findListItems: function (pattern) { - var matches = pattern.template.match(this.findListItemsRE); - return matches; - }, - - // given a pattern, and a partial string, tease out the "pattern key" and - // return it. - findPartialKey: function (partialString) { - //var partialKey = partialString.replace(this.findPartialsRE, '$1'); - var partialKey = partialString.match(this.findPartialKeyRE)[0]; - partialKey = partialKey.replace(/"/g, ''); - - return partialKey; - } -}; - -module.exports = engine_twig; diff --git a/core/lib/pattern_engines/engine_underscore.js b/core/lib/pattern_engines/engine_underscore.js deleted file mode 100644 index 6e9f7e7cc..000000000 --- a/core/lib/pattern_engines/engine_underscore.js +++ /dev/null @@ -1,109 +0,0 @@ -/* - * underscore pattern engine for patternlab-node - v0.15.1 - 2015 - * - * Geoffrey Pursell, Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - - -/* - * ENGINE SUPPORT LEVEL: - * - * Basic. We can't call partials from inside underscore templates yet, but we - * can render templates with backing JSON. - * - */ - -(function () { - "use strict"; - - var _ = require('underscore'); - - // extend underscore with partial-ing methods - // HANDLESCORE! UNDERBARS! - _.mixin({ - renderPartial: function (partial, data) { - var data = data || {}; - var compiled = _.template(partial); - return compiled(data); - }, - assignContext: function (viewModel, data) { - return viewModel(data); - } - }); - - var engine_underscore = { - engine: _, - engineName: 'underscore', - engineFileExtension: '.html', - - // partial expansion is only necessary for Mustache templates that have - // style modifiers or pattern parameters (I think) - expandPartials: false, - - // regexes, stored here so they're only compiled once - findPartialsRE: /<%= _.renderPartial\((.*?)\).*?%>/g, // TODO, - findPartialsWithStyleModifiersRE: /<%= _.renderPartial\((.*?)\).*?%>/g, // TODO - findPartialsWithPatternParametersRE: /<%= _.renderPartial\((.*?)\).*?%>/g, // TODO - findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, - - // render it - renderPattern: function renderPattern(pattern, data, partials) { - var compiled = _.template(pattern.extendedTemplate); - var renderedHTML; - - // This try-catch is necessary because references to undefined variables - // in underscore templates are eval()ed directly as javascript, and as - // such will throw very real exceptions that will shatter the whole build - // process if we don't handle them. - try { - renderedHTML = compiled(_.extend(data || {}, { - _allData: data, - _partials: partials - })); - } catch (e) { - var errorMessage = "WARNING: the underscore template " + pattern.fileName + " threw an exception; it probably just tried to reference an undefined variable. Is this pattern maybe missing a .json file?"; - console.log(errorMessage, e); - renderedHTML = "

    Error in underscore template

    " + errorMessage; - } - - return renderedHTML; - }, - - // registerPartial: function (oPattern) { - // debugger; - // _.registerPartial(oPattern.key, oPattern.template); - // }, - - // find and return any {{> template-name }} within pattern - findPartials: function findPartials(pattern) { - var matches = pattern.template.match(this.findPartialsRE); - return matches; - }, - findPartialsWithStyleModifiers: function () { - return []; - }, - - // returns any patterns that match {{> value(foo:"bar") }} or {{> - // value:mod(foo:"bar") }} within the pattern - findPartialsWithPatternParameters: function () { - return []; - }, - findListItems: function (pattern) { - var matches = pattern.template.match(this.findListItemsRE); - return matches; - }, - - // given a pattern, and a partial string, tease out the "pattern key" and - // return it. - findPartialKey: function (partialString) { - var partialKey = partialString.replace(this.findPartialsRE, '$1'); - return partialKey; - } - }; - - module.exports = engine_underscore; -})(); diff --git a/core/lib/pattern_engines/util_mustache.js b/core/lib/pattern_engines/util_mustache.js deleted file mode 100644 index bbc9468d6..000000000 --- a/core/lib/pattern_engines/util_mustache.js +++ /dev/null @@ -1,158 +0,0 @@ -/* - * mustache utilities for patternlab-node - v0.10.1 - 2015 - * - * Geoffrey Pursell, Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - -'use strict'; - -// the term "alphanumeric" includes underscores. - -// look for an opening mustache include tag, followed by >=0 whitespaces -var partialsStr = '{{>\\s*'; - -// begin 1st exterior group, a mandatory group -// look for >0 of an interior group comprising -// >0 digits, followed by a hyphen, followed by >0 alphanumerics -partialsStr += '((\\d+-[\\w-]+\\/)+'; - -// then an interior group comprising -// >0 digits, followed by a hyphen, followed by >0 alphanumerics, -// followed by an optional group of a period followed by >0 alphanumerics -partialsStr += '(\\d+-[\\w-]+(\\.\\w+)?)'; - -// if the previous two interior groups are not found, look for any number of -// alphanumerics or hyphens -partialsStr += '|[\\w\\-]+)'; - -// end 1st exterior group -// begin 2nd exterior group, an optional group -// look for a colon, followed by >0 alphanumerics or hyphens, -// followed by >=0 interior groups -// comprising a pipe, followed by >0 alphanumerics or hyphens -partialsStr += '(\\:[\\w\\-]+(\\|[\\w\\-]+)*)?'; - -// end 2nd exterior group -// begin 3rd exterior group, an optional group -// look for an opening parenthesis, followed by >=0 whitespaces, followed by -// >0 alphanumerics, followed by >=0 whitespaces, followed by a colon, -// followed by >=0 whitespaces -partialsStr += '(\\(\\s*\\w+\\s*\\:\\s*'; - -// followed by an interior group -// comprising a single quote, followed by an interior group comprising -// >=0 characters that are not single quotes or backslashes -// or >=0 character pairs comprising a backlash, followed by any character. -// look for a single quote to terminate this pattern -partialsStr += '(\'([^\'\\\\]|\\\\.)*\''; - -// if the pattern wrapped in single quotes is not found, look for one wrapped -// in double quotes -// look for a double quote, followed by an interior group comprising -// >=0 characters that are not double quotes or backslashes -// or >=0 character pairs comprising a backlash, followed by any character. -// look for a double quote to terminate this pattern -partialsStr += '|"([^"\\\\]|\\\\.)*")'; - -// look for a closing parenthesis -partialsStr += '\\))?'; - -// end 3rd exterior group -// look for >=0 whitespaces, followed by closing mustache tag -partialsStr += '\\s*}}'; -var partialsRE = new RegExp(partialsStr, 'g'); - -// look for an opening mustache include tag, followed by >=0 whitespaces -var partialsWithStyleModifiersStr = '{{>\\s*'; - -// one or more characters comprising any combination of alphanumerics, -// hyphens, periods, slashses, and tildes -partialsWithStyleModifiersStr += '([\\w\\-\\.\\/~]+)'; - -// the previous group cannot be followed by an opening parenthesis -partialsWithStyleModifiersStr += '(?!\\()'; - -// a colon followed by one or more characters comprising any combination -// of alphanumerics, hyphens, and pipes -partialsWithStyleModifiersStr += '(\\:[\\w\\-\\|]+)'; - -// an optional group of characters starting with >=0 whitespaces, followed by -// an opening parenthesis, followed by any number of characters that are not -// closing parentheses, followed by a closing parenthesis -partialsWithStyleModifiersStr += '(\\s*\\([^\\)]*\\))?'; - -// look for >=0 whitespaces, followed by closing mustache tag -partialsWithStyleModifiersStr += '\\s*}}'; -var partialsWithStyleModifiersRE = new RegExp(partialsWithStyleModifiersStr, 'g'); - -// look for an opening mustache include tag, followed by >=0 whitespaces -var partialsWithPatternParametersStr = '{{>\\s*'; - -// one or more characters comprising any combination of alphanumerics, -// hyphens, periods, slashses, and tildes -partialsWithPatternParametersStr += '([\\w\\-\\.\\/~]+)'; - -// an optional group comprising a colon followed by one or more characters -// comprising any combination of alphanumerics, -// hyphens, and pipes -partialsWithPatternParametersStr += '(\\:[\\w\\-\\|]+)?'; - -// a group of characters starting with >=0 whitespaces, followed by an opening -// parenthesis, followed by any number of characters that are not closing -// parentheses, followed by a closing parenthesis -partialsWithPatternParametersStr += '(\\s*\\([^\\)]*\\))'; - -// look for >=0 whitespaces, followed by closing mustache tag -partialsWithPatternParametersStr += '\\s*}}'; -var partialsWithPatternParametersRE = new RegExp(partialsWithPatternParametersStr, 'g'); - -// look for an opening mustache loop tag, followed by >=0 whitespaces -var listItemsStr = '{{#\\s*'; - -// look for the string 'listItems.' or 'listitems.' -listItemsStr += '(list(I|i)tems\\.)'; - -// look for a number 1 - 20, spelled out -listItemsStr += '(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)'; - -// look for >=0 whitespaces, followed by closing mustache tag -listItemsStr += '\\s*}}'; -var listItemsRE = new RegExp(listItemsStr, 'g'); - -// look for an opening mustache loop tag, followed by >=0 whitespaces -var partialKeyStr = '{{>\\s*'; - -// one or more characters comprising any combination of alphanumerics, -// hyphens, periods, slashses, and tildes -partialKeyStr += '([\\w\\-\\.\\/~]+)'; - -// an optional group of characters starting with a colon, followed by >0 -// alphanumerics, hyphens, or pipes -partialKeyStr += '(\\:[\\w\\-|]+)?'; - -// an optional group of characters starting with a colon, followed by >0 -// alphanumerics or hyphens -partialKeyStr += '(\\:[\\w\\-]+)?'; - -// an optional group of characters starting with >=0 whitespaces, followed by -// an opening parenthesis, followed by any number of characters that are not -// closing parentheses, followed by a closing parenthesis -partialKeyStr += '(\\s*\\([^\\)]*\\))?'; - -// look for >=0 whitespaces, followed by closing mustache tag -partialKeyStr += '\\s*}}'; -var partialKeyRE = new RegExp(partialKeyStr, 'g'); - -var utilMustache = { - partialsRE: partialsRE, - partialsWithStyleModifiersRE: partialsWithStyleModifiersRE, - partialsWithPatternParametersRE: partialsWithPatternParametersRE, - listItemsRE: listItemsRE, - partialKeyRE: partialKeyRE -}; - -module.exports = utilMustache; From 416132c64a4c6bdffc4aafa91e6250f176abb020 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Mon, 11 Apr 2016 16:16:53 -0500 Subject: [PATCH 122/187] engine loader now finds the mustache engine module from the edition! --- core/lib/pattern_engines/pattern_engines.js | 43 +++++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/core/lib/pattern_engines/pattern_engines.js b/core/lib/pattern_engines/pattern_engines.js index 3d9bfbbf2..8a24b0b99 100644 --- a/core/lib/pattern_engines/pattern_engines.js +++ b/core/lib/pattern_engines/pattern_engines.js @@ -12,40 +12,49 @@ var path = require('path'); var diveSync = require('diveSync'); -var engineMatcher = /^engine_(.*)\.js/; -var enginesDirectory = __dirname; - +var engineMatcher = /^patternengine-node-(.*)$/; +var enginesDirectory = path.join(process.cwd(), 'node_modules'); var PatternEngines; // the main export object var engineNameForExtension; // generated mapping of extension to engine name // free "private" functions, for internal setup only +// given a path: return the engine name is the path points to a valid engine +// module directory, or false if it doesn't +function isEngineModule(filePath) { + var baseName = path.basename(filePath); + var engineMatch = baseName.match(engineMatcher); + + if (engineMatch) { return engineMatch[1]; } + return false; +} + +function getEngineModulePath(engineName) { + return path.resolve(enginesDirectory, "patternengine-node-" + engineName); +} + +// go find the names of all found engines function findSupportedPatternEngineNames() { var foundPatternEngineNames = []; - // find + // iterate over module directory and build a list of available pattern engine + // names diveSync(enginesDirectory, { recursive: false, - filter: function (filePath, dir) { - var baseName = path.basename(filePath), - engineMatch = baseName.match(engineMatcher); - - if (dir || engineMatch !== null) { return true; } - return false; - } + directories: true }, function (err, filePath) { if (err) { throw err; } - var baseName = path.basename(filePath), - engineMatch = baseName.match(engineMatcher), - foundEngineName = engineMatch[1]; - - foundPatternEngineNames.push(foundEngineName); + var foundEngineName = isEngineModule(filePath); + if (foundEngineName) { + foundPatternEngineNames.push(foundEngineName); + } }); return foundPatternEngineNames; } + // try to load all supported engines function loadAllEngines(enginesObject) { console.log('\nLoading engines...'); @@ -54,7 +63,7 @@ function loadAllEngines(enginesObject) { var notLoaded = false; try { - enginesObject[engineName] = require('./engine_' + engineName); + enginesObject[engineName] = require(getEngineModulePath(engineName)); } catch (err) { // Handle errors loading each pattern engine. This will usually be // because the engine's renderer hasn't been installed by the end user From e0c4940c06187835424e8bef0f944a2c2d5d4704 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Mon, 11 Apr 2016 16:22:15 -0500 Subject: [PATCH 123/187] relocate pattern_engines.js --- core/lib/object_factory.js | 2 +- core/lib/pattern_assembler.js | 2 +- core/lib/{pattern_engines => }/pattern_engines.js | 2 +- test/pattern_engines_tests.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename core/lib/{pattern_engines => }/pattern_engines.js (99%) diff --git a/core/lib/object_factory.js b/core/lib/object_factory.js index 73ca4f59c..558290afb 100644 --- a/core/lib/object_factory.js +++ b/core/lib/object_factory.js @@ -10,7 +10,7 @@ "use strict"; -var patternEngines = require('./pattern_engines/pattern_engines'); +var patternEngines = require('./pattern_engines'); var path = require('path'); var extend = require('util')._extend; diff --git a/core/lib/pattern_assembler.js b/core/lib/pattern_assembler.js index f20589025..99f5919c7 100644 --- a/core/lib/pattern_assembler.js +++ b/core/lib/pattern_assembler.js @@ -16,7 +16,7 @@ var pattern_assembler = function () { fs = require('fs-extra'), of = require('./object_factory'), plutils = require('./utilities'), - patternEngines = require('./pattern_engines/pattern_engines'); + patternEngines = require('./pattern_engines'); // HELPER FUNCTIONS diff --git a/core/lib/pattern_engines/pattern_engines.js b/core/lib/pattern_engines.js similarity index 99% rename from core/lib/pattern_engines/pattern_engines.js rename to core/lib/pattern_engines.js index 8a24b0b99..c0042f102 100644 --- a/core/lib/pattern_engines/pattern_engines.js +++ b/core/lib/pattern_engines.js @@ -114,7 +114,7 @@ PatternEngines = Object.create({ getEngineNameForPattern: function (pattern) { // avoid circular dependency by putting this in here. TODO: is this slow? - var of = require('../object_factory'); + var of = require('./object_factory'); if (pattern instanceof of.oPattern && typeof pattern.fileExtension === 'string' && pattern.fileExtension) { return engineNameForExtension[pattern.fileExtension]; diff --git a/test/pattern_engines_tests.js b/test/pattern_engines_tests.js index 60229b357..f8613bc45 100644 --- a/test/pattern_engines_tests.js +++ b/test/pattern_engines_tests.js @@ -1,7 +1,7 @@ (function () { 'use strict'; - var patternEngines = require('../core/lib/pattern_engines/pattern_engines'); + var patternEngines = require('../core/lib/pattern_engines'); var of = require('../core/lib/object_factory'); // the mustache test pattern, stolen from object_factory unit tests From 12810de2550b380c3a2e7078b825e2d05249396b Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 12 Apr 2016 16:42:38 -0500 Subject: [PATCH 124/187] nicer error reporting for missing styleguidekit assets --- core/lib/patternlab.js | 12 ++++++------ core/lib/ui_builder.js | 9 ++++++++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 719940c63..15eee55ad 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -91,15 +91,15 @@ var patternlab_engine = function (config) { patternlab.listitems = {}; } try { - - patternlab.header = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/general-header.mustache'), 'utf8'); - patternlab.footer = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/general-footer.mustache'), 'utf8'); - patternlab.patternSection = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/patternSection.mustache'), 'utf8'); - patternlab.patternSectionSubType = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/patternSectionSubtype.mustache'), 'utf8'); + patternlab.header = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials', 'general-header.mustache'), 'utf8'); + patternlab.footer = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials', 'general-footer.mustache'), 'utf8'); + patternlab.patternSection = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials', 'patternSection.mustache'), 'utf8'); + patternlab.patternSectionSubType = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials', 'patternSectionSubtype.mustache'), 'utf8'); patternlab.viewAll = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'viewall.mustache'), 'utf8'); } catch (ex) { console.log(ex); - console.log('missing an essential file from ' + paths.source.patternlabFiles + '. Pattern Lab may not work without this file.'); + console.log('\nERROR: missing an essential file from ' + paths.source.patternlabFiles + '. Pattern Lab won\'t work without this file.\n'); + process.exit(1); } patternlab.patterns = []; patternlab.partials = {}; diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index 5e7d021d8..0cbe2c44b 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -405,7 +405,14 @@ function buildFrontEnd(patternlab) { buildNavigation(patternlab); //move the index file from its asset location into public root - var patternlabSiteHtml = fs.readFileSync(path.resolve(paths.source.styleguide, 'html/index.html'), 'utf8'); + var patternlabSiteHtml; + try { + patternlabSiteHtml = fs.readFileSync(path.resolve(paths.source.styleguide, 'html', 'index.html'), 'utf8'); + } catch (error) { + console.log(error); + console.log("\nERROR: Could not load one or more styleguidekit assets from", paths.source.styleguide, '\n'); + process.exit(1); + } fs.outputFileSync(path.resolve(paths.public.root, 'index.html'), patternlabSiteHtml); //write out the data From f472717b4d4a7b643d9164f3286a66287ed56467 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Tue, 12 Apr 2016 21:02:43 -0500 Subject: [PATCH 125/187] attempt to align lineage keys with styleguide addresses https://github.com/pattern-lab/edition-node-gulp/issues/4 --- core/lib/patternlab.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 719940c63..8c8b10e8e 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -239,8 +239,10 @@ var patternlab_engine = function (config) { var footerPartial = pattern_assembler.renderPattern(patternlab.footer, { patternData: JSON.stringify({ cssEnabled: false, - lineage: pattern.lineage, - lineageR: pattern.lineageR, + patternLineageExists: pattern.lineage.length > 0, + patternLineages: pattern.lineage, + patternLineageRExists: pattern.lineageR.length > 0, + patternLineagesR: pattern.lineageR, patternBreadcrumb: 'TODO', patternExtension: pattern.fileExtension, patternName: pattern.patternName, From faebb176c8288ee50b59e0a5e9b59523d5b50144 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Wed, 13 Apr 2016 00:14:26 -0500 Subject: [PATCH 126/187] basic support for lineage https://github.com/pattern-lab/edition-node-gulp/issues/4 --- core/lib/patternlab.js | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index def936e88..2c9e73e12 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -212,18 +212,14 @@ var patternlab_engine = function (config) { pattern.header = head; - //json stringify lineage and lineageR - var lineageArray = []; - for (var i = 0; i < pattern.lineage.length; i++) { - lineageArray.push(JSON.stringify(pattern.lineage[i])); - } - pattern.lineage = lineageArray; + //todo move this into lineage_hunter + pattern.patternLineages = pattern.lineage; + pattern.patternLineageExists = pattern.lineage.length > 0; - var lineageRArray = []; - for (var i = 0; i < pattern.lineageR.length; i++) { - lineageRArray.push(JSON.stringify(pattern.lineageR[i])); - } - pattern.lineageR = lineageRArray; + pattern.patternLineagesR = pattern.lineageR; + pattern.patternLineageRExists = pattern.lineageR.length > 0; + + pattern.patternLineageEExists = pattern.patternLineageExists || pattern.patternLineageRExists; //render the pattern, but first consolidate any data we may have var allData = JSON.parse(JSON.stringify(patternlab.data)); @@ -239,10 +235,11 @@ var patternlab_engine = function (config) { var footerPartial = pattern_assembler.renderPattern(patternlab.footer, { patternData: JSON.stringify({ cssEnabled: false, - patternLineageExists: pattern.lineage.length > 0, - patternLineages: pattern.lineage, - patternLineageRExists: pattern.lineageR.length > 0, - patternLineagesR: pattern.lineageR, + patternLineageExists: pattern.patternLineageExists, + patternLineages: pattern.patternLineages, + patternLineageRExists: pattern.patternLineageRExists, + patternLineagesR: pattern.patternLineagesR, + patternLineageEExists: pattern.patternLineageExists || pattern.patternLineageRExists, patternBreadcrumb: 'TODO', patternExtension: pattern.fileExtension, patternName: pattern.patternName, From c5e85c54784a1eb619a67ce58f651dfcd0fb512c Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Mon, 18 Apr 2016 23:39:49 -0500 Subject: [PATCH 127/187] added support for the old-style annotations as part of https://github.com/pattern-lab/edition-node-gulp/issues/12 (#319) --- core/lib/annotation_exporter.js | 42 +++++++++++++++++++++++++++++++++ core/lib/ui_builder.js | 6 +++-- 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 core/lib/annotation_exporter.js diff --git a/core/lib/annotation_exporter.js b/core/lib/annotation_exporter.js new file mode 100644 index 000000000..3dcd3963e --- /dev/null +++ b/core/lib/annotation_exporter.js @@ -0,0 +1,42 @@ +"use strict"; + +var annotations_exporter = function (pl) { + var path = require('path'), + fs = require('fs-extra'), + JSON5 = require('json5'), + paths = pl.config.paths; + + // HELPER FUNCTIONS + function parseAnnotationsJS() { + //attempt to read the file + try { + var oldAnnotations = fs.readFileSync(path.resolve(paths.source.annotations, 'annotations.js'), 'utf8'); + } catch (ex) { + console.log(ex, 'This may be expected.'); + } + + //parse as JSON by removing the old wrapping js syntax. comments and the trailing semi-colon + oldAnnotations = oldAnnotations.replace('var comments = ', ''); + try { + var oldAnnotationsJSON = JSON5.parse(oldAnnotations.trim().slice(0, -1)); + } catch (ex) { + console.log('There was an error parsing JSON for ' + paths.source.annotations + 'annotations.js'); + console.log(ex); + } + return oldAnnotationsJSON; + } + + function gatherAnnotations() { + //todo: merge markdown too https://github.com/pattern-lab/patternlab-php-core/blob/c2c4bc6a8bda2b2f9c08b197669ebc94c025e7c6/src/PatternLab/Annotations.php + return parseAnnotationsJS(); + } + + return { + gather: function () { + return gatherAnnotations(); + } + }; + +}; + +module.exports = annotations_exporter; diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index 0cbe2c44b..a15e0a656 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -351,6 +351,8 @@ function sortPatterns(patternsArray) { function buildFrontEnd(patternlab) { var mh = require('./media_hunter'); var media_hunter = new mh(); + var ae = require('./annotation_exporter'); + var annotation_exporter = new ae(patternlab); var styleguidePatterns = []; var paths = patternlab.config.paths; @@ -439,8 +441,8 @@ function buildFrontEnd(patternlab) { fs.outputFileSync(path.resolve(paths.public.data, 'patternlab-data.js'), output); //annotations - //todo: build this from _source/annotations/ https://github.com/pattern-lab/patternlab-php-core/blob/c2c4bc6a8bda2b2f9c08b197669ebc94c025e7c6/src/PatternLab/Annotations.php - var annotations = 'var comments = [];' + eol; + var annotationsJSON = annotation_exporter.gather(); + var annotations = 'var comments = ' + JSON.stringify(annotationsJSON); fs.outputFileSync(path.resolve(paths.public.annotations, 'annotations.js'), annotations); } From 133d07c6ef9e7e14824ab3451da61f34dd7ce040 Mon Sep 17 00:00:00 2001 From: Dawid Karabin Date: Mon, 25 Apr 2016 20:31:11 +0200 Subject: [PATCH 128/187] View all pages for atoms, molecules, organisms have still some (#323) {{mustache_variables}} in html. This commit fix this issue. --- core/lib/patternlab.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index b0192c8dd..1edbc622d 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -1,10 +1,10 @@ -/* - * patternlab-node - v1.3.0 - 2016 - * +/* + * patternlab-node - v1.3.0 - 2016 + * * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ @@ -355,7 +355,7 @@ var patternlab_engine = function (config) { var viewAllTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/viewall.mustache'), 'utf8'); var viewAllHtml = pattern_assembler.renderPattern(viewAllTemplate, {partials: viewAllPatterns, patternPartial: patternPartial, cacheBuster: patternlab.cacheBuster }); - fs.outputFileSync(paths.public.patterns + pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length) + '/index.html', mainPageHead + viewAllHtml + mainPageFoot); + fs.outputFileSync(paths.public.patterns + pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length) + '/index.html', mainPageHeadHtml + viewAllHtml + mainPageFootHtml); } // create the view all for the subsection From 241266ab7c2665a1707ab9861932365aa21c6e74 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sun, 8 May 2016 06:50:21 -0500 Subject: [PATCH 129/187] work in progress markdown pattern descriptions. --- core/lib/pattern_assembler.js | 15 ++++++++++++++ core/lib/patternlab.js | 38 ++++++++++++++++++++--------------- package.json | 7 ++++--- 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/core/lib/pattern_assembler.js b/core/lib/pattern_assembler.js index 532971244..dddfff146 100644 --- a/core/lib/pattern_assembler.js +++ b/core/lib/pattern_assembler.js @@ -15,6 +15,7 @@ var pattern_assembler = function () { var path = require('path'), fs = require('fs-extra'), of = require('./object_factory'), + md = require('markdown-it')(), plutils = require('./utilities'), patternEngines = require('./pattern_engines/pattern_engines'); @@ -182,6 +183,20 @@ var pattern_assembler = function () { // do nothing } + //look for a markdown file for this template + try { + var markdownFileName = path.resolve(patternlab.config.paths.source.patterns, currentPattern.subdir, currentPattern.fileName + ".md"); + var markdownFileContents = fs.readFileSync(markdownFileName, 'utf8'); + currentPattern.patternDescExists = true; + currentPattern.patternDesc = md.render(markdownFileContents); + if (patternlab.config.debug) { + console.log('found pattern-specific markdown-documentation.md for ' + currentPattern.patternPartial); + } + } + catch (e) { + // do nothing + } + //add the raw template to memory currentPattern.template = fs.readFileSync(file, 'utf8'); diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 31a6d669a..59ac78a9b 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -216,10 +216,8 @@ var patternlab_engine = function (config) { //todo move this into lineage_hunter pattern.patternLineages = pattern.lineage; pattern.patternLineageExists = pattern.lineage.length > 0; - pattern.patternLineagesR = pattern.lineageR; pattern.patternLineageRExists = pattern.lineageR.length > 0; - pattern.patternLineageEExists = pattern.patternLineageExists || pattern.patternLineageRExists; //render the pattern, but first consolidate any data we may have @@ -237,22 +235,30 @@ var patternlab_engine = function (config) { pattern.patternPartialCode = pattern_assembler.renderPattern(pattern, allData); pattern.patternPartialCodeE = entity_encoder.encode(pattern.patternPartialCode); + // stringify this data for individual pattern rendering and use on the styleguide + // see if patternData really needs these other duped values + pattern.patternData = JSON.stringify({ + isPattern: true, + cssEnabled: false, + patternLineageExists: pattern.patternLineageExists, + patternLineages: pattern.patternLineages, + lineage: pattern.patternLineages, + patternLineageRExists: pattern.patternLineageRExists, + patternLineagesR: pattern.patternLineagesR, + lineageR: pattern.patternLineagesR, + patternLineageEExists: pattern.patternLineageExists || pattern.patternLineageRExists, + patternDesc: pattern.patternDescExists ? pattern.patternDesc : '', + patternBreadcrumb: 'TODO', + patternExtension: pattern.fileExtension, + patternName: pattern.patternName, + patternPartial: pattern.patternPartial, + patternState: pattern.patternState, + extraOutput: {} + }); + //set the pattern-specific footer by compiling the general-footer with data, and then adding it to the meta footer var footerPartial = pattern_assembler.renderPattern(patternlab.footer, { - patternData: JSON.stringify({ - cssEnabled: false, - patternLineageExists: pattern.patternLineageExists, - patternLineages: pattern.patternLineages, - patternLineageRExists: pattern.patternLineageRExists, - patternLineagesR: pattern.patternLineagesR, - patternLineageEExists: pattern.patternLineageExists || pattern.patternLineageRExists, - patternBreadcrumb: 'TODO', - patternExtension: pattern.fileExtension, - patternName: pattern.patternName, - patternPartial: pattern.patternPartial, - patternState: pattern.patternState, - extraOutput: {} - }), + patternData: pattern.patternData, cacheBuster: patternlab.cacheBuster }); diff --git a/package.json b/package.json index aa076f0e5..636da7e54 100644 --- a/package.json +++ b/package.json @@ -7,13 +7,14 @@ "diveSync": "^0.3.0", "fs-extra": "^0.26.2", "glob": "^7.0.0", + "handlebars": "^4.0.5", "html-entities": "^1.2.0", "json5": "^0.5.0", + "markdown-it": "^6.0.1", "matchdep": "^1.0.0", "mustache": "^2.2.0", - "handlebars": "^4.0.5", - "underscore": "^1.8.3", - "twig": "^0.8.8" + "twig": "^0.8.8", + "underscore": "^1.8.3" }, "devDependencies": { "bs-html-injector": "^3.0.0", From fb3b240435ede595453c517f8baf6173f3d43a2f Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Wed, 18 May 2016 09:31:11 -0500 Subject: [PATCH 130/187] fix path to new location of styleguide assets index.html --- core/lib/ui_builder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index a15e0a656..df04b793f 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -409,7 +409,7 @@ function buildFrontEnd(patternlab) { //move the index file from its asset location into public root var patternlabSiteHtml; try { - patternlabSiteHtml = fs.readFileSync(path.resolve(paths.source.styleguide, 'html', 'index.html'), 'utf8'); + patternlabSiteHtml = fs.readFileSync(path.resolve(paths.source.styleguide, 'index.html'), 'utf8'); } catch (error) { console.log(error); console.log("\nERROR: Could not load one or more styleguidekit assets from", paths.source.styleguide, '\n'); From ea1b6803dc21b221740ad5caca35a4a51a8906e7 Mon Sep 17 00:00:00 2001 From: Geoff Pursell Date: Mon, 23 May 2016 14:39:20 -0500 Subject: [PATCH 131/187] Dev 2.0 core oPattern refactor (#331) * merge the oPattern refactor branch * Delete extra copy of expandPartials. How'd that get in there? * Factor out the iterative and recursive diveSync loops, and export them (sort of) so they can be re-used from the unit tests * Pattern.key -> Pattern.patternPartial * abspath -> relPath * Fix unit tests to use the new stuff, also factor out some diveSync loops that are now provided by the main patternlab module * "fixed" a couple unit tests by hopefully normalizing eol characters * addressed new lines in a couple more false positives. in one case, just removed them due to the length of the output being compared * removed a set of duplicate tests --- core/lib/lineage_hunter.js | 2 +- core/lib/list_item_hunter.js | 10 +- core/lib/object_factory.js | 70 ++++--- core/lib/parameter_hunter.js | 2 +- core/lib/pattern_assembler.js | 34 +-- core/lib/pattern_engines/engine_handlebars.js | 8 +- core/lib/pattern_engines/engine_twig.js | 4 +- core/lib/pattern_engines/engine_underscore.js | 4 +- core/lib/pattern_engines/pattern_engines.js | 2 +- core/lib/patternlab.js | 113 +++++----- core/lib/pseudopattern_hunter.js | 9 +- test/engine_handlebars_tests.js | 67 ++---- test/engine_twig_tests.js | 43 +--- test/lineage_hunter_tests.js | 55 +++-- test/list_item_hunter_tests.js | 18 +- test/object_factory_tests.js | 40 +++- test/pattern_assembler_tests.js | 193 +++++------------- test/pattern_engines_tests.js | 10 +- test/pseudopattern_hunter_tests.js | 96 +++++---- 19 files changed, 353 insertions(+), 427 deletions(-) diff --git a/core/lib/lineage_hunter.js b/core/lib/lineage_hunter.js index f4bbff2fc..306adf7c5 100644 --- a/core/lib/lineage_hunter.js +++ b/core/lib/lineage_hunter.js @@ -112,7 +112,7 @@ var lineage_hunter = function () { < patternlab.config.patternStateCascade.indexOf(lineageRPattern.patternState))) { if (patternlab.config.debug) { - console.log('Found a lower common denominator pattern state: ' + pattern.patternState + ' on ' + pattern.key + '. Setting reverse lineage pattern ' + lineageRPattern.patternPartial + ' from ' + (lineageRPattern.patternState === '' ? '<>' : lineageRPattern.patternState)); + console.log('Found a lower common denominator pattern state: ' + pattern.patternState + ' on ' + pattern.patternPartial + '. Setting reverse lineage pattern ' + lineageRPattern.patternPartial + ' from ' + (lineageRPattern.patternState === '' ? '<>' : lineageRPattern.patternState)); } lineageRPattern.patternState = pattern.patternState; diff --git a/core/lib/list_item_hunter.js b/core/lib/list_item_hunter.js index 3037a5b0c..bbf69549b 100644 --- a/core/lib/list_item_hunter.js +++ b/core/lib/list_item_hunter.js @@ -17,7 +17,7 @@ var list_item_hunter = function () { pa = require('./pattern_assembler'), smh = require('./style_modifier_hunter'), plutils = require('./utilities'), - of = require('./object_factory'); + Pattern = require('./object_factory').Pattern; var pattern_assembler = new pa(), style_modifier_hunter = new smh(), @@ -54,7 +54,7 @@ var list_item_hunter = function () { try { listData = JSON5.parse(JSON5.stringify(patternlab.listitems)); } catch (err) { - console.log('There was an error parsing JSON for ' + pattern.abspath); + console.log('There was an error parsing JSON for ' + pattern.relPath); console.log(err); } listData = plutils.mergeData(listData, pattern.listitems); @@ -73,7 +73,7 @@ var list_item_hunter = function () { globalData = JSON5.parse(JSON5.stringify(patternlab.data)); localData = JSON5.parse(JSON5.stringify(pattern.jsonFileData)); } catch (err) { - console.log('There was an error parsing JSON for ' + pattern.abspath); + console.log('There was an error parsing JSON for ' + pattern.relPath); console.log(err); } @@ -82,7 +82,7 @@ var list_item_hunter = function () { allData.link = extend({}, patternlab.data.link); //check for partials within the repeated block - var foundPartials = of.oPattern.createEmpty({'template': thisBlockTemplate}).findPartials(); + var foundPartials = Pattern.createEmpty({'template': thisBlockTemplate}).findPartials(); if (foundPartials && foundPartials.length > 0) { @@ -97,7 +97,7 @@ var list_item_hunter = function () { try { cleanPartialPattern = JSON5.parse(JSON5.stringify(partialPattern)); } catch (err) { - console.log('There was an error parsing JSON for ' + pattern.abspath); + console.log('There was an error parsing JSON for ' + pattern.relPath); console.log(err); } diff --git a/core/lib/object_factory.js b/core/lib/object_factory.js index e11e3284c..7a38d812d 100644 --- a/core/lib/object_factory.js +++ b/core/lib/object_factory.js @@ -14,24 +14,48 @@ var patternEngines = require('./pattern_engines/pattern_engines'); var path = require('path'); var extend = require('util')._extend; -// oPattern properties - -var oPattern = function (abspath, subdir, filename, data) { - this.fileName = filename.substring(0, filename.indexOf('.')); - this.fileExtension = path.extname(abspath); - this.abspath = abspath; - this.subdir = subdir; - this.name = subdir.replace(/[\/\\]/g, '-') + '-' + this.fileName; //this is the unique name with the subDir +// Pattern properties + +var Pattern = function (relPath, data) { + // We expect relPath to be the path of the pattern template, relative to the + // root of the pattern tree. Parse out the path parts and save the useful ones. + var pathObj = path.parse(relPath); + this.relPath = relPath; // '00-atoms/00-global/00-colors.mustache' + this.fileName = pathObj.name; // '00-colors' + this.subdir = pathObj.dir; // '00-atoms/00-global' + this.fileExtension = pathObj.ext; // '.mustache' + + // this is the unique name, subDir + fileName (sans extension) + this.name = this.subdir.replace(/[\/\\]/g, '-') + '-' + this.fileName; // '00-atoms-00-global-00-colors' + + // the JSON used to render values in the pattern this.jsonFileData = data || {}; - this.patternName = this.fileName.replace(/^\d*\-/, ''); + + // strip leading "00-" from the file name and flip tildes to dashes + this.patternName = this.fileName.replace(/^\d*\-/, '').replace('~', '-'); // 'colors' + + // Fancy name. No idea how this works. 'Colors' this.patternDisplayName = this.patternName.split('-').reduce(function (val, working) { return val.charAt(0).toUpperCase() + val.slice(1) + ' ' + working.charAt(0).toUpperCase() + working.slice(1); }, '').trim(); //this is the display name for the ui. strip numeric + hyphen prefixes - this.patternLink = this.name + '/' + this.name + '.html'; + + // calculated path from the root of the public directory to the generated html + // file for this pattern + this.patternLink = this.name + '/' + this.name + '.html'; // '00-atoms-00-global-00-colors/00-atoms-00-global-00-colors.html' + + // the top-level pattern group this pattern belongs to. 'atoms' this.patternGroup = this.name.substring(this.name.indexOf('-') + 1, this.name.indexOf('-', 4) + 1 - this.name.indexOf('-') + 1); - this.patternSubGroup = subdir.substring(subdir.indexOf('/') + 4); - this.flatPatternPath = subdir.replace(/[\/\\]/g, '-'); + + // the sub-group this pattern belongs to. + this.patternSubGroup = this.subdir.substring(this.subdir.indexOf('/') + 4); // 'global' + + // Not sure what this is used for. + this.flatPatternPath = this.subdir.replace(/[\/\\]/g, '-'); // '00-atoms-00-global' + + // The canonical "key" by which this pattern is known. This is the callable + // name of the pattern. UPDATE: this.key is now known as this.patternPartial this.patternPartial = this.patternGroup + '-' + this.patternName; + this.template = ''; this.patternPartialCode = ''; this.lineage = []; @@ -42,9 +66,9 @@ var oPattern = function (abspath, subdir, filename, data) { this.engine = patternEngines.getEngineForPattern(this); }; -// oPattern methods +// Pattern methods -oPattern.prototype = { +Pattern.prototype = { // render method on oPatterns; this acts as a proxy for the PatternEngine's // render function @@ -81,20 +105,20 @@ oPattern.prototype = { } }; -// oPattern static methods +// Pattern static methods -// factory: creates an empty oPattern for miscellaneous internal use, such as +// factory: creates an empty Pattern for miscellaneous internal use, such as // by list_item_hunter -oPattern.createEmpty = function (customProps) { - var pattern = new oPattern('', '', '', null); +Pattern.createEmpty = function (customProps) { + var pattern = new Pattern('', null); return extend(pattern, customProps); }; -// factory: creates an oPattern object on-demand from a hash; the hash accepts -// parameters that replace the positional parameters that the oPattern +// factory: creates an Pattern object on-demand from a hash; the hash accepts +// parameters that replace the positional parameters that the Pattern // constructor takes. -oPattern.create = function (abspath, subdir, filename, data, customProps) { - var newPattern = new oPattern(abspath || '', subdir || '', filename || '', data || null); +Pattern.create = function (relPath, data, customProps) { + var newPattern = new Pattern(relPath || '', data || null); return extend(newPattern, customProps); }; @@ -131,7 +155,7 @@ var oPatternSubTypeItem = function (name) { module.exports = { - oPattern: oPattern, + Pattern: Pattern, oPatternType: oPatternType, oPatternSubType: oPatternSubType, oPatternSubTypeItem: oPatternSubTypeItem diff --git a/core/lib/parameter_hunter.js b/core/lib/parameter_hunter.js index e8909782d..ffb41426d 100644 --- a/core/lib/parameter_hunter.js +++ b/core/lib/parameter_hunter.js @@ -274,7 +274,7 @@ var parameter_hunter = function () { globalData = JSON5.parse(JSON5.stringify(patternlab.data)); localData = JSON5.parse(JSON5.stringify(pattern.jsonFileData || {})); } catch (err) { - console.log('There was an error parsing JSON for ' + pattern.abspath); + console.log('There was an error parsing JSON for ' + pattern.relPath); console.log(err); } diff --git a/core/lib/pattern_assembler.js b/core/lib/pattern_assembler.js index dddfff146..6837dfad8 100644 --- a/core/lib/pattern_assembler.js +++ b/core/lib/pattern_assembler.js @@ -14,7 +14,7 @@ var pattern_assembler = function () { var path = require('path'), fs = require('fs-extra'), - of = require('./object_factory'), + Pattern = require('./object_factory').Pattern, md = require('markdown-it')(), plutils = require('./utilities'), patternEngines = require('./pattern_engines/pattern_engines'); @@ -92,9 +92,9 @@ var pattern_assembler = function () { //only push to array if the array doesn't contain this pattern var isNew = true; for (var i = 0; i < patternlab.patterns.length; i++) { - //so we need the identifier to be unique, which patterns[i].abspath is - if (pattern.abspath === patternlab.patterns[i].abspath) { - //if abspath already exists, overwrite that element + //so we need the identifier to be unique, which patterns[i].relPath is + if (pattern.relPath === patternlab.patterns[i].relPath) { + //if relPath already exists, overwrite that element patternlab.patterns[i] = pattern; patternlab.partials[pattern.patternPartial] = pattern.extendedTemplate || pattern.template; isNew = false; @@ -120,30 +120,30 @@ var pattern_assembler = function () { // Render a pattern on request. Long-term, this should probably go away. function renderPattern(pattern, data, partials) { - // if we've been passed a full oPattern, it knows what kind of template it + // if we've been passed a full Pattern, it knows what kind of template it // is, and how to render itself, so we just call its render method - if (pattern instanceof of.oPattern) { + if (pattern instanceof Pattern) { return pattern.render(data, partials); } else { // otherwise, assume it's a plain mustache template string, and we // therefore just need to create a dummpy pattern to be able to render // it - var dummyPattern = of.oPattern.createEmpty({extendedTemplate: pattern}); + var dummyPattern = Pattern.createEmpty({extendedTemplate: pattern}); return patternEngines.mustache.renderPattern(dummyPattern, data, partials); } } - function processPatternIterative(file, patternlab) { + function processPatternIterative(relPath, patternlab) { //extract some information - var subdir = path.dirname(path.relative(patternlab.config.paths.source.patterns, file)).replace('\\', '/'); - var filename = path.basename(file); + var filename = path.basename(relPath); var ext = path.extname(filename); + var patternsPath = patternlab.config.paths.source.patterns; // skip non-pattern files if (!patternEngines.isPatternFile(filename, patternlab)) { return null; } //make a new Pattern Object - var currentPattern = new of.oPattern(file, subdir, filename); + var currentPattern = new Pattern(relPath); //if file is named in the syntax for variants if (patternEngines.isPseudoPatternJSON(filename)) { @@ -160,7 +160,7 @@ var pattern_assembler = function () { //look for a json file for this template try { - var jsonFilename = path.resolve(patternlab.config.paths.source.patterns, currentPattern.subdir, currentPattern.fileName + ".json"); + var jsonFilename = path.resolve(patternsPath, currentPattern.subdir, currentPattern.fileName + ".json"); currentPattern.jsonFileData = fs.readJSONSync(jsonFilename); if (patternlab.config.debug) { console.log('processPatternIterative: found pattern-specific data.json for ' + currentPattern.patternPartial); @@ -172,7 +172,7 @@ var pattern_assembler = function () { //look for a listitems.json file for this template try { - var listJsonFileName = path.resolve(patternlab.config.paths.source.patterns, currentPattern.subdir, currentPattern.fileName + ".listitems.json"); + var listJsonFileName = path.resolve(patternsPath, currentPattern.subdir, currentPattern.fileName + ".listitems.json"); currentPattern.listitems = fs.readJSONSync(listJsonFileName); buildListItems(currentPattern); if (patternlab.config.debug) { @@ -198,7 +198,7 @@ var pattern_assembler = function () { } //add the raw template to memory - currentPattern.template = fs.readFileSync(file, 'utf8'); + currentPattern.template = fs.readFileSync(path.resolve(patternsPath, relPath), 'utf8'); //find any stylemodifiers that may be in the current pattern currentPattern.stylePartials = currentPattern.findPartialsWithStyleModifiers(); @@ -225,7 +225,7 @@ var pattern_assembler = function () { var currentPattern, i; for (i = 0; i < patternlab.patterns.length; i++) { - if (patternlab.patterns[i].abspath === file) { + if (patternlab.patterns[i].relPath === file) { currentPattern = patternlab.patterns[i]; } } @@ -285,9 +285,9 @@ var pattern_assembler = function () { //identify which pattern this partial corresponds to for (var j = 0; j < patternlab.patterns.length; j++) { if (patternlab.patterns[j].patternPartial === partial || - patternlab.patterns[j].abspath.indexOf(partial) > -1) + patternlab.patterns[j].relPath.indexOf(partial) > -1) { - partialPath = patternlab.patterns[j].abspath; + partialPath = patternlab.patterns[j].relPath; } } diff --git a/core/lib/pattern_engines/engine_handlebars.js b/core/lib/pattern_engines/engine_handlebars.js index f88a14d21..1857052a3 100644 --- a/core/lib/pattern_engines/engine_handlebars.js +++ b/core/lib/pattern_engines/engine_handlebars.js @@ -44,8 +44,8 @@ var engine_handlebars = { return compiled(data); }, - registerPartial: function (oPattern) { - Handlebars.registerPartial(oPattern.patternPartial, oPattern.template); + registerPartial: function (Pattern) { + Handlebars.registerPartial(Pattern.patternPartial, Pattern.template); }, // find and return any {{> template-name }} within pattern @@ -54,7 +54,7 @@ var engine_handlebars = { return matches; }, findPartialsWithStyleModifiers: function () { - // TODO: make the call to this from oPattern objects conditional on their + // TODO: make the call to this from Pattern objects conditional on their // being implemented here. return []; }, @@ -62,7 +62,7 @@ var engine_handlebars = { // returns any patterns that match {{> value(foo:"bar") }} or {{> // value:mod(foo:"bar") }} within the pattern findPartialsWithPatternParameters: function () { - // TODO: make the call to this from oPattern objects conditional on their + // TODO: make the call to this from Pattern objects conditional on their // being implemented here. return []; }, diff --git a/core/lib/pattern_engines/engine_twig.js b/core/lib/pattern_engines/engine_twig.js index acf30cfce..e2d08f1b0 100644 --- a/core/lib/pattern_engines/engine_twig.js +++ b/core/lib/pattern_engines/engine_twig.js @@ -51,7 +51,7 @@ var engine_twig = { return matches; }, findPartialsWithStyleModifiers: function () { - // TODO: make the call to this from oPattern objects conditional on their + // TODO: make the call to this from Pattern objects conditional on their // being implemented here. return []; }, @@ -59,7 +59,7 @@ var engine_twig = { // returns any patterns that match {{> value(foo:"bar") }} or {{> // value:mod(foo:"bar") }} within the pattern findPartialsWithPatternParameters: function () { - // TODO: make the call to this from oPattern objects conditional on their + // TODO: make the call to this from Pattern objects conditional on their // being implemented here. return []; }, diff --git a/core/lib/pattern_engines/engine_underscore.js b/core/lib/pattern_engines/engine_underscore.js index a99528ba0..607e96ded 100644 --- a/core/lib/pattern_engines/engine_underscore.js +++ b/core/lib/pattern_engines/engine_underscore.js @@ -73,9 +73,9 @@ return renderedHTML; }, - // registerPartial: function (oPattern) { + // registerPartial: function (Pattern) { // debugger; - // _.registerPartial(oPattern.patternPartial, oPattern.template); + // _.registerPartial(Pattern.patternPartial, Pattern.template); // }, // find and return any {{> template-name }} within pattern diff --git a/core/lib/pattern_engines/pattern_engines.js b/core/lib/pattern_engines/pattern_engines.js index 3d9bfbbf2..68f9af468 100644 --- a/core/lib/pattern_engines/pattern_engines.js +++ b/core/lib/pattern_engines/pattern_engines.js @@ -107,7 +107,7 @@ PatternEngines = Object.create({ // avoid circular dependency by putting this in here. TODO: is this slow? var of = require('../object_factory'); - if (pattern instanceof of.oPattern && typeof pattern.fileExtension === 'string' && pattern.fileExtension) { + if (pattern instanceof of.Pattern && typeof pattern.fileExtension === 'string' && pattern.fileExtension) { return engineNameForExtension[pattern.fileExtension]; } diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 59ac78a9b..b08cea483 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -8,13 +8,65 @@ * */ +var diveSync = require('diveSync'), + path = require('path'); + +// GTP: these two diveSync pattern processors factored out so they can be reused +// from unit tests to reduce code dupe! + +function processAllPatternsIterative(pattern_assembler, patterns_dir, patternlab) { + diveSync( + patterns_dir, + { + filter: function (thisPath, dir) { + if (dir) { + var remainingPath = thisPath.replace(patterns_dir, ''); + var isValidPath = remainingPath.indexOf('/_') === -1; + return isValidPath; + } + return true; + } + }, + function (err, file) { + //log any errors + if (err) { + console.log(err); + return; + } + pattern_assembler.process_pattern_iterative(path.relative(patterns_dir, file), patternlab); + } + ); +} + +function processAllPatternsRecursive(pattern_assembler, patterns_dir, patternlab) { + diveSync( + patterns_dir, + { + filter: function (thisPath, dir) { + if (dir) { + var remainingPath = thisPath.replace(patterns_dir, ''); + var isValidPath = remainingPath.indexOf('/_') === -1; + return isValidPath; + } + return true; + } + }, + function (err, file) { + //log any errors + if (err) { + console.log(err); + return; + } + pattern_assembler.process_pattern_recursive(path.relative(patterns_dir, file), patternlab); + } + ); +} + var patternlab_engine = function (config) { 'use strict'; - var path = require('path'), - JSON5 = require('json5'), + var JSON5 = require('json5'), fs = require('fs-extra'), - diveSync = require('diveSync'), pa = require('./pattern_assembler'), pe = require('./pattern_exporter'), lh = require('./lineage_hunter'), @@ -78,6 +130,8 @@ var patternlab_engine = function (config) { } } + + function buildPatterns(deletePatternDir) { try { patternlab.data = fs.readJSONSync(path.resolve(paths.source.data, 'data.json')); @@ -116,50 +170,12 @@ var patternlab_engine = function (config) { pattern_assembler.combine_listItems(patternlab); - //diveSync once to perform iterative populating of patternlab object - diveSync( - patterns_dir, - { - filter: function (thisPath, dir) { - if (dir) { - var remainingPath = thisPath.replace(patterns_dir, ''); - var isValidPath = remainingPath.indexOf('/_') === -1; - return isValidPath; - } - return true; - } - }, - function (err, file) { - //log any errors - if (err) { - console.log(err); - return; - } - pattern_assembler.process_pattern_iterative(path.resolve(file), patternlab); - }); + // diveSync once to perform iterative populating of patternlab object + processAllPatternsIterative(pattern_assembler, patterns_dir, patternlab); //diveSync again to recursively include partials, filling out the //extendedTemplate property of the patternlab.patterns elements - diveSync( - patterns_dir, - { - filter: function (thisPath, dir) { - if (dir) { - var remainingPath = thisPath.replace(patterns_dir, ''); - var isValidPath = remainingPath.indexOf('/_') === -1; - return isValidPath; - } - return true; - } - }, - function (err, file) { - //log any errors - if (err) { - console.log(err); - return; - } - pattern_assembler.process_pattern_recursive(path.resolve(file), patternlab); - }); + processAllPatternsRecursive(pattern_assembler, patterns_dir, patternlab); //set user defined head and foot if they exist try { @@ -225,7 +241,7 @@ var patternlab_engine = function (config) { try { allData = JSON5.parse(JSON5.stringify(patternlab.data)); } catch (err) { - console.log('There was an error parsing JSON for ' + pattern.abspath); + console.log('There was an error parsing JSON for ' + pattern.relPath); console.log(err); } allData = plutils.mergeData(allData, pattern.jsonFileData); @@ -298,7 +314,12 @@ var patternlab_engine = function (config) { printDebug(); } }; - }; +// export these free functions so they're available without calling the exported +// function, for use in reducing code dupe in unit tests. At least, until we +// have a better way to do this +patternlab_engine.process_all_patterns_iterative = processAllPatternsIterative; +patternlab_engine.process_all_patterns_recursive = processAllPatternsRecursive; + module.exports = patternlab_engine; diff --git a/core/lib/pseudopattern_hunter.js b/core/lib/pseudopattern_hunter.js index 0c0910b1d..dd55cb541 100644 --- a/core/lib/pseudopattern_hunter.js +++ b/core/lib/pseudopattern_hunter.js @@ -17,7 +17,7 @@ var pseudopattern_hunter = function () { fs = require('fs-extra'), pa = require('./pattern_assembler'), lh = require('./lineage_hunter'), - of = require('./object_factory'), + Pattern = require('./object_factory').Pattern, plutils = require('./utilities'), path = require('path'); @@ -46,11 +46,10 @@ var pseudopattern_hunter = function () { //extend any existing data with variant data variantFileData = plutils.mergeData(currentPattern.jsonFileData, variantFileData); - + var variantName = pseudoPatterns[i].substring(pseudoPatterns[i].indexOf('~') + 1).split('.')[0]; - var variantFilePath = path.resolve(paths.source.patterns, currentPattern.subdir, currentPattern.fileName + '~' + variantName + '.json'); - var variantFileName = currentPattern.fileName + '-' + variantName + '.'; - var patternVariant = of.oPattern.create(variantFilePath, currentPattern.subdir, variantFileName, variantFileData, { + var variantFilePath = path.join(currentPattern.subdir, currentPattern.fileName + '~' + variantName + '.json'); + var patternVariant = Pattern.create(variantFilePath, variantFileData, { //use the same template as the non-variant template: currentPattern.template, extendedTemplate: currentPattern.extendedTemplate, diff --git a/test/engine_handlebars_tests.js b/test/engine_handlebars_tests.js index 6203a38ce..fb3546936 100644 --- a/test/engine_handlebars_tests.js +++ b/test/engine_handlebars_tests.js @@ -6,8 +6,9 @@ catch (err) { return; } var path = require('path'); var pa = require('../core/lib/pattern_assembler'); -var object_factory = require('../core/lib/object_factory'); +var Pattern = require('../core/lib/object_factory').Pattern; var testPatternsPath = path.resolve(__dirname, 'files', '_handlebars-test-patterns'); +var eol = require('os').EOL; try { require('handlebars'); @@ -36,7 +37,7 @@ function fakePatternLab() { // patch the pattern source so the pattern assembler can correctly determine // the "subdir" - fpl.config.paths.source.patterns = './test/files/_handlebars-test-patterns'; + fpl.config.paths.source.patterns = testPatternsPath; return fpl; } @@ -49,10 +50,8 @@ function testFindPartials(test, partialTests) { // setup current pattern from what we would have during execution // docs on partial syntax are here: // http://patternlab.io/docs/pattern-including.html - var currentPattern = object_factory.oPattern.create( - '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.hbs', // abspath - '01-molecules\\00-testing', // subdir - '00-test-mol.hbs', // filename, + var currentPattern = Pattern.create( + '01-molecules/00-testing/00-test-mol.hbs', // relative path now null, // data { template: partialTests.join() @@ -75,12 +74,7 @@ exports['engine_handlebars'] = { 'hello world handlebars pattern renders': function (test) { test.expect(1); - var patternPath = path.resolve( - testPatternsPath, - '00-atoms', - '00-global', - '00-helloworld.hbs' - ); + var patternPath = path.join('00-atoms', '00-global', '00-helloworld.hbs'); // do all the normal processing of the pattern var patternlab = new fakePatternLab(); @@ -88,25 +82,15 @@ exports['engine_handlebars'] = { var helloWorldPattern = assembler.process_pattern_iterative(patternPath, patternlab); assembler.process_pattern_recursive(patternPath, patternlab); - test.equals(helloWorldPattern.render(), 'Hello world!\n'); + test.equals(helloWorldPattern.render(), 'Hello world!' + eol); test.done(); }, 'hello worlds handlebars pattern can see the atoms-helloworld partial and renders it twice': function (test) { test.expect(1); // pattern paths - var pattern1Path = path.resolve( - testPatternsPath, - '00-atoms', - '00-global', - '00-helloworld.hbs' - ); - var pattern2Path = path.resolve( - testPatternsPath, - '00-molecules', - '00-global', - '00-helloworlds.hbs' - ); + var pattern1Path = path.join('00-atoms', '00-global', '00-helloworld.hbs'); + var pattern2Path = path.join('00-molecules', '00-global', '00-helloworlds.hbs'); // set up environment var patternlab = new fakePatternLab(); // environment @@ -119,19 +103,14 @@ exports['engine_handlebars'] = { assembler.process_pattern_recursive(pattern2Path, patternlab); // test - test.equals(helloWorldsPattern.render(), 'Hello world!\n and Hello world!\n\n'); + test.equals(helloWorldsPattern.render(), 'Hello world!' + eol + ' and Hello world!' + eol + eol); test.done(); }, 'handlebars partials can render JSON values': function (test) { test.expect(1); // pattern paths - var pattern1Path = path.resolve( - testPatternsPath, - '00-atoms', - '00-global', - '00-helloworld-withdata.hbs' - ); + var pattern1Path = path.join('00-atoms', '00-global', '00-helloworld-withdata.hbs'); // set up environment var patternlab = new fakePatternLab(); // environment @@ -142,45 +121,35 @@ exports['engine_handlebars'] = { assembler.process_pattern_recursive(pattern1Path, patternlab); // test - test.equals(helloWorldWithData.render(), 'Hello world!\nYeah, we got the subtitle from the JSON.\n'); + test.equals(helloWorldWithData.render(), 'Hello world!' + eol + 'Yeah, we got the subtitle from the JSON.' + eol); test.done(); }, 'handlebars partials use the JSON environment from the calling pattern and can accept passed parameters': function (test) { test.expect(1); // pattern paths - var atomPath = path.resolve( - testPatternsPath, - '00-atoms', - '00-global', - '00-helloworld-withdata.hbs' - ); - var molPath = path.resolve( - testPatternsPath, - '00-molecules', - '00-global', - '00-call-atom-with-molecule-data.hbs' - ); + var atomPath = path.join('00-atoms', '00-global', '00-helloworld-withdata.hbs'); + var molPath = path.join('00-molecules', '00-global', '00-call-atom-with-molecule-data.hbs'); // set up environment var patternlab = new fakePatternLab(); // environment var assembler = new pa(); // do all the normal processing of the pattern - var atom = assembler.process_pattern_iterative(atomPath, patternlab); + assembler.process_pattern_iterative(atomPath, patternlab); var mol = assembler.process_pattern_iterative(molPath, patternlab); assembler.process_pattern_recursive(atomPath, patternlab); assembler.process_pattern_recursive(molPath, patternlab); // test - test.equals(mol.render(), '

    Call with default JSON environment:

    \nThis is Hello world!\nfrom the default JSON.\n\n\n

    Call with passed parameter:

    \nHowever, this is Hello world!\nfrom a totally different blob.\n\n'); + test.equals(mol.render(), '

    Call with default JSON environment:

    ' + eol + 'This is Hello world!' + eol + 'from the default JSON.' + eol + eol + eol +'

    Call with passed parameter:

    ' + eol + 'However, this is Hello world!' + eol + 'from a totally different blob.' + eol + eol); test.done(); }, 'find_pattern_partials finds partials': function (test) { testFindPartials(test, [ "{{> molecules-comment-header}}", "{{> molecules-comment-header}}", - "{{> \n molecules-comment-header\n}}", + "{{> " + eol + " molecules-comment-header" + eol + "}}", "{{> molecules-weird-spacing }}", "{{> molecules-ba_d-cha*rs }}" ]); @@ -209,7 +178,7 @@ exports['engine_handlebars'] = { 'find_pattern_partials finds partials with handlebars parameters': function (test) { testFindPartials(test, [ '{{> atoms-title title="bravo" headingLevel="2" headingSize="bravo" position="left"}}', - '{{> atoms-title title="bravo"\n headingLevel="2"\n headingSize="bravo"\n position="left"}}', + '{{> atoms-title title="bravo"' + eol + ' headingLevel="2"' + eol + ' headingSize="bravo"' + eol + ' position="left"}}', '{{> atoms-title title="color  midnight blue" headingSize="charlie"}}', '{{> atoms-input label="city" required=true}}', '{{> organisms-product-filter filterData}}', diff --git a/test/engine_twig_tests.js b/test/engine_twig_tests.js index 308193d93..49042ba27 100644 --- a/test/engine_twig_tests.js +++ b/test/engine_twig_tests.js @@ -7,8 +7,9 @@ catch (err) { return; } var path = require('path'); var pa = require('../core/lib/pattern_assembler'); -var object_factory = require('../core/lib/object_factory'); +var Pattern = require('../core/lib/object_factory').Pattern; var testPatternsPath = path.resolve(__dirname, 'files', '_twig-test-patterns'); +var eol = require('os').EOL; try { require('twig'); @@ -50,10 +51,8 @@ function testFindPartials(test, partialTests) { // setup current pattern from what we would have during execution // docs on partial syntax are here: // http://patternlab.io/docs/pattern-including.html - var currentPattern = object_factory.oPattern.create( - '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.twig', // abspath - '01-molecules\\00-testing', // subdir - '00-test-mol.twig', // filename, + var currentPattern = Pattern.create( + '01-molecules/00-testing/00-test-mol.twig', // relative path now null, // data { template: partialTests.join() @@ -76,14 +75,8 @@ exports['engine_twig'] = { 'button twig pattern renders': function (test) { test.expect(1); - var patternPath = path.resolve( - testPatternsPath, - '00-atoms', - '00-general', - '08-button.twig' - ); - - var expectedValue = '\n\nButton\n'; + var patternPath = path.join('00-atoms', '00-general', '08-button.twig'); + var expectedValue = '' + eol + eol + 'Button' + eol; // do all the normal processing of the pattern var patternlab = new fakePatternLab(); @@ -98,24 +91,9 @@ exports['engine_twig'] = { test.expect(1); // pattern paths - var buttonPatternPath = path.resolve( - testPatternsPath, - '00-atoms', - '00-general', - '08-button.twig' - ); - var imagePatternPath = path.resolve( - testPatternsPath, - '00-atoms', - '00-general', - '09-image.twig' - ); - var mediaObjectPatternPath = path.resolve( - testPatternsPath, - '00-molecules', - '00-general', - '00-media-object.twig' - ); + var buttonPatternPath = path.join('00-atoms', '00-general', '08-button.twig'); + var imagePatternPath = path.join('00-atoms', '00-general', '09-image.twig'); + var mediaObjectPatternPath = path.join('00-molecules', '00-general', '00-media-object.twig'); var expectedValue = '\n\n\n\n\n
    \n \n\n \n\nButton\n\n\n
    \n\n \n \n\n

    Oh, hello world!

    \n
    \n
    \n'; @@ -132,7 +110,8 @@ exports['engine_twig'] = { assembler.process_pattern_recursive(mediaObjectPatternPath, patternlab); // test - test.equals(mediaObjectPattern.render(), expectedValue); + // this pattern is too long - so just remove line endings on both sides and compare output + test.equals(mediaObjectPattern.render().replace(/\r?\n|\r/gm, ""), expectedValue.replace(/\r?\n|\r/gm, "")); test.done(); }, // 'twig partials can render JSON values': function (test) { diff --git a/test/lineage_hunter_tests.js b/test/lineage_hunter_tests.js index 6ede79815..cb9a70251 100644 --- a/test/lineage_hunter_tests.js +++ b/test/lineage_hunter_tests.js @@ -3,7 +3,10 @@ var lh = require('../core/lib/lineage_hunter'); var pa = require('../core/lib/pattern_assembler'); var of = require('../core/lib/object_factory'); +var Pattern = require('../core/lib/object_factory').Pattern; + var fs = require('fs-extra'); +var path = require('path'); var extend = require('util')._extend; var pattern_assembler = new pa(); @@ -11,10 +14,8 @@ var lineage_hunter = new lh(); // fake pattern creators function createFakeEmptyErrorPattern() { - return new of.oPattern( - '/home/fakeuser/pl/source/_patterns/01-molecules/01-toast/00-error.mustache', // abspath - '01-molecules\\01-toast', // subdir - '00-error.mustache', // filename, + return new Pattern( + '01-molecules/01-toast/00-error.mustache', // relative path now null // data ); } @@ -42,10 +43,8 @@ exports['lineage hunter '] = { 'find_lineage - finds lineage': function (test) { //setup current pattern from what we would have during execution - var currentPattern = new of.oPattern( - '/home/fakeuser/pl/source/_patterns/02-organisms/00-global/00-header.mustache', // abspath - '02-organisms\\00-global', // subdir - '00-header.mustache', // filename, + var currentPattern = new Pattern( + '02-organisms/00-global/00-header.mustache', // relative path now null // data ); extend(currentPattern, { @@ -136,10 +135,8 @@ exports['lineage hunter '] = { var patternlab = { patterns: [ - of.oPattern.create( - '/home/fakeuser/pl/source/_patterns/00-atoms/05-alerts/00-error.mustache', - '00-atoms\\05-alerts', - '00-error.mustache', + Pattern.create( + '00-atoms/05-alerts/00-error.mustache', null, { "template": "

    {{message}}

    ", @@ -167,14 +164,14 @@ exports['lineage hunter '] = { "test-bar": "inreview" }; - var atomPattern = new of.oPattern('test/files/_patterns/00-test/01-bar.mustache', '00-test', '01-bar.mustache'); + var atomPattern = new of.Pattern('00-test/01-bar.mustache'); atomPattern.template = fs.readFileSync(pl.config.paths.source.patterns + '00-test/01-bar.mustache', 'utf8'); atomPattern.extendedTemplate = atomPattern.template; pattern_assembler.setPatternState(atomPattern, pl); pattern_assembler.addPattern(atomPattern, pl); - var consumerPattern = new of.oPattern('test/files/_patterns/00-test/00-foo.mustache', '00-test', '00-foo.mustache'); + var consumerPattern = new of.Pattern('00-test/00-foo.mustache'); consumerPattern.template = fs.readFileSync(pl.config.paths.source.patterns + '00-test/00-foo.mustache', 'utf8'); consumerPattern.extendedTemplate = consumerPattern.template; pattern_assembler.setPatternState(consumerPattern, pl); @@ -199,14 +196,14 @@ exports['lineage hunter '] = { "test-bar": "inreview" }; - var atomPattern = new of.oPattern('test/files/_patterns/00-test/01-bar.mustache', '00-test', '01-bar.mustache'); + var atomPattern = new of.Pattern('00-test/01-bar.mustache'); atomPattern.template = fs.readFileSync(pl.config.paths.source.patterns + '00-test/01-bar.mustache', 'utf8'); atomPattern.extendedTemplate = atomPattern.template; pattern_assembler.setPatternState(atomPattern, pl); pattern_assembler.addPattern(atomPattern, pl); - var consumerPattern = new of.oPattern('test/files/_patterns/00-test/00-foo.mustache', '00-test', '00-foo.mustache'); + var consumerPattern = new of.Pattern('00-test/00-foo.mustache'); consumerPattern.template = fs.readFileSync(pl.config.paths.source.patterns + '00-test/00-foo.mustache', 'utf8'); consumerPattern.extendedTemplate = consumerPattern.template; pattern_assembler.setPatternState(consumerPattern, pl); @@ -231,14 +228,14 @@ exports['lineage hunter '] = { "test-bar": "inreview" }; - var atomPattern = new of.oPattern('test/files/_patterns/00-test/01-bar.mustache', '00-test', '01-bar.mustache'); + var atomPattern = new of.Pattern('00-test/01-bar.mustache'); atomPattern.template = fs.readFileSync(pl.config.paths.source.patterns + '00-test/01-bar.mustache', 'utf8'); atomPattern.extendedTemplate = atomPattern.template; pattern_assembler.setPatternState(atomPattern, pl); pattern_assembler.addPattern(atomPattern, pl); - var consumerPattern = new of.oPattern('test/files/_patterns/00-test/00-foo.mustache', '00-test', '00-foo.mustache'); + var consumerPattern = new of.Pattern('00-test/00-foo.mustache'); consumerPattern.template = fs.readFileSync(pl.config.paths.source.patterns + '00-test/00-foo.mustache', 'utf8'); consumerPattern.extendedTemplate = consumerPattern.template; pattern_assembler.setPatternState(consumerPattern, pl); @@ -263,15 +260,15 @@ exports['lineage hunter '] = { "test-bar": "inreview" }; - var atomPattern = new of.oPattern('test/files/_patterns/00-test/01-bar.mustache', '00-test', '01-bar.mustache'); - atomPattern.template = fs.readFileSync(pl.config.paths.source.patterns + '00-test/01-bar.mustache', 'utf8'); + var atomPattern = new of.Pattern('00-test/01-bar.mustache'); + atomPattern.template = fs.readFileSync(path.resolve(pl.config.paths.source.patterns, '00-test/01-bar.mustache'), 'utf8'); atomPattern.extendedTemplate = atomPattern.template; pattern_assembler.setPatternState(atomPattern, pl); pattern_assembler.addPattern(atomPattern, pl); - var consumerPattern = new of.oPattern('test/files/_patterns/00-test/00-foo.mustache', '00-test', '00-foo.mustache'); - consumerPattern.template = fs.readFileSync(pl.config.paths.source.patterns + '00-test/00-foo.mustache', 'utf8'); + var consumerPattern = new of.Pattern('00-test/00-foo.mustache'); + consumerPattern.template = fs.readFileSync(path.resolve(pl.config.paths.source.patterns, '00-test/00-foo.mustache'), 'utf8'); consumerPattern.extendedTemplate = consumerPattern.template; pattern_assembler.setPatternState(consumerPattern, pl); pattern_assembler.addPattern(consumerPattern, pl); @@ -334,7 +331,7 @@ exports['lineage hunter '] = { 'find_lineage - finds lineage with spaced styleModifier': function (test) { //setup current pattern from what we would have during execution - var currentPattern = of.oPattern.createEmpty({ + var currentPattern = Pattern.createEmpty({ "name": "01-molecules-01-toast-00-error", "subdir": "01-molecules\\01-toast", "filename": "00-error.mustache", @@ -355,7 +352,7 @@ exports['lineage hunter '] = { }); var patternlab = { patterns: [ - of.oPattern.createEmpty({ + Pattern.createEmpty({ "name": "01-atoms-05-alerts-00-error", "subdir": "01-atoms\\05-alerts", "filename": "00-error.mustache", @@ -388,7 +385,7 @@ exports['lineage hunter '] = { 'find_lineage - finds lineage with unspaced styleModifier': function (test) { //setup current pattern from what we would have during execution - var currentPattern = of.oPattern.createEmpty({ + var currentPattern = Pattern.createEmpty({ "name": "01-molecules-01-toast-00-error", "subdir": "01-molecules\\01-toast", "filename": "00-error.mustache", @@ -409,7 +406,7 @@ exports['lineage hunter '] = { }); var patternlab = { patterns: [ - of.oPattern.createEmpty({ + Pattern.createEmpty({ "name": "01-atoms-05-alerts-00-error", "subdir": "01-atoms\\05-alerts", "filename": "00-error.mustache", @@ -442,7 +439,7 @@ exports['lineage hunter '] = { 'find_lineage - finds lineage with fuzzy partial with styleModifier': function (test) { //setup current pattern from what we would have during execution - var currentPattern = of.oPattern.createEmpty({ + var currentPattern = Pattern.createEmpty({ "name": "01-molecules-01-toast-00-error", "subdir": "01-molecules\\01-toast", "filename": "00-error.mustache", @@ -463,7 +460,7 @@ exports['lineage hunter '] = { }); var patternlab = { patterns: [ - of.oPattern.createEmpty({ + Pattern.createEmpty({ "name": "01-atoms-05-alerts-00-error", "subdir": "01-atoms\\05-alerts", "filename": "00-error.mustache", @@ -535,6 +532,6 @@ exports['lineage hunter '] = { test.equals(patternlab.patterns[0].lineageR[0].lineagePattern, 'molecules-error'); test.done(); - }, + } }; diff --git a/test/list_item_hunter_tests.js b/test/list_item_hunter_tests.js index 64e55826a..361763eaa 100644 --- a/test/list_item_hunter_tests.js +++ b/test/list_item_hunter_tests.js @@ -2,18 +2,16 @@ "use strict"; var lih = require('../core/lib/list_item_hunter'); - var of = require('../core/lib/object_factory'); + var Pattern = require('../core/lib/object_factory').Pattern; var extend = require('util')._extend; // fake pattern creators function createFakeListPattern(customProps) { var inputs = { - abspath: '/home/fakeuser/pl/source/_patterns/01-molecules/01-lists/00-list.mustache', - subdir: '01-molecules\\01-lists', - filename: '00-list.mustache', + relPath: '01-molecules/01-lists/00-list.mustache', data: {} }; - var pattern = new of.oPattern(inputs.abspath, inputs.subdir, inputs.filename, inputs.data); + var pattern = new Pattern(inputs.relPath); return extend(pattern, customProps); } @@ -128,11 +126,11 @@ var patternlab = createFakePatternLab({ "patterns": [ - of.oPattern.create('/home/fakeuser/pl/source/_patterns/00-atoms/00-test/00-foo.mustache', "00-atoms/00-test", "00-foo.mustache", null, { + Pattern.create('00-atoms/00-test/00-foo.mustache', null, { "template": "{{ title }}", "extendedTemplate": "{{ title }}" }), - of.oPattern.create('/home/fakeuser/pl/source/_patterns/00-atoms/00-test/00-bar.mustache', "00-atoms/00-test", "00-bar.mustache", null, { + Pattern.create('00-atoms/00-test/00-bar.mustache', null, { "template": "{{ title }}", "extendedTemplate": "{{ title }}" }) @@ -300,7 +298,7 @@ pl.config.debug = false; pl.patterns = []; pl.partials = {}; - pl.config.patterns = { source: patterns_dir}; + pl.config.patterns = { source: patterns_dir }; pl.listitems = { "1": [ { @@ -317,12 +315,12 @@ ] }; - var atomPattern = new of.oPattern('test/files/_patterns/00-test/03-styled-atom.mustache', '00-test', '03-styled-atom.mustache'); + var atomPattern = new Pattern('00-test/03-styled-atom.mustache'); atomPattern.template = fs.readFileSync(patterns_dir + '/00-test/03-styled-atom.mustache', 'utf8'); atomPattern.extendedTemplate = atomPattern.template; atomPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(atomPattern); - var bookendPattern = new of.oPattern('test/files/_patterns/00-test/11-bookend-listitem.mustache', '00-test', '11-bookend-listitem.mustache'); + var bookendPattern = new Pattern('00-test/11-bookend-listitem.mustache'); bookendPattern.template = fs.readFileSync(patterns_dir + '/00-test/11-bookend-listitem.mustache', 'utf8'); bookendPattern.extendedTemplate = bookendPattern.template; bookendPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(bookendPattern); diff --git a/test/object_factory_tests.js b/test/object_factory_tests.js index 8f29e1c12..81dc3d59e 100644 --- a/test/object_factory_tests.js +++ b/test/object_factory_tests.js @@ -1,13 +1,14 @@ (function () { "use strict"; - var of = require('../core/lib/object_factory'); + var of = require('../core/lib/object_factory'); + var Pattern = require('../core/lib/object_factory').Pattern; - exports['oPattern initialization'] = { - 'test oPattern initializes correctly' : function(test){ - var p = new of.oPattern('source/_patterns/00-atoms/00-global/00-colors.mustache', '00-atoms/00-global', '00-colors.mustache', { d: 123}); + exports['Pattern initialization'] = { + 'test Pattern initializes correctly' : function (test) { + var p = new Pattern('00-atoms/00-global/00-colors.mustache', { d: 123}); + test.equals(p.relPath, '00-atoms/00-global/00-colors.mustache'); test.equals(p.name, '00-atoms-00-global-00-colors'); - test.equals(p.abspath, 'source/_patterns/00-atoms/00-global/00-colors.mustache'); test.equals(p.subdir, '00-atoms/00-global'); test.equals(p.fileName, '00-colors'); test.equals(p.fileExtension, '.mustache'); @@ -27,14 +28,35 @@ test.equals(p.lineageRIndex.length, 0); test.done(); }, - 'test oPattern capitalizes patternDisplayName correctly' : function(test){ - var p = new of.oPattern('source/_patterns/00-atoms/00-global/00-colors-alt.mustache', '00-atoms/00-global', '00-colors-alt.mustache', { d: 123}); + 'test Pattern with one-directory subdir works as expected' : function (test) { + var p = new Pattern('00-atoms/00-colors.mustache', { d: 123}); + test.equals(p.relPath, '00-atoms/00-colors.mustache'); + test.equals(p.name, '00-atoms-00-colors'); + test.equals(p.subdir, '00-atoms'); + test.equals(p.fileName, '00-colors'); + test.equals(p.fileExtension, '.mustache'); + test.equals(p.jsonFileData.d, 123); + test.equals(p.patternName, 'colors'); + test.equals(p.patternDisplayName, 'Colors'); + test.equals(p.patternLink, '00-atoms-00-colors/00-atoms-00-colors.html'); + test.equals(p.patternGroup, 'atoms'); + test.equals(p.flatPatternPath, '00-atoms'); + test.equals(p.patternPartial, 'atoms-colors'); + test.equals(p.template, ''); + test.equals(p.lineage.length, 0); + test.equals(p.lineageIndex.length, 0); + test.equals(p.lineageR.length, 0); + test.equals(p.lineageRIndex.length, 0); + test.done(); + }, + 'test Pattern capitalizes patternDisplayName correctly' : function(test){ + var p = new Pattern('00-atoms/00-global/00-colors-alt.mustache', { d: 123}); test.equals(p.patternName, 'colors-alt'); test.equals(p.patternDisplayName, 'Colors Alt'); test.done(); }, - 'test oPattern removes pattern paramter from key correctly' : function(test){ - var p = new of.oPattern('source/_patterns/00-atoms/00-global/00-colors-alt.mustache', '00-atoms/00-global', '00-colors-alt.mustache', { d: 123}); + 'test Pattern removes pattern paramter from key correctly' : function(test){ + var p = new Pattern('00-atoms/00-global/00-colors-alt.mustache', { d: 123}); test.equals(p.patternName, 'colors-alt'); test.equals(p.patternDisplayName, 'Colors Alt'); test.done(); diff --git a/test/pattern_assembler_tests.js b/test/pattern_assembler_tests.js index 50cbb9e7d..92c7ea73f 100644 --- a/test/pattern_assembler_tests.js +++ b/test/pattern_assembler_tests.js @@ -2,7 +2,7 @@ "use strict"; var pa = require('../core/lib/pattern_assembler'); - var object_factory = require('../core/lib/object_factory'); + var Pattern = require('../core/lib/object_factory').Pattern; var path = require('path'); exports['pattern_assembler'] = { @@ -18,10 +18,8 @@ // setup current pattern from what we would have during execution // docs on partial syntax are here: // http://patternlab.io/docs/pattern-including.html - var currentPattern = object_factory.oPattern.create( - '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath - '01-molecules\\00-testing', // subdir - '00-test-mol.mustache', // filename, + var currentPattern = Pattern.create( + '01-molecules/00-testing/00-test-mol.mustache', // relative path now null, // data { template: "{{> molecules-comment-header}}asdfasdf" + @@ -70,10 +68,8 @@ test.expect(3); //setup current pattern from what we would have during execution - var currentPattern = new object_factory.oPattern( - '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath - '01-molecules\\00-testing', // subdir - '00-test-mol.mustache', // filename, + var currentPattern = new Pattern( + '01-molecules/00-testing/00-test-mol.mustache', // relative path now null // data ); currentPattern.template = "

    {{> 01-molecules/06-components/03-comment-header.mustache }}

    {{> 01-molecules/06-components/02-single-comment.mustache(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}
    "; @@ -89,10 +85,8 @@ //setup current pattern from what we would have during execution - var currentPattern = new object_factory.oPattern( - '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath - '01-molecules\\00-testing', // subdir - '00-test-mol.mustache', // filename, + var currentPattern = new Pattern( + '01-molecules/00-testing/00-test-mol.mustache', // relative path now null // data ); currentPattern.template = "

    {{> molecules-comment-header}}

    {{> molecules-single-comment:foo }}
    {{> molecules-single-comment:foo_1 }}
    {{> molecules-single-comment:foo-1 }}
    "; @@ -110,10 +104,8 @@ //setup current pattern from what we would have during execution - var currentPattern = new object_factory.oPattern( - '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath - '01-molecules\\00-testing', // subdir - '00-test-mol.mustache', // filename, + var currentPattern = new Pattern( + '01-molecules/00-testing/00-test-mol.mustache', // relative path now null // data ); currentPattern.template = "

    {{> molecules-comment-header}}

    {{> molecules-single-comment:foo(bar:'baz') }}
    "; @@ -128,10 +120,8 @@ test.expect(2); //setup current pattern from what we would have during execution - var currentPattern = new object_factory.oPattern( - '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath - '01-molecules\\00-testing', // subdir - '00-test-mol.mustache', // filename, + var currentPattern = new Pattern( + '01-molecules/00-testing/00-test-mol.mustache', // relative path now null // data ); currentPattern.template = "

    {{> 01-molecules/06-components/molecules-comment-header}}

    {{> 01-molecules/06-components/molecules-single-comment:foo }}
    "; @@ -146,10 +136,8 @@ test.expect(1); //setup current pattern from what we would have during execution - var currentPattern = new object_factory.oPattern( - '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath - '01-molecules\\00-testing', // subdir - '00-test-mol.mustache', // filename, + var currentPattern = new Pattern( + '01-molecules/00-testing/00-test-mol.mustache', // relative path now null // data ); currentPattern.template = "

    {{> molecules-comment-header}}

    {{> molecules-single-comment }}
    "; @@ -163,10 +151,8 @@ test.expect(1); //setup current pattern from what we would have during execution - var currentPattern = new object_factory.oPattern( - '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath - '01-molecules\\00-testing', // subdir - '00-test-mol.mustache', // filename, + var currentPattern = new Pattern( + '01-molecules/00-testing/00-test-mol.mustache', // relative path now null // data ); currentPattern.template = "

    {{> molecules-comment-header}}

    {{> molecules-single-comment(foo: 'bar') }}
    "; @@ -180,10 +166,8 @@ test.expect(2); //setup current pattern from what we would have during execution - var currentPattern = new object_factory.oPattern( - '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath - '01-molecules\\00-testing', // subdir - '00-test-mol.mustache', // filename, + var currentPattern = new Pattern( + '01-molecules/00-testing/00-test-mol.mustache', // relative path now null // data ); currentPattern.template = "

    {{> molecules-comment-header}}

    {{> molecules-single-comment(bar:'baz') }}
    "; @@ -199,10 +183,8 @@ test.expect(2); //setup current pattern from what we would have during execution - var currentPattern = new object_factory.oPattern( - '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath - '01-molecules\\00-testing', // subdir - '00-test-mol.mustache', // filename, + var currentPattern = new Pattern( + '01-molecules/00-testing/00-test-mol.mustache', // relative path now null // data ); currentPattern.template = "

    {{> molecules-comment-header}}

    {{> molecules-single-comment:foo(bar:'baz') }}
    "; @@ -217,10 +199,8 @@ test.expect(2); //setup current pattern from what we would have during execution - var currentPattern = new object_factory.oPattern( - '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath - '01-molecules\\00-testing', // subdir - '00-test-mol.mustache', // filename, + var currentPattern = new Pattern( + '01-molecules/00-testing/00-test-mol.mustache', // relative path now null // data ); currentPattern.template = "

    {{> 01-molecules/06-components/molecules-comment-header}}

    {{> 01-molecules/06-components/molecules-single-comment(bar:'baz') }}
    "; @@ -235,10 +215,8 @@ test.expect(1); //setup current pattern from what we would have during execution - var currentPattern = new object_factory.oPattern( - '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath - '01-molecules\\00-testing', // subdir - '00-test-mol.mustache', // filename, + var currentPattern = new Pattern( + '01-molecules/00-testing/00-test-mol.mustache', // relative path now null // data ); currentPattern.template = "

    {{> molecules-comment-header}}

    {{> molecules-single-comment }}
    "; @@ -252,10 +230,8 @@ test.expect(1); //setup current pattern from what we would have during execution - var currentPattern = new object_factory.oPattern( - '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.mustache', // abspath - '01-molecules\\00-testing', // subdir - '00-test-mol.mustache', // filename, + var currentPattern = new Pattern( + '01-molecules/00-testing/00-test-mol.mustache', // relative path now null // data ); currentPattern.template = "

    {{> molecules-comment-header}}

    {{> molecules-single-comment:foo }}
    "; @@ -273,6 +249,7 @@ var diveSync = require('diveSync'); var fs = require('fs-extra'); var pa = require('../core/lib/pattern_assembler'); + var plMain = require('../core/lib/patternlab'); var pattern_assembler = new pa(); var patterns_dir = './test/files/_patterns'; var patternlab = {}; @@ -292,51 +269,11 @@ patternlab.partials = {}; //diveSync once to perform iterative populating of patternlab object - diveSync(patterns_dir, - { - filter: function(path, dir){ - if(dir){ - var remainingPath = path.replace(patterns_dir, ''); - var isValidPath = remainingPath.indexOf('/_') === -1; - return isValidPath; - } - return true; - } - }, - function(err, file){ - //log any errors - if(err){ - console.log(err); - return; - } - - pattern_assembler.process_pattern_iterative(path.resolve(file), patternlab); - } - ); + plMain.process_all_patterns_iterative(pattern_assembler, patterns_dir, patternlab); //diveSync again to recursively include partials, filling out the //extendedTemplate property of the patternlab.patterns elements - diveSync(patterns_dir, - { - filter: function(path, dir){ - if(dir){ - var remainingPath = path.replace(patterns_dir, ''); - var isValidPath = remainingPath.indexOf('/_') === -1; - return isValidPath; - } - return true; - } - }, - function(err, file){ - //log any errors - if(err){ - console.log(err); - return; - } - - pattern_assembler.process_pattern_recursive(path.resolve(file), patternlab); - } - ); + plMain.process_all_patterns_recursive(pattern_assembler, patterns_dir, patternlab); //get test output for comparison var foo = fs.readFileSync(patterns_dir + '/00-test/00-foo.mustache', 'utf8').trim(); @@ -359,7 +296,7 @@ test.done(); }, - 'processPatternRecursive - correctly replaces all stylemodifiers when multiple duplicate patterns with different stylemodifiers found' : function(test){ + 'processPatternRecursive - correctly replaces all stylemodifiers when multiple duplicate patterns with different stylemodifiers found' : function(test){ //arrange var fs = require('fs-extra'); var pattern_assembler = new pa(); @@ -379,11 +316,11 @@ pl.patterns = []; pl.partials = {}; - var atomPattern = new object_factory.oPattern('test/files/_patterns/00-test/03-styled-atom.mustache', '00-test', '03-styled-atom.mustache'); + var atomPattern = new Pattern('00-test/03-styled-atom.mustache'); atomPattern.template = fs.readFileSync(patterns_dir + '/00-test/03-styled-atom.mustache', 'utf8'); atomPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(atomPattern); - var groupPattern = new object_factory.oPattern('test/files/_patterns/00-test/04-group.mustache', '00-test', '04-group.mustache'); + var groupPattern = new Pattern('00-test/04-group.mustache'); groupPattern.template = fs.readFileSync(patterns_dir + '/00-test/04-group.mustache', 'utf8'); groupPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(groupPattern); @@ -391,7 +328,8 @@ pattern_assembler.addPattern(groupPattern, pl); //act - pattern_assembler.process_pattern_recursive('test/files/_patterns/00-test/04-group.mustache', pl, {}); + + pattern_assembler.process_pattern_recursive('00-test/04-group.mustache', pl, {}); //assert var expectedValue = '
    {{message}} {{message}} {{message}} {{message}}
    '; @@ -418,12 +356,12 @@ pl.patterns = []; pl.partials = {}; - var atomPattern = new object_factory.oPattern('test/files/_patterns/00-test/03-styled-atom.mustache', '00-test', '03-styled-atom.mustache'); + var atomPattern = new Pattern('00-test/03-styled-atom.mustache'); atomPattern.template = fs.readFileSync(patterns_dir + '/00-test/03-styled-atom.mustache', 'utf8'); atomPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(atomPattern); atomPattern.parameteredPartials = pattern_assembler.find_pattern_partials_with_parameters(atomPattern); - var groupPattern = new object_factory.oPattern('test/files/_patterns/00-test/10-multiple-classes-numeric.mustache', '00-test', '10-multiple-classes-numeric.mustache'); + var groupPattern = new Pattern('00-test/10-multiple-classes-numeric.mustache'); groupPattern.template = fs.readFileSync(patterns_dir + '/00-test/10-multiple-classes-numeric.mustache', 'utf8'); groupPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(groupPattern); groupPattern.parameteredPartials = pattern_assembler.find_pattern_partials_with_parameters(groupPattern); @@ -432,7 +370,7 @@ pattern_assembler.addPattern(groupPattern, pl); //act - pattern_assembler.process_pattern_recursive('test/files/_patterns/00-test/10-multiple-classes-numeric.mustache', pl, {}); + pattern_assembler.process_pattern_recursive('00-test/10-multiple-classes-numeric.mustache', pl, {}); //assert var expectedValue = '
    {{message}} {{message}} bar
    '; @@ -459,11 +397,11 @@ pl.patterns = []; pl.partials = {}; - var atomPattern = new object_factory.oPattern('test/files/_patterns/00-test/03-styled-atom.mustache', '00-test', '03-styled-atom.mustache'); + var atomPattern = new Pattern('00-test/03-styled-atom.mustache'); atomPattern.template = fs.readFileSync(patterns_dir + '/00-test/03-styled-atom.mustache', 'utf8'); atomPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(atomPattern); - var mixedPattern = new object_factory.oPattern('test/files/_patterns/00-test/06-mixed.mustache', '00-test', '06-mixed.mustache'); + var mixedPattern = new Pattern('00-test/06-mixed.mustache'); mixedPattern.template = fs.readFileSync(patterns_dir + '/00-test/06-mixed.mustache', 'utf8'); mixedPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(mixedPattern); @@ -471,7 +409,7 @@ pattern_assembler.addPattern(mixedPattern, pl); //act - pattern_assembler.process_pattern_recursive('test/files/_patterns/00-test/06-mixed.mustache', pl, {}); + pattern_assembler.process_pattern_recursive('00-test/06-mixed.mustache', pl, {}); //assert. here we expect {{styleModifier}} to be in the first group, since it was not replaced by anything. rendering with data will then remove this (correctly) var expectedValue = '
    {{message}} {{message}} {{message}} {{message}}
    '; @@ -498,21 +436,19 @@ pl.patterns = []; pl.partials = {}; - var atomPattern = new object_factory.oPattern('test/files/_patterns/00-test/03-styled-atom.mustache', '00-test', '03-styled-atom.mustache'); + var atomPattern = new Pattern('00-test/03-styled-atom.mustache'); atomPattern.template = fs.readFileSync(patterns_dir + '/00-test/03-styled-atom.mustache', 'utf8'); atomPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(atomPattern); - var bookendPattern = new object_factory.oPattern('test/files/_patterns/00-test/09-bookend.mustache', '00-test', '09-bookend.mustache'); + var bookendPattern = new Pattern('00-test/09-bookend.mustache'); bookendPattern.template = fs.readFileSync(patterns_dir + '/00-test/09-bookend.mustache', 'utf8'); bookendPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(bookendPattern); pattern_assembler.addPattern(atomPattern, pl); pattern_assembler.addPattern(bookendPattern, pl); - debugger; - //act - pattern_assembler.process_pattern_recursive('test/files/_patterns/00-test/09-bookend.mustache', pl, {}); + pattern_assembler.process_pattern_recursive('00-test/09-bookend.mustache', pl, {}); //assert. here we expect {{styleModifier}} to be in the first and last group, since it was not replaced by anything. rendering with data will then remove this (correctly) var expectedValue = '
    {{message}} {{message}} {{message}} {{message}}
    '; @@ -540,12 +476,12 @@ pl.patterns = []; pl.partials = {}; - var atomPattern = new object_factory.oPattern('test/files/_patterns/00-test/03-styled-atom.mustache', '00-test', '03-styled-atom.mustache'); + var atomPattern = new Pattern('00-test/03-styled-atom.mustache'); atomPattern.template = fs.readFileSync(patterns_dir + '/00-test/03-styled-atom.mustache', 'utf8'); atomPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(atomPattern); atomPattern.parameteredPartials = pattern_assembler.find_pattern_partials_with_parameters(atomPattern); - var mixedPattern = new object_factory.oPattern('test/files/_patterns/00-test/07-mixed-params.mustache', '00-test', '07-mixed-params.mustache'); + var mixedPattern = new Pattern('00-test/07-mixed-params.mustache'); mixedPattern.template = fs.readFileSync(patterns_dir + '/00-test/07-mixed-params.mustache', 'utf8'); mixedPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(mixedPattern); mixedPattern.parameteredPartials = pattern_assembler.find_pattern_partials_with_parameters(mixedPattern); @@ -554,7 +490,7 @@ pattern_assembler.addPattern(mixedPattern, pl); //act - pattern_assembler.process_pattern_recursive('test/files/_patterns/00-test/07-mixed-params.mustache', pl, {}); + pattern_assembler.process_pattern_recursive('00-test/07-mixed-params.mustache', pl, {}); //assert. here we expect {{styleModifier}} to be in the first span, since it was not replaced by anything. rendering with data will then remove this (correctly) var expectedValue = '
    {{message}} 2 3 4
    '; @@ -581,12 +517,12 @@ pl.patterns = []; pl.partials = {}; - var atomPattern = new object_factory.oPattern('test/files/_patterns/00-test/03-styled-atom.mustache', '00-test', '03-styled-atom.mustache'); + var atomPattern = new Pattern('00-test/03-styled-atom.mustache'); atomPattern.template = fs.readFileSync(patterns_dir + '/00-test/03-styled-atom.mustache', 'utf8'); atomPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(atomPattern); atomPattern.parameteredPartials = pattern_assembler.find_pattern_partials_with_parameters(atomPattern); - var bookendPattern = new object_factory.oPattern('test/files/_patterns/00-test/08-bookend-params.mustache', '00-test', '08-bookend-params.mustache'); + var bookendPattern = new Pattern('00-test/08-bookend-params.mustache'); bookendPattern.template = fs.readFileSync(patterns_dir + '/00-test/08-bookend-params.mustache', 'utf8'); bookendPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(bookendPattern); bookendPattern.parameteredPartials = pattern_assembler.find_pattern_partials_with_parameters(bookendPattern); @@ -595,7 +531,7 @@ pattern_assembler.addPattern(bookendPattern, pl); //act - pattern_assembler.process_pattern_recursive('test/files/_patterns/00-test/08-bookend-params.mustache', pl, {}); + pattern_assembler.process_pattern_recursive('00-test/08-bookend-params.mustache', pl, {}); //assert. here we expect {{styleModifier}} to be in the first and last span, since it was not replaced by anything. rendering with data will then remove this (correctly) var expectedValue = '
    {{message}} 2 3 {{message}}
    '; @@ -704,6 +640,7 @@ var diveSync = require('diveSync'); var fs = require('fs-extra'); var pa = require('../core/lib/pattern_assembler'); + var plMain = require('../core/lib/patternlab'); var pattern_assembler = new pa(); var patterns_dir = './test/files/_patterns/'; var patternlab = {}; @@ -722,35 +659,17 @@ patternlab.data.link = {}; patternlab.partials = {}; - diveSync(patterns_dir, - { - filter: function(path, dir){ - if(dir){ - var remainingPath = path.replace(patterns_dir, ''); - var isValidPath = remainingPath.indexOf('/_') === -1; - return isValidPath; - } - return true; - } - }, - function(err, file){ - //log any errors - if(err){ - console.log(err); - return; - } - pattern_assembler.process_pattern_iterative(file, patternlab); - } - ); + //diveSync once to perform iterative populating of patternlab object + plMain.process_all_patterns_iterative(pattern_assembler, patterns_dir, patternlab); //for the sake of the test, also imagining I have the following pages... patternlab.data.link['twitter-brad'] = 'https://twitter.com/brad_frost'; patternlab.data.link['twitter-dave'] = 'https://twitter.com/dmolsen'; patternlab.data.link['twitter-brian'] = 'https://twitter.com/bmuenzenmeyer'; - patternlab.data.brad = { url: "link.twitter-brad" } - patternlab.data.dave = { url: "link.twitter-dave" } - patternlab.data.brian = { url: "link.twitter-brian" } + patternlab.data.brad = { url: "link.twitter-brad" }; + patternlab.data.dave = { url: "link.twitter-dave" }; + patternlab.data.brian = { url: "link.twitter-brian" }; var pattern; @@ -827,7 +746,7 @@ patternlab.data = {link: {}}; patternlab.config = { debug: false }; - var pattern = new object_factory.oPattern('test/files/_patterns/00-test/01-bar.mustache', '00-test', '01-bar.mustache'); + var pattern = new Pattern('00-test/01-bar.mustache'); pattern.extendedTemplate = 'barExtended'; pattern.template = 'bar'; @@ -849,7 +768,7 @@ patternlab.data = {link: {}}; patternlab.config = { debug: false }; - var pattern = new object_factory.oPattern('test/files/_patterns/00-test/01-bar.mustache', '00-test', '01-bar.mustache'); + var pattern = new Pattern('00-test/01-bar.mustache'); pattern.extendedTemplate = undefined; pattern.template = 'bar'; diff --git a/test/pattern_engines_tests.js b/test/pattern_engines_tests.js index 60229b357..f55c28c99 100644 --- a/test/pattern_engines_tests.js +++ b/test/pattern_engines_tests.js @@ -2,12 +2,12 @@ 'use strict'; var patternEngines = require('../core/lib/pattern_engines/pattern_engines'); - var of = require('../core/lib/object_factory'); + var Pattern = require('../core/lib/object_factory').Pattern; // the mustache test pattern, stolen from object_factory unit tests - var mustacheTestPattern = new of.oPattern('source/_patterns/00-atoms/00-global/00-colors-alt.mustache', '00-atoms/00-global', '00-colors-alt.mustache', {d: 123}); - var mustacheTestPseudoPatternBasePattern = new of.oPattern('source/_patterns/04-pages/00-homepage.mustache', '04-pages', '00-homepage.mustache', {d: 123}); - var mustacheTestPseudoPattern = new of.oPattern('source/_patterns/04-pages/00-homepage~emergency.json', '04-pages', '00-homepage-emergency.', {d: 123}); + var mustacheTestPattern = new Pattern('source/_patterns/00-atoms/00-global/00-colors-alt.mustache', {d: 123}); + var mustacheTestPseudoPatternBasePattern = new Pattern('source/_patterns/04-pages/00-homepage.mustache', {d: 123}); + var mustacheTestPseudoPattern = new Pattern('source/_patterns/04-pages/00-homepage~emergency.json', {d: 123}); mustacheTestPseudoPattern.isPseudoPattern = true; mustacheTestPseudoPattern.basePattern = mustacheTestPseudoPatternBasePattern; var engineNames = Object.keys(patternEngines); @@ -26,7 +26,7 @@ }, 'getEngineNameForPattern returns "mustache" for an artificial empty template': function (test) { test.expect(1); - var emptyPattern = of.oPattern.createEmpty(); + var emptyPattern = Pattern.createEmpty(); test.equals(patternEngines.getEngineNameForPattern(emptyPattern), 'mustache'); test.done(); }, diff --git a/test/pseudopattern_hunter_tests.js b/test/pseudopattern_hunter_tests.js index b7d793a9b..a21b5565e 100644 --- a/test/pseudopattern_hunter_tests.js +++ b/test/pseudopattern_hunter_tests.js @@ -1,51 +1,49 @@ -(function () { - "use strict"; - - var pha = require('../core/lib/pseudopattern_hunter'); - var pa = require('../core/lib/pattern_assembler'); - var object_factory = require('../core/lib/object_factory'); - - exports['pseudopattern_hunter'] = { - 'pseudpattern found and added as a pattern' : function(test){ - //arrange - var fs = require('fs-extra'); - var pattern_assembler = new pa(); - var pseudopattern_hunter = new pha(); - var patterns_dir = './test/files/_patterns/'; - - var pl = {}; - pl.config = { - paths: { - source: { - patterns: patterns_dir - } +"use strict"; + +var pha = require('../core/lib/pseudopattern_hunter'); +var pa = require('../core/lib/pattern_assembler'); +var Pattern = require('../core/lib/object_factory').Pattern; + +exports['pseudopattern_hunter'] = { + 'pseudpattern found and added as a pattern' : function (test) { + //arrange + var fs = require('fs-extra'); + var pattern_assembler = new pa(); + var pseudopattern_hunter = new pha(); + var patterns_dir = './test/files/_patterns/'; + + var pl = {}; + pl.config = { + paths: { + source: { + patterns: patterns_dir } - }; - pl.data = {}; - pl.data.link = {}; - pl.config.debug = false; - pl.patterns = []; - pl.partials = {}; - pl.config.patternStates = {}; - - var atomPattern = new object_factory.oPattern('test/files/_patterns/00-test/03-styled-atom.mustache', '00-test', '03-styled-atom.mustache'); - atomPattern.template = fs.readFileSync(patterns_dir + '00-test/03-styled-atom.mustache', 'utf8'); - atomPattern.extendedTemplate = atomPattern.template; - atomPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(atomPattern); - - pattern_assembler.addPattern(atomPattern, pl); - - //act - var patternCountBefore = pl.patterns.length; - pseudopattern_hunter.find_pseudopatterns(atomPattern, pl); - - //assert - test.equals(patternCountBefore + 1, pl.patterns.length); - test.equals(pl.patterns[1].patternPartial, 'test-styled-atom-alt'); - test.equals(pl.patterns[1].extendedTemplate.replace(/\s\s+/g, ' ').replace(/\n/g, ' ').trim(), ' {{message}} '); - test.equals(JSON.stringify(pl.patterns[1].jsonFileData), JSON.stringify({"message": "alternateMessage"})); - - test.done(); - } + } + }; + pl.data = {}; + pl.data.link = {}; + pl.config.debug = false; + pl.patterns = []; + pl.partials = {}; + pl.config.patternStates = {}; + + var atomPattern = new Pattern('00-test/03-styled-atom.mustache'); + atomPattern.template = fs.readFileSync(patterns_dir + '00-test/03-styled-atom.mustache', 'utf8'); + atomPattern.extendedTemplate = atomPattern.template; + atomPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(atomPattern); + + pattern_assembler.addPattern(atomPattern, pl); + + //act + var patternCountBefore = pl.patterns.length; + pseudopattern_hunter.find_pseudopatterns(atomPattern, pl); + + //assert + test.equals(patternCountBefore + 1, pl.patterns.length); + test.equals(pl.patterns[1].patternPartial, 'test-styled-atom-alt'); + test.equals(pl.patterns[1].extendedTemplate.replace(/\s\s+/g, ' ').replace(/\n/g, ' ').trim(), ' {{message}} '); + test.equals(JSON.stringify(pl.patterns[1].jsonFileData), JSON.stringify({"message": "alternateMessage"})); + + test.done(); } -}()); +}; From f1f9f7129928fa51d4263aebc84bb0cc24457f6a Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Mon, 23 May 2016 14:47:26 -0500 Subject: [PATCH 132/187] updating dependencies --- package.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 636da7e54..37c277a62 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "./core/lib/patternlab.js", "dependencies": { "diveSync": "^0.3.0", - "fs-extra": "^0.26.2", + "fs-extra": "^0.30.0", "glob": "^7.0.0", "handlebars": "^4.0.5", "html-entities": "^1.2.0", @@ -13,17 +13,17 @@ "markdown-it": "^6.0.1", "matchdep": "^1.0.0", "mustache": "^2.2.0", - "twig": "^0.8.8", + "twig": "^0.9.5", "underscore": "^1.8.3" }, "devDependencies": { "bs-html-injector": "^3.0.0", - "grunt": "~0.4.5", + "grunt": "~1.0.1", "grunt-browser-sync": "^2.2.0", - "grunt-contrib-concat": "^0.5.1", - "grunt-contrib-copy": "^0.8.2", - "grunt-contrib-nodeunit": "^0.4.1", - "grunt-contrib-watch": "^0.6.1", + "grunt-contrib-concat": "^1.0.1", + "grunt-contrib-copy": "^1.0.0", + "grunt-contrib-nodeunit": "^1.0.0", + "grunt-contrib-watch": "^1.0.0", "grunt-eslint": "^18.0.0" }, "keywords": [ From 6695c2c35fc7448a9aafe0bcd66a68d4ef378cd8 Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Wed, 25 May 2016 09:35:37 -0500 Subject: [PATCH 133/187] Annotations Support (#337) * annotations exporter - built with TDD * annotations.md parsing with tests * merge both annotations formats. covers the majority of https://github.com/pattern-lab/edition-node-gulp/issues/12 --- core/lib/annotation_exporter.js | 78 +++++++++++++++++++++++++++++-- package.json | 1 + test/annotation_exporter_tests.js | 69 +++++++++++++++++++++++++++ test/files/annotations.js | 14 ++++++ test/files/annotations.md | 18 +++++++ 5 files changed, 175 insertions(+), 5 deletions(-) create mode 100644 test/annotation_exporter_tests.js create mode 100644 test/files/annotations.js create mode 100644 test/files/annotations.md diff --git a/core/lib/annotation_exporter.js b/core/lib/annotation_exporter.js index 3dcd3963e..570935e88 100644 --- a/core/lib/annotation_exporter.js +++ b/core/lib/annotation_exporter.js @@ -4,15 +4,19 @@ var annotations_exporter = function (pl) { var path = require('path'), fs = require('fs-extra'), JSON5 = require('json5'), + _ = require('lodash'), + md = require('markdown-it')(), paths = pl.config.paths; - // HELPER FUNCTIONS + /* + Returns the array of comments that used to be wrapped in raw JS. + */ function parseAnnotationsJS() { //attempt to read the file try { var oldAnnotations = fs.readFileSync(path.resolve(paths.source.annotations, 'annotations.js'), 'utf8'); } catch (ex) { - console.log(ex, 'This may be expected.'); + console.log(ex, 'annotations.js file missing from ' + paths.source.annotations + '. This may be expected.'); } //parse as JSON by removing the old wrapping js syntax. comments and the trailing semi-colon @@ -23,17 +27,81 @@ var annotations_exporter = function (pl) { console.log('There was an error parsing JSON for ' + paths.source.annotations + 'annotations.js'); console.log(ex); } - return oldAnnotationsJSON; + return oldAnnotationsJSON.comments; + } + + /* + Converts the annotations.md file yaml list into an array of annotations + */ + function parseAnnotationsMD() { + var annotations = []; + + //attempt to read the file + var annotationsMD = ''; + try { + annotationsMD = fs.readFileSync(path.resolve(paths.source.annotations, 'annotations.md'), 'utf8'); + } catch (ex) { + console.log(ex, 'annotations.md file missing from ' + paths.source.annotations + '. This may be expected.'); + } + + //take the annotation snippets and split them on our custom delimiter + var annotationsYAML = annotationsMD.split('~*~'); + for (var i = 0; i < annotationsYAML.length; i++) { + var annotation = {}; + + //for each annotation process the yaml frontmatter and markdown + var annotationSnippet = annotationsYAML[i]; + var annotationsRE = /---\n{1}([\s\S]*)---\n{1}([\s\S]*)+/gm; + var chunks = annotationsRE.exec(annotationSnippet); + if (chunks && chunks[1] && chunks[2]) { + + //convert each yaml frontmatter key into an object key + var frontmatter = chunks[1]; + var frontmatterLines = frontmatter.split(/\n/gm); + for (var j = 0; j < frontmatterLines.length; j++) { + var frontmatterLine = frontmatterLines[j]; + if (frontmatterLine.length > 0) { + var frontmatterLineChunks = frontmatterLine.split(':'); //test this + var frontmatterKey = frontmatterLineChunks[0].toLowerCase().trim(); + var frontmatterValueString = frontmatterLineChunks[1].trim(); + var frontmatterValue = frontmatterValueString.substring(1, frontmatterValueString.length - 1); + if (frontmatterKey === 'el' || frontmatterKey === 'selector') { + annotation.el = frontmatterValue; + } + if (frontmatterKey === 'title') { + annotation.title = frontmatterValue; + } + } + } + + //set the comment to the parsed markdown + var annotationMarkdown = chunks[2]; + annotation.comment = md.render(annotationMarkdown); + + annotations.push(annotation); + } else { + console.log('annotations.md file not formatted as expected. Error parsing frontmatter and markdown out of ' + annotationSnippet); + } + } + return annotations; } function gatherAnnotations() { - //todo: merge markdown too https://github.com/pattern-lab/patternlab-php-core/blob/c2c4bc6a8bda2b2f9c08b197669ebc94c025e7c6/src/PatternLab/Annotations.php - return parseAnnotationsJS(); + var annotationsJS = parseAnnotationsJS(); + var annotationsMD = parseAnnotationsMD(); + var mergedAnnotations = _.unionBy(annotationsJS, annotationsMD, 'el'); + return mergedAnnotations; } return { gather: function () { return gatherAnnotations(); + }, + gatherJS: function () { + return parseAnnotationsJS(); + }, + gatherMD: function () { + return parseAnnotationsMD(); } }; diff --git a/package.json b/package.json index 636da7e54..e0962ff3f 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "handlebars": "^4.0.5", "html-entities": "^1.2.0", "json5": "^0.5.0", + "lodash": "^4.12.0", "markdown-it": "^6.0.1", "matchdep": "^1.0.0", "mustache": "^2.2.0", diff --git a/test/annotation_exporter_tests.js b/test/annotation_exporter_tests.js new file mode 100644 index 000000000..70bbfec06 --- /dev/null +++ b/test/annotation_exporter_tests.js @@ -0,0 +1,69 @@ +"use strict"; + +var eol = require('os').EOL; +var Pattern = require('../core/lib/object_factory').Pattern; +var extend = require('util')._extend; + +function createFakePatternLab(customProps) { + var pl = { + "config": { + "paths": { + "source": { + "annotations": './test/files/' + } + } + } + }; + + return extend(pl, customProps); +} + +var patternlab = createFakePatternLab(); +var ae = require('../core/lib/annotation_exporter')(patternlab); + +exports['annotaton_exporter'] = { + + 'converts old JS annotations into new format': function (test) { + //arrange + //act + var annotations = ae.gatherJS(); + + //assert + test.equals(annotations.length, 2); + test.equals(annotations[1].el, '.logo'); + test.equals(annotations[1].title, 'Logo'); + test.equals(annotations[1].comment, "The logo image is an SVG file, which ensures that the logo displays crisply even on high resolution displays. A PNG fallback is provided for browsers that don't support SVG images.

    Further reading: Optimizing Web Experiences for High Resolution Screens

    "); + + test.done(); + }, + + 'converts new markdown annotations into an array': function (test) { + //arrange + //act + var annotations = ae.gatherMD(); + + //assert + test.equals(annotations.length, 3); + test.equals(annotations[1].el, '.logo'); + test.equals(annotations[1].title, 'Logo'); + test.equals(annotations[1].comment.replace(/\r?\n|\r/gm, ""), '

    The logo image is an SVG file.

    '); + + test.done(); + }, + + 'merges both annotation methods into one array' : function (test) { + //arrange + + //act + var annotations = ae.gather(); + + //assert + test.equals(annotations.length, 3); + test.equals(annotations[2].el, '#nav'); + test.equals(annotations[2].title, 'Navigation'); + test.equals(annotations[2].comment.replace(/\r?\n|\r/gm, ""), '

    Navigation for adaptive web experiences can be tricky. Refer to these repsonsive patterns when evaluating solutions.

    '); + + test.done(); + + } +}; diff --git a/test/files/annotations.js b/test/files/annotations.js new file mode 100644 index 000000000..f1077ed02 --- /dev/null +++ b/test/files/annotations.js @@ -0,0 +1,14 @@ +var comments = { + "comments" : [ + { + "el": "header[role=banner]", + "title" : "Masthead", + "comment": "The main header of the site doesn't take up too much screen real estate in order to keep the focus on the core content. It's using a linear CSS gradient instead of a background image to give greater design flexibility and reduce HTTP requests." + }, + { + "el": ".logo", + "title" : "Logo", + "comment": "The logo image is an SVG file, which ensures that the logo displays crisply even on high resolution displays. A PNG fallback is provided for browsers that don't support SVG images.

    Further reading: Optimizing Web Experiences for High Resolution Screens

    " + } + ] +}; diff --git a/test/files/annotations.md b/test/files/annotations.md new file mode 100644 index 000000000..caea14bab --- /dev/null +++ b/test/files/annotations.md @@ -0,0 +1,18 @@ +--- +el: "header[role=banner]" +title: "Masthead" +--- +The main header of the site doesn't take up *too much screen real estate* in order to keep the focus on the core content. +It's using a linear CSS gradient instead of a background image to give greater design flexibility and reduce HTTP requests. +~*~ +--- +selector: ".logo" +title: "Logo" +--- +The _logo image_ is an SVG file. +~*~ +--- +el: "#nav" +title : "Navigation" +--- +Navigation for adaptive web experiences can be tricky. Refer to [these repsonsive patterns](https://bradfrost.github.io/this-is-responsive/patterns.html#navigation) when evaluating solutions. From a6d419f96d2695bd48ad4a558d0b5a3952f845f0 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Wed, 25 May 2016 10:46:29 -0500 Subject: [PATCH 134/187] gutted most of gruntfile and package.json --- Gruntfile.js | 144 ++---------------------------- core/lib/lineage_hunter.js | 10 --- core/lib/list_item_hunter.js | 10 --- core/lib/media_hunter.js | 10 --- core/lib/object_factory.js | 10 --- core/lib/parameter_hunter.js | 10 --- core/lib/pattern_assembler.js | 11 --- core/lib/pattern_exporter.js | 10 --- core/lib/patternlab.js | 16 ++-- core/lib/patternlab_grunt.js | 10 +-- core/lib/patternlab_gulp.js | 10 +-- core/lib/pseudopattern_hunter.js | 12 +-- core/lib/style_modifier_hunter.js | 10 --- core/lib/ui_builder.js | 10 --- core/lib/utilities.js | 10 +-- package.json | 16 ++-- 16 files changed, 31 insertions(+), 278 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 03349ab4a..2d74d0d19 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,167 +1,41 @@ module.exports = function (grunt) { - var path = require('path'); - - function paths() { - return require('./patternlab-config.json').paths; - } - - // Project configuration. + /****************************** + * Project configuration. + * Should only be needed if you are developing against core, running tests, linting and want to run tests or increment package numbers + *****************************/ grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), concat: { options: { stripBanners: true, - banner: '/* \n * <%= pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy") %> \n * \n * <%= pkg.author %>, and the web community.\n * Licensed under the <%= pkg.license %> license. \n * \n * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. \n *\n */\n\n', + banner: '/* \n * <%= pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy") %> \n * \n * <%= pkg.author.name %>, <%= pkg.contributors[0].name %>, and the web community.\n * Licensed under the <%= pkg.license %> license. \n * \n * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. \n *\n */\n\n', }, patternlab: { src: './core/lib/patternlab.js', dest: './core/lib/patternlab.js' - }, - object_factory: { - src: './core/lib/object_factory.js', - dest: './core/lib/object_factory.js' - }, - lineage: { - src: './core/lib/lineage_hunter.js', - dest: './core/lib/lineage_hunter.js' - }, - media_hunter: { - src: './core/lib/media_hunter.js', - dest: './core/lib/media_hunter.js' - }, - patternlab_grunt: { - src: './core/lib/patternlab_grunt.js', - dest: './core/lib/patternlab_grunt.js' - }, - patternlab_gulp: { - src: './core/lib/patternlab_gulp.js', - dest: './core/lib/patternlab_gulp.js' - }, - parameter_hunter: { - src: './core/lib/parameter_hunter.js', - dest: './core/lib/parameter_hunter.js' - }, - pattern_exporter: { - src: './core/lib/pattern_exporter.js', - dest: './core/lib/pattern_exporter.js' - }, - pattern_assembler: { - src: './core/lib/pattern_assembler.js', - dest: './core/lib/pattern_assembler.js' - }, - pseudopattern_hunter: { - src: './core/lib/pseudopattern_hunter.js', - dest: './core/lib/pseudopattern_hunter.js' - }, - list_item_hunter: { - src: './core/lib/list_item_hunter.js', - dest: './core/lib/list_item_hunter.js' - }, - style_modifier_hunter: { - src: './core/lib/style_modifier_hunter.js', - dest: './core/lib/style_modifier_hunter.js' - } - }, - copy: { - main: { - files: [ - { expand: true, cwd: path.resolve(paths().source.js), src: '*.js', dest: path.resolve(paths().public.js) }, - { expand: true, cwd: path.resolve(paths().source.css), src: '*.css', dest: path.resolve(paths().public.css) }, - { expand: true, cwd: path.resolve(paths().source.images), src: ['**/*.png', '**/*.jpg', '**/*.gif', '**/*.jpeg'], dest: path.resolve(paths().public.images) }, - { expand: true, cwd: path.resolve(paths().source.fonts), src: '*', dest: path.resolve(paths().public.fonts) }, - { expand: true, cwd: path.resolve(paths().source.data), src: 'annotations.js', dest: path.resolve(paths().public.data) } - ] - }, - styleguide: { - files: [ - { expand: true, cwd: path.resolve(paths().source.styleguide), src: ['*.*', '**/*.*'], dest: path.resolve(paths().public.styleguide) } - ] - } - }, - watch: { - all: { - files: [ - path.resolve(paths().source.css + '**/*.css'), - path.resolve(paths().source.styleguide + 'css/*.css'), - path.resolve(paths().source.patterns + '**/*'), - path.resolve(paths().source.fonts + '/*'), - path.resolve(paths().source.images + '/*'), - path.resolve(paths().source.data + '*.json'), - path.resolve(paths().source.js + '/*.js') - ], - tasks: ['default', 'bsReload:css'] } }, nodeunit: { all: ['test/*_tests.js'] }, - browserSync: { - dev: { - options: { - server: path.resolve(paths().public.root), - watchTask: true, - watchOptions: { - ignoreInitial: true, - ignored: '*.html' - }, - snippetOptions: { - // Ignore all HTML files within the templates folder - blacklist: ['/index.html', '/', '/?*'] - }, - plugins: [ - { - module: 'bs-html-injector', - options: { - files: [path.resolve(paths().public.root + '/index.html'), path.resolve(paths().public.styleguide + '/styleguide.html')] - } - } - ], - notify: { - styles: [ - 'display: none', - 'padding: 15px', - 'font-family: sans-serif', - 'position: fixed', - 'font-size: 1em', - 'z-index: 9999', - 'bottom: 0px', - 'right: 0px', - 'border-top-left-radius: 5px', - 'background-color: #1B2032', - 'opacity: 0.4', - 'margin: 0', - 'color: white', - 'text-align: center' - ] - } - } - } - }, eslint: { options: { configFile: './.eslintrc' }, target: ['./core/lib/*'] - }, - bsReload: { - css: path.resolve(paths().public.root + '**/*.css') } }); // load all grunt tasks - require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks); - - //load the patternlab task - require('./core/lib/patternlab_grunt')(grunt); - - grunt.registerTask('default', ['patternlab', 'copy:main', 'copy:styleguide']); + grunt.loadNpmTasks('grunt-contrib-concat'); + grunt.loadNpmTasks('grunt-eslint'); + grunt.loadNpmTasks('grunt-contrib-nodeunit'); //travis CI task grunt.registerTask('travis', ['nodeunit', 'eslint']); - grunt.registerTask('serve', ['patternlab', 'copy:main', 'copy:styleguide', 'browserSync', 'watch:all']); - + //to be run prior to releasing a version grunt.registerTask('build', ['nodeunit', 'eslint', 'concat']); }; diff --git a/core/lib/lineage_hunter.js b/core/lib/lineage_hunter.js index 306adf7c5..2c5fb0112 100644 --- a/core/lib/lineage_hunter.js +++ b/core/lib/lineage_hunter.js @@ -1,13 +1,3 @@ -/* - * patternlab-node - v1.3.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - "use strict"; var lineage_hunter = function () { diff --git a/core/lib/list_item_hunter.js b/core/lib/list_item_hunter.js index bbf69549b..c3aee4d56 100644 --- a/core/lib/list_item_hunter.js +++ b/core/lib/list_item_hunter.js @@ -1,13 +1,3 @@ -/* - * patternlab-node - v1.3.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - "use strict"; var list_item_hunter = function () { diff --git a/core/lib/media_hunter.js b/core/lib/media_hunter.js index c5da7d980..8954df13e 100644 --- a/core/lib/media_hunter.js +++ b/core/lib/media_hunter.js @@ -1,13 +1,3 @@ -/* - * patternlab-node - v1.3.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - "use strict"; var diveSync = require('diveSync'), diff --git a/core/lib/object_factory.js b/core/lib/object_factory.js index 7a38d812d..9be81a5e7 100644 --- a/core/lib/object_factory.js +++ b/core/lib/object_factory.js @@ -1,13 +1,3 @@ -/* - * patternlab-node - v1.3.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - "use strict"; var patternEngines = require('./pattern_engines/pattern_engines'); diff --git a/core/lib/parameter_hunter.js b/core/lib/parameter_hunter.js index ffb41426d..0ae1ebf2f 100644 --- a/core/lib/parameter_hunter.js +++ b/core/lib/parameter_hunter.js @@ -1,13 +1,3 @@ -/* - * patternlab-node - v1.3.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - "use strict"; var parameter_hunter = function () { diff --git a/core/lib/pattern_assembler.js b/core/lib/pattern_assembler.js index 6837dfad8..e3bda0065 100644 --- a/core/lib/pattern_assembler.js +++ b/core/lib/pattern_assembler.js @@ -1,14 +1,3 @@ -/* - * patternlab-node - v1.3.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - - "use strict"; var pattern_assembler = function () { diff --git a/core/lib/pattern_exporter.js b/core/lib/pattern_exporter.js index 4a12c6872..c53768420 100644 --- a/core/lib/pattern_exporter.js +++ b/core/lib/pattern_exporter.js @@ -1,13 +1,3 @@ -/* - * patternlab-node - v1.3.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - "use strict"; var fs = require('fs-extra'); diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index b08cea483..6ef80aaeb 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -1,13 +1,15 @@ -/* - * patternlab-node - v1.3.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. +/* + * patternlab-node - v2.0.0 - 2016 + * + * Brian Muenzenmeyer, Geoff Pursell, and the web community. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ +"use strict"; + var diveSync = require('diveSync'), path = require('path'); diff --git a/core/lib/patternlab_grunt.js b/core/lib/patternlab_grunt.js index adc88f56b..aed8a0aa9 100644 --- a/core/lib/patternlab_grunt.js +++ b/core/lib/patternlab_grunt.js @@ -1,12 +1,4 @@ -/* - * patternlab-node - v1.3.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ +"use strict"; var patternlab_engine = require('./patternlab.js'); diff --git a/core/lib/patternlab_gulp.js b/core/lib/patternlab_gulp.js index 62f4e2eeb..fc8b12736 100644 --- a/core/lib/patternlab_gulp.js +++ b/core/lib/patternlab_gulp.js @@ -1,12 +1,4 @@ -/* - * patternlab-node - v1.3.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ +"use strict"; var patternlab_engine = require('./patternlab.js'); diff --git a/core/lib/pseudopattern_hunter.js b/core/lib/pseudopattern_hunter.js index dd55cb541..c49b93aca 100644 --- a/core/lib/pseudopattern_hunter.js +++ b/core/lib/pseudopattern_hunter.js @@ -1,13 +1,3 @@ -/* - * patternlab-node - v1.3.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - "use strict"; var pseudopattern_hunter = function () { @@ -46,7 +36,7 @@ var pseudopattern_hunter = function () { //extend any existing data with variant data variantFileData = plutils.mergeData(currentPattern.jsonFileData, variantFileData); - + var variantName = pseudoPatterns[i].substring(pseudoPatterns[i].indexOf('~') + 1).split('.')[0]; var variantFilePath = path.join(currentPattern.subdir, currentPattern.fileName + '~' + variantName + '.json'); var patternVariant = Pattern.create(variantFilePath, variantFileData, { diff --git a/core/lib/style_modifier_hunter.js b/core/lib/style_modifier_hunter.js index af916da9b..8c0b7413f 100644 --- a/core/lib/style_modifier_hunter.js +++ b/core/lib/style_modifier_hunter.js @@ -1,13 +1,3 @@ -/* - * patternlab-node - v1.3.0 - 2016 - * - * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - "use strict"; var style_modifier_hunter = function () { diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index df04b793f..33bec31a8 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -1,13 +1,3 @@ -/* - * patternlab-node - v1.2.0 - 2016 - * - * Brian Muenzenmeyer, Geoffrey Pursell, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ - "use strict"; var path = require('path'); diff --git a/core/lib/utilities.js b/core/lib/utilities.js index e5295838b..de37d6a57 100644 --- a/core/lib/utilities.js +++ b/core/lib/utilities.js @@ -1,12 +1,4 @@ -/* - * patternlab-node - v0.14.0 - 2015 - * - * Brian Muenzenmeyer, Geoffrey Pursell and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. - * - */ +"use strict"; var util = { // http://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array-in-javascript diff --git a/package.json b/package.json index 37c277a62..2e9dfb33d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "patternlab-node", "description": "Pattern Lab is a collection of tools to help you create atomic design systems. This is the node command line interface (CLI).", - "version": "1.3.0", + "version": "2.0.0", "main": "./core/lib/patternlab.js", "dependencies": { "diveSync": "^0.3.0", @@ -11,19 +11,14 @@ "html-entities": "^1.2.0", "json5": "^0.5.0", "markdown-it": "^6.0.1", - "matchdep": "^1.0.0", "mustache": "^2.2.0", "twig": "^0.9.5", "underscore": "^1.8.3" }, "devDependencies": { - "bs-html-injector": "^3.0.0", "grunt": "~1.0.1", - "grunt-browser-sync": "^2.2.0", "grunt-contrib-concat": "^1.0.1", - "grunt-contrib-copy": "^1.0.0", "grunt-contrib-nodeunit": "^1.0.0", - "grunt-contrib-watch": "^1.0.0", "grunt-eslint": "^18.0.0" }, "keywords": [ @@ -39,7 +34,14 @@ "url": "git://github.com/pattern-lab/patternlab-node.git" }, "bugs": "https://github.com/pattern-lab/patternlab-node/issues", - "author": "Brian Muenzenmeyer", + "author": { + "name": "Brian Muenzenmeyer" + }, + "contributors": [ + { + "name" : "Geoff Pursell" + } + ], "license": "MIT", "scripts": { "test": "grunt travis --verbose" From 8d62ca3c990bc7d50e23f9979241bbe5f13e6bfd Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Wed, 25 May 2016 11:03:51 -0500 Subject: [PATCH 135/187] moved head and foot management code be more explicit with lodash, which added a method we want in 4.13 --- core/lib/patternlab.js | 15 +++++++-------- package.json | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 6ef80aaeb..13e19f19d 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -181,23 +181,21 @@ var patternlab_engine = function (config) { //set user defined head and foot if they exist try { - patternlab.userHead = pattern_assembler.findPartial('atoms-_00-head', patternlab); - patternlab.userHead.extendedTemplate = patternlab.userHead.template; + patternlab.userHead = fs.readFileSync(path.resolve(paths.source.root, '_meta', '_00-head.mustache'), 'utf8'); } catch (ex) { if (patternlab.config.debug) { console.log(ex); - console.log('Could not find optional user-defined header, atoms-head pattern. It was likely deleted.'); + console.log('Could not find optional user-defined header, usually found at ./source/_meta/_001-head.mustache. It was likely deleted.'); } } try { - patternlab.userFoot = pattern_assembler.findPartial('atoms-_01-foot', patternlab); - patternlab.userFoot.extendedTemplate = patternlab.userFoot.template; + patternlab.userFoot = fs.readFileSync(path.resolve(paths.source.root, '_meta', '_01-foot.mustache'), 'utf8'); } catch (ex) { if (patternlab.config.debug) { console.log(ex); - console.log('Could not find optional user-defined footer, atoms-foot pattern. It was likely deleted.'); + console.log('Could not find optional user-defined footer, usually found at ./source/_meta/_01-foot.mustache. It was likely deleted.'); } } @@ -216,7 +214,7 @@ var patternlab_engine = function (config) { //set pattern-specific header if necessary var head; if (patternlab.userHead) { - head = patternlab.userHead.extendedTemplate.replace('{% pattern-lab-head %}', patternlab.header); + head = patternlab.userHead.replace('{% pattern-lab-head %}', patternlab.header); } else { head = patternlab.header; } @@ -247,7 +245,8 @@ var patternlab_engine = function (config) { console.log(err); } allData = plutils.mergeData(allData, pattern.jsonFileData); - var headHTML = pattern_assembler.renderPattern(patternlab.userHead, allData); + //var headHTML = pattern_assembler.renderPattern(patternlab.userHead, allData); + var headHTML = pattern_assembler.renderPattern(pattern.header, allData); //render the extendedTemplate with all data pattern.patternPartialCode = pattern_assembler.renderPattern(pattern, allData); diff --git a/package.json b/package.json index 6ded224b3..68f266994 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "handlebars": "^4.0.5", "html-entities": "^1.2.0", "json5": "^0.5.0", - "lodash": "^4.12.0", + "lodash": "~4.13.0", "markdown-it": "^6.0.1", "mustache": "^2.2.0", "twig": "^0.9.5", From 86d07839ab535a15db33fadd92b0a8a00907224e Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Wed, 25 May 2016 11:20:29 -0500 Subject: [PATCH 136/187] playing with travis ci webhook to gitter --- .travis.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.travis.yml b/.travis.yml index 71e746f02..5e578009b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,3 +18,10 @@ branches: - dev - pattern-engines - dev-2.0-core +notifications: + webhooks: + urls: + - https://webhooks.gitter.im/e/a14f537f16b0756d9470 + on_success: always + on_failure: always + on_start: never From b54387a0e2364ca6f4385fe64bae4d4a8da1e81d Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Wed, 25 May 2016 11:37:15 -0500 Subject: [PATCH 137/187] bumping node engine support --- .travis.yml | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5e578009b..ed3078720 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,9 +2,8 @@ language: node_js node_js: - stable + - 5.0 - 4.0 - - 0.12 - - 0.11 before_install: - phantomjs --version @@ -18,6 +17,7 @@ branches: - dev - pattern-engines - dev-2.0-core + notifications: webhooks: urls: diff --git a/package.json b/package.json index 68f266994..2db78d1af 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,6 @@ "test": "grunt travis --verbose" }, "engines": { - "node": ">=0.1" + "node": ">=4.0" } } From 57c0703c1e43d30a6b882de0c40d023e25cacc6d Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Wed, 25 May 2016 11:59:29 -0500 Subject: [PATCH 138/187] attempt to fix hardcoded path in media_hunter call --- core/lib/ui_builder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index 33bec31a8..0fb7e6ee2 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -355,7 +355,7 @@ function buildFrontEnd(patternlab) { patternlab.patterns = sortPatterns(patternlab.patterns); //find mediaQueries - media_hunter.find_media_queries('./source/css', patternlab); + media_hunter.find_media_queries(path.resolve(paths.source.css), patternlab); // check if patterns are excluded, if not add them to styleguidePatterns styleguidePatterns = assembleStyleguidePatterns(patternlab); From 934345d3b36d7262990bfe14eacd580c84a6044f Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Wed, 25 May 2016 11:59:59 -0500 Subject: [PATCH 139/187] still seeing intermitent lodash problems. explicit version dep. alter regex to account for possible /r/n --- core/lib/annotation_exporter.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/lib/annotation_exporter.js b/core/lib/annotation_exporter.js index 570935e88..491056aa1 100644 --- a/core/lib/annotation_exporter.js +++ b/core/lib/annotation_exporter.js @@ -51,7 +51,7 @@ var annotations_exporter = function (pl) { //for each annotation process the yaml frontmatter and markdown var annotationSnippet = annotationsYAML[i]; - var annotationsRE = /---\n{1}([\s\S]*)---\n{1}([\s\S]*)+/gm; + var annotationsRE = /---\r?\n{1}([\s\S]*)---\r?\n{1}([\s\S]*)+/gm; var chunks = annotationsRE.exec(annotationSnippet); if (chunks && chunks[1] && chunks[2]) { diff --git a/package.json b/package.json index 2db78d1af..54994c78a 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "handlebars": "^4.0.5", "html-entities": "^1.2.0", "json5": "^0.5.0", - "lodash": "~4.13.0", + "lodash": "~4.13.1", "markdown-it": "^6.0.1", "mustache": "^2.2.0", "twig": "^0.9.5", From b6e921c7cf8a38ef05fd981d69b3f8d844a9e3c7 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Wed, 25 May 2016 12:31:51 -0500 Subject: [PATCH 140/187] stubbed file --- core/lib/starterkit_manager.js | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 core/lib/starterkit_manager.js diff --git a/core/lib/starterkit_manager.js b/core/lib/starterkit_manager.js new file mode 100644 index 000000000..7abfaa7c2 --- /dev/null +++ b/core/lib/starterkit_manager.js @@ -0,0 +1,36 @@ +"use strict"; + +var starterkit_manager = function (pl) { + var path = require('path'), + fs = require('fs-extra'), + JSON5 = require('json5'), + _ = require('lodash'), + paths = pl.config.paths; + + function loadStarterKit(starterkitName) { + + } + + function listStarterkits() { + + } + + function packStarterkit() { + + } + + return { + load_starterkit: function (starterkitName) { + loadStarterKit(starterkitName); + }, + list_starterkits: function () { + listStarterkits(); + }, + pack_starterkit: function () { + packStarterkit(); + } + }; + +}; + +module.exports = starterkit_manager; From 5071ac9778d2f522daa8eeed36ebd236de184f0d Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Wed, 25 May 2016 12:47:14 -0500 Subject: [PATCH 141/187] console.log out the current list --- core/lib/starterkit_manager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/lib/starterkit_manager.js b/core/lib/starterkit_manager.js index 7abfaa7c2..343b9e51b 100644 --- a/core/lib/starterkit_manager.js +++ b/core/lib/starterkit_manager.js @@ -12,7 +12,7 @@ var starterkit_manager = function (pl) { } function listStarterkits() { - + console.log('https://github.com/search?utf8=%E2%9C%93&q=starterkit+in%3Aname%2C+user%3Apattern-lab&type=Repositories&ref=searchresults'); } function packStarterkit() { From a983189e29e67e787fa497b3faf108c3d0ebb3b7 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Fri, 27 May 2016 15:05:26 -0500 Subject: [PATCH 142/187] add patternengine-node-mustache as a dependency --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 54994c78a..de52879d8 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "markdown-it": "^6.0.1", "mustache": "^2.2.0", "twig": "^0.9.5", - "underscore": "^1.8.3" + "underscore": "^1.8.3", + "patternengine-node-mustache": "^0.0.1" }, "devDependencies": { "grunt": "~1.0.1", From c84e70cb9807b03ddb47c7013c06aaa81b004647 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sat, 28 May 2016 06:22:07 -0500 Subject: [PATCH 143/187] fix pathing issue in version command --- core/lib/patternlab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 13e19f19d..7204eaf41 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -77,7 +77,7 @@ var patternlab_engine = function (config) { plutils = require('./utilities'), patternlab = {}; - patternlab.package = fs.readJSONSync('./package.json'); + patternlab.package = fs.readJSONSync(path.resolve(__dirname, '../../package.json')); patternlab.config = config || fs.readJSONSync(path.resolve(__dirname, '../../patternlab-config.json')); var paths = patternlab.config.paths; From 63a89ea5454770f94e607ab74226652603766772 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sat, 28 May 2016 06:54:29 -0500 Subject: [PATCH 144/187] core side of starterkit list wiring --- core/lib/patternlab.js | 22 ++++++++++++++-------- core/lib/starterkit_manager.js | 8 ++++++++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 7204eaf41..6b0b7f0de 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -1,10 +1,10 @@ -/* - * patternlab-node - v2.0.0 - 2016 - * +/* + * patternlab-node - v2.0.0 - 2016 + * * Brian Muenzenmeyer, Geoff Pursell, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ @@ -75,6 +75,7 @@ var patternlab_engine = function (config) { buildFrontEnd = require('./ui_builder'), he = require('html-entities').AllHtmlEntities, plutils = require('./utilities'), + sm = require('./starterkit_manager'), patternlab = {}; patternlab.package = fs.readJSONSync(path.resolve(__dirname, '../../package.json')); @@ -82,7 +83,6 @@ var patternlab_engine = function (config) { var paths = patternlab.config.paths; - function getVersion() { console.log(patternlab.package.version); } @@ -132,7 +132,10 @@ var patternlab_engine = function (config) { } } - + function listStarterkits() { + var starterkit_manager = new sm(patternlab); + return starterkit_manager.list_starterkits(); + } function buildPatterns(deletePatternDir) { try { @@ -313,6 +316,9 @@ var patternlab_engine = function (config) { build_patterns_only: function (deletePatternDir) { buildPatterns(deletePatternDir); printDebug(); + }, + list_starterkits: function () { + return listStarterkits(); } }; }; diff --git a/core/lib/starterkit_manager.js b/core/lib/starterkit_manager.js index 343b9e51b..043d6caaf 100644 --- a/core/lib/starterkit_manager.js +++ b/core/lib/starterkit_manager.js @@ -8,6 +8,14 @@ var starterkit_manager = function (pl) { paths = pl.config.paths; function loadStarterKit(starterkitName) { + try { + var kit = require(starterkitName); + } catch (ex) { + console.log(ex); + console.log(starterkitName + ' not found, please use npm to install it first'); + } + console.log(kit); + } From 94a10758d619e8cca6084dbc9a64c423a685d54b Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sat, 28 May 2016 06:57:32 -0500 Subject: [PATCH 145/187] wiring up load kit --- core/lib/patternlab.js | 8 ++++++++ core/lib/starterkit_manager.js | 2 -- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 6b0b7f0de..07d773d82 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -137,6 +137,11 @@ var patternlab_engine = function (config) { return starterkit_manager.list_starterkits(); } + function loadStarterKit(starterkitName) { + var starterkit_manager = new sm(patternlab); + starterkit_manager.load_starterkit(starterkitName); + } + function buildPatterns(deletePatternDir) { try { patternlab.data = fs.readJSONSync(path.resolve(paths.source.data, 'data.json')); @@ -319,6 +324,9 @@ var patternlab_engine = function (config) { }, list_starterkits: function () { return listStarterkits(); + }, + load_starterkit: function (starterkitName) { + loadStarterKit(starterkitName); } }; }; diff --git a/core/lib/starterkit_manager.js b/core/lib/starterkit_manager.js index 043d6caaf..c9fe76016 100644 --- a/core/lib/starterkit_manager.js +++ b/core/lib/starterkit_manager.js @@ -15,8 +15,6 @@ var starterkit_manager = function (pl) { console.log(starterkitName + ' not found, please use npm to install it first'); } console.log(kit); - - } function listStarterkits() { From df8d1759f0d828230646865b8271c2582d8d0e2e Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sat, 28 May 2016 11:51:32 -0500 Subject: [PATCH 146/187] rudimentary starterkit support --- core/lib/starterkit_manager.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/core/lib/starterkit_manager.js b/core/lib/starterkit_manager.js index c9fe76016..7b604d45b 100644 --- a/core/lib/starterkit_manager.js +++ b/core/lib/starterkit_manager.js @@ -9,12 +9,26 @@ var starterkit_manager = function (pl) { function loadStarterKit(starterkitName) { try { - var kit = require(starterkitName); + var kitPath = path.resolve( + path.join(process.cwd(), 'node_modules', starterkitName, pl.config.starterkitSubDir) + ); + var kitPathDirExists = fs.statSync(kitPath).isDirectory(); + if (kitPathDirExists) { + + //todo check and prompt user is paths().source is not empty + + fs.copy(kitPath, paths.source.root, function(ex) { + if (ex) { + console.error(ex); + } + console.log('starterkit ' + starterkitName + ' loaded successfully.'); + }); + + } } catch (ex) { console.log(ex); console.log(starterkitName + ' not found, please use npm to install it first'); } - console.log(kit); } function listStarterkits() { From 2028f1f722586aa0653db7a662d11e834d58d4e5 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sat, 28 May 2016 12:24:39 -0500 Subject: [PATCH 147/187] remove angry error message output when caught gracefully --- core/lib/annotation_exporter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/lib/annotation_exporter.js b/core/lib/annotation_exporter.js index 491056aa1..879922554 100644 --- a/core/lib/annotation_exporter.js +++ b/core/lib/annotation_exporter.js @@ -16,7 +16,7 @@ var annotations_exporter = function (pl) { try { var oldAnnotations = fs.readFileSync(path.resolve(paths.source.annotations, 'annotations.js'), 'utf8'); } catch (ex) { - console.log(ex, 'annotations.js file missing from ' + paths.source.annotations + '. This may be expected.'); + console.log('annotations.js file missing from ' + paths.source.annotations + '. This may be expected.'); } //parse as JSON by removing the old wrapping js syntax. comments and the trailing semi-colon @@ -41,7 +41,7 @@ var annotations_exporter = function (pl) { try { annotationsMD = fs.readFileSync(path.resolve(paths.source.annotations, 'annotations.md'), 'utf8'); } catch (ex) { - console.log(ex, 'annotations.md file missing from ' + paths.source.annotations + '. This may be expected.'); + console.log('annotations.md file missing from ' + paths.source.annotations + '. This may be expected.'); } //take the annotation snippets and split them on our custom delimiter From 9975fc8e0bdf08949c42f31f99a97b8f90644f82 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sat, 28 May 2016 15:08:07 -0500 Subject: [PATCH 148/187] no need to encode these files anymore --- core/lib/patternlab.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 07d773d82..85244a708 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -258,6 +258,7 @@ var patternlab_engine = function (config) { //render the extendedTemplate with all data pattern.patternPartialCode = pattern_assembler.renderPattern(pattern, allData); + //todo see if this is still needed pattern.patternPartialCodeE = entity_encoder.encode(pattern.patternPartialCode); // stringify this data for individual pattern rendering and use on the styleguide @@ -296,10 +297,10 @@ var patternlab_engine = function (config) { fs.outputFileSync(paths.public.patterns + pattern.patternLink, patternPage); //write the mustache file too - fs.outputFileSync(paths.public.patterns + pattern.patternLink.replace('.html', '.mustache'), entity_encoder.encode(pattern.template)); + fs.outputFileSync(paths.public.patterns + pattern.patternLink.replace('.html', pattern.fileExtension), pattern.template); //write the encoded version too - fs.outputFileSync(paths.public.patterns + pattern.patternLink.replace('.html', '.escaped.html'), entity_encoder.encode(patternPage)); + fs.outputFileSync(paths.public.patterns + pattern.patternLink.replace('.html', '.markup-only.html'), pattern.patternPartialCode); }); //export patterns if necessary From 8778a938c9f6e59e6ffe1bba1905ab20c808ec12 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Wed, 1 Jun 2016 09:19:54 -0500 Subject: [PATCH 149/187] delete old grunt and gulp task files, having replaced them with editions https://github.com/pattern-lab/edition-node-gulp/issues/2 --- core/lib/patternlab_grunt.js | 30 ------------------------------ core/lib/patternlab_gulp.js | 27 --------------------------- 2 files changed, 57 deletions(-) delete mode 100644 core/lib/patternlab_grunt.js delete mode 100644 core/lib/patternlab_gulp.js diff --git a/core/lib/patternlab_grunt.js b/core/lib/patternlab_grunt.js deleted file mode 100644 index aed8a0aa9..000000000 --- a/core/lib/patternlab_grunt.js +++ /dev/null @@ -1,30 +0,0 @@ -"use strict"; - -var patternlab_engine = require('./patternlab.js'); - -module.exports = function (grunt) { - grunt.registerTask('patternlab', 'create design systems with atomic design', function (arg) { - var patternlab = patternlab_engine(); - - if (arguments.length === 0) { - patternlab.build(true); - } - - if (arg && arg === 'v') { - patternlab.version(); - } - - if (arg && arg === "only_patterns") { - patternlab.build_patterns_only(true); - } - - if (arg && arg === "help") { - patternlab.help(); - } - - if (arg && (arg !== "v" && arg !== "only_patterns" && arg !== "help")) { - patternlab.help(); - } - }); - -}; diff --git a/core/lib/patternlab_gulp.js b/core/lib/patternlab_gulp.js deleted file mode 100644 index fc8b12736..000000000 --- a/core/lib/patternlab_gulp.js +++ /dev/null @@ -1,27 +0,0 @@ -"use strict"; - -var patternlab_engine = require('./patternlab.js'); - -module.exports = function (gulp) { - - gulp.task('patternlab', ['clean'], function (cb) { - var patternlab = patternlab_engine(); - patternlab.build(false); - cb(); - }); - - gulp.task('patternlab:version', function () { - var patternlab = patternlab_engine(); - patternlab.version(); - }); - - gulp.task('patternlab:only_patterns', ['clean'], function () { - var patternlab = patternlab_engine(); - patternlab.build_patterns_only(false); - }); - - gulp.task('patternlab:help', function () { - var patternlab = patternlab_engine(); - patternlab.help(); - }); -}; From 3aaf422cba7e2bf118ca3407e730d9e339d85219 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Wed, 1 Jun 2016 16:46:58 -0500 Subject: [PATCH 150/187] Load engines flexibly from either the current directory's node_modules or the core's --- core/lib/pattern_engines.js | 85 ++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 35 deletions(-) diff --git a/core/lib/pattern_engines.js b/core/lib/pattern_engines.js index ff74accaf..acfe5f9db 100644 --- a/core/lib/pattern_engines.js +++ b/core/lib/pattern_engines.js @@ -13,14 +13,23 @@ var path = require('path'); var diveSync = require('diveSync'); var engineMatcher = /^patternengine-node-(.*)$/; -var enginesDirectory = path.join(process.cwd(), 'node_modules'); +var enginesDirectories = [ + { + displayName: 'the core', + path: path.resolve(__dirname, '..', '..', 'node_modules') + }, + { + displayName: 'the edition or test directory', + path: path.join(process.cwd(), 'node_modules') + } +]; var PatternEngines; // the main export object var engineNameForExtension; // generated mapping of extension to engine name // free "private" functions, for internal setup only -// given a path: return the engine name is the path points to a valid engine +// given a path: return the engine name if the path points to a valid engine // module directory, or false if it doesn't function isEngineModule(filePath) { var baseName = path.basename(filePath); @@ -30,54 +39,64 @@ function isEngineModule(filePath) { return false; } -function getEngineModulePath(engineName) { - return path.resolve(enginesDirectory, "patternengine-node-" + engineName); -} - -// go find the names of all found engines -function findSupportedPatternEngineNames() { - var foundPatternEngineNames = []; +function findEngineModulesInDirectory(dir) { + var foundEngines = []; - // iterate over module directory and build a list of available pattern engine - // names - diveSync(enginesDirectory, { + diveSync(dir, { recursive: false, directories: true }, function (err, filePath) { if (err) { throw err; } var foundEngineName = isEngineModule(filePath); if (foundEngineName) { - foundPatternEngineNames.push(foundEngineName); + foundEngines.push({ + name: foundEngineName, + modulePath: filePath + }); } }); - return foundPatternEngineNames; + return foundEngines; } - -// try to load all supported engines +// Try to load engines! We scan for engines at each path specified above. This +// function is kind of a big deal. function loadAllEngines(enginesObject) { console.log('\nLoading engines...'); - enginesObject.supportedPatternEngineNames.forEach(function (engineName) { - var notLoaded = false; - - try { - enginesObject[engineName] = require(getEngineModulePath(engineName)); - } catch (err) { - // Handle errors loading each pattern engine. This will usually be - // because the engine's renderer hasn't been installed by the end user - // -- we don't include any of them (except mustache) by default as - // depedencies in package.json. - notLoaded = (err.code === 'MODULE_NOT_FOUND'); - } finally { - console.log('-', engineName, 'engine:', - notLoaded ? 'renderer not installed; engine disabled' : 'good to go'); - } + enginesDirectories.forEach(function (engineDirectory) { + var enginesInThisDir = findEngineModulesInDirectory(engineDirectory.path); + console.log("...scanning for engines in", engineDirectory.displayName + "..."); + + // find all engine-named things in this directory and try to load them, + // unless it's already been loaded. + enginesInThisDir.forEach(function (engineDiscovery) { + var errorMessage; + var successMessage = "good to go"; + + try { + // give it a try! load 'er up. But not if we already have, of course. + if (enginesObject[engineDiscovery.name]) { + throw new Error("already loaded, skipping."); + } + enginesObject[engineDiscovery.name] = require(engineDiscovery.modulePath); + } catch (err) { + errorMessage = err.message; + } finally { + // report on the status of the engine, one way or another! + console.log('-', engineDiscovery.name, 'engine:', errorMessage ? errorMessage : successMessage); + } + }); }); + + // Complain if for some reason we haven't loaded any engines. + if (Object.keys(enginesObject).length === 0) { + throw new Error('No engines loaded! Something is seriously wrong.'); + } console.log('...done loading engines.\n'); } + // produce a mapping between file extension and engine name for each of the // loaded engines function createFileExtensionToEngineNameMap(enginesObject) { @@ -108,10 +127,6 @@ function createFileExtensionToEngineNameMap(enginesObject) { // methods and properites below should therefore be on its prototype. PatternEngines = Object.create({ - // build the list of supported pattern engines based on what plugins we have - // in the pattern_engines directory - supportedPatternEngineNames: findSupportedPatternEngineNames(), - getEngineNameForPattern: function (pattern) { // avoid circular dependency by putting this in here. TODO: is this slow? var of = require('./object_factory'); From 689337a2b7c9abe7f09223db652fca57732e012c Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Fri, 3 Jun 2016 04:46:47 -0500 Subject: [PATCH 151/187] fix some eslint warnings --- core/lib/pattern_assembler.js | 1 + core/lib/patternlab.js | 2 ++ core/lib/starterkit_manager.js | 4 +--- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/core/lib/pattern_assembler.js b/core/lib/pattern_assembler.js index 69dca7835..f24a03141 100644 --- a/core/lib/pattern_assembler.js +++ b/core/lib/pattern_assembler.js @@ -234,6 +234,7 @@ var pattern_assembler = function () { // the template and replace their calls in this template with rendered // results if (currentPattern.engine.expandPartials && (foundPatternPartials !== null && foundPatternPartials.length > 0)) { + // eslint-disable-next-line expandPartials(foundPatternPartials, list_item_hunter, patternlab, currentPattern); // update the extendedTemplate in the partials object in case this diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 85244a708..effbbd13d 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -253,11 +253,13 @@ var patternlab_engine = function (config) { console.log(err); } allData = plutils.mergeData(allData, pattern.jsonFileData); + //var headHTML = pattern_assembler.renderPattern(patternlab.userHead, allData); var headHTML = pattern_assembler.renderPattern(pattern.header, allData); //render the extendedTemplate with all data pattern.patternPartialCode = pattern_assembler.renderPattern(pattern, allData); + //todo see if this is still needed pattern.patternPartialCodeE = entity_encoder.encode(pattern.patternPartialCode); diff --git a/core/lib/starterkit_manager.js b/core/lib/starterkit_manager.js index 7b604d45b..caffc9c55 100644 --- a/core/lib/starterkit_manager.js +++ b/core/lib/starterkit_manager.js @@ -3,8 +3,6 @@ var starterkit_manager = function (pl) { var path = require('path'), fs = require('fs-extra'), - JSON5 = require('json5'), - _ = require('lodash'), paths = pl.config.paths; function loadStarterKit(starterkitName) { @@ -17,7 +15,7 @@ var starterkit_manager = function (pl) { //todo check and prompt user is paths().source is not empty - fs.copy(kitPath, paths.source.root, function(ex) { + fs.copy(kitPath, paths.source.root, function (ex) { if (ex) { console.error(ex); } From c87cdfc621e080af59aadf6449611168c536b8c0 Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Fri, 3 Jun 2016 08:17:05 -0500 Subject: [PATCH 152/187] move isPattern declaration to the proper data level closes https://github.com/pattern-lab/edition-node-gulp/issues/12 and https://github.com/pattern-lab/edition-node-gulp/issues/13 --- core/lib/patternlab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index effbbd13d..a1d73f268 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -266,7 +266,6 @@ var patternlab_engine = function (config) { // stringify this data for individual pattern rendering and use on the styleguide // see if patternData really needs these other duped values pattern.patternData = JSON.stringify({ - isPattern: true, cssEnabled: false, patternLineageExists: pattern.patternLineageExists, patternLineages: pattern.patternLineages, @@ -286,6 +285,7 @@ var patternlab_engine = function (config) { //set the pattern-specific footer by compiling the general-footer with data, and then adding it to the meta footer var footerPartial = pattern_assembler.renderPattern(patternlab.footer, { + isPattern: true, patternData: pattern.patternData, cacheBuster: patternlab.cacheBuster }); From 452748c24e1de20ea35b12ec932a033a9f90295a Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Fri, 3 Jun 2016 08:57:03 -0500 Subject: [PATCH 153/187] refactor patternName per styleguidekit-mustache-default key mismatch closes https://github.com/pattern-lab/edition-node-gulp/issues/15 --- core/lib/list_item_hunter.js | 2 +- core/lib/object_factory.js | 6 +++--- core/lib/pattern_assembler.js | 2 +- core/lib/patternlab.js | 2 +- core/lib/ui_builder.js | 2 +- test/lineage_hunter_tests.js | 22 +++++++++++----------- test/object_factory_tests.js | 18 ++++++------------ test/parameter_hunter_tests.js | 4 ++-- 8 files changed, 26 insertions(+), 32 deletions(-) diff --git a/core/lib/list_item_hunter.js b/core/lib/list_item_hunter.js index c3aee4d56..e8d278609 100644 --- a/core/lib/list_item_hunter.js +++ b/core/lib/list_item_hunter.js @@ -34,7 +34,7 @@ var list_item_hunter = function () { var repeatedBlockHtml = ''; for (var i = 0; i < items.indexOf(loopNumberString); i++) { if (patternlab.config.debug) { - console.log('list item(s) in pattern', pattern.patternName, 'adding', patternBlock, 'to repeatedBlockTemplate'); + console.log('list item(s) in pattern', pattern.patternPartial, 'adding', patternBlock, 'to repeatedBlockTemplate'); } repeatedBlockTemplate.push(patternBlock); } diff --git a/core/lib/object_factory.js b/core/lib/object_factory.js index e0ffeb41c..7dad7637d 100644 --- a/core/lib/object_factory.js +++ b/core/lib/object_factory.js @@ -22,10 +22,10 @@ var Pattern = function (relPath, data) { this.jsonFileData = data || {}; // strip leading "00-" from the file name and flip tildes to dashes - this.patternName = this.fileName.replace(/^\d*\-/, '').replace('~', '-'); // 'colors' + this.patternBaseName = this.fileName.replace(/^\d*\-/, '').replace('~', '-'); // 'colors' // Fancy name. No idea how this works. 'Colors' - this.patternDisplayName = this.patternName.split('-').reduce(function (val, working) { + this.patternName = this.patternBaseName.split('-').reduce(function (val, working) { return val.charAt(0).toUpperCase() + val.slice(1) + ' ' + working.charAt(0).toUpperCase() + working.slice(1); }, '').trim(); //this is the display name for the ui. strip numeric + hyphen prefixes @@ -44,7 +44,7 @@ var Pattern = function (relPath, data) { // The canonical "key" by which this pattern is known. This is the callable // name of the pattern. UPDATE: this.key is now known as this.patternPartial - this.patternPartial = this.patternGroup + '-' + this.patternName; + this.patternPartial = this.patternGroup + '-' + this.patternBaseName; this.template = ''; this.patternPartialCode = ''; diff --git a/core/lib/pattern_assembler.js b/core/lib/pattern_assembler.js index f24a03141..3fcedf2e8 100644 --- a/core/lib/pattern_assembler.js +++ b/core/lib/pattern_assembler.js @@ -76,7 +76,7 @@ var pattern_assembler = function () { function addPattern(pattern, patternlab) { //add the link to the global object - patternlab.data.link[pattern.patternGroup + '-' + pattern.patternName] = '/patterns/' + pattern.patternLink; + patternlab.data.link[pattern.patternGroup + '-' + pattern.patternBaseName] = '/patterns/' + pattern.patternLink; //only push to array if the array doesn't contain this pattern var isNew = true; diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index a1d73f268..88d0c6a81 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -275,7 +275,7 @@ var patternlab_engine = function (config) { lineageR: pattern.patternLineagesR, patternLineageEExists: pattern.patternLineageExists || pattern.patternLineageRExists, patternDesc: pattern.patternDescExists ? pattern.patternDesc : '', - patternBreadcrumb: 'TODO', + patternBreadcrumb: pattern.patternGroup, patternExtension: pattern.fileExtension, patternName: pattern.patternName, patternPartial: pattern.patternPartial, diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index 0fb7e6ee2..f2f548066 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -11,7 +11,7 @@ var eol = require('os').EOL; function addToPatternPaths(patternlab, patternTypeName, pattern) { //this is messy, could use a refactor. - patternlab.patternPaths[patternTypeName][pattern.patternName] = pattern.subdir.replace(/\\/g, '/') + "/" + pattern.fileName; + patternlab.patternPaths[patternTypeName][pattern.patternBaseName] = pattern.subdir.replace(/\\/g, '/') + "/" + pattern.fileName; } //todo: refactor this as a method on the pattern object itself once we merge dev with pattern-engines branch diff --git a/test/lineage_hunter_tests.js b/test/lineage_hunter_tests.js index cb9a70251..1d2fa941f 100644 --- a/test/lineage_hunter_tests.js +++ b/test/lineage_hunter_tests.js @@ -61,7 +61,7 @@ exports['lineage hunter '] = { "data": null, "template": "\"Logo", "patternPartialCode": "\"Logo", - "patternName": "logo", + "patternBaseName": "logo", "patternLink": "00-atoms-03-images-00-logo/00-atoms-03-images-00-logo.html", "patternGroup": "atoms", "patternSubGroup": "atoms\\03-images", @@ -80,7 +80,7 @@ exports['lineage hunter '] = { "data": null, "template": "\r\n", "patternPartialCode": "\r\n", - "patternName": "primary-nav", + "patternBaseName": "primary-nav", "patternLink": "01-molecules-05-navigation-00-primary-nav/01-molecules-05-navigation-00-primary-nav.html", "patternGroup": "molecules", "patternSubGroup": "molecules\\05-navigation", @@ -99,7 +99,7 @@ exports['lineage hunter '] = { "data": null, "template": "
    \r\n
    \r\n\t Search\r\n\t \r\n\t \r\n\t \r\n
    \r\n
    ", "patternPartialCode": "
    \r\n
    \r\n\t Search\r\n\t \r\n\t \r\n\t \r\n
    \r\n
    ", - "patternName": "search", + "patternBaseName": "search", "patternLink": "01-molecules-04-forms-00-search/01-molecules-04-forms-00-search.html", "patternGroup": "molecules", "patternSubGroup": "molecules\\04-forms", @@ -303,7 +303,7 @@ exports['lineage hunter '] = { "data": null, "template": "

    {{message}}

    ", "extendedTemplate": "

    {{message}}

    ", - "patternName": "error", + "patternBaseName": "error", "patternLink": "01-atoms-05-alerts-00-error/01-atoms-05-alerts-00-error.html", "patternGroup": "atoms", "patternSubGroup": "atoms\\05-alerts", @@ -338,7 +338,7 @@ exports['lineage hunter '] = { "data": null, "template": "{{> atoms-error:foo }}", "extendedTemplate": "{{> atoms-error:foo }}", - "patternName": "error", + "patternBaseName": "error", "patternLink": "01-molecules-01-toast-00-error/01-molecules-01-toast-00-error.html", "patternGroup": "molecules", "patternSubGroup": "molecules\\01-toast", @@ -359,7 +359,7 @@ exports['lineage hunter '] = { "data": null, "template": "

    {{message}}

    ", "extendedTemplate": "

    {{message}}

    ", - "patternName": "error", + "patternBaseName": "error", "patternLink": "01-atoms-05-alerts-00-error/01-atoms-05-alerts-00-error.html", "patternGroup": "atoms", "patternSubGroup": "atoms\\05-alerts", @@ -392,7 +392,7 @@ exports['lineage hunter '] = { "data": null, "template": "{{> atoms-error:foo }}", "extendedTemplate": "{{>atoms-error:foo}}", - "patternName": "error", + "patternBaseName": "error", "patternLink": "01-molecules-01-toast-00-error/01-molecules-01-toast-00-error.html", "patternGroup": "molecules", "patternSubGroup": "molecules\\01-toast", @@ -413,7 +413,7 @@ exports['lineage hunter '] = { "data": null, "template": "

    {{message}}

    ", "extendedTemlpate": "

    {{message}}

    ", - "patternName": "error", + "patternBaseName": "error", "patternLink": "01-atoms-05-alerts-00-error/01-atoms-05-alerts-00-error.html", "patternGroup": "atoms", "patternSubGroup": "atoms\\05-alerts", @@ -446,7 +446,7 @@ exports['lineage hunter '] = { "data": null, "template": "{{> atoms-e:foo }}", "extendedTemplate": "{{>atoms-e:foo}}", - "patternName": "error", + "patternBaseName": "error", "patternLink": "01-molecules-01-toast-00-error/01-molecules-01-toast-00-error.html", "patternGroup": "molecules", "patternSubGroup": "molecules\\01-toast", @@ -467,7 +467,7 @@ exports['lineage hunter '] = { "data": null, "template": "

    {{message}}

    ", "extendedTemplate": "

    {{message}}

    ", - "patternName": "error", + "patternBaseName": "error", "patternLink": "01-atoms-05-alerts-00-error/01-atoms-05-alerts-00-error.html", "patternGroup": "atoms", "patternSubGroup": "atoms\\05-alerts", @@ -507,7 +507,7 @@ exports['lineage hunter '] = { "data": null, "template": "

    {{message}}

    ", "extendedTemplate": "

    {{message}}

    ", - "patternName": "error", + "patternBaseName": "error", "patternLink": "01-atoms-05-alerts-00-error/01-atoms-05-alerts-00-error.html", "patternGroup": "atoms", "patternSubGroup": "atoms\\05-alerts", diff --git a/test/object_factory_tests.js b/test/object_factory_tests.js index 81dc3d59e..b2fdeab5e 100644 --- a/test/object_factory_tests.js +++ b/test/object_factory_tests.js @@ -13,8 +13,8 @@ test.equals(p.fileName, '00-colors'); test.equals(p.fileExtension, '.mustache'); test.equals(p.jsonFileData.d, 123); - test.equals(p.patternName, 'colors'); - test.equals(p.patternDisplayName, 'Colors'); + test.equals(p.patternBaseName, 'colors'); + test.equals(p.patternName, 'Colors'); test.equals(p.patternLink, '00-atoms-00-global-00-colors/00-atoms-00-global-00-colors.html'); test.equals(p.patternGroup, 'atoms'); test.equals(p.patternSubGroup, 'global'); @@ -36,8 +36,8 @@ test.equals(p.fileName, '00-colors'); test.equals(p.fileExtension, '.mustache'); test.equals(p.jsonFileData.d, 123); - test.equals(p.patternName, 'colors'); - test.equals(p.patternDisplayName, 'Colors'); + test.equals(p.patternBaseName, 'colors'); + test.equals(p.patternName, 'Colors'); test.equals(p.patternLink, '00-atoms-00-colors/00-atoms-00-colors.html'); test.equals(p.patternGroup, 'atoms'); test.equals(p.flatPatternPath, '00-atoms'); @@ -51,14 +51,8 @@ }, 'test Pattern capitalizes patternDisplayName correctly' : function(test){ var p = new Pattern('00-atoms/00-global/00-colors-alt.mustache', { d: 123}); - test.equals(p.patternName, 'colors-alt'); - test.equals(p.patternDisplayName, 'Colors Alt'); - test.done(); - }, - 'test Pattern removes pattern paramter from key correctly' : function(test){ - var p = new Pattern('00-atoms/00-global/00-colors-alt.mustache', { d: 123}); - test.equals(p.patternName, 'colors-alt'); - test.equals(p.patternDisplayName, 'Colors Alt'); + test.equals(p.patternBaseName, 'colors-alt'); + test.equals(p.patternName, 'Colors Alt'); test.done(); } }; diff --git a/test/parameter_hunter_tests.js b/test/parameter_hunter_tests.js index 17a8c2de8..1019d5569 100644 --- a/test/parameter_hunter_tests.js +++ b/test/parameter_hunter_tests.js @@ -9,7 +9,7 @@ "fileName": "01-sticky-comment", "subdir": "02-organisms/02-comments", "name": "02-organisms-02-comments-01-sticky-comment", - "patternName": "sticky-comment", + "patternBaseName": "sticky-comment", "patternLink": "02-organisms-02-comments-01-sticky-comment/02-organisms-02-comments-01-sticky-comment.html", "patternGroup": "organisms", "patternSubGroup": "comments", @@ -31,7 +31,7 @@ "fileName": "02-single-comment", "subdir": "01-molecules/06-components", "name": "01-molecules-06-components-02-single-comment", - "patternName": "single-comment", + "patternBaseName": "single-comment", "patternLink": "01-molecules-06-components-02-single-comment/01-molecules-06-components-02-single-comment.html", "patternGroup": "molecules", "patternSubGroup": "components", From dc6cd22833fc31b5176356f639389a5a897a8661 Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Fri, 3 Jun 2016 11:37:49 -0500 Subject: [PATCH 154/187] pushed to support https://github.com/pattern-lab/edition-node-gulp/issues/27 once https://github.com/pattern-lab/patternlab-node/issues/347 is fixed --- core/lib/patternlab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 88d0c6a81..05bf905e8 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -275,7 +275,7 @@ var patternlab_engine = function (config) { lineageR: pattern.patternLineagesR, patternLineageEExists: pattern.patternLineageExists || pattern.patternLineageRExists, patternDesc: pattern.patternDescExists ? pattern.patternDesc : '', - patternBreadcrumb: pattern.patternGroup, + patternBreadcrumb: pattern.patternGroup + ' > ' + pattern.patternSubGroup, patternExtension: pattern.fileExtension, patternName: pattern.patternName, patternPartial: pattern.patternPartial, From cac925a711ceb14c3764221a3fae3b05602eacb0 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Fri, 3 Jun 2016 11:44:29 -0500 Subject: [PATCH 155/187] Hopefully fix #347. Use Path tools and regex instead of hackish string-length tomfoolery --- core/lib/object_factory.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/lib/object_factory.js b/core/lib/object_factory.js index 7dad7637d..8fe9aa902 100644 --- a/core/lib/object_factory.js +++ b/core/lib/object_factory.js @@ -37,7 +37,7 @@ var Pattern = function (relPath, data) { this.patternGroup = this.name.substring(this.name.indexOf('-') + 1, this.name.indexOf('-', 4) + 1 - this.name.indexOf('-') + 1); // the sub-group this pattern belongs to. - this.patternSubGroup = this.subdir.substring(this.subdir.indexOf('/') + 4); // 'global' + this.patternSubGroup = path.basename(this.subdir).replace(/^\d*-/, ''); // 'global' // Not sure what this is used for. this.flatPatternPath = this.subdir.replace(/[\/\\]/g, '-'); // '00-atoms-00-global' From 8966f66c34d5f18d60daabbe0bb051c9d64f7bec Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Fri, 3 Jun 2016 12:01:27 -0500 Subject: [PATCH 156/187] Hopefully fix the nav issue --- core/lib/ui_builder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index f2f548066..7e99135ee 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -84,7 +84,7 @@ function buildNavigation(patternlab) { //if there is one or more slashes in the subdir, get everything after //the last slash. if no slash, get the whole subdir string and strip //any numeric + hyphen prefix - patternSubTypeName = pattern.subdir.split('/').pop().replace(/^\d*\-/, ''); + patternSubTypeName = pattern.subdir.split(path.sep).pop().replace(/^\d*\-/, ''); //get the patternSubTypeItem patternSubTypeItemName = pattern.patternName.replace(/-/g, ' '); From 618f8fd93f06bad69aed15481ef0606e89de35d2 Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Fri, 3 Jun 2016 12:11:18 -0500 Subject: [PATCH 157/187] better handles flat patterns when constructing the breadcrumb fixes https://github.com/pattern-lab/patternlab-node/issues/347 --- core/lib/patternlab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 05bf905e8..a9e2a7cf0 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -275,7 +275,7 @@ var patternlab_engine = function (config) { lineageR: pattern.patternLineagesR, patternLineageEExists: pattern.patternLineageExists || pattern.patternLineageRExists, patternDesc: pattern.patternDescExists ? pattern.patternDesc : '', - patternBreadcrumb: pattern.patternGroup + ' > ' + pattern.patternSubGroup, + patternBreadcrumb: pattern.patternGroup === pattern.patternSubGroup ? pattern.patternGroup : pattern.patternGroup + ' > ' + pattern.patternSubGroup, patternExtension: pattern.fileExtension, patternName: pattern.patternName, patternPartial: pattern.patternPartial, From 1c9c92d12f0ee56c043397e8036afef0f0a9733c Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Mon, 6 Jun 2016 20:43:59 -0500 Subject: [PATCH 158/187] return when an error occurs --- core/lib/annotation_exporter.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/lib/annotation_exporter.js b/core/lib/annotation_exporter.js index 879922554..c6effadae 100644 --- a/core/lib/annotation_exporter.js +++ b/core/lib/annotation_exporter.js @@ -17,6 +17,7 @@ var annotations_exporter = function (pl) { var oldAnnotations = fs.readFileSync(path.resolve(paths.source.annotations, 'annotations.js'), 'utf8'); } catch (ex) { console.log('annotations.js file missing from ' + paths.source.annotations + '. This may be expected.'); + return []; } //parse as JSON by removing the old wrapping js syntax. comments and the trailing semi-colon @@ -26,6 +27,7 @@ var annotations_exporter = function (pl) { } catch (ex) { console.log('There was an error parsing JSON for ' + paths.source.annotations + 'annotations.js'); console.log(ex); + return []; } return oldAnnotationsJSON.comments; } @@ -42,6 +44,7 @@ var annotations_exporter = function (pl) { annotationsMD = fs.readFileSync(path.resolve(paths.source.annotations, 'annotations.md'), 'utf8'); } catch (ex) { console.log('annotations.md file missing from ' + paths.source.annotations + '. This may be expected.'); + return []; } //take the annotation snippets and split them on our custom delimiter From 9599e4f435bce1919c20933778dea83b3beb0859 Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Tue, 7 Jun 2016 07:08:04 -0500 Subject: [PATCH 159/187] Make source/_meta a configurable path fixes #353 --- core/lib/patternlab.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index a9e2a7cf0..f10019281 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -189,16 +189,16 @@ var patternlab_engine = function (config) { //set user defined head and foot if they exist try { - patternlab.userHead = fs.readFileSync(path.resolve(paths.source.root, '_meta', '_00-head.mustache'), 'utf8'); + patternlab.userHead = fs.readFileSync(path.resolve(paths.source.meta, '_00-head.mustache'), 'utf8'); } catch (ex) { if (patternlab.config.debug) { console.log(ex); - console.log('Could not find optional user-defined header, usually found at ./source/_meta/_001-head.mustache. It was likely deleted.'); + console.log('Could not find optional user-defined header, usually found at ./source/_meta/_00-head.mustache. It was likely deleted.'); } } try { - patternlab.userFoot = fs.readFileSync(path.resolve(paths.source.root, '_meta', '_01-foot.mustache'), 'utf8'); + patternlab.userFoot = fs.readFileSync(path.resolve(paths.source.meta, '_01-foot.mustache'), 'utf8'); } catch (ex) { if (patternlab.config.debug) { From 1c8948953cedea5f344481d060ae314810aae03e Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 7 Jun 2016 13:42:32 -0500 Subject: [PATCH 160/187] Make the engine unit tests chill out if their engines aren't installed. Fixes #352. --- test/engine_handlebars_tests.js | 19 ++--- test/engine_twig_tests.js | 20 ++--- test/engine_underscore_tests.js | 144 ++++++++++++++++---------------- 3 files changed, 88 insertions(+), 95 deletions(-) diff --git a/test/engine_handlebars_tests.js b/test/engine_handlebars_tests.js index fb3546936..3521ee362 100644 --- a/test/engine_handlebars_tests.js +++ b/test/engine_handlebars_tests.js @@ -1,22 +1,11 @@ "use strict"; -// don't run these tests unless handlebars is installed -try { var handlebars = require('handlebars'); } -catch (err) { return; } - var path = require('path'); var pa = require('../core/lib/pattern_assembler'); var Pattern = require('../core/lib/object_factory').Pattern; var testPatternsPath = path.resolve(__dirname, 'files', '_handlebars-test-patterns'); var eol = require('os').EOL; -try { - require('handlebars'); -} catch (err) { - console.log('handlebars renderer not installed; skipping tests'); - return; -} - // fake pattern lab constructor: // sets up a fake patternlab object, which is needed by the pattern processing // apparatus. @@ -194,3 +183,11 @@ exports['engine_handlebars'] = { ]); } }; + + +// don't run these tests unless handlebars is installed +var engineLoader = require('../core/lib/pattern_engines'); +if (!engineLoader.handlebars) { + console.log("Handlebars engine not installed, skipping tests."); + delete exports.engine_handlebars; +} diff --git a/test/engine_twig_tests.js b/test/engine_twig_tests.js index 49042ba27..c5f9773b4 100644 --- a/test/engine_twig_tests.js +++ b/test/engine_twig_tests.js @@ -1,23 +1,11 @@ "use strict"; /*eslint-disable dot-notation*/ -// don't run these tests unless twig is installed -try { var twig = require('twig'); } -catch (err) { return; } - var path = require('path'); var pa = require('../core/lib/pattern_assembler'); var Pattern = require('../core/lib/object_factory').Pattern; -var testPatternsPath = path.resolve(__dirname, 'files', '_twig-test-patterns'); var eol = require('os').EOL; -try { - require('twig'); -} catch (err) { - console.log('twig renderer not installed; skipping tests'); - return; -} - // fake pattern lab constructor: // sets up a fake patternlab object, which is needed by the pattern processing // apparatus. @@ -193,3 +181,11 @@ exports['engine_twig'] = { ]); } }; + + +// don't run these tests unless twig is installed +var engineLoader = require('../core/lib/pattern_engines'); +if (!engineLoader.twig) { + console.log("Twig engine not installed, skipping tests."); + delete exports.engine_twig; +} diff --git a/test/engine_underscore_tests.js b/test/engine_underscore_tests.js index c7db11d66..b5beb95e3 100644 --- a/test/engine_underscore_tests.js +++ b/test/engine_underscore_tests.js @@ -1,85 +1,85 @@ -(function () { - "use strict"; +"use strict"; - var path = require('path'); - var pa = require('../core/lib/pattern_assembler'); - var testPatternsPath = path.resolve(__dirname, 'files', '_underscore-test-patterns'); - var eol = require('os').EOL; +var path = require('path'); +var pa = require('../core/lib/pattern_assembler'); +var testPatternsPath = path.resolve(__dirname, 'files', '_underscore-test-patterns'); +var eol = require('os').EOL; - try { - require('underscore'); - } catch (err) { - console.log('underscore renderer not installed; skipping tests'); - return; - } +// fake pattern lab constructor: +// sets up a fake patternlab object, which is needed by the pattern processing +// apparatus. +function fakePatternLab() { + var fpl = { + partials: {}, + patterns: [], + footer: '', + header: '', + listitems: {}, + listItemArray: [], + data: { + link: {} + }, + config: require('../patternlab-config.json'), + package: {} + }; - // fake pattern lab constructor: - // sets up a fake patternlab object, which is needed by the pattern processing - // apparatus. - function fakePatternLab() { - var fpl = { - partials: {}, - patterns: [], - footer: '', - header: '', - listitems: {}, - listItemArray: [], - data: { - link: {} - }, - config: require('../patternlab-config.json'), - package: {} - }; + // patch the pattern source so the pattern assembler can correctly determine + // the "subdir" + fpl.config.paths.source.patterns = testPatternsPath; - // patch the pattern source so the pattern assembler can correctly determine - // the "subdir" - fpl.config.paths.source.patterns = testPatternsPath; + return fpl; +} - return fpl; - } +exports['engine_underscore'] = { + 'hello world underscore pattern renders': function (test) { + test.expect(1); - exports['engine_underscore'] = { - 'hello world underscore pattern renders': function (test) { - test.expect(1); + var patternPath = path.resolve( + testPatternsPath, + '00-atoms', + '00-global', + '00-helloworld.html' + ); - var patternPath = path.resolve( - testPatternsPath, - '00-atoms', - '00-global', - '00-helloworld.html' - ); + // do all the normal processing of the pattern + var patternlab = new fakePatternLab(); + var assembler = new pa(); + var helloWorldPattern = assembler.process_pattern_iterative(patternPath, patternlab); + assembler.process_pattern_recursive(patternPath, patternlab); - // do all the normal processing of the pattern - var patternlab = new fakePatternLab(); - var assembler = new pa(); - var helloWorldPattern = assembler.process_pattern_iterative(patternPath, patternlab); - assembler.process_pattern_recursive(patternPath, patternlab); + test.equals(helloWorldPattern.render(), 'Hello world!' + eol); + test.done(); + }, + 'underscore partials can render JSON values': function (test) { + test.expect(1); - test.equals(helloWorldPattern.render(), 'Hello world!' + eol); - test.done(); - }, - 'underscore partials can render JSON values': function (test) { - test.expect(1); + // pattern paths + var pattern1Path = path.resolve( + testPatternsPath, + '00-atoms', + '00-global', + '00-helloworld-withdata.html' + ); - // pattern paths - var pattern1Path = path.resolve( - testPatternsPath, - '00-atoms', - '00-global', - '00-helloworld-withdata.html' - ); + // set up environment + var patternlab = new fakePatternLab(); // environment + var assembler = new pa(); - // set up environment - var patternlab = new fakePatternLab(); // environment - var assembler = new pa(); + // do all the normal processing of the pattern + var helloWorldWithData = assembler.process_pattern_iterative(pattern1Path, patternlab); + assembler.process_pattern_recursive(pattern1Path, patternlab); - // do all the normal processing of the pattern - var helloWorldWithData = assembler.process_pattern_iterative(pattern1Path, patternlab); - assembler.process_pattern_recursive(pattern1Path, patternlab); + // test + test.equals(helloWorldWithData.render(), 'Hello world!' + eol + 'Yeah, we got the subtitle from the JSON.' + eol); + test.done(); + } +}; - // test - test.equals(helloWorldWithData.render(), 'Hello world!' + eol + 'Yeah, we got the subtitle from the JSON.' + eol); - test.done(); - } - }; -})(); + + +// don't run these tests unless underscore is installed +var engineLoader = require('../core/lib/pattern_engines'); +if (!engineLoader.underscore) { + console.log("Underscore engine not installed, skipping tests."); + delete exports.engine_underscore; +} From bd0d95fc7cfdd1f50795f9328d78783cdb0f6e73 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Wed, 8 Jun 2016 22:23:59 -0500 Subject: [PATCH 161/187] improved throne error when cannot find partial by not clobbering it just beforehand --- core/lib/pattern_assembler.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/lib/pattern_assembler.js b/core/lib/pattern_assembler.js index 3fcedf2e8..6133dcc6a 100644 --- a/core/lib/pattern_assembler.js +++ b/core/lib/pattern_assembler.js @@ -32,9 +32,9 @@ var pattern_assembler = function () { for (var i = 0; i < patternlab.patterns.length; i++) { var partialParts = partialName.split('-'), partialType = partialParts[0], - partialName = partialParts.slice(1).join('-'); + partialNameEnd = partialParts.slice(1).join('-'); - if (patternlab.patterns[i].patternPartial.split('-')[0] === partialType && patternlab.patterns[i].patternPartial.indexOf(partialName) > -1) { + if (patternlab.patterns[i].patternPartial.split('-')[0] === partialType && patternlab.patterns[i].patternPartial.indexOf(partialNameEnd) > -1) { return patternlab.patterns[i]; } } From 9aeb5db3238e4931b545b07f780fc67e9cf8070e Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Thu, 9 Jun 2016 07:39:38 -0500 Subject: [PATCH 162/187] improve error message --- core/lib/patternlab.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index f10019281..c14f48038 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -146,13 +146,13 @@ var patternlab_engine = function (config) { try { patternlab.data = fs.readJSONSync(path.resolve(paths.source.data, 'data.json')); } catch (ex) { - console.log('missing ' + paths.source.data + '/data.json Pattern Lab may not work without this file.'); + console.log('missing ' + paths.source.data + 'data.json Pattern Lab may not work without this file.'); patternlab.data = {}; } try { patternlab.listitems = fs.readJSONSync(path.resolve(paths.source.data, 'listitems.json')); } catch (ex) { - console.log('missing ' + paths.source.data + '/listitems.json Pattern Lab may not work without this file.'); + console.log('missing ' + paths.source.data + 'listitems.json Pattern Lab may not work without this file.'); patternlab.listitems = {}; } try { From 9640056e6c9fd1f23624b63a2d565dd7fe99d188 Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Fri, 10 Jun 2016 14:05:58 -0500 Subject: [PATCH 163/187] removing direct dependencies fixes#350 --- package.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/package.json b/package.json index de52879d8..c3eb6a5cc 100644 --- a/package.json +++ b/package.json @@ -7,14 +7,10 @@ "diveSync": "^0.3.0", "fs-extra": "^0.30.0", "glob": "^7.0.0", - "handlebars": "^4.0.5", "html-entities": "^1.2.0", "json5": "^0.5.0", "lodash": "~4.13.1", "markdown-it": "^6.0.1", - "mustache": "^2.2.0", - "twig": "^0.9.5", - "underscore": "^1.8.3", "patternengine-node-mustache": "^0.0.1" }, "devDependencies": { From 8c9d85e0f6d017303caea839b610e2527d04a0d4 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sat, 11 Jun 2016 05:02:28 -0500 Subject: [PATCH 164/187] pushing a failing test for #356 --- .../00-test/12-another-styled-atom.mustache | 1 + .../_patterns/00-test/13-listitem.mustache | 5 ++ test/list_item_hunter_tests.js | 59 +++++++++++++++++-- 3 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 test/files/_patterns/00-test/12-another-styled-atom.mustache create mode 100644 test/files/_patterns/00-test/13-listitem.mustache diff --git a/test/files/_patterns/00-test/12-another-styled-atom.mustache b/test/files/_patterns/00-test/12-another-styled-atom.mustache new file mode 100644 index 000000000..2f03b4974 --- /dev/null +++ b/test/files/_patterns/00-test/12-another-styled-atom.mustache @@ -0,0 +1 @@ +{{> test-styled-atom:test_1 }} diff --git a/test/files/_patterns/00-test/13-listitem.mustache b/test/files/_patterns/00-test/13-listitem.mustache new file mode 100644 index 000000000..cad86d2c7 --- /dev/null +++ b/test/files/_patterns/00-test/13-listitem.mustache @@ -0,0 +1,5 @@ +
    + {{#listItems.one}} + {{> test-styled-atom }} + {{/listItems.one}} +
    diff --git a/test/list_item_hunter_tests.js b/test/list_item_hunter_tests.js index 361763eaa..86689124f 100644 --- a/test/list_item_hunter_tests.js +++ b/test/list_item_hunter_tests.js @@ -20,7 +20,8 @@ var pl = { "listitems": { "1": [ - { "title": "Foo" } + { "title": "Foo" }, + { "message" : "FooM"} ], "2": [ { "title": "Foo" }, @@ -31,8 +32,16 @@ "link": {}, "partials": [] }, - "config": {"debug": false}, - "partials" : {} + "config": { + "debug": false, + "paths": { + "source": { + "patterns": "./test/files/_patterns" + } + } + }, + "partials" : {}, + "patterns" : [] }; return extend(pl, customProps); @@ -335,7 +344,49 @@ var expectedValue = '
    Foo Foo Foo Bar Bar Bar
    '; test.equals(bookendPattern.extendedTemplate.replace(/\s\s+/g, ' ').replace(/\n/g, ' ').trim(), expectedValue.trim()); test.done(); - } + }, + + 'process_list_item_partials - correctly ignores already processed partial that had a style modifier when the same partial no longer has one' : function(test){ + //arrange + var fs = require('fs-extra'); + var pa = require('../core/lib/pattern_assembler'); + var pattern_assembler = new pa(); + var list_item_hunter = new lih(); + var patterns_dir = './test/files/_patterns'; + + var pl = createFakePatternLab(); + + var atomPattern = new Pattern('00-test/03-styled-atom.mustache'); + atomPattern.template = fs.readFileSync(patterns_dir + '/00-test/03-styled-atom.mustache', 'utf8'); + atomPattern.extendedTemplate = atomPattern.template; + atomPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(atomPattern); + + var anotherStyledAtomPattern = new Pattern('00-test/12-another-styled-atom.mustache'); + anotherStyledAtomPattern.template = fs.readFileSync(patterns_dir + '/00-test/12-another-styled-atom.mustache', 'utf8'); + anotherStyledAtomPattern.extendedTemplate = anotherStyledAtomPattern.template; + anotherStyledAtomPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(anotherStyledAtomPattern); + + var listPattern = new Pattern('00-test/13-listitem.mustache'); + listPattern.template = fs.readFileSync(patterns_dir + '/00-test/13-listitem.mustache', 'utf8'); + listPattern.extendedTemplate = listPattern.template; + listPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(listPattern); + + pl.patterns.push(atomPattern); + pl.patterns.push(anotherStyledAtomPattern); + pl.patterns.push(listPattern); + + //act + + //might need to cal processPatternRecursive instead + pattern_assembler.process_pattern_recursive(atomPattern.relPath, pl); + pattern_assembler.process_pattern_recursive(anotherStyledAtomPattern.relPath, pl); + pattern_assembler.process_pattern_recursive(listPattern.relPath, pl); + + //assert. + var expectedValue = '
    FooM
    '; + test.equals(listPattern.extendedTemplate.replace(/\s\s+/g, ' ').replace(/\n/g, ' ').trim(), expectedValue.trim()); + test.done(); + }, }; From eda17c0c364b090db59edb0ec1748674bd11945e Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sat, 11 Jun 2016 05:48:12 -0500 Subject: [PATCH 165/187] reset extendedTemplate to template after retrieval passing unit test and passing npm linked private instance of PL closes #356 --- core/lib/list_item_hunter.js | 3 +++ test/list_item_hunter_tests.js | 46 ++++++++++++++++++++++++++-------- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/core/lib/list_item_hunter.js b/core/lib/list_item_hunter.js index e8d278609..ec4199327 100644 --- a/core/lib/list_item_hunter.js +++ b/core/lib/list_item_hunter.js @@ -91,6 +91,9 @@ var list_item_hunter = function () { console.log(err); } + //if we retrieved a pattern we should make sure that its extendedTemplate is reset. looks to fix #356 + cleanPartialPattern.extendedTemplate = cleanPartialPattern.template; + //if partial has style modifier data, replace the styleModifier value if (foundPartials[j].indexOf(':') > -1) { style_modifier_hunter.consume_style_modifier(cleanPartialPattern, foundPartials[j], patternlab); diff --git a/test/list_item_hunter_tests.js b/test/list_item_hunter_tests.js index 86689124f..7fe3cea56 100644 --- a/test/list_item_hunter_tests.js +++ b/test/list_item_hunter_tests.js @@ -4,6 +4,8 @@ var lih = require('../core/lib/list_item_hunter'); var Pattern = require('../core/lib/object_factory').Pattern; var extend = require('util')._extend; + var pa = require('../core/lib/pattern_assembler'); + var pattern_assembler = new pa(); // fake pattern creators function createFakeListPattern(customProps) { @@ -17,15 +19,40 @@ } function createFakePatternLab(customProps) { + + //NOTE: These listitems are faked so that pattern_assembler.combine_listitems has already clobbered them. + var pl = { "listitems": { "1": [ - { "title": "Foo" }, - { "message" : "FooM"} + { + "title": "Foo", + "message": "FooM" + } ], - "2": [ - { "title": "Foo" }, - { "title": "Bar" } + "2" : [ + { + "title": "Foo", + "message": "FooM" + }, + { + "title": "Bar", + "message": "BarM" + } + ], + "3": [ + { + "title": "Foo", + "message": "FooM" + }, + { + "title": "Bar", + "message": "BarM" + }, + { + "title": "Baz", + "message": "BazM" + }, ] }, "data": { @@ -349,25 +376,22 @@ 'process_list_item_partials - correctly ignores already processed partial that had a style modifier when the same partial no longer has one' : function(test){ //arrange var fs = require('fs-extra'); - var pa = require('../core/lib/pattern_assembler'); - var pattern_assembler = new pa(); var list_item_hunter = new lih(); - var patterns_dir = './test/files/_patterns'; var pl = createFakePatternLab(); var atomPattern = new Pattern('00-test/03-styled-atom.mustache'); - atomPattern.template = fs.readFileSync(patterns_dir + '/00-test/03-styled-atom.mustache', 'utf8'); + atomPattern.template = fs.readFileSync(pl.config.paths.source.patterns + '/00-test/03-styled-atom.mustache', 'utf8'); atomPattern.extendedTemplate = atomPattern.template; atomPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(atomPattern); var anotherStyledAtomPattern = new Pattern('00-test/12-another-styled-atom.mustache'); - anotherStyledAtomPattern.template = fs.readFileSync(patterns_dir + '/00-test/12-another-styled-atom.mustache', 'utf8'); + anotherStyledAtomPattern.template = fs.readFileSync(pl.config.paths.source.patterns + '/00-test/12-another-styled-atom.mustache', 'utf8'); anotherStyledAtomPattern.extendedTemplate = anotherStyledAtomPattern.template; anotherStyledAtomPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(anotherStyledAtomPattern); var listPattern = new Pattern('00-test/13-listitem.mustache'); - listPattern.template = fs.readFileSync(patterns_dir + '/00-test/13-listitem.mustache', 'utf8'); + listPattern.template = fs.readFileSync(pl.config.paths.source.patterns + '/00-test/13-listitem.mustache', 'utf8'); listPattern.extendedTemplate = listPattern.template; listPattern.stylePartials = pattern_assembler.find_pattern_partials_with_style_modifiers(listPattern); From a17fa3018a2b0bbccfbeeb1adb39a08e6a893c53 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sat, 11 Jun 2016 06:10:43 -0500 Subject: [PATCH 166/187] clean up travis file per docs --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index ed3078720..90d48e964 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,10 @@ language: node_js node_js: - - stable - - 5.0 - - 4.0 + - node + - 6 + - 5 + - 4 before_install: - phantomjs --version @@ -15,7 +16,6 @@ branches: only: - master - dev - - pattern-engines - dev-2.0-core notifications: From 0f75f156ce4a6f94646201b037bfeba90c5d0a08 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sat, 11 Jun 2016 08:54:44 -0500 Subject: [PATCH 167/187] improved help and changed CLI interface a bit --- core/lib/patternlab.js | 64 +++++++++++++++++++++++++++++++++--------- core/lib/utilities.js | 8 ++++++ 2 files changed, 59 insertions(+), 13 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index c14f48038..19883e784 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -87,19 +87,57 @@ var patternlab_engine = function (config) { console.log(patternlab.package.version); } + function help() { - console.log('Patternlab Node Help'); + + console.log(''); + + console.log('|=======================================|'); + plutils.logGreen(' Pattern Lab Node Help v ' + patternlab.package.version); + console.log('|=======================================|'); + + console.log(''); + console.log('Command Line Interface - usually consumed by an edition'); + console.log(''); + + plutils.logGreen(' patternlab:build'); + console.log(' > Compiles the patterns and frontend, outputting to config.paths.public'); + console.log(''); + + plutils.logGreen(' patternlab:patternsonly'); + console.log(' > Compiles the patterns only, outputting to config.paths.public'); + console.log(''); + + plutils.logGreen(' patternlab:version'); + console.log(' > Return the version of patternlab-node you have installed'); + console.log(''); + + plutils.logGreen(' patternlab:help'); + console.log(' > Get more information about patternlab-node, pattern lab in general, and where to report issues.'); + console.log(''); + + plutils.logGreen(' patternlab:liststarterkits'); + console.log(' > Returns a url with the list of available starterkits hosted on the Pattern Lab organization Github account'); + console.log(''); + + plutils.logGreen(' patternlab:loadstarterkit'); + console.log(' > Load a starterkit into config.paths.soource/*'); + console.log(' > NOTE: This does overwrite any existing contents, and does not clean the directory first.'); + console.log(' > NOTE: In most cases, `npm install starterkit-name` will precede this call.'); + console.log(' > arguments:'); + console.log(' -- kit '); + console.log(' > the name of the starter kit to load'); + console.log(' > example (gulp):'); + console.log(' `gulp patternlab:starterkit-load --kit=starterkit-mustache-demo`'); + console.log(''); + console.log('==============================='); - console.log('Command Line Arguments'); - console.log('patternlab:only_patterns'); - console.log(' > Compiles the patterns only, outputting to config.patterns.public'); - console.log('patternlab:v'); - console.log(' > Retrieve the version of patternlab-node you have installed'); - console.log('patternlab:help'); - console.log(' > Get more information about patternlab-node, pattern lab in general, and where to report issues.'); + console.log(''); + console.log('Visit http://patternlab.io/ for more info about Pattern Lab'); + console.log('Visit https://github.com/pattern-lab/patternlab-node/issues to open an issue.'); + console.log('Visit https://github.com/pattern-lab/patternlab-node/wiki to view the changelog, roadmap, and other info.'); + console.log(''); console.log('==============================='); - console.log('Visit http://patternlab.io/docs/index.html for general help on pattern-lab'); - console.log('Visit https://github.com/pattern-lab/patternlab-node/issues to open a bug.'); } function printDebug() { @@ -321,14 +359,14 @@ var patternlab_engine = function (config) { help: function () { help(); }, - build_patterns_only: function (deletePatternDir) { + patternsonly: function (deletePatternDir) { buildPatterns(deletePatternDir); printDebug(); }, - list_starterkits: function () { + liststarterkits: function () { return listStarterkits(); }, - load_starterkit: function (starterkitName) { + loadstarterkit: function (starterkitName) { loadStarterKit(starterkitName); } }; diff --git a/core/lib/utilities.js b/core/lib/utilities.js index de37d6a57..ef4e866fc 100644 --- a/core/lib/utilities.js +++ b/core/lib/utilities.js @@ -8,6 +8,14 @@ var util = { return o; }, + logGreen: function (message) { + console.log('\x1b[32m', message, '\x1b[0m'); + }, + + logRed: function (message) { + console.log('\x1b[41m', message, '\x1b[0m'); + }, + /** * Recursively merge properties of two objects. * From f2d62273f2767fe197cc464faf99ffffa440a218 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sat, 11 Jun 2016 09:08:51 -0500 Subject: [PATCH 168/187] remove space --- core/lib/patternlab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 19883e784..543ebf718 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -93,7 +93,7 @@ var patternlab_engine = function (config) { console.log(''); console.log('|=======================================|'); - plutils.logGreen(' Pattern Lab Node Help v ' + patternlab.package.version); + plutils.logGreen(' Pattern Lab Node Help v' + patternlab.package.version); console.log('|=======================================|'); console.log(''); From 105c57b666f40a898853b458fffa6c1130e97a7b Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sat, 11 Jun 2016 09:55:40 -0500 Subject: [PATCH 169/187] bumping engine semver --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c3eb6a5cc..35a4d9ca3 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "json5": "^0.5.0", "lodash": "~4.13.1", "markdown-it": "^6.0.1", - "patternengine-node-mustache": "^0.0.1" + "patternengine-node-mustache": "^1.0.0" }, "devDependencies": { "grunt": "~1.0.1", From 037a42ec74444dfd0a39084f31278fb47f5d2192 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sat, 11 Jun 2016 09:56:44 -0500 Subject: [PATCH 170/187] bumping semver --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 35a4d9ca3..fc440ec77 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "patternlab-node", "description": "Pattern Lab is a collection of tools to help you create atomic design systems. This is the node command line interface (CLI).", - "version": "2.0.0", + "version": "2.0.0-alpha", "main": "./core/lib/patternlab.js", "dependencies": { "diveSync": "^0.3.0", From 7c2d2fd382e595084798b96f2c0c46ba044bde07 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sat, 11 Jun 2016 10:15:23 -0500 Subject: [PATCH 171/187] reverting engine dependency until Geoff npm publishes it --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fc440ec77..fb9ac32a1 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "json5": "^0.5.0", "lodash": "~4.13.1", "markdown-it": "^6.0.1", - "patternengine-node-mustache": "^1.0.0" + "patternengine-node-mustache": "^0.0.1" }, "devDependencies": { "grunt": "~1.0.1", From ac9cb7738450693ac455959cf0f143e8ec679327 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sat, 11 Jun 2016 10:27:43 -0500 Subject: [PATCH 172/187] update engine dependency --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fb9ac32a1..fc440ec77 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "json5": "^0.5.0", "lodash": "~4.13.1", "markdown-it": "^6.0.1", - "patternengine-node-mustache": "^0.0.1" + "patternengine-node-mustache": "^1.0.0" }, "devDependencies": { "grunt": "~1.0.1", From 234f4c897ecee87ce6db3e850690c938f2918c46 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sat, 11 Jun 2016 10:35:18 -0500 Subject: [PATCH 173/187] changing the version comment after build --- core/lib/patternlab.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 543ebf718..dd56a38e4 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -1,10 +1,10 @@ -/* - * patternlab-node - v2.0.0 - 2016 - * +/* + * patternlab-node - v2.0.0-alpha - 2016 + * * Brian Muenzenmeyer, Geoff Pursell, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ From a8392f682c76814542acbe5e462883b3da9b1d82 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sat, 11 Jun 2016 12:18:53 -0500 Subject: [PATCH 174/187] Update the README --- README.md | 428 +++--------------------------------------------------- 1 file changed, 20 insertions(+), 408 deletions(-) diff --git a/README.md b/README.md index 307a5bd06..1f5b87805 100644 --- a/README.md +++ b/README.md @@ -1,425 +1,37 @@ [![Build Status](https://travis-ci.org/pattern-lab/patternlab-node.png?branch=master)](https://travis-ci.org/pattern-lab/patternlab-node) -## About the Node Version of Pattern Lab +# Pattern Lab Node Core -The Node version of [Pattern Lab](http://patternlab.io/) is, at its core, a static site generator. It combines platform-agnostic assets, like the Mustache-based patterns, the JavaScript-based viewer, and the self-contained webserver, with a Node-based "builder" that transforms and dynamically builds the Pattern Lab site. +This repository contains the core functionality for Pattern Lab Node. Pattern Lab Core is designed to be included as a dependency within [Node Editions](https://github.com/pattern-lab?utf8=%E2%9C%93&query=edition-node). +If this looks **REALLY DIFFERENT** from what you expected, check out the [ChangeLog](https://github.com/pattern-lab/patternlab-node/wiki/ChangeLog). -This repository contains the vanilla builder logic, grunt and gulp configurations, and some sample template/css/data to illustrate the power and flexibility of the tool. - -###### Core Team +## Core Team * [@bmuenzenmeyer](https://github.com/bmuenzenmeyer) - Lead Maintainer * [@geoffp](https://github.com/geoffp) - Core Contributor -### Prerequisites - -Make sure Node and npm are installed. A great guide can be found here: [https://docs.npmjs.com/getting-started/installing-node](https://docs.npmjs.com/getting-started/installing-node) - -### Download - -* Download the [latest release of patternlab-node](https://github.com/pattern-lab/patternlab-node/releases/latest) from Github -* Via npm, run `npm install patternlab-node` (Note this will auto install the grunt version currently. see below) -* **NOTE** Node version 4.X and 5.X have tentative support, citing [a lot of Windows issues](https://github.com/nodejs/node-gyp/issues/629), including [mine](https://github.com/pattern-lab/patternlab-node/issues/162). Upgrade node at your own risk until otherwise stated. I've tried to catalog some issues and troubleshooting steps on the [wiki](https://github.com/pattern-lab/patternlab-node/wiki/Windows-Issues). - -### Troubleshooting Installs - -Make sure you are running your terminal/command line session as administrator. This could mean `sudo`, or opening the window with a right-click option. - -### Choose Your Adventure! Now Vanilla, Grunt & Gulp - -This repository ships with two `package.json` files, a `Gruntfile.js`, and a `gulpfile.js`. The default is grunt currently. The core builder is not dependent on either. - -### Getting Started - Grunt - -To run patternlab-node using grunt, do the following in the directory you downloaded and extracted the zipped release: - -1. Run `npm install` from the command line -2. Optionally, delete `package.gulp.json`, `gulpfile.js`, and `core/lib/patternlab_gulp.js` files if you are certain you don't need it. -* Not deleting `core/lib/patternlab_gulp.js` may cause a harmless error when running grunt. Delete it. -3. Run `grunt` or `grunt serve` from the command line - -This creates all patterns, the styleguide, and the pattern lab site. It's strongly recommended to run `grunt serve` to have BrowserSync spin up and serve the files to you. - -### Getting Started - Gulp - -To run patternlab-node using gulp, you need to swap out the default grunt configuration. Do the following in the directory you downloaded and extracted the zipped release: - -1. Rename `package.json` to `package.grunt.json` or delete it if you don't intend on going back -2. Rename `package.gulp.json` to `package.json` -3. Run `npm install` from the command line -4. Run `gulp` or `gulp serve` from the command line - -This creates all patterns, the styleguide, and the pattern lab site. It's strongly recommended to run `gulp serve` to have BrowserSync spin up and serve the files to you. - -### There and Back Again, or Switching Between Grunt and Gulp - -It's not expected to toggle between the two build systems, but for those migrating between the two configs, here's some general guidelines: - -* Make sure your `package.json` files are correct per the Getting Started sections. -* Run `npm cache clear` before installation -* Delete the contents of `./node_modules` if you want a cleaner installation. -* Regarding speed, Gulp is faster. BrowserSync takes a bit longer than the old static server to spin up, but its capabilities far outweigh the startup cost. - -### Upgrading - -You can find instructions on how to upgrade from version to version of Pattern Lab Node here: [https://github.com/pattern-lab/patternlab-node/wiki/Upgrading](https://github.com/pattern-lab/patternlab-node/wiki/Upgrading) - -### Command Line Interface - -The following are grunt/gulp task arguments you may execute: - -##### `patternlab` -With no arguments, patternlab runs the full builder, compiling patterns, and constructing the front-end site. - -##### `patternlab:only_patterns` -Compile the patterns only, outputting to ./public/patterns - -##### `patternlab:v` -Retrieve the version of patternlab-node you have installed - -##### `patternlab:help` -Get more information about patternlab-node, pattern lab in general, and where to report issues. - -### Further Configuration - -##### Watching Changes -To have patternlab-node watch for changes to either a mustache template, data, or stylesheets, run `grunt|gulp watch` or `grunt|gulp serve`. The `Gruntfile|Gulpfile` governs what is watched. It should be easy to add scss or whatever preprocessor you fancy. - -##### Configurable Paths -Pattern Lab Node ships with a particular source and public workflow intended to separate the code you work on with the code generated for consumption elsewhere. If you wish to change any paths, you may do so within `patternlab-config.json`. The contents are here: - -``` -"paths" : { - "source" : { - "root": "./source/", - "patterns" : "./source/_patterns/", - "data" : "./source/_data/", - "styleguide" : "./core/styleguide/", - "patternlabFiles" : "./source/_patternlab-files/", - "js" : "./source/js", - "images" : "./source/images", - "fonts" : "./source/fonts", - "css" : "./source/css/" - }, - "public" : { - "root" : "./public/", - "patterns" : "./public/patterns/", - "data" : "./public/data/", - "styleguide" : "./public/styleguide/", - "js" : "./public/js", - "images" : "./public/images", - "fonts" : "./public/fonts", - "css" : "./public/css" - } -} -``` - -Note the intentional repitition of the nested structure, made this way for maximum flexibility. Relative paths are default but absolute paths should work too. You may also use these paths within Grunt or Gulp files by referring to the paths() object. - -##### Nav Bar Controls -If you don't have a need for some of the nav-bar tools in the Pattern Lab frontend, you can turn them off in `patternlab-config.json`. - -The current selection is as follows. - -``` -"ishControlsVisible": { - "s": true, - "m": true, - "l": true, - "full": true, - "random": true, - "disco": true, - "hay": true, - "mqs": false, - "find": false, - "views-all": true, - "views-annotations": true, - "views-code": true, - "views-new": true, - "tools-all": true, - "tools-follow": false, - "tools-reload": false, - "tools-shortcuts": false, - "tools-docs": true -} -``` -##### Pattern States -You can set the state of a pattern by including its key in the `patternStates` object in `patternlab-config.json`, along with a style defined inside `patternStateCascade`. The out of the box styles are in progress (orange), in review (yellow), and complete (green). -``` -"patternStates": { - "atoms-colors" : "complete", - "molecules-primary-nav" : "inreview", - "organisms-header" : "inprogress" -} -``` - -Note that patterns inherit the lowest common denominator pattern state of their lineage. -Consider: -``` -"patternStates": { - "molecules-single-comment" : "complete", - "organisms-sticky-comment" : "inreview", - "templates-article" : "complete" -} -``` -In this case, two things are of note: - -* templates-article will display inreview since it inherits `organisms-sticky-comment` -* pages-article will not display any pattern state, as it does not define one - -The `patternStateCascade` array is important in that the order is hierarchical. -The default is below: - -``` -"patternStateCascade": ["inprogress", "inreview", "complete"], -``` - -which correspond to classes defined inside `./core/styleguide/css/styleguide.css` - -``` -/* pattern states */ -.inprogress:before { - color: #FF4136 !important; -} - -.inreview:before { - color: #FFCC00 !important; -} - -.complete:before { - color: #2ECC40 !important; -} -``` - -##### Pattern Export -`patternlab-config.json` also has two properties that work together to export completed patterns for use in a production environment. Provide an array of keys and an output directory. Pattern Lab doesn't ship with any pattern export keys, but the default directory is `"./pattern_exports/"` created inside the install directory. - -``` -"patternExportKeys": ["molecules-primary-nav", "organisms-header", "organisms-header"], -"patternExportDirectory": "./pattern_exports/" -``` - -Coupled with exported css (much easier to extract with existing tools like [grunt-contrib-copy](https://github.com/gruntjs/grunt-contrib-copy)), pattern export can help to maintain the relevancy of the design system by directly placing partials in a directory of your choosing. - -##### cacheBust -`patternlab-config.json` has this flag to instruct Pattern Lab to append a unique query string to Javascript and CSS assets throughout the frontend. - -``` -"cacheBust": true -``` - -Default: true - -##### defaultPattter -`patternlab-config.json` has an entry that allows you to specifiy a specific pattern upon launch of the main site. It works even without BrowserSync running. Set it like this: - -``` -"defaultPattern": "pages-homepage", -``` -Default: "all" -If running with BrowserSync, you may also set [this BrowserSync options](https://www.browsersync.io/docs/options/#option-startPath) to achieve the same result via your Gruntfile or Gulpfile. - -``` -startPath: '/?p=pages-homepage', -``` - -##### baseurl - -If your instance of Pattern Lab lives in a subdirectory of your server, for instance on github pages (ex: yourusername.github.io/patterns-demo/), then add the baseurl here. The baseurl is everything after the hostname - ie: `patterns-demo` - -``` -"baseurl" : "/patterns-demo" -``` - -Default: blank - -##### excluding patterns - -If you'd like to exclude an individual pattern you can do so by prepending the filename with an underscore, like: `_filename.mustache` - -You can also exclude complete directories by prepending the directory name with an underscore, like: `/_experiment/...` - -##### Style Guide Excludes - -Exclude whole pattern types from the "All patterns" styleguide by adding entries to `patternlab-config.json`. This is quite useful to make speedier. Pattern Lab Node ships with the following: - -``` -"styleGuideExcludes": [ - "templates", - "pages" -] -``` - - -##### Debug Mode -`patternlab.json` is a file created for debugging purposes. Set `debug` to true in `.patternlab-config.json` to see all the secrets. - -##### Server & BrowserSync -Running `grunt serve` or `gulp serve` will compile the Pattern Lab frontend and host it by default on http://localhost:3000 via [BrowserSync](http://www.browsersync.io/docs/). After it starts, templates, `data.json`, and scss/css changes in your source code will be automatically injected into the page. - -You'll notice that if you have this open across different browsers, we do our best to keep the frontend in sync, but there is a known issue with synced navigation using the main menu. - -### Roadmap - - -A roadmap exists for Pattern Lab Node. Check it out [here](https://github.com/pattern-lab/patternlab-node/issues/134). The Node version of Pattern Lab is maintained by [@bmuenzenmeyer](https://twitter.com/bmuenzenmeyer) and contributors. Pull requests welcome, but please take a moment to read the [guidelines](https://github.com/pattern-lab/patternlab-node/blob/master/CONTRIBUTING.md). - -Dave Olsen has also published the [specification](https://github.com/pattern-lab/the-spec/blob/draft/SPEC.md) for Pattern Lab ports. Development will be oriented toward compliance with this as the spec and the port mature together. Post v1 work will focus on other pattern engines and a plugin architecture. - -### Advanced Pattern Library Features - -##### Pattern Parameters -Pattern parameters are a simple mechanism for replacing Mustache variables via attributes on a pattern partial tag rather than having to use a pattern-specific json file. They are especially useful when you want to supply distinct values for Mustache variables in a specific pattern partial instance that may be included multiple times in a molecule, template, or page. - -The basic syntax is this: - -``` -{{> molecules-single-comment(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }} -``` - -The attributes listed in the pattern parameters should match Mustache variable names in your pattern. The values listed for each attribute will replace the Mustache variables. Again, pattern parameters are a simple find and replace of Mustache variables with the supplied values. - -Pattern parameters **do not** currently support the following: - -* sub-lists (e.g. iteration of a section), -* and the use of long strings of text can be unwieldy -* nested properties within the parameter data, such as `{{> molecules-single-comment(foo.bar: 'baz') }}` - -You can read the full documentation on pattern parameters here: [Using Pattern Parameters](http://patternlab.io/docs/pattern-parameters.html) - -##### Pattern Style Modifiers -Style Modifiers allow you to create a base pattern that you can easily modify by adding a class name to the pattern partial. Read more about them [here](http://patternlab.io/docs/pattern-stylemodifier.html), including support with pattern parameters. Below is the gist. - -The basic syntax is this: - -``` -{{> atoms-message:error }} -``` - -This works by using a reserved mustache variable of sorts called {{ styleModifier }} applied to the atoms-message mustache file itself: - -``` -
    {{ message }}
    -``` - -Once rendered, it looks like this: - -``` -
    -
    -
    -``` - -You may also specify multiple classes using a pipe character (|). - -``` -{{> atoms-message:error|is-on }} -``` - - - -##### Pseudo-Patterns -Pseudo-patterns are meant to give developers the ability to build multiple and unique **rendered** patterns off of one base pattern and its mark-up while giving them control over the data that is injected into the base pattern. This feature is especially useful when developing template- and page-style patterns. - -Pseudo-patterns are, essentially, the pattern-specific JSON files that would accompany a pattern. Rather than require a Mustache pattern, though, pseudo-patterns are hinted so a developer can reference a shared pattern. The basic syntax: - -`patternName~pseudoPatternName.json` - -The tilde, `~`, and JSON extension denotes that this is a pseudo-pattern. `patternName` is the parent pattern that will be used when rendering the pseudo-pattern. `patternName` and `pseudoPatternName` are combined when adding the pseudo-pattern to the navigation. - -The JSON file itself works exactly like the [pattern-specific JSON file](http://patternlab.io/docs/data-pattern-specific.html). It has the added benefit that the pseudo-pattern will also import any values from the parent pattern's pattern-specific JSON file. Here is an example (which ships with the package) where we want to show an emergency notification on our homepage template. Our `03-templates/` directory looks like this: - -``` -00-homepage.mustache -01-blog.mustache -02-article.mustache -``` - -Our `00-homepage.mustache` template might look like this: - -``` -
    - {{# emergency }} -
    Oh Noes! Emergency!
    - {{/ emergency }} - { ...a bunch of other content... } -
    -``` - -If our `_data.json` file doesn't give a value for `emergency` that section will never show up when `00-homepage.mustache` is rendered. - -We want to show both the regular and emergency states of the homepage but we don't want to duplicate the entire `00-homepage.mustache` template. That would be a maintenance nightmare. So let's add our pseudo-pattern: - -``` -00-homepage.mustache -00-homepage~emergency.json -01-blog.mustache -02-article.mustache -``` - -In our pseudo-pattern, `00-homepage~emergency.json`, we add our `emergency` attribute: - -``` -{ - "emergency": true -} -``` - -Now when we generate our site we'll have our homepage template rendered twice. Once as the regular template and once as a pseudo-pattern showing the emergency section. Note that the pseudo-pattern will show up in our navigation as `Homepage Emergency`. - -##### Pattern Linking -You can build patterns that link to one another to help simulate using a real website. This is especially useful when working with the Pages and Templates pattern types. The basic format is: - -`{{ link.pattern-name }}` - -For example, if you wanted to add a link to the `home page` template from your `blog` template you could write the following: - -`Home` - -This would compile to: - -`Home` - -As you can see, it's a much easier way of linking patterns to one another. - -=== - -## Working with Patterns +## Upgrading -(The following documentation is built for the PHP version of Pattern Lab, but most applies to the node version too. If you find omissions or mistakes please open an issue.) +If you find yourself here and are looking to ugpgrade, check out how to upgrade from version to version of Pattern Lab Node here: [https://github.com/pattern-lab/patternlab-node/wiki/Upgrading](https://github.com/pattern-lab/patternlab-node/wiki/Upgrading) -Patterns are the core element of Pattern Lab. Understanding how they work is the key to getting the most out of the system. Patterns use [Mustache](http://mustache.github.io/) so please read [Mustache's docs](http://mustache.github.io/mustache.5.html) as well. +## Command Line Interface -* [How Patterns Are Organized](http://patternlab.io/docs/pattern-organization.html) -* [Adding New Patterns](http://patternlab.io/docs/pattern-add-new.html) -* [Reorganizing Patterns](http://patternlab.io/docs/pattern-reorganizing.html) -* [Including One Pattern Within Another via Partials](http://patternlab.io/docs/pattern-including.html) -* [Managing Assets for a Pattern: JavaScript, images, CSS, etc.](http://patternlab.io/docs/pattern-managing-assets.html) -* [Modifying the Pattern Header and Footer](http://patternlab.io/docs/pattern-header-footer.html) -* [Using Pattern Parameters](http://patternlab.io/docs/pattern-parameters.html) -* [Using Pattern State](http://patternlab.io/docs/pattern-states.html) -* ["Hiding" Patterns in the Navigation](http://patternlab.io/docs/pattern-hiding.html) -* [Adding Annotations](http://patternlab.io/docs/pattern-adding-annotations.html) -* [Viewing Patterns on a Mobile Device](http://patternlab.io/docs/pattern-mobile-view.html) +The [command line interface](https://github.com/pattern-lab/patternlab-node/wiki/Command-Line-Interface) is documented in the wiki, and already implemented for you within [Node Editions](https://github.com/pattern-lab?utf8=%E2%9C%93&query=edition-node). -## Creating & Working With Dynamic Data for a Pattern +## Contributing -The Node version of Pattern Lab utilizes Mustache as the template language for patterns. In addition to allowing for the [inclusion of one pattern within another](http://patternlab.io/docs/pattern-including.html) it also gives pattern developers the ability to include variables. This means that attributes like image sources can be centralized in one file for easy modification across one or more patterns. The Node version of Pattern Lab uses a JSON file, `source/_data/data.json`, to centralize many of these attributes. +If you'd like to contribute to Pattern Lab Node, please do so! There is always a lot of ground to cover and something for your wheelhouse. -* [Introduction to JSON & Mustache Variables](http://patternlab.io/docs/data-json-mustache.html) -* [Overriding the Central `data.json` Values with Pattern-specific Values](http://patternlab.io/docs/data-pattern-specific.html) -* [Linking to Patterns with Pattern Lab's Default `link` Variable](http://patternlab.io/docs/data-link-variable.html) -* [Creating Lists with Pattern Lab's Default `listItems` Variable](http://patternlab.io/docs/data-listitems.html) +No pull request is too small. Check out any [up for grabs issues](https://github.com/pattern-lab/patternlab-node/labels/up%20for%20grabs) as a good way to get your feet wet, or add some more unit tests. -## Using Pattern Lab's Advanced Features +## Guidelines +1. Please keep your pull requests concise and limited to **ONE** substantive change at a time. This makes reviewing and testing so much easier. +2. _ALWAYS_ submit pull requests against the [dev branch](https://github.com/pattern-lab/patternlab-node/tree/dev). If this does not occur, I will first, try to redirect you gently, second, port over your contribution manually if time allows, and/or third, close your pull request. If you have a major feature to stabilize over time, talk to @bmuenzenmeyer about making a dedicated `feature-branch` +3. If you can, add some unit tests using the existing patterns in the `./test` directory +4. To help hack on core from an edition, read [this wiki page](https://github.com/pattern-lab/patternlab-node/wiki/Running-an-Edition-Against-Local-Core) -By default, the Pattern Lab assets can be manually generated and the Pattern Lab site manually refreshed but who wants to waste time doing that? Here are some ways that Pattern Lab can make your development workflow a little smoother: +## Coding style +Two files combine within the project to define and maintain our coding style. -* [Watching for Changes and Auto-Regenerating Patterns](http://patternlab.io/docs/advanced-auto-regenerate.html) - Node version coming soon -* [Auto-Reloading the Browser Window When Changes Are Made](http://patternlab.io/docs/advanced-reload-browser.html) - Node version coming soon -* [Multi-browser & Multi-device Testing with Page Follow](http://patternlab.io/docs/advanced-page-follow.html) -* [Keyboard Shortcuts](http://patternlab.io/docs/advanced-keyboard-shortcuts.html) -* [Special Pattern Lab-specific Query String Variables ](http://patternlab.io/docs/pattern-linking.html) -* [Preventing the Cleaning of public/](http://patternlab.io/docs/advanced-clean-public.html) - Node version coming soon -* [Modifying the Pattern Lab Nav](http://patternlab.io/docs/advanced-pattern-lab-nav.html) - Node version coming soon -* [Editing the config.ini Options](http://patternlab.io/docs/advanced-config-options.html) - Node version coming soon +* The `.editorconfig` controls spaces / tabs within supported editors. Check out their [site](http://editorconfig.org/). +* The `.eslintrc` defines our javascript standards. Some editors will evaluate this real-time - otherwise it's run using `grunt|gulp build` From 6f87215cdb8caa9e85a2159d3f4980a6b3b9de03 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sat, 11 Jun 2016 12:22:16 -0500 Subject: [PATCH 175/187] added explicit links to gulp and grunt editions from core --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 1f5b87805..0c50d0fc6 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,9 @@ This repository contains the core functionality for Pattern Lab Node. Pattern Lab Core is designed to be included as a dependency within [Node Editions](https://github.com/pattern-lab?utf8=%E2%9C%93&query=edition-node). If this looks **REALLY DIFFERENT** from what you expected, check out the [ChangeLog](https://github.com/pattern-lab/patternlab-node/wiki/ChangeLog). +* [Pattern Lab/Node: Gulp Edition](https://github.com/pattern-lab/edition-node-gulp) contains info how to get started within a Gulp task running environment. +* [Pattern Lab/Node: Grunt Node Edition](https://github.com/pattern-lab/edition-node-grunt) contains info how to get started within a Grunt task running environment. + ## Core Team * [@bmuenzenmeyer](https://github.com/bmuenzenmeyer) - Lead Maintainer From 16bbe3d86a11a544f81662c81e2ef5b74cf13719 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sat, 11 Jun 2016 18:08:25 -0500 Subject: [PATCH 176/187] add gitter information --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0c50d0fc6..9e56f6fb3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/pattern-lab/patternlab-node.png?branch=master)](https://travis-ci.org/pattern-lab/patternlab-node) +[![Build Status](https://travis-ci.org/pattern-lab/patternlab-node.png?branch=master)](https://travis-ci.org/pattern-lab/patternlab-node) [![Join the chat at Gitter](https://badges.gitter.im/pattern-lab/node.svg)](https://gitter.im/pattern-lab/node) # Pattern Lab Node Core @@ -38,3 +38,7 @@ Two files combine within the project to define and maintain our coding style. * The `.editorconfig` controls spaces / tabs within supported editors. Check out their [site](http://editorconfig.org/). * The `.eslintrc` defines our javascript standards. Some editors will evaluate this real-time - otherwise it's run using `grunt|gulp build` + +## Gitter + +The Pattern Lab Node team uses [our gitter.im channel, pattern-lab/node](https://gitter.im/pattern-lab/node) to keep in sync, share updates, and talk shop. Please stop by to say hello or as a first place to turn if stuck. Other channels in the Pattern Lab organization can be found on gitter too. From 4bbf0b85b2bc18b4997b31691e9e74e3f9e7ada3 Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Wed, 15 Jun 2016 09:22:08 -0500 Subject: [PATCH 177/187] add callback to build and patternsonly calls - and are now explicitly deleting when told to do so --- core/lib/patternlab.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index dd56a38e4..6fc111887 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -1,10 +1,10 @@ -/* - * patternlab-node - v2.0.0-alpha - 2016 - * +/* + * patternlab-node - v2.0.0-alpha - 2016 + * * Brian Muenzenmeyer, Geoff Pursell, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ @@ -254,6 +254,7 @@ var patternlab_engine = function (config) { //delete the contents of config.patterns.public before writing if (deletePatternDir) { + fs.removeSync(paths.public.patterns); fs.emptyDirSync(paths.public.patterns); } @@ -351,17 +352,19 @@ var patternlab_engine = function (config) { version: function () { return getVersion(); }, - build: function (deletePatternDir) { + build: function (callback, deletePatternDir) { buildPatterns(deletePatternDir); buildFrontEnd(patternlab); printDebug(); + callback(); }, help: function () { help(); }, - patternsonly: function (deletePatternDir) { + patternsonly: function (callback, deletePatternDir) { buildPatterns(deletePatternDir); printDebug(); + callback(); }, liststarterkits: function () { return listStarterkits(); From c99d91318ff7febef4260816fed806888984334e Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Wed, 15 Jun 2016 15:31:25 -0500 Subject: [PATCH 178/187] support a clean option when loading starterkits --- core/lib/patternlab.js | 16 +++++++++------- core/lib/starterkit_manager.js | 28 ++++++++++++++++++++-------- core/lib/utilities.js | 25 +++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 6fc111887..a5aafdd40 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -121,14 +121,16 @@ var patternlab_engine = function (config) { console.log(''); plutils.logGreen(' patternlab:loadstarterkit'); - console.log(' > Load a starterkit into config.paths.soource/*'); - console.log(' > NOTE: This does overwrite any existing contents, and does not clean the directory first.'); + console.log(' > Load a starterkit into config.paths.source/*'); + console.log(' > NOTE: Overwrites existing content, and only cleans out existing directory if --clean=true argument is passed.'); console.log(' > NOTE: In most cases, `npm install starterkit-name` will precede this call.'); console.log(' > arguments:'); console.log(' -- kit '); console.log(' > the name of the starter kit to load'); + console.log(' -- clean '); + console.log(' > removes all files from config.paths.source/ prior to load'); console.log(' > example (gulp):'); - console.log(' `gulp patternlab:starterkit-load --kit=starterkit-mustache-demo`'); + console.log(' `gulp patternlab:loadstarterkit --kit=starterkit-mustache-demo`'); console.log(''); console.log('==============================='); @@ -175,9 +177,9 @@ var patternlab_engine = function (config) { return starterkit_manager.list_starterkits(); } - function loadStarterKit(starterkitName) { + function loadStarterKit(starterkitName, clean) { var starterkit_manager = new sm(patternlab); - starterkit_manager.load_starterkit(starterkitName); + starterkit_manager.load_starterkit(starterkitName, clean); } function buildPatterns(deletePatternDir) { @@ -369,8 +371,8 @@ var patternlab_engine = function (config) { liststarterkits: function () { return listStarterkits(); }, - loadstarterkit: function (starterkitName) { - loadStarterKit(starterkitName); + loadstarterkit: function (starterkitName, clean) { + loadStarterKit(starterkitName, clean); } }; }; diff --git a/core/lib/starterkit_manager.js b/core/lib/starterkit_manager.js index caffc9c55..e14503d45 100644 --- a/core/lib/starterkit_manager.js +++ b/core/lib/starterkit_manager.js @@ -3,29 +3,41 @@ var starterkit_manager = function (pl) { var path = require('path'), fs = require('fs-extra'), + util = require('./utilities'), paths = pl.config.paths; - function loadStarterKit(starterkitName) { + function loadStarterKit(starterkitName, clean) { try { var kitPath = path.resolve( path.join(process.cwd(), 'node_modules', starterkitName, pl.config.starterkitSubDir) ); - var kitPathDirExists = fs.statSync(kitPath).isDirectory(); + console.log('Attempting to load starterkit from', kitPath); + try { + var kitDirStats = fs.statSync(kitPath); + } catch (ex) { + util.logRed(starterkitName + ' not found, please use npm to install it first.'); + util.logRed(starterkitName + ' not loaded.'); + return; + } + var kitPathDirExists = kitDirStats.isDirectory(); if (kitPathDirExists) { - //todo check and prompt user is paths().source is not empty + if (clean) { + console.log('Deleting contents of', paths.source.root, 'prior to starterkit load.'); + util.emptyDirectory(paths.source.root); + } else { + console.log('Overwriting contents of', paths.source.root, 'during starterkit load.'); + } fs.copy(kitPath, paths.source.root, function (ex) { if (ex) { console.error(ex); } - console.log('starterkit ' + starterkitName + ' loaded successfully.'); + util.logGreen('starterkit ' + starterkitName + ' loaded successfully.'); }); - } } catch (ex) { console.log(ex); - console.log(starterkitName + ' not found, please use npm to install it first'); } } @@ -38,8 +50,8 @@ var starterkit_manager = function (pl) { } return { - load_starterkit: function (starterkitName) { - loadStarterKit(starterkitName); + load_starterkit: function (starterkitName, clean) { + loadStarterKit(starterkitName, clean); }, list_starterkits: function () { listStarterkits(); diff --git a/core/lib/utilities.js b/core/lib/utilities.js index ef4e866fc..4765e874b 100644 --- a/core/lib/utilities.js +++ b/core/lib/utilities.js @@ -1,5 +1,8 @@ "use strict"; +var fs = require('fs-extra'), + path = require('path'); + var util = { // http://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array-in-javascript shuffle: function (o) { @@ -58,6 +61,28 @@ var util = { if (obj.hasOwnProperty(prop)) { return false; } } return true; + }, + + // recursively delete the contents of directory + // adapted from https://gist.github.com/tkihira/2367067 + emptyDirectory: function (dir, cleanDir) { + var list = fs.readdirSync(dir); + for (var i = 0; i < list.length; i++) { + var filename = path.join(dir, list[i]); + var stat = fs.statSync(filename); + + if (filename === "." || filename === "..") { + // pass these files + } else if (stat.isDirectory()) { + this.emptyDirectory(filename); + } else { + // rm fiilename + fs.unlinkSync(filename); + } + } + if (cleanDir) { + fs.rmdirSync(dir); + } } }; From ea614104c7f452fb6a6d58c3f0f626a4f09af63f Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Fri, 17 Jun 2016 14:26:05 -0500 Subject: [PATCH 179/187] tamp down this message to only when debug mode is on --- core/lib/annotation_exporter.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/core/lib/annotation_exporter.js b/core/lib/annotation_exporter.js index c6effadae..0000e2bbd 100644 --- a/core/lib/annotation_exporter.js +++ b/core/lib/annotation_exporter.js @@ -16,7 +16,9 @@ var annotations_exporter = function (pl) { try { var oldAnnotations = fs.readFileSync(path.resolve(paths.source.annotations, 'annotations.js'), 'utf8'); } catch (ex) { - console.log('annotations.js file missing from ' + paths.source.annotations + '. This may be expected.'); + if (pl.config.debug) { + console.log('annotations.js file missing from ' + paths.source.annotations + '. This may be expected.'); + } return []; } @@ -43,7 +45,9 @@ var annotations_exporter = function (pl) { try { annotationsMD = fs.readFileSync(path.resolve(paths.source.annotations, 'annotations.md'), 'utf8'); } catch (ex) { - console.log('annotations.md file missing from ' + paths.source.annotations + '. This may be expected.'); + if (pl.config.debug) { + console.log('annotations.md file missing from ' + paths.source.annotations + '. This may be expected.'); + } return []; } From e07ffcbbf72647000e9cd80d60335fd29727584c Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sun, 19 Jun 2016 06:01:16 -0500 Subject: [PATCH 180/187] working link parsing within list items and improvements to pseudopattern processing. still needs some refactoring and unit test coverage --- core/lib/list_item_hunter.js | 2 ++ core/lib/object_factory.js | 2 +- core/lib/pattern_assembler.js | 17 +++++++++++------ core/lib/pseudopattern_hunter.js | 1 + core/lib/ui_builder.js | 2 +- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/core/lib/list_item_hunter.js b/core/lib/list_item_hunter.js index ec4199327..35c077f5d 100644 --- a/core/lib/list_item_hunter.js +++ b/core/lib/list_item_hunter.js @@ -47,7 +47,9 @@ var list_item_hunter = function () { console.log('There was an error parsing JSON for ' + pattern.relPath); console.log(err); } + listData = plutils.mergeData(listData, pattern.listitems); + listData = pattern_assembler.parse_data_links_specific(patternlab, listData, 'listitems.json + any pattern listitems.json'); //iterate over each copied block, rendering its contents along with pattenlab.listitems[i] for (var i = 0; i < repeatedBlockTemplate.length; i++) { diff --git a/core/lib/object_factory.js b/core/lib/object_factory.js index 8fe9aa902..1a55c5760 100644 --- a/core/lib/object_factory.js +++ b/core/lib/object_factory.js @@ -16,7 +16,7 @@ var Pattern = function (relPath, data) { this.fileExtension = pathObj.ext; // '.mustache' // this is the unique name, subDir + fileName (sans extension) - this.name = this.subdir.replace(/[\/\\]/g, '-') + '-' + this.fileName; // '00-atoms-00-global-00-colors' + this.name = this.subdir.replace(/[\/\\]/g, '-') + '-' + this.fileName.replace('~', '-'); // '00-atoms-00-global-00-colors' // the JSON used to render values in the pattern this.jsonFileData = data || {}; diff --git a/core/lib/pattern_assembler.js b/core/lib/pattern_assembler.js index 6133dcc6a..23759ebcf 100644 --- a/core/lib/pattern_assembler.js +++ b/core/lib/pattern_assembler.js @@ -4,6 +4,7 @@ var pattern_assembler = function () { var path = require('path'), fs = require('fs-extra'), Pattern = require('./object_factory').Pattern, + pph = require('./pseudopattern_hunter'), md = require('markdown-it')(), plutils = require('./utilities'), patternEngines = require('./pattern_engines'); @@ -123,6 +124,9 @@ var pattern_assembler = function () { } function processPatternIterative(relPath, patternlab) { + + var pseudopattern_hunter = new pph(); + //extract some information var filename = path.basename(relPath); var ext = path.extname(filename); @@ -198,17 +202,18 @@ var pattern_assembler = function () { //add currentPattern to patternlab.patterns array addPattern(currentPattern, patternlab); + //look for a pseudo pattern by checking if there is a file containing same name, with ~ in it, ending in .json + pseudopattern_hunter.find_pseudopatterns(currentPattern, patternlab); + return currentPattern; } function processPatternRecursive(file, patternlab) { var lh = require('./lineage_hunter'), - pph = require('./pseudopattern_hunter'), lih = require('./list_item_hunter'); var lineage_hunter = new lh(), - list_item_hunter = new lih(), - pseudopattern_hunter = new pph(); + list_item_hunter = new lih(); //find current pattern in patternlab object using var file as a partial var currentPattern, i; @@ -247,9 +252,6 @@ var pattern_assembler = function () { //add to patternlab object so we can look these up later. addPattern(currentPattern, patternlab); - - //look for a pseudo pattern by checking if there is a file containing same name, with ~ in it, ending in .json - pseudopattern_hunter.find_pseudopatterns(currentPattern, patternlab); } function expandPartials(foundPatternPartials, list_item_hunter, patternlab, currentPattern) { @@ -376,6 +378,9 @@ var pattern_assembler = function () { }, parse_data_links: function (patternlab) { parseDataLinks(patternlab); + }, + parse_data_links_specific: function (patternlab, data, label){ + return parseDataLinksHelper(patternlab, data, label) } }; diff --git a/core/lib/pseudopattern_hunter.js b/core/lib/pseudopattern_hunter.js index c49b93aca..ddbfdd899 100644 --- a/core/lib/pseudopattern_hunter.js +++ b/core/lib/pseudopattern_hunter.js @@ -42,6 +42,7 @@ var pseudopattern_hunter = function () { var patternVariant = Pattern.create(variantFilePath, variantFileData, { //use the same template as the non-variant template: currentPattern.template, + fileExtension: currentPattern.fileExtension, extendedTemplate: currentPattern.extendedTemplate, isPseudoPattern: true, basePattern: currentPattern, diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index 7e99135ee..90d45e0f3 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -11,7 +11,7 @@ var eol = require('os').EOL; function addToPatternPaths(patternlab, patternTypeName, pattern) { //this is messy, could use a refactor. - patternlab.patternPaths[patternTypeName][pattern.patternBaseName] = pattern.subdir.replace(/\\/g, '/') + "/" + pattern.fileName; + patternlab.patternPaths[patternTypeName][pattern.patternBaseName] = pattern.subdir.replace(/\\/g, '/') + "/" + pattern.fileName.replace('~', '-'); } //todo: refactor this as a method on the pattern object itself once we merge dev with pattern-engines branch From cb328f4b29ea24cf65860e8ce0bfb38b7f833758 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sun, 19 Jun 2016 06:04:38 -0500 Subject: [PATCH 181/187] removing a unit test that no longer applies. it should be refactored --- test/pattern_assembler_tests.js | 57 --------------------------------- 1 file changed, 57 deletions(-) diff --git a/test/pattern_assembler_tests.js b/test/pattern_assembler_tests.js index 92c7ea73f..bc649ac62 100644 --- a/test/pattern_assembler_tests.js +++ b/test/pattern_assembler_tests.js @@ -538,63 +538,6 @@ test.equals(bookendPattern.extendedTemplate.replace(/\s\s+/g, ' ').replace(/\n/g, ' ').trim(), expectedValue.trim()); test.done(); }, - 'processPatternIterative - ignores files that are variants' : function(test){ - //arrange - var diveSync = require('diveSync'); - var fs = require('fs-extra'); - var pa = require('../core/lib/pattern_assembler'); - var pattern_assembler = new pa(); - var patterns_dir = './test/files/_patterns'; - var patternlab = {}; - //THIS IS BAD. - patternlab.config = fs.readJSONSync('./patternlab-config.json'); - patternlab.config.paths.source.patterns = patterns_dir; - - //patternlab.data = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'data.json')); - patternlab.data = {}; - //patternlab.listitems = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'listitems.json')); - patternlab.listitems = {}; - //patternlab.header = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'templates/pattern-header-footer/header.html'), 'utf8'); - patternlab.header = ''; - //patternlab.footer = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'templates/pattern-header-footer/footer.html'), 'utf8'); - patternlab.footer = ''; - patternlab.patterns = []; - patternlab.data.link = {}; - patternlab.partials = {}; - - //act - diveSync(patterns_dir, - { - filter: function(path, dir){ - if(dir){ - var remainingPath = path.replace(patterns_dir, ''); - var isValidPath = remainingPath.indexOf('/_') === -1; - return isValidPath; - } - return true; - } - }, - function(err, file){ - //log any errors - if(err){ - console.log(err); - return; - } - - pattern_assembler.process_pattern_iterative(path.resolve(file), patternlab); - } - ); - - //assert - var foundVariant = false; - for(var i = 0; i < patternlab.patterns.length; i++){ - if(patternlab.patterns[i].fileName.indexOf('~') > -1){ - foundVariant = true; - } - } - test.equals(foundVariant, false); - test.done(); - }, 'setState - applies any patternState matching the pattern' : function(test){ //arrange var pa = require('../core/lib/pattern_assembler'); From 49538bd93bd6cd0281dbdb1c3d7d8139fd0ce5f4 Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Mon, 20 Jun 2016 09:34:54 -0500 Subject: [PATCH 182/187] spec changes https://github.com/pattern-lab/the-spec/issues/15 https://github.com/pattern-lab/the-spec/issues/13 closes #364 closes #365 --- core/lib/ui_builder.js | 92 ++++++++++++++++++++++++++++++++++++------ patternlab-config.json | 1 - 2 files changed, 80 insertions(+), 13 deletions(-) diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index 90d45e0f3..f14e160a3 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -11,6 +11,9 @@ var eol = require('os').EOL; function addToPatternPaths(patternlab, patternTypeName, pattern) { //this is messy, could use a refactor. + if (!patternlab.patternPaths[patternTypeName]) { + patternlab.patternPaths[patternTypeName] = {}; + } patternlab.patternPaths[patternTypeName][pattern.patternBaseName] = pattern.subdir.replace(/\\/g, '/') + "/" + pattern.fileName.replace('~', '-'); } @@ -29,31 +32,52 @@ function assembleStyleguidePatterns(patternlab) { if (styleguideExcludes && styleguideExcludes.length) { for (var i = 0; i < patternlab.patterns.length; i++) { + var pattern = patternlab.patterns[i]; + // skip underscore-prefixed files - if (isPatternExcluded(patternlab.patterns[i])) { + if (isPatternExcluded(pattern)) { if (patternlab.config.debug) { - console.log('Omitting ' + patternlab.patterns[i].patternPartial + " from styleguide pattern exclusion."); + console.log('Omitting ' + pattern.patternPartial + " from styleguide pattern exclusion."); } continue; } - var partial = patternlab.patterns[i].patternPartial; + //this is meant to be a homepage that is not present anywhere else + if (pattern.patternPartial === patternlab.config.defaultPattern) { + if (patternlab.config.debug) { + console.log('omitting ' + pattern.patternPartial + ' from styleguide patterns because it is defined as a defaultPattern'); + } + continue; + } + + var partial = pattern.patternPartial; var partialType = partial.substring(0, partial.indexOf('-')); var isExcluded = (styleguideExcludes.indexOf(partialType) > -1); if (!isExcluded) { - styleguidePatterns.push(patternlab.patterns[i]); + styleguidePatterns.push(pattern); } } } else { for (i = 0; i < patternlab.patterns.length; i++) { + var pattern = patternlab.patterns[i]; + // skip underscore-prefixed files - if (isPatternExcluded(patternlab.patterns[i])) { + if (isPatternExcluded(pattern)) { if (patternlab.config.debug) { - console.log('Omitting ' + patternlab.patterns[i].patternPartial + " from styleguide pattern exclusion."); + console.log('Omitting ' + pattern.patternPartial + " from styleguide pattern exclusion."); } continue; } - styleguidePatterns.push(patternlab.patterns[i]); + + //this is meant to be a homepage that is not present anywhere else + if (pattern.patternPartial === patternlab.config.defaultPattern) { + if (patternlab.config.debug) { + console.log('omitting ' + pattern.patternPartial + ' from styleguide patterns because it is defined as a defaultPattern'); + } + continue; + } + + styleguidePatterns.push(pattern); } } @@ -68,6 +92,19 @@ function buildNavigation(patternlab) { //todo: check if this is already available var patternTypeName = pattern.name.replace(/\\/g, '-').split('-')[1]; + //exclude any named defaultPattern from the navigation. + //this is meant to be a homepage that is not navigable + if (pattern.patternPartial === patternlab.config.defaultPattern) { + if (patternlab.config.debug) { + console.log('omitting ' + pattern.patternPartial + ' from navigation because it is defined as a defaultPattern'); + } + + //add to patternPaths before continuing + addToPatternPaths(patternlab, patternTypeName, pattern); + + continue; + } + // skip underscore-prefixed files. don't create a patternType on account of an underscored pattern if (isPatternExcluded(pattern)) { continue; @@ -101,7 +138,7 @@ function buildNavigation(patternlab) { var patternType = new of.oPatternType(patternTypeName); //add patternPath and viewAllPath - patternlab.patternPaths[patternTypeName] = {}; + patternlab.patternPaths[patternTypeName] = patternlab.patternPaths[patternTypeName] || {}; patternlab.viewAllPaths[patternTypeName] = {}; //test whether the pattern structure is flat or not - usually due to a template or page @@ -246,15 +283,24 @@ function buildViewAllPages(mainPageHeadHtml, patternlab) { var i; for (i = 0; i < patternlab.patterns.length; i++) { + + var pattern = patternlab.patterns[i]; + // skip underscore-prefixed files - if (isPatternExcluded(patternlab.patterns[i])) { + if (isPatternExcluded(pattern)) { if (patternlab.config.debug) { - console.log('Omitting ' + patternlab.patterns[i].patternPartial + " from view all rendering."); + console.log('Omitting ' + pattern.patternPartial + " from view all rendering."); } continue; } - var pattern = patternlab.patterns[i]; + //this is meant to be a homepage that is not present anywhere else + if (pattern.patternPartial === patternlab.config.defaultPattern) { + if (patternlab.config.debug) { + console.log('Omitting ' + pattern.patternPartial + ' from view all rendering because it is defined as a defaultPattern'); + } + continue; + } //create the view all for the section // check if the current section is different from the previous one @@ -275,6 +321,14 @@ function buildViewAllPages(mainPageHeadHtml, patternlab) { continue; } + //this is meant to be a homepage that is not present anywhere else + if (patternlab.patterns[j].patternPartial === patternlab.config.defaultPattern) { + if (patternlab.config.debug) { + console.log('Omitting ' + pattern.patternPartial + ' from view all sibling rendering because it is defined as a defaultPattern'); + } + continue; + } + viewAllPatterns.push(patternlab.patterns[j]); } } @@ -306,6 +360,14 @@ function buildViewAllPages(mainPageHeadHtml, patternlab) { continue; } + //this is meant to be a homepage that is not present anywhere else + if (patternlab.patterns[j].patternPartial === patternlab.config.defaultPattern) { + if (patternlab.config.debug) { + console.log('Omitting ' + pattern.patternPartial + ' from view all sibling rendering because it is defined as a defaultPattern'); + } + continue; + } + viewAllPatterns.push(patternlab.patterns[j]); } } @@ -428,11 +490,17 @@ function buildFrontEnd(patternlab) { //plugins someday output += 'var plugins = [];' + eol; + + //smaller config elements + output += 'var defaultShowPatternInfo = ' + (patternlab.config.defaultShowPatternInfo ? patternlab.config.defaultShowPatternInfo : 'false') + ';' + eol; + output += 'var defaultPattern = "' + (patternlab.config.defaultPattern ? patternlab.config.defaultPattern : 'all') + '";' + eol; + + //write all ouytput to patternlab-data fs.outputFileSync(path.resolve(paths.public.data, 'patternlab-data.js'), output); //annotations var annotationsJSON = annotation_exporter.gather(); - var annotations = 'var comments = ' + JSON.stringify(annotationsJSON); + var annotations = 'var comments = { "comments" : ' + JSON.stringify(annotationsJSON) + '};'; fs.outputFileSync(path.resolve(paths.public.annotations, 'annotations.js'), annotations); } diff --git a/patternlab-config.json b/patternlab-config.json index c82b2a336..984ec73c0 100644 --- a/patternlab-config.json +++ b/patternlab-config.json @@ -55,6 +55,5 @@ }, "patternExportPatternPartials": [], "patternExportDirectory": "./pattern_exports/", - "baseurl" : "", "cacheBust": true } From d9f677f662ee49817c49cd952592bdeee87819ad Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Mon, 20 Jun 2016 12:07:02 -0500 Subject: [PATCH 183/187] bump version number --- core/lib/pattern_assembler.js | 2 +- core/lib/patternlab.js | 12 ++++++------ package.json | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/lib/pattern_assembler.js b/core/lib/pattern_assembler.js index 23759ebcf..4cc8137fb 100644 --- a/core/lib/pattern_assembler.js +++ b/core/lib/pattern_assembler.js @@ -379,7 +379,7 @@ var pattern_assembler = function () { parse_data_links: function (patternlab) { parseDataLinks(patternlab); }, - parse_data_links_specific: function (patternlab, data, label){ + parse_data_links_specific: function (patternlab, data, label) { return parseDataLinksHelper(patternlab, data, label) } }; diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index a5aafdd40..bcbae9e59 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -1,10 +1,10 @@ -/* - * patternlab-node - v2.0.0-alpha - 2016 - * +/* + * patternlab-node - v2.0.0-alpha.2 - 2016 + * * Brian Muenzenmeyer, Geoff Pursell, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ diff --git a/package.json b/package.json index fc440ec77..9dbaed3a4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "patternlab-node", "description": "Pattern Lab is a collection of tools to help you create atomic design systems. This is the node command line interface (CLI).", - "version": "2.0.0-alpha", + "version": "2.0.0-alpha.2", "main": "./core/lib/patternlab.js", "dependencies": { "diveSync": "^0.3.0", From 9d8d66ae95829d71a93f9b0db0d5c33e8baf6f3b Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Mon, 20 Jun 2016 12:08:07 -0500 Subject: [PATCH 184/187] bumping to alpha.3 --- core/lib/patternlab.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index bcbae9e59..b9aa235d8 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -1,5 +1,5 @@ /* - * patternlab-node - v2.0.0-alpha.2 - 2016 + * patternlab-node - v2.0.0-alpha.3 - 2016 * * Brian Muenzenmeyer, Geoff Pursell, and the web community. * Licensed under the MIT license. diff --git a/package.json b/package.json index 9dbaed3a4..7257cc9ed 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "patternlab-node", "description": "Pattern Lab is a collection of tools to help you create atomic design systems. This is the node command line interface (CLI).", - "version": "2.0.0-alpha.2", + "version": "2.0.0-alpha.3", "main": "./core/lib/patternlab.js", "dependencies": { "diveSync": "^0.3.0", From 29438741a9c318e87516e87f9fc68d8d35f18d78 Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Tue, 21 Jun 2016 07:00:42 -0500 Subject: [PATCH 185/187] Change patternBreadcrumb to an Object Instead of a String closes #363 --- core/lib/patternlab.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index b9aa235d8..88fbf8351 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -1,10 +1,10 @@ -/* - * patternlab-node - v2.0.0-alpha.3 - 2016 - * +/* + * patternlab-node - v2.0.0-alpha.3 - 2016 + * * Brian Muenzenmeyer, Geoff Pursell, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ @@ -316,7 +316,14 @@ var patternlab_engine = function (config) { lineageR: pattern.patternLineagesR, patternLineageEExists: pattern.patternLineageExists || pattern.patternLineageRExists, patternDesc: pattern.patternDescExists ? pattern.patternDesc : '', - patternBreadcrumb: pattern.patternGroup === pattern.patternSubGroup ? pattern.patternGroup : pattern.patternGroup + ' > ' + pattern.patternSubGroup, + patternBreadcrumb: + pattern.patternGroup === pattern.patternSubGroup ? + { + patternType: pattern.patternGroup + } : { + patternType: pattern.patternGroup, + patternSubtype: pattern.patternSubGroup + }, patternExtension: pattern.fileExtension, patternName: pattern.patternName, patternPartial: pattern.patternPartial, From b7797c78fe7ddf1ba85ec744d8589976730c4da4 Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Tue, 21 Jun 2016 07:33:29 -0500 Subject: [PATCH 186/187] added some more error logging --- core/lib/pattern_assembler.js | 38 +++++++++++++++++++++++--------- core/lib/pseudopattern_hunter.js | 9 ++++++-- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/core/lib/pattern_assembler.js b/core/lib/pattern_assembler.js index 4cc8137fb..829cc0bc8 100644 --- a/core/lib/pattern_assembler.js +++ b/core/lib/pattern_assembler.js @@ -154,26 +154,42 @@ var pattern_assembler = function () { //look for a json file for this template try { var jsonFilename = path.resolve(patternsPath, currentPattern.subdir, currentPattern.fileName + ".json"); - currentPattern.jsonFileData = fs.readJSONSync(jsonFilename); - if (patternlab.config.debug) { - console.log('processPatternIterative: found pattern-specific data.json for ' + currentPattern.patternPartial); + try { + var jsonFilenameStats = fs.statSync(jsonFilename); + } catch (err) { + //not a file + } + if (jsonFilenameStats && jsonFilenameStats.isFile()) { + currentPattern.jsonFileData = fs.readJSONSync(jsonFilename); + if (patternlab.config.debug) { + console.log('processPatternIterative: found pattern-specific data.json for ' + currentPattern.patternPartial); + } } } - catch (e) { - // do nothing + catch (err) { + console.log('There was an error parsing sibling JSON for ' + currentPattern.relPath); + console.log(err); } //look for a listitems.json file for this template try { var listJsonFileName = path.resolve(patternsPath, currentPattern.subdir, currentPattern.fileName + ".listitems.json"); - currentPattern.listitems = fs.readJSONSync(listJsonFileName); - buildListItems(currentPattern); - if (patternlab.config.debug) { - console.log('found pattern-specific listitems.json for ' + currentPattern.patternPartial); + try { + var listJsonFileStats = fs.statSync(listJsonFileName); + } catch (err) { + //not a file + } + if (listJsonFileStats && listJsonFileStats.isFile()) { + currentPattern.listitems = fs.readJSONSync(listJsonFileName); + buildListItems(currentPattern); + if (patternlab.config.debug) { + console.log('found pattern-specific listitems.json for ' + currentPattern.patternPartial); + } } } - catch (e) { - // do nothing + catch (err) { + console.log('There was an error parsing sibling listitem JSON for ' + currentPattern.relPath); + console.log(err); } //look for a markdown file for this template diff --git a/core/lib/pseudopattern_hunter.js b/core/lib/pseudopattern_hunter.js index ddbfdd899..47e4b7e57 100644 --- a/core/lib/pseudopattern_hunter.js +++ b/core/lib/pseudopattern_hunter.js @@ -32,8 +32,13 @@ var pseudopattern_hunter = function () { } //we want to do everything we normally would here, except instead read the pseudoPattern data - var variantFileData = fs.readJSONSync(path.resolve(paths.source.patterns, pseudoPatterns[i])); - + try { + var variantFileData = fs.readJSONSync(path.resolve(paths.source.patterns, pseudoPatterns[i])); + } catch (err) { + console.log('There was an error parsing pseudopattern JSON for ' + currentPattern.relPath); + console.log(err); + } + //extend any existing data with variant data variantFileData = plutils.mergeData(currentPattern.jsonFileData, variantFileData); From 412f10b14f0eacf41c289518ef10fe5aba34791d Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Tue, 21 Jun 2016 07:33:44 -0500 Subject: [PATCH 187/187] bumping to 2.0.0 --- core/lib/patternlab.js | 18 +++++++++--------- package.json | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 88fbf8351..45835b5e2 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -1,10 +1,10 @@ -/* - * patternlab-node - v2.0.0-alpha.3 - 2016 - * +/* + * patternlab-node - v2.0.0 - 2016 + * * Brian Muenzenmeyer, Geoff Pursell, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ @@ -186,13 +186,13 @@ var patternlab_engine = function (config) { try { patternlab.data = fs.readJSONSync(path.resolve(paths.source.data, 'data.json')); } catch (ex) { - console.log('missing ' + paths.source.data + 'data.json Pattern Lab may not work without this file.'); + plutils.logRed('missing or malformed' + paths.source.data + 'data.json Pattern Lab may not work without this file.'); patternlab.data = {}; } try { patternlab.listitems = fs.readJSONSync(path.resolve(paths.source.data, 'listitems.json')); } catch (ex) { - console.log('missing ' + paths.source.data + 'listitems.json Pattern Lab may not work without this file.'); + plutils.logRed('missing or malformed' + paths.source.data + 'listitems.json Pattern Lab may not work without this file.'); patternlab.listitems = {}; } try { @@ -203,7 +203,7 @@ var patternlab_engine = function (config) { patternlab.viewAll = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'viewall.mustache'), 'utf8'); } catch (ex) { console.log(ex); - console.log('\nERROR: missing an essential file from ' + paths.source.patternlabFiles + '. Pattern Lab won\'t work without this file.\n'); + plutils.logRed('\nERROR: missing an essential file from ' + paths.source.patternlabFiles + '. Pattern Lab won\'t work without this file.\n'); process.exit(1); } patternlab.patterns = []; diff --git a/package.json b/package.json index 7257cc9ed..35a4d9ca3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "patternlab-node", "description": "Pattern Lab is a collection of tools to help you create atomic design systems. This is the node command line interface (CLI).", - "version": "2.0.0-alpha.3", + "version": "2.0.0", "main": "./core/lib/patternlab.js", "dependencies": { "diveSync": "^0.3.0",