<commit_before>steal("can/util","can/view/mustache", "can/control", function(can){

	/**
	 * @function can.view.bindings.can-value can-value
	 * @parent can.view.bindings
	 *
	 * Sets up two way bindings in a template.
	 *
	 * @signature `can-value='KEY'`
	 *
	 * Binds the element's value or checked property to the value specified by
	 * key. Example:
	 *
	 *     <input type='text' can-value='first.name'/>
	 *
	 * @param {can.Mustache.key} key A named value in the current scope.
	 *
	 * @body
	 *
	 * ## Use
	 *
	 * Add a `can-value="KEY"` attribute to an input or select element and
	 * the element's value will be cross-bound to an observable value specified by `KEY`.
	 *
	 * Depending on the element and the element's type, `can-value` takes on
	 * different behaviors.  If an input element has a type
	 * not listed here, the behavior is the same as the `text` type.
	 *
	 * ## input type=text
	 *
	 * Cross binds the input's string text value with the observable value.
	 *
	 * @demo can/view/bindings/hyperloop.html
	 *
	 * ## input type=checkbox
	 *
	 * Cross binds the checked property to a true or false value. An alternative
	 * true and false value can be specified by setting `can-true-value` and
	 * `can-false-value` attributes.
	 *
	 * @demo can/view/bindings/input-checkbox.html
	 *
	 * ## input type='radio'
	 *
	 * If the radio element is checked, sets the observable specified by `can-value` to match the value of
	 * `value` attribute.
	 *
	 * @demo can/view/bindings/input-radio.html
	 *
	 * ## select
	 *
	 * Cross binds the selected option value with an observable value.
	 *
	 * @demo can/view/bindings/select.html
	 *
	 */
	can.view.Scanner.attribute("can-value", function(data, el){

		var attr = el.getAttribute("can-value"),
			value = data.scope.computeData(attr,{args:[]}).compute;

		if(el.nodeName.toLowerCase() === "input"){
			if(el.type === "checkbox") {
				if( el.hasAttribute("can-true-value") ) {
					var trueValue = data.scope.compute( el.getAttribute("can-true-value") )
				} else {
					var trueValue = can.compute(true)
				}
				if( el.hasAttribute("can-false-value") ) {
					var falseValue = data.scope.compute( el.getAttribute("can-false-value") )
				} else {
					var falseValue = can.compute(false)
				}
			}

			if(el.type === "checkbox" || el.type === "radio") {
				new Checked(el,{
					value: value,
					trueValue: trueValue,
					falseValue: falseValue
				});
				return;
			}
		}

		if(el.nodeName.toLowerCase() === "select" && el.multiple) {
			new Multiselect(el, {
				value: value
			});
			return;
		}

		new Value(el,{value: value})
	});

	var special = {
		enter: function(data, el, original){
			return {
				event: "keyup",
				handler: function(ev){
					if(ev.keyCode == 13) {
						return original.call(this,ev)
					}
				}
			}
		}
	}

	/**
	 * @function can.view.bindings.can-EVENT can-EVENT
	 * @parent can.view.bindings
	 *
	 * @signature `can-EVENT='KEY'`
	 *
	 * Specify a callback function to be called on a particular event.
	 *
	 * @param {String} EVENT A event name like `click` or `keyup`.  If you are
	 * using jQuery, you can listen to jQuery special events too.
	 *
	 * @param {can.Mustache.key} key A named value in the current scope.  The value
	 * should be a function.
	 *
	 * @body
	 *
	 * ## Use
	 *
	 * By adding `can-EVENT='KEY'` to an element, the function pointed to
	 * by `KEY` is bound to the element's `EVENT` event. The function
	 * is called back with:
	 *
	 *  - `context` - the context of the element
	 *  - `element` - the element that was bound
	 *  - `event` - the event that was triggered
	 *
	 * @demo can/view/bindings/can-event.html
	 *
	 */
	can.view.Scanner.attribute(/can-[\w\.]+/,function(data, el){

		var attributeName = data.attr,
			event = data.attr.substr("can-".length),
			handler = function(ev){
				var attr = el.getAttribute(attributeName),
					scopeData = data.scope.read(attr,{returnObserveMethods: true, isArgument: true});
				return scopeData.value.call(scopeData.parent,data.scope._data, can.$(this), ev )
			};

		if(special[event]){
			var specialData = special[event](data, el, handler);
			handler = specialData.handler;
			event = specialData.event;
		}

		can.bind.call( el, event, handler);
	});

	var Value = can.Control.extend({
		init: function(){
			if(this.element[0].nodeName.toUpperCase() === "SELECT"){
				// need to wait until end of turn ...
				setTimeout($.proxy(this.set,this),1)
			} else {
				this.set()
			}

		},
		"{value} change": "set",
		set: function(){
			this.element[0].value = this.options.value()
		},
		"change": function(){
			this.options.value(this.element[0].value)
		}
	}), Checked = can.Control.extend({
		init: function(){
			this.isCheckebox = (this.element[0].type.toLowerCase() == "checkbox");
			this.check()
		},
		"{value} change": "check",
		"{trueValue} change": "check",
		"{falseValue} change": "check",
		check: function(){
			if(this.isCheckebox){
				var value =  this.options.value(),
					trueValue = this.options.trueValue() || true,
					falseValue = this.options.falseValue() || false;

				this.element[0].checked = ( value == trueValue )
			} else {
				if(this.options.value() === this.element[0].value){
					this.element[0].checked = true //.prop("checked", true)
				} else {
					this.element[0].checked = false //.prop("checked", false)
				}
			}

		},
		"change": function(){

			if(this.isCheckebox){
				this.options.value( this.element[0].checked? this.options.trueValue() : this.options.falseValue() );
			} else {
				if(this.element[0].checked){
					this.options.value( this.element[0].value );
				}
			}

		}
	}), Multiselect = Value.extend({
		init: function() {
			this.set();
		},

		_set: function(newVal){
			var selectedItem = this.element.find("option[value='" + newVal + "']");

			if(selectedItem.length && !selectedItem.is(':selected')) {
				selectedItem.attr('selected', 'selected');
			}
		},

		set: function() {
			var newVal = this.options.value(), self = this;

			//unset every option
			this.element.find('option').removeAttr('selected');

			//reselect the newly selected options
			can.each(can.makeArray(newVal), function(id){
				self._set(id);
			});

			this.element[0].value = this.get().join(';');
		},

		get: function(){
			var arr = this.element.find('option:selected')
				.map(function(){
					return this.value;
				});

			return can.makeArray(arr);
		},

		'change': function() {
			this.options.value(this.get());
		}
	})

})
<commit_msg>Fixed a small bug, the value must not be set directly as this confuses the browser.<commit_after>steal("can/util","can/view/mustache", "can/control", function(can){

	/**
	 * @function can.view.bindings.can-value can-value
	 * @parent can.view.bindings
	 *
	 * Sets up two way bindings in a template.
	 *
	 * @signature `can-value='KEY'`
	 *
	 * Binds the element's value or checked property to the value specified by
	 * key. Example:
	 *
	 *     <input type='text' can-value='first.name'/>
	 *
	 * @param {can.Mustache.key} key A named value in the current scope.
	 *
	 * @body
	 *
	 * ## Use
	 *
	 * Add a `can-value="KEY"` attribute to an input or select element and
	 * the element's value will be cross-bound to an observable value specified by `KEY`.
	 *
	 * Depending on the element and the element's type, `can-value` takes on
	 * different behaviors.  If an input element has a type
	 * not listed here, the behavior is the same as the `text` type.
	 *
	 * ## input type=text
	 *
	 * Cross binds the input's string text value with the observable value.
	 *
	 * @demo can/view/bindings/hyperloop.html
	 *
	 * ## input type=checkbox
	 *
	 * Cross binds the checked property to a true or false value. An alternative
	 * true and false value can be specified by setting `can-true-value` and
	 * `can-false-value` attributes.
	 *
	 * @demo can/view/bindings/input-checkbox.html
	 *
	 * ## input type='radio'
	 *
	 * If the radio element is checked, sets the observable specified by `can-value` to match the value of
	 * `value` attribute.
	 *
	 * @demo can/view/bindings/input-radio.html
	 *
	 * ## select
	 *
	 * Cross binds the selected option value with an observable value.
	 *
	 * @demo can/view/bindings/select.html
	 *
	 */
	can.view.Scanner.attribute("can-value", function(data, el){

		var attr = el.getAttribute("can-value"),
			value = data.scope.computeData(attr,{args:[]}).compute;

		if(el.nodeName.toLowerCase() === "input"){
			if(el.type === "checkbox") {
				if( el.hasAttribute("can-true-value") ) {
					var trueValue = data.scope.compute( el.getAttribute("can-true-value") )
				} else {
					var trueValue = can.compute(true)
				}
				if( el.hasAttribute("can-false-value") ) {
					var falseValue = data.scope.compute( el.getAttribute("can-false-value") )
				} else {
					var falseValue = can.compute(false)
				}
			}

			if(el.type === "checkbox" || el.type === "radio") {
				new Checked(el,{
					value: value,
					trueValue: trueValue,
					falseValue: falseValue
				});
				return;
			}
		}

		if(el.nodeName.toLowerCase() === "select" && el.multiple) {
			new Multiselect(el, {
				value: value
			});
			return;
		}

		new Value(el,{value: value})
	});

	var special = {
		enter: function(data, el, original){
			return {
				event: "keyup",
				handler: function(ev){
					if(ev.keyCode == 13) {
						return original.call(this,ev)
					}
				}
			}
		}
	}

	/**
	 * @function can.view.bindings.can-EVENT can-EVENT
	 * @parent can.view.bindings
	 *
	 * @signature `can-EVENT='KEY'`
	 *
	 * Specify a callback function to be called on a particular event.
	 *
	 * @param {String} EVENT A event name like `click` or `keyup`.  If you are
	 * using jQuery, you can listen to jQuery special events too.
	 *
	 * @param {can.Mustache.key} key A named value in the current scope.  The value
	 * should be a function.
	 *
	 * @body
	 *
	 * ## Use
	 *
	 * By adding `can-EVENT='KEY'` to an element, the function pointed to
	 * by `KEY` is bound to the element's `EVENT` event. The function
	 * is called back with:
	 *
	 *  - `context` - the context of the element
	 *  - `element` - the element that was bound
	 *  - `event` - the event that was triggered
	 *
	 * @demo can/view/bindings/can-event.html
	 *
	 */
	can.view.Scanner.attribute(/can-[\w\.]+/,function(data, el){

		var attributeName = data.attr,
			event = data.attr.substr("can-".length),
			handler = function(ev){
				var attr = el.getAttribute(attributeName),
					scopeData = data.scope.read(attr,{returnObserveMethods: true, isArgument: true});
				return scopeData.value.call(scopeData.parent,data.scope._data, can.$(this), ev )
			};

		if(special[event]){
			var specialData = special[event](data, el, handler);
			handler = specialData.handler;
			event = specialData.event;
		}

		can.bind.call( el, event, handler);
	});

	var Value = can.Control.extend({
		init: function(){
			if(this.element[0].nodeName.toUpperCase() === "SELECT"){
				// need to wait until end of turn ...
				setTimeout($.proxy(this.set,this),1)
			} else {
				this.set()
			}

		},
		"{value} change": "set",
		set: function(){
			this.element[0].value = this.options.value()
		},
		"change": function(){
			this.options.value(this.element[0].value)
		}
	}), Checked = can.Control.extend({
		init: function(){
			this.isCheckebox = (this.element[0].type.toLowerCase() == "checkbox");
			this.check()
		},
		"{value} change": "check",
		"{trueValue} change": "check",
		"{falseValue} change": "check",
		check: function(){
			if(this.isCheckebox){
				var value =  this.options.value(),
					trueValue = this.options.trueValue() || true,
					falseValue = this.options.falseValue() || false;

				this.element[0].checked = ( value == trueValue )
			} else {
				if(this.options.value() === this.element[0].value){
					this.element[0].checked = true //.prop("checked", true)
				} else {
					this.element[0].checked = false //.prop("checked", false)
				}
			}

		},
		"change": function(){

			if(this.isCheckebox){
				this.options.value( this.element[0].checked? this.options.trueValue() : this.options.falseValue() );
			} else {
				if(this.element[0].checked){
					this.options.value( this.element[0].value );
				}
			}

		}
	}), Multiselect = Value.extend({
		init: function() {
			this.set();
		},

		_set: function(newVal){
			var selectedItem = this.element.find("option[value='" + newVal + "']");

			if(selectedItem.length && !selectedItem.is(':selected')) {
				selectedItem.attr('selected', 'selected');
			}
		},

		set: function() {
			var newVal = this.options.value(), self = this;

			//unset every option
			this.element.find('option').removeAttr('selected');

			//reselect the newly selected options
			can.each(can.makeArray(newVal), function(id){
				self._set(id);
			});
		},

		get: function(){
			var arr = this.element.find('option:selected')
				.map(function(){
					return this.value;
				});

			return can.makeArray(arr);
		},

		'change': function() {
			this.options.value(this.get());
		}
	})

})
<|endoftext|>


