<commit_before>const $ = require('jquery');

export default function( msg ) {
    $('.message-panel .message-content').html( msg );
    var $panel = $('.message-panel');
    var $textbox = $('#textbox');
    $panel.removeClass('hidden');
    let stickyWatch = setInterval(function(){
        if ( $textbox.offset().top < 0 ) {
            $panel.css('margin-left', $panel.css('margin-left') );
            $panel.addClass('stuck');
        } else {
            $panel.removeClass('stuck');
        }
    },50);

    $('.close-message-panel').click(function(){
        oT.message.close();
    });

    function close() {
        $('.message-panel').addClass('hidden');
        clearInterval(stickyWatch);
    }
}

<commit_msg>Fix message panel close button bug<commit_after>const $ = require('jquery');

export default function( msg ) {
    $('.message-panel .message-content').html( msg );
    var $panel = $('.message-panel');
    var $textbox = $('#textbox');
    $panel.removeClass('hidden');
    let stickyWatch = setInterval(function(){
        if ( $textbox.offset().top < 0 ) {
            $panel.css('margin-left', $panel.css('margin-left') );
            $panel.addClass('stuck');
        } else {
            $panel.removeClass('stuck');
        }
    },50);

    $('.close-message-panel').click(function(){
        close();
    });

    function close() {
        $('.message-panel').addClass('hidden');
        clearInterval(stickyWatch);
    }
}

<|endoftext|>


<commit_before>import React from 'react'

const Header = (props) => {
  return (

 { props.actions.prevDate() }}>prev

        {props.store.date}
        <button onClick={() => { props.actions.gotoToday() }}>today</button>

 { props.actions.nextDate() }}>next

  )
}

export default Header
<commit_msg>Change html tag from p to tag<commit_after>import React from 'react'

const Header = (props) => {
  return (

      <button onClick={() => { props.actions.prevDate() }}>prev</button>

        {props.store.date}
        <button onClick={() => { props.actions.gotoToday() }}>today</button>

      <button onClick={() => { props.actions.nextDate() }}>next</button>

  )
}

export default Header
<|endoftext|>


<commit_before>var config = require('./config');
var ERROR = config.ERROR;
var WARNING = config.WARNING;
var IGNORE = config.IGNORE;

/**
 * ### Ruleset: Best Practices
 *
 * These are rules designed to prevent you from making mistakes.
 * They either prescribe a better way of doing something or
 * help you avoid footguns.
 *
 * @see http://eslint.org/docs/rules/#best-practices
 */
module.exports = {
  rules: {
    // Enforces getter/setter pairs in objects
    'accessor-pairs': IGNORE,
    // treat var statements as if they were block scoped
    'block-scoped-var': ERROR,
    // specify the maximum cyclomatic complexity allowed in a program
    complexity: [ERROR, 11],
    // require return statements to either always or never specify values
    'consistent-return': ERROR,
    // specify curly brace conventions for all control statements
    curly: [ERROR, 'multi-line'],
    // require default case in switch statements
    'default-case': ERROR,
    // encourages use of dot notation whenever possible
    'dot-notation': [ERROR, {
      allowKeywords: true
    }],
    // enforces consistent newlines before or after dots
    'dot-location': IGNORE,
    // require the use of === and !==
    eqeqeq: ERROR,
    // make sure for-in loops have an if statement
    'guard-for-in': ERROR,
    // disallow the use of alert, confirm, and prompt
    'no-alert': WARNING,
    // disallow use of arguments.caller or arguments.callee
    'no-caller': ERROR,
    // disallow division operators explicitly at beginning of regular expression
    'no-div-regex': IGNORE,
    // disallow else after a return in an if
    'no-else-return': ERROR,
    // disallow use of labels for anything other then loops and switches
    'no-empty-label': ERROR,
    // disallow comparisons to null without a type-checking operator
    'no-eq-null': IGNORE,
    // disallow use of eval()
    'no-eval': ERROR,
    // disallow adding to native types
    'no-extend-native': ERROR,
    // disallow unnecessary function binding
    'no-extra-bind': ERROR,
    // disallow fallthrough of case statements
    'no-fallthrough': ERROR,
    // disallow the use of leading or trailing decimal points in numeric literals
    'no-floating-decimal': ERROR,
    // disallow the type conversions with shorter notations
    'no-implicit-coercion': IGNORE,
    // disallow use of eval()-like methods
    'no-implied-eval': ERROR,
    // disallow this keywords outside of classes or class-like objects
    'no-invalid-this': 0,
    // disallow usage of __iterator__ property
    'no-iterator': ERROR,
    // disallow use of labeled statements
    'no-labels': ERROR,
    // disallow unnecessary nested blocks
    'no-lone-blocks': ERROR,
    // disallow creation of functions within loops
    'no-loop-func': ERROR,
    // disallow use of multiple spaces
    'no-multi-spaces': ERROR,
    // disallow use of multiline strings
    'no-multi-str': ERROR,
    // disallow reassignments of native objects
    'no-native-reassign': ERROR,
    // disallow use of new operator when not part of the assignment or comparison
    'no-new': ERROR,
    // disallow use of new operator for Function object
    'no-new-func': ERROR,
    // disallows creating new instances of String,Number, and Boolean
    'no-new-wrappers': ERROR,
    // disallow use of (old style) octal literals
    'no-octal': ERROR,
    // disallow use of octal escape sequences in string literals, such as
    // var foo = 'Copyright \251';
    'no-octal-escape': ERROR,
    // disallow reassignment of function parameters
    /**
     * @differ - Breaks `module.exports = function(opts, fn){}` convention.
     */
    'no-param-reassign': IGNORE,
    // disallow use of process.env
    'no-process-env': IGNORE,
    // disallow usage of __proto__ property
    'no-proto': ERROR,
    // disallow declaring the same variable more then once
    'no-redeclare': ERROR,
    // disallow use of assignment in return statement
    'no-return-assign': ERROR,
    // disallow use of `javascript:` urls.
    'no-script-url': ERROR,
    // disallow comparisons where both sides are exactly the same
    'no-self-compare': ERROR,
    // disallow use of comma operator
    'no-sequences': ERROR,
    // restrict what can be thrown as an exception
    'no-throw-literal': ERROR,
    // disallow usage of expressions in statement position
    'no-unused-expressions': ERROR,
    // disallow unnecessary .call() and .apply()
    'no-useless-call': IGNORE,
    // disallow use of void operator
    'no-void': IGNORE,
    // disallow usage of configurable warning terms in comments: e.g. todo
    'no-warning-comments': [IGNORE, {
      terms: ['todo', 'note'],
      location: 'start'
    }],
    // disallow use of the with statement
    'no-with': ERROR,
    // require use of the second argument for parseInt()
    radix: ERROR,
    // requires to declare all vars on top of their containing scope
    'vars-on-top': ERROR,
    // require immediate function invocation to be wrapped in parentheses
    'wrap-iife': [ERROR, 'any'],
    // require or disallow Yoda conditions
    yoda: ERROR
  }
};
<commit_msg>:shirt: IGNORE vars-on-top<commit_after>var config = require('./config');
var ERROR = config.ERROR;
var WARNING = config.WARNING;
var IGNORE = config.IGNORE;

/**
 * ### Ruleset: Best Practices
 *
 * These are rules designed to prevent you from making mistakes.
 * They either prescribe a better way of doing something or
 * help you avoid footguns.
 *
 * @see http://eslint.org/docs/rules/#best-practices
 */
module.exports = {
  rules: {
    // Enforces getter/setter pairs in objects
    'accessor-pairs': IGNORE,
    // treat var statements as if they were block scoped
    'block-scoped-var': ERROR,
    // specify the maximum cyclomatic complexity allowed in a program
    complexity: [ERROR, 11],
    // require return statements to either always or never specify values
    'consistent-return': ERROR,
    // specify curly brace conventions for all control statements
    curly: [ERROR, 'multi-line'],
    // require default case in switch statements
    'default-case': ERROR,
    // encourages use of dot notation whenever possible
    'dot-notation': [ERROR, {
      allowKeywords: true
    }],
    // enforces consistent newlines before or after dots
    'dot-location': IGNORE,
    // require the use of === and !==
    eqeqeq: ERROR,
    // make sure for-in loops have an if statement
    'guard-for-in': ERROR,
    // disallow the use of alert, confirm, and prompt
    'no-alert': WARNING,
    // disallow use of arguments.caller or arguments.callee
    'no-caller': ERROR,
    // disallow division operators explicitly at beginning of regular expression
    'no-div-regex': IGNORE,
    // disallow else after a return in an if
    'no-else-return': ERROR,
    // disallow use of labels for anything other then loops and switches
    'no-empty-label': ERROR,
    // disallow comparisons to null without a type-checking operator
    'no-eq-null': IGNORE,
    // disallow use of eval()
    'no-eval': ERROR,
    // disallow adding to native types
    'no-extend-native': ERROR,
    // disallow unnecessary function binding
    'no-extra-bind': ERROR,
    // disallow fallthrough of case statements
    'no-fallthrough': ERROR,
    // disallow the use of leading or trailing decimal points in numeric literals
    'no-floating-decimal': ERROR,
    // disallow the type conversions with shorter notations
    'no-implicit-coercion': IGNORE,
    // disallow use of eval()-like methods
    'no-implied-eval': ERROR,
    // disallow this keywords outside of classes or class-like objects
    'no-invalid-this': 0,
    // disallow usage of __iterator__ property
    'no-iterator': ERROR,
    // disallow use of labeled statements
    'no-labels': ERROR,
    // disallow unnecessary nested blocks
    'no-lone-blocks': ERROR,
    // disallow creation of functions within loops
    'no-loop-func': ERROR,
    // disallow use of multiple spaces
    'no-multi-spaces': ERROR,
    // disallow use of multiline strings
    'no-multi-str': ERROR,
    // disallow reassignments of native objects
    'no-native-reassign': ERROR,
    // disallow use of new operator when not part of the assignment or comparison
    'no-new': ERROR,
    // disallow use of new operator for Function object
    'no-new-func': ERROR,
    // disallows creating new instances of String,Number, and Boolean
    'no-new-wrappers': ERROR,
    // disallow use of (old style) octal literals
    'no-octal': ERROR,
    // disallow use of octal escape sequences in string literals, such as
    // var foo = 'Copyright \251';
    'no-octal-escape': ERROR,
    // disallow reassignment of function parameters
    /**
     * @differ - Breaks `module.exports = function(opts, fn){}` convention.
     */
    'no-param-reassign': IGNORE,
    // disallow use of process.env
    'no-process-env': IGNORE,
    // disallow usage of __proto__ property
    'no-proto': ERROR,
    // disallow declaring the same variable more then once
    'no-redeclare': ERROR,
    // disallow use of assignment in return statement
    'no-return-assign': ERROR,
    // disallow use of `javascript:` urls.
    'no-script-url': ERROR,
    // disallow comparisons where both sides are exactly the same
    'no-self-compare': ERROR,
    // disallow use of comma operator
    'no-sequences': ERROR,
    // restrict what can be thrown as an exception
    'no-throw-literal': ERROR,
    // disallow usage of expressions in statement position
    'no-unused-expressions': ERROR,
    // disallow unnecessary .call() and .apply()
    'no-useless-call': IGNORE,
    // disallow use of void operator
    'no-void': IGNORE,
    // disallow usage of configurable warning terms in comments: e.g. todo
    'no-warning-comments': [IGNORE, {
      terms: ['todo', 'note'],
      location: 'start'
    }],
    // disallow use of the with statement
    'no-with': ERROR,
    // require use of the second argument for parseInt()
    radix: ERROR,
    // requires to declare all vars on top of their containing scope
    /**
     * @differ - YOU BE YOU, DEVELOPER.
     */
    'vars-on-top': IGNORE,
    // require immediate function invocation to be wrapped in parentheses
    'wrap-iife': [ERROR, 'any'],
    // require or disallow Yoda conditions
    yoda: ERROR
  }
};
<|endoftext|>


