<commit_before>// Sample view

enyo.kind({
	name: "moon.sample.photos.PhotoGridSample",
	kind: "moon.Panel",
	classes: "moon enyo-fit",
	titleAbove: "02",
	title: "Album Name",
	titleBelow: "97 Photos",
	headerComponents: [
		{kind: "moon.IconButton", src: "../assets/icon-list.png"},
		{kind: "moon.IconButton", src: "../assets/icon-favorite.png"},
		{kind: "moon.IconButton", src: "../assets/icon-download.png"},
		{kind: "moon.IconButton", src: "../assets/icon-next.png"}
	],
	components: [
		{name: "menuList", kind: "enyo.DataGridList", fit: true, scrollerOptions: {kind: "moon.Scroller", horizontal: "hidden"}, components: [
			{kind: "enyo.Image", classes: "moon-3h moon-4v", bindings: [{from: ".model.imgSrc", to: ".src"}]}
		]}
	],
	bindings: [
		{from: ".controller.menus", to: ".$.menuList.controller"}
	]
});

// Sample model

enyo.ready(function(){
    var sampleModel = new enyo.Model({
        menus: new enyo.Collection([
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"}
        ])
    });

//  Application to render sample

    new enyo.Application({
        view: {
            classes: "enyo-unselectable moon",
            components: [
                {
                    kind: "moon.sample.photos.PhotoGridSample",
                    controller: ".app.controllers.photoController",
                    classes: "enyo-fit"
                }
            ]
        },
        controllers: [
            {
                name: "photoController",
                kind: "enyo.ModelController",
                model: sampleModel
            }
        ]
    });
});<commit_msg>GF-6532 PhotoGridWideSample updated<commit_after>// Sample view

enyo.kind({
	name: "moon.sample.photos.PhotoGridSample",
	kind: "moon.Panel",
	classes: "moon enyo-fit",
	titleAbove: "02",
	title: "Album Name",
	titleBelow: "97 Photos",
	headerComponents: [
		{kind: "moon.IconButton", src: "../assets/icon-list.png"},
		{kind: "moon.IconButton", src: "../assets/icon-favorite.png"},
		{kind: "moon.IconButton", src: "../assets/icon-download.png"},
		{kind: "moon.IconButton", src: "../assets/icon-next.png"}
	],
    components: [
        {
            name: "menuList",
            minWidth: 140,
            spacing: 10,
            kind: "moon.DataGridList",
            fit: true,
            components: [
                {
                    kind: "moon.GridListImageItem",
                    bindings: [
                        {from: ".model.imgSrc", to: ".source"}
                    ]
                }
            ]
        }
    ],
    bindings: [
		{from: ".controller.menus", to: ".$.menuList.controller"}
	]
});

// Sample model

enyo.ready(function(){
    var sampleModel = new enyo.Model({
        menus: new enyo.Collection([
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"},
            {imgSrc: "../assets/default-movie.png"}
        ])
    });

//  Application to render sample

    new enyo.Application({
        view: {
            classes: "enyo-unselectable moon",
            components: [
                {
                    kind: "moon.sample.photos.PhotoGridSample",
                    controller: ".app.controllers.photoController",
                    classes: "enyo-fit"
                }
            ]
        },
        controllers: [
            {
                name: "photoController",
                kind: "enyo.ModelController",
                model: sampleModel
            }
        ]
    });
});<|endoftext|>


<commit_before>var Mocha = require('mocha'),
    path = require('path'),
    fs = require('fs');

var mocha = new Mocha({
    reporter: 'dot',
    ui: 'bdd',
    timeout: 999999
});

var testDir = 'D:/Workplace/git/fis-kernel/test/ut/cache.js';

//fs.readdir(testDir, function (err, files) {
//    if (err) {
//        console.log(err);
//        return;
//    }
//    files.forEach(function (file) {
//        if (path.extname(file) === '.js') {
//            console.log('adding test file: %s', file);
//            mocha.addFile(testDir + file);
//        }
//    });

mocha.addFile(testDir);

    var runner = mocha.run(function () {
//        console.log('all cases finished');
    });

    runner.on('pass', function (test) {
        console.log('... %s passed', test.title);
    });

    runner.on('fail', function (test) {
        console.log('... %s failed', test.title);
    });
//});<commit_msg>rm ut file<commit_after><|endoftext|>


<commit_before>/**
 * User management tool.
 *
 * @author keshav
 * @version $Id$
 */
Ext.namespace('Gemma');
Ext.BLANK_IMAGE_URL = '/Gemma/images/default/s.gif';

Gemma.USER_PAGE_SIZE = 10;

Ext.onReady(function() {
	Ext.QuickTips.init();
	Ext.state.Manager.setProvider(new Ext.state.CookieProvider());

	if (Ext.isIE && !Ext.isIE7) {
		Ext.DomHelper.append('errorMessage', {
			tag : 'p',
			cls : 'trouble',
			html : 'This page may display improperly in older versions of Internet Explorer. Please upgrade to Internet Explorer 7 or newer.'
		});
	}

	// A simple test store using canned "data" and an array "reader".
	// var store = new Ext.data.Store({
	// data : [[1, "mjudge", "Judge", "foo@foo.com", true],
	// [2, "mjudge", "Judge", "foo@foo.com", true],
	// [3, "mjudge", "Judge", "foo@foo.com", true],
	// [4, "mjudge", "Judge", "foo@foo.com", false]],
	//
	// reader : new Ext.data.ArrayReader({
	// id : 'id'
	// }, ['id', 'userName', 'lastName', 'email', 'enabled'])
	//
	// });

	var record = Ext.data.Record.create([{
				name : "id",
				type : "int"
			}, {
				name : "userName",
				type : "string"
			}, {
				name : "email",
				type : "string"
			}, {
				name : "role",
				type : "string"
			}, {
				name : "enabled",
				type : "boolean"
			}]);

	var userStore = new Gemma.PagingDataStore({
		proxy : new Ext.data.DWRProxy(UserListController.getUsers),
		reader : new Ext.data.ListRangeReader({
					id : 'id'
				}, record),
		remoteSort : false,
		pageSize : Gemma.USER_PAGE_SIZE
	})
	userStore.load();

	/* create editors for the grid */
	var userNameEdit = new Ext.form.TextField({
		allowBlank : false
	});

	var emailEdit = new Ext.form.TextField({
		allowBlank : false,
		vtype : 'email'
	});

	var checkColumn = new Ext.grid.CheckColumn({
		header : "Enabled?",
		dataIndex : 'enabled',
		width : 55
	});

	// var d = userStore.data.items;
	// var r = record.get("role").createDelegate(this);

	var roleEdit = new Ext.form.ComboBox({
		typeAhead : true,
		lazyRender : true,
		triggerAction : 'all',
		mode : 'local',
		selectOnFocus : true,
		displayField : 'role',

		// the role (combo box) editor needs a store
		store : new Ext.data.Store({
			data : [[1, "user"], [2, "admin"]],

			reader : new Ext.data.ArrayReader({
						id : 'id'
					}, ['id', 'role'])

		}),
		valueField : 'role'
	});

	var userGrid = new Ext.grid.EditorGridPanel({

		renderTo : "userList",
		title : "User Management",
		frame : true,
		height : 300,
		width : 900,
		stripeRows : true,
		clicksToEdit : 2,
		plugins : checkColumn,
		loadMask : true,
		autoScroll : true,
		store : userStore,

		tbar : [

				{
					text : 'Add',
					tooltip : 'Add a new user',
					disabled : true,
					icon : 'images/icons/add.png',
					cls : 'x-btn-text-icon',
					handler : function() {
						userGrid.getStore().insert(0, new record({
									userName : 'New User',
									email : '',
									role : 'Select Role',
									enabled : true
								}));
						userGrid.startEditing(0, 0);
					}
				},

				{
					text : 'Remove',
					disabled : true,
					tooltip : 'Remove selected user',
					icon : 'images/icons/delete.png',
					cls : 'x-btn-text-icon',
					handler : function() {
						var sm = userGrid.getSelectionModel();
						var sel = sm.getSelected();
						if (sm.hasSelection()) {
							Ext.Msg.show({
								title : 'Remove User',
								buttons : Ext.MessageBox.YESNO,
								msg : 'Remove ' + sel.data.userName + '?',
								fn : function(btn) {
									if (btn == 'yes') {
										userGrid.getStore().remove(sel);
									}
								}
							});
						};
					}
				},

				{
					text : 'Save',
					tooltip : 'Save the selected user',
					icon : 'images/icons/database_save.png',
					cls : 'x-btn-text-icon',
					handler : function() {
						var sm = userGrid.getSelectionModel();
						var sel = sm.getSelected();
						if (sm.hasSelection()) {
							Ext.Msg.show({
								title : 'Save User',
								buttons : Ext.MessageBox.YESNO,
								msg : 'Save ' + sel.data.userName + '?',
								fn : function(btn) {
									if (btn == 'yes') {
										UserListController.saveUser({
													userName : sel.data.userName,
													email : sel.data.email,
													enabled : sel.data.enabled,
													role : sel.data.role
												}, {
													callback : function() {
														userGrid.getStore().reload();
													}
												});
									}
								}
							});
						};
					}
				}

		],

		bbar : new Ext.PagingToolbar({
			pageSize : Gemma.USER_PAGE_SIZE,
			store : userStore
		}),

		cm : new Ext.grid.ColumnModel([{
					header : "Username",
					dataIndex : 'userName',
					editor : userNameEdit,
					sortable : true
				}, {
					header : "Email",
					dataIndex : 'email',
					editor : emailEdit
				}, {
					header : "Role",
					dataIndex : 'role',
					editor : roleEdit
				}, checkColumn]),

		viewConfig : {
			forceFit : true
		},

		sm : new Ext.grid.RowSelectionModel({
			singleSelect : true
		})

	});
});<commit_msg>changed the store to a Gemma.PagingDataStore and added a paging toolbar as the bottom bar.<commit_after>/**
 * User management tool.
 *
 * @author keshav
 * @version $Id$
 */
