add immoweb ui

This commit is contained in:
Viktor Barzin 2025-05-26 19:41:36 +00:00
parent 7e8c79d3d1
commit 151da16c27
No known key found for this signature in database
GPG key ID: 4056458DBDBF8863
266 changed files with 264879 additions and 0 deletions

60
immoweb/node_modules/rivets/spec/lib/mock.data.js generated vendored Normal file
View file

@ -0,0 +1,60 @@
function Data(attributes) {
this.attributes = attributes || {};
this.change = {}
}
Data.prototype.on = function(key, callback) {
if(this.hasCallback(key, callback))
return;
var ref = this.change[key] || (this.change[key] = []);
this.change[key].push(callback);
}
Data.prototype.hasCallback = function(key, callback) {
return indexOf(this.change[key], callback) !== -1;
}
indexOf = function(array, value) {
array || (array = [])
if(array.indexOf)
return array.indexOf(value);
for(i in array || {}) {
if(array[i] === value)
return i;
}
return -1;
}
Data.prototype.off = function(key, callback) {
var index = indexOf(this.change[key], callback);
if(index !== -1)
this.change[key].splice(index, 1);
}
Data.prototype.set = function(attributes) {
var old, key;
for(key in attributes) {
old = this.attributes[key];
this.attributes[key] = attributes[key];
if(this.get(key) !== old)
this.alertCallbacks(key);
}
}
Data.prototype.get = function(key) {
return this.attributes[key];
}
Data.prototype.alertCallbacks = function(key) {
if(!this.change[key])
return;
var key, callbacks;
for(i in this.change[key]) {
this.change[key][i](this.get(key));
}
}
window.Data = Data;

318
immoweb/node_modules/rivets/spec/rivets/binders.js generated vendored Normal file
View file