<commit_before>/**
 * @class CM_View_Abstract
 * @extends Backbone.View
 */
var CM_View_Abstract = Backbone.View.extend({
	_class: 'CM_View_Abstract',

	_children: [],

	initialize: function() {
		this._children = [];

		if (this.getParent()) {
			this.getParent().registerChild(this);
		}

		if (this.actions) {
			this._bindActions(this.actions);
		}
		if (this.streams) {
			this._bindStreams(this.streams);
		}
		if (this.childrenEvents) {
			this._bindChildrenEvents(this.childrenEvents);
		}
		this.on('all', function(eventName, data) {
			cm.viewEvents.trigger(this, eventName, data);
		});
	},

	ready: function() {
	},

	_ready: function() {
		this.ready();
		_.each(this.getChildren(), function(child) {
			child._ready();
		});
	},

	/**
	 * @param {CM_View_Abstract} child
	 */
	registerChild: function(child) {
		this._children.push(child);
	},

	/**
	 * @return CM_View_Abstract[]
	 */
	getChildren: function() {
		return this._children;
	},

	/**
	 * @param {String} className
	 * @return CM_View_Abstract|null
	 */
	findChild: function(className) {
		return _.find(this.getChildren(), function(child) {
			return _.contains(child.getClasses(), className);
		}) || null;
	},

	/**
	 * @return CM_View_Abstract|null
	 */
	getParent: function() {
		if (this.options.parent) {
			return this.options.parent;
		}
		return null;
	},

	/**
	 * @param {String} className
	 * @return CM_View_Abstract|null
	 */
	findParent: function(className) {
		var parent = this.getParent();
		if (!parent) {
			return null;
		}
		if (_.contains(parent.getClasses(), className)) {
			return parent;
		}
		return parent.findParent(className);
	},

	/**
	 * @return String
	 */
	getAutoId: function() {
		return this.el.id;
	},

	/**
	 * @return Object
	 */
	getParams: function() {
		return this.options.params || {};
	},

	/**
	 * @return string[]
	 */
	getClasses: function() {
		var classes = [this.getClass()];
		if ('CM_View_Abstract' != this.getClass()) {
			classes = classes.concat(this.constructor.__super__.getClasses());
		}
		return classes;
	},

	/**
	 * @return String
	 */
	getClass: function() {
		return this._class;
	},

	/**
	 * @param {Boolean} skipDomRemoval OPTIONAL
	 */
	remove: function(skipDomRemoval) {
		this.trigger("destruct");

		if (this.getParent()) {
			var siblings = this.getParent().getChildren();
			for (var i = 0, sibling; sibling = siblings[i]; i++) {
				if (sibling.getAutoId() == this.getAutoId()) {
					siblings.splice(i, 1);
				}
			}
		}

		_.each(_.clone(this.getChildren()), function(child) {
			child.remove();
		});

		delete cm.views[this.getAutoId()];

		if (!skipDomRemoval) {
			this.$().remove();
		}
	},

	disable: function() {
		this.$().disable();
	},

	enable: function() {
		this.$().enable();
	},

	/**
	 * @param {String} functionName
	 * @param {Object|Null} [params]
	 * @param {Object|Null} [callbacks]
	 * @return jqXHR
	 */
	ajax: function(functionName, params, callbacks) {
		callbacks = callbacks || {};
		params = params || {};
		var handler = this;
		var xhr = cm.ajax('ajax', {view:this._getArray(), method:functionName, params:params}, {
			success: function(response) {
				if (response.exec) {
					new Function(response.exec).call(handler);
				}
				if (callbacks.success) {
					return callbacks.success.call(handler, response.data);
				}
			},
			error: function(msg, type, isPublic) {
				if (callbacks.error) {
					return callbacks.error.call(handler, msg, type, isPublic);
				}
			},
			complete: function() {
				if (callbacks.complete) {
					return callbacks.complete.call(handler);
				}
			}
		});
		this.on('destruct', function() {
			xhr.abort();
		});
		return xhr;
	},

	/**
	 * @param {String} functionName
	 * @param {Object|Null} [params]
	 * @param {Object|Null} [callbacks]
	 * @return jqXHR
	 */
	ajaxModal: function(functionName, params, callbacks) {
		callbacks = callbacks || {};
		var handler = this;
		var callbackComplete = callbacks.complete;
		callbacks.complete = function() {
			handler.enable();
			if (callbackComplete) {
				return callbackComplete(handler);
			}
		};
		this.disable();
		return this.ajax(functionName, params, callbacks);
	},

	/**
	 * @param {String} className
	 * @param {Object|Null} [params]
	 * @param {Object|Null} [options]
	 * @return jqXHR
	 */
	loadComponent: function(className, params, options) {
		options = options || {};
		params = params || {};
		params.className = className;
		var successPopOut = options.successPopOut || function() {};
		var successPre = options.success ? options.success :  function() { this.popOut(); };
		var successPost = options.success ? function() {} : function() { successPopOut.call(this); };
		options.success = function(autoId) {
			var handlerNew = cm.views[autoId];
			successPre.call(handlerNew);
			handlerNew._ready();
			successPost.call(handlerNew);
		};
		return this.ajaxModal('loadComponent', params, options);
	},

	/**
	 * @param {String} path
	 * @param {Object|Null} callbacks
	 * @return jqXHR
	 */
	loadPage: function (path, callbacks) {
		callbacks = callbacks || {};
		var success = callbacks.success || function() {};

		return this.ajaxModal('loadPage', {path: path}, {
			success: function(response) {
				cm.window.appendHidden(response.html);
				new Function(response.js).call(this);
				var page = cm.views[response.autoId];
				success.call(page, response.title, response.url, response.menuEntryHashes, response.layoutClass);
				page._ready();
			},
			error: callbacks.error,
			complete: callbacks.complete
		});
	},

	/**
	 * @param {int} actionVerb
	 * @param {int} modelType
	 * @param {Function} callback fn(CM_Action_Abstract action, CM_Model_Abstract model, array data)
	 */
	bindAction: function(actionVerb, modelType, callback) {
		cm.action.bind(actionVerb, modelType, callback, this);
		this.on('destruct', function() {
			cm.action.unbind(actionVerb, modelType, callback, this);
		});
	},

	/**
	 * @param {String} event
	 * @param {Function} callback fn(array data)
	 */
	bindStream: function(event, callback) {
		var namespace = this.getClass() + ':' + event;
		cm.stream.bind(namespace, callback, this);
		this.on('destruct', function() {
			cm.stream.unbind(namespace, callback, this);
		});
	},

	/**
	 * @param {String} viewClassName
	 * @param {String} event
	 * @param {Function} callback fn(CM_View_Abstract view, array data)
	 */
	bindChildrenEvent: function(viewClassName, event, callback) {
		cm.viewEvents.bind(this, viewClassName, event, callback, this);
		this.on('destruct', function() {
			cm.viewEvents.unbind(this, viewClassName, event, callback, this);
		});
	},

	/**
	 * @param {String|Function} callback
	 * @param {int} interval
	 * @return {int}
	 */
	setInterval: function(callback, interval) {
		var id = window.setInterval(callback, interval);
		this.on('destruct', function() {
			window.clearInterval(id);
		});
		return id;
	},

	/**
	 * @param {String|Function} callback
	 * @param {int} timeout
	 * @return {int}
	 */
	setTimeout: function(callback, timeout) {
		var id = window.setTimeout(callback, timeout);
		this.on('destruct', function() {
			window.clearTimeout(id);
		});
		return id;
	},

	/**
	 * @param {Object} actions
	 */
	_bindActions: function(actions) {
		_.each(actions, function(callback, key) {
			var match = key.match(/^(\S+)\s+(.+)$/);
			var modelType = cm.model.types[match[1]];
			var actionNames = match[2].split(/\s*,\s*/);
			_.each(actionNames, function(actionName) {
				var actionVerb = cm.action.verbs[actionName];
				this.bindAction(actionVerb, modelType, callback);
			}, this);
		}, this);
	},

	/**
	 * @param {Object} streams
	 */
	_bindStreams: function(streams) {
		_.each(streams, function(callback, key) {
			this.bindStream(key, callback);
		}, this);
	},

	/**
	 * @param {Object} events
	 */
	_bindChildrenEvents: function(events) {
		_.each(events, function (callback, key) {
			var match = key.match(/^(\S+)\s+(.+)$/);
			var viewName = match[1];
			var eventNames = match[2].split(/\s*,\s*/);
			_.each(eventNames, function(eventName) {
				this.bindChildrenEvent(viewName, eventName, callback);
			}, this);
		});
	},

	/**
	 * @return Object
	 */
	_getArray: function() {
		return {
			className: this.getClass(),
			id: this.getAutoId(),
			params: this.getParams(),
			parentId: this.getParent() ? this.getParent().getAutoId() : null
		};
	}
});<commit_msg>Extend events<commit_after>/**
 * @class CM_View_Abstract
 * @extends Backbone.View
 */