Ext.namespace('Gemma');
Ext.BLANK_IMAGE_URL = '/Gemma/images/default/s.gif';

Gemma.USER_PAGE_SIZE = 10;

Ext.onReady(function() {
	Ext.QuickTips.init();
	Ext.state.Manager.setProvider(new Ext.state.CookieProvider());

	if (Ext.isIE && !Ext.isIE7) {
		Ext.DomHelper.append('errorMessage', {
			tag : 'p',
			cls : 'trouble',
			html : 'This page may display improperly in older versions of Internet Explorer. Please upgrade to Internet Explorer 7 or newer.'
		});
	}

	// A simple test store using canned "data" and an array "reader".
	// var store = new Ext.data.Store({
	// data : [[1, "mjudge", "Judge", "foo@foo.com", true],
	// [2, "mjudge", "Judge", "foo@foo.com", true],
	// [3, "mjudge", "Judge", "foo@foo.com", true],
	// [4, "mjudge", "Judge", "foo@foo.com", false]],
	//
	// reader : new Ext.data.ArrayReader({
	// id : 'id'
	// }, ['id', 'userName', 'lastName', 'email', 'enabled'])
	//
	// });

	var record = Ext.data.Record.create([{
				name : "id",
				type : "int"
			}, {
				name : "userName",
				type : "string"
			}, {
				name : "email",
				type : "string"
			}, {
				name : "role",
				type : "string"
			}, {
				name : "enabled",
				type : "boolean"
			}]);

	var userStore = new Gemma.PagingDataStore({
		proxy : new Ext.data.DWRProxy(UserListController.getUsers),
		reader : new Ext.data.ListRangeReader({
					id : 'id'
				}, record),
		remoteSort : false,
		pageSize : Gemma.USER_PAGE_SIZE
	})
	userStore.load();

	/* create editors for the grid */
	var userNameEdit = new Ext.form.TextField({
		allowBlank : false
	});

	var emailEdit = new Ext.form.TextField({
		allowBlank : false,
		vtype : 'email'
	});

	var checkColumn = new Ext.grid.CheckColumn({
		header : "Enabled?",
		dataIndex : 'enabled',
		width : 55
	});

	var roleEdit = new Ext.form.ComboBox({
		typeAhead : true,
		lazyRender : true,
		triggerAction : 'all',
		mode : 'local',
		selectOnFocus : true,
		displayField : 'role',

		// the role (combo box) editor needs a store
		store : new Ext.data.Store({
			data : [[1, "user"], [2, "admin"]],

			reader : new Ext.data.ArrayReader({
						id : 'id'
					}, ['id', 'role'])

		}),
		valueField : 'role'
	});

	var userGrid = new Ext.grid.EditorGridPanel({

		renderTo : "userList",
		title : "User Management",
		frame : true,
		height : 300,
		width : 900,
		stripeRows : true,
		clicksToEdit : 2,
		plugins : checkColumn,
		loadMask : true,
		autoScroll : true,
		store : userStore,

		tbar : [

				{
					text : 'Add',
					tooltip : 'Add a new user',
					disabled : true,
					icon : 'images/icons/add.png',
					cls : 'x-btn-text-icon',
					handler : function() {
						userGrid.getStore().insert(0, new record({
									userName : 'New User',
									email : '',
									role : 'Select Role',
									enabled : true
								}));
						userGrid.startEditing(0, 0);
					}
				},

				{
					text : 'Remove',
					disabled : true,
					tooltip : 'Remove selected user',
					icon : 'images/icons/delete.png',
					cls : 'x-btn-text-icon',
					handler : function() {
						var sm = userGrid.getSelectionModel();
						var sel = sm.getSelected();
						if (sm.hasSelection()) {
							Ext.Msg.show({
								title : 'Remove User',
								buttons : Ext.MessageBox.YESNO,
								msg : 'Remove ' + sel.data.userName + '?',
								fn : function(btn) {
									if (btn == 'yes') {
										userGrid.getStore().remove(sel);
									}
								}
							});
						};
					}
				},

				{
					text : 'Save',
					tooltip : 'Save the selected user',
					icon : 'images/icons/database_save.png',
					cls : 'x-btn-text-icon',
					handler : function() {
						var sm = userGrid.getSelectionModel();
						var sel = sm.getSelected();
						if (sm.hasSelection()) {
							Ext.Msg.show({
								title : 'Save User',
								buttons : Ext.MessageBox.YESNO,
								msg : 'Save ' + sel.data.userName + '?',
								fn : function(btn) {
									if (btn == 'yes') {
										UserListController.saveUser({
													userName : sel.data.userName,
													email : sel.data.email,
													enabled : sel.data.enabled,
													role : sel.data.role
												}, {
													callback : function() {
														userGrid.getStore().reload();
													}
												});
									}
								}
							});
						};
					}
				}

		],

		bbar : new Ext.PagingToolbar({
			pageSize : Gemma.USER_PAGE_SIZE,
			store : userStore
		}),

		cm : new Ext.grid.ColumnModel([{
					header : "Username",
					dataIndex : 'userName',
					editor : userNameEdit,
					sortable : true
				}, {
					header : "Email",
					dataIndex : 'email',
					editor : emailEdit
				}, {
					header : "Role",
					dataIndex : 'role',
					editor : roleEdit
				}, checkColumn]),

		viewConfig : {
			forceFit : true
		},

		sm : new Ext.grid.RowSelectionModel({
			singleSelect : true
		})

	});
});<|endoftext|>


<commit_before>import angular from 'angular';
import _ from 'underscore';

angular.module('dimApp')
  .factory('dimDestinyTrackerService', DestinyTrackerService);

function DestinyTrackerService($q,
                               $http,
                               $rootScope) {
  var _gunListBuilder = gunListBuilder();

  $rootScope.$on('item-clicked', function(event, item) {
    console.log("Caught click event.");
  });

  $rootScope.$on('dim-stores-updated', function(event, stores) {
    _bulkFetch(stores)
      .then((bulkRankings) => attachRankings(bulkRankings,
                                             stores.stores));
  });

  function attachRankings(bulkRankings,
                          stores) {
    if ((!bulkRankings) ||
        (!bulkRankings.length)) {
      return;
    }

    bulkRankings.forEach(function(bulkRanking) {
      stores.forEach(function(store) {
        store.items.forEach(function(storeItem) {
          if (storeItem.hash == bulkRanking.referenceId) {
            storeItem.dtrRating = bulkRanking.rating;
          }
        });
      });
    });
  }

  function getBulkWeaponDataPromise(gunList) {
    return {
      method: 'POST',
      url: 'https://reviews-api.destinytracker.net/api/weaponChecker/fetch',
      data: gunList,
      dataType: 'json'
    };
  }

  function submitItemReviewPromise(itemReview) {
    return {
      method: 'POST',
      url: 'https://reviews-api.destinytracker.net/api/weaponChecker/reviews/submit',
      data: itemReview,
      dataType: 'json'
    };
  }

  function handleErrors(response) {
    if (response.status !== 200) {
      return $q.reject(new Error("Destiny tracker service call failed."));
    }

    return response;
  }

  function handleSubmitErrors(response) {
    if (response.status !== 204) {
      return $q.reject(new Error("Destiny tracker service submit failed."));
    }

    return response;
  }

  function toReviewer(membershipInfo) {
    return {
      membershipId: membershipInfo.membershipId,
      type: membershipInfo.type,
      displayName: membershipInfo.id
    };
  }

  function toRatingAndReview(userReview) {
    return {
      rating: userReview.rating,
      review: userReview.review
    };
  }

  function _bulkFetch(stores) {
    if (stores.stores.length === 0) {
      return $q.resolve();
    }
    var weaponList = _gunListBuilder.getWeaponList(stores.stores);

    var promise = $q
              .when(getBulkWeaponDataPromise(weaponList))
              .then($http)
              .then(handleErrors, handleErrors)
              .then((response) => { return response.data; });

    return promise;
  }

  return {
    authenticate: function() {
    },
    bulkFetch: function(stores) {
      return _bulkFetch(stores);
    },
    submitReview: function(membershipInfo, item, userReview) {
      var rollAndPerks = _gunListBuilder.getRollAndPerks(item);
      var reviewer = toReviewer(membershipInfo);
      var review = toRatingAndReview(userReview);

      var rating = Object.assign(rollAndPerks, review);
      rating.reviewer = reviewer;

      var promise = $q
                .when(submitItemReviewPromise(rating))
                .then($http)
                .then(handleSubmitErrors, handleSubmitErrors)
                .then((response) => { return; });

      return promise;
    }
  };
}

function gunListBuilder() {
  var glb = {};

  function getNewItems(allItems) {
    return _.where(allItems, { isNew: true });
  }

  function getAllItems(stores) {
    var allItems = [];

    stores.forEach(function(store) {
      allItems = allItems.concat(store.items);
    });

    var newItems = getNewItems(allItems);

    if (newItems.length > 0) {
      return newItems;
    }

    return allItems;
  }

  function getGuns(stores) {
    var allItems = getAllItems(stores);

    return _.filter(allItems,
                        function(item) {
                          if (!item.primStat) {
                            return false;
                          }

                          return (item.primStat.statHash === 368428387);
                        });
  }

  glb.getWeaponList = function(stores) {
    var guns = getGuns(stores);

    var list = [];

    guns.forEach(function(gun) {
      var dtrGun = translateToDtrGun(gun);

      if (!isKnownGun(list, dtrGun)) {
        list.push(dtrGun);
      }
    });

    return list;
  };

  function getDtrPerks(gun) {
    if (!gun.talentGrid) {
      return null;
    }

    return gun.talentGrid.dtrPerks;
  }

  function getGunRoll(gun) {
    var dtrPerks = getDtrPerks(gun);

    if (dtrPerks.length > 0) {
      return dtrPerks.replace(/o/g, "");
    }

    return null;
  }

  function translateToDtrGun(gun) {
    return {
      referenceId: gun.hash,
      roll: getGunRoll(gun)
    };
  }

  glb.getRollAndPerks = function(gun) {
    return {
      roll: getGunRoll(gun),
      selectedPerks: getDtrPerks(gun),
      referenceId: gun.hash,
      instanceId: gun.id,
    };
  };

  function isKnownGun(list, dtrGun) {
    return _.contains(list, dtrGun);
  }

  return glb;
}<commit_msg>Let's be precise and check for new weapons.<commit_after>import angular from 'angular';
import _ from 'underscore';