@ -0,0 +1,318 @@
describe("Rivets.binders", function() {
var context
beforeEach(function() {
context = {
publish: function() {}
}
})
describe("value", function() {
var el
beforeEach(function() {
el = document.createElement('input')
})
it("unbinds the same bound function", function() {
var boundFn
sinon.stub(el, 'addEventListener', function(event, fn) {
boundFn = fn
})
rivets.binders.value.bind.call(context, el)
sinon.stub(el, 'removeEventListener', function(event, fn) {
fn.should.equal(boundFn)
})
rivets.binders.value.unbind.call(context, el)
})
})
describe("each-*", function() {
var fragment;
var el;
var model;
beforeEach(function() {
fragment = document.createDocumentFragment();
el = document.createElement("li");
el.setAttribute("rv-each-item", "items");
el.setAttribute("rv-text", "item.val");
fragment.appendChild(el);
model = { items: [{val: 0},{val: 1},{val: 2}] };
});
it("binds to the model creating a list item for each element in items", function() {
var view = rivets.bind(fragment, model);
// one child for each element in the model plus 1 for the comment placeholder
Should(fragment.childNodes.length).be.exactly(model.items.length + 1);
});
it("reflects changes to the model into the DOM", function() {
var view = rivets.bind(fragment, model);
Should(fragment.childNodes[1].textContent).be.exactly("0");
model.items[0].val = "howdy";
Should(fragment.childNodes[1].textContent).be.exactly("howdy");
});
it("reflects changes to the model into the DOM after unbind/bind", function() {
var view = rivets.bind(fragment, model);
Should(fragment.childNodes[1].textContent).be.exactly("0");
view.unbind();
view.bind();
model.items[0].val = "howdy";
Should(fragment.childNodes[1].textContent).be.exactly("howdy");
});
it("lets you push an item", function() {
var view = rivets.bind(fragment, model);
var originalLength = model.items.length;
// one child for each element in the model plus 1 for the comment placeholder
Should(fragment.childNodes.length).be.exactly(model.items.length + 1);
model.items.push({val: 3});
Should(model.items.length).be.exactly(originalLength + 1);
Should(fragment.childNodes.length).be.exactly(model.items.length + 1);
});
it("lets you push an item after unbind/bind", function() {
var view = rivets.bind(fragment, model);
var originalLength = model.items.length;
// one child for each element in the model plus 1 for the comment placeholder
Should(fragment.childNodes.length).be.exactly(model.items.length + 1);
view.unbind();
view.bind();
model.items.push({val: 3});
Should(model.items.length).be.exactly(originalLength + 1);
Should(fragment.childNodes.length).be.exactly(model.items.length + 1);
});
});
describe("nested-each-*", function() {
var fragment;
var el;
var nestedEl;
var model;
beforeEach(function() {
fragment = document.createDocumentFragment();
el = document.createElement("span");
el.setAttribute("rv-each-item", "items");
nestedEl = document.createElement("span");
nestedEl.setAttribute("rv-each-nested", "item.val");
nestedEl.textContent = "{%item%}-{%nested%}";
el.appendChild(nestedEl);
fragment.appendChild(el);
model = { items: [{val: [{val: 0},{val: 1}]},{val: [{val: 2},{val: 3}]},{val: [{val: 4},{val: 5}]}] };
});
it("lets you get all the indexes", function() {
var view = rivets.bind(el, model);
Should(fragment.childNodes[1].childNodes[1].textContent).be.exactly('0-0');
Should(fragment.childNodes[1].childNodes[2].textContent).be.exactly('0-1');
Should(fragment.childNodes[2].childNodes[2].textContent).be.exactly('1-1');
});
});
describe("if", function() {
var fragment;
var el;
var model;
beforeEach(function() {
fragment = document.createDocumentFragment();
el = document.createElement("div");
el.setAttribute("rv-if", "data.show");
el.innerHTML = "{ data.count }";
fragment.appendChild(el);
model = { data: {
show: true,
count: 1
} };
});
it("shows element with bound key inside if the value is true", function() {
var view = rivets.bind(fragment, model);
// one child for the original div plus 1 for the comment placeholder
Should(fragment.childNodes.length).be.exactly(2);
Should(fragment.childNodes[1].innerHTML).be.exactly("1");
});
it("hides if the value is false", function() {
var view = rivets.bind(fragment, model);
model.data.show = false;
// 1 for the comment placeholder
Should(fragment.childNodes.length).be.exactly(1);
});
it("keeps binding when element becomes visible again", function() {
var view = rivets.bind(fragment, model);
model.data.show = false;
model.data.count = 2;
model.data.show = true;
// one child for the original div plus 1 for the comment placeholder
Should(fragment.childNodes.length).be.exactly(2);
Should(fragment.childNodes[1].innerHTML).be.exactly("2");
});
it("hides if the value is falsey - zero", function() {
var view = rivets.bind(fragment, model);
model.data.show = 0;
// 1 for the comment placeholder
Should(fragment.childNodes.length).be.exactly(1);
});
it("hides if the value is falsey - empty string", function() {
var view = rivets.bind(fragment, model);
model.data.show = "";
// 1 for the comment placeholder
Should(fragment.childNodes.length).be.exactly(1);
});
it("hides if the value is falsey - undefined", function() {
var view = rivets.bind(fragment, model);
model.data.show = undefined;
// 1 for the comment placeholder
Should(fragment.childNodes.length).be.exactly(1);
});
it("rebindes nested if", function() {
var nestedEl = document.createElement("div")
nestedEl.setAttribute("rv-if", "data.showNested");
nestedEl.innerHTML = "{ data.countNested }";
el.appendChild(nestedEl);
var view = rivets.bind(fragment, model);
model.data.countNested = "1";
model.data.showNested = true;
Should(nestedEl.innerHTML).be.exactly("1");
model.data.show = false;
model.data.show = true;
model.data.countNested = "42";
Should(nestedEl.innerHTML).be.exactly("42");
});
it("does not throw when root scope is reset", function () {
el.setAttribute('rv-if', 'scope.error.errors');
el.innerHTML = '<div>{scope.error.errors.email}</div>';
model = {
scope: {
error: {
errors: {
email: 'not a valid address'
}
}
}
};
var view = rivets.bind(el, model);
(function(){
model.scope.error = {};
}).should.not.throw();
})
});
describe("Custom binder with no attribute value", function() {
rivets.binders["custom-binder"] = function(el, value) {
el.innerHTML = "received " + value;
};
beforeEach(function() {
fragment = document.createDocumentFragment();
el = document.createElement("div");
fragment.appendChild(el);
model = {};
});
it("receives undefined when html attribute is not specified", function() {
el.innerHTML = "<div rv-custom-binder></div>";
var view = rivets.bind(fragment, model);
Should(el.children[0].innerHTML).be.exactly('received undefined');
});
it("receives undefined when html attribute is not specified", function() {
el.innerHTML = "<div rv-custom-binder=''></div>";
var view = rivets.bind(fragment, model);
Should(el.children[0].innerHTML).be.exactly('received undefined');
});
});
describe('Array observe and unobserve', function() {
var fragment;
var el1;
var elEach;
var el2;
var el3;
var model;
beforeEach(function() {
/*
DOM for test
<div>
<div rv-if="scope.visible">
<div>
<div rv-each-item="scope.items">{item.data}</div>
</div>
</div>
<div>
<div rv-each-item="scope.items">{item.data}</div>
</div>
</div>
*/
fragment = document.createElement("div");
el1 = document.createElement("div");
el1.setAttribute("rv-if", "scope.visible");
el2 = document.createElement("div");
elEach = document.createElement("div");
elEach.setAttribute('rv-each-item', 'scope.items');
elEach.innerHTML = '{item.data}';
el2.appendChild(elEach);
el1.appendChild(el2);
el3 = document.createElement("div");
elEach = document.createElement("div");
elEach.setAttribute('rv-each-item', 'scope.items');
elEach.innerHTML = '{item.data}';
el3.appendChild(elEach);
fragment.appendChild(el1);
fragment.appendChild(el3);
model = { scope: {items: [], visible:true }};
});
it('observes array changes after another array binding is unbound', function() {
var view = rivets.bind(fragment, model);
model.scope.items.push({data:"data"});
Should(el3.childNodes.length).be.exactly(2);
model.scope.items.push({data:"data"});
Should(el3.childNodes.length).be.exactly(3);
model.scope.visible = false;
model.scope.items.push({data:"data"});
Should(el3.childNodes.length).be.exactly(4);
});
});
});

481
immoweb/node_modules/rivets/spec/rivets/binding.js generated vendored Normal file
View file