var CM_View_Abstract = Backbone.View.extend({
	_class: 'CM_View_Abstract',

	_children: [],

	initialize: function() {
		this._children = [];

		if (this.getParent()) {
			this.getParent().registerChild(this);
		}
		this.events = this.collectEvents();

		if (this.actions) {
			this._bindActions(this.actions);
		}
		if (this.streams) {
			this._bindStreams(this.streams);
		}
		if (this.childrenEvents) {
			this._bindChildrenEvents(this.childrenEvents);
		}
		this.on('all', function(eventName, data) {
			cm.viewEvents.trigger(this, eventName, data);
		});
	},

	collectEvents: function() {
		var eventsObjects = [], currentConstructor = this.constructor, currentProto = currentConstructor.prototype;

		do {
			if (currentProto.hasOwnProperty('events')) {
				eventsObjects.unshift(currentProto.events);
			}
		} while (currentConstructor = ( currentProto = currentConstructor.__super__ ) && currentProto.constructor);
		eventsObjects.unshift({});
		return _.extend.apply(_, eventsObjects);
	},

	ready: function() {
	},

	_ready: function() {
		this.ready();
		_.each(this.getChildren(), function(child) {
			child._ready();
		});
	},

	/**
	 * @param {CM_View_Abstract} child
	 */
	registerChild: function(child) {
		this._children.push(child);
	},

	/**
	 * @return CM_View_Abstract[]
	 */
	getChildren: function() {
		return this._children;
	},

	/**
	 * @param {String} className
	 * @return CM_View_Abstract|null
	 */
	findChild: function(className) {
		return _.find(this.getChildren(), function(child) {
			return _.contains(child.getClasses(), className);
		}) || null;
	},

	/**
	 * @return CM_View_Abstract|null
	 */
	getParent: function() {
		if (this.options.parent) {
			return this.options.parent;
		}
		return null;
	},

	/**
	 * @param {String} className
	 * @return CM_View_Abstract|null
	 */
	findParent: function(className) {
		var parent = this.getParent();
		if (!parent) {
			return null;
		}
		if (_.contains(parent.getClasses(), className)) {
			return parent;
		}
		return parent.findParent(className);
	},

	/**
	 * @return String
	 */
	getAutoId: function() {
		return this.el.id;
	},

	/**
	 * @return Object
	 */
	getParams: function() {
		return this.options.params || {};
	},

	/**
	 * @return string[]
	 */
	getClasses: function() {
		var classes = [this.getClass()];
		if ('CM_View_Abstract' != this.getClass()) {
			classes = classes.concat(this.constructor.__super__.getClasses());
		}
		return classes;
	},

	/**
	 * @return String
	 */
	getClass: function() {
		return this._class;
	},

	/**
	 * @param {Boolean} skipDomRemoval OPTIONAL
	 */
	remove: function(skipDomRemoval) {
		this.trigger("destruct");

		if (this.getParent()) {
			var siblings = this.getParent().getChildren();
			for (var i = 0, sibling; sibling = siblings[i]; i++) {
				if (sibling.getAutoId() == this.getAutoId()) {
					siblings.splice(i, 1);
				}
			}
		}

		_.each(_.clone(this.getChildren()), function(child) {
			child.remove();
		});

		delete cm.views[this.getAutoId()];

		if (!skipDomRemoval) {
			this.$().remove();
		}
	},

	disable: function() {
		this.$().disable();
	},

	enable: function() {
		this.$().enable();
	},

	/**
	 * @param {String} functionName
	 * @param {Object|Null} [params]
	 * @param {Object|Null} [callbacks]
	 * @return jqXHR
	 */
	ajax: function(functionName, params, callbacks) {
		callbacks = callbacks || {};
		params = params || {};
		var handler = this;
		var xhr = cm.ajax('ajax', {view: this._getArray(), method: functionName, params: params}, {
			success: function(response) {
				if (response.exec) {
					new Function(response.exec).call(handler);
				}
				if (callbacks.success) {
					return callbacks.success.call(handler, response.data);
				}
			},
			error: function(msg, type, isPublic) {
				if (callbacks.error) {
					return callbacks.error.call(handler, msg, type, isPublic);
				}
			},
			complete: function() {
				if (callbacks.complete) {
					return callbacks.complete.call(handler);
				}
			}
		});
		this.on('destruct', function() {
			xhr.abort();
		});
		return xhr;
	},

	/**
	 * @param {String} functionName
	 * @param {Object|Null} [params]
	 * @param {Object|Null} [callbacks]
	 * @return jqXHR
	 */
	ajaxModal: function(functionName, params, callbacks) {
		callbacks = callbacks || {};
		var handler = this;
		var callbackComplete = callbacks.complete;
		callbacks.complete = function() {
			handler.enable();
			if (callbackComplete) {
				return callbackComplete(handler);
			}
		};
		this.disable();
		return this.ajax(functionName, params, callbacks);
	},

	/**
	 * @param {String} className
	 * @param {Object|Null} [params]
	 * @param {Object|Null} [options]
	 * @return jqXHR
	 */
	loadComponent: function(className, params, options) {
		options = options || {};
		params = params || {};
		params.className = className;
		var successPopOut = options.successPopOut || function() {
		};
		var successPre = options.success ? options.success : function() {
			this.popOut();
		};
		var successPost = options.success ? function() {
		} : function() {
			successPopOut.call(this);
		};
		options.success = function(autoId) {
			var handlerNew = cm.views[autoId];
			successPre.call(handlerNew);
			handlerNew._ready();
			successPost.call(handlerNew);
		};
		return this.ajaxModal('loadComponent', params, options);
	},

	/**
	 * @param {String} path
	 * @param {Object|Null} callbacks
	 * @return jqXHR
	 */
	loadPage: function(path, callbacks) {
		callbacks = callbacks || {};
		var success = callbacks.success || function() {
		};

		return this.ajaxModal('loadPage', {path: path}, {
			success: function(response) {
				cm.window.appendHidden(response.html);
				new Function(response.js).call(this);
				var page = cm.views[response.autoId];
				success.call(page, response.title, response.url, response.menuEntryHashes, response.layoutClass);
				page._ready();
			},
			error: callbacks.error,
			complete: callbacks.complete
		});
	},

	/**
	 * @param {int} actionVerb
	 * @param {int} modelType
	 * @param {Function} callback fn(CM_Action_Abstract action, CM_Model_Abstract model, array data)
	 */
	bindAction: function(actionVerb, modelType, callback) {
		cm.action.bind(actionVerb, modelType, callback, this);
		this.on('destruct', function() {
			cm.action.unbind(actionVerb, modelType, callback, this);
		});
	},

	/**
	 * @param {String} event
	 * @param {Function} callback fn(array data)
	 */
	bindStream: function(event, callback) {
		var namespace = this.getClass() + ':' + event;
		cm.stream.bind(namespace, callback, this);
		this.on('destruct', function() {
			cm.stream.unbind(namespace, callback, this);
		});
	},

	/**
	 * @param {String} viewClassName
	 * @param {String} event
	 * @param {Function} callback fn(CM_View_Abstract view, array data)
	 */
	bindChildrenEvent: function(viewClassName, event, callback) {
		cm.viewEvents.bind(this, viewClassName, event, callback, this);
		this.on('destruct', function() {
			cm.viewEvents.unbind(this, viewClassName, event, callback, this);
		});
	},

	/**
	 * @param {String|Function} callback
	 * @param {int} interval
	 * @return {int}
	 */
	setInterval: function(callback, interval) {
		var id = window.setInterval(callback, interval);
		this.on('destruct', function() {
			window.clearInterval(id);
		});
		return id;
	},

	/**
	 * @param {String|Function} callback
	 * @param {int} timeout
	 * @return {int}
	 */
	setTimeout: function(callback, timeout) {
		var id = window.setTimeout(callback, timeout);
		this.on('destruct', function() {
			window.clearTimeout(id);
		});
		return id;
	},

	/**
	 * @param {Object} actions
	 */
	_bindActions: function(actions) {
		_.each(actions, function(callback, key) {
			var match = key.match(/^(\S+)\s+(.+)$/);
			var modelType = cm.model.types[match[1]];
			var actionNames = match[2].split(/\s*,\s*/);
			_.each(actionNames, function(actionName) {
				var actionVerb = cm.action.verbs[actionName];
				this.bindAction(actionVerb, modelType, callback);
			}, this);
		}, this);
	},

	/**
	 * @param {Object} streams
	 */
	_bindStreams: function(streams) {
		_.each(streams, function(callback, key) {
			this.bindStream(key, callback);
		}, this);
	},

	/**
	 * @param {Object} events
	 */
	_bindChildrenEvents: function(events) {
		_.each(events, function(callback, key) {
			var match = key.match(/^(\S+)\s+(.+)$/);
			var viewName = match[1];
			var eventNames = match[2].split(/\s*,\s*/);
			_.each(eventNames, function(eventName) {
				this.bindChildrenEvent(viewName, eventName, callback);
			}, this);
		}, this);
	},

	/**
	 * @return Object
	 */
	_getArray: function() {
		return {
			className: this.getClass(),
			id: this.getAutoId(),
			params: this.getParams(),
			parentId: this.getParent() ? this.getParent().getAutoId() : null
		};
	}
});<|endoftext|>


<commit_before>'use strict';
// Get page object
var ExamplePage = require('./docs.po').ExamplePage;

// Turn off angular support
browser.ignoreSynchronization = true;

describe('Hierarchy select with search and hierarchy', function () {
  var examplePage;

  beforeEach(function () {
    browser.get('/');
    examplePage = new ExamplePage('example-one');
  });

  it('should open a drop-down and set focus on filter input field on initial click', function () {
    examplePage.openDropDown();

    expect(examplePage.filterInput).toBeActiveElement();
    expect(examplePage.root).toHaveClass('open');
  });

  it('should close drop-down on ESC or TAB key and set focus on drop-down button', function () {
    Promise.all([
      examplePage.openDropDown(),
      examplePage.setFilter(protractor.Key.ESCAPE),
    ])
      .then(function () {
        expect(examplePage.root).not.toHaveClass('open');
        expect(examplePage.dropDownButton).toBeActiveElement();

        return Promise.all([
          examplePage.openDropDown(),

          examplePage.setFilter(protractor.Key.TAB),
        ]);
      })
      .then(function () {
        expect(examplePage.root).not.toHaveClass('open');
        expect(examplePage.dropDownButton).toBeActiveElement();
      });
  });

  it('should set first element in drop-down list active on initial click', function () {
    examplePage.openDropDown();

    expect(examplePage.getListElement(0)).toHaveClass('active');
  });

  it('should navigate through elements on arrow keys up/down', function () {
    examplePage.openDropDown();

    expect(examplePage.getListElement(0)).toHaveClass('active');

    examplePage.setFilter(protractor.Key.ARROW_DOWN)
      .then(function () {
        expect(examplePage.getListElement(0)).not.toHaveClass('active');
        expect(examplePage.getListElement(1)).toHaveClass('active');

        return examplePage.setFilter(protractor.Key.ARROW_UP);
      })
      .then(function () {
        expect(examplePage.getListElement(0)).toHaveClass('active');
        expect(examplePage.getListElement(1)).not.toHaveClass('active');
      });
  });

  it('should select currently active value after pressing enter', function () {
    var selectedValue = '';

    examplePage.openDropDown();

    expect(examplePage.getListElement(0)).toHaveClass('active');

    Promise.all([
      examplePage.setFilter(protractor.Key.ARROW_DOWN),
      examplePage.getListElement(1).getAttribute('data-value'),
    ])
      .then(function (resolved) {
        selectedValue = resolved[1];
        return examplePage.setFilter(protractor.Key.ENTER);
      })
      .then(function () {
        expect(examplePage.getCurrentValue()).toBe(selectedValue);
      });
  });

  it('should have the value of an element with the attribute `data-default-selected` be the default value', function () {
    expect(examplePage.defaultSelected.getAttribute('data-value')).toBe(examplePage.getCurrentValue());
  });
});
<commit_msg>Fix test for `data-default-selected` logic<commit_after>'use strict';
// Get page object
var ExamplePage = require('./docs.po').ExamplePage;

// Turn off angular support
browser.ignoreSynchronization = true;