angular.module('dimApp')
  .factory('dimDestinyTrackerService', DestinyTrackerService);

function DestinyTrackerService($q,
                               $http,
                               $rootScope) {
  var _gunListBuilder = gunListBuilder();

  $rootScope.$on('item-clicked', function(event, item) {
    console.log("Caught click event.");
  });

  $rootScope.$on('dim-stores-updated', function(event, stores) {
    _bulkFetch(stores)
      .then((bulkRankings) => attachRankings(bulkRankings,
                                             stores.stores));
  });

  function attachRankings(bulkRankings,
                          stores) {
    if ((!bulkRankings) ||
        (!bulkRankings.length)) {
      return;
    }

    bulkRankings.forEach(function(bulkRanking) {
      stores.forEach(function(store) {
        store.items.forEach(function(storeItem) {
          if (storeItem.hash == bulkRanking.referenceId) {
            storeItem.dtrRating = bulkRanking.rating;
          }
        });
      });
    });
  }

  function getBulkWeaponDataPromise(gunList) {
    return {
      method: 'POST',
      url: 'https://reviews-api.destinytracker.net/api/weaponChecker/fetch',
      data: gunList,
      dataType: 'json'
    };
  }

  function submitItemReviewPromise(itemReview) {
    return {
      method: 'POST',
      url: 'https://reviews-api.destinytracker.net/api/weaponChecker/reviews/submit',
      data: itemReview,
      dataType: 'json'
    };
  }

  function handleErrors(response) {
    if (response.status !== 200) {
      return $q.reject(new Error("Destiny tracker service call failed."));
    }

    return response;
  }

  function handleSubmitErrors(response) {
    if (response.status !== 204) {
      return $q.reject(new Error("Destiny tracker service submit failed."));
    }

    return response;
  }

  function toReviewer(membershipInfo) {
    return {
      membershipId: membershipInfo.membershipId,
      type: membershipInfo.type,
      displayName: membershipInfo.id
    };
  }

  function toRatingAndReview(userReview) {
    return {
      rating: userReview.rating,
      review: userReview.review
    };
  }

  function _bulkFetch(stores) {
    if (stores.stores.length === 0) {
      return $q.resolve();
    }
    var weaponList = _gunListBuilder.getWeaponList(stores.stores);

    var promise = $q
              .when(getBulkWeaponDataPromise(weaponList))
              .then($http)
              .then(handleErrors, handleErrors)
              .then((response) => { return response.data; });

    return promise;
  }

  return {
    authenticate: function() {
    },
    bulkFetch: function(stores) {
      return _bulkFetch(stores);
    },
    submitReview: function(membershipInfo, item, userReview) {
      var rollAndPerks = _gunListBuilder.getRollAndPerks(item);
      var reviewer = toReviewer(membershipInfo);
      var review = toRatingAndReview(userReview);

      var rating = Object.assign(rollAndPerks, review);
      rating.reviewer = reviewer;

      var promise = $q
                .when(submitItemReviewPromise(rating))
                .then($http)
                .then(handleSubmitErrors, handleSubmitErrors)
                .then((response) => { return; });

      return promise;
    }
  };
}

function gunListBuilder() {
  var glb = {};

  function getNewItems(allItems) {
    return _.where(allItems, { isNew: true });
  }

  function getAllItems(stores) {
    var allItems = [];

    stores.forEach(function(store) {
      allItems = allItems.concat(store.items);
    });

    return allItems;
  }

  function getGuns(stores) {
    var allItems = getAllItems(stores);

    var allGuns = _.filter(allItems,
                        function(item) {
                          if (!item.primStat) {
                            return false;
                          }

                          return (item.primStat.statHash === 368428387);
                        });

    var newGuns = getNewItems(allGuns);

    if (newGuns.length > 0) {
      return newGuns;
    }

    return allGuns;
  }

  glb.getWeaponList = function(stores) {
    var guns = getGuns(stores);

    var list = [];

    guns.forEach(function(gun) {
      var dtrGun = translateToDtrGun(gun);

      if (!isKnownGun(list, dtrGun)) {
        list.push(dtrGun);
      }
    });

    return list;
  };

  function getDtrPerks(gun) {
    if (!gun.talentGrid) {
      return null;
    }

    return gun.talentGrid.dtrPerks;
  }

  function getGunRoll(gun) {
    var dtrPerks = getDtrPerks(gun);

    if (dtrPerks.length > 0) {
      return dtrPerks.replace(/o/g, "");
    }

    return null;
  }

  function translateToDtrGun(gun) {
    return {
      referenceId: gun.hash,
      roll: getGunRoll(gun)
    };
  }

  glb.getRollAndPerks = function(gun) {
    return {
      roll: getGunRoll(gun),
      selectedPerks: getDtrPerks(gun),
      referenceId: gun.hash,
      instanceId: gun.id,
    };
  };

  function isKnownGun(list, dtrGun) {
    return _.contains(list, dtrGun);
  }

  return glb;
}<|endoftext|>


<commit_before>'use strict';

let UserConfig = {
  optionTemplates: {},
  savedConfig: null,
  registerOptions: function(overlayName, optionTemplates) {
    this.optionTemplates[overlayName] = optionTemplates;
  },
  getUserConfigLocation: function(overlayName, callback) {
    window.addOverlayListener('onUserFileChanged', () => {
      window.location.reload();
    });
    window.addOverlayListener('onForceReload', () => {
      window.location.reload();
    });

    let readOptions = callOverlayHandler({
      call: 'cactbotLoadData',
      overlay: 'options',
    });

    callOverlayHandler({
      call: 'cactbotLoadUser',
      source: location.href,
    }).then(async (e) => {
      let localFiles = e.detail.localUserFiles;
      let basePath = e.detail.userLocation;
      let jsFile = overlayName + '.js';
      let cssFile = overlayName + '.css';

      // The plugin auto-detects the language, so set this first.
      // If options files want to override it, they can for testing.
      if (e.detail.language)
        Options.Language = e.detail.language;

      // Handle processOptions after default language selection above,
      // but before css below which may load skin files.
      // processOptions needs to be called whether or not there are
      // any userOptions saved, as it sets up the defaults.
      let userOptions = await readOptions || {};
      this.savedConfig = userOptions.data || {};
      this.processOptions(
          Options,
          this.savedConfig[overlayName],
          this.optionTemplates[overlayName],
      );

      // In cases where the user files are local but the overlay url
      // is remote, local files needed to be read by the plugin and
      // passed to Javascript for Chrome security reasons.
      if (localFiles) {
        if (jsFile in localFiles) {
          try {
            console.log('local user file: ' + basePath + '\\' + jsFile);
            eval(localFiles[jsFile]);
          } catch (e) {
            // Be very visible for users.
            console.log('*** ERROR IN USER FILE ***');
            console.log(e.stack);
          }
        }

        // This is a bit awkward to handle skin settings here, but
        // doing it after user config files and before user css files
        // allows user css to override skin-specific css as well.
        this.handleSkin(Options.Skin);

        if (cssFile in localFiles) {
          console.log('local user file: ' + basePath + '\\' + cssFile);
          let userCssText = document.createElement('style');
          userCssText.innerText = localFiles[cssFile];
          document.getElementsByTagName('head')[0].appendChild(userCssText);
        }
      } else if (basePath) {
        if (basePath.slice(-1) != '/')
          basePath += '/';
        let jsUrl = basePath + jsFile;
        console.log('remote user file: ' + jsUrl);
        this.appendJSLink(jsUrl);

        // See note above in localFiles case about skin load ordering.
        this.handleSkin(Options.Skin);

        let cssUrl = basePath + cssFile;
        console.log('remote user file: ' + cssUrl);
        this.appendCSSLink(cssUrl);
      }

      // Post this callback so that the js and css can be executed first.
      if (Options.Language && Options.Language in this.languageFuncs)
        this.languageFuncs[Options.Language]();
      if (callback)
        callback();

      callOverlayHandler({ call: 'cactbotRequestState' });
    });
  },
  registerLanguage: function(lang, func) {
    this.languageFuncs[lang] = func;
  },
  languageFuncs: {},
  handleSkin: function(skinName) {
    if (!skinName || skinName == 'default')
      return;

    let basePath = document.location.toString();
    let slashIdx = basePath.lastIndexOf('/');
    if (slashIdx != -1)
      basePath = basePath.substr(0, slashIdx);
    if (basePath.slice(-1) != '/')
      basePath += '/';
    let skinHref = basePath + 'skins/' + skinName + '/' + skinName + '.css';
    this.appendCSSLink(skinHref);
  },
  appendJSLink: function(src) {
    let userJS = document.createElement('script');
    userJS.setAttribute('type', 'text/javascript');
    userJS.setAttribute('src', src);
    userJS.setAttribute('async', false);
    document.getElementsByTagName('head')[0].appendChild(userJS);
  },
  appendCSSLink: function(href) {
    let userCSS = document.createElement('link');
    userCSS.setAttribute('rel', 'stylesheet');
    userCSS.setAttribute('type', 'text/css');
    userCSS.setAttribute('href', href);
    document.getElementsByTagName('head')[0].appendChild(userCSS);
  },
  processOptions: function(options, savedConfig, template) {
    // If for some reason this overlay has no options saved yet,
    // then there will be nothing in the config.
    if (!savedConfig)
      return;

    // Take options from the template, find them in savedConfig,
    // and apply them to options. This also handles setting
    // defaults for anything in the template, even if it does not
    // exist in savedConfig.
    if (Array.isArray(template)) {
      for (let i = 0; i < template.length; ++i)
        this.processOptions(options, savedConfig, template[i]);
      return;
    }

    // Not all overlays have option templates.
    if (!template)
      return;

    let templateOptions = template.options || [];
    for (let i = 0; i < templateOptions.length; ++i) {
      let opt = templateOptions[i];

      // Grab the saved value or the default to set in options.
      let value = opt.id in savedConfig ? savedConfig[opt.id] : opt.default;

      // Options can provide custom logic to turn a value into options settings.
      // If this doesn't exist, just set the value directly.
      // Option template ids are identical to field names on Options.
      if (opt.setterFunc)
        opt.setterFunc(options, value);
      else
        options[opt.id] = value;
    }

    // For things like raidboss that build extra UI, also give them a chance
    // to handle anything that has been set on that UI.
    if (template.processExtraOptions)
      template.processExtraOptions(options, savedConfig);
  },
};
<commit_msg>Don't log user files unless debug setting is true<commit_after>'use strict';