@ -0,0 +1,481 @@
describe('Rivets.Binding', function() {
var model, el, view, binding, opts, originalPrefix
beforeEach(function() {
originalPrefix = rivets.prefix
rivets.prefix = 'data'
adapter = rivets.adapters['.']
el = document.createElement('div')
el.setAttribute('data-text', 'obj.name')
view = rivets.bind(el, {obj: {name: 'test'}})
binding = view.bindings[0]
model = binding.model
})
afterEach(function() {
rivets.prefix = originalPrefix
})
it('gets assigned the proper binder routine matching the identifier', function() {
binding.binder.routine.should.equal(rivets.binders.text)
})
describe('with formatters', function() {
it('register all formatters', function() {
valueInput = document.createElement('input')
valueInput.setAttribute('type','text')
valueInput.setAttribute('data-value', "obj.name | awesome | radical | totally")
view = rivets.bind(valueInput, {obj: { name: 'nothing' }})
binding = view.bindings[0]
binding.formatters.should.be.eql(['awesome', 'radical', 'totally'])
})
it('allows arguments with pipes', function () {
valueInput = document.createElement('input')
valueInput.setAttribute('type', 'text')
valueInput.setAttribute('data-value', "obj.name | awesome | totally 'arg | with || pipes' 'and more args' | and 'others formatters' with 'pi||pes'")
view = rivets.bind(valueInput, { obj: { name: 'nothing' } })
binding = view.bindings[0]
binding.formatters.should.be.eql(['awesome', "totally 'arg | with || pipes' 'and more args'", "and 'others formatters' with 'pi||pes'"])
})
})
describe('bind()', function() {
it('subscribes to the model for changes via the adapter', function() {
sinon.spy(adapter, 'observe')
binding.bind()
adapter.observe.calledWith(model, 'name', binding.sync).should.be.true
})
it("calls the binder's bind method if one exists", function() {
binding.bind.should.not.throw()
binding.binder.bind = function(){}
sinon.spy(binding.binder, 'bind')
binding.bind()
binding.binder.bind.called.should.be.true
})
describe('with preloadData set to true', function() {
beforeEach(function() {
rivets.preloadData = true
})
it('sets the initial value', function() {
sinon.spy(binding, 'set')
binding.bind()
binding.set.calledWith('test').should.be.true
})
})
describe('with dependencies', function() {
beforeEach(function() {
binding.options.dependencies = ['.fname', '.lname']
})
it('sets up observers on the dependant attributes', function() {
binding.bind()
adapter.observe.calledWith(model, 'fname', binding.sync).should.be.true
adapter.observe.calledWith(model, 'lname', binding.sync).should.be.true
})
})
})
describe('unbind()', function() {
describe('without a binder.unbind defined', function() {
it('should not throw an error', function() {
binding.unbind.should.not.throw()
})
})
describe('with a binder.unbind defined', function() {
beforeEach(function() {
binding.binder.unbind = function(){}
})
it('should not throw an error', function() {
binding.unbind.should.not.throw()
})
it("calls the binder's unbind method", function() {
sinon.spy(binding.binder, 'unbind')
binding.unbind()
binding.binder.unbind.called.should.be.true
})
})
})
describe('set()', function() {
it('performs the binding routine with the supplied value', function() {
sinon.spy(binding.binder, 'routine')
binding.set('sweater')
binding.binder.routine.calledWith(el, 'sweater').should.be.true
})
it('applies any formatters to the value before performing the routine', function() {
view.formatters.awesome = function(value) { return 'awesome ' + value }
binding.formatters.push('awesome')
sinon.spy(binding.binder, 'routine')
binding.set('sweater')
binding.binder.routine.calledWith(el, 'awesome sweater').should.be.true
})
})
describe('functions in bindings', function() {
it('does not call methods by default', function() {
sinon.spy(binding.binder, 'routine')
var fn = function() {};
binding.set(fn)
binding.binder.routine.calledWith(el, fn).should.be.true
})
it('does call methods with model if backward compatibility is set', function() {
rivets.configure({
executeFunctions:true
})
binding.model = {foo: 'bar'}
sinon.spy(binding.binder, 'routine')
binding.set(function() { return this.foo })
binding.binder.routine.calledWith(el, binding.model.foo).should.be.true
// Back to default !!
rivets.configure({
executeFunctions:false
})
})
})
describe('prototype functions', function() {
it('does call routine if observed value is a function', function() {
rivets.configure({
executeFunctions:true
})
var Employee = function(name) {
this.name = name
}
Employee.prototype.getName = function() {
return this.name;
}
var model = {employee: new Employee("John")}
el = document.createElement('div')
el.setAttribute('data-text', 'employee.getName')
view = rivets.bind(el, model)
binding = view.bindings[0]
sinon.spy(binding.binder, 'routine')
model.employee = new Employee("Peter")
binding.binder.routine.calledWith(el, "Peter").should.be.true
// Back to default !!
rivets.configure({
executeFunctions:false
})
})
})
describe('publish()', function() {
it("should publish the value of a number input", function() {
numberInput = document.createElement('input')
numberInput.setAttribute('type', 'number')
numberInput.setAttribute('data-value', 'obj.num')
view = rivets.bind(numberInput, {obj: {num: 42}})
binding = view.bindings[0]
model = binding.model
numberInput.value = 42
sinon.spy(adapter, 'set')
binding.publish({target: numberInput})
adapter.set.calledWith(model, 'num', '42').should.be.true
})
})
describe('publishTwoWay()', function() {
it('applies a two-way read formatter to function same as a single-way', function() {
view.formatters.awesome = {
read: function(value) { return 'awesome ' + value }
}
binding.formatters.push('awesome')
sinon.spy(binding.binder, 'routine')
binding.set('sweater')
binding.binder.routine.calledWith(el, 'awesome sweater').should.be.true
})
it("should publish the value of a number input", function() {
rivets.formatters.awesome = {
publish: function(value) { return 'awesome ' + value }
}
numberInput = document.createElement('input')
numberInput.setAttribute('type', 'number')
numberInput.setAttribute('data-value', 'obj.num | awesome')
view = rivets.bind(numberInput, {obj: {num: 42}})
binding = view.bindings[0]
model = binding.model
numberInput.value = 42
binding.publish({target: numberInput})
adapter.set.calledWith(model, 'num', 'awesome 42').should.be.true
})
it("should format a value in both directions", function() {
rivets.formatters.awesome = {
publish: function(value) { return 'awesome ' + value },
read: function(value) { return value + ' is awesome' }
}
valueInput = document.createElement('input')
valueInput.setAttribute('type','text')
valueInput.setAttribute('data-value', 'obj.name | awesome')
view = rivets.bind(valueInput, {obj: { name: 'nothing' }})
binding = view.bindings[0]
model = binding.model
valueInput.value = 'charles'
binding.publish({target: valueInput})
adapter.set.calledWith(model, 'name', 'awesome charles').should.be.true
sinon.spy(binding.binder, 'routine')
binding.set('fred')
binding.binder.routine.calledWith(valueInput, 'fred is awesome').should.be.true
})
it("should resolve formatter arguments to their values", function() {
rivets.formatters.withArguments = {
publish: function(value, arg1, arg2) {
return value + ':' + arg1 + ':' + arg2
},
read: function(value, arg1, arg2) {
return value.replace(':' + arg1 + ':' + arg2, '')
}
}
valueInput = document.createElement('input')
valueInput.setAttribute('type', 'text')
valueInput.setAttribute('data-value', "obj.name | withArguments config.age 'male'")
view = rivets.bind(valueInput, {
obj: {
name: 'nothing'
},
config: {
age: 50
}
})
binding = view.bindings[0]
model = binding.model
valueInput.value = 'bobby'
binding.publish({target: valueInput})
adapter.set.calledWith(model, 'name', 'bobby:50:male').should.be.true
valueInput.value.should.equal('bobby')
binding.set('andy:50:male')
binding.binder.routine.calledWith(valueInput, 'andy').should.be.true
})
it("should resolve formatter arguments correctly with multiple formatters", function() {
rivets.formatters.wrap = {
publish: function(value, arg1, arg2) {
return arg1 + value + arg2
},
read: function(value, arg1, arg2) {
return value.replace(arg1, '').replace(arg2, '')
}
}
rivets.formatters.saveAsCase = {
publish: function(value, typeCase) {
return value['to' + typeCase + 'Case']()
},
read: function(value, typeCase) {
return value[typeCase === 'Upper' ? 'toLowerCase' : 'toUpperCase']()
}
}
valueInput = document.createElement('input')
valueInput.setAttribute('type', 'text')
valueInput.setAttribute(
'data-value',
"obj.name | saveAsCase config.typeCase | wrap config.curly '}' | wrap config.square ']' | wrap config.paren ')'"
)
view = rivets.bind(valueInput, {
obj: {
name: 'nothing'
},
config: {
paren: '(',
square: '[',
curly: '{',
typeCase: 'Upper'
}
})
binding = view.bindings[0]
model = binding.model
valueInput.value = 'bobby'
binding.publish({target: valueInput})
adapter.set.calledWith(model, 'name', '{[(BOBBY)]}').should.be.true
valueInput.value.should.equal('bobby')
binding.set('{[(ANDY)]}')
binding.binder.routine.calledWith(valueInput, 'andy').should.be.true
})
it("should not fail or format if the specified binding function doesn't exist", function() {
rivets.formatters.awesome = { }
valueInput = document.createElement('input')
valueInput.setAttribute('type','text')
valueInput.setAttribute('data-value', 'obj.name | awesome')
view = rivets.bind(valueInput, {obj: { name: 'nothing' }})
binding = view.bindings[0]
model = binding.model
valueInput.value = 'charles'
binding.publish({target: valueInput})
adapter.set.calledWith(model, 'name', 'charles').should.be.true
binding.set('fred')
binding.binder.routine.calledWith(valueInput, 'fred').should.be.true
})
it("should apply read binders left to right, and publish binders right to left", function() {
rivets.formatters.totally = {
publish: function(value) { return value + ' totally' },
read: function(value) { return value + ' totally' }
}
rivets.formatters.awesome = {
publish: function(value) { return value + ' is awesome' },
read: function(value) { return value + ' is awesome' }
}
valueInput = document.createElement('input')
valueInput.setAttribute('type','text')
valueInput.setAttribute('data-value', 'obj.name | awesome | totally')
view = rivets.bind(valueInput, {obj: { name: 'nothing' }})
binding = view.bindings[0]
model = binding.model
binding.set('fred')
binding.binder.routine.calledWith(valueInput, 'fred is awesome totally').should.be.true
valueInput.value = 'fred'
binding.publish({target: valueInput})
adapter.set.calledWith(model, 'name', 'fred totally is awesome').should.be.true
})
it("binders in a chain should be skipped if they're not there", function() {
rivets.formatters.totally = {
publish: function(value) { return value + ' totally' },
read: function(value) { return value + ' totally' }
}
rivets.formatters.radical = {
publish: function(value) { return value + ' is radical' },
}
rivets.formatters.awesome = function(value) { return value + ' is awesome' }
valueInput = document.createElement('input')
valueInput.setAttribute('type','text')
valueInput.setAttribute('data-value', 'obj.name | awesome | radical | totally')
view = rivets.bind(valueInput, {obj: { name: 'nothing' }})
binding = view.bindings[0]
model = binding.model
binding.set('fred')
binding.binder.routine.calledWith(valueInput, 'fred is awesome totally').should.be.true
valueInput.value = 'fred'
binding.publish({target: valueInput})
adapter.set.calledWith(model, 'name', 'fred totally is radical').should.be.true
})
})
describe('formattedValue()', function() {
it('applies the current formatters on the supplied value', function() {
view.formatters.awesome = function(value) { return 'awesome ' + value }
binding.formatters.push('awesome')
binding.formattedValue('hat').should.equal('awesome hat')
})
describe('with a multi-argument formatter string', function() {
beforeEach(function() {
view.formatters.awesome = function(value, prefix) {
return prefix + ' awesome ' + value
}
binding.formatters.push("awesome 'super'")
})
it('applies the formatter with arguments', function() {
binding.formattedValue('jacket').should.equal('super awesome jacket')
})
})
describe('with a formatter string with pipes in argument', function() {
beforeEach(function () {
view.formatters.totally = function (value, prefix) {
return prefix + ' totally ' + value
}
binding.formatters.push("totally 'arg | with || pipes'")
})
it('applies the formatter with arguments with pipes', function () {
binding.formattedValue('jacket').should.equal('arg | with || pipes totally jacket')
})
})
})
describe('getValue()', function() {
it('should use binder.getValue() if present', function() {
binding.binder.getValue = function(el) {
return 'foo'
}
binding.getValue(el).should.equal('foo')
})
it('binder.getValue() should have access to passed element', function() {
binding.binder.getValue = function(el) {
return el.dataset.foo
}
el.dataset.foo = 'bar'
binding.getValue(el).should.equal('bar')
})
it('binder.getValue() should have access to binding', function() {
binding.binder.getValue = function(el) {
return this.foo
}
binding.foo = 'bar'
binding.getValue(el).should.equal('bar')
})
})
})