describe('Hierarchy select with search and hierarchy', function () {
  var examplePage;

  beforeEach(function () {
    browser.get('/');
    examplePage = new ExamplePage('example-one');
  });

  it('should open a drop-down and set focus on filter input field on initial click', function () {
    examplePage.openDropDown();

    expect(examplePage.filterInput).toBeActiveElement();
    expect(examplePage.root).toHaveClass('open');
  });

  it('should close drop-down on ESC or TAB key and set focus on drop-down button', function () {
    Promise.all([
      examplePage.openDropDown(),
      examplePage.setFilter(protractor.Key.ESCAPE),
    ])
      .then(function () {
        expect(examplePage.root).not.toHaveClass('open');
        expect(examplePage.dropDownButton).toBeActiveElement();

        return Promise.all([
          examplePage.openDropDown(),

          examplePage.setFilter(protractor.Key.TAB),
        ]);
      })
      .then(function () {
        expect(examplePage.root).not.toHaveClass('open');
        expect(examplePage.dropDownButton).toBeActiveElement();
      });
  });

  it('should set first element in drop-down list active on initial click', function () {
    examplePage.openDropDown();

    expect(examplePage.getListElement(0)).toHaveClass('active');
  });

  it('should navigate through elements on arrow keys up/down', function () {
    examplePage.openDropDown();

    expect(examplePage.getListElement(0)).toHaveClass('active');

    examplePage.setFilter(protractor.Key.ARROW_DOWN)
      .then(function () {
        expect(examplePage.getListElement(0)).not.toHaveClass('active');
        expect(examplePage.getListElement(1)).toHaveClass('active');

        return examplePage.setFilter(protractor.Key.ARROW_UP);
      })
      .then(function () {
        expect(examplePage.getListElement(0)).toHaveClass('active');
        expect(examplePage.getListElement(1)).not.toHaveClass('active');
      });
  });

  it('should select currently active value after pressing enter', function () {
    var selectedValue = '';

    examplePage.openDropDown();

    expect(examplePage.getListElement(0)).toHaveClass('active');

    Promise.all([
      examplePage.setFilter(protractor.Key.ARROW_DOWN),
      examplePage.getListElement(1).getAttribute('data-value'),
    ])
      .then(function (resolved) {
        selectedValue = resolved[1];
        return examplePage.setFilter(protractor.Key.ENTER);
      })
      .then(function () {
        expect(examplePage.getCurrentValue()).toBe(selectedValue);
      });
  });

  it('should have the value of an element with the attribute `data-default-selected` be the default value', function () {
    examplePage.defaultSelected.isPresent()
      .then(function (isPresent) {
        if (isPresent) {
          expect(examplePage.defaultSelected.getAttribute('data-value')).toBe(examplePage.getCurrentValue());
        }
      });
  });
});
<|endoftext|>


<commit_before>/**
  @module ember-data
*/

var get = Ember.get, fmt = Ember.String.fmt,
    indexOf = Ember.EnumerableUtils.indexOf;

var counter = 0;

import Adapter from "../system/adapter";

/**
  `DS.FixtureAdapter` is an adapter that loads records from memory.
  It's primarily used for development and testing. You can also use
  `DS.FixtureAdapter` while working on the API but are not ready to
  integrate yet. It is a fully functioning adapter. All CRUD methods
  are implemented. You can also implement query logic that a remote
  system would do. It's possible to develop your entire application
  with `DS.FixtureAdapter`.

  For information on how to use the `FixtureAdapter` in your
  application please see the [FixtureAdapter
  guide](/guides/models/the-fixture-adapter/).

  @class FixtureAdapter
  @namespace DS
  @extends DS.Adapter
*/
var FixtureAdapter = Adapter.extend({
  // by default, fixtures are already in normalized form
  serializer: null,

  /**
    If `simulateRemoteResponse` is `true` the `FixtureAdapter` will
    wait a number of milliseconds before resolving promises with the
    fixture values. The wait time can be configured via the `latency`
    property.

    @property simulateRemoteResponse
    @type {Boolean}
    @default true
  */
  simulateRemoteResponse: true,

  /**
    By default the `FixtureAdapter` will simulate a wait of the
    `latency` milliseconds before resolving promises with the fixture
    values. This behavior can be turned off via the
    `simulateRemoteResponse` property.

    @property latency
    @type {Number}
    @default 50
  */
  latency: 50,

  /**
    Implement this method in order to provide data associated with a type

    @method fixturesForType
    @param {Subclass of DS.Model} type
    @return {Array}
  */
  fixturesForType: function(type) {
    if (type.FIXTURES) {
      var fixtures = Ember.A(type.FIXTURES);
      return fixtures.map(function(fixture){
        var fixtureIdType = typeof fixture.id;
        if(fixtureIdType !== "number" && fixtureIdType !== "string"){
          throw new Error(fmt('the id property must be defined as a number or string for fixture %@', [fixture]));
        }
        fixture.id = fixture.id + '';
        return fixture;
      });
    }
    return null;
  },

  /**
    Implement this method in order to query fixtures data

    @method queryFixtures
    @param {Array} fixture
    @param {Object} query
    @param {Subclass of DS.Model} type
    @return {Promise|Array}
  */
  queryFixtures: function(fixtures, query, type) {
    Ember.assert('Not implemented: You must override the DS.FixtureAdapter::queryFixtures method to support querying the fixture store.');
  },

  /**
    @method updateFixtures
    @param {Subclass of DS.Model} type
    @param {Array} fixture
  */
  updateFixtures: function(type, fixture) {
    if(!type.FIXTURES) {
      type.FIXTURES = [];
    }

    var fixtures = type.FIXTURES;

    this.deleteLoadedFixture(type, fixture);

    fixtures.push(fixture);
  },

  /**
    Implement this method in order to provide json for CRUD methods

    @method mockJSON
    @param {Subclass of DS.Model} type
    @param {DS.Model} record
  */
  mockJSON: function(store, type, record) {
    return store.serializerFor(type).serialize(record, { includeId: true });
  },

  /**
    @method generateIdForRecord
    @param {DS.Store} store
    @param {DS.Model} record
    @return {String} id
  */
  generateIdForRecord: function(store) {
    return "fixture-" + counter++;
  },

  /**
    @method find
    @param {DS.Store} store
    @param {subclass of DS.Model} type
    @param {String} id
    @return {Promise} promise
  */
  find: function(store, type, id) {
    var fixtures = this.fixturesForType(type),
        fixture;

    Ember.assert("Unable to find fixtures for model type "+type.toString(), fixtures);

    if (fixtures) {
      fixture = Ember.A(fixtures).findProperty('id', id);
    }

    if (fixture) {
      return this.simulateRemoteCall(function() {
        return fixture;
      }, this);
    }
  },

  /**
    @method findMany
    @param {DS.Store} store
    @param {subclass of DS.Model} type
    @param {Array} ids
    @return {Promise} promise
  */
  findMany: function(store, type, ids) {
    var fixtures = this.fixturesForType(type);

    Ember.assert("Unable to find fixtures for model type "+type.toString(), fixtures);

    if (fixtures) {
      fixtures = fixtures.filter(function(item) {
        return indexOf(ids, item.id) !== -1;
      });
    }

    if (fixtures) {
      return this.simulateRemoteCall(function() {
        return fixtures;
      }, this);
    }
  },

  /**
    @private
    @method findAll
    @param {DS.Store} store
    @param {subclass of DS.Model} type
    @param {String} sinceToken
    @return {Promise} promise
  */
  findAll: function(store, type) {
    var fixtures = this.fixturesForType(type);

    Ember.assert("Unable to find fixtures for model type "+type.toString(), fixtures);

    return this.simulateRemoteCall(function() {
      return fixtures;
    }, this);
  },

  /**
    @private
    @method findQuery
    @param {DS.Store} store
    @param {subclass of DS.Model} type
    @param {Object} query
    @param {DS.AdapterPopulatedRecordArray} recordArray
    @return {Promise} promise
  */
  findQuery: function(store, type, query, array) {
    var fixtures = this.fixturesForType(type);

    Ember.assert("Unable to find fixtures for model type " + type.toString(), fixtures);

    fixtures = this.queryFixtures(fixtures, query, type);

    if (fixtures) {
      return this.simulateRemoteCall(function() {
        return fixtures;
      }, this);
    }
  },

  /**
    @method createRecord
    @param {DS.Store} store
    @param {subclass of DS.Model} type
    @param {DS.Model} record
    @return {Promise} promise
  */
  createRecord: function(store, type, record) {
    var fixture = this.mockJSON(store, type, record);

    this.updateFixtures(type, fixture);

    return this.simulateRemoteCall(function() {
      return fixture;
    }, this);
  },

  /**
    @method updateRecord
    @param {DS.Store} store
    @param {subclass of DS.Model} type
    @param {DS.Model} record
    @return {Promise} promise
  */
  updateRecord: function(store, type, record) {
    var fixture = this.mockJSON(store, type, record);

    this.updateFixtures(type, fixture);

    return this.simulateRemoteCall(function() {
      return fixture;
    }, this);
  },

  /**
    @method deleteRecord
    @param {DS.Store} store
    @param {subclass of DS.Model} type
    @param {DS.Model} record
    @return {Promise} promise
  */
  deleteRecord: function(store, type, record) {
    var fixture = this.mockJSON(store, type, record);

    this.deleteLoadedFixture(type, fixture);

    return this.simulateRemoteCall(function() {
      // no payload in a deletion
      return null;
    });
  },

  /*
    @method deleteLoadedFixture
    @private
    @param type
    @param record
  */
  deleteLoadedFixture: function(type, record) {
    var existingFixture = this.findExistingFixture(type, record);

    if(existingFixture) {
      var index = indexOf(type.FIXTURES, existingFixture);
      type.FIXTURES.splice(index, 1);
      return true;
    }
  },

  /*
    @method findExistingFixture
    @private
    @param type
    @param record
  */
  findExistingFixture: function(type, record) {
    var fixtures = this.fixturesForType(type);
    var id = get(record, 'id');

    return this.findFixtureById(fixtures, id);
  },

  /*
    @method findFixtureById
    @private
    @param fixtures
    @param id
  */
  findFixtureById: function(fixtures, id) {
    return Ember.A(fixtures).find(function(r) {
      if(''+get(r, 'id') === ''+id) {
        return true;
      } else {
        return false;
      }
    });
  },

  /*
    @method simulateRemoteCall
    @private
    @param callback
    @param context
  */
  simulateRemoteCall: function(callback, context) {
    var adapter = this;

    return new Ember.RSVP.Promise(function(resolve) {
      if (get(adapter, 'simulateRemoteResponse')) {
        // Schedule with setTimeout
        Ember.run.later(function() {
          resolve(callback.call(context));
        }, get(adapter, 'latency'));
      } else {
        // Asynchronous, but at the of the runloop with zero latency
        Ember.run.schedule('actions', null, function() {
          resolve(callback.call(context));
        });
      }
    }, "DS: FixtureAdapter#simulateRemoteCall");
  }
});

export default FixtureAdapter;
<commit_msg>Improve error message<commit_after>/**
  @module ember-data
*/

var get = Ember.get, fmt = Ember.String.fmt,
    indexOf = Ember.EnumerableUtils.indexOf;

var counter = 0;

import Adapter from "../system/adapter";

