<commit_before>/**
 * Module : Kero datetime
 * Author : Kvkens(yueming@yonyou.com)
 * Date	  : 2016-08-09 14:59:37
 */

import {BaseAdapter} from '../core/baseAdapter';
import {ValueMixin} from '../core/valueMixin';
import {EnableMixin} from '../core/enableMixin';
import {RequiredMixin} from '../core/requiredMixin';
import {ValidateMixin} from '../core/validateMixin';
import {on,off,stopEvent} from 'tinper-sparrow/js/event';
import {addClass,removeClass} from 'tinper-sparrow/js/dom';
import {core} from 'tinper-sparrow/js/core';

import {DataTable} from 'kero/js/dataTable/indexDataTable';
import {env} from 'tinper-sparrow/js/env';
import {DateTimePicker} from 'tinper-neoui/js/neoui-datetimepicker';
import {date} from 'tinper-sparrow/js/util/dateUtils';
import {compMgr} from 'tinper-sparrow/js/compMgr';
import {getFunction} from 'tinper-sparrow/js/util';

var DateTimeAdapter = BaseAdapter.extend({
	mixins: [ValueMixin,EnableMixin,RequiredMixin, ValidateMixin],
	init: function (options) {
		var self = this,adapterType,format;
		// DateTimeAdapter.superclass.initialize.apply(this, arguments);
		if (this.options.type === 'u-date'){
			this.adapterType = 'date';
		}else{
			this.adapterType = 'datetime'
			addClass(this.element,'time');
		}

		this.beforeValueChangeFun = getFunction(this.viewModel, this.options['beforeValueChangeFun']);

		this.maskerMeta = core.getMaskerMeta(this.adapterType) || {};
		this.maskerMeta.format = this.options['format'] || this.maskerMeta.format;
		if(this.dataModel){
			this.dataModel.on(this.field + '.format.' +  DataTable.ON_CURRENT_META_CHANGE, function(event){
				self.setFormat(event.newValue)
			});
		}

		if(this.dataModel && !this.options['format'])
			this.options.format = this.dataModel.getMeta(this.field, "format")

		if(!this.options['format']){
			if(this.options.type === 'u-date'){
				this.options.format = "YYYY-MM-DD";
			}else if(this.options.type === 'year'){
				this.options.format = "YYYY";
			}else if(this.options.type === 'month'){
				this.options.format = "MM";
			}else if(this.options.type === 'yearmonth'){
				this.options.format = "YYYY-MM";
			}else{
				this.options.format = "YYYY-MM-DD HH:mm:ss";
			}
		}
		format = this.options.format;
		this.maskerMeta.format = format || this.maskerMeta.format

		this.startField = this.options.startField?this.options.startField : this.dataModel.getMeta(this.field, "startField");

		this.endField = this.options.endField?this.options.endField : this.dataModel.getMeta(this.field, "endField");

		// this.formater = new $.DateFormater(this.maskerMeta.format);
		// this.masker = new DateTimeMasker(this.maskerMeta);
		this.op = {};
		var mobileDateFormat = "", mobileTimeFormat = "", dateOrder = "", timeOrder = "";
		if(env.isMobile){
			switch (format) {
				case "YYYY-MM-DD":
					mobileDateFormat = "yy-mm-dd";
					dateOrder = mobileDateFormat.replace(/-/g, '');
					break;
				case "YYYY-MM-DD HH:mm":
					mobileDateFormat = "yy-mm-dd";
					mobileTimeFormat = "HH:ii".replace(/\:/g, '');
					dateOrder = mobileDateFormat.replace(/-/g, '');
					timeOrder = mobileTimeFormat.replace(/\:/g, '');
					break;
				case "YYYY-MM":
					mobileDateFormat = "yy-mm";
					dateOrder = mobileDateFormat.replace(/-/g, '');
					break;
				default:
					mobileDateFormat = "yy-mm-dd";
					mobileTimeFormat = "HH:ii:ss";
					dateOrder = mobileDateFormat.replace(/-/g, '');
					timeOrder = mobileTimeFormat.replace(/\:/g, '');
			}

			this.op = {
				theme:"ios",
				mode:"scroller",
				lang: "zh",
				cancelText: null,
				dateFormat: mobileDateFormat,
				timeWheels: timeOrder,
				dateWheels: dateOrder,
				timeFormat: mobileTimeFormat,
				onSelect:function(val){
					if(typeof self.options.beforeValueChangeFun == 'function'){
				        if(!self.options.beforeValueChangeFun.call(this,this.pickerDate)){
				            return;
				        }
				    }
					self.setValue(val);
				}
			}
			this._span = this.element.querySelector("span");
			this.element = this.element.querySelector("input");
			this.element.setAttribute('readonly','readonly');
			if (this._span){
		        on(this._span, 'click', function(e){
		            self.element.focus();
		            stopEvent(e);
		        });
		    }
			if(this.adapterType == 'date'){
				$(this.element).mobiscroll().date(this.op);
			}else{
				$(this.element).mobiscroll().datetime(this.op);
			}
		}else{
			this.comp = new DateTimePicker({el:this.element,format:this.maskerMeta.format,showFix:this.options.showFix,beforeValueChangeFun:this.beforeValueChangeFun});
		}

		this.element['u.DateTimePicker'] = this.comp;

		if(!env.isMobile){
			this.comp.on('select', function(event){
				self.setValue(event.value);
			});
		}

		this.setStartField(this.startField);
		this.setEndField(this.endField);
        if(!env.isMobile){
			// 校验
			this.comp.on('validate', function(event){
				self.doValidate();
			});
		}
	},

	setEndField: function(endField){
		var self = this;
		self.endField = endField;
		if(self.dataModel){
			if(self.endField){
				self.dataModel.ref(self.endField).subscribe(function(value) {
					if(env.isMobile){
						var valueObj = date.getDateObj(value);
						self.op.minDate = valueObj;
						if(self.adapterType == 'date'){
							$(self.element).mobiscroll().date(self.op);
						}else{
							$(self.element).mobiscroll().datetime(self.op);
						}
						var nowDate = date.getDateObj(self.dataModel.getValue(self.field));
						if(nowDate < valueObj || !value){
							self.dataModel.setValue(self.field,'');
						}
					}else{
						self.comp.setEndDate(value);
						if(self.comp.date > date.getDateObj(value) || !value){
							self.dataModel.setValue(self.field,'');
						}
					}

				});
			}

			if(self.endField){
				var endValue = self.dataModel.getValue(self.endField);
				if(endValue){
					if(env.isMobile){
						self.op.minDate = date.getDateObj(endValue);
						if(self.adapterType == 'date'){
							$(self.element).mobiscroll().date(self.op);
						}else{
							$(self.element).mobiscroll().datetime(self.op);
						}
					}else{
						self.comp.setEndDate(endValue);
					}
				}
			}
		}
	},

	setStartField: function(startField){
		var self = this;
		self.startField = startField;
		if(self.dataModel){
			if(self.startField){
				self.dataModel.ref(self.startField).subscribe(function(value) {
					if(env.isMobile){
						value = date.getDateObj(value);

						var valueObj = self.setMobileStartDate(value, self.options.format);
						self.op.minDate = valueObj;
						if(self.adapterType == 'date'){
							$(self.element).mobiscroll().date(self.op);
						}else{
							$(self.element).mobiscroll().datetime(self.op);
						}
						var nowDate = date.getDateObj(self.dataModel.getValue(self.field));
						if(nowDate < valueObj || !value){
							self.dataModel.setValue(self.field,'');
						}
					}else{
						self.comp.setStartDate(value, self.options.format);
						if(self.comp.date < date.getDateObj(value) || !value){
							self.dataModel.setValue(self.field,'');
						}
					}

				});
			}
			if(self.startField){
				var startValue = self.dataModel.getValue(self.startField);
				if(startValue){
					if(env.isMobile){
						startValue = date.getDateObj(startValue);
						self.op.minDate = self.setMobileStartDate(startValue, self.options.format);
						if(self.adapterType == 'date'){
							$(self.element).mobiscroll().date(self.op);
						}else{
							$(self.element).mobiscroll().datetime(self.op);
						}
					}else{
						self.comp.setStartDate(startValue, self.options.format);
					}
				}
			}
		}
	},

	setMobileStartDate: function (startDate, type) {

	    if(startDate){
	        switch (type) {
	            case 'YYYY-MM':
	                startDate = date.add(startDate, 'M', 1);
	                break;
	            case 'YYYY-MM-DD':
	                startDate = date.add(startDate, 'd', 1);
	                break;
	        }
	    }
	    return startDate;
	},

	modelValueChange: function(value){
		if (this.slice) return;
		this.trueValue = value;
		if(env.isMobile){
			if(value){
				value = date.format(value,this.options.format);
				$(this.element).scroller('setDate', date.getDateObj(value), true);
			}
		}else{
			this.comp.setDate(value);
		}

	},
	setFormat: function(format){
		if (this.maskerMeta.format == format) return;
		this.options.format = format;
		this.maskerMeta.format = format;
		if(!env.isMobile)
			this.comp.setFormat(format);
		// this.formater = new $.DateFormater(this.maskerMeta.format);
		// this.masker = new DateTimeMasker(this.maskerMeta);
	},
	setValue: function (value) {
		value = date.format(value,this.options.format);
        this.trueValue = this.formater ? this.formater.format(value) : value;
        this.showValue = this.masker ? this.masker.format(this.trueValue).value : this.trueValue;
        this.setShowValue(this.showValue);
        this.slice = true;
        this.dataModel.setValue(this.field, this.trueValue);
        this.slice = false;
    },
    setEnable: function(enable){
        if (enable === true || enable === 'true') {
            this.enable = true;
            if(env.isMobile){
            	this.element.removeAttribute('disabled');
            }else{
            	this.comp._input.removeAttribute('readonly');
            }
            removeClass(this.element.parentNode,'disablecover');
        } else if (enable === false || enable === 'false') {
            this.enable = false;
            if(env.isMobile){
            	this.element.setAttribute('disabled','disabled');
            }else{
            	this.comp._input.setAttribute('readonly', 'readonly');
            }
            addClass(this.element.parentNode,'disablecover');
        }
        if(!env.isMobile)
        	this.comp.setEnable(enable);
    }

});

