Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'multimap'

Conflicts:
	lib/plates.js
	test/api-test.js
	test/fixtures/test-21.html
	test/fixtures/test-21.json
	test/fixtures/test-21.out
	test/fixtures/test-22.html
	test/fixtures/test-22.json
	test/fixtures/test-22.out
	test/fixtures/test-24.html
	test/fixtures/test-24.json
	test/fixtures/test-24.out
	test/fixtures/test-25.html
	test/fixtures/test-25.json
	test/fixtures/test-25.out
	test/fixtures/test-26.html
	test/fixtures/test-26.json
	test/fixtures/test-26.out
	test/fixtures/test-27.html
	test/fixtures/test-27.json
	test/fixtures/test-27.out
  • Loading branch information...
commit b0515b8b159f725266052462a06d1c6f083bc8c1 2 parents 5450c28 + 4620d18
Pedro Teixeira pgte authored
Showing with 248 additions and 31 deletions.
  1. +36 −8 lib/plates.js
  2. +115 −0 test/api-test.js
  3. +5 −5 test/common.js
  4. +1 −1  test/fixtures/test-21.html
  5. +1 −1  test/fixtures/test-21.json
  6. +1 −1  test/fixtures/test-21.out
  7. +1 −1  test/fixtures/test-22.html
  8. +1 −1  test/fixtures/test-22.json
  9. +1 −1  test/fixtures/test-22.out
  10. +1 −1  test/fixtures/test-24.html
  11. +1 −1  test/fixtures/test-24.json
  12. +1 −1  test/fixtures/test-24.out
  13. +1 −1  test/fixtures/test-25.html
  14. +1 −1  test/fixtures/test-25.json
  15. +1 −1  test/fixtures/test-25.out
  16. +1 −1  test/fixtures/test-26.html
  17. +1 −1  test/fixtures/test-26.json
  18. +1 −1  test/fixtures/test-26.out
  19. +1 −1  test/fixtures/test-27.html
  20. +1 −1  test/fixtures/test-27.json
  21. +1 −1  test/fixtures/test-27.out
  22. +1 −0  test/fixtures/test-31.html
  23. +4 −0 test/fixtures/test-31.json
  24. +1 −0  test/fixtures/test-31.out
  25. +1 −0  test/fixtures/test-32.html
  26. +4 −0 test/fixtures/test-32.json
  27. +1 −0  test/fixtures/test-32.out
  28. +1 −0  test/fixtures/test-34.html
  29. +4 −0 test/fixtures/test-34.json
  30. +1 −0  test/fixtures/test-34.out
  31. +1 −0  test/fixtures/test-35.html
  32. +5 −0 test/fixtures/test-35.json
  33. +1 −0  test/fixtures/test-35.out
  34. +8 −0 test/fixtures/test-36.html
  35. +4 −0 test/fixtures/test-36.json
  36. +8 −0 test/fixtures/test-36.out
  37. +8 −0 test/fixtures/test-37.html
  38. +7 −0 test/fixtures/test-37.json
  39. +14 −0 test/fixtures/test-37.out