View file

@ -0,0 +1,79 @@
describe('Component binding', function() {
var scope, element, component, componentRoot
beforeEach(function() {
element = document.createElement('div')
element.innerHTML = '<test></test>'
componentRoot = element.firstChild
scope = { name: 'Rivets' }
component = rivets.components.test = {
initialize: sinon.stub().returns(scope),
template: function() { return '' }
}
})
it('renders "template" as a string', function() {
component.template = function() {return '<h1>test</h1>'}
rivets.bind(element)
componentRoot.innerHTML.should.equal(component.template())
})
it('binds binders on component root element only once', function() {
rivets.binders['test-binder'] = sinon.spy();
componentRoot.setAttribute('rv-test-binder', 'true');
rivets.bind(element);
rivets.binders['test-binder'].calledOnce.should.be.true;
delete rivets.binders['test-binder'];
})
describe('initialize()', function() {
var locals
beforeEach(function() {
locals = { object: { name: 'Rivets locals' } }
componentRoot.setAttribute('item', 'object')
})
it('receives element as first argument and attributes as second', function() {
rivets.bind(element, locals)
component.initialize.calledWith(componentRoot, { item: locals.object }).should.be.true
})
it('receives primitives attributes', function() {
componentRoot.setAttribute('primitivestring', "'value'")
componentRoot.setAttribute('primitivenumber', "42")
componentRoot.setAttribute('primitiveboolean', "true")
rivets.bind(element, locals)
component.initialize.calledWith(componentRoot, { item: locals.object,
primitivestring: 'value',
primitivenumber: 42,
primitiveboolean: true })
.should.be.true
})
it('returns attributes assigned to "static" property as they are', function() {
var type = 'text'
component.static = ['type']
componentRoot.setAttribute('type', type)
rivets.bind(element, locals)
component.initialize.calledWith(componentRoot, { item: locals.object, type: type }).should.be.true
})
})
describe('when "template" is a function', function() {
it('renders returned string as component template', function() {
component.template = sinon.stub().returns('<h1>{ name }</h1>')
rivets.bind(element)
componentRoot.innerHTML.should.equal('<h1>' + scope.name + '</h1>')
})
})
})