compMgr.addDataAdapter({
	adapter: DateTimeAdapter,
	name: 'u-date'
});

compMgr.addDataAdapter({
	adapter: DateTimeAdapter,
	name: 'u-datetime'
});

export {DateTimeAdapter};
<commit_msg>fix bug<commit_after>/**
 * Module : Kero datetime
 * Author : Kvkens(yueming@yonyou.com)
 * Date	  : 2016-08-09 14:59:37
 */

import {BaseAdapter} from '../core/baseAdapter';
import {ValueMixin} from '../core/valueMixin';
import {EnableMixin} from '../core/enableMixin';
import {RequiredMixin} from '../core/requiredMixin';
import {ValidateMixin} from '../core/validateMixin';
import {on,off,stopEvent} from 'tinper-sparrow/js/event';
import {addClass,removeClass} from 'tinper-sparrow/js/dom';
import {core} from 'tinper-sparrow/js/core';

import {DataTable} from 'kero/js/dataTable/indexDataTable';
import {env} from 'tinper-sparrow/js/env';
import {DateTimePicker} from 'tinper-neoui/js/neoui-datetimepicker';
import {date} from 'tinper-sparrow/js/util/dateUtils';
import {compMgr} from 'tinper-sparrow/js/compMgr';
import {getFunction} from 'tinper-sparrow/js/util';

var DateTimeAdapter = BaseAdapter.extend({
	mixins: [ValueMixin,EnableMixin,RequiredMixin, ValidateMixin],
	init: function (options) {
		var self = this,adapterType,format;
		// DateTimeAdapter.superclass.initialize.apply(this, arguments);
		if (this.options.type === 'u-date'){
			this.adapterType = 'date';
		}else{
			this.adapterType = 'datetime'
			addClass(this.element,'time');
		}

		this.beforeValueChangeFun = getFunction(this.viewModel, this.options['beforeValueChangeFun']);

		this.maskerMeta = core.getMaskerMeta(this.adapterType) || {};
		this.maskerMeta.format = this.options['format'] || this.maskerMeta.format;
		if(this.dataModel){
			this.dataModel.on(this.field + '.format.' +  DataTable.ON_CURRENT_META_CHANGE, function(event){
				self.setFormat(event.newValue)
			});
		}

		if(this.dataModel && !this.options['format'])
			this.options.format = this.dataModel.getMeta(this.field, "format")

		if(!this.options['format']){
			if(this.options.type === 'u-date'){
				this.options.format = "YYYY-MM-DD";
			}else if(this.options.type === 'year'){
				this.options.format = "YYYY";
			}else if(this.options.type === 'month'){
				this.options.format = "MM";
			}else if(this.options.type === 'yearmonth'){
				this.options.format = "YYYY-MM";
			}else{
				this.options.format = "YYYY-MM-DD HH:mm:ss";
			}
		}
		format = this.options.format;
		this.maskerMeta.format = format || this.maskerMeta.format

		this.startField = this.options.startField?this.options.startField : this.dataModel.getMeta(this.field, "startField");

		this.endField = this.options.endField?this.options.endField : this.dataModel.getMeta(this.field, "endField");

		// this.formater = new $.DateFormater(this.maskerMeta.format);
		// this.masker = new DateTimeMasker(this.maskerMeta);
		this.op = {};
		var mobileDateFormat = "", mobileTimeFormat = "", dateOrder = "", timeOrder = "";
		if(env.isMobile){
			switch (format) {
				case "YYYY-MM-DD":
					mobileDateFormat = "yy-mm-dd";
					dateOrder = mobileDateFormat.replace(/-/g, '');
					break;
				case "YYYY-MM-DD HH:mm":
					mobileDateFormat = "yy-mm-dd";
					mobileTimeFormat = "HH:ii";
					dateOrder = mobileDateFormat.replace(/-/g, '');
					timeOrder = mobileTimeFormat.replace(/\:/g, '');
					break;
				case "YYYY-MM":
					mobileDateFormat = "yy-mm";
					dateOrder = mobileDateFormat.replace(/-/g, '');
					break;
				default:
					mobileDateFormat = "yy-mm-dd";
					mobileTimeFormat = "HH:ii:ss";
					dateOrder = mobileDateFormat.replace(/-/g, '');
					timeOrder = mobileTimeFormat.replace(/\:/g, '');
			}

			this.op = {
				theme:"ios",
				mode:"scroller",
				lang: "zh",
				cancelText: null,
				dateFormat: mobileDateFormat,
				timeWheels: timeOrder,
				dateWheels: dateOrder,
				timeFormat: mobileTimeFormat,
				onSelect:function(val){
					if(typeof self.options.beforeValueChangeFun == 'function'){
				        if(!self.options.beforeValueChangeFun.call(this,this.pickerDate)){
				            return;
				        }
				    }
					self.setValue(val);
				}
			}
			this._span = this.element.querySelector("span");
			this.element = this.element.querySelector("input");
			this.element.setAttribute('readonly','readonly');
			if (this._span){
		        on(this._span, 'click', function(e){
		            self.element.focus();
		            stopEvent(e);
		        });
		    }
			if(this.adapterType == 'date'){
				$(this.element).mobiscroll().date(this.op);
			}else{
				$(this.element).mobiscroll().datetime(this.op);
			}
		}else{
			this.comp = new DateTimePicker({el:this.element,format:this.maskerMeta.format,showFix:this.options.showFix,beforeValueChangeFun:this.beforeValueChangeFun});
		}

		this.element['u.DateTimePicker'] = this.comp;

		if(!env.isMobile){
			this.comp.on('select', function(event){
				self.setValue(event.value);
			});
		}

		this.setStartField(this.startField);
		this.setEndField(this.endField);
        if(!env.isMobile){
			// 校验
			this.comp.on('validate', function(event){
				self.doValidate();
			});
		}
	},

	setEndField: function(endField){
		var self = this;
		self.endField = endField;
		if(self.dataModel){
			if(self.endField){
				self.dataModel.ref(self.endField).subscribe(function(value) {
					if(env.isMobile){
						var valueObj = date.getDateObj(value);
						self.op.minDate = valueObj;
						if(self.adapterType == 'date'){
							$(self.element).mobiscroll().date(self.op);
						}else{
							$(self.element).mobiscroll().datetime(self.op);
						}
						var nowDate = date.getDateObj(self.dataModel.getValue(self.field));
						if(nowDate < valueObj || !value){
							self.dataModel.setValue(self.field,'');
						}
					}else{
						self.comp.setEndDate(value);
						if(self.comp.date > date.getDateObj(value) || !value){
							self.dataModel.setValue(self.field,'');
						}
					}

				});
			}

			if(self.endField){
				var endValue = self.dataModel.getValue(self.endField);
				if(endValue){
					if(env.isMobile){
						self.op.minDate = date.getDateObj(endValue);
						if(self.adapterType == 'date'){
							$(self.element).mobiscroll().date(self.op);
						}else{
							$(self.element).mobiscroll().datetime(self.op);
						}
					}else{
						self.comp.setEndDate(endValue);
					}
				}
			}
		}
	},

	setStartField: function(startField){
		var self = this;
		self.startField = startField;
		if(self.dataModel){
			if(self.startField){
				self.dataModel.ref(self.startField).subscribe(function(value) {
					if(env.isMobile){
						value = date.getDateObj(value);

						var valueObj = self.setMobileStartDate(value, self.options.format);
						self.op.minDate = valueObj;
						if(self.adapterType == 'date'){
							$(self.element).mobiscroll().date(self.op);
						}else{
							$(self.element).mobiscroll().datetime(self.op);
						}
						var nowDate = date.getDateObj(self.dataModel.getValue(self.field));
						if(nowDate < valueObj || !value){
							self.dataModel.setValue(self.field,'');
						}
					}else{
						self.comp.setStartDate(value, self.options.format);
						if(self.comp.date < date.getDateObj(value) || !value){
							self.dataModel.setValue(self.field,'');
						}
					}

				});
			}
			if(self.startField){
				var startValue = self.dataModel.getValue(self.startField);
				if(startValue){
					if(env.isMobile){
						startValue = date.getDateObj(startValue);
						self.op.minDate = self.setMobileStartDate(startValue, self.options.format);
						if(self.adapterType == 'date'){
							$(self.element).mobiscroll().date(self.op);
						}else{
							$(self.element).mobiscroll().datetime(self.op);
						}
					}else{
						self.comp.setStartDate(startValue, self.options.format);
					}
				}
			}
		}
	},

	setMobileStartDate: function (startDate, type) {

	    if(startDate){
	        switch (type) {
	            case 'YYYY-MM':
	                startDate = date.add(startDate, 'M', 1);
	                break;
	            case 'YYYY-MM-DD':
	                startDate = date.add(startDate, 'd', 1);
	                break;
	        }
	    }
	    return startDate;
	},

	modelValueChange: function(value){
		if (this.slice) return;
		this.trueValue = value;
		if(env.isMobile){
			if(value){
				value = date.format(value,this.options.format);
				$(this.element).scroller('setDate', date.getDateObj(value), true);
			}
		}else{
			this.comp.setDate(value);
		}

	},
	setFormat: function(format){
		if (this.maskerMeta.format == format) return;
		this.options.format = format;
		this.maskerMeta.format = format;
		if(!env.isMobile)
			this.comp.setFormat(format);
		// this.formater = new $.DateFormater(this.maskerMeta.format);
		// this.masker = new DateTimeMasker(this.maskerMeta);
	},
	setValue: function (value) {
		value = date.format(value,this.options.format);
        this.trueValue = this.formater ? this.formater.format(value) : value;
        this.showValue = this.masker ? this.masker.format(this.trueValue).value : this.trueValue;
        this.setShowValue(this.showValue);
        this.slice = true;
        this.dataModel.setValue(this.field, this.trueValue);
        this.slice = false;
    },
    setEnable: function(enable){
        if (enable === true || enable === 'true') {
            this.enable = true;
            if(env.isMobile){
            	this.element.removeAttribute('disabled');
            }else{
            	this.comp._input.removeAttribute('readonly');
            }
            removeClass(this.element.parentNode,'disablecover');
        } else if (enable === false || enable === 'false') {
            this.enable = false;
            if(env.isMobile){
            	this.element.setAttribute('disabled','disabled');
            }else{
            	this.comp._input.setAttribute('readonly', 'readonly');
            }
            addClass(this.element.parentNode,'disablecover');
        }
        if(!env.isMobile)
        	this.comp.setEnable(enable);
    }

});