let UserConfig = {
  optionTemplates: {},
  savedConfig: null,
  registerOptions: function(overlayName, optionTemplates) {
    this.optionTemplates[overlayName] = optionTemplates;
  },
  getUserConfigLocation: function(overlayName, callback) {
    window.addOverlayListener('onUserFileChanged', () => {
      window.location.reload();
    });
    window.addOverlayListener('onForceReload', () => {
      window.location.reload();
    });

    let readOptions = callOverlayHandler({
      call: 'cactbotLoadData',
      overlay: 'options',
    });

    callOverlayHandler({
      call: 'cactbotLoadUser',
      source: location.href,
    }).then(async (e) => {
      let localFiles = e.detail.localUserFiles;
      let basePath = e.detail.userLocation;
      let jsFile = overlayName + '.js';
      let cssFile = overlayName + '.css';

      // The plugin auto-detects the language, so set this first.
      // If options files want to override it, they can for testing.
      if (e.detail.language)
        Options.Language = e.detail.language;

      // Handle processOptions after default language selection above,
      // but before css below which may load skin files.
      // processOptions needs to be called whether or not there are
      // any userOptions saved, as it sets up the defaults.
      let userOptions = await readOptions || {};
      this.savedConfig = userOptions.data || {};
      this.processOptions(
          Options,
          this.savedConfig[overlayName],
          this.optionTemplates[overlayName],
      );

      // If the overlay has a "Debug" setting, set to true via the config tool,
      // then also print out user files that have been loaded.
      let printUserFile = Options.Debug ? (x) => console.log(x) : (x) => {};

      // In cases where the user files are local but the overlay url
      // is remote, local files needed to be read by the plugin and
      // passed to Javascript for Chrome security reasons.
      if (localFiles) {
        if (jsFile in localFiles) {
          try {
            printUserFile('local user file: ' + basePath + '\\' + jsFile);
            eval(localFiles[jsFile]);
          } catch (e) {
            // Be very visible for users.
            console.log('*** ERROR IN USER FILE ***');
            console.log(e.stack);
          }
        }

        // This is a bit awkward to handle skin settings here, but
        // doing it after user config files and before user css files
        // allows user css to override skin-specific css as well.
        this.handleSkin(Options.Skin);

        if (cssFile in localFiles) {
          printUserFile('local user file: ' + basePath + '\\' + cssFile);
          let userCssText = document.createElement('style');
          userCssText.innerText = localFiles[cssFile];
          document.getElementsByTagName('head')[0].appendChild(userCssText);
        }
      } else if (basePath) {
        if (basePath.slice(-1) != '/')
          basePath += '/';
        let jsUrl = basePath + jsFile;
        printUserFile('remote user file: ' + jsUrl);
        this.appendJSLink(jsUrl);

        // See note above in localFiles case about skin load ordering.
        this.handleSkin(Options.Skin);

        let cssUrl = basePath + cssFile;
        printUserFile('remote user file: ' + cssUrl);
        this.appendCSSLink(cssUrl);
      }

      // Post this callback so that the js and css can be executed first.
      if (Options.Language && Options.Language in this.languageFuncs)
        this.languageFuncs[Options.Language]();
      if (callback)
        callback();

      callOverlayHandler({ call: 'cactbotRequestState' });
    });
  },
  registerLanguage: function(lang, func) {
    this.languageFuncs[lang] = func;
  },
  languageFuncs: {},
  handleSkin: function(skinName) {
    if (!skinName || skinName == 'default')
      return;

    let basePath = document.location.toString();
    let slashIdx = basePath.lastIndexOf('/');
    if (slashIdx != -1)
      basePath = basePath.substr(0, slashIdx);
    if (basePath.slice(-1) != '/')
      basePath += '/';
    let skinHref = basePath + 'skins/' + skinName + '/' + skinName + '.css';
    this.appendCSSLink(skinHref);
  },
  appendJSLink: function(src) {
    let userJS = document.createElement('script');
    userJS.setAttribute('type', 'text/javascript');
    userJS.setAttribute('src', src);
    userJS.setAttribute('async', false);
    document.getElementsByTagName('head')[0].appendChild(userJS);
  },
  appendCSSLink: function(href) {
    let userCSS = document.createElement('link');
    userCSS.setAttribute('rel', 'stylesheet');
    userCSS.setAttribute('type', 'text/css');
    userCSS.setAttribute('href', href);
    document.getElementsByTagName('head')[0].appendChild(userCSS);
  },
  processOptions: function(options, savedConfig, template) {
    // If for some reason this overlay has no options saved yet,
    // then there will be nothing in the config.
    if (!savedConfig)
      return;

    // Take options from the template, find them in savedConfig,
    // and apply them to options. This also handles setting
    // defaults for anything in the template, even if it does not
    // exist in savedConfig.
    if (Array.isArray(template)) {
      for (let i = 0; i < template.length; ++i)
        this.processOptions(options, savedConfig, template[i]);
      return;
    }

    // Not all overlays have option templates.
    if (!template)
      return;

    let templateOptions = template.options || [];
    for (let i = 0; i < templateOptions.length; ++i) {
      let opt = templateOptions[i];

      // Grab the saved value or the default to set in options.
      let value = opt.id in savedConfig ? savedConfig[opt.id] : opt.default;

      // Options can provide custom logic to turn a value into options settings.
      // If this doesn't exist, just set the value directly.
      // Option template ids are identical to field names on Options.
      if (opt.setterFunc)
        opt.setterFunc(options, value);
      else
        options[opt.id] = value;
    }

    // For things like raidboss that build extra UI, also give them a chance
    // to handle anything that has been set on that UI.
    if (template.processExtraOptions)
      template.processExtraOptions(options, savedConfig);
  },
};
<|endoftext|>


<commit_before>// The main and unique function !
function renderView(viewObj, parent, dataObj)
{

  // if parent is null or undefined, we stock outerHTML of rendered element in
	var viewString = "";

  for(var v in viewObj)
  {

    // if data is an array
    if(dataObj && dataObj[v] && dataObj[v].constructor === Array) viewObj[v].number = dataObj[v].length;

    // number of iterations of this object
    if(viewObj[v].number === undefined) viewObj[v].number = 1;

	  // if no tag, set it to div by default
	  if(!viewObj[v].tag) viewObj[v].tag = "div";

    for(var i = 0; i < viewObj[v].number; i++)
    {
      // create obj with tag value
      var element = document.createElement(viewObj[v].tag);

      // loop on each element
      for(var a in viewObj[v].attribute)
      {
        // set each attribute for element
        element.setAttribute(a, viewObj[v].attribute[a]);
      }

      // if innerHTML, set it
      if(viewObj[v].innerHTML)
      {
        element.innerHTML = viewObj[v].innerHTML;
      }

      // if data is an aray, override innerHTML with data i
      if(dataObj && dataObj[v] && dataObj[v].constructor === Array) element.innerHTML = dataObj[v][i];

      // else set data if string, number etc
      else if(dataObj && dataObj[v]) element.innerHTML = dataObj[v];

      // if child, we create childs
      if(viewObj[v].child)
      {
        // create each child element with parent = current scope element recursively
        renderView(viewObj[v].child, element, dataObj);
      }

      // here append child to parent, you can use insertBefore either etc
      if(parent) parent.appendChild(element);
      else viewString += element.outerHTML;
    }

   }

   // return viewString in all case
   return viewString;
}
<commit_msg>Add JSDOC comment style<commit_after>/**
 * renderView - The unique method of easyplate :)
 * @method
 * @param  {object} viewObj The view object
 * @param  {element} parent The parent DOM element, could be empty, so return a string
 * @param  {object} dataObj The data that could be mapped to the view : each key is mapped to innerHTML element in viewObj
 * @return {string} Return a string of generated html
 */