31
immoweb/node_modules/rivets/spec/rivets/formatters.js generated vendored Normal file
View file

@ -0,0 +1,31 @@
describe("Rivets.formatters", function() {
describe("call", function() {
var model
beforeEach(function() {
model = {
fn: function(arg1, arg2) {
return '' + arg1 + arg2;
}
}
})
it("calls function with arguments", function() {
rivets.formatters['call'](model.fn, 'foo', 'bar').should.equal('foobar')
})
it("calls function with the model as context", function() {
model.obj = {
name: 'foo',
fn: function() {
return this.name;
}
}
var el = document.createElement('div')
el.setAttribute('rv-text', 'obj.fn | call')
rivets.bind(el, model)
el.innerText.should.equal('foo')
})
})
});

283
immoweb/node_modules/rivets/spec/rivets/functional.js generated vendored Normal file
View file

@ -0,0 +1,283 @@
describe('Functional', function() {
var data, bindData, el, input, originalPrefix
beforeEach(function() {
originalPrefix = rivets.prefix;
rivets.prefix = 'data';
adapter = {
observe: function(obj, keypath, callback) {
obj.on(keypath, callback)
},
unobserve: function(obj, keypath, callback) {
obj.off(keypath, callback)
},
get: function(obj, keypath) {
return obj.get(keypath)
},
set: function(obj, keypath, value) {
attributes = {}
attributes[keypath] = value
obj.set(attributes)
}
}
sightglass.adapters[':'] = adapter
rivets.configure({preloadData: true})
data = new Data({
foo: 'bar',
items: [{name: 'a'}, {name: 'b'}]
})
bindData = {data: data}
el = document.createElement('div')
input = document.createElement('input')
input.setAttribute('type', 'text')
})
afterEach(function() {
rivets.prefix = originalPrefix
})
describe('Adapter', function() {
it('should read the initial value', function() {
sinon.spy(data, 'get')
el.setAttribute('data-text', 'data:foo')
rivets.bind(el, bindData)
data.get.calledWith('foo').should.be.true
})
it('should read the initial value unless preloadData is false', function() {
rivets.configure({preloadData: false})
sinon.spy(data, 'get')
el.setAttribute('data-value', 'data:foo')
rivets.bind(el, bindData)
data.get.called.should.be.false
})
it('should subscribe to updates', function() {
sinon.spy(data, 'on')
el.setAttribute('data-value', 'data:foo')
rivets.bind(el, bindData)
data.on.called.should.be.true
})
})
describe('Binds', function() {
describe('Text', function() {
it('should set the text content of the element', function() {
el.setAttribute('data-text', 'data:foo')
rivets.bind(el, bindData)
el.textContent.should.equal(data.get('foo'))
})
it('should correctly handle HTML in the content', function() {
el.setAttribute('data-text', 'data:foo')
value = '<b>Fail</b>'
data.set({foo: value})
rivets.bind(el, bindData)
el.textContent.should.equal(value)
})
})
describe('HTML', function() {
it('should set the html content of the element', function() {
el.setAttribute('data-html', 'data:foo')
rivets.bind(el, bindData)
el.textContent.should.equal(data.get('foo'))
})
it('should correctly handle HTML in the content', function() {
el.setAttribute('data-html', 'data:foo')
value = '<b>Fail</b>'
data.set({foo: value})
rivets.bind(el, bindData)
el.innerHTML.should.equal(value)
})
})
describe('Value', function() {
it('should set the value of the element', function() {
input.setAttribute('data-value', 'data:foo')
rivets.bind(input, bindData)
input.value.should.equal(data.get('foo'))
})
})
describe('Multiple', function() {
it('should bind a list of multiple elements', function() {
el.setAttribute('data-html', 'data:foo')
input.setAttribute('data-value', 'data:foo')
rivets.bind([el, input], bindData)
el.textContent.should.equal(data.get('foo'))
input.value.should.equal(data.get('foo'))
})
})
describe('Priority', function() {
beforeEach(function() {
rivets.binders.a = {bind: function(){}}
rivets.binders.b = {bind: function(){}}
sinon.spy(rivets.binders.a, 'bind')
sinon.spy(rivets.binders.b, 'bind')
el.setAttribute('data-a', 'data:foo')
el.setAttribute('data-b', 'data:foo')
})
describe('a:10, b:30', function() {
beforeEach(function() {
rivets.binders.a.priority = 10
rivets.binders.b.priority = 30
rivets.bind(el, bindData)
})
it('should bind b before a', function() {
rivets.binders.b.bind.calledBefore(rivets.binders.a.bind).should.be.true
})
})
describe('a:5, b:2', function() {
beforeEach(function() {
rivets.binders.a.priority = 5
rivets.binders.b.priority = 2
rivets.bind(el, bindData)
})
it('should bind a before b', function() {
rivets.binders.a.bind.calledBefore(rivets.binders.b.bind).should.be.true
})
})
describe('a:undefined, b:1', function() {
beforeEach(function() {
rivets.binders.b.priority = 1
rivets.bind(el, bindData)
})
it('should bind b before a', function() {
rivets.binders.b.bind.calledBefore(rivets.binders.a.bind).should.be.true
})
})
})
describe('Iteration', function() {
beforeEach(function(){
list = document.createElement('ul')
el.appendChild(list)
listItem = document.createElement('li')
listItem.setAttribute('data-each-item', 'data:items')
list.appendChild(listItem)
})
it('should loop over a collection and create new instances of that element + children', function() {
el.getElementsByTagName('li').length.should.equal(1)
rivets.bind(el, bindData)
el.getElementsByTagName('li').length.should.equal(2)
})
it('should not fail if the collection being bound to is null', function() {
data.set({ items: null})
rivets.bind(el, bindData)
el.getElementsByTagName('li').length.should.equal(0)
})
it('should re-loop over the collection and create new instances when the array changes', function() {
rivets.bind(el, bindData)
el.getElementsByTagName('li').length.should.equal(2)
newItems = [{name: 'a'}, {name: 'b'}, {name: 'c'}]
data.set({items: newItems})
el.getElementsByTagName('li').length.should.equal(3)
})
it('should allow binding to the iterated item as well as any parent contexts', function() {
span1 = document.createElement('span')
span1.setAttribute('data-text', 'item.name')
span2 = document.createElement('span')
span2.setAttribute('data-text', 'data:foo')
listItem.appendChild(span1)
listItem.appendChild(span2)
rivets.bind(el, bindData)
el.getElementsByTagName('span')[0].textContent.should.equal('a')
el.getElementsByTagName('span')[1].textContent.should.equal('bar')
})
it('should allow binding to the iterated element directly', function() {
listItem.setAttribute('data-text', 'item.name')
listItem.setAttribute('data-class', 'data:foo')
rivets.bind(el, bindData)
el.getElementsByTagName('li')[0].textContent.should.equal('a')
el.getElementsByTagName('li')[0].className.should.equal('bar')
})
it('should insert items between any surrounding elements', function(){
firstItem = document.createElement('li')
lastItem = document.createElement('li')
firstItem.textContent = 'first'
lastItem.textContent = 'last'
list.appendChild(lastItem)
list.insertBefore(firstItem, listItem)
listItem.setAttribute('data-text', 'item.name')
rivets.bind(el, bindData)
el.getElementsByTagName('li')[0].textContent.should.equal('first')
el.getElementsByTagName('li')[1].textContent.should.equal('a')
el.getElementsByTagName('li')[2].textContent.should.equal('b')
el.getElementsByTagName('li')[3].textContent.should.equal('last')
})
it('should allow binding to the iterated element index', function() {
listItem.setAttribute('data-index', 'index')
rivets.bind(el, bindData)
el.getElementsByTagName('li')[0].getAttribute('index').should.equal('0')
el.getElementsByTagName('li')[1].getAttribute('index').should.equal('1')
})
it('should allow binding to the iterated element index by using the %item% syntax', function() {
listItem.setAttribute('data-index', '%item%')
rivets.bind(el, bindData)
el.getElementsByTagName('li')[0].getAttribute('index').should.equal('0')
el.getElementsByTagName('li')[1].getAttribute('index').should.equal('1')
})
it('should allow the developer to configure the index attribute available in the iteration', function() {
rivets.configure({
iterationAlias : function(modelName) {
return modelName + 'Index';
}
});
listItem.setAttribute('data-index', 'itemIndex')
rivets.bind(el, bindData)
el.getElementsByTagName('li')[0].getAttribute('index').should.equal('0')
el.getElementsByTagName('li')[1].getAttribute('index').should.equal('1')
})
})
})
describe('Updates', function() {
it('should change the value', function() {
el.setAttribute('data-text', 'data:foo')
rivets.bind(el, bindData)
data.set({foo: 'some new value'})
el.textContent.should.equal(data.get('foo'))
})
})
describe('Input', function() {
it('should update the model value', function() {
input.setAttribute('data-value', 'data:foo')
rivets.bind(input, bindData)
input.value = 'some new value'
var event = document.createEvent('HTMLEvents')
event.initEvent('input', true, true)
input.dispatchEvent(event)
input.value.should.equal(data.get('foo'))
})
})
})