compMgr.addDataAdapter({
	adapter: DateTimeAdapter,
	name: 'u-date'
});

compMgr.addDataAdapter({
	adapter: DateTimeAdapter,
	name: 'u-datetime'
});

export {DateTimeAdapter};
<|endoftext|>


<commit_before>/* globals $ */

'use strict';

describe('CMS.Modal', function () {
    fixture.setBase('cms/tests/frontend/unit/fixtures');

    it('creates a Modal class when document is ready', function () {
        expect(CMS.Modal).toBeDefined();
    });

    it('has public API', function () {
        expect(CMS.Modal.prototype.open).toEqual(jasmine.any(Function));
        expect(CMS.Modal.prototype.close).toEqual(jasmine.any(Function));
        expect(CMS.Modal.prototype.minimize).toEqual(jasmine.any(Function));
        expect(CMS.Modal.prototype.maximize).toEqual(jasmine.any(Function));
    });

    describe('instance', function () {
        it('has ui', function (done) {
            $(function () {
                var modal = new CMS.Modal();
                expect(modal.ui).toEqual(jasmine.any(Object));
                expect(Object.keys(modal.ui)).toContain('modal');
                expect(Object.keys(modal.ui)).toContain('body');
                expect(Object.keys(modal.ui)).toContain('window');
                expect(Object.keys(modal.ui)).toContain('toolbarLeftPart');
                expect(Object.keys(modal.ui)).toContain('minimizeButton');
                expect(Object.keys(modal.ui)).toContain('maximizeButton');
                expect(Object.keys(modal.ui)).toContain('title');
                expect(Object.keys(modal.ui)).toContain('titlePrefix');
                expect(Object.keys(modal.ui)).toContain('titleSuffix');
                expect(Object.keys(modal.ui)).toContain('resize');
                expect(Object.keys(modal.ui)).toContain('breadcrumb');
                expect(Object.keys(modal.ui)).toContain('closeAndCancel');
                expect(Object.keys(modal.ui)).toContain('modalButtons');
                expect(Object.keys(modal.ui)).toContain('modalBody');
                expect(Object.keys(modal.ui)).toContain('frame');
                expect(Object.keys(modal.ui)).toContain('shim');
                expect(Object.keys(modal.ui).length).toEqual(16);
                done();
            });
        });

        it('has options', function (done) {
            $(function () {
                var modal = new CMS.Modal();
                expect(modal.options).toEqual({
                    onClose: false,
                    minHeight: 400,
                    minWidth: 800,
                    modalDuration: 200,
                    newPlugin: false,
                    resizable: true,
                    maximizable: true,
                    minimizable: true
                });

                var modal2 = new CMS.Modal({ minHeight: 300, minWidth: 100 });
                expect(modal2.options).toEqual({
                    onClose: false,
                    minHeight: 300,
                    minWidth: 100,
                    modalDuration: 200,
                    newPlugin: false,
                    resizable: true,
                    maximizable: true,
                    minimizable: true
                });

                done();
            });
        });
    });

    describe('.open()', function () {
        beforeEach(function (done) {
            fixture.load('modal.html');
            delete CMS._newPlugin;
            CMS.API.Tooltip = {
                hide: jasmine.createSpy()
            };
            CMS.API.Toolbar = {
                open: jasmine.createSpy(),
                showLoader: jasmine.createSpy(),
                hideLoader: jasmine.createSpy()
            };
            $(function () {
                done();
            });
        });

        afterEach(function () {
            fixture.cleanup();
        });

        it('throws an error when no url or html options were passed', function () {
            var modal = new CMS.Modal();

            expect(modal.open.bind(modal, {})).toThrowError(
                Error, 'The arguments passed to "open" were invalid.'
            );
            expect(modal.open.bind(modal, { html: '' })).toThrowError(
                Error, 'The arguments passed to "open" were invalid.'
            );
            expect(modal.open.bind(modal, { url: '' })).toThrowError(
                Error, 'The arguments passed to "open" were invalid.'
            );
            expect(modal.open.bind(modal, { html: '

' })).not.toThrow();
            expect(modal.open.bind(modal, {
                url: '/base/cms/tests/frontend/unit/html/modal_iframe.html'
            })).not.toThrow();
        });

        it('does not open if there is a plugin creation in process', function () {
            var modal = new CMS.Modal();
            CMS._newPlugin = true;
            spyOn(modal, '_deletePlugin').and.callFake(function () {
                return false;
            });

            expect(modal.open({ html: '

' })).toEqual(false);
        });

        it('confirms if the user wants to remove freshly created plugin when opening new modal', function () {
            var modal = new CMS.Modal();
            spyOn(CMS.Navigation.prototype, 'initialize').and.callFake(function () {
                return {};
            });
            jasmine.clock().install(); // stop timeout that does initialStates
            CMS.API.Toolbar = new CMS.Toolbar();
            CMS._newPlugin = {
                delete: '/delete-url',
                breadcrumb: [{ title: 'Fresh plugin' }]
            };

            CMS.config = $.extend(CMS.config, {
                csrf: 'custom-token',
                lang: {
                    confirmEmpty: 'Question about {1}?'
                }
            });

            spyOn(modal, '_deletePlugin').and.callThrough();
            jasmine.Ajax.install();
            spyOn(CMS.API.Toolbar, 'openAjax').and.callThrough();
            spyOn(CMS.API.Helpers, 'secureConfirm').and.callFake(function () {
                return false;
            });

            expect(modal.open({ html: '

' })).toEqual(false);
            expect(CMS.API.Toolbar.openAjax).toHaveBeenCalledWith({
                url: '/delete-url',
                post: '{ "csrfmiddlewaretoken": "custom-token" }',
                text: 'Question about Fresh plugin?',
                callback: jasmine.any(Function)
            });
            jasmine.Ajax.uninstall();
            jasmine.clock().uninstall();
        });

        it('should be chainable', function () {
            var modal = new CMS.Modal();

            expect(modal.open({ html: '

' })).toEqual(modal);
        });

        it('hides the tooltip', function () {
            var modal = new CMS.Modal();

            modal.open({ html: '

' });
            expect(CMS.API.Tooltip.hide).toHaveBeenCalled();
        });

        it('triggers load events on instance and the DOM node', function () {
            var modal = new CMS.Modal();

            spyOn(modal, 'trigger');
            var spyEvent = spyOnEvent(modal.ui.modal, 'cms.modal.load');
            modal.open({ html: '

' });

            expect(modal.trigger).toHaveBeenCalledWith('cms.modal.load');
            expect(spyEvent).toHaveBeenTriggered();
            expect(modal.trigger).toHaveBeenCalledWith('cms.modal.loaded');
        });

        it('sets CMS._newPlugin if we are opening a plugin creation modal', function () {
            var modal = new CMS.Modal({
                newPlugin: {
                    something: true
                }
            });

            modal.open({ html: '

' });
            expect(CMS._newPlugin).toEqual({ something: true });
        });

        it('applies correct state to modal controls', function () {
            var modal;
            modal = new CMS.Modal();
            modal.open({ html: '

' });
            expect(modal.ui.resize).toBeVisible();
            expect(modal.ui.minimizeButton).toBeVisible();
            expect(modal.ui.maximizeButton).toBeVisible();

            modal = new CMS.Modal({ resizable: false });
            modal.open({ html: '

' });
            expect(modal.ui.resize).not.toBeVisible();
            expect(modal.ui.minimizeButton).toBeVisible();
            expect(modal.ui.maximizeButton).toBeVisible();

            modal = new CMS.Modal({ resizable: true });
            modal.open({ html: '

' });
            expect(modal.ui.resize).toBeVisible();
            expect(modal.ui.minimizeButton).toBeVisible();
            expect(modal.ui.maximizeButton).toBeVisible();

            modal = new CMS.Modal({ minimizable: false });
            modal.open({ html: '

' });
            expect(modal.ui.resize).toBeVisible();
            expect(modal.ui.minimizeButton).not.toBeVisible();
            expect(modal.ui.maximizeButton).toBeVisible();

            modal = new CMS.Modal({ minimizable: true });
            modal.open({ html: '

' });
            expect(modal.ui.resize).toBeVisible();
            expect(modal.ui.minimizeButton).toBeVisible();
            expect(modal.ui.maximizeButton).toBeVisible();

            modal = new CMS.Modal({ maximizable: false });
            modal.open({ html: '

' });
            expect(modal.ui.resize).toBeVisible();
            expect(modal.ui.minimizeButton).toBeVisible();
            expect(modal.ui.maximizeButton).not.toBeVisible();

            modal = new CMS.Modal({ maximizable: true });
            modal.open({ html: '

' });
            expect(modal.ui.resize).toBeVisible();
            expect(modal.ui.minimizeButton).toBeVisible();
            expect(modal.ui.maximizeButton).toBeVisible();
        });

        it('resets minimized state if the modal was already minimized', function () {
            var modal = new CMS.Modal();

            modal.open({ html: '

' });
            modal.minimize();
            expect(modal.minimized).toEqual(true);

            spyOn(modal, 'minimize').and.callThrough();

            modal.open({ html: '' });
            expect(modal.minimized).toEqual(false);
            expect(modal.minimize).toHaveBeenCalled();
            expect(modal.minimize.calls.count()).toEqual(1);
        });

        it('clears breadcrumbs and buttons if they exist', function () {
            var modal = new CMS.Modal();
            modal.ui.modal.addClass('cms-modal-has-breadcrumb');
            modal.ui.modalButtons.html('
button
');
            modal.ui.breadcrumb.html('
breadcrumbs
');

            modal.open({ html: '

' });
            expect(modal.ui.modal).not.toHaveClass('cms-modal-has-breadcrumb');
            expect(modal.ui.modalButtons).toBeEmpty();
            expect(modal.ui.breadcrumb).toBeEmpty();
        });
    });

    describe('.minimize()', function () {
        beforeEach(function (done) {
            fixture.load('modal.html');
            CMS.API.Tooltip = {
                hide: jasmine.createSpy()
            };
            CMS.API.Toolbar = {
                open: jasmine.createSpy(),
                showLoader: jasmine.createSpy(),
                hideLoader: jasmine.createSpy()
            };
            $(function () {
                done();
            });
        });

        afterEach(function () {
            fixture.cleanup();
        });

        it('minimizes the modal', function () {
            var modal = new CMS.Modal();

            expect(modal.minimized).toEqual(false);
            modal.open({ html: '

' });
            modal.minimize();

            expect(modal.minimized).toEqual(true);
            expect(modal.ui.body).toHaveClass('cms-modal-minimized');
            expect(modal.ui.modal).toHaveCss({
                left: '50px'
            });

            modal.minimize(); // restore
        });

        it('opens the toolbar', function () {
            var modal = new CMS.Modal();

            modal.open({ html: '

' });
            modal.minimize();

            expect(CMS.API.Toolbar.open).toHaveBeenCalled();
            modal.minimize(); // restore
        });

        it('stores the css data to be able to restore a modal', function () {
            var modal = new CMS.Modal();

            modal.open({ html: '

' });
            modal.minimize();

            var css = modal.ui.modal.data('css');
            expect(css).toEqual(jasmine.any(Object));
            expect(Object.keys(css)).toContain('margin-left');
            expect(Object.keys(css)).toContain('margin-top');
            expect(Object.keys(css)).toContain('top');
            expect(Object.keys(css)).toContain('left');

            modal.minimize(); // restore
        });

        it('doesnt minimize maximized modal');

        it('restores modal if it was already minimized');
    });

    describe('.maximize()', function () {

    });

    describe('.close()', function () {

    });
});
<commit_msg>minimize tests [use saucelabs]<commit_after>/* globals $ */

'use strict';

describe('CMS.Modal', function () {
    fixture.setBase('cms/tests/frontend/unit/fixtures');

    it('creates a Modal class when document is ready', function () {
        expect(CMS.Modal).toBeDefined();
    });

    it('has public API', function () {
        expect(CMS.Modal.prototype.open).toEqual(jasmine.any(Function));
        expect(CMS.Modal.prototype.close).toEqual(jasmine.any(Function));
        expect(CMS.Modal.prototype.minimize).toEqual(jasmine.any(Function));
        expect(CMS.Modal.prototype.maximize).toEqual(jasmine.any(Function));
    });

    describe('instance', function () {
        it('has ui', function (done) {
            $(function () {
                var modal = new CMS.Modal();
                expect(modal.ui).toEqual(jasmine.any(Object));
                expect(Object.keys(modal.ui)).toContain('modal');
                expect(Object.keys(modal.ui)).toContain('body');
                expect(Object.keys(modal.ui)).toContain('window');
                expect(Object.keys(modal.ui)).toContain('toolbarLeftPart');
                expect(Object.keys(modal.ui)).toContain('minimizeButton');
                expect(Object.keys(modal.ui)).toContain('maximizeButton');
                expect(Object.keys(modal.ui)).toContain('title');
                expect(Object.keys(modal.ui)).toContain('titlePrefix');
                expect(Object.keys(modal.ui)).toContain('titleSuffix');
                expect(Object.keys(modal.ui)).toContain('resize');
                expect(Object.keys(modal.ui)).toContain('breadcrumb');
                expect(Object.keys(modal.ui)).toContain('closeAndCancel');
                expect(Object.keys(modal.ui)).toContain('modalButtons');
                expect(Object.keys(modal.ui)).toContain('modalBody');
                expect(Object.keys(modal.ui)).toContain('frame');
                expect(Object.keys(modal.ui)).toContain('shim');
                expect(Object.keys(modal.ui).length).toEqual(16);
                done();
            });
        });

        it('has options', function (done) {
            $(function () {
                var modal = new CMS.Modal();
                expect(modal.options).toEqual({
                    onClose: false,
                    minHeight: 400,
                    minWidth: 800,
                    modalDuration: 200,
                    newPlugin: false,
                    resizable: true,
                    maximizable: true,
                    minimizable: true
                });

                var modal2 = new CMS.Modal({ minHeight: 300, minWidth: 100 });
                expect(modal2.options).toEqual({
                    onClose: false,
                    minHeight: 300,
                    minWidth: 100,
                    modalDuration: 200,
                    newPlugin: false,
                    resizable: true,
                    maximizable: true,
                    minimizable: true
                });

                done();
            });
        });
    });

    describe('.open()', function () {
        beforeEach(function (done) {
            fixture.load('modal.html');
            delete CMS._newPlugin;
            CMS.API.Tooltip = {
                hide: jasmine.createSpy()
            };
            CMS.API.Toolbar = {
                open: jasmine.createSpy(),
                showLoader: jasmine.createSpy(),
                hideLoader: jasmine.createSpy()
            };
            $(function () {
                done();
            });
        });

        afterEach(function () {
            fixture.cleanup();
        });

        it('throws an error when no url or html options were passed', function () {
            var modal = new CMS.Modal();

            expect(modal.open.bind(modal, {})).toThrowError(
                Error, 'The arguments passed to "open" were invalid.'
            );
            expect(modal.open.bind(modal, { html: '' })).toThrowError(
                Error, 'The arguments passed to "open" were invalid.'
            );
            expect(modal.open.bind(modal, { url: '' })).toThrowError(
                Error, 'The arguments passed to "open" were invalid.'
            );
            expect(modal.open.bind(modal, { html: '

' })).not.toThrow();
            expect(modal.open.bind(modal, {
                url: '/base/cms/tests/frontend/unit/html/modal_iframe.html'
            })).not.toThrow();
        });

        it('does not open if there is a plugin creation in process', function () {
            var modal = new CMS.Modal();
            CMS._newPlugin = true;
            spyOn(modal, '_deletePlugin').and.callFake(function () {
                return false;
            });

            expect(modal.open({ html: '

' })).toEqual(false);
        });

        it('confirms if the user wants to remove freshly created plugin when opening new modal', function () {
            var modal = new CMS.Modal();
            spyOn(CMS.Navigation.prototype, 'initialize').and.callFake(function () {
                return {};
            });
            jasmine.clock().install(); // stop timeout that does initialStates
            CMS.API.Toolbar = new CMS.Toolbar();
            CMS._newPlugin = {
                delete: '/delete-url',
                breadcrumb: [{ title: 'Fresh plugin' }]
            };

            CMS.config = $.extend(CMS.config, {
                csrf: 'custom-token',
                lang: {
                    confirmEmpty: 'Question about {1}?'
                }
            });

            spyOn(modal, '_deletePlugin').and.callThrough();
            jasmine.Ajax.install();
            spyOn(CMS.API.Toolbar, 'openAjax').and.callThrough();
            spyOn(CMS.API.Helpers, 'secureConfirm').and.callFake(function () {
                return false;
            });

            expect(modal.open({ html: '

' })).toEqual(false);
            expect(CMS.API.Toolbar.openAjax).toHaveBeenCalledWith({
                url: '/delete-url',
                post: '{ "csrfmiddlewaretoken": "custom-token" }',
                text: 'Question about Fresh plugin?',
                callback: jasmine.any(Function)
            });
            jasmine.Ajax.uninstall();
            jasmine.clock().uninstall();
        });

        it('should be chainable', function () {
            var modal = new CMS.Modal();

            expect(modal.open({ html: '

' })).toEqual(modal);
        });

        it('hides the tooltip', function () {
            var modal = new CMS.Modal();

            modal.open({ html: '

' });
            expect(CMS.API.Tooltip.hide).toHaveBeenCalled();
        });

        it('triggers load events on instance and the DOM node', function () {
            var modal = new CMS.Modal();

            spyOn(modal, 'trigger');
            var spyEvent = spyOnEvent(modal.ui.modal, 'cms.modal.load');
            modal.open({ html: '

' });

            expect(modal.trigger).toHaveBeenCalledWith('cms.modal.load');
            expect(spyEvent).toHaveBeenTriggered();
            expect(modal.trigger).toHaveBeenCalledWith('cms.modal.loaded');
        });

        it('sets CMS._newPlugin if we are opening a plugin creation modal', function () {
            var modal = new CMS.Modal({
                newPlugin: {
                    something: true
                }
            });

            modal.open({ html: '

' });
            expect(CMS._newPlugin).toEqual({ something: true });
        });

        it('applies correct state to modal controls', function () {
            var modal;
            modal = new CMS.Modal();
            modal.open({ html: '

' });
            expect(modal.ui.resize).toBeVisible();
            expect(modal.ui.minimizeButton).toBeVisible();
            expect(modal.ui.maximizeButton).toBeVisible();

            modal = new CMS.Modal({ resizable: false });
            modal.open({ html: '

' });
            expect(modal.ui.resize).not.toBeVisible();
            expect(modal.ui.minimizeButton).toBeVisible();
            expect(modal.ui.maximizeButton).toBeVisible();

            modal = new CMS.Modal({ resizable: true });
            modal.open({ html: '

' });
            expect(modal.ui.resize).toBeVisible();
            expect(modal.ui.minimizeButton).toBeVisible();
            expect(modal.ui.maximizeButton).toBeVisible();

            modal = new CMS.Modal({ minimizable: false });
            modal.open({ html: '

' });
            expect(modal.ui.resize).toBeVisible();
            expect(modal.ui.minimizeButton).not.toBeVisible();
            expect(modal.ui.maximizeButton).toBeVisible();

            modal = new CMS.Modal({ minimizable: true });
            modal.open({ html: '

' });
            expect(modal.ui.resize).toBeVisible();
            expect(modal.ui.minimizeButton).toBeVisible();
            expect(modal.ui.maximizeButton).toBeVisible();

            modal = new CMS.Modal({ maximizable: false });
            modal.open({ html: '

' });
            expect(modal.ui.resize).toBeVisible();
            expect(modal.ui.minimizeButton).toBeVisible();
            expect(modal.ui.maximizeButton).not.toBeVisible();

            modal = new CMS.Modal({ maximizable: true });
            modal.open({ html: '

' });
            expect(modal.ui.resize).toBeVisible();
            expect(modal.ui.minimizeButton).toBeVisible();
            expect(modal.ui.maximizeButton).toBeVisible();
        });

        it('resets minimized state if the modal was already minimized', function () {
            var modal = new CMS.Modal();

            modal.open({ html: '

' });
            modal.minimize();
            expect(modal.minimized).toEqual(true);

            spyOn(modal, 'minimize').and.callThrough();

            modal.open({ html: '' });
            expect(modal.minimized).toEqual(false);
            expect(modal.minimize).toHaveBeenCalled();
            expect(modal.minimize.calls.count()).toEqual(1);
        });

        it('clears breadcrumbs and buttons if they exist', function () {
            var modal = new CMS.Modal();
            modal.ui.modal.addClass('cms-modal-has-breadcrumb');
            modal.ui.modalButtons.html('
button
');
            modal.ui.breadcrumb.html('
breadcrumbs
');

            modal.open({ html: '

' });
            expect(modal.ui.modal).not.toHaveClass('cms-modal-has-breadcrumb');
            expect(modal.ui.modalButtons).toBeEmpty();
            expect(modal.ui.breadcrumb).toBeEmpty();
        });
    });

    describe('.minimize()', function () {
        beforeEach(function (done) {
            fixture.load('modal.html');
            CMS.API.Tooltip = {
                hide: jasmine.createSpy()
            };
            CMS.API.Toolbar = {
                open: jasmine.createSpy(),
                showLoader: jasmine.createSpy(),
                hideLoader: jasmine.createSpy()
            };
            $(function () {
                done();
            });
        });

        afterEach(function () {
            fixture.cleanup();
        });

        it('minimizes the modal', function () {
            var modal = new CMS.Modal();

            expect(modal.minimized).toEqual(false);
            modal.open({ html: '

' });
            modal.minimize();

            expect(modal.minimized).toEqual(true);
            expect(modal.ui.body).toHaveClass('cms-modal-minimized');
            expect(modal.ui.modal).toHaveCss({
                left: '50px'
            });

            modal.minimize(); // restore
        });

        it('opens the toolbar', function () {
            var modal = new CMS.Modal();

            modal.open({ html: '

' });
            modal.minimize();

            expect(CMS.API.Toolbar.open).toHaveBeenCalled();
            modal.minimize(); // restore
        });

        it('stores the css data to be able to restore a modal', function () {
            var modal = new CMS.Modal();

            modal.open({ html: '

' });
            modal.minimize();

            var css = modal.ui.modal.data('css');
            expect(css).toEqual(jasmine.any(Object));
            expect(Object.keys(css)).toContain('margin-left');
            expect(Object.keys(css)).toContain('margin-top');
            expect(Object.keys(css)).toContain('top');
            expect(Object.keys(css)).toContain('left');

            modal.minimize(); // restore
        });

        it('doesnt minimize maximized modal', function () {
            var modal = new CMS.Modal();

            modal.maximized = true;
            expect(modal.minimize()).toEqual(false);
            expect(CMS.API.Toolbar.open).not.toHaveBeenCalled();
            expect(modal.ui.body).not.toHaveClass('cms-modal-minimized');
        });

        it('restores modal if it was already minimized', function () {
            var modal = new CMS.Modal();
            modal.open({ html: '

' });
            modal.minimize();

            expect(modal.minimized).toEqual(true);
            expect(modal.ui.body).toHaveClass('cms-modal-minimized');

            modal.minimize();

            expect(modal.minimized).toEqual(false);
            expect(modal.ui.body).not.toHaveClass('cms-modal-minimized');
        });
    });

    describe('.maximize()', function () {

    });

    describe('.close()', function () {

    });
});
<|endoftext|>


<commit_before>/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Ajax.org Code Editor (ACE).
 *
 * The Initial Developer of the Original Code is
 * Ajax.org B.V.
 * Portions created by the Initial Developer are Copyright (C) 2010
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *      Fabian Jakobs <fabian AT ajax DOT org>
 *      Julian Viereck <julian.viereck@gmail.com>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {

var dom = require("pilot/dom");

var Gutter = function(parentEl) {
    this.element = document.createElement("div");
    this.element.className = "ace_layer ace_gutter-layer";
    parentEl.appendChild(this.element);

    this.$breakpoints = [];
    this.$annotations = [];
    this.$decorations = [];
};

(function() {

    this.setSession = function(session) {
        this.session = session;
    };

    this.addGutterDecoration = function(row, className){
        if (!this.$decorations[row])
            this.$decorations[row] = "";
        this.$decorations[row] += " ace_" + className;
    }

    this.removeGutterDecoration = function(row, className){
        this.$decorations[row] = this.$decorations[row].replace(" ace_" + className, "");
    };

    this.setBreakpoints = function(rows) {
        this.$breakpoints = rows.concat();
    };

    this.setAnnotations = function(annotations) {
        // iterate over sparse array
        this.$annotations = [];
        for (var row in annotations) {
            var rowAnnotations = annotations[row];
            if (!rowAnnotations)
                continue;

            var rowInfo = this.$annotations[row] = {
                text: []
            };
            for (var i=0; i<rowAnnotations.length; i++) {
                var annotation = rowAnnotations[i];
                rowInfo.text.push(annotation.text.replace(/"/g, """).replace(/'/g, "’").replace(/</, "<"));
                var type = annotation.type;
                if (type == "error")
                    rowInfo.className = "ace_error";
                else if (type == "warning" && rowInfo.className != "ace_error")
                    rowInfo.className = "ace_warning";
                else if (type == "info" && (!rowInfo.className))
                    rowInfo.className = "ace_info";
            }
        }
    };

    this.update = function(config) {
        this.$config = config;

        var html = [];
        for ( var i = config.firstRow; i <= config.lastRow; i++) {
            var annotation = this.$annotations[i] || {
                className: "",
                text: []
            };
            html.push("
", (i+1), "
");
            html.push("
");
        }
		this.element = dom.setInnerHtml(this.element, html.join(""));
        this.element.style.height = config.minHeight + "px";
    };

}).call(Gutter.prototype);

exports.Gutter = Gutter;

});
<commit_msg>fix https://github.com/ajaxorg/ace/issues#issue/80<commit_after>/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Ajax.org Code Editor (ACE).
 *
 * The Initial Developer of the Original Code is
 * Ajax.org B.V.
 * Portions created by the Initial Developer are Copyright (C) 2010
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *      Fabian Jakobs <fabian AT ajax DOT org>
 *      Julian Viereck <julian.viereck@gmail.com>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {

var dom = require("pilot/dom");

var Gutter = function(parentEl) {
    this.element = document.createElement("div");
    this.element.className = "ace_layer ace_gutter-layer";
    parentEl.appendChild(this.element);

    this.$breakpoints = [];
    this.$annotations = [];
    this.$decorations = [];
};

(function() {

    this.setSession = function(session) {
        this.session = session;
    };

    this.addGutterDecoration = function(row, className){
        if (!this.$decorations[row])
            this.$decorations[row] = "";
        this.$decorations[row] += " ace_" + className;
    }

    this.removeGutterDecoration = function(row, className){
        this.$decorations[row] = this.$decorations[row].replace(" ace_" + className, "");
    };

    this.setBreakpoints = function(rows) {
        this.$breakpoints = rows.concat();
    };

    this.setAnnotations = function(annotations) {
        // iterate over sparse array
        this.$annotations = [];
        for (var row in annotations) if (annotations.hasOwnProperty(row)) {
            var rowAnnotations = annotations[row];
            if (!rowAnnotations)
                continue;

            var rowInfo = this.$annotations[row] = {
                text: []
            };
            for (var i=0; i<rowAnnotations.length; i++) {
                var annotation = rowAnnotations[i];
                rowInfo.text.push(annotation.text.replace(/"/g, """).replace(/'/g, "’").replace(/</, "<"));
                var type = annotation.type;
                if (type == "error")
                    rowInfo.className = "ace_error";
                else if (type == "warning" && rowInfo.className != "ace_error")
                    rowInfo.className = "ace_warning";
                else if (type == "info" && (!rowInfo.className))
                    rowInfo.className = "ace_info";
            }
        }
    };

    this.update = function(config) {
        this.$config = config;

        var html = [];
        for ( var i = config.firstRow; i <= config.lastRow; i++) {
            var annotation = this.$annotations[i] || {
                className: "",
                text: []
            };
            html.push("
", (i+1), "
");
            html.push("
");
        }
		this.element = dom.setInnerHtml(this.element, html.join(""));
        this.element.style.height = config.minHeight + "px";
    };

}).call(Gutter.prototype);

exports.Gutter = Gutter;

});
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 Stephen Peasley (http://www.speasley.com)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * Version 2.0.0
 * Made in Canada
 */
;(function($) {

	'use strict';

  var $element = null;
  var occasions = null;

  // internal functions
	var internals = {}

  var init = internals.init = function(settings,element) {
    var files = ['occasions.json'];
    if(settings.country != 'none') { files.push(settings.country.toLowerCase()+'.json'); }
    if(settings.sect != 'none') { files.push(settings.sect.toLowerCase()+'.json'); }
    var loaded = 0;
    for (var i=0; i < files.length; i++) {
      $.ajax({
        async: true,
        url: settings.path+files[i],
        type:'get',
        dataType:'json',
        success: function(data) {
          if(occasions == null) {
            occasions = data;
          }else{
            mergeHashes(occasions,data);
          }
          loaded++;
          if(loaded===files.length) {
            main(settings,element);
          }
        }
      });
    }
  }

  var mergeHashes = internals.mergeHashes = function(obj, src) {
    Object.keys(src).forEach(function(key) { obj[key] = src[key]; });
    return obj;
  }

  var todaysDate = internals.todaysDate = function(override) {
    var today = new Date();
    var now_month = today.getMonth()+1;
    var now_day = today.getDate();
    var now_date = (now_month<10 ? '0' : '') + now_month + '/' + (now_day<10 ? '0' : '') + now_day;
    if (override) {
      now_date = override;
    }
    return now_date;
  }

	var timestamp = internals.timestamp = function(month,day) {
    var today = new Date();
    var ts = new Date(today.getFullYear()+'-'+today.getMonth()+'-'+today.getDate()).getTime() / 1000;
    return ts;
  };

  var main = internals.main = function(settings,element) {
    var todays_date = todaysDate(settings.date_override);
    if(occasions[todays_date]!=null) {
      element.addClass(occasions[todays_date]);
      element.occasion = occasions[todays_date];
      settings.onSuccess.call(element);
    }
  }

  $.fn.occasions = function() {

    $element = $(this);
    var settings = $.extend({
      country: 'none',
      internals: false,
      path: '',
      sect: 'none',
      onSuccess: function() {}
    }, arguments[0] || {});

    if (settings.internals) {
      return internals;
    }

    var $element = $(this);
    init(settings,$element);

    return this;
  };
})(jQuery);
<commit_msg>Little reorganization<commit_after>/*
 * Copyright (c) 2014 Stephen Peasley (http://www.speasley.com)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * Version 2.0.0
 * Made in Canada
 */
;(function($) {

	'use strict';

  $.fn.occasions = function() {

    $element = this;

    var settings = $.extend({
      country: 'none',
      internals: false,
      path: '',
      sect: 'none',
      onSuccess: function() {}
    }, arguments[0] || {});

    if (settings.internals) {
      return internals;
    }

    return this.each(function() {
      init(settings,$element);
    });

  };

  var $element = null;
  var occasions = null;

  // internal functions
	var internals = {}

  var init = internals.init = function(settings,element) {
    var files = ['occasions.json'];
    if(settings.country != 'none') { files.push(settings.country.toLowerCase()+'.json'); }
    if(settings.sect != 'none') { files.push(settings.sect.toLowerCase()+'.json'); }
    var loaded = 0;
    for (var i=0; i < files.length; i++) {
      $.ajax({
        async: true,
        url: settings.path+files[i],
        type:'get',
        dataType:'json',
        success: function(data) {
          if(occasions == null) {
            occasions = data;
          }else{
            mergeHashes(occasions,data);
          }
          loaded++;
          if(loaded===files.length) {
            main(settings,element);
          }
        }
      });
    }
  }

  var mergeHashes = internals.mergeHashes = function(obj, src) {
    Object.keys(src).forEach(function(key) { obj[key] = src[key]; });
    return obj;
  }

  var todaysDate = internals.todaysDate = function(override) {
    var today = new Date();
    var now_month = today.getMonth()+1;
    var now_day = today.getDate();
    var now_date = (now_month<10 ? '0' : '') + now_month + '/' + (now_day<10 ? '0' : '') + now_day;
    if (override) {
      now_date = override;
    }
    return now_date;
  }

	var timestamp = internals.timestamp = function(month,day) {
    var today = new Date();
    var ts = new Date(today.getFullYear()+'-'+today.getMonth()+'-'+today.getDate()).getTime() / 1000;
    return ts;
  };

  var main = internals.main = function(settings,element) {
    var todays_date = todaysDate(settings.date_override);
    if(occasions[todays_date]!=null) {
      console.log(element.css({'background':'red'}));
      element.addClass(occasions[todays_date]);
      element.occasion = occasions[todays_date];
      settings.onSuccess.call(element);
    }
  }

})(jQuery);
<|endoftext|>


<commit_before>$(function() {
  $('#sign-in-modal').modal();
  seekLogic();

  $('.list-group-item').click(function() {
    console.log("hmm");
  });

});

$('#magic2').click(function() {
  console.log("hi");
  window.location = '/loggedin.html';
});

var seekLogic = function() {
  var seekPos;

  $('.player-progress-bar-wrapper').mousemove(function(e) {
    seekPos = e.pageX - $(this).children().offset().left - 5;
  });

  $('.player-progress-bar-wrapper').click(function(e) {
    console.log($(this).children().width())
    console.log("seekpos: "+seekPos+". width: "+$(this).children().width());
    var time = seekPos / $(this).children().width();
    window.iguanaScope.seekTo(time);
  });
};
<commit_msg>Random whitespace<commit_after>$(function() {
  $('#sign-in-modal').modal();
  seekLogic();

  $('.list-group-item').click(function() {
    console.log("hmm");
  });

});

$('#magic2').click(function() {
  console.log("hi");
  window.location = '/loggedin.html';
});

var seekLogic = function() {
  var seekPos;

  $('.player-progress-bar-wrapper').mousemove(function(e) {
    seekPos = e.pageX - $(this).children().offset().left - 5;
  });

  $('.player-progress-bar-wrapper').click(function(e) {
    console.log($(this).children().width())
    console.log("seekpos: "+seekPos+". width: "+$(this).children().width());
    var time = seekPos / $(this).children().width();
    window.iguanaScope.seekTo(time);
  });
};
<|endoftext|>


<commit_before>var app = angular.module('odin.categoryControllers', []);

app.factory('model', function($resource) {
    return $resource();
});

function CategoryListController($scope, $location, rest, $rootScope, $routeParams, $httpParamSerializer) {
    $scope.activeCategories = [];
    $scope.activeCategory = $routeParams['categories.name'];
    $scope.url_api = $rootScope.url;
    $scope.activeCategory = $.isArray($scope.activeCategory) ? $scope.activeCategory[0] : $routeParams['categories.name'];
    $scope.modelName = "Category";
    $scope.type = "categories";
    $scope.showCategories = true;
    $scope.statistics = {};
    $scope.porcentual = {};
    $scope.totalStatistics = 0;
    $scope.hideCategoriesSidebar = function() {
        $rootScope.showBackdrop = false;
        $rootScope.showCategoriesSidebar = false;
    };

    rest().get({
        type: $scope.type,
        params: "orderBy=createdAt&sort=DESC"
    }, function(categories) {
        $scope.categories = categories.data;
        $scope.showCategories = false;

        $scope.categories.forEach(function(element) {
            $scope.statistics[element.id] = 0;
            $scope.porcentual[element.id] = 0;
        });

        rest().statistics({
            type: "datasets",
            params: "groupBy=category&action=download"
        }, function(statistics) {
            for (element in statistics.data) {
                var cat = statistics.data[element];
                $scope.statistics[element] = cat.count.GET;
                $scope.totalStatistics += cat.count.GET;
            }

            for (element in statistics.data) {
                $scope.porcentual[element] = $scope.statistics[element] * 100 / $scope.totalStatistics;;
            }
        });
    });
}
<commit_msg>Fixed coloring category in datasets.<commit_after>var app = angular.module('odin.categoryControllers', []);

app.factory('model', function($resource) {
    return $resource();
});

function CategoryListController($scope, $location, rest, $rootScope, $routeParams, $httpParamSerializer) {
    $scope.activeCategory = $routeParams['categories.name'];
    $scope.url_api = $rootScope.url;
    $scope.activeCategory = $.isArray($scope.activeCategory) ? $scope.activeCategory[0] : $routeParams['categories.name'];
    $scope.modelName = "Category";
    $scope.type = "categories";
    $scope.showCategories = true;
    $scope.statistics = {};
    $scope.porcentual = {};
    $scope.totalStatistics = 0;
    $scope.hideCategoriesSidebar = function() {
        $rootScope.showBackdrop = false;
        $rootScope.showCategoriesSidebar = false;
    };

    rest().get({
        type: $scope.type,
        params: "orderBy=createdAt&sort=DESC"
    }, function(categories) {
        $scope.categories = categories.data;
        $scope.showCategories = false;

        $scope.categories.forEach(function(element) {
            $scope.statistics[element.id] = 0;
            $scope.porcentual[element.id] = 0;
        });

        rest().statistics({
            type: "datasets",
            params: "groupBy=category&action=download"
        }, function(statistics) {
            for (element in statistics.data) {
                var cat = statistics.data[element];
                $scope.statistics[element] = cat.count.GET;
                $scope.totalStatistics += cat.count.GET;
            }

            for (element in statistics.data) {
                $scope.porcentual[element] = $scope.statistics[element] * 100 / $scope.totalStatistics;;
            }
        });
    });
}
<|endoftext|>


<commit_before>/**
 * @fileoverview discriminate type of touch event
 */

var Gesture = ne.util.defineModule('ne.component.Gesture');

/**
 * To find out it's flick or click or nothing from event datas.
 * @namespace ne.component.Gesture.Flick
 * @example
 * var movedetector = new ne.component.MoveDetector({
 *      flickTime: 300, // time to check flick
 *      flickRange: 250, // range(distance) to check flick
 *      clickTime: 200, // time to check click
 *      minDist: 15 // range(distance) to check movement
 * });
 */
Gesture.Flick = ne.util.defineClass(/** @lends ne.component.Gesture.Flick.prototype */{
    /**
     * time is considered flick.
     */
    flickTime: 100,
    /**
     * width is considered flick.
     */
    flickRange: 300,
    /**
     * time is considered click
     */
    clickTime: 200,
    /**
     * width is considered moving.
     */
    minDist: 10,
    /**
     * click timer for check double click
     */
    clickTimer: null,
    /**
     * extracted event type
     */
    type: null,
    /**
     * set options
     * @param {object} option
     *      @param {number} [option.flickTime] time to check flick
     *      @param {number} [option.flickRange] range to check flick
     *      @param {number} [option.clickTime] time to check click
     *      @param {number} [option.minDist] distance to check movement
     */
    init: function(option) {
        this.flickTime = option.flickTime || this.flickTime;
        this.flickRange = option.flickRange || this.flickRange;
        this.clickTime = option.clickTime || this.clickTime;
        this.minDist = option.minDist || this.minDist;
    },
    /**
     * pick event type from eventData
     * @param {object} eventData event Data
     * @return {object}
     */
    figure: function(eventData) {
        var direction = this.getDirection(eventData.list);
        this.extractType(eventData);
        return {
            direction : direction,
            type: this.type
        }
    },
    /**
     * return direction figured out
     * @param {array} list eventPoint List
     * @returns {string}
     */
    getDirection: function(list) {
        var first = list[0],
            final = list[list.length-1],
            cardinalPoint = this.getCardinalPoints(first, final),
            res = this.getNearestPoint(first, final, cardinalPoint);

        return res;
    },
    /**
     * return cardinal points figured out
     * @param {object} first start point
     * @param {object} last end point
     */
    getCardinalPoints: function(first, last) {
        var verticalDist = first.y - last.y,
            horizonDist = first.x - last.x,
            NS = '',
            WE = '';

        if (verticalDist < 0) {
            NS = 'S';
        } else if (verticalDist > 0) {
            NS = 'N';
        }

        if (horizonDist < 0) {
            WE = 'E';
        } else if (horizonDist > 0) {
            WE = 'W';
        }

        return NS+WE;
    },
    /**
     * return nearest four cardinal points
     * @param {object} first start point
     * @param {object} last end point
     * @param {string} cardinalPoint cardinalPoint from getCardinalPoints
     * @returns {string}
     */
    getNearestPoint: function(first, last, cardinalPoint) {
        var slop = (last.y - first.y) / (last.x - first.x),
            direction;
        if (slop < 0) {
            direction = slop < -1 ? 'NS' : 'WE';
        } else {
            direction = slop > 1 ? 'NS' : 'WE';
        }

        direction = this._getDuplicatedString(direction, cardinalPoint);
        return direction;
    },
    /**
     * return duplicate charters
     * @param {string} str1 compared charters
     * @param {string} str2 compared charters
     * @returns {string}
     */
    _getDuplicatedString: function(str1, str2) {
        var dupl,
            key,
            i = 0,
            len = str1.length,
            pool = {};

        // save opered characters
        for (; i < len; i++) {
            key = str1.charAt(i);
            pool[key] = 1;
        }

        // change saved flag if charater exist in pool
        for (i = 0, len = str2.length; i < len; i++) {
            key = str2.charAt(i);
            pool[key] = pool[key] ? 2 : 1;
        }

        pool = ne.util.filter(pool, function(item) {
            return item === 2;
        });
        dupl = ne.util.keys(pool).join('');

        return dupl;
    },
    /**
     * extract type of event
     * @param {object} eventData event data
     * @returns {string}
     * @example
     * movedetector.extractType({
     *      start: 1000,
     *      end: 1100,
     *      list: [
     *            {
     *                x: 10,
     *                y: 10
     *            },
     *            {
     *                x: 11,
     *                y: 11
     *            }
     *      ]
     * });
     */
    extractType: function(eventData) {
        var start = eventData.start,
            end = eventData.end,
            list = eventData.list,
            first = list[0],
            final = list[list.length - 1],
            timeDist = end - start,
            xDist = Math.abs(first.x - final.x),
            yDist = Math.abs(first.y - final.y);

        // compare dist with minDist
        if (xDist < this.minDist && yDist < this.minDist) {
            this._detectClickType(timeDist);
        } else if (timeDist < this.flickTime || xDist > this.flickRange || yDist > this.flickRange) {
            this.type = 'flick';
        } else {
            this.type = 'none';
        }
    },
    /**
     * check click or double click
     * @param {number} timeDist distance from mousedown/touchstart to mouseup/touchend
     * @returns {*}
     */
    _detectClickType: function(timeDist) {
        var self = this;
        if (timeDist < this.clickTime) {
            if (this.clickTimer) {
                this.resetTimer();
                this.type = 'dbclick';
            } else {
                this.type = 'click';
                this.clickTimer = window.setTimeout(function () {
                    self.resetTimer();
                }, this.clickTime);
            }
        } else {
            this.type = 'none';
        }
    },
    /**
     * clear clickTimer
     */
    resetTimer: function() {
        window.clearTimeout(this.clickTimer);
        this.clickTimer = null;
    }
});<commit_msg>name changed<commit_after>/**
 * @fileoverview discriminate type of touch event
 */

var Gesture = ne.util.defineModule('ne.component.Gesture');

/**
 * To find out it's flick or click or nothing from event datas.
 * @namespace ne.component.Gesture.Flick
 * @example
 * var movedetector = new ne.component.MoveDetector({
 *      flickTime: 300, // time to check flick
 *      flickRange: 250, // range(distance) to check flick
 *      clickTime: 200, // time to check click
 *      minDist: 15 // range(distance) to check movement
 * });
 */
Gesture.Flick = ne.util.defineClass(/** @lends ne.component.Gesture.Flick.prototype */{
    /**
     * time is considered flick.
     */
    flickTime: 100,
    /**
     * width is considered flick.
     */
    flickRange: 300,
    /**
     * time is considered click
     */
    clickTime: 200,
    /**
     * width is considered moving.
     */
    minDist: 10,
    /**
     * click timer for check double click
     */
    clickTimer: null,
    /**
     * extracted event type
     */
    type: null,
    /**
     * set options
     * @param {object} option
     *      @param {number} [option.flickTime] time to check flick
     *      @param {number} [option.flickRange] range to check flick
     *      @param {number} [option.clickTime] time to check click
     *      @param {number} [option.minDist] distance to check movement
     */
    init: function(option) {
        this.flickTime = option.flickTime || this.flickTime;
        this.flickRange = option.flickRange || this.flickRange;
        this.clickTime = option.clickTime || this.clickTime;
        this.minDist = option.minDist || this.minDist;
    },
    /**
     * pick event type from eventData
     * @param {object} eventData event Data
     * @return {object}
     */
    figure: function(eventData) {
        var direction = this.getDirection(eventData.list);
        this.extractType(eventData);
        return {
            direction : direction,
            type: this.type
        }
    },
    /**
     * return direction figured out
     * @param {array} list eventPoint List
     * @returns {string}
     */
    getDirection: function(list) {
        var first = list[0],
            final = list[list.length-1],
            cardinalPoint = this.getCardinalPoints(first, final),
            res = this.getNearestPoint(first, final, cardinalPoint);

        return res;
    },
    /**
     * return cardinal points figured out
     * @param {object} first start point
     * @param {object} last end point
     */
    getCardinalPoints: function(first, last) {
        var verticalDist = first.y - last.y,
            horizonDist = first.x - last.x,
            NS = '',
            WE = '';

        if (verticalDist < 0) {
            NS = 'S';
        } else if (verticalDist > 0) {
            NS = 'N';
        }

        if (horizonDist < 0) {
            WE = 'E';
        } else if (horizonDist > 0) {
            WE = 'W';
        }

        return NS+WE;
    },
    /**
     * return nearest four cardinal points
     * @param {object} first start point
     * @param {object} last end point
     * @param {string} cardinalPoint cardinalPoint from getCardinalPoints
     * @returns {string}
     */
    getNearestPoint: function(first, last, cardinalPoint) {
        var slop = (last.y - first.y) / (last.x - first.x),
            direction;
        if (slop < 0) {
            direction = slop < -1 ? 'NS' : 'WE';
        } else {
            direction = slop > 1 ? 'NS' : 'WE';
        }

        direction = this._getDuplicatedString(direction, cardinalPoint);
        return direction;
    },
    /**
     * return duplicate charters
     * @param {string} str1 compared charters
     * @param {string} str2 compared charters
     * @private
     * @returns {string}
     */
    _getDuplicatedString: function(str1, str2) {
        var dupl,
            key,
            i = 0,
            len = str1.length,
            pool = {};

        // save opered characters
        for (; i < len; i++) {
            key = str1.charAt(i);
            pool[key] = 1;
        }

        // change saved flag if charater exist in pool
        for (i = 0, len = str2.length; i < len; i++) {
            key = str2.charAt(i);
            pool[key] = pool[key] ? 2 : 1;
        }

        pool = ne.util.filter(pool, function(item) {
            return item === 2;
        });
        dupl = ne.util.keys(pool).join('');

        return dupl;
    },
    /**
     * extract type of event
     * @param {object} eventData event data
     * @returns {string}
     * @example
     * movedetector.extractType({
     *      start: 1000,
     *      end: 1100,
     *      list: [
     *            {
     *                x: 10,
     *                y: 10
     *            },
     *            {
     *                x: 11,
     *                y: 11
     *            }
     *      ]
     * });
     */
    extractType: function(eventData) {
        var start = eventData.start,
            end = eventData.end,
            list = eventData.list,
            first = list[0],
            final = list[list.length - 1],
            timeDist = end - start,
            xDist = Math.abs(first.x - final.x),
            yDist = Math.abs(first.y - final.y);

        // compare dist with minDist
        if (xDist < this.minDist && yDist < this.minDist) {
            this._detectClickType(timeDist);
        } else if (timeDist < this.flickTime || xDist > this.flickRange || yDist > this.flickRange) {
            this.type = 'flick';
        } else {
            this.type = 'none';
        }
    },
    /**
     * check click or double click
     * @param {number} timeDist distance from mousedown/touchstart to mouseup/touchend
     * @priavte
     * @returns {*}
     */
    _detectClickType: function(timeDist) {
        var self = this;
        if (timeDist < this.clickTime) {
            if (this.clickTimer) {
                this.resetTimer();
                this.type = 'dbclick';
            } else {
                this.type = 'click';
                this.clickTimer = window.setTimeout(function () {
                    self.resetTimer();
                }, this.clickTime);
            }
        } else {
            this.type = 'none';
        }
    },
    /**
     * clear clickTimer
     */
    resetTimer: function() {
        window.clearTimeout(this.clickTimer);
        this.clickTimer = null;
    }
});<|endoftext|>


<commit_before>var renderer = PIXI.autoDetectRenderer(256, 256);

document.body.appendChild(renderer.view);

var stage = new PIXI.Container();

renderer.render(stage);
<commit_msg>Add render loop<commit_after>var renderer = PIXI.autoDetectRenderer(256, 256);
document.body.appendChild(renderer.view);

var stage = new PIXI.Container();

render();

function render() {
    requestAnimationFrame(render);

    renderer.render(stage);
}
<|endoftext|>


<commit_before>define (["jquery", "underscore", "tri/core/helpers"], function($, _, helpers) {
	"use strict";

	function CountdownPage(data, trial) {
		this.data = data;
		this.time = helpers.ParseTime(data.time);
		this.trial = trial;
	}
	CountdownPage.prototype.show = function() {
		console.log("Showing CountdownPage");

		var base = this;
		// TODO: Remove use of load layout
		helpers.LoadLayout("countdown", ["title", "content"], this.data, function () {
			var count = base.time;
			function countdown(val, completion) {
				console.log("countdown with " + val);
				if (val == 0) {
					completion();
				}
				else {
					$("#countdown").text(val);
					_.delay(countdown, 1000, val - 1, completion);
				}
			}
			countdown(count / 1000, function () {
				base.end();
			});
		});
	};
	CountdownPage.prototype.end = function () {
        this.trial.nextPage();
    };

	return CountdownPage;
});
<commit_msg>Remove loadlayout from countdown.js<commit_after>define (["jquery", "underscore", "tri/core/helpers"], function($, _, helpers) {
	"use strict";

	function CountdownPage(data, trial) {
		this.data = data;
		this.time = helpers.ParseTime(data.time);
		this.trial = trial;
		this.bindable = ["title", "content"];
	}
	CountdownPage.prototype.show = function() {
		console.log("Showing CountdownPage");

		var base = this;

		function countdown(val, completion) {
			console.log("countdown with " + val);
			if (val == 0) {
				completion();
			}
			else {
				$("#countdown").text(val);
				_.delay(countdown, 1000, val - 1, completion);
			}
		}

		var count = this.time / 1000;
		countdown(count, function () {
			base.end();
		});
	};
	CountdownPage.prototype.end = function () {
        this.trial.nextPage();
    };

	return CountdownPage;
});
<|endoftext|>