function renderView(viewObj, parent, dataObj)
{

  // if parent is null or undefined, we stock outerHTML of rendered element in
	var viewString = "";

  for(var v in viewObj)
  {

    // if data is an array
    if(dataObj && dataObj[v] && dataObj[v].constructor === Array) viewObj[v].number = dataObj[v].length;

    // number of iterations of this object
    if(viewObj[v].number === undefined) viewObj[v].number = 1;

	  // if no tag, set it to div by default
	  if(!viewObj[v].tag) viewObj[v].tag = "div";

    for(var i = 0; i < viewObj[v].number; i++)
    {
      // create obj with tag value
      var element = document.createElement(viewObj[v].tag);

      // loop on each element
      for(var a in viewObj[v].attribute)
      {
        // set each attribute for element
        element.setAttribute(a, viewObj[v].attribute[a]);
      }

      // if innerHTML, set it
      if(viewObj[v].innerHTML)
      {
        element.innerHTML = viewObj[v].innerHTML;
      }

      // if data is an aray, override innerHTML with data i
      if(dataObj && dataObj[v] && dataObj[v].constructor === Array) element.innerHTML = dataObj[v][i];

      // else set data if string, number etc
      else if(dataObj && dataObj[v]) element.innerHTML = dataObj[v];

      // if child, we create childs
      if(viewObj[v].child)
      {
        // create each child element with parent = current scope element recursively
        renderView(viewObj[v].child, element, dataObj);
      }

      // here append child to parent, you can use insertBefore either etc
      if(parent) parent.appendChild(element);
      else viewString += element.outerHTML;
    }

   }

   // return viewString in all case
   return viewString;
}
<|endoftext|>


<commit_before>var Data = {

  starts : [
    "Experiential truth ",
    "Coffee ",
    "Geopolitics ",
    "Javascript ",
    "Glory ",
    "Espresso ",
    "Heuristic thought ",
    "Absinthe ",
    "Surrogate birth ",
    "Rishathra ",
    "Irradiation ",
    "Megalomania ",
    "Solar radiation ",
    "Autosomy ",
    "Practical economics ",
    "Activism ",
    "Dental plaque ",
    "Consternation ",
    "Vanilla nougat ",
    "The physical world ",
    "Sadness ",
    "Chicken ",
    "Non-judgment ",
    "Parsimony ",
    "Hodor ",
    "Salacity ",
    "Grunge music ",
    "Clarity ",
    "Antagonism ",
    "Heterodoxity ",
    "Erudition ",
    "Amalgamation ",
    "Remuneration ",
    "Primacy ",
    "The empty set ",
    "Bergamot marmalade ",
    "Amelioration ",
    "Apostasy ",
    "Reprobacy ",
    "Aquaculture ",
    "Infinity ",
    "Rubric ",
    "Email ",
    "Calamity ",
    "Loquacity ",
    "Honesty ",
    "Cosmology ",
    "Aperture science ",
    "Temporal quaquaversality ",
    "Derrida ",
    "Mellow vibe ",
    "Prosody ",
    "Selectivity ",
    "Unity ",
    "Good health ",
    "A quantum leap ",    // thanks Francis Veilleux-Gaboury
    "A clean brain ",
    "Entreaty ",
    "Brusque temperment ",
    "A flexible thought pattern ",
    "Insightful visage ",
    "Mindfulness in action ",
    "Automated translation ",
    "Facebook ",
    "Compassion ",
    "Altruism ",
    "Totality ",
    "Rhetorical training ",
    "Insoucinace ",
    "Dynamic mutative creation ",
    "The graspably non-considerable ",
    "Social science ",
    "Stone age philosophy ",
    "Interpretive dance ",
    "Meditative physics ",
    "Rambunctious cause ",
    "Biology ",
    "Multitudinality ",
    "Nascent luminence ",
    "True randomness ",
    "Deconstrutionist wisdom ",
    "Science intersecting religion ",
    "The role of a leader ",
    "The soul of a calm person ",
    "The idea of God ",
    "Mechanistic reaction ",
    "Semiotic involvement ",
    "Herotodeus ",
    "Quantum physics ",
    "Cerebrolinguistics ",
    "Dubstep as a metaphor for liberty "
  ],

  middles : [
    "nurtures ",
    "unifies ",
    "stymies ",
    "separates ",
    "distributes widely ",
    "appreciates ",
    "deprecates ",
    "conglomerates ",
    "gives meaning to ",
    "displays ",
    "projects ",
    "permeates ",
    "eviscerates ",
    "clarifies ",
    "macerates ",
    "asceticizes ",
    "recapitulates ",
    "satisfies ",
    "sanctifies via ",
    "trivializes ",
    "justifies with ",
    "rarifies ",
    "enjoins ",
    "codifies ",
    "socializes by way of ",
    "promulgates ",
    "reclaims ",
    "disintegrates ",
    "integrates ",
    "racemizes ",
    "reduces ",
    "explores ",
    "dissociates from within ",
    "cosequences ",
    "exposes ",
    "masticates ",
    "builds, using ",
    "teaches through ",
    "projects onto ",
    "imparts reality to ",
    "constructs with "
  ],

  qualifiers : [
    "abundance of ",
    "ostentatious ",
    "the barrier of ",
    "self-righteous ",
    "collective ",
    "species specific ",
    "heterodynamic ",
    "clarity within ",
    "epistemological ",
    "synchronistic ",
    "timely ",
    "unpredictable ",
    "unassailable ",
    "glassy eyed ",
    "dishonest ",
    "indefatigable ",
    "factual ",
    "highly descriptive ",
    "location based ",
    "describably pure ",
    "bounded ",
    "unbounded ",
    "trans-boundary ",
    "expedient ",
    "ontogenous ",
    "parallelizes ",
    "serendipitous ",
    "geopolitical ",
    "popular ",
    "advocatory ",
    "pluripotentialistic ",
    "atomized ",
    "rhythmatic ",
    "dimensional ",
    "sophist ",
    "Etruscan ",
    "reliquary ",
    "escapist ",
    "aerated ",
    "anarchist ",
    "conformist ",
    "erudite ",
    "epistemic ",
    "cromulent ",
    "poker faced ",
    "miniscule ",
    "Manichean ",
    "Hadrean ",
    "media driven ",
    "global ",
    "local ",
    "post-",
    "hyper-",
    "trans-",
    "extra-",
    "super-",
    "supra-",
    "world regarding ",
    "provably optimal ",
    "potential ",
    "munctional "
  ],

  finishes : [
    "marvel.",
    "choices.",
    "harmony.",
    "phylogeny.",
    "disharmony.",
    "traversal.",
    "ostracism.",
    "semiotics.",
    "deconstructionism.",
    "post-logic.",
    "escapism.",
    "criarchy.",
    "permaculture.",
    "platitudinality.",
    "creosophy.",
    "journalism.",
    "preternaturality.",
    "glossolalia.",
    "idolatry.",
    "conscience confluence.",
    "hapto-ergonomics.",
    "mental rigor.",
    "spiritual fortitude.",
    "wisdom.",
    "secret genius.",
    "inner brilliance.",
    "unseen internal gift.",
    "combobulation.",
    "transdoctrinal inference.",
    "creativity.",
    "significance.",
    "materialization.",
    "generosity.",
    "infinitude.",
    "plurality.",
    "asceticism.",
    "truism.",
    "horizontal scaling.",
    "monopoly.",
    "temerity.",
    "neo-Platonism."
    "monosophism.",
    "polyarchy.",
    "heredity.",
    "togetherness.",
    "voluminous reaction.",
    "joyous revelation.",
    "stimulation.",
    "numbing.",
    "intuition.",
    "actions."
  ]

};

function randFrom(X) {
  return X[Math.floor(Math.random() * X.length)];
}

function makeDC() {
  return randFrom(Data.starts) + randFrom(Data.middles) + randFrom(Data.qualifiers) + randFrom(Data.finishes);
}