/**
  `DS.FixtureAdapter` is an adapter that loads records from memory.
  It's primarily used for development and testing. You can also use
  `DS.FixtureAdapter` while working on the API but are not ready to
  integrate yet. It is a fully functioning adapter. All CRUD methods
  are implemented. You can also implement query logic that a remote
  system would do. It's possible to develop your entire application
  with `DS.FixtureAdapter`.

  For information on how to use the `FixtureAdapter` in your
  application please see the [FixtureAdapter
  guide](/guides/models/the-fixture-adapter/).

  @class FixtureAdapter
  @namespace DS
  @extends DS.Adapter
*/
var FixtureAdapter = Adapter.extend({
  // by default, fixtures are already in normalized form
  serializer: null,

  /**
    If `simulateRemoteResponse` is `true` the `FixtureAdapter` will
    wait a number of milliseconds before resolving promises with the
    fixture values. The wait time can be configured via the `latency`
    property.

    @property simulateRemoteResponse
    @type {Boolean}
    @default true
  */
  simulateRemoteResponse: true,

  /**
    By default the `FixtureAdapter` will simulate a wait of the
    `latency` milliseconds before resolving promises with the fixture
    values. This behavior can be turned off via the
    `simulateRemoteResponse` property.

    @property latency
    @type {Number}
    @default 50
  */
  latency: 50,

  /**
    Implement this method in order to provide data associated with a type

    @method fixturesForType
    @param {Subclass of DS.Model} type
    @return {Array}
  */
  fixturesForType: function(type) {
    if (type.FIXTURES) {
      var fixtures = Ember.A(type.FIXTURES);
      return fixtures.map(function(fixture){
        var fixtureIdType = typeof fixture.id;
        if(fixtureIdType !== "number" && fixtureIdType !== "string"){
          throw new Error(fmt('the id property must be defined as a number or string for fixture %@', [fixture]));
        }
        fixture.id = fixture.id + '';
        return fixture;
      });
    }
    return null;
  },

  /**
    Implement this method in order to query fixtures data

    @method queryFixtures
    @param {Array} fixture
    @param {Object} query
    @param {Subclass of DS.Model} type
    @return {Promise|Array}
  */
  queryFixtures: function(fixtures, query, type) {
    Ember.assert('Not implemented: You must override the DS.FixtureAdapter::queryFixtures method to support querying the fixture store.');
  },

  /**
    @method updateFixtures
    @param {Subclass of DS.Model} type
    @param {Array} fixture
  */
  updateFixtures: function(type, fixture) {
    if(!type.FIXTURES) {
      type.FIXTURES = [];
    }

    var fixtures = type.FIXTURES;

    this.deleteLoadedFixture(type, fixture);

    fixtures.push(fixture);
  },

  /**
    Implement this method in order to provide json for CRUD methods

    @method mockJSON
    @param {Subclass of DS.Model} type
    @param {DS.Model} record
  */
  mockJSON: function(store, type, record) {
    return store.serializerFor(type).serialize(record, { includeId: true });
  },

  /**
    @method generateIdForRecord
    @param {DS.Store} store
    @param {DS.Model} record
    @return {String} id
  */
  generateIdForRecord: function(store) {
    return "fixture-" + counter++;
  },

  /**
    @method find
    @param {DS.Store} store
    @param {subclass of DS.Model} type
    @param {String} id
    @return {Promise} promise
  */
  find: function(store, type, id) {
    var fixtures = this.fixturesForType(type),
        fixture;

    Ember.assert("Unable to find fixtures for model type "+type.toString() +". If you're defining your fixtures using `Model.FIXTURES = ...`, please change it to `Model.reopenClass({ FIXTURES: ... })`.", fixtures);

    if (fixtures) {
      fixture = Ember.A(fixtures).findProperty('id', id);
    }

    if (fixture) {
      return this.simulateRemoteCall(function() {
        return fixture;
      }, this);
    }
  },

  /**
    @method findMany
    @param {DS.Store} store
    @param {subclass of DS.Model} type
    @param {Array} ids
    @return {Promise} promise
  */
  findMany: function(store, type, ids) {
    var fixtures = this.fixturesForType(type);

    Ember.assert("Unable to find fixtures for model type "+type.toString(), fixtures);

    if (fixtures) {
      fixtures = fixtures.filter(function(item) {
        return indexOf(ids, item.id) !== -1;
      });
    }

    if (fixtures) {
      return this.simulateRemoteCall(function() {
        return fixtures;
      }, this);
    }
  },

  /**
    @private
    @method findAll
    @param {DS.Store} store
    @param {subclass of DS.Model} type
    @param {String} sinceToken
    @return {Promise} promise
  */
  findAll: function(store, type) {
    var fixtures = this.fixturesForType(type);

    Ember.assert("Unable to find fixtures for model type "+type.toString(), fixtures);

    return this.simulateRemoteCall(function() {
      return fixtures;
    }, this);
  },

  /**
    @private
    @method findQuery
    @param {DS.Store} store
    @param {subclass of DS.Model} type
    @param {Object} query
    @param {DS.AdapterPopulatedRecordArray} recordArray
    @return {Promise} promise
  */
  findQuery: function(store, type, query, array) {
    var fixtures = this.fixturesForType(type);

    Ember.assert("Unable to find fixtures for model type " + type.toString(), fixtures);

    fixtures = this.queryFixtures(fixtures, query, type);

    if (fixtures) {
      return this.simulateRemoteCall(function() {
        return fixtures;
      }, this);
    }
  },

  /**
    @method createRecord
    @param {DS.Store} store
    @param {subclass of DS.Model} type
    @param {DS.Model} record
    @return {Promise} promise
  */
  createRecord: function(store, type, record) {
    var fixture = this.mockJSON(store, type, record);

    this.updateFixtures(type, fixture);

    return this.simulateRemoteCall(function() {
      return fixture;
    }, this);
  },

  /**
    @method updateRecord
    @param {DS.Store} store
    @param {subclass of DS.Model} type
    @param {DS.Model} record
    @return {Promise} promise
  */
  updateRecord: function(store, type, record) {
    var fixture = this.mockJSON(store, type, record);

    this.updateFixtures(type, fixture);

    return this.simulateRemoteCall(function() {
      return fixture;
    }, this);
  },

  /**
    @method deleteRecord
    @param {DS.Store} store
    @param {subclass of DS.Model} type
    @param {DS.Model} record
    @return {Promise} promise
  */
  deleteRecord: function(store, type, record) {
    var fixture = this.mockJSON(store, type, record);

    this.deleteLoadedFixture(type, fixture);

    return this.simulateRemoteCall(function() {
      // no payload in a deletion
      return null;
    });
  },

  /*
    @method deleteLoadedFixture
    @private
    @param type
    @param record
  */
  deleteLoadedFixture: function(type, record) {
    var existingFixture = this.findExistingFixture(type, record);

    if(existingFixture) {
      var index = indexOf(type.FIXTURES, existingFixture);
      type.FIXTURES.splice(index, 1);
      return true;
    }
  },

  /*
    @method findExistingFixture
    @private
    @param type
    @param record
  */
  findExistingFixture: function(type, record) {
    var fixtures = this.fixturesForType(type);
    var id = get(record, 'id');

    return this.findFixtureById(fixtures, id);
  },

  /*
    @method findFixtureById
    @private
    @param fixtures
    @param id
  */
  findFixtureById: function(fixtures, id) {
    return Ember.A(fixtures).find(function(r) {
      if(''+get(r, 'id') === ''+id) {
        return true;
      } else {
        return false;
      }
    });
  },

  /*
    @method simulateRemoteCall
    @private
    @param callback
    @param context
  */
  simulateRemoteCall: function(callback, context) {
    var adapter = this;

    return new Ember.RSVP.Promise(function(resolve) {
      if (get(adapter, 'simulateRemoteResponse')) {
        // Schedule with setTimeout
        Ember.run.later(function() {
          resolve(callback.call(context));
        }, get(adapter, 'latency'));
      } else {
        // Asynchronous, but at the of the runloop with zero latency
        Ember.run.schedule('actions', null, function() {
          resolve(callback.call(context));
        });
      }
    }, "DS: FixtureAdapter#simulateRemoteCall");
  }
});

export default FixtureAdapter;
<|endoftext|>


<commit_before>// ==========================================================================
// Project:   Ember Handlebars Views
// Copyright: ©2011 Strobe Inc. and contributors.
// License:   Licensed under MIT license (see license.js)
// ==========================================================================
/*globals Handlebars */

// TODO: Don't require all of this module
require('ember-handlebars');
require('ember-handlebars/helpers/view');

var get = Ember.get, getPath = Ember.Handlebars.getPath, fmt = Ember.String.fmt;

/**
  `{{collection}}` is a `Ember.Handlebars` helper for adding instances of
  `Ember.CollectionView` to a template.  See `Ember.CollectionView` for additional
  information on how a `CollectionView` functions.

  `{{collection}}`'s primary use is as a block helper with a `contentBinding` option
  pointing towards an `Ember.Array`-compatible object.  An `Ember.View` instance will
  be created for each item in its `content` property. Each view will have its own
  `content` property set to the appropriate item in the collection.

  The provided block will be applied as the template for each item's view.

  Given an empty `<body>` the following template:

  And the following application code

      App = Ember.Application.create()
      App.items = [
        Ember.Object.create({name: 'Dave'}),
        Ember.Object.create({name: 'Mary'}),
        Ember.Object.create({name: 'Sara'})
      ]

  Will result in the HTML structure below

Hi Dave

Hi Mary

Hi Sara

  ### Blockless Use
  If you provide an `itemViewClass` option that has its own `template` you can omit
  the block.

  The following template:

  And application code

      App = Ember.Application.create()
      App.items = [
        Ember.Object.create({name: 'Dave'}),
        Ember.Object.create({name: 'Mary'}),
        Ember.Object.create({name: 'Sara'})
      ]

      App.AnItemView = Ember.View.extend({
        template: Ember.Handlebars.compile("Greetings {{content.name}}")
      })

  Will result in the HTML structure below

Greetings Dave

Greetings Mary

Greetings Sara

  ### Specifying a CollectionView subclass
  By default the `{{collection}}` helper will create an instance of `Ember.CollectionView`.
  You can supply a `Ember.CollectionView` subclass to the helper by passing it
  as the first argument:

  ### Forwarded `item.*`-named Options
  As with the `{{view}}`, helper options passed to the `{{collection}}` will be set on
  the resulting `Ember.CollectionView` as properties. Additionally, options prefixed with
  `item` will be applied to the views rendered for each item (note the camelcasing):

  Will result in the following HTML structure:

Howdy Dave

Howdy Mary

Howdy Sara

  @name Handlebars.helpers.collection
  @param {String} path
  @param {Hash} options
  @returns {String} HTML string
*/
Ember.Handlebars.registerHelper('collection', function(path, options) {
  // If no path is provided, treat path param as options.
  if (path && path.data && path.data.isRenderData) {
    options = path;
    path = undefined;
    Ember.assert("You cannot pass more than one argument to the collection helper", arguments.length === 1);
  } else {
    Ember.assert("You cannot pass more than one argument to the collection helper", arguments.length === 2);
  }

  var fn = options.fn;
  var data = options.data;
  var inverse = options.inverse;

  // If passed a path string, convert that into an object.
  // Otherwise, just default to the standard class.
  var collectionClass;
  collectionClass = path ? getPath(this, path, options) : Ember.CollectionView;
  Ember.assert(fmt("%@ #collection: Could not find collection class %@", [data.view, path]), !!collectionClass);

  var hash = options.hash, itemHash = {}, match;

  // Extract item view class if provided else default to the standard class
  var itemViewClass, itemViewPath = hash.itemViewClass;
  var collectionPrototype = collectionClass.proto();
  delete hash.itemViewClass;
  itemViewClass = itemViewPath ? getPath(collectionPrototype, itemViewPath, options) : collectionPrototype.itemViewClass;
  Ember.assert(fmt("%@ #collection: Could not find itemViewClass %@", [data.view, itemViewPath]), !!itemViewClass);

  // Go through options passed to the {{collection}} helper and extract options
  // that configure item views instead of the collection itself.
  for (var prop in hash) {
    if (hash.hasOwnProperty(prop)) {
      match = prop.match(/^item(.)(.*)$/);

      if(match) {
        // Convert itemShouldFoo -> shouldFoo
        itemHash[match[1].toLowerCase() + match[2]] = hash[prop];
        // Delete from hash as this will end up getting passed to the
        // {{view}} helper method.
        delete hash[prop];
      }
    }
  }

  var tagName = hash.tagName || collectionPrototype.tagName;

  if (fn) {
    itemHash.template = fn;
    delete options.fn;
  }

  var emptyViewClass;
  if (inverse && inverse !== Handlebars.VM.noop) {
    emptyViewClass = get(collectionPrototype, 'emptyViewClass');
    emptyViewClass = emptyViewClass.extend({
          template: inverse,
          tagName: itemHash.tagName
    });
  } else if (hash.emptyViewClass) {
    emptyViewClass = getPath(this, hash.emptyViewClass, options);
  }
  hash.emptyView = emptyViewClass;

  if (hash.eachHelper === 'each') {
    itemHash._context = Ember.computed(function() {
      return get(this, 'content');
    }).property('content');
    delete hash.eachHelper;
  }

  var viewOptions = Ember.Handlebars.ViewHelper.propertiesFromHTMLOptions({ data: data, hash: itemHash }, this);
  hash.itemViewClass = itemViewClass.extend(viewOptions);

  return Ember.Handlebars.helpers.view.call(this, collectionClass, options);
});