339
immoweb/node_modules/rivets/spec/rivets/routines.js generated vendored Normal file
View file

@ -0,0 +1,339 @@
describe('Routines', function() {
var el, input, trueRadioInput, falseRadioInput, checkboxInput
var createInputElement = function(type, value) {
var elem = document.createElement('input')
elem.setAttribute('type', type)
if (value !== undefined) {
elem.setAttribute('value', value)
}
document.body.appendChild(elem)
return elem
}
var createOptionEls = function(val) {
var option = document.createElement('option')
option.value = val
option.textContent = val + ' text'
return option
}
var createSelectElement = function(isMultiple, optionValues) {
var elem = document.createElement('select')
var options
if (optionValues instanceof Array) {
options = optionValues.map(createOptionEls)
options.forEach(function(option) {
elem.appendChild(option)
})
} else {
//grouped
Object.keys(optionValues).forEach(function(group) {
var optGroupEl = document.createElement('optgroup')
optGroupEl.label = group;
options = optionValues[group].map(createOptionEls);
options.forEach(function(option) {
optGroupEl.appendChild(option)
})
elem.appendChild(optGroupEl)
});
}
if (isMultiple) elem.multiple = true
document.body.appendChild(elem)
return elem
}
beforeEach(function() {
rivets.configure({
adapter: {
subscribe: function() {},
unsubscribe: function() {},
read: function() {},
publish: function() {}
}
})
el = document.createElement('div')
document.body.appendChild(el)
input = createInputElement('text')
// to test the radio input scenario when its value is "true"
trueRadioInput = createInputElement('radio', 'true')
// to test the radio input scenario when its value is "false"
falseRadioInput = createInputElement('radio', 'false')
// to test the checkbox input scenario
checkboxInput = createInputElement('checkbox') })
afterEach(function(){
el.parentNode.removeChild(el)
input.parentNode.removeChild(input)
trueRadioInput.parentNode.removeChild(trueRadioInput)
falseRadioInput.parentNode.removeChild(falseRadioInput)
checkboxInput.parentNode.removeChild(checkboxInput)
})
describe('text', function() {
it("sets the element's text content", function() {
rivets.binders.text(el, '<em>hello</em>')
el.textContent.should.equal('<em>hello</em>')
el.innerHTML.should.equal('&lt;em&gt;hello&lt;/em&gt;')
})
it("sets the element's text content to zero when a numeric zero is passed", function() {
rivets.binders.text(el, 0)
el.textContent.should.equal('0')
el.innerHTML.should.equal('0')
})
})
describe('html', function() {
it("sets the element's HTML content", function() {
rivets.binders.html(el, '<strong>hello</strong>')
el.textContent.should.equal('hello')
el.innerHTML.should.equal('<strong>hello</strong>')
})
it("sets the element's HTML content to zero when a zero value is passed", function() {
rivets.binders.html(el, 0)
el.textContent.should.equal('0')
el.innerHTML.should.equal('0')
})
})
describe('value', function() {
it("sets the element's value", function() {
rivets.binders.value.routine(input, 'pitchfork')
input.value.should.equal('pitchfork')
})
it("applies a default value to the element when the model doesn't contain it", function() {
rivets.binders.value.routine(input, undefined)
input.value.should.equal('')
})
it("sets the element's value to zero when a zero value is passed", function() {
rivets.binders.value.routine(input, 0)
input.value.should.equal('0')
})
describe('in a select element', function(){
beforeEach(function () {
selectEl = createSelectElement(false, ['a', 'b', 'c'])
selectMultipleEl = createSelectElement(true, ['d', 'e', 'f'])
groupedSelectEl = createSelectElement(false, {'group1': ['a'], 'group2': ['b', 'c']})
groupedMultipleSelectEl = createSelectElement(true, {'group1': ['a'], 'group2': ['b', 'c']})
})
it("sets the correct option on a select element", function() {
rivets.binders.value.routine(selectEl, 'b')
rivets.binders.value.routine(selectEl, 'c')
selectEl.value.should.equal('c')
})
it("sets the correct option on a select-multiple element", function() {
rivets.binders.value.routine(selectMultipleEl, ['d', 'f'])
Array.prototype.slice.call(selectMultipleEl.children)
.filter(function(option) {
return option.selected
})
.map(function(option) {
return option.value
})
.should.eql(['d', 'f'])
})
it("sets the correct option on a grouped select element", function() {
rivets.binders.value.routine(groupedSelectEl, 'b')
rivets.binders.value.routine(groupedSelectEl, 'c')
groupedSelectEl.value.should.equal('c')
})
it("sets the correct option on a select-multiple element", function() {
var i
rivets.binders.value.routine(groupedMultipleSelectEl, ['a', 'c'])
Array.prototype.slice.call(groupedMultipleSelectEl.options)
.filter(function(option) {
return option.selected
})
.map(function(option) {
return option.value
})
.should.eql(['a', 'c'])
})
afterEach(function () {
selectEl.parentNode.removeChild(selectEl)
selectMultipleEl.parentNode.removeChild(selectMultipleEl)
groupedSelectEl.parentNode.removeChild(groupedSelectEl)
groupedMultipleSelectEl.parentNode.removeChild(groupedMultipleSelectEl)
})
})
})
describe('show', function() {
describe('with a truthy value', function() {
it('shows the element', function() {
rivets.binders.show(el, true)
el.style.display.should.equal('')
})
})
describe('with a falsey value', function() {
it('hides the element', function() {
rivets.binders.show(el, false)
el.style.display.should.equal('none')
})
})
})
describe('hide', function() {
describe('with a truthy value', function() {
it('hides the element', function() {
rivets.binders.hide(el, true)
el.style.display.should.equal('none')
})
})
describe('with a falsey value', function() {
it('shows the element', function() {
rivets.binders.hide(el, false)
el.style.display.should.equal('')
})
})
})
describe('enabled', function() {
describe('with a truthy value', function() {
it('enables the element', function() {
rivets.binders.enabled(el, true)
el.disabled.should.equal(false)
})
})
describe('with a falsey value', function() {
it('disables the element', function() {
rivets.binders.enabled(el, false)
el.disabled.should.equal(true)
})
})
})
describe('disabled', function() {
describe('with a truthy value', function() {
it('disables the element', function() {
rivets.binders.disabled(el, true)
el.disabled.should.equal(true)
})
})
describe('with a falsey value', function() {
it('enables the element', function() {
rivets.binders.disabled(el, false)
el.disabled.should.equal(false)
})
})
})
describe('checked', function() {
describe('with a checkbox input', function() {
describe('and a truthy value', function() {
it('checks the checkbox input', function() {
rivets.binders.checked.routine(checkboxInput, true)
checkboxInput.checked.should.equal(true)
})
})
describe('with a falsey value', function() {
it('unchecks the checkbox input', function() {
rivets.binders.checked.routine(checkboxInput, false)
checkboxInput.checked.should.equal(false)
})
})
})
describe('with a radio input with value="true"', function() {
describe('and a truthy value', function() {
it('checks the radio input', function() {
rivets.binders.checked.routine(trueRadioInput, true)
trueRadioInput.checked.should.equal(true)
})
})
describe('with a falsey value', function() {
it('unchecks the radio input', function() {
rivets.binders.checked.routine(trueRadioInput, false)
trueRadioInput.checked.should.equal(false)
})
})
})
describe('with a radio input with value="false"', function() {
describe('and a truthy value', function() {
it('checks the radio input', function() {
rivets.binders.checked.routine(falseRadioInput, true)
falseRadioInput.checked.should.equal(false)
})
})
describe('with a falsey value', function() {
it('unchecks the radio input', function() {
rivets.binders.checked.routine(falseRadioInput, false)
falseRadioInput.checked.should.equal(true)
})
})
})
})
describe('unchecked', function() {
describe('and a truthy value', function() {
describe('and a truthy value', function() {
it('checks the checkbox input', function() {
rivets.binders.unchecked.routine(checkboxInput, true)
checkboxInput.checked.should.equal(false)
})
})
describe('with a falsey value', function() {
it('unchecks the checkbox input', function() {
rivets.binders.unchecked.routine(checkboxInput, false)
checkboxInput.checked.should.equal(true)
})
})
})
describe('with a radio input with value="true"', function() {
describe('and a truthy value', function() {
it('checks the radio input', function() {
rivets.binders.unchecked.routine(trueRadioInput, true)
trueRadioInput.checked.should.equal(false)
})
})
describe('with a falsey value', function() {
it('unchecks the radio input', function() {
rivets.binders.unchecked.routine(trueRadioInput, false)
trueRadioInput.checked.should.equal(true)
})
})
})
describe('with a radio input with value="false"', function() {
describe('and a truthy value', function() {
it('checks the radio input', function() {
rivets.binders.unchecked.routine(falseRadioInput, true)
falseRadioInput.checked.should.equal(true)
})
})
describe('with a falsey value', function() {
it('unchecks the radio input', function() {
rivets.binders.unchecked.routine(falseRadioInput, false)
falseRadioInput.checked.should.equal(false)
})
})
})
})
})