function go() {
  document.getElementById('txt').innerHTML = '"' + makeDC() + '"';
}
<commit_msg>colocates by way of<commit_after>var Data = {

  starts : [
    "Experiential truth ",
    "Coffee ",
    "Geopolitics ",
    "Javascript ",
    "Glory ",
    "Espresso ",
    "Heuristic thought ",
    "Absinthe ",
    "Surrogate birth ",
    "Rishathra ",
    "Irradiation ",
    "Megalomania ",
    "Solar radiation ",
    "Autosomy ",
    "Practical economics ",
    "Activism ",
    "Dental plaque ",
    "Consternation ",
    "Vanilla nougat ",
    "The physical world ",
    "Sadness ",
    "Chicken ",
    "Non-judgment ",
    "Parsimony ",
    "Hodor ",
    "Salacity ",
    "Grunge music ",
    "Clarity ",
    "Antagonism ",
    "Heterodoxity ",
    "Erudition ",
    "Amalgamation ",
    "Remuneration ",
    "Primacy ",
    "The empty set ",
    "Bergamot marmalade ",
    "Amelioration ",
    "Apostasy ",
    "Reprobacy ",
    "Aquaculture ",
    "Infinity ",
    "Rubric ",
    "Email ",
    "Calamity ",
    "Loquacity ",
    "Honesty ",
    "Cosmology ",
    "Aperture science ",
    "Temporal quaquaversality ",
    "Derrida ",
    "Mellow vibe ",
    "Prosody ",
    "Selectivity ",
    "Unity ",
    "Good health ",
    "A quantum leap ",    // thanks Francis Veilleux-Gaboury
    "A clean brain ",
    "Entreaty ",
    "Brusque temperment ",
    "A flexible thought pattern ",
    "Insightful visage ",
    "Mindfulness in action ",
    "Automated translation ",
    "Facebook ",
    "Compassion ",
    "Altruism ",
    "Totality ",
    "Rhetorical training ",
    "Insoucinace ",
    "Dynamic mutative creation ",
    "The graspably non-considerable ",
    "Social science ",
    "Stone age philosophy ",
    "Interpretive dance ",
    "Meditative physics ",
    "Rambunctious cause ",
    "Biology ",
    "Multitudinality ",
    "Nascent luminence ",
    "True randomness ",
    "Deconstrutionist wisdom ",
    "Science intersecting religion ",
    "The role of a leader ",
    "The soul of a calm person ",
    "The idea of God ",
    "Mechanistic reaction ",
    "Semiotic involvement ",
    "Herotodeus ",
    "Quantum physics ",
    "Cerebrolinguistics ",
    "Dubstep as a metaphor for liberty "
  ],

  middles : [
    "nurtures ",
    "colocates by way of ",
    "unifies ",
    "stymies ",
    "separates ",
    "distributes widely ",
    "appreciates ",
    "deprecates ",
    "conglomerates ",
    "gives meaning to ",
    "displays ",
    "projects ",
    "permeates ",
    "eviscerates ",
    "clarifies ",
    "macerates ",
    "asceticizes ",
    "recapitulates ",
    "satisfies ",
    "sanctifies via ",
    "trivializes ",
    "justifies with ",
    "rarifies ",
    "enjoins ",
    "codifies ",
    "socializes by way of ",
    "promulgates ",
    "reclaims ",
    "disintegrates ",
    "integrates ",
    "racemizes ",
    "reduces ",
    "explores ",
    "dissociates from within ",
    "cosequences ",
    "exposes ",
    "masticates ",
    "builds, using ",
    "teaches through ",
    "projects onto ",
    "imparts reality to ",
    "constructs with "
  ],

  qualifiers : [
    "abundance of ",
    "ostentatious ",
    "the barrier of ",
    "self-righteous ",
    "collective ",
    "species specific ",
    "heterodynamic ",
    "clarity within ",
    "epistemological ",
    "synchronistic ",
    "timely ",
    "unpredictable ",
    "unassailable ",
    "glassy eyed ",
    "dishonest ",
    "indefatigable ",
    "factual ",
    "highly descriptive ",
    "location based ",
    "describably pure ",
    "bounded ",
    "unbounded ",
    "trans-boundary ",
    "expedient ",
    "ontogenous ",
    "parallelizes ",
    "serendipitous ",
    "geopolitical ",
    "popular ",
    "advocatory ",
    "pluripotentialistic ",
    "atomized ",
    "rhythmatic ",
    "dimensional ",
    "sophist ",
    "Etruscan ",
    "reliquary ",
    "escapist ",
    "aerated ",
    "anarchist ",
    "conformist ",
    "erudite ",
    "epistemic ",
    "cromulent ",
    "poker faced ",
    "miniscule ",
    "Manichean ",
    "Hadrean ",
    "media driven ",
    "global ",
    "local ",
    "post-",
    "hyper-",
    "trans-",
    "extra-",
    "super-",
    "supra-",
    "world regarding ",
    "provably optimal ",
    "potential ",
    "munctional "
  ],

  finishes : [
    "marvel.",
    "choices.",
    "harmony.",
    "phylogeny.",
    "disharmony.",
    "traversal.",
    "ostracism.",
    "semiotics.",
    "deconstructionism.",
    "post-logic.",
    "escapism.",
    "criarchy.",
    "permaculture.",
    "platitudinality.",
    "creosophy.",
    "journalism.",
    "preternaturality.",
    "glossolalia.",
    "idolatry.",
    "conscience confluence.",
    "hapto-ergonomics.",
    "mental rigor.",
    "spiritual fortitude.",
    "wisdom.",
    "secret genius.",
    "inner brilliance.",
    "unseen internal gift.",
    "combobulation.",
    "transdoctrinal inference.",
    "creativity.",
    "significance.",
    "materialization.",
    "generosity.",
    "infinitude.",
    "plurality.",
    "asceticism.",
    "truism.",
    "horizontal scaling.",
    "monopoly.",
    "temerity.",
    "neo-Platonism."
    "monosophism.",
    "polyarchy.",
    "heredity.",
    "togetherness.",
    "voluminous reaction.",
    "joyous revelation.",
    "stimulation.",
    "numbing.",
    "intuition.",
    "actions."
  ]

};

function randFrom(X) {
  return X[Math.floor(Math.random() * X.length)];
}

function makeDC() {
  return randFrom(Data.starts) + randFrom(Data.middles) + randFrom(Data.qualifiers) + randFrom(Data.finishes);
}

function go() {
  document.getElementById('txt').innerHTML = '"' + makeDC() + '"';
}
<|endoftext|>


<commit_before>var Leap = require('leapjs');

var controller = new Leap.Controller({ inNode: true });

var eventemitter;
var inflight = false;
var drone_ready = true;

var leap = function(emitter) {
	eventemitter = emitter;

	eventemitter.on('inflight', function() {
		inflight = true;
	});
};

controller.on("frame", function(frame) {
	if (!inflight) {
		return;
	}

	if (frame.hands.length > 0) {
		var speed = frame.hands[0].palmVelocity[1];
		if (speed > 0) {
			eventemitter.emit('up', speed);
		} else if (speed < 0) {
			eventemitter.emit('down', -1 * speed);
		}
	}
});

var frameCount = 0;
controller.on("frame", function(frame) {
	frameCount++;
});

setInterval(function() {
	var time = frameCount/2;
	console.log("received " + frameCount + " frames @ " + time + "fps");
	frameCount = 0;
}, 2000);

controller.on('ready', function() {
	console.log("ready");
});
controller.on('connect', function() {
	console.log("connect");
});

controller.on('disconnect', function() {
	console.log("disconnect -> land");
	eventemitter.emit('land');
	inflight = false;
});
controller.on('focus', function() {
	if (drone_ready) {
		console.log("focus -> takeoff");
		eventemitter.emit('takeoff');
	}
});
controller.on('blur', function() {
	console.log("blur");
});
controller.on('deviceConnected', function() {
	console.log("deviceConnected");
	eventemitter.emit('takeoff');
});
controller.on('deviceDisconnected', function() {
	console.log("deviceDisconnected -> land");
	inflight = false;
	eventemitter.emit('land');
});

controller.connect();

module.exports = leap;
<commit_msg>added left / right<commit_after>var Leap = require('leapjs');

var controller = new Leap.Controller({ inNode: true });

var eventemitter;
var inflight = false;
var drone_ready = true;

var leap = function(emitter) {
	eventemitter = emitter;

	eventemitter.on('inflight', function() {
		inflight = true;
	});
};

controller.on("frame", function(frame) {
	if (!inflight) {
		//return;
	}

	if (frame.hands.length > 0) {
		var up_down_speed = frame.hands[0].palmVelocity[1];
		if (up_down_speed > 20) {
			eventemitter.emit('up', up_down_speed);
		} else if (up_down_speed < -20) {
			eventemitter.emit('down', -1 * up_down_speed);
		}

		var right_left_speed = frame.hands[0].palmNormal[0];
		if (right_left_speed > 0.15) {
			eventemitter.emit('left', right_left_speed);
		} else if (right_left_speed < -0.15) {
			eventemitter.emit('right', -1 * right_left_speed);
		}

	}
});

var frameCount = 0;
controller.on("frame", function(frame) {
	frameCount++;
});

setInterval(function() {
	var time = frameCount/2;
	console.log("received " + frameCount + " frames @ " + time + "fps");
	frameCount = 0;
}, 2000);

controller.on('ready', function() {
	console.log("ready");
});
controller.on('connect', function() {
	console.log("connect");
});

controller.on('disconnect', function() {
	console.log("disconnect -> land");
	eventemitter.emit('land');
	inflight = false;
});
controller.on('focus', function() {
	if (drone_ready) {
		console.log("focus -> takeoff");
		eventemitter.emit('takeoff');
	}
});
controller.on('blur', function() {
	console.log("blur");
});
controller.on('deviceConnected', function() {
	console.log("deviceConnected");
	eventemitter.emit('takeoff');
});
controller.on('deviceDisconnected', function() {
	console.log("deviceDisconnected -> land");
	inflight = false;
	eventemitter.emit('land');
});

controller.connect();

module.exports = leap;
<|endoftext|>


