From 8528bb13012d5987398fc2aad04099c0fe081ff4 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Mon, 20 May 2013 14:10:21 -0700 Subject: [PATCH] updated modelbinder, mutator, pagable, lunr. --- UI/JsLibraries/backbone.modelbinder.js | 58 +++++----- UI/JsLibraries/backbone.mutators.js | 147 ++++++++++++++++--------- UI/JsLibraries/backbone.pageable.js | 4 +- UI/JsLibraries/lunr.js | 12 +- 4 files changed, 132 insertions(+), 89 deletions(-) diff --git a/UI/JsLibraries/backbone.modelbinder.js b/UI/JsLibraries/backbone.modelbinder.js index 4970aa5ad..fcc2164c7 100644 --- a/UI/JsLibraries/backbone.modelbinder.js +++ b/UI/JsLibraries/backbone.modelbinder.js @@ -38,7 +38,7 @@ this._model = model; this._rootEl = rootEl; - this._setOptions(options); + this._setOptions(options); if (!this._model) this._throwException('model must be specified'); if (!this._rootEl) this._throwException('rootEl must be specified'); @@ -58,10 +58,10 @@ this._bindViewToModel(); }, - bindCustomTriggers: function (model, rootEl, triggers, attributeBindings, modelSetOptions) { - this._triggers = triggers; - this.bind(model, rootEl, attributeBindings, modelSetOptions) - }, + bindCustomTriggers: function (model, rootEl, triggers, attributeBindings, modelSetOptions) { + this._triggers = triggers; + this.bind(model, rootEl, attributeBindings, modelSetOptions) + }, unbind:function () { this._unbindModelToView(); @@ -74,7 +74,9 @@ }, _setOptions: function(options){ - this._options = _.extend({}, Backbone.ModelBinder.options, options); + this._options = _.extend({ + boundAttribute: 'name' + }, Backbone.ModelBinder.options, options); // initialize default options if(!this._options['modelSetOptions']){ @@ -122,24 +124,25 @@ } }, - // If the bindings are not specified, the default binding is performed on the name attribute + // If the bindings are not specified, the default binding is performed on the specified attribute, name by default _initializeDefaultBindings: function(){ - var elCount, namedEls, namedEl, name, attributeBinding; + var elCount, elsWithAttribute, matchedEl, name, attributeBinding; + this._attributeBindings = {}; - namedEls = $('[name]', this._rootEl); + elsWithAttribute = $('[' + this._options['boundAttribute'] + ']', this._rootEl); - for(elCount = 0; elCount < namedEls.length; elCount++){ - namedEl = namedEls[elCount]; - name = $(namedEl).attr('name'); + for(elCount = 0; elCount < elsWithAttribute.length; elCount++){ + matchedEl = elsWithAttribute[elCount]; + name = $(matchedEl).attr(this._options['boundAttribute']); // For elements like radio buttons we only want a single attribute binding with possibly multiple element bindings if(!this._attributeBindings[name]){ attributeBinding = {attributeName: name}; - attributeBinding.elementBindings = [{attributeBinding: attributeBinding, boundEls: [namedEl]}]; + attributeBinding.elementBindings = [{attributeBinding: attributeBinding, boundEls: [matchedEl]}]; this._attributeBindings[name] = attributeBinding; } else{ - this._attributeBindings[name].elementBindings.push({attributeBinding: this._attributeBindings[name], boundEls: [namedEl]}); + this._attributeBindings[name].elementBindings.push({attributeBinding: this._attributeBindings[name], boundEls: [matchedEl]}); } } }, @@ -370,7 +373,7 @@ el.text(convertedValue); break; case 'enabled': - el.attr('disabled', !convertedValue); + el.prop('disabled', !convertedValue); break; case 'displayed': el[convertedValue ? 'show' : 'hide'](); @@ -383,8 +386,8 @@ break; case 'class': var previousValue = this._model.previous(elementBinding.attributeBinding.attributeName); - var currentValue = this._model.get(elementBinding.attributeBinding.attributeName); - // is current value is now defined then remove the class the may have been set for the undefined value + var currentValue = this._model.get(elementBinding.attributeBinding.attributeName); + // is current value is now defined then remove the class the may have been set for the undefined value if(!_.isUndefined(previousValue) || !_.isUndefined(currentValue)){ previousValue = this._getConvertedValue(Backbone.ModelBinder.Constants.ModelToView, elementBinding, previousValue); el.removeClass(previousValue); @@ -404,22 +407,21 @@ switch (el.attr('type')) { case 'radio': if (el.val() === convertedValue) { - el.attr('checked', 'checked'); + // must defer the change trigger or the change will actually fire with the old value + el.prop('checked') || _.defer(function() { el.trigger('change'); }); + el.prop('checked', true); } else { - el.removeAttr('checked'); + // must defer the change trigger or the change will actually fire with the old value + el.prop('checked', false); } break; case 'checkbox': - if (convertedValue) { - //Fixing this while we wait for an official update - el.prop('checked', 'checked'); - } - else { - el.removeAttr('checked'); - } + // must defer the change trigger or the change will actually fire with the old value + el.prop('checked') === !!convertedValue || _.defer(function() { el.trigger('change') }); + el.prop('checked', !!convertedValue); break; - case 'file': + case 'file': break; default: el.val(convertedValue); @@ -571,4 +573,4 @@ return Backbone.ModelBinder; -})); +})); \ No newline at end of file diff --git a/UI/JsLibraries/backbone.mutators.js b/UI/JsLibraries/backbone.mutators.js index bb79f4d1b..97438e0be 100644 --- a/UI/JsLibraries/backbone.mutators.js +++ b/UI/JsLibraries/backbone.mutators.js @@ -1,11 +1,36 @@ -(function (root, define, require, exports, module, factory, undef) { +/*! Backbone.Mutators - v0.4.0 +------------------------------ +Build @ 2013-05-01 +Documentation and Full License Available at: +http://asciidisco.github.com/Backbone.Mutators/index.html +git://github.com/asciidisco/Backbone.Mutators.git +Copyright (c) 2013 Sebastian Golasch + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the + +Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE.*/ +(function (root, factory, undef) { 'use strict'; if (typeof exports === 'object') { // Node. Does not work with strict CommonJS, but // only CommonJS-like enviroments that support module.exports, // like Node. - module.exports = factory(require('underscore'), require('backbone')); + module.exports = factory(require('underscore'), require('Backbone')); } else if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define(['underscore', 'backbone'], function (_, Backbone) { @@ -19,45 +44,45 @@ root.returnExportsGlobal = factory(root._, root.Backbone); } - // Usage: - // - // Note: This plugin is UMD compatible, you can use it in node, amd and vanilla js envs - // - // Vanilla JS: - // - // - // - // - // Node: - // var _ = require('underscore'); - // var Backbone = require('backbone'); - // var Mutators = require('backbone.mutators'); - // - // - // AMD: - // define(['underscore', 'backbone', 'backbone.mutators'], function (_, Backbone, Mutators) { - // // insert sample from below - // return User; - // }); - // - // var User = Backbone.Model.extend({ - // mutators: { - // fullname: function () { - // return this.firstname + ' ' + this.lastname; - // } - // }, - // - // defaults: { - // firstname: 'Sebastian', - // lastname: 'Golasch' - // } - // }); - // - // var user = new User(); - // user.get('fullname') // returns 'Sebastian Golasch' - // user.toJSON() // return '{firstname: 'Sebastian', lastname: 'Golasch', fullname: 'Sebastian Golasch'}' - -}(this, this.define, this.require, this.exports, this.module, function (_, Backbone, root, undef) { +// Usage: +// +// Note: This plugin is UMD compatible, you can use it in node, amd and vanilla js envs +// +// Vanilla JS: +// +// +// +// +// Node: +// var _ = require('underscore'); +// var Backbone = require('backbone'); +// var Mutators = require('backbone.mutators'); +// +// +// AMD: +// define(['underscore', 'backbone', 'backbone.mutators'], function (_, Backbone, Mutators) { +// // insert sample from below +// return User; +// }); +// +// var User = Backbone.Model.extend({ +// mutators: { +// fullname: function () { +// return this.firstname + ' ' + this.lastname; +// } +// }, +// +// defaults: { +// firstname: 'Sebastian', +// lastname: 'Golasch' +// } +// }); +// +// var user = new User(); +// user.get('fullname') // returns 'Sebastian Golasch' +// user.toJSON() // return '{firstname: 'Sebastian', lastname: 'Golasch', fullname: 'Sebastian Golasch'}' + +}(this, function (_, Backbone, root, undef) { 'use strict'; // check if we use the amd branch of backbone and underscore @@ -65,10 +90,10 @@ _ = _ === undef ? root._ : _; // extend backbones model prototype with the mutator functionality - var Mutator = function () { }, - oldGet = Backbone.Model.prototype.get, - oldSet = Backbone.Model.prototype.set, - oldToJson = Backbone.Model.prototype.toJSON; + var Mutator = function () {}, + oldGet = Backbone.Model.prototype.get, + oldSet = Backbone.Model.prototype.set, + oldToJson = Backbone.Model.prototype.toJSON; // This is necessary to ensure that Models declared without the mutators object do not throw and error Mutator.prototype.mutators = {}; @@ -94,12 +119,11 @@ Mutator.prototype.set = function (key, value, options) { var isMutator = this.mutators !== undef, ret = null, - attrs = null, - attr = null; + attrs = null; // seamleassly stolen from backbone core - // check if the setter action is triggered - // using key <-> value or object + // check if the setter action is triggered + // using key <-> value or object if (_.isObject(key) || key === null) { attrs = key; options = value; @@ -114,29 +138,36 @@ // check if we need to set a single value if (_.isFunction(this.mutators[key].set) === true) { ret = this.mutators[key].set.call(this, key, attrs[key], options, _.bind(oldSet, this)); - } else if (_.isFunction(this.mutators[key])) { + } else if(_.isFunction(this.mutators[key])){ ret = this.mutators[key].call(this, key, attrs[key], options, _.bind(oldSet, this)); } } if (_.isObject(attrs)) { _.each(attrs, _.bind(function (attr, attrKey) { + var cur_ret = null; if (isMutator === true && _.isObject(this.mutators[attrKey]) === true) { // check if we need to set a single value var meth = this.mutators[attrKey]; - if (_.isFunction(meth.set)) { + if(_.isFunction(meth.set)){ meth = meth.set; } - if (_.isFunction(meth)) { + if(_.isFunction(meth)){ if (options === undef || (_.isObject(options) === true && options.silent !== true && (options.mutators !== undef && options.mutators.silent !== true))) { this.trigger('mutators:set:' + attrKey); } - ret = meth.call(this, attrKey, attr, options, _.bind(oldSet, this)); + cur_ret = meth.call(this, attrKey, attr, options, _.bind(oldSet, this)); } } + if (cur_ret === null) { + cur_ret = _.bind(oldSet, this)(attrKey, attr, options); + } + + if (ret !== false) { ret = cur_ret; } + }, this)); } @@ -154,7 +185,7 @@ var attr = oldToJson.call(this); // iterate over all mutators (if there are some) _.each(this.mutators, _.bind(function (mutator, name) { - // check if we have some getter mutations (nested or ) + // check if we have some getter mutations if (_.isObject(this.mutators[name]) === true && _.isFunction(this.mutators[name].get)) { attr[name] = _.bind(this.mutators[name].get, this)(); } else { @@ -165,10 +196,16 @@ return attr; }; + // override get functionality to get HTML-escaped the mutator props + Mutator.prototype.escape = function (attr){ + var val = this.get(attr); + return _.escape(val == null ? '' : '' + val); + }; + // extend the models prototype _.extend(Backbone.Model.prototype, Mutator.prototype); // make mutators globally available under the Backbone namespace Backbone.Mutators = Mutator; return Mutator; -})); \ No newline at end of file +})); diff --git a/UI/JsLibraries/backbone.pageable.js b/UI/JsLibraries/backbone.pageable.js index 7733d1c54..d7f763a94 100644 --- a/UI/JsLibraries/backbone.pageable.js +++ b/UI/JsLibraries/backbone.pageable.js @@ -506,8 +506,8 @@ } pageCol.state = pageCol._checkState(state); if (collection == pageCol) fullCol.trigger(event, fullCol, options); - resetQuickly(pageCol, fullCol.models.slice(pageStart, pageEnd), - _extend({}, options, {parse: false})); + else resetQuickly(pageCol, fullCol.models.slice(pageStart, pageEnd), + _extend({}, options, {parse: false})); } } diff --git a/UI/JsLibraries/lunr.js b/UI/JsLibraries/lunr.js index 6bbd38b3f..e6c73a766 100644 --- a/UI/JsLibraries/lunr.js +++ b/UI/JsLibraries/lunr.js @@ -1,5 +1,5 @@ /** - * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.3.1 + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.3.2 * Copyright (C) 2013 Oliver Nightingale * MIT Licensed * @license @@ -50,7 +50,7 @@ var lunr = function (config) { return idx } -lunr.version = "0.3.1" +lunr.version = "0.3.2" if (typeof module !== 'undefined') { module.exports = lunr @@ -69,6 +69,7 @@ if (typeof module !== 'undefined') { * @returns {Array} */ lunr.tokenizer = function (str) { + if (!str) return [] if (Array.isArray(str)) return str var str = str.replace(/^\s+/, '') @@ -737,8 +738,11 @@ lunr.Index.prototype.add = function (doc) { for (var i = 0; i < allDocumentTokens.length; i++) { var token = allDocumentTokens.elements[i] var tf = this._fields.reduce(function (memo, field) { - var tokenCount = docTokens[field.name].filter(function (t) { return t === token }).length, - fieldLength = docTokens[field.name].length + var fieldLength = docTokens[field.name].length + + if (!fieldLength) return memo + + var tokenCount = docTokens[field.name].filter(function (t) { return t === token }).length return memo + (tokenCount / fieldLength * field.boost) }, 0)