<commit_msg>update collection helper documentation against view context change<commit_after>// ==========================================================================
// Project:   Ember Handlebars Views
// Copyright: ©2011 Strobe Inc. and contributors.
// License:   Licensed under MIT license (see license.js)
// ==========================================================================
/*globals Handlebars */

// TODO: Don't require all of this module
require('ember-handlebars');
require('ember-handlebars/helpers/view');

var get = Ember.get, getPath = Ember.Handlebars.getPath, fmt = Ember.String.fmt;

/**
  `{{collection}}` is a `Ember.Handlebars` helper for adding instances of
  `Ember.CollectionView` to a template.  See `Ember.CollectionView` for additional
  information on how a `CollectionView` functions.

  `{{collection}}`'s primary use is as a block helper with a `contentBinding` option
  pointing towards an `Ember.Array`-compatible object.  An `Ember.View` instance will
  be created for each item in its `content` property. Each view will have its own
  `content` property set to the appropriate item in the collection.

  The provided block will be applied as the template for each item's view.

  Given an empty `<body>` the following template:

  And the following application code

      App = Ember.Application.create()
      App.items = [
        Ember.Object.create({name: 'Dave'}),
        Ember.Object.create({name: 'Mary'}),
        Ember.Object.create({name: 'Sara'})
      ]

  Will result in the HTML structure below

Hi Dave

Hi Mary

Hi Sara

  ### Blockless Use
  If you provide an `itemViewClass` option that has its own `template` you can omit
  the block.

  The following template:

  And application code

      App = Ember.Application.create()
      App.items = [
        Ember.Object.create({name: 'Dave'}),
        Ember.Object.create({name: 'Mary'}),
        Ember.Object.create({name: 'Sara'})
      ]

      App.AnItemView = Ember.View.extend({
        template: Ember.Handlebars.compile("Greetings {{view.content.name}}")
      })

  Will result in the HTML structure below

Greetings Dave

Greetings Mary

Greetings Sara

  ### Specifying a CollectionView subclass
  By default the `{{collection}}` helper will create an instance of `Ember.CollectionView`.
  You can supply a `Ember.CollectionView` subclass to the helper by passing it
  as the first argument:

  ### Forwarded `item.*`-named Options
  As with the `{{view}}`, helper options passed to the `{{collection}}` will be set on
  the resulting `Ember.CollectionView` as properties. Additionally, options prefixed with
  `item` will be applied to the views rendered for each item (note the camelcasing):

  Will result in the following HTML structure:

Howdy Dave

Howdy Mary

Howdy Sara

  @name Handlebars.helpers.collection
  @param {String} path
  @param {Hash} options
  @returns {String} HTML string
*/
Ember.Handlebars.registerHelper('collection', function(path, options) {
  // If no path is provided, treat path param as options.
  if (path && path.data && path.data.isRenderData) {
    options = path;
    path = undefined;
    Ember.assert("You cannot pass more than one argument to the collection helper", arguments.length === 1);
  } else {
    Ember.assert("You cannot pass more than one argument to the collection helper", arguments.length === 2);
  }

  var fn = options.fn;
  var data = options.data;
  var inverse = options.inverse;

  // If passed a path string, convert that into an object.
  // Otherwise, just default to the standard class.
  var collectionClass;
  collectionClass = path ? getPath(this, path, options) : Ember.CollectionView;
  Ember.assert(fmt("%@ #collection: Could not find collection class %@", [data.view, path]), !!collectionClass);

  var hash = options.hash, itemHash = {}, match;

  // Extract item view class if provided else default to the standard class
  var itemViewClass, itemViewPath = hash.itemViewClass;
  var collectionPrototype = collectionClass.proto();
  delete hash.itemViewClass;
  itemViewClass = itemViewPath ? getPath(collectionPrototype, itemViewPath, options) : collectionPrototype.itemViewClass;
  Ember.assert(fmt("%@ #collection: Could not find itemViewClass %@", [data.view, itemViewPath]), !!itemViewClass);

  // Go through options passed to the {{collection}} helper and extract options
  // that configure item views instead of the collection itself.
  for (var prop in hash) {
    if (hash.hasOwnProperty(prop)) {
      match = prop.match(/^item(.)(.*)$/);

      if(match) {
        // Convert itemShouldFoo -> shouldFoo
        itemHash[match[1].toLowerCase() + match[2]] = hash[prop];
        // Delete from hash as this will end up getting passed to the
        // {{view}} helper method.
        delete hash[prop];
      }
    }
  }

  var tagName = hash.tagName || collectionPrototype.tagName;

  if (fn) {
    itemHash.template = fn;
    delete options.fn;
  }

  var emptyViewClass;
  if (inverse && inverse !== Handlebars.VM.noop) {
    emptyViewClass = get(collectionPrototype, 'emptyViewClass');
    emptyViewClass = emptyViewClass.extend({
          template: inverse,
          tagName: itemHash.tagName
    });
  } else if (hash.emptyViewClass) {
    emptyViewClass = getPath(this, hash.emptyViewClass, options);
  }
  hash.emptyView = emptyViewClass;

  if (hash.eachHelper === 'each') {
    itemHash._context = Ember.computed(function() {
      return get(this, 'content');
    }).property('content');
    delete hash.eachHelper;
  }

  var viewOptions = Ember.Handlebars.ViewHelper.propertiesFromHTMLOptions({ data: data, hash: itemHash }, this);
  hash.itemViewClass = itemViewClass.extend(viewOptions);

  return Ember.Handlebars.helpers.view.call(this, collectionClass, options);
});

<|endoftext|>


<commit_before>/**
 * Reordering utilities for the items drag and drop ordering page -AZ
 * Does not put stuff into the global namespace and uses only methods that are compatible with most browsers
 *
 * Update: Functions have been exposed to enable startSort() to be accessible by custom plugins - lovemore.nalube@uct.ac.za
 **/
var sortableIds = new Array();
$(document).ready(
        function () {
			startSort();
            $(document).trigger('activateControls.templateItems');
            buildSortableIds();

        }
        );

function $it(id) {
    return document.getElementById(id);
}

function enableOrderButtons() {
	try {
		$("#revertOrderButton")
                .attr('disabled', false)
                // put original order into the revertOrder trigger
                .bind('click', function() {
                    disableOrderButtons();
                    for (var i = sortableIds.length - 1; i > 0; --i) {
                        var thisitem = $it(sortableIds[i]);
                        var previtem = $it(sortableIds[i - 1]);
                        previtem.parentNode.removeChild(previtem);
                        thisitem.parentNode.insertBefore(previtem, thisitem);
                        setIndex(thisitem.id, i);
                    }
                    setIndex(sortableIds[0], 0);
                });
		$("#saveReorderButton").attr('disabled', false);
		$("#orderInputs").attr("class","itemOperationsEnabled");
	}catch(e){}
}

function disableOrderButtons() {
    try {
		$("#revertOrderButton").attr('disabled', true);
		$("#saveReorderButton").attr('disabled', true);
		$("#orderInputs").attr("class","itemOperations");
	}catch(e){}
}
function buildSortableIds() {
    $("#itemList > div.itemRow").each(function(){
       sortableIds.push($(this).attr('id'));
    });
}

function setIndex(itemId, newindex) {
	if (newindex != null || newindex != "") {
		var changed = sortableIds[newindex] != itemId;
		var itemSelect = document.getElementById(itemId + "item-select-selection");
		itemSelect.selectedIndex = newindex;
		// NOTE: might need to disable the pulldowns once the user drags
		$it(itemId + "hidden-item-num").value = newindex;
	}
}

