/*! * intention.js Library v0.9.7.2 * http://intentionjs.com/ * * Copyright 2011, 2013 Dowjones and other contributors * Released under the MIT license * */ (function(root, factory) { 'use strict'; if (typeof define === 'function' && define.amd) { define('intention', ['jquery', 'underscore'], factory); } else { root.Intention = factory(root.jQuery, root._); } }(this, function($, _) { 'use strict'; var Intention = function(params){ var intent = _.extend(this, params, {_listeners:{}, contexts:[], elms:$(), axes:{}, priority:[]}); return intent; }; Intention.prototype = { // public methods responsive:function responsive(contexts, options){ // for generating random ids for axis when not specified var idChars = 'abcdefghijklmnopqrstuvwxyz0123456789', id='', i; // create a random id for the axis for(i=0; i<5; i++){ id += idChars[Math.floor(Math.random() * idChars.length)]; } var defaults = { // if no matcher function is specified expect to compare a // string to the ctx.name property matcher: function(measure, ctx){ return measure === ctx.name; }, // function takes one arg and returns it measure: _.identity, ID: id }; if(_.isObject(options) === false) { options = {}; } if((_.isArray(contexts)) && (_.isArray(contexts[0].contexts))){ _.each(contexts, function(axis){ responsive.apply(this, axis); }, this); return; } if((_.isArray(contexts) === false) && _.isObject(contexts)){ options = contexts; } else { options.contexts = contexts; } // fill in the options options = _.extend({}, defaults, options); // bind an the respond function to the axis ID and prefix it // with an underscore so that it does not get whomped accidentally this.on('_' + options.ID + ':', _.bind( function(e){ this.axes = this._contextualize( options.ID, e.context, this.axes); this._respond(this.axes, this.elms); }, this)); var axis = { ID:options.ID, current:null, contexts:options.contexts, respond:_.bind(this._responder(options.ID, options.contexts, options.matcher, options.measure), this) }; this.axes[options.ID] = axis; this.axes.__keys__ = this.priority; this.priority.unshift(options.ID); return axis; }, elements: function(scope){ // find all responsive elms in a specific dom scope if(!scope){ scope = document; } $('[data-intent],[intent],[data-in],[in]', scope).each(_.bind(function(i, elm){ this.add($(elm)); }, this)); return this; }, add: function(elms, options){ var spec; if(!options) { options = {}; } // is expecting a jquery object elms.each(_.bind(function(i, elm){ var exists = false; this.elms.each(function(i, respElm){ if(elm === respElm) { exists=true; return false; } return true; }); if(exists === false){ // create the elements responsive data spec = this._fillSpec( _.extend(options, this._attrsToSpec(elm.attributes, this.axes))); // make any appropriate changes based on the current contexts this._makeChanges($(elm), spec, this.axes); this.elms.push({ elm: elm, spec: spec }); } }, this)); return this; }, remove: function(elms){ // is expecting a jquery object var respElms = this.elms; // elms to remove elms.each(function(i, elm){ // elms to check against respElms.each(function(i, candidate){ if(elm === candidate.elm){ respElms.splice(i, 1); // found the match, break the loop return false; } return true; }); }); return this; }, is: function(ctxName){ var axes = this.axes; return _.some(axes.__keys__, function(key){ return ctxName === axes[key].current; }); }, current: function(axisName){ if(this.axes.hasOwnProperty(axisName)){ return this.axes[axisName].current; } else { return false; } }, // code and concept taken from simple implementation of // observer pattern outlined here: // http://www.nczonline.net/blog/2010/03/09/custom-events-in-javascript/ on: function(type, listener){ var events = type.split(' '), i=0; for(i;i