UNPKG

dynamic

Version:
1,587 lines (1,343 loc) 47 kB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.dynamic = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ /* * Dynamic - Declarative DOM behaviour * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/dynamic * * Released under the MIT license * https://github.com/asmblah/dynamic/raw/master/MIT-LICENSE.txt */ 'use strict'; var expressionEvaluator = require('expression-eval'), Dynamic = require('./src/Dynamic'), DataAttributeOptionReader = require('./src/OptionSet/DataAttributeOptionReader'), ObjectOptionReader = require('./src/OptionSet/ObjectOptionReader'), OptionReader = require('./src/OptionSet/OptionReader'), OptionSet = require('./src/OptionSet/OptionSet'), OptionSetFactory = require('./src/OptionSet/OptionSetFactory'), SelectorEngine = require('./src/SelectorEngine'), ToggleBehaviour = require('./src/Behaviour/ToggleBehaviour'); module.exports = { create: function ($, $root) { var $context = $root || $('html'), expressionContext = {$: $}, dataAttributeOptionReader = new OptionReader( new DataAttributeOptionReader(), expressionContext, expressionEvaluator ), objectOptionReader = new OptionReader( new ObjectOptionReader(), expressionContext, expressionEvaluator ), selectorEngine = new SelectorEngine($context), dataAttributeOptionSetFactory = new OptionSetFactory( $, OptionSet, dataAttributeOptionReader, selectorEngine ), objectOptionSetFactory = new OptionSetFactory( $, OptionSet, objectOptionReader, selectorEngine ), dynamic = new Dynamic( dataAttributeOptionSetFactory, objectOptionSetFactory, $, $context ), toggleBehaviour = new ToggleBehaviour(); // Add the default 'toggle' behaviour dynamic.addBehaviour('toggle', $.proxy(toggleBehaviour.handle, toggleBehaviour)); return dynamic; } }; },{"./src/Behaviour/ToggleBehaviour":18,"./src/Dynamic":19,"./src/OptionSet/DataAttributeOptionReader":20,"./src/OptionSet/ObjectOptionReader":21,"./src/OptionSet/OptionReader":22,"./src/OptionSet/OptionSet":23,"./src/OptionSet/OptionSetFactory":24,"./src/SelectorEngine":25,"expression-eval":2}],2:[function(require,module,exports){ var jsep = require('jsep'); /** * Evaluation code from JSEP project, under MIT License. * Copyright (c) 2013 Stephen Oney, http://jsep.from.so/ */ var binops = { '||': function (a, b) { return a || b; }, '&&': function (a, b) { return a && b; }, '|': function (a, b) { return a | b; }, '^': function (a, b) { return a ^ b; }, '&': function (a, b) { return a & b; }, '==': function (a, b) { return a == b; }, // jshint ignore:line '!=': function (a, b) { return a != b; }, // jshint ignore:line '===': function (a, b) { return a === b; }, '!==': function (a, b) { return a !== b; }, '<': function (a, b) { return a < b; }, '>': function (a, b) { return a > b; }, '<=': function (a, b) { return a <= b; }, '>=': function (a, b) { return a >= b; }, '<<': function (a, b) { return a << b; }, '>>': function (a, b) { return a >> b; }, '>>>': function (a, b) { return a >>> b; }, '+': function (a, b) { return a + b; }, '-': function (a, b) { return a - b; }, '*': function (a, b) { return a * b; }, '/': function (a, b) { return a / b; }, '%': function (a, b) { return a % b; } }; var unops = { '-' : function (a) { return -a; }, '+' : function (a) { return a; }, '~' : function (a) { return ~a; }, '!' : function (a) { return !a; }, }; function evaluateArray ( list, context ) { return list.map(function (v) { return evaluate(v, context); }); } function evaluateMember ( node, context ) { var object = evaluate(node.object, context); if ( node.computed ) { return [object, object[evaluate(node.property, context)]]; } else { return [object, object[node.property.name]]; } } function evaluate ( node, context ) { switch ( node.type ) { case 'ArrayExpression': return evaluateArray( node.elements, context ); case 'BinaryExpression': return binops[ node.operator ]( evaluate( node.left, context ), evaluate( node.right, context ) ); case 'CallExpression': var caller, fn, assign; if (node.callee.type === 'MemberExpression') { assign = evaluateMember( node.callee, context ); caller = assign[0]; fn = assign[1]; } else { fn = evaluate( node.callee, context ); } if (typeof fn !== 'function') { return undefined; } return fn.apply( caller, evaluateArray( node.arguments, context ) ); case 'ConditionalExpression': return evaluate( node.test, context ) ? evaluate( node.consequent, context ) : evaluate( node.alternate, context ); case 'Identifier': return context[node.name]; case 'Literal': return node.value; case 'LogicalExpression': if (node.operator === '||') { return evaluate( node.left, context ) || evaluate( node.right, context ); } else if (node.operator === '&&') { return evaluate( node.left, context ) && evaluate( node.right, context ); } return binops[ node.operator ]( evaluate( node.left, context ), evaluate( node.right, context ) ); case 'MemberExpression': return evaluateMember(node, context)[1]; case 'ThisExpression': return context; case 'UnaryExpression': return unops[ node.operator ]( evaluate( node.argument, context ) ); default: return undefined; } } function compile (expression) { return evaluate.bind(null, jsep(expression)); } module.exports = { parse: jsep, eval: evaluate, compile: compile }; },{"jsep":3}],3:[function(require,module,exports){ // JavaScript Expression Parser (JSEP) 0.3.4 // JSEP may be freely distributed under the MIT License // http://jsep.from.so/ /*global module: true, exports: true, console: true */ (function (root) { 'use strict'; // Node Types // ---------- // This is the full set of types that any JSEP node can be. // Store them here to save space when minified var COMPOUND = 'Compound', IDENTIFIER = 'Identifier', MEMBER_EXP = 'MemberExpression', LITERAL = 'Literal', THIS_EXP = 'ThisExpression', CALL_EXP = 'CallExpression', UNARY_EXP = 'UnaryExpression', BINARY_EXP = 'BinaryExpression', LOGICAL_EXP = 'LogicalExpression', CONDITIONAL_EXP = 'ConditionalExpression', ARRAY_EXP = 'ArrayExpression', PERIOD_CODE = 46, // '.' COMMA_CODE = 44, // ',' SQUOTE_CODE = 39, // single quote DQUOTE_CODE = 34, // double quotes OPAREN_CODE = 40, // ( CPAREN_CODE = 41, // ) OBRACK_CODE = 91, // [ CBRACK_CODE = 93, // ] QUMARK_CODE = 63, // ? SEMCOL_CODE = 59, // ; COLON_CODE = 58, // : throwError = function(message, index) { var error = new Error(message + ' at character ' + index); error.index = index; error.description = message; throw error; }, // Operations // ---------- // Set `t` to `true` to save space (when minified, not gzipped) t = true, // Use a quickly-accessible map to store all of the unary operators // Values are set to `true` (it really doesn't matter) unary_ops = {'-': t, '!': t, '~': t, '+': t}, // Also use a map for the binary operations but set their values to their // binary precedence for quick reference: // see [Order of operations](http://en.wikipedia.org/wiki/Order_of_operations#Programming_language) binary_ops = { '||': 1, '&&': 2, '|': 3, '^': 4, '&': 5, '==': 6, '!=': 6, '===': 6, '!==': 6, '<': 7, '>': 7, '<=': 7, '>=': 7, '<<':8, '>>': 8, '>>>': 8, '+': 9, '-': 9, '*': 10, '/': 10, '%': 10 }, // Get return the longest key length of any object getMaxKeyLen = function(obj) { var max_len = 0, len; for(var key in obj) { if((len = key.length) > max_len && obj.hasOwnProperty(key)) { max_len = len; } } return max_len; }, max_unop_len = getMaxKeyLen(unary_ops), max_binop_len = getMaxKeyLen(binary_ops), // Literals // ---------- // Store the values to return for the various literals we may encounter literals = { 'true': true, 'false': false, 'null': null }, // Except for `this`, which is special. This could be changed to something like `'self'` as well this_str = 'this', // Returns the precedence of a binary operator or `0` if it isn't a binary operator binaryPrecedence = function(op_val) { return binary_ops[op_val] || 0; }, // Utility function (gets called from multiple places) // Also note that `a && b` and `a || b` are *logical* expressions, not binary expressions createBinaryExpression = function (operator, left, right) { var type = (operator === '||' || operator === '&&') ? LOGICAL_EXP : BINARY_EXP; return { type: type, operator: operator, left: left, right: right }; }, // `ch` is a character code in the next three functions isDecimalDigit = function(ch) { return (ch >= 48 && ch <= 57); // 0...9 }, isIdentifierStart = function(ch) { return (ch === 36) || (ch === 95) || // `$` and `_` (ch >= 65 && ch <= 90) || // A...Z (ch >= 97 && ch <= 122) || // a...z (ch >= 128 && !binary_ops[String.fromCharCode(ch)]); // any non-ASCII that is not an operator }, isIdentifierPart = function(ch) { return (ch === 36) || (ch === 95) || // `$` and `_` (ch >= 65 && ch <= 90) || // A...Z (ch >= 97 && ch <= 122) || // a...z (ch >= 48 && ch <= 57) || // 0...9 (ch >= 128 && !binary_ops[String.fromCharCode(ch)]); // any non-ASCII that is not an operator }, // Parsing // ------- // `expr` is a string with the passed in expression jsep = function(expr) { // `index` stores the character number we are currently at while `length` is a constant // All of the gobbles below will modify `index` as we move along var index = 0, charAtFunc = expr.charAt, charCodeAtFunc = expr.charCodeAt, exprI = function(i) { return charAtFunc.call(expr, i); }, exprICode = function(i) { return charCodeAtFunc.call(expr, i); }, length = expr.length, // Push `index` up to the next non-space character gobbleSpaces = function() { var ch = exprICode(index); // space or tab while(ch === 32 || ch === 9 || ch === 10 || ch === 13) { ch = exprICode(++index); } }, // The main parsing function. Much of this code is dedicated to ternary expressions gobbleExpression = function() { var test = gobbleBinaryExpression(), consequent, alternate; gobbleSpaces(); if(exprICode(index) === QUMARK_CODE) { // Ternary expression: test ? consequent : alternate index++; consequent = gobbleExpression(); if(!consequent) { throwError('Expected expression', index); } gobbleSpaces(); if(exprICode(index) === COLON_CODE) { index++; alternate = gobbleExpression(); if(!alternate) { throwError('Expected expression', index); } return { type: CONDITIONAL_EXP, test: test, consequent: consequent, alternate: alternate }; } else { throwError('Expected :', index); } } else { return test; } }, // Search for the operation portion of the string (e.g. `+`, `===`) // Start by taking the longest possible binary operations (3 characters: `===`, `!==`, `>>>`) // and move down from 3 to 2 to 1 character until a matching binary operation is found // then, return that binary operation gobbleBinaryOp = function() { gobbleSpaces(); var biop, to_check = expr.substr(index, max_binop_len), tc_len = to_check.length; while(tc_len > 0) { // Don't accept a binary op when it is an identifier. // Binary ops that start with a identifier-valid character must be followed // by a non identifier-part valid character if(binary_ops.hasOwnProperty(to_check) && ( !isIdentifierStart(exprICode(index)) || (index+to_check.length< expr.length && !isIdentifierPart(exprICode(index+to_check.length))) )) { index += tc_len; return to_check; } to_check = to_check.substr(0, --tc_len); } return false; }, // This function is responsible for gobbling an individual expression, // e.g. `1`, `1+2`, `a+(b*2)-Math.sqrt(2)` gobbleBinaryExpression = function() { var ch_i, node, biop, prec, stack, biop_info, left, right, i; // First, try to get the leftmost thing // Then, check to see if there's a binary operator operating on that leftmost thing left = gobbleToken(); biop = gobbleBinaryOp(); // If there wasn't a binary operator, just return the leftmost node if(!biop) { return left; } // Otherwise, we need to start a stack to properly place the binary operations in their // precedence structure biop_info = { value: biop, prec: binaryPrecedence(biop)}; right = gobbleToken(); if(!right) { throwError("Expected expression after " + biop, index); } stack = [left, biop_info, right]; // Properly deal with precedence using [recursive descent](http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm) while((biop = gobbleBinaryOp())) { prec = binaryPrecedence(biop); if(prec === 0) { break; } biop_info = { value: biop, prec: prec }; // Reduce: make a binary expression from the three topmost entries. while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) { right = stack.pop(); biop = stack.pop().value; left = stack.pop(); node = createBinaryExpression(biop, left, right); stack.push(node); } node = gobbleToken(); if(!node) { throwError("Expected expression after " + biop, index); } stack.push(biop_info, node); } i = stack.length - 1; node = stack[i]; while(i > 1) { node = createBinaryExpression(stack[i - 1].value, stack[i - 2], node); i -= 2; } return node; }, // An individual part of a binary expression: // e.g. `foo.bar(baz)`, `1`, `"abc"`, `(a % 2)` (because it's in parenthesis) gobbleToken = function() { var ch, to_check, tc_len; gobbleSpaces(); ch = exprICode(index); if(isDecimalDigit(ch) || ch === PERIOD_CODE) { // Char code 46 is a dot `.` which can start off a numeric literal return gobbleNumericLiteral(); } else if(ch === SQUOTE_CODE || ch === DQUOTE_CODE) { // Single or double quotes return gobbleStringLiteral(); } else if (ch === OBRACK_CODE) { return gobbleArray(); } else { to_check = expr.substr(index, max_unop_len); tc_len = to_check.length; while(tc_len > 0) { // Don't accept an unary op when it is an identifier. // Unary ops that start with a identifier-valid character must be followed // by a non identifier-part valid character if(unary_ops.hasOwnProperty(to_check) && ( !isIdentifierStart(exprICode(index)) || (index+to_check.length < expr.length && !isIdentifierPart(exprICode(index+to_check.length))) )) { index += tc_len; return { type: UNARY_EXP, operator: to_check, argument: gobbleToken(), prefix: true }; } to_check = to_check.substr(0, --tc_len); } if (isIdentifierStart(ch) || ch === OPAREN_CODE) { // open parenthesis // `foo`, `bar.baz` return gobbleVariable(); } } return false; }, // Parse simple numeric literals: `12`, `3.4`, `.5`. Do this by using a string to // keep track of everything in the numeric literal and then calling `parseFloat` on that string gobbleNumericLiteral = function() { var number = '', ch, chCode; while(isDecimalDigit(exprICode(index))) { number += exprI(index++); } if(exprICode(index) === PERIOD_CODE) { // can start with a decimal marker number += exprI(index++); while(isDecimalDigit(exprICode(index))) { number += exprI(index++); } } ch = exprI(index); if(ch === 'e' || ch === 'E') { // exponent marker number += exprI(index++); ch = exprI(index); if(ch === '+' || ch === '-') { // exponent sign number += exprI(index++); } while(isDecimalDigit(exprICode(index))) { //exponent itself number += exprI(index++); } if(!isDecimalDigit(exprICode(index-1)) ) { throwError('Expected exponent (' + number + exprI(index) + ')', index); } } chCode = exprICode(index); // Check to make sure this isn't a variable name that start with a number (123abc) if(isIdentifierStart(chCode)) { throwError('Variable names cannot start with a number (' + number + exprI(index) + ')', index); } else if(chCode === PERIOD_CODE) { throwError('Unexpected period', index); } return { type: LITERAL, value: parseFloat(number), raw: number }; }, // Parses a string literal, staring with single or double quotes with basic support for escape codes // e.g. `"hello world"`, `'this is\nJSEP'` gobbleStringLiteral = function() { var str = '', quote = exprI(index++), closed = false, ch; while(index < length) { ch = exprI(index++); if(ch === quote) { closed = true; break; } else if(ch === '\\') { // Check for all of the common escape codes ch = exprI(index++); switch(ch) { case 'n': str += '\n'; break; case 'r': str += '\r'; break; case 't': str += '\t'; break; case 'b': str += '\b'; break; case 'f': str += '\f'; break; case 'v': str += '\x0B'; break; default : str += ch; } } else { str += ch; } } if(!closed) { throwError('Unclosed quote after "'+str+'"', index); } return { type: LITERAL, value: str, raw: quote + str + quote }; }, // Gobbles only identifiers // e.g.: `foo`, `_value`, `$x1` // Also, this function checks if that identifier is a literal: // (e.g. `true`, `false`, `null`) or `this` gobbleIdentifier = function() { var ch = exprICode(index), start = index, identifier; if(isIdentifierStart(ch)) { index++; } else { throwError('Unexpected ' + exprI(index), index); } while(index < length) { ch = exprICode(index); if(isIdentifierPart(ch)) { index++; } else { break; } } identifier = expr.slice(start, index); if(literals.hasOwnProperty(identifier)) { return { type: LITERAL, value: literals[identifier], raw: identifier }; } else if(identifier === this_str) { return { type: THIS_EXP }; } else { return { type: IDENTIFIER, name: identifier }; } }, // Gobbles a list of arguments within the context of a function call // or array literal. This function also assumes that the opening character // `(` or `[` has already been gobbled, and gobbles expressions and commas // until the terminator character `)` or `]` is encountered. // e.g. `foo(bar, baz)`, `my_func()`, or `[bar, baz]` gobbleArguments = function(termination) { var ch_i, args = [], node, closed = false; while(index < length) { gobbleSpaces(); ch_i = exprICode(index); if(ch_i === termination) { // done parsing closed = true; index++; break; } else if (ch_i === COMMA_CODE) { // between expressions index++; } else { node = gobbleExpression(); if(!node || node.type === COMPOUND) { throwError('Expected comma', index); } args.push(node); } } if (!closed) { throwError('Expected ' + String.fromCharCode(termination), index); } return args; }, // Gobble a non-literal variable name. This variable name may include properties // e.g. `foo`, `bar.baz`, `foo['bar'].baz` // It also gobbles function calls: // e.g. `Math.acos(obj.angle)` gobbleVariable = function() { var ch_i, node; ch_i = exprICode(index); if(ch_i === OPAREN_CODE) { node = gobbleGroup(); } else { node = gobbleIdentifier(); } gobbleSpaces(); ch_i = exprICode(index); while(ch_i === PERIOD_CODE || ch_i === OBRACK_CODE || ch_i === OPAREN_CODE) { index++; if(ch_i === PERIOD_CODE) { gobbleSpaces(); node = { type: MEMBER_EXP, computed: false, object: node, property: gobbleIdentifier() }; } else if(ch_i === OBRACK_CODE) { node = { type: MEMBER_EXP, computed: true, object: node, property: gobbleExpression() }; gobbleSpaces(); ch_i = exprICode(index); if(ch_i !== CBRACK_CODE) { throwError('Unclosed [', index); } index++; } else if(ch_i === OPAREN_CODE) { // A function call is being made; gobble all the arguments node = { type: CALL_EXP, 'arguments': gobbleArguments(CPAREN_CODE), callee: node }; } gobbleSpaces(); ch_i = exprICode(index); } return node; }, // Responsible for parsing a group of things within parentheses `()` // This function assumes that it needs to gobble the opening parenthesis // and then tries to gobble everything within that parenthesis, assuming // that the next thing it should see is the close parenthesis. If not, // then the expression probably doesn't have a `)` gobbleGroup = function() { index++; var node = gobbleExpression(); gobbleSpaces(); if(exprICode(index) === CPAREN_CODE) { index++; return node; } else { throwError('Unclosed (', index); } }, // Responsible for parsing Array literals `[1, 2, 3]` // This function assumes that it needs to gobble the opening bracket // and then tries to gobble the expressions as arguments. gobbleArray = function() { index++; return { type: ARRAY_EXP, elements: gobbleArguments(CBRACK_CODE) }; }, nodes = [], ch_i, node; while(index < length) { ch_i = exprICode(index); // Expressions can be separated by semicolons, commas, or just inferred without any // separators if(ch_i === SEMCOL_CODE || ch_i === COMMA_CODE) { index++; // ignore separators } else { // Try to gobble each expression individually if((node = gobbleExpression())) { nodes.push(node); // If we weren't able to find a binary expression and are out of room, then // the expression passed in probably has too much } else if(index < length) { throwError('Unexpected "' + exprI(index) + '"', index); } } } // If there's only one expression just try returning the expression if(nodes.length === 1) { return nodes[0]; } else { return { type: COMPOUND, body: nodes }; } }; // To be filled in by the template jsep.version = '0.3.4'; jsep.toString = function() { return 'JavaScript Expression Parser (JSEP) v' + jsep.version; }; /** * @method jsep.addUnaryOp * @param {string} op_name The name of the unary op to add * @return jsep */ jsep.addUnaryOp = function(op_name) { max_unop_len = Math.max(op_name.length, max_unop_len); unary_ops[op_name] = t; return this; }; /** * @method jsep.addBinaryOp * @param {string} op_name The name of the binary op to add * @param {number} precedence The precedence of the binary op (can be a float) * @return jsep */ jsep.addBinaryOp = function(op_name, precedence) { max_binop_len = Math.max(op_name.length, max_binop_len); binary_ops[op_name] = precedence; return this; }; /** * @method jsep.addLiteral * @param {string} literal_name The name of the literal to add * @param {*} literal_value The value of the literal * @return jsep */ jsep.addLiteral = function(literal_name, literal_value) { literals[literal_name] = literal_value; return this; }; /** * @method jsep.removeUnaryOp * @param {string} op_name The name of the unary op to remove * @return jsep */ jsep.removeUnaryOp = function(op_name) { delete unary_ops[op_name]; if(op_name.length === max_unop_len) { max_unop_len = getMaxKeyLen(unary_ops); } return this; }; /** * @method jsep.removeAllUnaryOps * @return jsep */ jsep.removeAllUnaryOps = function() { unary_ops = {}; max_unop_len = 0; return this; }; /** * @method jsep.removeBinaryOp * @param {string} op_name The name of the binary op to remove * @return jsep */ jsep.removeBinaryOp = function(op_name) { delete binary_ops[op_name]; if(op_name.length === max_binop_len) { max_binop_len = getMaxKeyLen(binary_ops); } return this; }; /** * @method jsep.removeAllBinaryOps * @return jsep */ jsep.removeAllBinaryOps = function() { binary_ops = {}; max_binop_len = 0; return this; }; /** * @method jsep.removeLiteral * @param {string} literal_name The name of the literal to remove * @return jsep */ jsep.removeLiteral = function(literal_name) { delete literals[literal_name]; return this; }; /** * @method jsep.removeAllLiterals * @return jsep */ jsep.removeAllLiterals = function() { literals = {}; return this; }; // In desktop environments, have a way to restore the old value for `jsep` if (typeof exports === 'undefined') { var old_jsep = root.jsep; // The star of the show! It's a function! root.jsep = jsep; // And a courteous function willing to move out of the way for other similarly-named objects! jsep.noConflict = function() { if(root.jsep === jsep) { root.jsep = old_jsep; } return jsep; }; } else { // In Node.JS environments if (typeof module !== 'undefined' && module.exports) { exports = module.exports = jsep; } else { exports.parse = jsep; } } }(this)); },{}],4:[function(require,module,exports){ /* * Microdash - Tiny utilities for Node and the browser * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/microdash * * Released under the MIT license * https://github.com/asmblah/microdash/raw/master/MIT-LICENSE.txt */ 'use strict'; var each = require('./src/each'), escapeRegExp = require('./src/escapeRegExp'), extend = require('./src/extend'), filter = require('./src/filter'), forOwn = require('./src/forOwn'), isArray = require('./src/isArray'), isBoolean = require('./src/isBoolean'), isFunction = require('./src/isFunction'), isNumber = require('./src/isNumber'), isPlainObject = require('./src/isPlainObject'), isString = require('./src/isString'), map = require('./src/map'); module.exports = { each: each, escapeRegExp: escapeRegExp, extend: extend, filter: filter, forOwn: forOwn, isArray: isArray, isBoolean: isBoolean, isFunction: isFunction, isNumber: isNumber, isPlainObject: isPlainObject, isString: isString, map: map }; },{"./src/each":5,"./src/escapeRegExp":6,"./src/extend":7,"./src/filter":8,"./src/forOwn":9,"./src/isArray":11,"./src/isBoolean":12,"./src/isFunction":13,"./src/isNumber":14,"./src/isPlainObject":15,"./src/isString":16,"./src/map":17}],5:[function(require,module,exports){ /* * Microdash - Tiny utilities for Node and the browser * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/microdash * * Released under the MIT license * https://github.com/asmblah/microdash/raw/master/MIT-LICENSE.txt */ 'use strict'; var hasOwn = {}.hasOwnProperty, isArray = require('./isArray'); module.exports = function (object, iterator, thisArg) { var key, length; if (!object) { return; } if (isArray(object) || hasOwn.call(object, 'length')) { for (key = 0, length = object.length; key < length; key++) { if (iterator.call(thisArg, object[key], key, object) === false) { break; } } return; } /*jshint forin: false */ for (key in object) { if (hasOwn.call(object, key)) { if (iterator.call(thisArg, object[key], key, object) === false) { break; } } } }; },{"./isArray":11}],6:[function(require,module,exports){ 'use strict'; var REGEX = /[|\\{}()[\]^$+*?.]/g; // From https://github.com/sindresorhus/escape-string-regexp/blob/master/index.js module.exports = function (string) { if (typeof string !== 'string') { throw new TypeError('Expected a string'); } return string.replace(REGEX, '\\$&'); }; },{}],7:[function(require,module,exports){ /* * Microdash - Tiny utilities for Node and the browser * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/microdash * * Released under the MIT license * https://github.com/asmblah/microdash/raw/master/MIT-LICENSE.txt */ 'use strict'; var each = require('./each'), forOwn = require('./forOwn'); module.exports = function (object) { var sources = [].slice.call(arguments, 1); each(sources, function (source) { forOwn(source, function (value, key) { object[key] = value; }); }); return object; }; },{"./each":5,"./forOwn":9}],8:[function(require,module,exports){ /* * Microdash - Tiny utilities for Node and the browser * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/microdash * * Released under the MIT license * https://github.com/asmblah/microdash/raw/master/MIT-LICENSE.txt */ 'use strict'; var each = require('./each'); module.exports = function (collection, iteratee, thisArg) { var result = []; each(collection, function (value, key) { if (iteratee.call(thisArg, value, key, collection)) { result.push(value); } }); return result; }; },{"./each":5}],9:[function(require,module,exports){ /* * Microdash - Tiny utilities for Node and the browser * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/microdash * * Released under the MIT license * https://github.com/asmblah/microdash/raw/master/MIT-LICENSE.txt */ 'use strict'; var hasOwn = {}.hasOwnProperty; module.exports = function (object, iterator, thisArg) { var key; /*jshint forin: false */ for (key in object) { if (hasOwn.call(object, key)) { if (iterator.call(thisArg, object[key], key, object) === false) { break; } } } }; },{}],10:[function(require,module,exports){ /* * Microdash - Tiny utilities for Node and the browser * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/microdash * * Released under the MIT license * https://github.com/asmblah/microdash/raw/master/MIT-LICENSE.txt */ 'use strict'; var REGEX = /\[object ([^\]]+)\]/; module.exports = function (object) { return {}.toString.call(object).match(REGEX)[1]; }; },{}],11:[function(require,module,exports){ /* * Microdash - Tiny utilities for Node and the browser * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/microdash * * Released under the MIT license * https://github.com/asmblah/microdash/raw/master/MIT-LICENSE.txt */ 'use strict'; var getType = require('./getType'); module.exports = function (object) { return getType(object) === 'Array'; }; },{"./getType":10}],12:[function(require,module,exports){ /* * Microdash - Tiny utilities for Node and the browser * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/microdash * * Released under the MIT license * https://github.com/asmblah/microdash/raw/master/MIT-LICENSE.txt */ 'use strict'; var getType = require('./getType'); module.exports = function (object) { return getType(object) === 'Boolean'; }; },{"./getType":10}],13:[function(require,module,exports){ /* * Microdash - Tiny utilities for Node and the browser * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/microdash * * Released under the MIT license * https://github.com/asmblah/microdash/raw/master/MIT-LICENSE.txt */ 'use strict'; var getType = require('./getType'); module.exports = function (object) { return getType(object) === 'Function'; }; },{"./getType":10}],14:[function(require,module,exports){ /* * Microdash - Tiny utilities for Node and the browser * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/microdash * * Released under the MIT license * https://github.com/asmblah/microdash/raw/master/MIT-LICENSE.txt */ 'use strict'; var getType = require('./getType'); module.exports = function (object) { return getType(object) === 'Number'; }; },{"./getType":10}],15:[function(require,module,exports){ /* * Microdash - Tiny utilities for Node and the browser * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/microdash * * Released under the MIT license * https://github.com/asmblah/microdash/raw/master/MIT-LICENSE.txt */ 'use strict'; var getType = require('./getType'); module.exports = function (object) { return getType(object) === 'Object'; }; },{"./getType":10}],16:[function(require,module,exports){ /* * Microdash - Tiny utilities for Node and the browser * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/microdash * * Released under the MIT license * https://github.com/asmblah/microdash/raw/master/MIT-LICENSE.txt */ 'use strict'; var getType = require('./getType'); module.exports = function (object) { return getType(object) === 'String'; }; },{"./getType":10}],17:[function(require,module,exports){ /* * Microdash - Tiny utilities for Node and the browser * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/microdash * * Released under the MIT license * https://github.com/asmblah/microdash/raw/master/MIT-LICENSE.txt */ 'use strict'; var each = require('./each'); module.exports = function (collection, iteratee, thisArg) { var result = []; each(collection, function (value, key) { result[key] = iteratee.call(thisArg, value, key, collection); }); return result; }; },{"./each":5}],18:[function(require,module,exports){ /* * Dynamic - Declarative DOM behaviour * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/dynamic * * Released under the MIT license * https://github.com/asmblah/dynamic/raw/master/MIT-LICENSE.txt */ 'use strict'; function ToggleBehaviour() { } ToggleBehaviour.prototype.handle = function ($element, options) { var $target = options.select('toggle'); $target.toggleClass('hide'); }; module.exports = ToggleBehaviour; },{}],19:[function(require,module,exports){ /* * Dynamic - Declarative DOM behaviour * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/dynamic * * Released under the MIT license * https://github.com/asmblah/dynamic/raw/master/MIT-LICENSE.txt */ 'use strict'; var _ = require('microdash'); function Dynamic(dataAttributeOptionSetFactory, objectOptionSetFactory, $, $context) { this.$ = $; this.behaviours = {}; this.$context = $context; this.dataAttributeOptionSetFactory = dataAttributeOptionSetFactory; this.objectOptionSetFactory = objectOptionSetFactory; } _.extend(Dynamic.prototype, { addBehaviour: function (name, handler) { var dynamic = this; dynamic.behaviours[name] = handler; return dynamic; }, applyTo: function ($container) { var dynamic = this, $ = dynamic.$; _.each(dynamic.behaviours, function (handler, behaviourName) { $container.find('[data-dyn-' + behaviourName + '-on]').each(function () { var $element = $(this), onEvent = $element.data('dyn-' + behaviourName + '-on'), options = dynamic.dataAttributeOptionSetFactory.create( behaviourName, $element ); $element.on(onEvent, function (event) { handler($element, options, dynamic.$context, $, event); }); $element.trigger('init'); }); }); dynamic.$context.find('script[type="text/x-dyn-json"]').each(function () { var json = $(this).html(), config = JSON.parse(json); _.forOwn(config, function (elementConfig, selector) { function handleConfig(elementConfig) { $container.find(selector).each(function () { var $element = $(this), onEvent = elementConfig.on, options = dynamic.objectOptionSetFactory.create( elementConfig.behaviour, $element, elementConfig ), handler = dynamic.behaviours[elementConfig.behaviour]; if (!handler) { throw new Error( 'No behaviour called "' + elementConfig.behaviour + '" is defined' ); } $element.on(onEvent, function (event) { handler($element, options, dynamic.$context, $, event); }); $element.trigger('init'); }); } if (_.isArray(elementConfig)) { _.each(elementConfig, handleConfig); } else { handleConfig(elementConfig); } }); }); return dynamic; }, use: function (plugin) { var dynamic = this; plugin(dynamic); return dynamic; } }); module.exports = Dynamic; },{"microdash":4}],20:[function(require,module,exports){ /* * Dynamic - Declarative DOM behaviour * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/dynamic * * Released under the MIT license * https://github.com/asmblah/dynamic/raw/master/MIT-LICENSE.txt */ 'use strict'; function DataAttributeOptionReader() { } DataAttributeOptionReader.prototype.get = function ($element, name, behaviourName) { if (name !== behaviourName) { // Namespace additional behaviour options, // so .get('extra') fetches data-dyn-<behav>-extra name = behaviourName + '-' + name; } return $element.data('dyn-' + name); }; module.exports = DataAttributeOptionReader; },{}],21:[function(require,module,exports){ /* * Dynamic - Declarative DOM behaviour * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/dynamic * * Released under the MIT license * https://github.com/asmblah/dynamic/raw/master/MIT-LICENSE.txt */ 'use strict'; function ObjectOptionReader() { } ObjectOptionReader.prototype.get = function ($element, name, behaviourName, elementConfig) { return elementConfig[name]; }; module.exports = ObjectOptionReader; },{}],22:[function(require,module,exports){ /* * Dynamic - Declarative DOM behaviour * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/dynamic * * Released under the MIT license * https://github.com/asmblah/dynamic/raw/master/MIT-LICENSE.txt */ 'use strict'; var _ = require('microdash'), undef; function OptionReader(optionReader, expressionContext, expressionEvaluator) { this.expressionContext = expressionContext; this.expressionEvaluator = expressionEvaluator; this.optionReader = optionReader; } OptionReader.prototype.get = function ($element, name, behaviourName, defaultValue, elementConfig) { var reader = this, expressionContext, value = reader.optionReader.get($element, name, behaviourName, elementConfig), valueExpression, valueExpressionAST; if (value === undef) { valueExpression = reader.optionReader.get($element, name + '-expr', behaviourName, elementConfig); if (valueExpression === undef) { if (defaultValue !== undef) { return defaultValue; } throw new Error('Neither "' + name + '" nor "' + name + '-expr" options were specified'); } expressionContext = _.extend({}, reader.expressionContext, { '$this': $element }); valueExpressionAST = reader.expressionEvaluator.parse(valueExpression); value = reader.expressionEvaluator.eval(valueExpressionAST, expressionContext); } return value; }; module.exports = OptionReader; },{"microdash":4}],23:[function(require,module,exports){ /* * Dynamic - Declarative DOM behaviour * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/dynamic * * Released under the MIT license * https://github.com/asmblah/dynamic/raw/master/MIT-LICENSE.txt */ 'use strict'; var undef; function OptionSet($, optionReader, selectorEngine, behaviourName, $element, options) { this.$ = $; this.behaviourName = behaviourName; this.$element = $element; this.optionReader = optionReader; this.options = options; this.selectorEngine = selectorEngine; } OptionSet.prototype.get = function (name, defaultValue) { var optionSet = this; return optionSet.optionReader.get( optionSet.$element, name, optionSet.behaviourName, defaultValue, optionSet.options ); }; OptionSet.prototype.select = function (name, $defaultCollection) { var optionSet = this, selector = optionSet.optionReader.get( optionSet.$element, name, optionSet.behaviourName, $defaultCollection ? null : undef, optionSet.options ); // Option is not specified, return the default if (selector === null) { return $defaultCollection; } // Option was an expression that has returned a collection, no selector to process if (selector instanceof optionSet.$) { return selector; } return optionSet.selectorEngine.select(optionSet.$element, selector); }; module.exports = OptionSet; },{}],24:[function(require,module,exports){ /* * Dynamic - Declarative DOM behaviour * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/dynamic * * Released under the MIT license * https://github.com/asmblah/dynamic/raw/master/MIT-LICENSE.txt */ 'use strict'; function OptionSetFactory($, OptionSet, optionReader, selectorEngine) { this.$ = $; this.optionReader = optionReader; this.OptionSet = OptionSet; this.selectorEngine = selectorEngine; } OptionSetFactory.prototype.create = function (behaviourName, $element, elementConfig) { var factory = this; return new factory.OptionSet( factory.$, factory.optionReader, factory.selectorEngine, behaviourName, $element, elementConfig || {} ); }; module.exports = OptionSetFactory; },{}],25:[function(require,module,exports){ /* * Dynamic - Declarative DOM behaviour * Copyright (c) Dan Phillimore (asmblah) * https://github.com/asmblah/dynamic * * Released under the MIT license * https://github.com/asmblah/dynamic/raw/master/MIT-LICENSE.txt */ 'use strict'; var _ = require('microdash'); function SelectorEngine($context) { this.$context = $context; } SelectorEngine.prototype.select = function ($element, selector) { var engine = this, functionArgs, functionName, match; // Selector starts with an element-relative combinator if (/^\s*[+~>]/.test(selector)) { return $element.find(selector); } // Selector starts with a function match = selector.match(/^\s*@([a-z0-9_-]+)\(([^\)]*)\)/i); if (match) { // Strip function off the selector to leave a (hopefully) valid selector selector = selector.substr(match[0].length).replace(/^\s+|\s+$/, ''); functionName = match[1]; functionArgs = match[2].split(/\s*,\s*/); if (!_.isFunction($element[functionName])) { throw new Error('Unsupported selector function "' + match[1] + '"'); } // Call the jQuery method and use its result as the base $element = $element[functionName].apply($element, functionArgs); // If a selector is specified then search relative to the element, // otherwise just return the element return selector !== '' ? $element.find(selector) : $element; } return engine.$context.find(selector); }; module.exports = SelectorEngine; },{"microdash":4}]},{},[1])(1) });