<commit_before>angular.module('movieTemplate',[])
.constant('movie','/api/agent/moviesShow/')
.constant('movieNew','/api/agent/moviesShowNew/')
.directive('myMovie',function($location,$resource,movie,movieNew){
	return{
		scope:{
			movieAll:'=movieAll'
		},
		link:function(scope,element,attrs){
			var head=document.querySelectorAll('head')[0]
			var headEle=angular.element(head)
			var titleEle=angular.element('<title>')
			var absurl=$location.absUrl()

			var width=document.documentElement.clientWidth||document.body.clientWidth,	// 获取页面宽度
			designWidth=952,		// 设计时的宽度
			differ=(parseInt(width)-designWidth)/2,	// 获取当前页面宽度与设计宽度的差值
			leftPersent=(differ/width)*100+'%'
			movieBox=document.querySelectorAll('.movieBox')[0],
			movieBoxEle=angular.element(movieBox)

			movieBoxEle.attr('style','left:'+leftPersent)

			var count=absurl.match(/\/\d+/g)[0].match(/\d+/g)[0]

			var newOrOld=absurl.match(/\/\D+\//g)[0].match(/\w+/g)[0]

			if(newOrOld=='moviesShow'){
				scope.movieResource=$resource(movie+count)
			}else{
				scope.movieResource=$resource(movieNew+count)
			}

			scope.movieResource.query().$promise.then(function(data){
				scope.movie=data[0]
				titleEle.text(scope.movie.name)
				headEle.append(titleEle)
			})

		},
		templateUrl:'../views/components/templates/movie.ejs'
	}
})<commit_msg>change<commit_after>angular.module('movieTemplate',[])
.constant('movie','/api/agent/moviesShow/')
.constant('movieNew','/api/agent/moviesShowNew/')
.directive('myMovie',function($location,$resource,movie,movieNew){
	return{
		scope:{
			movieAll:'=movieAll'
		},
		link:function(scope,element,attrs){
			var head=document.querySelectorAll('head')[0]
			var headEle=angular.element(head)
			var titleEle=angular.element('<title>')
			var absurl=$location.absUrl()

			var width=document.documentElement.clientWidth||document.body.clientWidth,	// 获取页面宽度
			designWidth=952,		// 设计时的宽度
			differ=(parseInt(width)-designWidth)/2,	// 获取当前页面宽度与设计宽度的差值
			leftPersent=(differ/width)*100+'%'
			movieBox=document.querySelectorAll('.movieBox')[0],
			movieBoxEle=angular.element(movieBox)

			movieBoxEle.attr('style','left:'+leftPersent)

			var count=absurl.match(/\/\d+/g)[0].match(/\d+/g)[0]

			var newOrOld=absurl.match(/\/\D+\//g)[0].match(/\w+/g)[0]

			if(newOrOld=='moviesShow'){
				scope.movieResource=$resource(movie+count)
			}else{
				scope.movieResource=$resource(movieNew+count)
			}

			scope.movieResource.query().$promise.then(function(data){
				console.log(data)
				scope.movie=data[0]
				titleEle.text(scope.movie.name)
				headEle.append(titleEle)
			})

		},
		templateUrl:'../views/components/templates/movie.ejs'
	}
})<|endoftext|>


<commit_before>/**
 * Copyright (c) 2014-2016, CKSource - Frederico Knabben. All rights reserved.
 * Licensed under the terms of the MIT License (see LICENSE.md).
 */

// Note: This automatic widget to dialog window binding (the fact that every field is set up from the widget
// and is committed to the widget) is only possible when the dialog is opened by the Widgets System
// (i.e. the widgetDef.dialog property is set).
// When you are opening the dialog window by yourself, you need to take care of this by yourself too.

CKEDITOR.dialog.add( 'ckrlite', function( editor ) {
	return {
		title: 'rlite widget editor',
		minWidth: 800,
		minHeight: 150,
		contents: [
			{
				id: 'info',
				elements: [
				    {
						id:'functions',
    					type: 'hbox',
   	 					widths: [ '25%', '25%', '25%', '25%' ],
    					children: [
        							{
            							type: 'button',
            							id: 'setformat',
            							label: 'Format',
            							onClick: function(){
            								// calculate and reset the Format
            								var widget = this.getDialog().widget;
            								var content = this.getDialog().getContentElement('info',
            																			'content').getValue();
            								var format = widget.resetFormat(JSON.parse(content));
            								this.getDialog().getContentElement('info','format').setValue(format);
            								widget.editor.ckrlite.format[widget.ckrlite.id]=format;
            							}
        							},
        							{
            							type: 'button',
            							id: 'setTemplate',
            							label: 'Template',
            							onClick: function(){
            								// calculate and reset the Format
            								var widget = this.getDialog().widget;
            								var format = this.getDialog().getContentElement('info',
            																				'format').getValue();
            								var type = this.getDialog().getContentElement('info',
            																				'type').getValue();
            								var template = widget.resetTemplate(format,type);
            								this.getDialog().getContentElement('info',
            																	'template').setValue(template);
            								widget.editor.ckrlite.template[widget.ckrlite.id]=template;
            							}
        							},
        							{
            							type: 'button',
            							id: 'render',
            							label: 'Render',
            							onClick: function(){
            								var widget = this.getDialog().widget;
            								widget.refresh();
            							}
        							},
        							 {
                    					type: 'html',
                    					html: '',
                    					id: 'htmlid',
                    					lable: 'ID',
                    					setup: function( widget ){
											var id = widget.ckrlite.id;
											var html = this.getDialog().getContentElement('info','htmlid');
											html.getElement().$.innerText="ref:"+id;
										}
               						 }
    								]
					},
				    {
						id:'references',
    					type: 'hbox',
   	 					widths: [ '25%', '25%' , '25%' , '25%'],
    					children: [
							{
								id: 'table',
								type: 'text',
								label: 'table',
								width: '250px',
								setup: function( widget ) {
									var eckrlite = widget.editor.ckrlite;
									var wckrlite = widget.ckrlite;
									if(eckrlite.dataset[wckrlite.id].select.table!=undefined)
										this.setValue( eckrlite.dataset[wckrlite.id].select.table );
								},
								commit: function( widget ) {
									// persist
									widget.editor.ckrlite.dataset[widget.ckrlite.id].select.table=this.getValue();
								},
								onChange: function(api){
									var widget = this.getDialog().widget;
									widget.editor.ckrlite.dataset[widget.ckrlite.id].select.table=this.getValue();
									// just update content from ArrestDB (not all editor's widgets)
									var uri = root.uri+root.adb+
									       widget.editor.ckrlite.dataset[widget.ckrlite.id].select.table+"/"+
									       widget.editor.ckrlite.dataset[widget.ckrlite.id].select.column+"/"+
									       widget.editor.ckrlite.dataset[widget.ckrlite.id].select.id;
									widget.editor.ckrlite.dataset[widget.ckrlite.id].content =
												CKEDITOR.restajax.getjson(uri);
									this.getDialog().getContentElement('info','content').setValue(JSON.stringify(
									          widget.editor.ckrlite.dataset[widget.ckrlite.id].content
									       ));

								}
							},
							{
								id: 'column',
								type: 'text',
								label: 'column',
								width: '250px',
								setup: function( widget ) {
									var eckrlite = widget.editor.ckrlite;
									var wckrlite = widget.ckrlite;
									if(eckrlite.dataset[wckrlite.id].select.column!=undefined)
										this.setValue( eckrlite.dataset[wckrlite.id].select.column );
								},
								commit: function( widget ) {
									// persist
								  widget.editor.ckrlite.dataset[widget.ckrlite.id].select.column=this.getValue();
								},
								onChange: function(api){
									var widget = this.getDialog().widget;

								}
							},
							{
								id: 'id',
								type: 'text',
								label: 'id',
								width: '250px',
								setup: function( widget ) {
									var eckrlite = widget.editor.ckrlite;
									var wckrlite = widget.ckrlite;
									if(eckrlite.dataset[wckrlite.id].select.id!=undefined)
										this.setValue( eckrlite.dataset[wckrlite.id].select.id );
								},
								commit: function( widget ) {
									// persist
								  widget.editor.ckrlite.dataset[widget.ckrlite.id].select.id=this.getValue();
								},
								onChange: function(api){
									var widget = this.getDialog().widget;
								}
							}
					    ]
					},
					{
						id: 'content',
						type: 'textarea',
						label: 'ArrestDB Content',
						'default':'',
						setup: function( widget ) {
						},
						commit: function( widget ) {
						}
					},
					{
						id: 'format',
						type: 'textarea',
						label: 'Format',
						'default':'',
						setup: function( widget ) {
							var eckrlite = widget.editor.ckrlite;
							var wckrlite = widget.ckrlite;
							if(eckrlite.format[wckrlite.id]!=undefined)
								this.setValue( eckrlite.format[wckrlite.id] );
						},
						commit: function( widget ) {
						}
					},
					{
						id: 'template',
						type: 'textarea',
						label: 'Template',
						'default':'',
						setup: function( widget ) {
							var eckrlite = widget.editor.ckrlite;
							var wckrlite = widget.ckrlite;
							if(eckrlite.template[wckrlite.id]!=undefined)
								this.setValue( eckrlite.template[wckrlite.id] );
						},
						commit: function( widget ) {
						},
						onChange: function(api){
						}
					},
					{
						id: 'type',
						type: 'radio',
						label: 'Type',
						items: [
							[ 'horizontal', 'horizontal' ],
							[ 'vertical', 'vertical' ],
						],
						'default':'horizontal',
						// When setting up this field, set its value to the "type" value from widget data.
						setup: function( widget ) {
						},
						// When committing (saving) this field, set its value to the widget data.
						commit: function( widget ) {
						}
					},
					{
						id:'positionning',
    					type: 'hbox',
   	 					widths: [ '50%', '50%' ],
    					children: [
							{
								id: 'align',
								type: 'select',
								label: 'Align',
								items: [
									[ editor.lang.common.notSet, '' ],
									[ editor.lang.common.alignLeft, 'left' ],
									[ editor.lang.common.alignRight, 'right' ],
									[ editor.lang.common.alignCenter, 'center' ]
								],
								// When setting up this field, set its value to the "align"
								// value from widget data.
								// Note: Align values used in the widget need to be
								// the same as those defined in the "items" array above.
								setup: function( widget ) {
								this.setValue( widget.data.align );

								},
								// When committing (saving) this field, set its value to the widget data.
								commit: function( widget ) {
									widget.setData( 'align', this.getValue() );
								}
							},
							{
								id: 'width',
								type: 'text',
								label: 'Width',
								width: '50px',
								setup: function( widget ) {
									this.setValue( widget.data.width );
								},
								commit: function( widget ) {
									widget.setData( 'width', this.getValue() );
								}
							}
					]
					}
				]
			}
		]
	};
} );
<commit_msg>update item saving (bug)<commit_after>/**
 * Copyright (c) 2014-2016, CKSource - Frederico Knabben. All rights reserved.
 * Licensed under the terms of the MIT License (see LICENSE.md).
 */

// Note: This automatic widget to dialog window binding (the fact that every field is set up from the widget
// and is committed to the widget) is only possible when the dialog is opened by the Widgets System
// (i.e. the widgetDef.dialog property is set).
// When you are opening the dialog window by yourself, you need to take care of this by yourself too.

CKEDITOR.dialog.add( 'ckrlite', function( editor ) {
	return {
		title: 'rlite widget editor',
		minWidth: 800,
		minHeight: 150,
		contents: [
			{
				id: 'info',
				elements: [
				    {
						id:'functions',
    					type: 'hbox',
   	 					widths: [ '25%', '25%', '25%', '25%' ],
    					children: [
        							{
            							type: 'button',
            							id: 'setformat',
            							label: 'Format',
            							onClick: function(){
            								// calculate and reset the Format
            								var widget = this.getDialog().widget;
            								var content = this.getDialog().getContentElement('info',
            																			'content').getValue();
            								var format = widget.resetFormat(JSON.parse(content));
            								this.getDialog().getContentElement('info','format').setValue(format);
            								widget.editor.ckrlite.format[widget.ckrlite.id]=format;
            							}
        							},
        							{
            							type: 'button',
            							id: 'setTemplate',
            							label: 'Template',
            							onClick: function(){
            								// calculate and reset the Format
            								var widget = this.getDialog().widget;
            								var format = this.getDialog().getContentElement('info',
            																				'format').getValue();
            								var type = this.getDialog().getContentElement('info',
            																				'type').getValue();
            								var template = widget.resetTemplate(format,type);
            								this.getDialog().getContentElement('info',
            																	'template').setValue(template);
            								widget.editor.ckrlite.template[widget.ckrlite.id]=template;
            							}
        							},
        							{
            							type: 'button',
            							id: 'render',
            							label: 'Render',
            							onClick: function(){
            								var widget = this.getDialog().widget;
            								widget.refresh();
            							}
        							},
        							 {
                    					type: 'html',
                    					html: '',
                    					id: 'htmlid',
                    					lable: 'ID',
                    					setup: function( widget ){
											var id = widget.ckrlite.id;
											var html = this.getDialog().getContentElement('info','htmlid');
											html.getElement().$.innerText="ref:"+id;
										}
               						 }
    								]
					},
				    {
						id:'references',
    					type: 'hbox',
   	 					widths: [ '25%', '25%' , '25%' , '25%'],
    					children: [
							{
								id: 'table',
								type: 'text',
								label: 'table',
								width: '250px',
								setup: function( widget ) {
									var eckrlite = widget.editor.ckrlite;
									var wckrlite = widget.ckrlite;
									if(eckrlite.dataset[wckrlite.id].select.table!=undefined)
										this.setValue( eckrlite.dataset[wckrlite.id].select.table );
								},
								commit: function( widget ) {
									// persist
									widget.editor.ckrlite.dataset[widget.ckrlite.id].select.table=this.getValue();
								},
								onChange: function(api){
									var widget = this.getDialog().widget;
									widget.editor.ckrlite.dataset[widget.ckrlite.id].select.table=this.getValue();
									// just update content from ArrestDB (not all editor's widgets)
									var uri = root.uri+root.adb+
									       widget.editor.ckrlite.dataset[widget.ckrlite.id].select.table+"/"+
									       widget.editor.ckrlite.dataset[widget.ckrlite.id].select.column+"/"+
									       widget.editor.ckrlite.dataset[widget.ckrlite.id].select.id;
									widget.editor.ckrlite.dataset[widget.ckrlite.id].content =
												CKEDITOR.restajax.getjson(uri);
									this.getDialog().getContentElement('info','content').setValue(JSON.stringify(
									          widget.editor.ckrlite.dataset[widget.ckrlite.id].content
									       ));

								}
							},
							{
								id: 'column',
								type: 'text',
								label: 'column',
								width: '250px',
								setup: function( widget ) {
									var eckrlite = widget.editor.ckrlite;
									var wckrlite = widget.ckrlite;
									if(eckrlite.dataset[wckrlite.id].select.column!=undefined)
										this.setValue( eckrlite.dataset[wckrlite.id].select.column );
								},
								commit: function( widget ) {
									// persist
								  widget.editor.ckrlite.dataset[widget.ckrlite.id].select.column=this.getValue();
								},
								onChange: function(api){
									var widget = this.getDialog().widget;

								}
							},
							{
								id: 'id',
								type: 'text',
								label: 'id',
								width: '250px',
								setup: function( widget ) {
									var eckrlite = widget.editor.ckrlite;
									var wckrlite = widget.ckrlite;
									if(eckrlite.dataset[wckrlite.id].select.id!=undefined)
										this.setValue( eckrlite.dataset[wckrlite.id].select.id );
								},
								commit: function( widget ) {
									// persist
								  widget.editor.ckrlite.dataset[widget.ckrlite.id].select.id=this.getValue();
								},
								onChange: function(api){
									var widget = this.getDialog().widget;
								}
							}
					    ]
					},
					{
						id: 'content',
						type: 'textarea',
						label: 'ArrestDB Content',
						'default':'',
						setup: function( widget ) {
						},
						commit: function( widget ) {
						}
					},
					{
						id: 'format',
						type: 'textarea',
						label: 'Format',
						'default':'',
						setup: function( widget ) {
							var eckrlite = widget.editor.ckrlite;
							var wckrlite = widget.ckrlite;
							if(eckrlite.format[wckrlite.id]!=undefined)
								this.setValue( eckrlite.format[wckrlite.id] );
						},
						commit: function( widget ) {
							var eckrlite = widget.editor.ckrlite;
							var wckrlite = widget.ckrlite;
							eckrlite.format[wckrlite.id]=this.getValue();
						}
					},
					{
						id: 'template',
						type: 'textarea',
						label: 'Template',
						'default':'',
						setup: function( widget ) {
							var eckrlite = widget.editor.ckrlite;
							var wckrlite = widget.ckrlite;
							if(eckrlite.template[wckrlite.id]!=undefined)
								this.setValue( eckrlite.template[wckrlite.id] );
						},
						commit: function( widget ) {
							var eckrlite = widget.editor.ckrlite;
							var wckrlite = widget.ckrlite;
							eckrlite.template[wckrlite.id]=this.getValue();
						}
					},
					{
						id: 'type',
						type: 'radio',
						label: 'Type',
						items: [
							[ 'horizontal', 'horizontal' ],
							[ 'vertical', 'vertical' ],
						],
						'default':'horizontal',
						// When setting up this field, set its value to the "type" value from widget data.
						setup: function( widget ) {
						},
						// When committing (saving) this field, set its value to the widget data.
						commit: function( widget ) {
						}
					},
					{
						id:'positionning',
    					type: 'hbox',
   	 					widths: [ '50%', '50%' ],
    					children: [
							{
								id: 'align',
								type: 'select',
								label: 'Align',
								items: [
									[ editor.lang.common.notSet, '' ],
									[ editor.lang.common.alignLeft, 'left' ],
									[ editor.lang.common.alignRight, 'right' ],
									[ editor.lang.common.alignCenter, 'center' ]
								],
								// When setting up this field, set its value to the "align"
								// value from widget data.
								// Note: Align values used in the widget need to be
								// the same as those defined in the "items" array above.
								setup: function( widget ) {
								this.setValue( widget.data.align );

								},
								// When committing (saving) this field, set its value to the widget data.
								commit: function( widget ) {
									widget.setData( 'align', this.getValue() );
								}
							},
							{
								id: 'width',
								type: 'text',
								label: 'Width',
								width: '50px',
								setup: function( widget ) {
									this.setValue( widget.data.width );
								},
								commit: function( widget ) {
									widget.setData( 'width', this.getValue() );
								}
							}
					]
					}
				]
			}
		]
	};
} );
<|endoftext|>


<commit_before>/**
 * Custom component for BlockDropZone for being able to position inner blocks via drag and drop.
 * Parts of this are taken from the original BlockDropZone component.
 */

/**
 * WordPress dependencies
 */
import {
	DropZone,
} from '@wordpress/components';
import { Component } from '@wordpress/element';
import { withDispatch } from '@wordpress/data';
import {
	MediaUploadCheck,
} from '@wordpress/editor';

/**
 * Internal dependencies
 */
import { getPercentageFromPixels } from './../helpers';

const wrapperElSelector = 'div[data-amp-selected="parent"] .editor-inner-blocks';

class BlockDropZone extends Component {
	constructor() {
		super( ...arguments );

		this.onDrop = this.onDrop.bind( this );
	}

	onDrop( event ) {
		const { updateBlockAttributes, srcClientId } = this.props;

		const elementId = `block-${ srcClientId }`;
		const cloneElementId = `clone-block-${ srcClientId }`;
		const element = document.getElementById( elementId );
		const clone = document.getElementById( cloneElementId );

		// Get the editor wrapper element for calculating the width and height.
		const wrapperEl = document.querySelector( wrapperElSelector );
		if ( ! element || ! clone || ! wrapperEl ) {
			event.preventDefault();
			return;
		}

		// Get the current position of the clone.
		const clonePosition = clone.getBoundingClientRect();

		const wrapperPosition = wrapperEl.getBoundingClientRect();

		// We will set the new position based on where the clone was moved to, with reference being the wrapper element.
		// Lets take the % based on the wrapper for top and left.
		updateBlockAttributes( srcClientId, {
			positionLeft: getPercentageFromPixels( 'x', clonePosition.left - wrapperPosition.left ),
			positionTop: getPercentageFromPixels( 'y', clonePosition.top - wrapperPosition.top ),
		} );
	}

	render() {
		return (
			<MediaUploadCheck>
				<DropZone
					className="editor-block-drop-zone"
					onDrop={ this.onDrop }
				/>
			</MediaUploadCheck>
		);
	}
}
export default withDispatch( ( dispatch ) => {
	const { updateBlockAttributes } = dispatch( 'core/block-editor' );

	return {
		updateBlockAttributes( ...args ) {
			updateBlockAttributes( ...args );
		},
	};
} )( BlockDropZone );
<commit_msg>Remove errant MediaUploadCheck component<commit_after>/**
 * Custom component for BlockDropZone for being able to position inner blocks via drag and drop.
 * Parts of this are taken from the original BlockDropZone component.
 */

/**
 * WordPress dependencies
 */
import {
	DropZone,
} from '@wordpress/components';
import { Component } from '@wordpress/element';
import { withDispatch } from '@wordpress/data';

/**
 * Internal dependencies
 */
import { getPercentageFromPixels } from './../helpers';

const wrapperElSelector = 'div[data-amp-selected="parent"] .editor-inner-blocks';

class BlockDropZone extends Component {
	constructor() {
		super( ...arguments );

		this.onDrop = this.onDrop.bind( this );
	}

	onDrop( event ) {
		const { updateBlockAttributes, srcClientId } = this.props;

		const elementId = `block-${ srcClientId }`;
		const cloneElementId = `clone-block-${ srcClientId }`;
		const element = document.getElementById( elementId );
		const clone = document.getElementById( cloneElementId );

		// Get the editor wrapper element for calculating the width and height.
		const wrapperEl = document.querySelector( wrapperElSelector );
		if ( ! element || ! clone || ! wrapperEl ) {
			event.preventDefault();
			return;
		}

		// Get the current position of the clone.
		const clonePosition = clone.getBoundingClientRect();

		const wrapperPosition = wrapperEl.getBoundingClientRect();

		// We will set the new position based on where the clone was moved to, with reference being the wrapper element.
		// Lets take the % based on the wrapper for top and left.
		updateBlockAttributes( srcClientId, {
			positionLeft: getPercentageFromPixels( 'x', clonePosition.left - wrapperPosition.left ),
			positionTop: getPercentageFromPixels( 'y', clonePosition.top - wrapperPosition.top ),
		} );
	}

	render() {
		return (
			<DropZone
				className="editor-block-drop-zone"
				onDrop={ this.onDrop }
			/>
		);
	}
}
export default withDispatch( ( dispatch ) => {
	const { updateBlockAttributes } = dispatch( 'core/block-editor' );

	return {
		updateBlockAttributes( ...args ) {
			updateBlockAttributes( ...args );
		},
	};
} )( BlockDropZone );
<|endoftext|>


<commit_before>/* global c3 */
import Ember from 'ember';
import ENV from 'analytics-dashboard/config/environment';

const NIH_LABELS = {
  'fogarty international center': 'FIC',
  'national center for advancing translational sciences': 'NCATS',
  'national center for complementary and integrative health': 'NCCIH',
  'national cancer institute': 'NCI',
  'national eye institute': 'NEI',
  'national human genome research institute': 'NHGRI',
  'national heart': 'NHLBI',
  'national institute on aging': 'NIA',
  'national institute on alcohol abuse and alcoholism': 'NIAAA',
  'national institute of allergy and infectious diseases': 'NIAID',
  'national institute of arthritis and musculoskeletal and skin diseases': 'NIAMS',
  'national institute of biomedical imaging and bioengineering': 'NIBIB',
  'national institute of child health and human development': 'NICHD',
  'national institute on drug abuse': 'NIDA',
  'national institute on deafness and other communication disorders': 'NIDCD',
  'national institute of dental and craniofacial research': 'NIDCR',
  'national institute of diabetes and digestive and kidney diseases': 'NIDDK',
  'national institute of environmental health sciences': 'NIEHS',
  'national institute of general medical sciences': 'NIGMS',
  'national institute of mental health': 'NIMH',
  'national institute of neurological disorders and stroke': 'NINDS',
  'national institute of nursing research': 'NINR',
  'national library of medicine': 'NLM',
  'office of the director': 'OD'
};

function log10ToLinear(log_num) {
    if (log_num <= 0) {
        return 0;
    }
    return Math.pow(10, log_num-1).toFixed(0);
}

function linearToLog10(lin_num) {
    if (lin_num <= 0) {
        return 0;
    }
    return (Math.log(lin_num) / Math.LN10) + 1;
}

function getLabel(label) {
    if (NIH_LABELS[label.toLowerCase()]) {
        return NIH_LABELS[label.toLowerCase()];
    }
    return label;
}

export default Ember.Component.extend({

    classNames: ['chart'],
    charttitle: 'Untitled Chart',

    dataChanged: Ember.observer('data', function() {
        this.updateChart();
    }),

    dataChanged2: Ember.observer('data.[]', function() {
        this.updateChart();
    }),

    data: [],

    init() {
        this._super(...arguments);
        if (this.get('name') === 'Data Providers') {
            this.processData(this.get("aggregations.publishers.buckets"))
        }
        if (this.get('name') === "Awards") {
            this.processData(this.get('aggregations.funders.buckets'));
        }
    },

    processData: async function(data) {
        if (this.get('name') === 'Data Providers') {
            this.set("data",
                await Ember.RSVP.Promise.all(
                    data.map(async function(datum, index, array) {
                        let agent_info = await Ember.$.ajax({
                            url: ENV.apiUrl + '/search/agents/' + datum.key,
                            crossDomain: true,
                            type: 'GET',
                            contentType: 'application/json',
                        });
                        data[index]._source = agent_info._source;
                        data[index].doc_count = data[index].doc_count;
                        data[index].key = data[index].key;
                        return data[index];
                    })
                )
            );
        }
        if (this.get('name') === "Awards") {
            data =  data.map(function(datum) {
                datum._source = {
                    id: datum.key,
                    name: datum.key
                };
                return datum;
            });
            this.set('data', await data);
        }

    },

    sizeChanged: Ember.observer('resizedSignal', function() {
        if (this.get('resizedSignal') === false) { return; }
        this.updateChart();
        this.set('resizedSignal', false);
    }),

    charTypeChange: Ember.observer('chartType', function(){
        this.updateChart();
    }),

    updateChart: async function() {

        var self = this;

        let chart_type = this.get('chartType');

        let chart_options = {
            bindto: this.$(this.element).find('.renderChart')[0],
            data: {
                columns: null, //to be filled later
                type: chart_type,
                onclick: (d) => {
                    self.get('actions').transitionToFacet.call(self, d.id);
                },
            },
            legend: { show: false },
            [chart_type]: {
                title: this.get('charttitle'),  //to be filled later
                label: {
                    show: false
                }
            },
        };

        if (chart_type == 'donut') {
            var title = '';

            var _data = this.get('data');

            if (this.get('data').length === 0 && this.get('name') === 'Data Providers') {
                var key = 'UC San Diego Library';
                var data = [{
                   'key': '64201-BDE-4D4',
                   'doc_count': 55,
                   '_source': {
                      'id': '64201-BDE-4D4',
                      'name': key
                   }
                }];
                this.set('data', data);
            }

            if (this.get('item.mappingType') === 'OBJECT_TO_ARRAY') {
                var columns = this.get('data').map(({ key, doc_count }) => [key, doc_count]);
            }

            if (this.get('item.mappingType') === 'OBJECT_AWARDS_NESTED_VALUE_TO_ARRAY') {
                var columns = this.get('data').map(({ key, doc_count, awards }) => [key, awards.value]);
            }

            chart_options['tooltip'] = {
                format: { // We want to return a nice-looking tooltip whose content is determined by (or at least consistent with) sour TS intervals
                    name: function (id, percentage) {
                        return self.data.reduce(function(acc, cur, idx, arr) {
                            if (cur._source.id === id) {
                                return cur._source.name;
                            }
                            return acc;
                        }, false);
                    },
                    value: function (value, percent, id) {
                        var units = self.get('name') === 'Awards' ? 'dollars' : 'records';
                        return Math.floor(percent*100) + "% (" + value + " " + units; // This isn't perfect, but it's at least more verbose than before
                    }
                }
            };

            chart_options['donut'].width = 100;

        } else if (chart_type === 'bar') {

            this.set('data', this.get('aggregations.contributors.buckets'));
            var columns = this.get('data').map(({ key, doc_count }) => [key, doc_count]).slice(0, 10);

            chart_options['axis'] = {
                x: {
                    tick: {
                        format: function() {
                            return 'Top 10 Contributors';
                        }
                    }
                },
                y: {
                     label: 'Number of Publications'
                },
            };
            chart_options['tooltip'] = {
                grouped: false, // Default true
            };
            chart_options['tooltip'] = tooltip;

        } else if (chart_type === 'relevanceHistogram') {

            let UC_hits = this.get('aggregations.filtered_score.buckets.institution.doc_count')
            let total_hits = this.get('total')
            var columns = [
                ['overallCountByRelevance'].concat(this.get('data.aggregations.all_score.buckets').map((datum) => {
                    let val = this.get('aggregations.all_score.buckets')[datum.key];
                    if (val && val.doc_count > 0) { return val.doc_count * UC_hits / total_hits; }
                    return 0;
                })),
                ['ucCountByRelevance'].concat(this.get('aggregations.all_score.buckets').map((datum) => {
                    let val = this.get('aggregations.filtered_score.buckets.institution.score.buckets')[datum.key];
                    if (val && val.doc_count > 0) { return val.doc_count; }
                    return 0;
                })),
            ];

            chart_options['axis'] = {
                x: {
                    tick: {
                        format: function(val) {
                            return val;
                        }
                    },
                    label: 'Relevance Score'
                },
                y: {
                    tick: {
                        format: function (d) { return d; }
                    },
                    label: 'Number of Items'
                }
            };

            chart_options['data']['types'] = {
                x: 'bar',
                overallCountByRelevance: 'bar',
                doeCountByRelevance: 'bar',
                ucCountByRelevance: 'bar'
            };

            chart_options['data']['labels'] = {
                //labels: {
                //    format: {
                //        overallCountByRelevance: function(d,id){console.log(id, Math.pow(10,d));return Math.pow(10,d).toFixed(0);},
                //        institutionCountByRelevance: function(d,id){console.log(id, Math.pow(10,d));return Math.pow(10,d).toFixed(0);}
                //    }
                //}
            };

            chart_options['point'] = {show: false};

        } else if (chart_type === 'timeseries') {

            let x_axis = this.get('data.aggregations.all_over_time.buckets').map((datum) => { return datum.key_as_string; });
            var columns = this.get('data.aggregations.sorted_by_type.buckets').map((bucket) => {
                return [bucket.key].concat(bucket['type_over_time'].buckets.reduce((ret, bucket) => {
                    ret[x_axis.indexOf(bucket.key_as_string)] = linearToLog10(bucket.doc_count);
                    return ret;
                }, (new Array(x_axis.length)).fill(0)));
            });
            columns.unshift(['x'].concat(x_axis));
            columns.unshift(['All Events'].concat(this.get('data.aggregations.all_over_time.buckets').map((bucket) => {
                return linearToLog10(bucket.doc_count);
            })));
            let data_x = 'x';
            chart_options['axis'] = {
                x: {
                    type: 'timeseries',
                    tick: {
                        culling: {
                            max: 10
                        },
                        rotate: 90,
                        format: '%d-%m-%Y' // Format the tick labels on our chart
                    }
                },
                y: {
                    min: 1,
                    tick: {
                        format: log10ToLinear
                    },
                    label: 'Number of Items (Log Scale)'
                }
            };
            let data_types = columns.reduce((r, c, i, a) => {
                r[c[0]] = 'area-spline';
                return r;
            }, {});
            chart_options['tooltip'] = {
                format: { // We want to return a nice-looking tooltip whose content is determined by (or at least consistent with) sour TS intervals
                    title: function (d) {
                        return d.toString().substring(4,15); // This isn't perfect, but it's at least more verbose than before
                    }
                }
            };

            let point = {
                show: false,
            };

            chart_options['data']['types'] = data_types;
            chart_options['data']['x'] = data_x;
            chart_options['legend'] = { position: "right" };
            chart_options['point'] = point;

        }

        chart_options['data']['columns'] = columns;
        chart_options[chart_type]['title'] = title;
        this.set('chart', c3.generate(chart_options));

        if (chart_type === "donut") {
            var labels = d3.selectAll(this.$(this.element).find('.c3-chart-arc')).select(function(d) {
                let angle_size = d.endAngle - d.startAngle;
                if (angle_size < 0.5) {
                    return;
                }
                d3.select(this.parentNode).append('text')
                    .text(self.data.reduce(function(acc, cur, idx, arr) {
                        var string;
                        if (cur._source.id === d.data.id) {
                            if (self.get('name') === 'Awards') {
                               string = getLabel(cur._source.id);
                            } else if (cur._source.name) {
                                string = cur._source.name
                            } else {
                                string = cur._source.id;
                            }
                            if (string.length > 38) {
                                return string.substring(0,25) + "...";
                            }
                            return string;
                        }
                        return acc;
                    }, false))
                    .attr("x", 160*Math.sin((d.startAngle + d.endAngle)/2))
                    .attr("y", -130*Math.cos((d.startAngle + d.endAngle)/2))
                    .attr("text-anchor", "middle")
                    .attr("alignment-baseline", "central")
                    .attr("font-size", "12px")
                    .attr("fill", "rgb(250,250,250)")
                    .each(function(d) {
                        var rect = document.createElementNS("http://www.w3.org/2000/svg","rect");
                        this.parentNode.insertBefore(rect, this);
                        let bbox = this.getBBox();
                        d3.select(rect)
                            .attr("fill", "rgba(0,0,0,0.5)")
                            .attr("stroke", "rgba(0,0,0,0.6)")
                            .attr("width", bbox.width + 14)
                            .attr("height", bbox.height + 8)
                            .attr("x", bbox.x - 7)
                            .attr("y", bbox.y - 4)
                    })
            });
            /*var labels_bgs = d3.selectAll(this.$(this.element).find('.c3-chart-arc'))
                .insert('rect', 'text')
                .each(function(d) {
                    d.attr("width", 200).attr("height", 20)
                })

            labels.select(function() {
            });*/
        }

    },

    didRender() {
        //this.updateChart();
    },

    actions: {

        transitionToFacet(id, override) { //Two different items here; one refers to the widget; one refers to the datum.
            override = override || false;
            let queryParams = {};
            let data = this.get('data');
            let item = data.reduce((acc, cur, idx, arr) => {
                if (cur._source.id === id) {
                    return cur;
                }
                return acc;
            }, false);
            var facet = this.get("item.facetDashParameter");
            var facetDash = this.get("item.facetDash");
            if(override){
                facetDash = override;
            }
            if (facetDash === "url" && item.url) {
                window.location.href = item.url;
                return;
            }
            if (facet) {
                queryParams[facet] = item.name;
                if (item._source.types.indexOf("agent") > -1) {
                    queryParams[facet] = item._source.id;
                }
                this.attrs.transitionToFacet(facetDash, queryParams);
            }
        },
    }

});
<commit_msg>Format dollar figures in awards widget<commit_after>/* global c3 */
import Ember from 'ember';
import ENV from 'analytics-dashboard/config/environment';

const NIH_LABELS = {
  'fogarty international center': 'FIC',
  'national center for advancing translational sciences': 'NCATS',
  'national center for complementary and integrative health': 'NCCIH',
  'national cancer institute': 'NCI',
  'national eye institute': 'NEI',
  'national human genome research institute': 'NHGRI',
  'national heart': 'NHLBI',
  'national institute on aging': 'NIA',
  'national institute on alcohol abuse and alcoholism': 'NIAAA',
  'national institute of allergy and infectious diseases': 'NIAID',
  'national institute of arthritis and musculoskeletal and skin diseases': 'NIAMS',
  'national institute of biomedical imaging and bioengineering': 'NIBIB',
  'national institute of child health and human development': 'NICHD',
  'national institute on drug abuse': 'NIDA',
  'national institute on deafness and other communication disorders': 'NIDCD',
  'national institute of dental and craniofacial research': 'NIDCR',
  'national institute of diabetes and digestive and kidney diseases': 'NIDDK',
  'national institute of environmental health sciences': 'NIEHS',
  'national institute of general medical sciences': 'NIGMS',
  'national institute of mental health': 'NIMH',
  'national institute of neurological disorders and stroke': 'NINDS',
  'national institute of nursing research': 'NINR',
  'national library of medicine': 'NLM',
  'office of the director': 'OD'
};

function log10ToLinear(log_num) {
    if (log_num <= 0) {
        return 0;
    }
    return Math.pow(10, log_num-1).toFixed(0);
}

function linearToLog10(lin_num) {
    if (lin_num <= 0) {
        return 0;
    }
    return (Math.log(lin_num) / Math.LN10) + 1;
}

function getLabel(label) {
    if (NIH_LABELS[label.toLowerCase()]) {
        return NIH_LABELS[label.toLowerCase()];
    }
    return label;
}

export default Ember.Component.extend({

    classNames: ['chart'],
    charttitle: 'Untitled Chart',

    dataChanged: Ember.observer('data', function() {
        this.updateChart();
    }),

    dataChanged2: Ember.observer('data.[]', function() {
        this.updateChart();
    }),

    data: [],

    init() {
        this._super(...arguments);
        if (this.get('name') === 'Data Providers') {
            this.processData(this.get("aggregations.publishers.buckets"))
        }
        if (this.get('name') === "Awards") {
            this.processData(this.get('aggregations.funders.buckets'));
        }
    },

    processData: async function(data) {
        if (this.get('name') === 'Data Providers') {
            this.set("data",
                await Ember.RSVP.Promise.all(
                    data.map(async function(datum, index, array) {
                        let agent_info = await Ember.$.ajax({
                            url: ENV.apiUrl + '/search/agents/' + datum.key,
                            crossDomain: true,
                            type: 'GET',
                            contentType: 'application/json',
                        });
                        data[index]._source = agent_info._source;
                        data[index].doc_count = data[index].doc_count;
                        data[index].key = data[index].key;
                        return data[index];
                    })
                )
            );
        }
        if (this.get('name') === "Awards") {
            data =  data.map(function(datum) {
                datum._source = {
                    id: datum.key,
                    name: datum.key
                };
                return datum;
            });
            this.set('data', await data);
        }

    },

    sizeChanged: Ember.observer('resizedSignal', function() {
        if (this.get('resizedSignal') === false) { return; }
        this.updateChart();
        this.set('resizedSignal', false);
    }),

    charTypeChange: Ember.observer('chartType', function(){
        this.updateChart();
    }),

    updateChart: async function() {

        var self = this;

        let chart_type = this.get('chartType');

        let chart_options = {
            bindto: this.$(this.element).find('.renderChart')[0],
            data: {
                columns: null, //to be filled later
                type: chart_type,
                onclick: (d) => {
                    self.get('actions').transitionToFacet.call(self, d.id);
                },
            },
            legend: { show: false },
            [chart_type]: {
                title: this.get('charttitle'),  //to be filled later
                label: {
                    show: false
                }
            },
        };

        if (chart_type == 'donut') {
            var title = '';

            var _data = this.get('data');

            if (this.get('data').length === 0 && this.get('name') === 'Data Providers') {
                var key = 'UC San Diego Library';
                var data = [{
                   'key': '64201-BDE-4D4',
                   'doc_count': 55,
                   '_source': {
                      'id': '64201-BDE-4D4',
                      'name': key
                   }
                }];
                this.set('data', data);
            }

            if (this.get('item.mappingType') === 'OBJECT_TO_ARRAY') {
                var columns = this.get('data').map(({ key, doc_count }) => [key, doc_count]);
            }

            if (this.get('item.mappingType') === 'OBJECT_AWARDS_NESTED_VALUE_TO_ARRAY') {
                var columns = this.get('data').map(({ key, doc_count, awards }) => [key, awards.value]);
            }

            chart_options['tooltip'] = {
                format: { // We want to return a nice-looking tooltip whose content is determined by (or at least consistent with) sour TS intervals
                    name: function (id, percentage) {
                        return self.data.reduce(function(acc, cur, idx, arr) {
                            if (cur._source.id === id) {
                                return cur._source.name;
                            }
                            return acc;
                        }, false);
                    },
                    value: function (value, percent, id) {
                        var percentage = Math.floor(percent*100);
                        if (self.get('name') === 'Awards') {
                            var formatted = value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
                            return percentage + "% ($" + formatted + ")";
                        }
                        return percentage + "% (" + value + " records)"; // This isn't perfect, but it's at least more verbose than before
                    }
                }
            };

            chart_options['donut'].width = 100;

        } else if (chart_type === 'bar') {

            this.set('data', this.get('aggregations.contributors.buckets'));
            var columns = this.get('data').map(({ key, doc_count }) => [key, doc_count]).slice(0, 10);

            chart_options['axis'] = {
                x: {
                    tick: {
                        format: function() {
                            return 'Top 10 Contributors';
                        }
                    }
                },
                y: {
                     label: 'Number of Publications'
                },
            };
            chart_options['tooltip'] = {
                grouped: false, // Default true
            };
            chart_options['tooltip'] = tooltip;

        } else if (chart_type === 'relevanceHistogram') {

            let UC_hits = this.get('aggregations.filtered_score.buckets.institution.doc_count')
            let total_hits = this.get('total')
            var columns = [
                ['overallCountByRelevance'].concat(this.get('data.aggregations.all_score.buckets').map((datum) => {
                    let val = this.get('aggregations.all_score.buckets')[datum.key];
                    if (val && val.doc_count > 0) { return val.doc_count * UC_hits / total_hits; }
                    return 0;
                })),
                ['ucCountByRelevance'].concat(this.get('aggregations.all_score.buckets').map((datum) => {
                    let val = this.get('aggregations.filtered_score.buckets.institution.score.buckets')[datum.key];
                    if (val && val.doc_count > 0) { return val.doc_count; }
                    return 0;
                })),
            ];

            chart_options['axis'] = {
                x: {
                    tick: {
                        format: function(val) {
                            return val;
                        }
                    },
                    label: 'Relevance Score'
                },
                y: {
                    tick: {
                        format: function (d) { return d; }
                    },
                    label: 'Number of Items'
                }
            };

            chart_options['data']['types'] = {
                x: 'bar',
                overallCountByRelevance: 'bar',
                doeCountByRelevance: 'bar',
                ucCountByRelevance: 'bar'
            };

            chart_options['data']['labels'] = {
                //labels: {
                //    format: {
                //        overallCountByRelevance: function(d,id){console.log(id, Math.pow(10,d));return Math.pow(10,d).toFixed(0);},
                //        institutionCountByRelevance: function(d,id){console.log(id, Math.pow(10,d));return Math.pow(10,d).toFixed(0);}
                //    }
                //}
            };

            chart_options['point'] = {show: false};

        } else if (chart_type === 'timeseries') {

            let x_axis = this.get('data.aggregations.all_over_time.buckets').map((datum) => { return datum.key_as_string; });
            var columns = this.get('data.aggregations.sorted_by_type.buckets').map((bucket) => {
                return [bucket.key].concat(bucket['type_over_time'].buckets.reduce((ret, bucket) => {
                    ret[x_axis.indexOf(bucket.key_as_string)] = linearToLog10(bucket.doc_count);
                    return ret;
                }, (new Array(x_axis.length)).fill(0)));
            });
            columns.unshift(['x'].concat(x_axis));
            columns.unshift(['All Events'].concat(this.get('data.aggregations.all_over_time.buckets').map((bucket) => {
                return linearToLog10(bucket.doc_count);
            })));
            let data_x = 'x';
            chart_options['axis'] = {
                x: {
                    type: 'timeseries',
                    tick: {
                        culling: {
                            max: 10
                        },
                        rotate: 90,
                        format: '%d-%m-%Y' // Format the tick labels on our chart
                    }
                },
                y: {
                    min: 1,
                    tick: {
                        format: log10ToLinear
                    },
                    label: 'Number of Items (Log Scale)'
                }
            };
            let data_types = columns.reduce((r, c, i, a) => {
                r[c[0]] = 'area-spline';
                return r;
            }, {});
            chart_options['tooltip'] = {
                format: { // We want to return a nice-looking tooltip whose content is determined by (or at least consistent with) sour TS intervals
                    title: function (d) {
                        return d.toString().substring(4,15); // This isn't perfect, but it's at least more verbose than before
                    }
                }
            };

            let point = {
                show: false,
            };

            chart_options['data']['types'] = data_types;
            chart_options['data']['x'] = data_x;
            chart_options['legend'] = { position: "right" };
            chart_options['point'] = point;

        }

        chart_options['data']['columns'] = columns;
        chart_options[chart_type]['title'] = title;
        this.set('chart', c3.generate(chart_options));

        if (chart_type === "donut") {
            var labels = d3.selectAll(this.$(this.element).find('.c3-chart-arc')).select(function(d) {
                let angle_size = d.endAngle - d.startAngle;
                if (angle_size < 0.5) {
                    return;
                }
                d3.select(this.parentNode).append('text')
                    .text(self.data.reduce(function(acc, cur, idx, arr) {
                        var string;
                        if (cur._source.id === d.data.id) {
                            if (self.get('name') === 'Awards') {
                               string = getLabel(cur._source.id);
                            } else if (cur._source.name) {
                                string = cur._source.name
                            } else {
                                string = cur._source.id;
                            }
                            if (string.length > 38) {
                                return string.substring(0,25) + "...";
                            }
                            return string;
                        }
                        return acc;
                    }, false))
                    .attr("x", 160*Math.sin((d.startAngle + d.endAngle)/2))
                    .attr("y", -130*Math.cos((d.startAngle + d.endAngle)/2))
                    .attr("text-anchor", "middle")
                    .attr("alignment-baseline", "central")
                    .attr("font-size", "12px")
                    .attr("fill", "rgb(250,250,250)")
                    .each(function(d) {
                        var rect = document.createElementNS("http://www.w3.org/2000/svg","rect");
                        this.parentNode.insertBefore(rect, this);
                        let bbox = this.getBBox();
                        d3.select(rect)
                            .attr("fill", "rgba(0,0,0,0.5)")
                            .attr("stroke", "rgba(0,0,0,0.6)")
                            .attr("width", bbox.width + 14)
                            .attr("height", bbox.height + 8)
                            .attr("x", bbox.x - 7)
                            .attr("y", bbox.y - 4)
                    })
            });
            /*var labels_bgs = d3.selectAll(this.$(this.element).find('.c3-chart-arc'))
                .insert('rect', 'text')
                .each(function(d) {
                    d.attr("width", 200).attr("height", 20)
                })

            labels.select(function() {
            });*/
        }

    },

    didRender() {
        //this.updateChart();
    },

    actions: {

        transitionToFacet(id, override) { //Two different items here; one refers to the widget; one refers to the datum.
            override = override || false;
            let queryParams = {};
            let data = this.get('data');
            let item = data.reduce((acc, cur, idx, arr) => {
                if (cur._source.id === id) {
                    return cur;
                }
                return acc;
            }, false);
            var facet = this.get("item.facetDashParameter");
            var facetDash = this.get("item.facetDash");
            if(override){
                facetDash = override;
            }
            if (facetDash === "url" && item.url) {
                window.location.href = item.url;
                return;
            }
            if (facet) {
                queryParams[facet] = item.name;
                if (item._source.types.indexOf("agent") > -1) {
                    queryParams[facet] = item._source.id;
                }
                this.attrs.transitionToFacet(facetDash, queryParams);
            }
        },
    }

});
<|endoftext|>


<commit_before>'use strict';

class BattleController {
  constructor($timeout, gameData) {
    var vm = this;
    vm.gameData = gameData;

    vm.gameResults = vm.gameData.testAllTargets();

    vm.results = [
      { name: 'discretion', text: 'Discretion', value: vm.gameResults.DSum },
      { name: 'suspense', text: 'Suspense', value: vm.gameResults.SSum },
      { name: 'reserve', text: 'Reserve', value: vm.gameResults.R }
    ];
  }
}

angular.module('gameApp')
  .controller('BattleController', BattleController);
<commit_msg>returned final CR<commit_after>'use strict';

class BattleController {
  constructor($timeout, gameData) {
    var vm = this;
    vm.gameData = gameData;

    vm.gameResults = vm.gameData.testAllTargets();

    vm.results = [
      { name: 'discretion', text: 'Discretion', value: vm.gameResults.DSum },
      { name: 'suspense', text: 'Suspense', value: vm.gameResults.SSum },
      { name: 'finalcr', text: 'Final CR', value: vm.gameResults.finalCR },
      { name: 'reserve', text: 'Reserve', value: vm.gameResults.R }
    ];
  }
}

angular.module('gameApp')
  .controller('BattleController', BattleController);
<|endoftext|>


<commit_before>describe('Console Service', function() {
    let sandbox;

    beforeEach(function() {
        module('app.services');
        bard.inject('Consoles', '$http','CollectionsApi','EventNotifications','$timeout','$window');
    });
    const successResponse = {
        'success': true,
        'message': 'launching console',
        'task_id': '1'
    };

    it('should try and open up a console', () => {
        const collectionsApiSpy = sinon.stub(CollectionsApi, 'post').returns(Promise.resolve(successResponse));
        const requestOptions = { action: "request_console", resource: { protocol: "html5" } };
        Consoles.open('12345');
        expect(collectionsApiSpy).to.have.been.calledWith('vms', '12345', {}, requestOptions);
    });

     it('should give an error if it failed but has a 200 status code', () => {
        const failureResponse = {
            'message': 'failed'
        };
        const eventNotificationsFailureSpy = sinon.spy(EventNotifications, 'error');

        const collectionsApiSpy = sinon.stub(CollectionsApi, 'post').returns(Promise.resolve(failureResponse));
        const requestOptions = { action: "request_console", resource: { protocol: "html5" } };
        return Consoles.open('12345').then((data)=>{
            expect(eventNotificationsFailureSpy).to.have.been.calledWith('There was an error opening the console. failed');
        });
     });
     it('should give a success notification if it was called and was successful', () => {
        const collectionsApiSpy = sinon.stub(CollectionsApi, 'post').returns(Promise.resolve(successResponse));
        const eventNotificationsSpy = sinon.spy(EventNotifications, 'info');
        const requestOptions = { action: "request_console", resource: { protocol: "html5" } };
        return Consoles.open('12345').then((data)=>{
            expect(eventNotificationsSpy).to.have.been.calledWith('Waiting for the console to become ready. ','launching console');
        });
     });

  it('should successfully start a spice session', function() {
        const taskResponse = {
                'state': 'Finished',
                'status': 'Ok',
                'task_results': {
                    'proto':'spice',
                    'url':'blah',
                    'secret':'blah'
                }
            };
        const collectionsApiPostSpy = sinon.stub(CollectionsApi, 'post').returns(Promise.resolve(successResponse));
        const collectionsApiGetSpy = sinon.stub(CollectionsApi, 'get').returns(Promise.resolve(taskResponse));
        return Consoles.open('12345').then((data)=>{
            $timeout.flush()
            expect(collectionsApiGetSpy).to.have.been.calledWith('tasks', '1', { attributes: 'task_results' });
        });
    });
});
<commit_msg>bring unit tests up to 100% for console services.<commit_after>describe('Console Service', function() {
    let sandbox;

    beforeEach(function() {
        module('app.services');
        bard.inject('Consoles', '$http','CollectionsApi','EventNotifications','$timeout','$window');
    });
    const successResponse = {
        'success': true,
        'message': 'launching console',
        'task_id': '1'
    };

    it('should try and open up a console', () => {
        const collectionsApiSpy = sinon.stub(CollectionsApi, 'post').returns(Promise.resolve(successResponse));
        const requestOptions = { action: "request_console", resource: { protocol: "html5" } };
        Consoles.open('12345');
        expect(collectionsApiSpy).to.have.been.calledWith('vms', '12345', {}, requestOptions);
    });

     it('should give an error if it failed but has a 200 status code', () => {
        const failureResponse = {
            'message': 'failed'
        };
        const eventNotificationsFailureSpy = sinon.spy(EventNotifications, 'error');

        const collectionsApiSpy = sinon.stub(CollectionsApi, 'post').returns(Promise.resolve(failureResponse));
        const requestOptions = { action: "request_console", resource: { protocol: "html5" } };
        return Consoles.open('12345').then((data)=>{
            expect(eventNotificationsFailureSpy).to.have.been.calledWith('There was an error opening the console. failed');
        });
     });
     it('should give a success notification if it was called and was successful', () => {
        const collectionsApiSpy = sinon.stub(CollectionsApi, 'post').returns(Promise.resolve(successResponse));
        const eventNotificationsSpy = sinon.spy(EventNotifications, 'info');
        const requestOptions = { action: "request_console", resource: { protocol: "html5" } };
        return Consoles.open('12345').then((data)=>{
            expect(eventNotificationsSpy).to.have.been.calledWith('Waiting for the console to become ready. ','launching console');
        });
     });

  it('should successfully start a spice session', function() {
        const taskResponse = {
                'state': 'Finished',
                'status': 'Ok',
                'task_results': {
                    'proto':'spice',
                    'url':'blah',
                    'secret':'blah'
                }
            };
        const collectionsApiPostSpy = sinon.stub(CollectionsApi, 'post').returns(Promise.resolve(successResponse));
        const collectionsApiGetSpy = sinon.stub(CollectionsApi, 'get').returns(Promise.resolve(taskResponse));
        return Consoles.open('12345').then((data)=>{
            $timeout.flush()
            expect(collectionsApiGetSpy).to.have.been.calledWith('tasks', '1', { attributes: 'task_results' });
        });
    });
    it('should successfully start a vnc session', function() {
        const taskResponse = {
                'state': 'Finished',
                'status': 'Ok',
                'task_results': {
                    'proto':'vnc',
                    'url':'blah',
                    'secret':'blah'
                }
            };
        const collectionsApiPostSpy = sinon.stub(CollectionsApi, 'post').returns(Promise.resolve(successResponse));
        const collectionsApiGetSpy = sinon.stub(CollectionsApi, 'get').returns(Promise.resolve(taskResponse));
        return Consoles.open('12345').then((data)=>{
            $timeout.flush()
            expect(collectionsApiGetSpy).to.have.been.calledWith('tasks', '1', { attributes: 'task_results' });
        });
    });
    it('should successfully start a remote session', function() {
        const taskResponse = {
                'state': 'Finished',
                'status': 'Ok',
                'task_results': {
                    'proto':'remote',
                    'remote_url':'blah'
                }
            };
        const collectionsApiPostSpy = sinon.stub(CollectionsApi, 'post').returns(Promise.resolve(successResponse));
        const collectionsApiGetSpy = sinon.stub(CollectionsApi, 'get').returns(Promise.resolve(taskResponse));
        return Consoles.open('12345').then((data)=>{
            $timeout.flush()
            expect(collectionsApiGetSpy).to.have.been.calledWith('tasks', '1', { attributes: 'task_results' });
        });
    });
    it('should fail if a unknown protocol is sent', function() {
        const taskResponse = {
                'state': 'Finished',
                'status': 'Ok',
                'task_results': {
                    'proto':'fds',
                    'remote_url':'blah'
                }
            };
        const collectionsApiPostSpy = sinon.stub(CollectionsApi, 'post').returns(Promise.resolve(successResponse));
        const collectionsApiGetSpy = sinon.stub(CollectionsApi, 'get').returns(Promise.resolve(taskResponse));
        const eventNotificationsFailureSpy = sinon.spy(EventNotifications, 'error');
        return Consoles.open('12345').then((data)=>{
            $timeout.flush()
          expect(collectionsApiGetSpy).to.have.been.calledWith('tasks', '1', { attributes: 'task_results' });
        });
    });
    it('should rerun if state is queued', function() {
        const taskResponse = {
                'id':'1',
                'state': 'Queued',
                'status': 'Ok',
                'task_results': {
                    'proto':'fds',
                    'remote_url':'blah'
                }
            };
        const collectionsApiPostSpy = sinon.stub(CollectionsApi, 'post').returns(Promise.resolve(successResponse));
        const collectionsApiGetSpy = sinon.stub(CollectionsApi, 'get').returns(Promise.resolve(taskResponse));
        const eventNotificationsFailureSpy = sinon.spy(EventNotifications, 'error');
        return Consoles.open('12345').then((data)=>{
            $timeout.flush()
          expect(collectionsApiGetSpy).to.have.been.calledWith('tasks', '1', { attributes: 'task_results' });
        });
    });
    it('should throw an error if task fails', function() {
        const taskResponse = {
                'id':'1',
                'state': 'Queued',
                'status': 'failed',
                'task_results': {
                    'proto':'fds',
                    'remote_url':'blah'
                }
            };
        const collectionsApiPostSpy = sinon.stub(CollectionsApi, 'post').returns(Promise.resolve(successResponse));
        const collectionsApiGetSpy = sinon.stub(CollectionsApi, 'get').returns(Promise.resolve(taskResponse));
        const eventNotificationsFailureSpy = sinon.spy(EventNotifications, 'error');
        return Consoles.open('12345').then((data)=>{
            $timeout.flush()
          expect(collectionsApiGetSpy).to.have.been.calledWith('tasks', '1', { attributes: 'task_results' });
        });
    });
});
<|endoftext|>


<commit_before>/* global expect */
/* global angular */
/* global jasmine */

describe('Angular Availability', function() { //describe specifies a "spec" : logical grouping of tests
    it('Angular Available', function() {
        var angularCheck = (typeof(angular) != "undefined");
        expect(angularCheck).toBe(true);
    });
    it('Angular Mock Available', function() {
        var angularMockCheck = (typeof(angular.mock) != "undefined");
        expect(angularMockCheck).toBe(true);
    });
});

describe('Component Availability', function() { //describe specifies a "spec" : logical grouping of tests

    beforeEach(angular.mock.module('timesync'));

    it('SocketNTPSync is Available', function () {
        var instanceOfSocketNTPSyncService;
        angular.mock.inject(function (_SocketNTPSync_) {
            instanceOfSocketNTPSyncService = _SocketNTPSync_;
        });

        expect(instanceOfSocketNTPSyncService).toBeDefined();
    });

    it('TimeSyncController is Available', function() {

        var instanceOfSocketNTPSyncService;
        var controllerService;

        var injectedHTTP;
        var injectedINTERVAL;

        var operatingScope;

        angular.mock.inject(function (_SocketNTPSync_, _$controller_, _$http_, _$interval_, _$rootScope_) {
            instanceOfSocketNTPSyncService = _SocketNTPSync_;
            controllerService = _$controller_;
            injectedHTTP = _$http_;
            injectedINTERVAL = _$interval_;
            operatingScope = _$rootScope_.$new();
        });

        var tsController = controllerService('TimeSyncController', {
            $http: injectedHTTP,
            $interval: injectedINTERVAL,
            $scope: operatingScope,
            SocketNTPSync: instanceOfSocketNTPSyncService
        });

        expect(tsController).toBeDefined();
        expect(tsController.fTitle).toEqual('UberTimeSync');

    });
});

describe('TimeSyncController', function() { //describe specifies a "spec" : logical grouping of tests

    beforeEach(angular.mock.module('timesync'));

    var $controller;
    var $scope;
    var $interval;
    var $http;
    var SocketNTPSync;
    var $httpBackend;

    beforeEach(angular.mock.inject(function(_$controller_, _$rootScope_, _$interval_, _$http_, _$httpBackend_, _SocketNTPSync_) {
        $controller = _$controller_;
        $scope = _$rootScope_.$new();
        $interval = _$interval_;
        $http = _$http_;
        $httpBackend = _$httpBackend_;
        SocketNTPSync = _SocketNTPSync_;
    }));

    afterEach(function () {

    //This verifies that all calls came through.
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest(); //Extra assert to make sure we flush all backend requests stuff
});

    it('TimeSyncController Attempts A Sync with Server', function () {

        var tsController = $controller('TimeSyncController', {
            $http: $http,
            $interval: $interval,
            $scope: $scope,
            SocketNTPSync: SocketNTPSync
        });

        var urlValidator = function (url) {
                    //dump(url);
                    return url === '/doSynchronize.json';

                };

        $httpBackend.expectGET(urlValidator).respond(200);

        expect($httpBackend.flush).not.toThrow(); //Another check

    });

    // it('Controller is there', function() {
    //
    //     //var $intervalSpy = jasmine.createSpy('$interval', $interval);
    //
    //     var tsController = $controller('TimeSyncController', {
    //         $http: $http,
    //         $interval: $interval,
    //         $scope: $scope,
    //         SocketNTPSync: SocketNTPSync
    //     });
    //
    //     expect(tsController.fTitle).toEqual('UberTimeSync');
    //
    // }); // it specifies a single test within a spec
    //
    // it('Controller establishes heartbeat at > 30 fps', function() {
    //
    //     //This references stuff in http://www.bradoncode.com/blog/2015/06/15/unit-testing-interval-angularls/
    //
    //     var $intervalSpy = jasmine.createSpy('$interval', $interval);
    //
    //     var tsController = $controller('TimeSyncController', {
    //         $http: $http,
    //         $interval: $intervalSpy,
    //         $scope: $scope,
    //         SocketNTPSync: SocketNTPSync
    //     });
    //
    //     expect(tsController.fTitle).toEqual('UberTimeSync');
    //
    //     expect($intervalSpy).toHaveBeenCalled();
    //
    //     var calls = $intervalSpy.calls.all();
    //     var args0 = calls[0].args;
    //
    //     var heartbeatAtLeast30fps = args0[1] < 1000.0 / 30.0; //Second argument is milliseconds delay
    //     //For interval to fire with at least 30 fps, delay needs to be less
    //     //than 1000/30
    //
    //     expect(heartbeatAtLeast30fps).toBe(true);
    //
    // });

    //Other matchers (trutherizers)

    // expect(true).toBe(true);
    // expect(false).not.toBe(true);
    // expect(1).toEqual(1);
    // expect('foo').toEqual('foo');
    // expect('foo').not.toEqual('bar');

});
<commit_msg>Code beautification<commit_after>/* global expect */
/* global angular */
/* global jasmine */

describe('Angular Availability', function () { //describe specifies a "spec" : logical grouping of tests
    it('Angular Available', function () {
        var angularCheck = (typeof (angular) != "undefined");
        expect(angularCheck).toBe(true);
    });
    it('Angular Mock Available', function () {
        var angularMockCheck = (typeof (angular.mock) != "undefined");
        expect(angularMockCheck).toBe(true);
    });
});

describe('Component Availability', function () { //describe specifies a "spec" : logical grouping of tests

    beforeEach(angular.mock.module('timesync'));

    it('SocketNTPSync is Available', function () {
        var instanceOfSocketNTPSyncService;
        angular.mock.inject(function (_SocketNTPSync_) {
            instanceOfSocketNTPSyncService = _SocketNTPSync_;
        });

        expect(instanceOfSocketNTPSyncService).toBeDefined();
    });

    it('TimeSyncController is Available', function () {

        var instanceOfSocketNTPSyncService;
        var controllerService;

        var injectedHTTP;
        var injectedINTERVAL;

        var operatingScope;

        angular.mock.inject(function (_SocketNTPSync_, _$controller_, _$http_, _$interval_, _$rootScope_) {
            instanceOfSocketNTPSyncService = _SocketNTPSync_;
            controllerService = _$controller_;
            injectedHTTP = _$http_;
            injectedINTERVAL = _$interval_;
            operatingScope = _$rootScope_.$new();
        });

        var tsController = controllerService('TimeSyncController', {
            $http: injectedHTTP,
            $interval: injectedINTERVAL,
            $scope: operatingScope,
            SocketNTPSync: instanceOfSocketNTPSyncService
        });

        expect(tsController).toBeDefined();
        expect(tsController.fTitle).toEqual('UberTimeSync');

    });
});

describe('TimeSyncController', function () { //describe specifies a "spec" : logical grouping of tests

    beforeEach(angular.mock.module('timesync'));

    var $controller;
    var $scope;
    var $interval;
    var $http;
    var SocketNTPSync;
    var $httpBackend;

    beforeEach(angular.mock.inject(function (_$controller_, _$rootScope_, _$interval_, _$http_, _$httpBackend_, _SocketNTPSync_) {
        $controller = _$controller_;
        $scope = _$rootScope_.$new();
        $interval = _$interval_;
        $http = _$http_;
        $httpBackend = _$httpBackend_;
        SocketNTPSync = _SocketNTPSync_;
    }));

    afterEach(function () {

        //This verifies that all calls came through.
        $httpBackend.verifyNoOutstandingExpectation();
        $httpBackend.verifyNoOutstandingRequest(); //Extra assert to make sure we flush all backend requests stuff
    });

    it('TimeSyncController Attempts A Sync with Server', function () {

        var tsController = $controller('TimeSyncController', {
            $http: $http,
            $interval: $interval,
            $scope: $scope,
            SocketNTPSync: SocketNTPSync
        });

        var urlValidator = function (url) {
            //dump(url);
            return url === '/doSynchronize.json';

        };

        $httpBackend.expectGET(urlValidator).respond(200);

        expect($httpBackend.flush).not.toThrow(); //Another check

    });

    // it('Controller is there', function() {
    //
    //     //var $intervalSpy = jasmine.createSpy('$interval', $interval);
    //
    //     var tsController = $controller('TimeSyncController', {
    //         $http: $http,
    //         $interval: $interval,
    //         $scope: $scope,
    //         SocketNTPSync: SocketNTPSync
    //     });
    //
    //     expect(tsController.fTitle).toEqual('UberTimeSync');
    //
    // }); // it specifies a single test within a spec
    //
    // it('Controller establishes heartbeat at > 30 fps', function() {
    //
    //     //This references stuff in http://www.bradoncode.com/blog/2015/06/15/unit-testing-interval-angularls/
    //
    //     var $intervalSpy = jasmine.createSpy('$interval', $interval);
    //
    //     var tsController = $controller('TimeSyncController', {
    //         $http: $http,
    //         $interval: $intervalSpy,
    //         $scope: $scope,
    //         SocketNTPSync: SocketNTPSync
    //     });
    //
    //     expect(tsController.fTitle).toEqual('UberTimeSync');
    //
    //     expect($intervalSpy).toHaveBeenCalled();
    //
    //     var calls = $intervalSpy.calls.all();
    //     var args0 = calls[0].args;
    //
    //     var heartbeatAtLeast30fps = args0[1] < 1000.0 / 30.0; //Second argument is milliseconds delay
    //     //For interval to fire with at least 30 fps, delay needs to be less
    //     //than 1000/30
    //
    //     expect(heartbeatAtLeast30fps).toBe(true);
    //
    // });

    //Other matchers (trutherizers)

    // expect(true).toBe(true);
    // expect(false).not.toBe(true);
    // expect(1).toEqual(1);
    // expect('foo').toEqual('foo');
    // expect('foo').not.toEqual('bar');

});
<|endoftext|>


<commit_before>'use strict';

var Marionette = require('backbone.marionette'),
    entity = require('./../../factory/entity'),
    service = require('./../../factory/service'),
    _ = require('underscore');

module.exports = Marionette.Controller.extend({
  /**
   * Shows the new user view
   */
  initialize: function () {
    this.defaultTitle = document.title;
    this.user = entity.getCurrentUser();

    this.socket = service.getSocket();
    this.socket.on('messages:create', _.bind(this.notifyUser, this));

    window.addEventListener('focus', _.bind(this.userFocused, this));
    window.addEventListener('blur', _.bind(this.userBlured, this));
  },

  /**
   * Sets the user as focused
   */
  userFocused: function () {
    this.user.set('focused', true);
  },

  /**
   * Sets the user as unfocused
   */
  userBlured: function () {
    this.user.set('focused', false);
  },

  /**
   * If the user is not focus on window it will
   * start a blinking page title notification
   * @param  {Object} message
   */
  notifyUser: function (message) {
    if (!this.user.get('focused')) {
      clearInterval(this.titleInterval);
      this.notificationTitle = message.user.name + ' sent you a message...';
      this.titleInterval = setInterval(_.bind(this.toggleTitle, this), 1000);
    }
  },

  /**
   * Toggles the title from default to notifcation
   * NOTE: When user is re-focused it resets the title
   */
  toggleTitle: function () {
    document.title = document.title === this.defaultTitle ?
      this.notificationTitle : this.defaultTitle;

    if (this.user.get('focused')) {
      this.resetTitle();
    }
  },

  /**
   * Resets the title back to default and clear interval
   */
  resetTitle: function () {
    clearInterval(this.titleInterval);
    document.title = this.defaultTitle;
  }
});
<commit_msg>Corrected comment spelling mistake<commit_after>'use strict';

var Marionette = require('backbone.marionette'),
    entity = require('./../../factory/entity'),
    service = require('./../../factory/service'),
    _ = require('underscore');

module.exports = Marionette.Controller.extend({
  /**
   * Shows the new user view
   */
  initialize: function () {
    this.defaultTitle = document.title;
    this.user = entity.getCurrentUser();

    this.socket = service.getSocket();
    this.socket.on('messages:create', _.bind(this.notifyUser, this));

    window.addEventListener('focus', _.bind(this.userFocused, this));
    window.addEventListener('blur', _.bind(this.userBlured, this));
  },

  /**
   * Sets the user as focused
   */
  userFocused: function () {
    this.user.set('focused', true);
  },

  /**
   * Sets the user as unfocused
   */
  userBlured: function () {
    this.user.set('focused', false);
  },

  /**
   * If the user is not focus on window it will
   * start a blinking page title notification
   * @param  {Object} message
   */
  notifyUser: function (message) {
    if (!this.user.get('focused')) {
      clearInterval(this.titleInterval);
      this.notificationTitle = message.user.name + ' sent you a message...';
      this.titleInterval = setInterval(_.bind(this.toggleTitle, this), 1000);
    }
  },

  /**
   * Toggles the title from default to notification
   * NOTE: When user is re-focused it resets the title
   */
  toggleTitle: function () {
    document.title = document.title === this.defaultTitle ?
      this.notificationTitle : this.defaultTitle;

    if (this.user.get('focused')) {
      this.resetTitle();
    }
  },

  /**
   * Resets the title back to default and clear interval
   */
  resetTitle: function () {
    clearInterval(this.titleInterval);
    document.title = this.defaultTitle;
  }
});
<|endoftext|>