<commit_before>/*
 Limited scope for setup
*/
(function() {
    "use strict"
    var PatienceError = function(msg) {
        this.toString = function() {
            return '[ PatienceError: ' + msg + ' ]';
        };
    };

    /*
        Decent visibility check using jQuery
    */
    function hidden(item) {
        return (
            item.css('display') === 'none' ||
            item.css('visibility') === 'hidden' ||
            item.css('opacity') == 0 ||
            item.height() === 0 ||
            item.width() === 0
        );
    }

    if (void(0) === window) {
        throw new PatienceError('window is not defined. Are you using Patience in a web browser? Currently that is all it supports.');
    }

    if (window.Patience) {
        throw new PatienceError('Patience is already defined. :(');
    }

    window.Patience = new (function() {

        var self = this;
        this.DEFAULT_TIMEOUT = 5000;
        this.DEFAULT_INTERVAL = 500;
        this.has$ = false;

        if (void(0) === window.jQuery && window.console && window.console.log) {
            console.log('jQuery was not found, some features will be restricted. If you are using jQuery, load patience.js after jQuery.');
        } else {
            self.has$ = true;
        }

        /*
            Ironically, Patience isn't very patient.
            After a certain amount of time, Patience will call
            the reject method to indicate that whatever you
            were waiting for "never" happened.
        */
        this.setDefaultTimeout = function(timeout) {
            if (isNaN(timeout) || typeof timeout != 'number') {
                throw new PatienceError('setDefaultTimeout expects a number (milliseconds)');
            }
            self.DEFAULT_TIMEOUT = timeout;
        };

        /*
            Default interval is how often Patience waiters will
            look for the specified condition to be met
        */
        this.setDefaultInterval = function(timeout) {
            if (isNaN(timeout) || typeof timeout != 'number') {
                throw new PatienceError('setDefaultInterval expects a number (milliseconds)');
            }
            self.DEFAULT_INTERVAL = timeout;
        };

        /*
        * Simply for debugging and keeping track of
        * possible leaks. All waiter objects get stuffed
        * into here until they are gone, which, if all goes
        * correctly should clean themsevles up.
        * */
        this.waiters = {};
        // arbitrary counter for keying waiters map
        this.waiterCounter = 0;
        this.addWaiter = function(w) {
            w.id = self.waiterCounter;
            self.waiters[w.id] = w;
            self.waiterCounter += 1;
        };
        this.removeWaiter = function(w) {
            delete self.waiters[w.id];
        };

        this.finish = function(waiter, complete) {
            clearInterval(waiter.interval);
            self.removeWaiter(waiter);
            complete();
        };

        /*
        * Patience is simply an interface to create new waiters
        *
        * Waiters get instantiated and start waiting for
        * methods to return true, then makes it's best
        * attempt to clean itself up. It's simpler
        * than trying to manage many intervals in the
        * scope of the Patience parent object
        * */
        var Waiter = function(fn, result, timeout) {
            var w = this;
            this.interval = null;
            this.id = null;
            this.start = function(resolve, reject) {
                var startTime = +new Date();
                w.interval = setInterval(function() {
                    if (+new Date() - startTime > timeout) {
                        // Condition was not met in time
                        self.finish(w, reject);
                    } else {
                        var r = fn();
                        if (r === result) {
                            self.finish(w, resolve);
                        }
                    }
                }, self.DEFAULT_INTERVAL);
            };

        };

        function checkTimeout(timeout) {
            timeout = timeout || self.DEFAULT_TIMEOUT;
            if (!timeout || isNaN(timeout) || timeout < 501) {
                throw new PatienceError('Specified Patience.waitFor timeout is too short.');
            }
            return timeout;
        }

        this.waitFor = function waitFor(fn, timeout) {
            if (typeof fn != 'function') {
                throw new PatienceError("waitFor() requires a function argument (a condition to periodically check)");
            }
            timeout = checkTimeout(timeout);
            return {
                toBe: function(result) {
                    if (arguments.length > 0) {
                        var w = new Waiter(fn, result, timeout);
                        self.addWaiter(w);
                        return new Promise(function(resolve, reject) {
                            w.start(resolve, reject);
                        });
                    } else {
                        throw new PatienceError('You must set a result with .toBe(<result>)');
                    }
                }
            };
        };

        this.waitForSelector = function(selector, timeout) {
            if (!self.has$) {
                throw new PatienceError("Patience.waitForSelector requires jQuery");
            }
            if (typeof selector != 'string') {
                throw new PatienceError("waitForSelector() requires a selector");
            }
            timeout = checkTimeout(timeout);
            return {
                toBe: {
                    visible: function() {
                        var fn = function() {
                            var item = $(selector);
                            return item && !hidden(item);
                        };
                        var w = new Waiter(fn, true, timeout);
                        self.addWaiter(w);
                        return new Promise(function(resolve, reject) {
                            w.start(resolve, reject);
                        });
                    },
                    hidden: function() {
                        var fn = function() {
                            var item = $(selector);
                            return item && hidden(item);
                        };
                        var w = new Waiter(fn, true, timeout);
                        self.addWaiter(w);
                        return new Promise(function(resolve, reject) {
                            w.start(resolve, reject);
                        });
                    },
                    present: function() {
                        var fn = function() {
                            var item = $(selector);
                            return !!item;
                        };
                        var w = new Waiter(fn, true, timeout);
                        self.addWaiter(w);
                        return new Promise(function(resolve, reject) {
                            w.start(resolve, reject);
                        });
                    }
                }
            }

        };

    })();
})();<commit_msg>Fix present jquery built int<commit_after>/*
 Limited scope for setup
*/
(function() {
    "use strict"
    var PatienceError = function(msg) {
        this.toString = function() {
            return '[ PatienceError: ' + msg + ' ]';
        };
    };

    /*
        Decent visibility check using jQuery
    */
    function hidden(item) {
        return (
            item.css('display') === 'none' ||
            item.css('visibility') === 'hidden' ||
            item.css('opacity') == 0 ||
            item.height() === 0 ||
            item.width() === 0
        );
    }

    if (void(0) === window) {
        throw new PatienceError('window is not defined. Are you using Patience in a web browser? Currently that is all it supports.');
    }

    if (window.Patience) {
        throw new PatienceError('Patience is already defined. :(');
    }

    window.Patience = new (function() {

        var self = this;
        this.DEFAULT_TIMEOUT = 5000;
        this.DEFAULT_INTERVAL = 500;
        this.has$ = false;

        if (void(0) === window.jQuery && window.console && window.console.log) {
            console.log('jQuery was not found, some features will be restricted. If you are using jQuery, load patience.js after jQuery.');
        } else {
            self.has$ = true;
        }

        /*
            Ironically, Patience isn't very patient.
            After a certain amount of time, Patience will call
            the reject method to indicate that whatever you
            were waiting for "never" happened.
        */
        this.setDefaultTimeout = function(timeout) {
            if (isNaN(timeout) || typeof timeout != 'number') {
                throw new PatienceError('setDefaultTimeout expects a number (milliseconds)');
            }
            self.DEFAULT_TIMEOUT = timeout;
        };

        /*
            Default interval is how often Patience waiters will
            look for the specified condition to be met
        */
        this.setDefaultInterval = function(timeout) {
            if (isNaN(timeout) || typeof timeout != 'number') {
                throw new PatienceError('setDefaultInterval expects a number (milliseconds)');
            }
            self.DEFAULT_INTERVAL = timeout;
        };

        /*
        * Simply for debugging and keeping track of
        * possible leaks. All waiter objects get stuffed
        * into here until they are gone, which, if all goes
        * correctly should clean themsevles up.
        * */
        this.waiters = {};
        // arbitrary counter for keying waiters map
        this.waiterCounter = 0;
        this.addWaiter = function(w) {
            w.id = self.waiterCounter;
            self.waiters[w.id] = w;
            self.waiterCounter += 1;
        };
        this.removeWaiter = function(w) {
            delete self.waiters[w.id];
        };

        this.finish = function(waiter, complete) {
            clearInterval(waiter.interval);
            self.removeWaiter(waiter);
            complete();
        };

        /*
        * Patience is simply an interface to create new waiters
        *
        * Waiters get instantiated and start waiting for
        * methods to return true, then makes it's best
        * attempt to clean itself up. It's simpler
        * than trying to manage many intervals in the
        * scope of the Patience parent object
        * */
        var Waiter = function(fn, result, timeout) {
            var w = this;
            this.interval = null;
            this.id = null;
            this.start = function(resolve, reject) {
                var startTime = +new Date();
                w.interval = setInterval(function() {
                    if (+new Date() - startTime > timeout) {
                        // Condition was not met in time
                        self.finish(w, reject);
                    } else {
                        var r = fn();
                        if (r === result) {
                            self.finish(w, resolve);
                        }
                    }
                }, self.DEFAULT_INTERVAL);
            };

        };

        function checkTimeout(timeout) {
            timeout = timeout || self.DEFAULT_TIMEOUT;
            if (!timeout || isNaN(timeout) || timeout < 501) {
                throw new PatienceError('Specified Patience.waitFor timeout is too short.');
            }
            return timeout;
        }

        this.waitFor = function waitFor(fn, timeout) {
            if (typeof fn != 'function') {
                throw new PatienceError("waitFor() requires a function argument (a condition to periodically check)");
            }
            timeout = checkTimeout(timeout);
            return {
                toBe: function(result) {
                    if (arguments.length > 0) {
                        var w = new Waiter(fn, result, timeout);
                        self.addWaiter(w);
                        return new Promise(function(resolve, reject) {
                            w.start(resolve, reject);
                        });
                    } else {
                        throw new PatienceError('You must set a result with .toBe(<result>)');
                    }
                }
            };
        };

        this.waitForSelector = function(selector, timeout) {
            if (!self.has$) {
                throw new PatienceError("Patience.waitForSelector requires jQuery");
            }
            if (typeof selector != 'string') {
                throw new PatienceError("waitForSelector() requires a selector");
            }
            timeout = checkTimeout(timeout);
            return {
                toBe: {
                    visible: function() {
                        var fn = function() {
                            var item = $(selector);
                            return item && !hidden(item);
                        };
                        var w = new Waiter(fn, true, timeout);
                        self.addWaiter(w);
                        return new Promise(function(resolve, reject) {
                            w.start(resolve, reject);
                        });
                    },
                    hidden: function() {
                        var fn = function() {
                            var item = $(selector);
                            return item && hidden(item);
                        };
                        var w = new Waiter(fn, true, timeout);
                        self.addWaiter(w);
                        return new Promise(function(resolve, reject) {
                            w.start(resolve, reject);
                        });
                    },
                    present: function() {
                        var fn = function() {
                            var item = $(selector);
                            return !!item && item.length > 0;
                        };
                        var w = new Waiter(fn, true, timeout);
                        self.addWaiter(w);
                        return new Promise(function(resolve, reject) {
                            w.start(resolve, reject);
                        });
                    }
                }
            }

        };

    })();
})();<|endoftext|>