44 lib/plates.js
View
@@ -62,6 +62,33 @@ var Plates = (typeof module !== 'undefined' && typeof module.exports !== 'undefi
return result || data[key];
}
+ //
+ // compileMappings
+ //
+ // sort the mappings so that mappings for the same attribute and value go consecutive
+ // and inside those, those that change attributes appear first.
+ //
+ function compileMappings(oldMappings) {
+ var mappings = oldMappings.slice(0);
+ mappings.sort(function(map1, map2) {
+ if (map1.attribute !== map2.attribute) {
+ return map1.attribute < map2.attribute ? -1 : 1;
+ }
+ if (map1.value !== map2.value) {
+ return map1.value < map2.value ? -1 : 1;
+ }
+ if (! ('replace' in map1) && ! ('replace' in map2)) {
+ throw new Error('Conflicting mappings for attribute ' + map1.attribute + ' and value ' + map1.value);
+ }
+ if (map1.replace) {
+ return 1;
+ }
+ return -1;
+ });
+
+ return mappings;
+ }
+
var Merge = function Merge() {};
Merge.prototype = {
nest: [],
@@ -108,7 +135,8 @@ var Plates = (typeof module !== 'undefined' && typeof module.exports !== 'undefi
//
// Iterate over over the supplied HTML.
//
- iterate: function iterate(html, value, components, tagname, key) {
+ iterate: function iterate(html, value, components, tagname, key, map) {
+
var output = '',
segment = html.slice(
html.search(components.input),
@@ -128,7 +156,7 @@ var Plates = (typeof module !== 'undefined' && typeof module.exports !== 'undefi
data = value[i];
}
- output += this.bind(segment, data);
+ output += this.bind(segment, data, map);
}
return output;
@@ -136,7 +164,7 @@ var Plates = (typeof module !== 'undefined' && typeof module.exports !== 'undefi
// We need to refine the selection now that we know we're dealing with a
// nested object
segment = segment.slice(components.input.length, -(tagname.length + 3));
- return output += this.bind(segment, value);
+ return output += this.bind(segment, value, map);
}
return value;
@@ -169,7 +197,7 @@ var Plates = (typeof module !== 'undefined' && typeof module.exports !== 'undefi
remove = 0,
components,
attributes,
- mappings = map && map.mappings,
+ mappings = map && compileMappings(map.mappings),
intag = false,
tagname = '',
isClosing = false,
@@ -293,19 +321,19 @@ var Plates = (typeof module !== 'undefined' && typeof module.exports !== 'undefi
, mapping.mapper
);
- buffer += tagbody + that.iterate(html, partial, components, tagname);
+ buffer += tagbody + that.iterate(html, partial, components, tagname, undefined, map);
matchmode = true;
} else {
var v = newdata = fetch(data, mapping, value, tagbody, key);
newdata = tagbody + newdata;
if (Array.isArray(v)) {
- newdata = that.iterate(html, v, components, tagname, value);
+ newdata = that.iterate(html, v, components, tagname, value, map);
// If the item is an array, then we need to tell
// Plates that we're dealing with nests
that.nest.push(tagname);
} else if (typeof v === 'object') {
- newdata = tagbody + that.iterate(html, v, components, tagname, value);
+ newdata = tagbody + that.iterate(html, v, components, tagname, value, map);
}
buffer += newdata || '';
@@ -353,7 +381,7 @@ var Plates = (typeof module !== 'undefined' && typeof module.exports !== 'undefi
if (key === map && map.conf.where || 'id' && data[value]) {
var v = data[value],
nest = Array.isArray(v),
- output = (nest || typeof v === 'object') ? that.iterate(html, v, components, tagname, value) : v;
+ output = (nest || typeof v === 'object') ? that.iterate(html, v, components, tagname, value, map) : v;
// If the item is an array, then we need to tell
// Plates that we're dealing with nests
115 test/api-test.js
View
@@ -1,4 +1,5 @@
var vows = require('vows'),
+ assert = require('assert'),
Plates = require('../lib/plates');
common = require('./common');
@@ -151,6 +152,8 @@ vows.describe('merge data into markup').addBatch({
function() {
var map = Plates.Map();
map.class("names").use("names");
+ map.class("first").use("first");
+ map.class("last").use("last");
return common.createTest('test-14', map);
}()
@@ -163,6 +166,9 @@ vows.describe('merge data into markup').addBatch({
var map = Plates.Map();
map.where("href").is("placeholder").insert("link");
map.class("names").use("names");
+ map.class("first").use("first");
+ map.class("middle").use("middle");
+ map.class("last").use("last");
return common.createTest('test-15', map);
}()
@@ -326,6 +332,115 @@ vows.describe('merge data into markup').addBatch({
return common.createTest('test-30', map);
}()
+ ),
+
+ '(31) Two maps on the same class, one for attribute work if the attribute one comes last': (
+
+ function() {
+ var map = Plates.Map();
+ map.class('author').to('name');
+ map.class('author').use('url').as('href');
+
+ return common.createTest('test-31', map);
+ }()
+
+ ),
+
+ '(32) Two maps on the same class, one for attribute work if the attribute one comes first': (
+
+ function() {
+ var map = Plates.Map();
+ map.class('author').use('url').as('href');
+ map.class('doesnotexist').to('donotcare');
+ map.class('author').to('name');
+
+ return common.createTest('test-32', map);
+ }()
+
+ ),
+
+ '(33) Two maps on the same attribute and value should throw': (
+
+
+ function() {
+ var map = Plates.Map();
+ map.class('author').use('url').as('href');
+ map.class('author').to('name');
+ map.class('author').to('name');
+
+ return {
+ topic: function() {
+
+ try {
+ Plates.bind('<a></a>', {a:1}, map);
+ } catch(err) {
+ return {
+ error: err
+ };
+ }
+ return {};
+
+ },
+ 'should throw': function(result) {
+ assert.ok(!! result.error, 'Should have thrown');
+ assert.equal(result.error.message, 'Conflicting mappings for attribute class and value author');
+ }
+ };
+
+ }()
+
+ ),
+
+ '(34) Two maps for thr same class, updating two attributes should update both attributes': (
+
+ function() {
+ var map = Plates.Map();
+ map.class('author').use('url').as('href');
+ map.class('author').use('class').as('class');
+
+ return common.createTest('test-34', map);
+ }()
+ ),
+
+ '(35) Two maps for thr same class, updating two attributes plus a body class map should update both attributes': (
+
+ function() {
+ var map = Plates.Map();
+ map.class('author').use('url').as('href');
+ map.class('author').use('class').as('class');
+ map.class('author').to('name');
+
+
+ return common.createTest('test-35', map);
+ }()
+ ),
+
+ '(36) complex nesting should work as expected': (
+
+ function() {
+ var map = Plates.Map();
+ map.class('author').use('author');
+ map.class('name').use('name');
+ map.class('name').use('link').as('href');
+ map.class('title').use('title');
+ map.class('inner').use('inner');
+
+ return common.createTest('test-36', map);
+ }()
+ ),
+
+ '(37) complex nesting with arrays should work as expected': (
+
+ function() {
+ var map = Plates.Map();
+ map.class('author').use('author');
+ map.class('name').use('name');
+ map.class('name').use('link').as('href');
+ map.class('title').use('title');
+ map.class('inner').use('inner');
+
+ return common.createTest('test-37', map);
+ }()
)
}
10 test/common.js
View
@@ -11,12 +11,12 @@ function get(name, extension) {
__dirname +
'/fixtures/' +
name + '.' +
- extension
- ).toString();
+ extension, 'utf8'
+ );
} catch(e) {
return null;
}
-};
+}
common.render = function(name, data, map) {
@@ -34,11 +34,11 @@ common.createTest = function(name, map) {
return {
- render: common.render(name, this.data, map),
+ render: common.render(name, this.data, map)
};
},
'should merge data to markup': function(result) {
- assert.equal(result.render, this.out);
+ assert.equal(this.out, result.render);
}
};
2  test/fixtures/test-21.html
View
@@ -1 +1 @@
-<div id="key"><div class="removed">Hello world</div></div>
+<div id="key"><div class="removed">Hello world</div></div>
2  test/fixtures/test-21.json
View
@@ -1 +1 @@
-{}
+{}
2  test/fixtures/test-21.out
View
@@ -1 +1 @@
-<div id="key"></div>
+<div id="key"></div>
2  test/fixtures/test-22.html
View
@@ -1 +1 @@
-<div id="key"><input type="email" value="testing" /></div>
+<div id="key"><input type="email" value="testing" /></div>
2  test/fixtures/test-22.json
View
@@ -1 +1 @@
-{}
+{}
2  test/fixtures/test-22.out
View
@@ -1 +1 @@
-<div id="key"></div>
+<div id="key"></div>
2  test/fixtures/test-24.html
View
@@ -1 +1 @@
-<div class="insert"></div>
+<div class="insert"></div>
2  test/fixtures/test-24.json
View
@@ -1 +1 @@
-{}
+{}
2  test/fixtures/test-24.out
View
@@ -1 +1 @@
-<div class="insert"><div class="trolling"></div></div>
+<div class="insert"><div class="trolling"></div></div>
2  test/fixtures/test-25.html
View
@@ -1 +1 @@
-<div class="insert"></div>
+<div class="insert"></div>
2  test/fixtures/test-25.json
View
@@ -1 +1 @@
-{}
+{}
2  test/fixtures/test-25.out
View
@@ -1 +1 @@
-<div class="insert"><div class="trolling">moo</div></div>
+<div class="insert"><div class="trolling">moo</div></div>
2  test/fixtures/test-26.html
View
@@ -1 +1 @@
-<div class="insert"></div>
+<div class="insert"></div>
2  test/fixtures/test-26.json
View
@@ -2,4 +2,4 @@
"partial": {
"boink": "moo"
}
-}
+}
2  test/fixtures/test-26.out
View
@@ -1 +1 @@
-<div class="insert"><div class="trolling">moo</div></div>
+<div class="insert"><div class="trolling">moo</div></div>
2  test/fixtures/test-27.html
View
@@ -1 +1 @@
-<div class="insert"></div>
+<div class="insert"></div>
2  test/fixtures/test-27.json
View
@@ -1 +1 @@
-{}
+{}
2  test/fixtures/test-27.out
View
@@ -1,2 +1,2 @@
<div class="insert"><strong>strong</strong> plates
-</div>
+</div>
1  test/fixtures/test-31.html
View
@@ -0,0 +1 @@
+<a class="author" href=""></a>
4 test/fixtures/test-31.json
View
@@ -0,0 +1,4 @@
+{
+ "name": "The Name",
+ "url": "//the.url.com/abc"
+}
1  test/fixtures/test-31.out
View
@@ -0,0 +1 @@
+<a class="author" href="//the.url.com/abc">The Name</a>
1  test/fixtures/test-32.html
View
@@ -0,0 +1 @@
+<a class="author" href=""></a>
4 test/fixtures/test-32.json
View
@@ -0,0 +1,4 @@
+{
+ "name": "The Name",
+ "url": "//the.url.com/abc"
+}
1  test/fixtures/test-32.out
View
@@ -0,0 +1 @@
+<a class="author" href="//the.url.com/abc">The Name</a>
1  test/fixtures/test-34.html
View
@@ -0,0 +1 @@
+<a class="author" href=""></a>
4 test/fixtures/test-34.json
View
@@ -0,0 +1,4 @@
+{
+ "class": "class1 author",
+ "url": "//the.url.com/abc"
+}
1  test/fixtures/test-34.out
View
@@ -0,0 +1 @@
+<a class="class1 author" href="//the.url.com/abc"></a>
1  test/fixtures/test-35.html
View
@@ -0,0 +1 @@
+<a class="author" href=""></a>
5 test/fixtures/test-35.json
View
@@ -0,0 +1,5 @@
+{
+ "name": "The Name",
+ "class": "class1 author",
+ "url": "//the.url.com/abc"
+}
1  test/fixtures/test-35.out
View
@@ -0,0 +1 @@
+<a class="class1 author" href="//the.url.com/abc">The Name</a>
8 test/fixtures/test-36.html
View
@@ -0,0 +1,8 @@
+<div class="authors">
+ <ul>
+ <li class="author">
+ <h2 class="title"></h2>
+ <a class="name" href="">The author name is<span class="inner"></span></a>
+ </li>
+ </ul>
+</div>
4 test/fixtures/test-36.json
View
@@ -0,0 +1,4 @@
+{
+ "author":
+ { "name": {"inner": "Author 1"}, "title": "Title 1", "link": "//1" }
+}
8 test/fixtures/test-36.out
View
@@ -0,0 +1,8 @@
+<div class="authors">
+ <ul>
+ <li class="author">
+ <h2 class="title">Title 1</h2>
+ <a class="name" href="//1">The author name is<span class="inner">Author 1</span></a>
+ </li>
+ </ul>
+</div>
8 test/fixtures/test-37.html
View
@@ -0,0 +1,8 @@
+<div class="authors">
+ <ul>
+ <li class="author">
+ <h2 class="title"></h2>
+ <a class="name" href="">The author name is<span class="inner"></span></a>
+ </li>
+ </ul>
+</div>
7 test/fixtures/test-37.json
View
@@ -0,0 +1,7 @@
+{
+ "author": [
+ { "name": {"inner": "Author 1"}, "title": "Title 1", "link": "//1" },
+ { "name": {"inner": "Author 2"}, "title": "Title 2", "link": "//2" },
+ { "name": {"inner": "Author 3"}, "title": "Title 3", "link": "//3" }
+ ]
+}
14 test/fixtures/test-37.out
View
@@ -0,0 +1,14 @@
+<div class="authors">
+ <ul>
+ <li class="author">
+ <h2 class="title">Title 1</h2>
+ <a class="name" href="//1">The author name is<span class="inner">Author 1</span></a>
+ </li><li class="author">
+ <h2 class="title">Title 2</h2>
+ <a class="name" href="//2">The author name is<span class="inner">Author 2</span></a>
+ </li><li class="author">
+ <h2 class="title">Title 3</h2>
+ <a class="name" href="//3">The author name is<span class="inner">Author 3</span></a>
+ </li>
+ </ul>
+</div>
Please sign in to comment.
Something went wrong with that request. Please try again.