View file

@ -0,0 +1,55 @@
describe("Rivets.TextTemplateParser", function() {
var Rivets = rivets._
describe("parse()", function() {
it("tokenizes a text template", function() {
template = "Hello {{ user.name }}, you have {{ user.messages.unread | length }} unread messages."
expected = [
{type: 0, value: "Hello "},
{type: 1, value: "user.name"},
{type: 0, value: ", you have "},
{type: 1, value: "user.messages.unread | length"},
{type: 0, value: " unread messages."}
]
results = Rivets.TextTemplateParser.parse(template, ['{{', '}}'])
results.length.should.equal(5)
for (i = 0; i < results.length; i++) {
results[i].type.should.equal(expected[i].type)
results[i].value.should.equal(expected[i].value)
}
})
describe("with no binding fragments", function() {
it("should return a single text token", function() {
template = "Hello World!"
expected = [{type: 0, value: "Hello World!"}]
results = Rivets.TextTemplateParser.parse(template, ['{{', '}}'])
results.length.should.equal(1)
for (i = 0; i < results.length; i++) {
results[i].type.should.equal(expected[i].type)
results[i].value.should.equal(expected[i].value)
}
})
})
describe("with only a binding fragment", function() {
it("should return a single binding token", function() {
template = "{{ user.name }}"
expected = [{type: 1, value: "user.name"}]
results = Rivets.TextTemplateParser.parse(template, ['{{', '}}'])
results.length.should.equal(1)
for (i = 0; i < results.length; i++) {
results[i].type.should.equal(expected[i].type)
results[i].value.should.equal(expected[i].value)
}
})
})
})
})

39
immoweb/node_modules/rivets/spec/runner.html generated vendored Normal file
View file

@ -0,0 +1,39 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mocha Test Runner</title>
<link rel="stylesheet" href="../node_modules/mocha/mocha.css">
</head>
<body>
<div id="mocha"></div>
<script src="../node_modules/mocha/mocha.js"></script>
<script src="../node_modules/should/should.js"></script>
<script src="../node_modules/sinon/pkg/sinon.js"></script>
<script src="../node_modules/sightglass/index.js"></script>
<script src="../dist/rivets.js"></script>
<script>mocha.setup('bdd')</script>
<script src="lib/mock.data.js"></script>
<script src="rivets/binders.js"></script>
<script src="rivets/formatters.js"></script>
<script src="rivets/binding.js"></script>
<script src="rivets/component_binding.js"></script>
<script src="rivets/functional.js"></script>
<script src="rivets/routines.js"></script>
<script src="rivets/text_template_parser.js"></script>
<script>
if (window.mochaPhantomJS) {
mochaPhantomJS.run();
} else {
mocha.run();
}
</script>
</body>
</html>