function startSort() {
    $("#itemList").sortable({
        axis:         'y',
        cancel:     ':input, button, a, select, div.itemLine3',
        connectWith: ['.itemTableBlock'],
        cursor:     'move',
        delay:         '1',
        opacity:     '0.9',
        scroll:     true,
        update: function(data) {
            var list = $("#itemList > div").get();
            for (var i = 0; i < list.length - 1; i++) {
                if (list[i].id) {
                    setIndex(list[i].id, i);
                }
            }
            enableOrderButtons();
        }

    });
    $(".itemTableBlock").each(function() {
        $(this).sortable({
            axis: 'y',
            cancel: ':input, button, a, select',
            containment: 'parent',
            cursor: 'move',
            over: function(e, ui) {
                if ($('#closeItemOperationsEnabled').length > 0) {
                    $('#closeItemOperationsEnabled').parent().remove();
                }
            },
            deactivate: function(e, ui) {
                if ((ui.sender.attr('id') != "itemTableBlock") && (ui.item.parent().attr('id') != "itemList")) {
                    var that = ui.item.find('.itemCheckbox > input').eq(0).attr('id');
                    if (that == null) {
                        $(document).trigger('block.rejectItem', [ui , "plain"]);
                    }
                    var target = ui.item.parents('.itemRow').eq(0).find('.itemCheckbox > input').eq(0).attr('id');
                    if (target == null)
                        return false;
                    var targetVal = target.substring(target.indexOf('-') + 1, target.lastIndexOf('-'));
                    var thatVal = that.substring(that.indexOf('-') + 1, that.lastIndexOf('-'));
                    if (targetVal != thatVal) {
                        $(document).trigger('block.rejectItem', [ui]);
                    } else {

                        var confirmMsg = '\

Are you sure?

\

 \
			                  <input type="button" name="blockChildConfirm" msg="yes" accesskey="s" value="Yes"/>  |  \
			                  Cancel  \

 \
                                         ';

                        $.facebox(confirmMsg);

                        $('#facebox .header').eq(0).hide();
                        $('#facebox table').attr('width', 250);
                        $('#facebox .body').css('width', 250);
                        $('#facebox .body [name*=blockChildConfirm]').click(function() {
                            if ($(this).attr('msg') == 'yes') {
                                $.facebox('\

  Saving... \

 \

 \
			                   Please do not close this window.  \

 ');
                                ui.item.attr('style', 'display:none');
                                var shadow = ui.item.parent().find('.itemRowBlock').eq(0).clone(true);
                                shadow.insertAfter(ui.item);
                                ui.item.parent().find('div[id="' + shadow.attr('id') + '"]').not(':lt(2)').remove();
                                shadow.find('span').eq(1).html(ui.item.find('.itemText > span').eq(0).html());
                                shadow.find('input').eq(0).val(ui.item.find('a[templateitemid]').attr('templateitemid'));
                                shadow.find('a[templateitemid]').attr('templateitemid', ui.item.find('a[templateitemid]').attr('templateitemid'));
                                shadow.find('a[otp]').attr('otp', ui.item.find('a[otp]').attr('otp'));
                                $(document).trigger('block.saveReorder', [ui]);
                                return false;

                            }
                            else if ($(this).attr('msg') == 'no') {
                                $(document).trigger('block.rejectItem', [ui, "noAlert"]);
                                $(document).trigger('close.facebox');
                                return false;
                            }

                        });
                    }

                }
                return false;
            },
            delay: '1',
            items: 'div',
            opacity: '0.9',
            scroll: true,
            update: function(e, ui) {
                $(document).trigger('block.triggerChildrenSort', [ui]);
                if (ui.item.parents('.itemTableBlock').find('.itemBlockSave').length == 0) {
                    var saveAction = 'Save new order for grouped items';
                    $(saveAction).appendTo(ui.item.parents('.itemTableBlock').children('.instruction').eq(0));
                    ui.item.parents('.itemTableBlock').children('.instruction').eq(0).effect('highlight', 1500);
                    ui.item.parents('.itemTableBlock').find('.itemBlockSave').bind('click', function() {
                        $(document).trigger('block.triggerChildrenSort', [ui]);
                        $(this).html('Saving... ');
                        ui.item.parents('.itemTableBlock').sortable('disable');
                        $(document).trigger('block.saveReorder', [ui,"simple"]);
                        ui.item.parents('.itemTableBlock').sortable('enable');
                        return false;
                    });
                }

            }
        });
    });
}
function refreshSort() {
    $("div.itemList").sortable('destroy');
    $("div.itemTableBlock").sortable('destroy');
    startSort();
}
$(document).bind('block.triggerChildrenSort', function(e, ui) {
	if(!ui.item){
        var tempUi = ui;
        var ui = new Object()
          ui.item = tempUi;
    }
    var count = 1;
    ui.item.parents('.itemTableBlock').find('div.itemRowBlock').not('.ui-sortable-helper').each(function(){
		$(this).find('.itemLabel').text(count);
		count++;
	});
});
$(document).bind('block.rejectItem', function(e, ui, option) {
    $(document).trigger('list.warning', [ui, option, 'block', 'Sorry this item cannot be grouped here. It is not the same type as the grouped items.']);
    var shadow = ui.item.clone(true);
    var shadowPlace = $('.itemList > div.itemRow').eq(ui.item.find('input').eq(0).val()).attr('id');
    ui.item.remove();
    shadow.insertBefore($('[id="' + shadowPlace + '"]'));
    shadow.removeAttr('style').effect('highlight', 3500);
    $('.itemList div[id="' + shadow.attr('id') + '"]').not(':lt(1)').remove();
    refreshSort();
    var list = $(".itemList > div.itemRow").get();
    for (var i = 0; i < list.length; i++) {
        if (list[i].id) {
            setIndex(list[i].id, i);
        }
    }
});

$(document).bind('block.saveReorder', function(e, ui, type) {
    if(!ui.item){
        var tempUi = ui;
        var ui = new Object()
          ui.item = tempUi;
    }
	$(document).trigger('list.busy', true);
    var currentOrder = ui.item.parents('.itemRow').children('input[name=*hidden-item-num]').eq(0).val();
    $.get('/direct/eval-templateitem/' + ui.item.parents('.itemRow').children('.itemLine2').find('a[templateitemid]').attr('templateitemid') + '.xml',
            function(msg) {
                var itemText = $(msg).find('item > itemText').text();
                var usesNA = $(msg).find('usesNA').eq(1).text();
                var category = $(msg).find('category').eq(1).text();
                var idealColour =  $(msg).find('item > scaleDisplaySetting').text();
                var t = ui.item.parents('.itemRow').eq(0).children('.itemLine2').find('a[templateitemid]');

                $.ajax({
                    url: "remove_item",
                    data: 'templateItemId=' + t.attr('templateitemid') + '&templateId=' + t.attr('templateid') + '&command+link+parameters%26deletion-binding%3Dl%2523%257B' + t.attr('otp') + '%257D%26Submitting%2520control%3Dremove-item-command-link=Remove+Item',
                    type: "POST",
                    success: function() {
                        var params = 'item-text=' + itemText;
                        params += '&item-text-fossil=istring%23%7BtemplateItemWBL.new1.item.itemText%7D';
                        params += '&showItemCategory%3A%3Aitem-category-list-selection-fossil=istring%23%7BtemplateItemWBL.new1.category%7DCourse';
                        params += '$showItemCategory%3A%3Aitem-category-list-selection=' + category;
                        params += '&idealColor-fossil=iboolean%23%7BtemplateBBean.idealColor%7Dfalse';
                        params += '&idealColor=' + (idealColour == "Stepped" ? "false" : "true");
                        params += '&item_NA-fossil=iboolean%23%7BtemplateItemWBL.new1.usesNA%7Dfalse';
                        params += '&item_NA=' + usesNA;
                        var ordering = new Array();
                        ui.item.parents('.itemTableBlock').eq(0).children('.itemRowBlock').filter(':visible').each(function() {
                            var val = $(this).children('input[name=hidden-item-id]').eq(0).val();
                            params += '&hidden-item-id=' + val;
                            ordering.push(val);
                        });
                        params += '&templateItemIds=' + ordering.toString();
                        params += '&ordered-child-ids=' + ordering.toString();
                        params += '&ordered-child-ids-fossil=istring%23%7BtemplateBBean.orderedChildIds%7D';
                        params += '&templateId=' + t.attr('templateid');
                        params += '&command+link+parameters%26el-binding%3Dj%2523%257BtemplateBBean.blockId%257Dnew1%26el-binding%3Dj%2523%257BtemplateBBean.templateItemIds%257D' + ordering.toString() + '%26el-binding%3Dj%2523%257BtemplateBBean.originalDisplayOrder%257D2%26Submitting%2520control%3DsaveBlockAction%26Fast%2520track%2520action%3DtemplateBBean.saveBlockItemAction=Save+item';
                        $.ajax({
                            url: "modify_block",
                            data: params,
                            type: "POST",
                            success: function(d) {
                                var id = 'input[value=' + ui.item.find('input[name=hidden-item-id]').eq(0).val() + ']:hidden';
                                ui.item.parents('.itemRow').eq(0).html($(d).find(id).parents('.itemRow').eq(0).html());
                                $(document).trigger('list.triggerSort');
                                ui.item.parents('.itemRow').eq(0).children('input[name=*hidden-item-num]').eq(0).val(currentOrder);

                                $('form[name=modify_form_rows]').ajaxSubmit({
                                    success: function(d) {
                                        if ((type != null) && (type == "simple")) {
                                            $(document).trigger('activateControls.templateItems');
                                            ui.item.parents('.itemRow').effect('highlight', 1500);
                                            ui.item.parents('.itemRow').find('.itemBlockSave').fadeOut('fast', function() {
                                                $(this).remove();
                                            });
                                        } else {
                                            $('#itemList').html($(d).find('#itemList').html());
                                            $(document).trigger('list.triggerSort', [ui]);
                                            $(document).trigger('activateControls.templateItems');
                                            $(document).trigger('close.facebox');
                                            ui.item.parents('.itemTableBlock').effect('highlight', 3500);
                                        }
										$(document).trigger('list.busy', false);
                                    }
                                });
                            }
                        });
                    }
                });
});
});
$(document).bind('list.triggerSort', function() {
var c = 0;
$(".itemList > div.itemRow").filter(':visible').each(function() {
    $(this).find('select').eq(0).val(c + 1);
    $(this).find('input[name=*hidden-item-num]').eq(0).val(c);
    c++;
});
});

$(document).bind('list.warning', function(e, ui, option, extra, err){
	if(!ui.item){
        var tempUi = ui;
        var ui = new Object()
          ui.item = tempUi;
    }
	    if (option != "noAlert") {
		$('.itemOperationsEnabled').remove();
        var error = '
\
                        \
                        '+ err +' close
\
                        ';
		if(extra == 'block')
        	ui.item.parents('.itemLine3').prepend(error);
        $('#closeItemOperationsEnabled').click(function() {
            $(this).parent().slideUp('normal', function() {
                $(this).remove()
            });
            return false
        });
    }
});
<commit_msg>Reformatting patch (tabs -> spaces, general linting) http://bugs.sakaiproject.org/jira/browse/NOJIRA<commit_after>/**
 * Reordering utilities for the items drag and drop ordering page -AZ
 * Does not put stuff into the global namespace and uses only methods that are compatible with most browsers
 *
 * Update: Functions have been exposed to enable startSort() to be accessible by custom plugins - lovemore.nalube@uct.ac.za
 **/
var sortableIds = new Array();

$(document).ready(
        function () {
            startSort();
            $(document).trigger('activateControls.templateItems');
            buildSortableIds();
        }
    );

function $it(id) {
    return document.getElementById(id);
}

function enableOrderButtons() {
    try {
        $("#revertOrderButton")
                .attr('disabled', false)
                // put original order into the revertOrder trigger
                .bind('click', function() {
                    disableOrderButtons();
                    for (var i = sortableIds.length - 1; i > 0; --i) {
                        var thisitem = $it(sortableIds[i]);
                        var previtem = $it(sortableIds[i - 1]);
                        previtem.parentNode.removeChild(previtem);
                        thisitem.parentNode.insertBefore(previtem, thisitem);
                        setIndex(thisitem.id, i);
                    }
                    setIndex(sortableIds[0], 0);
                });
        $("#saveReorderButton").attr('disabled', false);
        $("#orderInputs").attr("class","itemOperationsEnabled");
    }catch(e){}
}

function disableOrderButtons() {
    try {
        $("#revertOrderButton").attr('disabled', true);
        $("#saveReorderButton").attr('disabled', true);
        $("#orderInputs").attr("class","itemOperations");
    }catch(e){}
}

function buildSortableIds() {
    $("#itemList > div.itemRow").each(function(){
       sortableIds.push($(this).attr('id'));
    });
}

function setIndex(itemId, newindex) {
    if (newindex != null || newindex != "") {
        var changed = sortableIds[newindex] != itemId;
        var itemSelect = document.getElementById(itemId + "item-select-selection");
        itemSelect.selectedIndex = newindex;
        // NOTE: might need to disable the pulldowns once the user drags
        $it(itemId + "hidden-item-num").value = newindex;
    }
}

function startSort() {
    $("#itemList").sortable({
        axis:         'y',
        cancel:     ':input, button, a, select, div.itemLine3',
        connectWith: ['.itemTableBlock'],
        cursor:     'move',
        delay:         '1',
        opacity:     '0.9',
        scroll:     true,
        update: function(data) {
            var list = $("#itemList > div").get();
            for (var i = 0; i < list.length - 1; i++) {
                if (list[i].id) {
                    setIndex(list[i].id, i);
                }
            }
            enableOrderButtons();
        }

    });
    $(".itemTableBlock").each(function() {
        $(this).sortable({
            axis: 'y',
            cancel: ':input, button, a, select',
            containment: 'parent',
            cursor: 'move',
            over: function(e, ui) {
                if ($('#closeItemOperationsEnabled').length > 0) {
                    $('#closeItemOperationsEnabled').parent().remove();
                }
            },
            deactivate: function(e, ui) {
                if ((ui.sender.attr('id') != "itemTableBlock") && (ui.item.parent().attr('id') != "itemList")) {
                    var that = ui.item.find('.itemCheckbox > input').eq(0).attr('id');
                    if (that == null) {
                        $(document).trigger('block.rejectItem', [ui , "plain"]);
                    }
                    var target = ui.item.parents('.itemRow').eq(0).find('.itemCheckbox > input').eq(0).attr('id');
                    if (target == null)
                        return false;
                    var targetVal = target.substring(target.indexOf('-') + 1, target.lastIndexOf('-'));
                    var thatVal = that.substring(that.indexOf('-') + 1, that.lastIndexOf('-'));
                    if (targetVal != thatVal) {
                        $(document).trigger('block.rejectItem', [ui]);
                    } else {

                        var confirmMsg = '\

Are you sure?

\

 \
                              <input type="button" name="blockChildConfirm" msg="yes" accesskey="s" value="Yes"/>  |  \
                              Cancel  \

 \
                                         ';

                        $.facebox(confirmMsg);

                        $('#facebox .header').eq(0).hide();
                        $('#facebox table').attr('width', 250);
                        $('#facebox .body').css('width', 250);
                        $('#facebox .body [name*=blockChildConfirm]').click(function() {
                            if ($(this).attr('msg') == 'yes') {
                                $.facebox('\

  Saving... \

 \

 \
                               Please do not close this window.  \

 ');
                                ui.item.attr('style', 'display:none');
                                var shadow = ui.item.parent().find('.itemRowBlock').eq(0).clone(true);
                                shadow.insertAfter(ui.item);
                                ui.item.parent().find('div[id="' + shadow.attr('id') + '"]').not(':lt(2)').remove();
                                shadow.find('span').eq(1).html(ui.item.find('.itemText > span').eq(0).html());
                                shadow.find('input').eq(0).val(ui.item.find('a[templateitemid]').attr('templateitemid'));
                                shadow.find('a[templateitemid]').attr('templateitemid', ui.item.find('a[templateitemid]').attr('templateitemid'));
                                shadow.find('a[otp]').attr('otp', ui.item.find('a[otp]').attr('otp'));
                                $(document).trigger('block.saveReorder', [ui]);
                                return false;

                            }
                            else if ($(this).attr('msg') == 'no') {
                                $(document).trigger('block.rejectItem', [ui, "noAlert"]);
                                $(document).trigger('close.facebox');
                                return false;
                            }

                        });
                    }

                }
                return false;
            },
            delay: '1',
            items: 'div',
            opacity: '0.9',
            scroll: true,
            update: function(e, ui) {
                $(document).trigger('block.triggerChildrenSort', [ui]);
                if (ui.item.parents('.itemTableBlock').find('.itemBlockSave').length == 0) {
                    var saveAction = 'Save new order for grouped items';
                    $(saveAction).appendTo(ui.item.parents('.itemTableBlock').children('.instruction').eq(0));
                    ui.item.parents('.itemTableBlock').children('.instruction').eq(0).effect('highlight', 1500);
                    ui.item.parents('.itemTableBlock').find('.itemBlockSave').bind('click', function() {
                        $(document).trigger('block.triggerChildrenSort', [ui]);
                        $(this).html('Saving... ');
                        ui.item.parents('.itemTableBlock').sortable('disable');
                        $(document).trigger('block.saveReorder', [ui,"simple"]);
                        ui.item.parents('.itemTableBlock').sortable('enable');
                        return false;
                    });
                }

            }
        });
    });
}
function refreshSort() {
    $("div.itemList").sortable('destroy');
    $("div.itemTableBlock").sortable('destroy');
    startSort();
}
$(document).bind('block.triggerChildrenSort', function(e, ui) {
    var item = ui.item? ui.item : ui;

    var count = 1;
    item.parents('.itemTableBlock').find('div.itemRowBlock').not('.ui-sortable-helper').each(function(){
        $(this).find('.itemLabel').text(count);
        count++;
    });
});
$(document).bind('block.rejectItem', function(e, ui, option) {
    $(document).trigger('list.warning', [ui, option, 'block', 'Sorry this item cannot be grouped here. It is not the same type as the grouped items.']);
    var shadow = ui.item.clone(true);
    var shadowPlace = $('.itemList > div.itemRow').eq(ui.item.find('input').eq(0).val()).attr('id');
    ui.item.remove();
    shadow.insertBefore($('[id="' + shadowPlace + '"]'));
    shadow.removeAttr('style').effect('highlight', 3500);
    $('.itemList div[id="' + shadow.attr('id') + '"]').not(':lt(1)').remove();
    refreshSort();
    var list = $(".itemList > div.itemRow").get();
    for (var i = 0; i < list.length; i++) {
        if (list[i].id) {
            setIndex(list[i].id, i);
        }
    }
});

$(document).bind('block.saveReorder', function(e, ui, type) {
    var item = ui.item? ui.item : ui;
    ui = {item: item};

    $(document).trigger('list.busy', true);
    var currentOrder = item.parents('.itemRow').children('input[name=*hidden-item-num]').eq(0).val();
    $.get('/direct/eval-templateitem/' + item.parents('.itemRow').children('.itemLine2').find('a[templateitemid]').attr('templateitemid') + '.xml',
            function(msg) {
                var itemText = $(msg).find('item > itemText').text();
                var usesNA = $(msg).find('usesNA').eq(1).text();
                var category = $(msg).find('category').eq(1).text();
                var idealColour =  $(msg).find('item > scaleDisplaySetting').text();
                var t = item.parents('.itemRow').eq(0).children('.itemLine2').find('a[templateitemid]');

                $.ajax({
                    url: "remove_item",
                    data: 'templateItemId=' + t.attr('templateitemid') + '&templateId=' + t.attr('templateid') + '&command+link+parameters%26deletion-binding%3Dl%2523%257B' + t.attr('otp') + '%257D%26Submitting%2520control%3Dremove-item-command-link=Remove+Item',
                    type: "POST",
                    success: function() {
                        var params = 'item-text=' + itemText;
                        params += '&item-text-fossil=istring%23%7BtemplateItemWBL.new1.item.itemText%7D';
                        params += '&showItemCategory%3A%3Aitem-category-list-selection-fossil=istring%23%7BtemplateItemWBL.new1.category%7DCourse';
                        params += '$showItemCategory%3A%3Aitem-category-list-selection=' + category;
                        params += '&idealColor-fossil=iboolean%23%7BtemplateBBean.idealColor%7Dfalse';
                        params += '&idealColor=' + (idealColour == "Stepped" ? "false" : "true");
                        params += '&item_NA-fossil=iboolean%23%7BtemplateItemWBL.new1.usesNA%7Dfalse';
                        params += '&item_NA=' + usesNA;
                        var ordering = new Array();
                        item.parents('.itemTableBlock').eq(0).children('.itemRowBlock').filter(':visible').each(function() {
                            var val = $(this).children('input[name=hidden-item-id]').eq(0).val();
                            params += '&hidden-item-id=' + val;
                            ordering.push(val);
                        });
                        params += '&templateItemIds=' + ordering.toString();
                        params += '&ordered-child-ids=' + ordering.toString();
                        params += '&ordered-child-ids-fossil=istring%23%7BtemplateBBean.orderedChildIds%7D';
                        params += '&templateId=' + t.attr('templateid');
                        params += '&command+link+parameters%26el-binding%3Dj%2523%257BtemplateBBean.blockId%257Dnew1%26el-binding%3Dj%2523%257BtemplateBBean.templateItemIds%257D' + ordering.toString() + '%26el-binding%3Dj%2523%257BtemplateBBean.originalDisplayOrder%257D2%26Submitting%2520control%3DsaveBlockAction%26Fast%2520track%2520action%3DtemplateBBean.saveBlockItemAction=Save+item';
                        $.ajax({
                            url: "modify_block",
                            data: params,
                            type: "POST",
                            success: function(d) {
                                var id = 'input[value=' + item.find('input[name=hidden-item-id]').eq(0).val() + ']:hidden';
                                item.parents('.itemRow').eq(0).html($(d).find(id).parents('.itemRow').eq(0).html());
                                $(document).trigger('list.triggerSort');
                                item.parents('.itemRow').eq(0).children('input[name=*hidden-item-num]').eq(0).val(currentOrder);

                                $('form[name=modify_form_rows]').ajaxSubmit({
                                    success: function(d) {
                                        if ((type != null) && (type == "simple")) {
                                            $(document).trigger('activateControls.templateItems');
                                            item.parents('.itemRow').effect('highlight', 1500);
                                            item.parents('.itemRow').find('.itemBlockSave').fadeOut('fast', function() {
                                                $(this).remove();
                                            });
                                        } else {
                                            $('#itemList').html($(d).find('#itemList').html());
                                            $(document).trigger('list.triggerSort', [ui]);
                                            $(document).trigger('activateControls.templateItems');
                                            $(document).trigger('close.facebox');
                                            item.parents('.itemTableBlock').effect('highlight', 3500);
                                        }
                                        $(document).trigger('list.busy', false);
                                    }
                                });
                            }
                        });
                    }
                });
    });
});
$(document).bind('list.triggerSort', function() {
var c = 0;
$(".itemList > div.itemRow").filter(':visible').each(function() {
    $(this).find('select').eq(0).val(c + 1);
    $(this).find('input[name=*hidden-item-num]').eq(0).val(c);
    c++;
});
});

$(document).bind('list.warning', function(e, ui, option, extra, err){
    var item = ui.item? ui.item : ui;
        if (option != "noAlert") {
        $('.itemOperationsEnabled').remove();
        var error = '
\
                        \
                        '+ err +' close
\
                        ';
        if(extra == 'block')
            item.parents('.itemLine3').prepend(error);
        $('#closeItemOperationsEnabled').click(function() {
            $(this).parent().slideUp('normal', function() {
                $(this).remove()
            });
            return false
        });
    }
});
<|endoftext|>