<commit_before>/**
@ngdoc directive
@name umbraco.directives.directive:umbEditorHeader
@restrict E
@scope

@description
Use this directive to construct a header inside the main editor window.

Markup example

        <form name="mySectionForm" novalidate>

            <umb-editor-view>

                <umb-editor-header
                    name="vm.content.name"
                    hide-alias="true"
                    hide-description="true"
                    hide-icon="true">
                </umb-editor-header>

                <umb-editor-container>
                    // main content here
                </umb-editor-container>

                <umb-editor-footer>
                    // footer content here
                </umb-editor-footer>

            </umb-editor-view>

        </form>

Markup example - with tabs

        <form name="mySectionForm" val-form-manager novalidate>

            <umb-editor-view umb-tabs>

                <umb-editor-header
                    name="vm.content.name"
                    tabs="vm.content.tabs"
                    hide-alias="true"
                    hide-description="true"
                    hide-icon="true">
                </umb-editor-header>

                <umb-editor-container>
                    <umb-tabs-content class="form-horizontal" view="true">
                        <umb-tab id="tab{{tab.id}}" ng-repeat="tab in vm.content.tabs" rel="{{tab.id}}">

                                // tab 1 content

                                // tab 2 content

                        </umb-tab>
                    </umb-tabs-content>
                </umb-editor-container>

                <umb-editor-footer>
                    // footer content here
                </umb-editor-footer>

            </umb-editor-view>

        </form>

Controller example - with tabs

    (function () {
        "use strict";

        function Controller() {

            var vm = this;
            vm.content = {
                name: "",
                tabs: [
                    {
                        id: 1,
                        label: "Tab 1",
                        alias: "tab1",
                        active: true
                    },
                    {
                        id: 2,
                        label: "Tab 2",
                        alias: "tab2",
                        active: false
                    }
                ]
            };

        }

        angular.module("umbraco").controller("MySection.Controller", Controller);
    })();

Markup example - with sub views

        <form name="mySectionForm" val-form-manager novalidate>

            <umb-editor-view>

                <umb-editor-header
                    name="vm.content.name"
                    navigation="vm.content.navigation"
                    hide-alias="true"
                    hide-description="true"
                    hide-icon="true">
                </umb-editor-header>

                <umb-editor-container>

                    <umb-editor-sub-views
                        sub-views="vm.content.navigation"
                        model="vm.content">
                    </umb-editor-sub-views>

                </umb-editor-container>

                <umb-editor-footer>
                    // footer content here
                </umb-editor-footer>

            </umb-editor-view>

        </form>

Controller example - with sub views

    (function () {

        "use strict";

        function Controller() {

            var vm = this;
            vm.content = {
                name: "",
                navigation: [
                    {
                        "name": "Section 1",
                        "icon": "icon-document-dashed-line",
                        "view": "/App_Plugins/path/to/html.html",
                        "active": true
                    },
                    {
                        "name": "Section 2",
                        "icon": "icon-list",
                        "view": "/App_Plugins/path/to/html.html",
                    }
                ]
            };

        }

        angular.module("umbraco").controller("MySection.Controller", Controller);
    })();

Use in combination with

{@link umbraco.directives.directive:umbEditorView umbEditorView}

{@link umbraco.directives.directive:umbEditorContainer umbEditorContainer}

{@link umbraco.directives.directive:umbEditorFooter umbEditorFooter}

@param {string} name The content name.
@param {array=} tabs Array of tabs. See example above.
@param {array=} navigation Array of sub views. See example above.
@param {boolean=} nameLocked Set to true to lock the name.
@param {object=} menu Add a context menu to the editor.
@param {string=} icon Show and edit the content icon. Opens an overlay to change the icon.
@param {boolean=} hideIcon Set to true to hide icon.
@param {string=} alias show and edit the content alias.
@param {boolean=} hideAlias Set to true to hide alias.
@param {string=} description Add a description to the content.
@param {boolean=} hideDescription Set to true to hide description.

**/

(function() {
    'use strict';

    function EditorHeaderDirective(iconHelper) {

        function link(scope, el, attr, ctrl) {

            scope.openIconPicker = function() {
                scope.dialogModel = {
                    view: "iconpicker",
                    show: true,
                    icon: scope.icon.split(' ')[0],
                    color: scope.icon.split(' ')[1],
                    submit: function (model) {

                        /* ensure an icon is selected, because on focus on close button
                           or an element in background no icon is submitted. So don't clear/update existing icon/preview.
                        */
                        if (model.icon) {

                            if (model.color) {
                                scope.icon = model.icon + " " + model.color;
                            } else {
                                scope.icon = model.icon;
                            }

                            // set the icon form to dirty
                            scope.iconForm.$setDirty();
                        }

                        scope.dialogModel.show = false;
                        scope.dialogModel = null;
                    }
                };
            };
        }

        var directive = {
            transclude: true,
            restrict: 'E',
            replace: true,
            templateUrl: 'views/components/editor/umb-editor-header.html',
            scope: {
                tabs: "=",
                actions: "=",
                name: "=",
                nameLocked: "=",
                menu: "=",
                icon: "=",
                hideIcon: "@",
                alias: "=",
                hideAlias: "@",
                description: "=",
                hideDescription: "@",
                descriptionLocked: "@",
                navigation: "=",
                key: "="
            },
            link: link
        };

        return directive;
    }

    angular.module('umbraco.directives').directive('umbEditorHeader', EditorHeaderDirective);

})();
<commit_msg>Setting hide-alias to false still hides the alias<commit_after>/**
@ngdoc directive
@name umbraco.directives.directive:umbEditorHeader
@restrict E
@scope

@description
Use this directive to construct a header inside the main editor window.

Markup example

        <form name="mySectionForm" novalidate>

            <umb-editor-view>

                <umb-editor-header
                    name="vm.content.name"
                    hide-alias="true"
                    hide-description="true"
                    hide-icon="true">
                </umb-editor-header>

                <umb-editor-container>
                    // main content here
                </umb-editor-container>

                <umb-editor-footer>
                    // footer content here
                </umb-editor-footer>

            </umb-editor-view>

        </form>

Markup example - with tabs

        <form name="mySectionForm" val-form-manager novalidate>

            <umb-editor-view umb-tabs>

                <umb-editor-header
                    name="vm.content.name"
                    tabs="vm.content.tabs"
                    hide-alias="true"
                    hide-description="true"
                    hide-icon="true">
                </umb-editor-header>

                <umb-editor-container>
                    <umb-tabs-content class="form-horizontal" view="true">
                        <umb-tab id="tab{{tab.id}}" ng-repeat="tab in vm.content.tabs" rel="{{tab.id}}">

                                // tab 1 content

                                // tab 2 content

                        </umb-tab>
                    </umb-tabs-content>
                </umb-editor-container>

                <umb-editor-footer>
                    // footer content here
                </umb-editor-footer>

            </umb-editor-view>

        </form>

Controller example - with tabs

    (function () {
        "use strict";

        function Controller() {

            var vm = this;
            vm.content = {
                name: "",
                tabs: [
                    {
                        id: 1,
                        label: "Tab 1",
                        alias: "tab1",
                        active: true
                    },
                    {
                        id: 2,
                        label: "Tab 2",
                        alias: "tab2",
                        active: false
                    }
                ]
            };

        }

        angular.module("umbraco").controller("MySection.Controller", Controller);
    })();

Markup example - with sub views

        <form name="mySectionForm" val-form-manager novalidate>

            <umb-editor-view>

                <umb-editor-header
                    name="vm.content.name"
                    navigation="vm.content.navigation"
                    hide-alias="true"
                    hide-description="true"
                    hide-icon="true">
                </umb-editor-header>

                <umb-editor-container>

                    <umb-editor-sub-views
                        sub-views="vm.content.navigation"
                        model="vm.content">
                    </umb-editor-sub-views>

                </umb-editor-container>

                <umb-editor-footer>
                    // footer content here
                </umb-editor-footer>

            </umb-editor-view>

        </form>

Controller example - with sub views

    (function () {

        "use strict";

        function Controller() {

            var vm = this;
            vm.content = {
                name: "",
                navigation: [
                    {
                        "name": "Section 1",
                        "icon": "icon-document-dashed-line",
                        "view": "/App_Plugins/path/to/html.html",
                        "active": true
                    },
                    {
                        "name": "Section 2",
                        "icon": "icon-list",
                        "view": "/App_Plugins/path/to/html.html",
                    }
                ]
            };

        }

        angular.module("umbraco").controller("MySection.Controller", Controller);
    })();

Use in combination with

{@link umbraco.directives.directive:umbEditorView umbEditorView}

{@link umbraco.directives.directive:umbEditorContainer umbEditorContainer}

{@link umbraco.directives.directive:umbEditorFooter umbEditorFooter}

@param {string} name The content name.
@param {array=} tabs Array of tabs. See example above.
@param {array=} navigation Array of sub views. See example above.
@param {boolean=} nameLocked Set to true to lock the name.
@param {object=} menu Add a context menu to the editor.
@param {string=} icon Show and edit the content icon. Opens an overlay to change the icon.
@param {boolean=} hideIcon Set to true to hide icon.
@param {string=} alias show and edit the content alias.
@param {boolean=} hideAlias Set to true to hide alias.
@param {string=} description Add a description to the content.
@param {boolean=} hideDescription Set to true to hide description.

**/

(function() {
    'use strict';

    function EditorHeaderDirective(iconHelper) {

        function link(scope, el, attr, ctrl) {

            scope.openIconPicker = function() {
                scope.dialogModel = {
                    view: "iconpicker",
                    show: true,
                    icon: scope.icon.split(' ')[0],
                    color: scope.icon.split(' ')[1],
                    submit: function (model) {

                        /* ensure an icon is selected, because on focus on close button
                           or an element in background no icon is submitted. So don't clear/update existing icon/preview.
                        */
                        if (model.icon) {

                            if (model.color) {
                                scope.icon = model.icon + " " + model.color;
                            } else {
                                scope.icon = model.icon;
                            }

                            // set the icon form to dirty
                            scope.iconForm.$setDirty();
                        }

                        scope.dialogModel.show = false;
                        scope.dialogModel = null;
                    }
                };
            };
        }

        var directive = {
            transclude: true,
            restrict: 'E',
            replace: true,
            templateUrl: 'views/components/editor/umb-editor-header.html',
            scope: {
                tabs: "=",
                actions: "=",
                name: "=",
                nameLocked: "=",
                menu: "=",
                icon: "=",
                hideIcon: "@",
                alias: "=",
                hideAlias: "=",
                description: "=",
                hideDescription: "@",
                descriptionLocked: "@",
                navigation: "=",
                key: "="
            },
            link: link
        };

        return directive;
    }

    angular.module('umbraco.directives').directive('umbEditorHeader', EditorHeaderDirective);

})();
<|endoftext|>