<commit_before>// change layout based on amount of Y scroll
var startProductBarPos=-1;

function moveThings() {
    if(window.innerWidth > 960) {
        var nav = document.getElementById('video-navigation');
        var con = document.getElementById('video-frame');
        // var gotovideo = document.getElementById('gotovideo');
        var phonemesO = document.getElementById('gotophonemes-original');
        var phonemes = document.getElementById('gotophonemes');
        var recbuttons = document.getElementsByClassName('recorder');
        var entryContent = document.getElementsByClassName('entry-content')[0];
        var clusters = document.getElementById('clusters');
        var clustersTop = findPosY(clusters);
        var navtop;
        var contop;
        if(window.innerWidth > 1242){
            navtop = '75px';
            contop = 125;
        }else{
            navtop = 0;
            contop = 75;
        }

        if(startProductBarPos<0)startProductBarPos=findPosY(nav);
        if(pageYOffset>startProductBarPos){
            nav.style.position='fixed';
            nav.style.top=navtop;
            nav.style.display='flex';
            nav.style.width='100%';
            nav.style.height='2em';
            nav.style.lineHeight='1em';
            // gotovideo.style.display='inherit';
            phonemes.style.display='inherit';
            phonemesO.style.display='none';
            con.style.position='fixed';
            con.style.top=contop+'px';
            if(pageYOffset>clustersTop){
                con.style.top=(contop-pageYOffset+clustersTop)+'px';
            }
            con.style.right='5px';
            con.style.width='30%';
            entryContent.style.position='relative';
            entryContent.style.left='-20%';
            if(window.innerWidth < 1100) {
                con.style.width='20%';
                entryContent.style.left='-12%';
            }

            for (var i=1; i < recbuttons.length; i++) recbuttons[i].style.margin='0 5px';
        }else{
            nav.style.position='relative';
            nav.style.top=0;
            nav.style.display='inline-block';
            nav.style.width='30%';
            nav.style.height='inherit';
            nav.style.lineHeight='inherit';
            // gotovideo.style.display='none';
            phonemes.style.display='none';
            phonemesO.style.display='inherit';
            con.style.position='relative';
            con.style.top=0;
            con.style.right=0;
            con.style.width='70%';
            entryContent.style.position='inherit';
            entryContent.style.left=0;
            for (var i=1; i < recbuttons.length; i++) recbuttons[i].style.margin='25px 5px';
        }
    }else{
        var vid = document.getElementById('video-frame');
        var navmobile = document.getElementById('video-navigation-mobile');
        if(pageYOffset>vid.offsetTop){
            navmobile.style.display='flex';
        }else{
            navmobile.style.display='none';
        }
    }
}

window.onscroll=function(){
    moveThings();
};

window.onresize=function(){
    moveThings();
};

function findPosY(obj) {
    var curtop = 0;
    if (typeof (obj.offsetParent) != 'undefined' && obj.offsetParent) {
        while (obj.offsetParent) {
            curtop += obj.offsetTop;
            obj = obj.offsetParent;
        }
        curtop += obj.offsetTop;
    }
    else if (obj.y)
        curtop += obj.y;
    return curtop;
}
<commit_msg>minor interface update<commit_after>// change layout based on amount of Y scroll
var startProductBarPos=-1;

function moveThings() {
    if(window.innerWidth > 960) {
        var nav = document.getElementById('video-navigation');
        var con = document.getElementById('video-frame');
        // var gotovideo = document.getElementById('gotovideo');
        var phonemesO = document.getElementById('gotophonemes-original');
        var phonemes = document.getElementById('gotophonemes');
        var recbuttons = document.getElementsByClassName('recorder');
        var entryContent = document.getElementsByClassName('entry-content')[0];
        var clusters = document.getElementById('clusters');
        var clustersTop = findPosY(clusters);
        var navtop;
        var contop;
        if(window.innerWidth > 1242){
            navtop = '75px';
            contop = 125;
        }else{
            navtop = 0;
            contop = 75;
        }

        if(startProductBarPos<0)startProductBarPos=findPosY(nav);
        if(pageYOffset>startProductBarPos){
            nav.style.position='fixed';
            nav.style.top=navtop;
            nav.style.display='flex';
            nav.style.width='100%';
            nav.style.height='2em';
            nav.style.lineHeight='1em';
            // gotovideo.style.display='inherit';
            phonemes.style.display='inherit';
            phonemesO.style.display='none';
            con.style.position='fixed';
            con.style.top=contop+'px';
            if(pageYOffset>clustersTop){
                con.style.top=(contop-pageYOffset+clustersTop)+'px';
            }
            con.style.right='5px';
            con.style.width='30%';
            entryContent.style.position='relative';
            entryContent.style.left='-20%';
            if(window.innerWidth < 1100) {
                con.style.width='20%';
                entryContent.style.left='-12%';
            }
            $("#phoneme-explanation").detach().appendTo('#video-frame')
            for (var i=1; i < recbuttons.length; i++) recbuttons[i].style.margin='0 5px';
        }else{
            nav.style.position='relative';
            nav.style.top=0;
            nav.style.display='inline-block';
            nav.style.width='30%';
            nav.style.height='inherit';
            nav.style.lineHeight='inherit';
            // gotovideo.style.display='none';
            phonemes.style.display='none';
            phonemesO.style.display='inherit';
            con.style.position='relative';
            con.style.top=0;
            con.style.right=0;
            con.style.width='70%';
            entryContent.style.position='inherit';
            entryContent.style.left=0;
            $("#phoneme-explanation").detach().appendTo('#phoneme')
            for (var i=1; i < recbuttons.length; i++) recbuttons[i].style.margin='25px 5px';
        }
    }else{
        var vid = document.getElementById('video-frame');
        var navmobile = document.getElementById('video-navigation-mobile');
        if(pageYOffset>vid.offsetTop){
            navmobile.style.display='flex';
        }else{
            navmobile.style.display='none';
        }
    }
}

window.onscroll=function(){
    moveThings();
};

window.onresize=function(){
    moveThings();
};

function findPosY(obj) {
    var curtop = 0;
    if (typeof (obj.offsetParent) != 'undefined' && obj.offsetParent) {
        while (obj.offsetParent) {
            curtop += obj.offsetTop;
            obj = obj.offsetParent;
        }
        curtop += obj.offsetTop;
    }
    else if (obj.y)
        curtop += obj.y;
    return curtop;
}
<|endoftext|>


<commit_before>// Extract a list of property values

var map = require('./map')

function pluck (arr, propName) {
  return map(arr, propName)
}

module.exports = pluck
<commit_msg>update array/pluck<commit_after>// Extract a list of property values

var map = require('./map')
var prop = require('../function/prop')

function pluck (arr, name) {
  return map(arr, prop(name))
}

module.exports = pluck
<|endoftext|>


<commit_before>/* Copyright (c) Royal Holloway, University of London | Contact Blake Loring (blake@parsed.uk), Duncan Mitchell (Duncan.Mitchell.2015@rhul.ac.uk), or Johannes Kinder (johannes.kinder@rhul.ac.uk) for details or support | LICENSE.md for license details */

const {app, Menu, BrowserWindow} = require('electron');

const path = require('path');
const url = require('url');

app.commandLine.appendSwitch('proxy-server', '127.0.0.1:8080');

console.log(process.argv[process.argv.length - 2])

let mainWindow;

function createWindow () {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    minWidth: 800,
    minHeight: 600
  })

  // and load the index.html of the app.
//  mainWindow.loadURL(process.argv[process.argv.length - 2]);
  mainWindow.loadURL('https://google.com');
  mainWindow.on('closed', function () {
    mainWindow = null;
  });
}

app.on('ready', function() {
  const menu = Menu.buildFromTemplate([]);
  //Menu.setApplicationMenu(menu);
  createWindow();
});

app.on('window-all-closed', function () {
  app.quit();
});

app.on('activate', function () {
  if (mainWindow === null) {
    createWindow();
  }
})
<commit_msg>Set to real URL<commit_after>/* Copyright (c) Royal Holloway, University of London | Contact Blake Loring (blake@parsed.uk), Duncan Mitchell (Duncan.Mitchell.2015@rhul.ac.uk), or Johannes Kinder (johannes.kinder@rhul.ac.uk) for details or support | LICENSE.md for license details */

const {app, Menu, BrowserWindow} = require('electron');

const path = require('path');
const url = require('url');

app.commandLine.appendSwitch('proxy-server', '127.0.0.1:8080');

console.log(process.argv[process.argv.length - 2])

let mainWindow;

function createWindow () {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    minWidth: 800,
    minHeight: 600
  })

  // and load the index.html of the app.
  mainWindow.loadURL(process.argv[process.argv.length - 2]);
  mainWindow.on('closed', function () {
    mainWindow = null;
  });
}

app.on('ready', function() {
  const menu = Menu.buildFromTemplate([]);
  //Menu.setApplicationMenu(menu);
  createWindow();
});

app.on('window-all-closed', function () {
  app.quit();
});

app.on('activate', function () {
  if (mainWindow === null) {
    createWindow();
  }
})
<|endoftext|>


<commit_before>"use strict";
// Base modules
var _ 	= require('underscore');

// Derplib modules
var MM 			= module.parent,
	utils 		= MM.libary.load('utils'),
	eventModule = MM.libary.load('eventModule'),
	db 			= MM.plugin.load('database'),
	permissions = MM.plugin.load('permissions');

// data
var commands = {};

// Register commands
MM._data.command = {
	dir: './commands/',
	loaded: {},
	prot: [],
};

MM.command = {
	load: function(x){ return MM._load(x, 'command') },
	unload: function(x){ return MM._unload(x, 'command') },
	reload: function(x){ return MM._reload(x, 'command') },
	all: function(){ return MM._data.command.loaded; },
};

// Load all commands
exports.autoLoad = function(){

	utils.walkdir('./commands', function(err, result){
		if(err) throw err;
		_.each(_.filter(result, function(x){ return x.substr(-3) == ".js"; }), function(cmd){
			MM.command.load(cmd);
		});
	});

	return exports;
}

exports.get = function(cmd){
	if(undefined == cmd)
		return commands;
	else if(_.has(commands, cmd))
		return commands[cmd];
	else if(~cmd.indexOf('-')){

	} else
		return false;
}

// Raw command object
function newCommand(args){
	var commandObject = {
		key: '',			// Handle key and command word
		access: false,		// Required access level
		nodes: ['run'],		// For permissions
		prefixes: [],		// If not empty over-writes default prefixes
		description: '',	// Text shown for commands in !help (leave empty to not show)
		// Settings
		active: true,		// Disable command
		user_timeout: 0,	// Interval in between the function can be used per user
		room_timeout: 0,	// Interval in between the function can be used in whole room
		room_only: false,	// Command can't be used in pm
		pm_only: false,		// Command can't be used in rooms
		abbreviations: [],	// Alternate command words
		available: function(req){ return true; },	// Check if the user is allowed to execute command, aside from access level
		subcommands: [],	// If first argument equals subcommand key, execute that.
		cache: {
			users: {},		// User cache, dissapears on reboot - includes 'lastused'
			rooms: {},		// Room cache, dissapears on reboot - includes 'lastused'
			global: {},		// Global cache for the command
		},
		run: function(req){}, //Execution function
	};
	return _.extend(commandObject, args);
}

exports.findCommand = function(args){
	if(args.length === 0) return false;
	var cmd = _.first(args).toLowerCase();
	var command = _.find(commands, function(x){ return x.key == cmd || _.contains(x.abbreviations, cmd); });

	if(command){ // Found a command to run
		args.shift();

		if(args.length > 0){ // Check for sub command
			var subcmd =_.first(args).toLowerCase();
			var subcommand = _.find(command.subcommands, function(x){ return x.key == subcmd || _.contains(x.abbreviations, subcmd); });
			if(subcommand){
				command = subcommand;
				args.shift();
			}
		}

		return command;
	}

	return false;
}

exports.register = function(command){
	if(!_.has(command, 'key') || !_.has(command, 'run')) return false;

	eventModule.emit('event', 'registerCommand', command, function(command){
		// Register command
		commands[command.key] = newCommand(command);
		// Register nodes
		//permissions.register(command.key, commands[command.key].nodes);
	});
}

exports.registerSubCmd = function(key, command){
	if(!key || !command || !_.has(command, 'key') || !_.has(command, 'run')) return false;
	if(!_.find(commands[key].subcommands, function(x){ return x.key == command.key; })){
		commands[key].subcommands.push(newCommand(command));
	}
}

// Handle requests

exports.request = function(args, cb){
	var req = args[0];

	var data = db.get('commands');

	if(!_.has(data, 'prefixes') || data.prefixes.length == 0) data.prefixes = ['-'];

	var prefixList = _.reduce(data.prefixes, function(list, prefix){
		if(prefix) list.push('\\'+prefix);
		return list;
	}, []);

	var command_regex = new RegExp('^\\s*('+prefixList.join('|')+')([a-z].*)','i');
	var match = command_regex.exec(req.message.text);

	if(match){ // Prefix matches
		var parts = match[2].split(' ');
		parts = parts.filter(function(e) {return e}); //remove empty
		if(parts.length == 0) return false; //nothing left
		// Find a command
		var command = exports.findCommand(parts);
		if(command){
			// Add the command
			req.command = command;
			if(req.perm){
				if(req.perm('cmd.'+command.key+'.run')){
					// Execute command
					req.message.args = parts;
					eventModule.emit('event', 'command', command, req, function(){
						execute(command, req);
					});
				}else{
					console.log('User '+req.user.name+' does not have permission for cmd.'+command.key+'.run');
				}
			}else{
				console.log('Request for '+req.user.name+' did not have perm function');
			}
		}
	}

}

function execute(command, req){
	console.log("["+req.room.name+"]["+req.user.name+"]["+command.key+']', req.message.args.join(' '));

	if(!command.active){
		console.log('['+req.room.name+']['+req.user.name+']['+command.key+'] DENIED, COMMAND INACTIVE');
		return;
	}

	if(!command.available(req)){
		console.log('['+req.room.name+']['+req.user.name+']['+command.key+'] DENIED, COMMAND AVAILABLE FALSE');
		return;
	}

	if(req.room.ispm && command.room_only){
		console.log('['+req.room.name+']['+req.user.name+']['+command.key+'] DENIED, COMMAND ROOM ONLY');
		return;
	}

	if(!req.room.ispm && command.pm_only){
		console.log('['+req.room.name+']['+req.user.name+']['+command.key+'] DENIED, COMMAND PM ONLY');
		return;
	}

	if(!_.has(command.cache.users, req.user.name)) command.cache.users[req.user.name] = {lastused:0};
	if(!_.has(command.cache.rooms, req.room.name)) command.cache.rooms[req.room.name] = {lastused:0};

	var now = new Date/1000;

	if(!req.room.ispm && command.room_timeout > 0){
		if(now < (command.cache.rooms[req.room.name].lastused + command.room_timeout)){
			var room_timeout = (command.cache.rooms[req.room.name].lastused + command.room_timeout - now);
			console.log('['+req.room.name+']['+req.user.name+']['+command.key+'] DENIED, ROOM TIMEOUT: '+utils.secondsToString(room_timeout));
			return;
		}else{
			command.cache.rooms[req.room.name] = {lastused:now}
		}
	}

	if(command.user_timeout > 0){
		if(now < (command.cache.users[req.room.name].lastused + command.user_timeout)){
			var user_timeout = (command.cache.users[req.room.name].lastused + command.user_timeout - now);
			console.log('['+req.room.name+']['+req.user.name+']['+command.key+'] DENIED, USER TIMEOUT: '+utils.secondsToString(user_timeout));
			return;
		}else{
			command.cache.users[req.user.name] = {lastused:now}
		}
	}

	eventModule.emit('beforeCommand', req);
	command.run(req);

	// Finish command
}
<commit_msg>Version 0.4<commit_after>"use strict";
// Base modules
var _ 	= require('underscore');

// Derplib modules
var MM 			= module.parent,
	utils 		= MM.libary.load('utils'),
	eventModule = MM.libary.load('eventModule'),
	db 			= MM.plugin.load('database'),
	permissions = MM.plugin.load('permissions');

// data
var commands = {};

// Register commands
MM._data.command = {
	dir: './commands/',
	loaded: {},
	prot: [],
};

MM.command = {
	load: function(x){ return MM._load(x, 'command') },
	unload: function(x){ return MM._unload(x, 'command') },
	reload: function(x){ return MM._reload(x, 'command') },
	all: function(){ return MM._data.command.loaded; },
};

// Load all commands
exports.autoLoad = function(){

	utils.walkdir('./commands', function(err, result){
		if(err) throw err;
		_.each(_.filter(result, function(x){ return x.substr(-3) == ".js"; }), function(cmd){
			MM.command.load(cmd);
		});
	});

	return exports;
}

exports.get = function(cmd){
	if(undefined == cmd)
		return commands;
	else if(_.has(commands, cmd))
		return commands[cmd];
	else if(~cmd.indexOf('-')){

	} else
		return false;
}

// Raw command object
function newCommand(args){
	var commandObject = {
		key: '',			// Handle key and command word
		access: false,		// Required access level
		nodes: ['run'],		// For permissions
		prefixes: [],		// If not empty over-writes default prefixes
		description: '',	// Text shown for commands in !help (leave empty to not show)
		// Settings
		active: true,		// Disable command
		user_timeout: 0,	// Interval in between the function can be used per user
		room_timeout: 0,	// Interval in between the function can be used in whole room
		room_only: false,	// Command can't be used in pm
		pm_only: false,		// Command can't be used in rooms
		abbreviations: [],	// Alternate command words
		available: function(req){ return true; },	// Check if the user is allowed to execute command, aside from access level
		subcommands: [],	// If first argument equals subcommand key, execute that.
		cache: {
			users: {},		// User cache, dissapears on reboot - includes 'lastused'
			rooms: {},		// Room cache, dissapears on reboot - includes 'lastused'
			global: {},		// Global cache for the command
		},
		run: function(req){}, //Execution function
	};
	return _.extend(commandObject, args);
}

exports.findCommand = function(args){
	if(args.length === 0) return false;
	var cmd = _.first(args).toLowerCase();
	var command = _.find(commands, function(x){ return x.key == cmd || _.contains(x.abbreviations, cmd); });

	if(command){ // Found a command to run
		args.shift();

		if(args.length > 0){ // Check for sub command
			var subcmd =_.first(args).toLowerCase();
			var subcommand = _.find(command.subcommands, function(x){ return x.key == subcmd || _.contains(x.abbreviations, subcmd); });
			if(subcommand){
				command = subcommand;
				args.shift();
			}
		}

		return command;
	}

	return false;
}

exports.register = function(command){
	if(!_.has(command, 'key') || !_.has(command, 'run')) return false;

	eventModule.emit('event', 'registerCommand', command, function(command){
		// Register command
		commands[command.key] = newCommand(command);
		// Register nodes
		//permissions.register(command.key, commands[command.key].nodes);
	});
}

exports.registerSubCmd = function(key, command){
	if(!key || !command || !_.has(command, 'key') || !_.has(command, 'run')) return false;
	if(!_.find(commands[key].subcommands, function(x){ return x.key == command.key; })){
		commands[key].subcommands.push(newCommand(command));
	}
}

// Handle requests

exports.request = function(args, cb){
	var req = args[0];

	var data = db.get('commands');

	if(!_.has(data, 'prefixes') || data.prefixes.length == 0) data.prefixes = ['-'];

	var prefixList = _.reduce(data.prefixes, function(list, prefix){
		if(prefix) list.push('\\'+prefix);
		return list;
	}, []);

	var command_regex = new RegExp('^\\s*('+prefixList.join('|')+')([a-z].*)','i');
	var match = command_regex.exec(req.message.text);

	if(match){ // Prefix matches
		var parts = match[2].split(' ');
		parts = parts.filter(function(e) {return e}); //remove empty
		if(parts.length == 0) return false; //nothing left
		// Find a command
		var command = exports.findCommand(parts);
		if(command){
			// Add the command
			req.command = command;
			if(req.perm){
				if(req.perm('cmd.'+command.key+'.run')){
					// Execute command
					req.message.args = parts;
					eventModule.emit('event', 'command', command, req, function(){
						execute(command, req);
					});
				}else{
					console.log('User '+req.user.name+' does not have permission for cmd.'+command.key+'.run');
				}
			}else{
				console.log('Request for '+req.user.name+' did not have perm function');
			}
		}
	}

}

function execute(command, req){
	console.log("["+req.room.name+"]["+req.user.name+"]["+command.key+']', req.message.args.join(' '));

	if(!command.active){
		console.log('['+req.room.name+']['+req.user.name+']['+command.key+'] DENIED, COMMAND INACTIVE');
		return;
	}

	if(!command.available(req)){
		console.log('['+req.room.name+']['+req.user.name+']['+command.key+'] DENIED, COMMAND AVAILABLE FALSE');
		return;
	}

	if(req.room.ispm && command.room_only){
		console.log('['+req.room.name+']['+req.user.name+']['+command.key+'] DENIED, COMMAND ROOM ONLY');
		return;
	}

	if(!req.room.ispm && command.pm_only){
		console.log('['+req.room.name+']['+req.user.name+']['+command.key+'] DENIED, COMMAND PM ONLY');
		return;
	}

	if(!_.has(command.cache.users, req.user.name)) command.cache.users = {lastused:0};
	if(!_.has(command.cache.rooms, req.room.name)) command.cache.rooms = {lastused:0};

	var now = new Date/1000;

	if(!req.room.ispm && command.room_timeout > 0){
		if(now < (command.cache.rooms[req.room.name].lastused + command.room_timeout)){
			var room_timeout = (command.cache.rooms[req.room.name].lastused + command.room_timeout - now);
			console.log('['+req.room.name+']['+req.user.name+']['+command.key+'] DENIED, ROOM TIMEOUT: '+utils.secondsToString(room_timeout));
			return;
		}
	}

	if(command.user_timeout > 0){
		if(now < (command.cache.users[req.room.name].lastused + command.user_timeout)){
			var user_timeout = (command.cache.users[req.room.name].lastused + command.user_timeout - now);
			console.log('['+req.room.name+']['+req.user.name+']['+command.key+'] DENIED, USER TIMEOUT: '+utils.secondsToString(user_timeout));
			return;
		}
	}

	eventModule.emit('beforeCommand', req);
	command.run(req);

	// Finish command
}
<|endoftext|>


<commit_before>function initMappingController(
    $scope, analyzerNames, dateTimeParserNames, mappingsIn) {
    $scope.analyzerNames = analyzerNames;

    $scope.dateTimeParserNames = dateTimeParserNames;

    $scope.fieldTypes = ['text', 'number', 'datetime', 'disabled'];

    var kindAttrs = {
        "field": {
            'property': null,
            'name': validateString,
            'type': null,
            'analyzer': null,
            'store': null,
            'index': null,
            'include_term_vectors': null,
            'include_in_all': null,
            'date_format': null,
        },
        "mapping": {
            'name': validateString,
            'enabled': null,
            'dynamic': null,
            'default_analyzer': null
        }
    };

    kindAttrs['mappingType'] = kindAttrs['mapping'];

    // -------------------------------------------------------

    $scope.mappings = mappingsIn;

    $scope.editing = null;

    $scope.popup = null;

    $scope.popupToggle = function(obj) {
        $scope.popup = ($scope.popup == obj) ? null : obj;
    }

    $scope.removeFromParent = function(obj, scope) {
        $scope.editAttrsDone(obj, false); // Cancel any edits.

        scope.remove();
    };

    $scope.addChildField = function(mapping) {
        if ($scope.editing) {
            return;
        }

        var f = {
            _kind: 'field',
            property: "",
            name: "",
            type: "text",
            analyzer: "",
            store: true,
            index: true,
            include_term_vectors: true,
            include_in_all: true,
            date_format: null,
        };
        f._editing = function() { removeEntry(mapping.fields, f); };
        mapping.fields.unshift(f);

        $scope.editing = f;
        $scope.popup = null;
    };

    $scope.addChildMapping = function(mapping) {
        if ($scope.editing) {
            return;
        }

        if (mapping == null) {
            mapping = $scope;
        }

        var m = {
            _kind: mapping == $scope ? 'mappingType' : 'mapping',
            name: "",
            fields: [],
            mappings: []
        };
        m._editing = function() { removeEntry(mapping.mappings, m); };
        mapping.mappings.unshift(m);

        $scope.editing = m;
        $scope.popup = null;
    };

    $scope.editAttrs = function(obj) {
        var attrs = kindAttrs[obj._kind];
        for (var attr in attrs) {
            obj["_" + attr + "_ERR"] = null;
            obj["_" + attr + "_PREV"] = obj[attr];
        }

        obj._editing = true;
        $scope.editing = obj;
    }

    $scope.editAttrsDone = function(obj, ok) {
        var valid = true;

        var attrs = kindAttrs[obj._kind];
        for (var attr in attrs) {
            var attrValidator = attrs[attr];

            if (ok) {
                if (attrValidator) {
                    valid = attrValidator(obj, attr) && valid;
                }
            } else { // Cancelled.
                obj[attr] = obj["_" + attr + "_PREV"];
            }
        }

        if (!valid) {
            return;
        }

        for (var attr in attrs) {
            delete obj["_" + attr + "_ERR"];
            delete obj["_" + attr + "_PREV"];
        }

        if (!ok && typeof(obj._editing) == 'function') {
            obj._editing(); // Invoke editing cancellation callback.
        }

        delete obj._editing;
        $scope.editing = null;
    }

    $scope.options = {
        accept: function(sourceAccept, destAccept, destIndex) {
            if ($scope.editing) {
                return false;
            }

            var sourceData = sourceAccept.$modelValue;
            var destType = destAccept.$element.attr('data-type');

            return (sourceData._kind+"Container") == destType;
        }
    };

    function validateString(obj, attr) {
        if (obj[attr] != null && obj[attr].length <= 0) {
            obj["_" + attr + "_ERR"] = attr + " required";
            return false;
        }
        return true;
    }

    function removeEntry(arr, entry) {
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] === entry) {
                arr.splice(i, 1);
            }
        }
    }
}
<commit_msg>convertToTypeMapping<commit_after>function initMappingController(
    $scope, analyzerNames, dateTimeParserNames, mappingsIn) {
    $scope.analyzerNames = analyzerNames;

    $scope.dateTimeParserNames = dateTimeParserNames;

    $scope.fieldTypes = ['text', 'number', 'datetime', 'disabled'];

    var kindAttrs = {
        "field": {
            'property': null,
            'name': validateString,
            'type': null,
            'analyzer': null,
            'store': null,
            'index': null,
            'include_term_vectors': null,
            'include_in_all': null,
            'date_format': null,
        },
        "mapping": {
            'name': validateString,
            'enabled': null,
            'dynamic': null,
            'default_analyzer': null
        }
    };

    kindAttrs['mappingType'] = kindAttrs['mapping'];

    // -------------------------------------------------------

    $scope.mappings = mappingsIn;

    $scope.editing = null;

    $scope.popup = null;

    $scope.popupToggle = function(obj) {
        $scope.popup = ($scope.popup == obj) ? null : obj;
    }

    $scope.removeFromParent = function(obj, scope) {
        $scope.editAttrsDone(obj, false); // Cancel any edits.

        scope.remove();
    };

    $scope.addChildField = function(mapping) {
        if ($scope.editing) {
            return;
        }

        var f = {
            _kind: 'field',
            property: "",
            name: "",
            type: "text",
            analyzer: "",
            store: true,
            index: true,
            include_term_vectors: true,
            include_in_all: true,
            date_format: null,
        };
        f._editing = function() { removeEntry(mapping.fields, f); };
        mapping.fields.unshift(f);

        $scope.editing = f;
        $scope.popup = null;
    };

    $scope.addChildMapping = function(mapping) {
        if ($scope.editing) {
            return;
        }

        if (mapping == null) {
            mapping = $scope;
        }

        var m = {
            _kind: mapping == $scope ? 'mappingType' : 'mapping',
            name: "",
            fields: [],
            mappings: []
        };
        m._editing = function() { removeEntry(mapping.mappings, m); };
        mapping.mappings.unshift(m);

        $scope.editing = m;
        $scope.popup = null;
    };

    $scope.editAttrs = function(obj) {
        var attrs = kindAttrs[obj._kind];
        for (var attr in attrs) {
            obj["_" + attr + "_ERR"] = null;
            obj["_" + attr + "_PREV"] = obj[attr];
        }

        obj._editing = true;
        $scope.editing = obj;
    }

    $scope.editAttrsDone = function(obj, ok) {
        var valid = true;

        var attrs = kindAttrs[obj._kind];
        for (var attr in attrs) {
            var attrValidator = attrs[attr];

            if (ok) {
                if (attrValidator) {
                    valid = attrValidator(obj, attr) && valid;
                }
            } else { // Cancelled.
                obj[attr] = obj["_" + attr + "_PREV"];
            }
        }

        if (!valid) {
            return;
        }

        for (var attr in attrs) {
            delete obj["_" + attr + "_ERR"];
            delete obj["_" + attr + "_PREV"];
        }

        if (!ok && typeof(obj._editing) == 'function') {
            obj._editing(); // Invoke editing cancellation callback.
        }

        delete obj._editing;
        $scope.editing = null;
    }

    $scope.options = {
        accept: function(sourceAccept, destAccept, destIndex) {
            if ($scope.editing) {
                return false;
            }

            var sourceData = sourceAccept.$modelValue;
            var destType = destAccept.$element.attr('data-type');

            return (sourceData._kind+"Container") == destType;
        }
    };

    function validateString(obj, attr) {
        if (obj[attr] != null && obj[attr].length <= 0) {
            obj["_" + attr + "_ERR"] = attr + " required";
            return false;
        }
        return true;
    }

    function removeEntry(arr, entry) {
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] === entry) {
                arr.splice(i, 1);
            }
        }
    }
}

// Convert from a near-bleve-friendly TypeMapping data structure to a
// UI-friendly data structure.  By "near", an entry with null key
// represents the default type mapping.
function convertFromTypeMapping(typeMapping) {
    typeMapping = JSON.parse(JSON.stringify(typeMapping));
}

// Convert froma UI-friendly data structure to a near-bleve-friendly
// TypeMapping data structure.  By "near", an entry with null key
// represents the default type mapping.
function convertToTypeMapping(mappings) {
    var typeMapping = {};

    mappings = scrub(JSON.parse(JSON.stringify(mappings)));
    for (var i in mappings) {
        var mapping = mappings[i];

        typeMapping[mapping.name] = mapping; // The mapping.name may be null.

        delete mapping["name"];

        convertPropertiedFields(mapping);

        mapping.display_order = i;
    }

    return typeMapping;

    // Recursively remove every entry with '_' prefix.
    function scrub(m) {
        if (typeof(m) == "object") {
            for (var k in m) {
                if (typeof(k) == "string" && k.charAt(0) == "_") {
                    delete m[k];
                    continue;
                }

                m[k] = scrub(m[k]);
            }
        }

        return m;
    }

    // Recursively convert fields with "property" attribute into a
    // document mapping in the properties map.
    function convertPropertiedFields(m) {
        var properties = {};
        var fields = [];

        for (var i in m.fields) {
            var field = m.fields[i];
            if (field.property && field.property.length > 0) {
                var property = properties[field.property];
                if (property == null) {
                    property = properties[field.property] = {
                        enabled: true,
                        dynamic: false,
                        properties: {},
                        fields: []
                    };
                }

                property.fields.push(field);
            } else {
                fields.push(field);
            }

            delete field["property"];
            field.display_order = i;
        }

        for (var i in m.mappings) {
            var mapping = m.mappings[i];

            properties[mapping.name] = mapping;

            delete mapping["name"];
            mapping.display_order = i;

            convertPropertiedFields(mapping);
        }

        m.properties = properties;
        m.fields = fields;
    }
}
<|endoftext|>


<commit_before>//database.js
const Mongoose = require('mongoose');
const databaseUrl = 'localhost:27017';
const databaseOptions = {
  db: {
    native_parser: true,
    useMongoClient: true
  }
}

//load database
Mongoose.Promise = global.Promise;
Mongoose.connect(databaseUrl, databaseOptions, function() {
});
const db = Mongoose.connection;
db.on('error', function calback() {
    console.log('Connection failed');
    return;
}/*console.error.bind(console, 'connection error')*/);
db.once('open', function callback() {
    console.log('Connection with database succeeded.');
});
exports.db = db;
<commit_msg>typo<commit_after>//database.js
const Mongoose = require('mongoose');
const databaseUrl = 'localhost:27017';
const databaseOptions = {
  db: {
    native_parser: true,
    useMongoClient: true
  }
}

//load database
Mongoose.Promise = global.Promise;
Mongoose.connect(databaseUrl, databaseOptions, function() {
});
const db = Mongoose.connection;
db.on('error', function callback() {
    console.log('Connection failed');
    return;
}/*console.error.bind(console, 'connection error')*/);
db.once('open', function callback() {
    console.log('Connection with database succeeded.');
});
exports.db = db;
<|endoftext|>


<commit_before>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

(function(global) {

// According to MDN, we're supposed to dispatch |start|, |finish|, and |bounce|
// events at various points in the marquee's lifecycle, but Blink doesn't
// appear to dispatch those events.

var kDefaultScrollAmount = 6;
var kDefaultScrollDelayMS = 85;
var kMinimumScrollDelayMS = 60;

var kDefaultLoopLimit = -1;

var kBehaviorScroll = 'scroll';
var kBehaviorSlide = 'slide';
var kBehaviorAlternate = 'alternate';

var kDirectionLeft = 'left';
var kDirectionRight = 'right';
var kDirectionUp = 'up';
var kDirectionDown = 'down';

var HTMLMarqueeElementPrototype = Object.create(HTMLElement.prototype);

HTMLMarqueeElementPrototype.createdCallback = function() {
    var shadow = this.createShadowRoot();
    var style = global.document.createElement('style');
    style.textContent = ':host { display: inline-block; width: -webkit-fill-available; overflow: hidden }' +
                        ':host([direction="up"]), :host([direction="down"]) { height: 200px; }';
    shadow.appendChild(style);

    var mover = global.document.createElement('div');
    mover.setAttribute('style', 'display: inline-block;');
    shadow.appendChild(mover);

    var content = global.document.createElement('content');
    mover.appendChild(content);

    this.running_ = false;
    this.loopCount_ = 0;
    this.mover_ = mover;
    this.player_ = null;
    this.continueCallback_ = null;
};

HTMLMarqueeElementPrototype.attachedCallback = function() {
    this.start();
};

HTMLMarqueeElementPrototype.getScrollAmount_  = function() {
    var value = this.getAttribute('scrollamount');
    return value === null ? kDefaultScrollAmount : parseInt(value)
};

HTMLMarqueeElementPrototype.getScrollDelay_  = function() {
    var value = this.getAttribute('scrolldelay');
    if (value === null)
        return kDefaultScrollDelayMS;
    var specifiedScrollDelay = parseInt(value);
    if (specifiedScrollDelay < kMinimumScrollDelayMS && !this.hasAttribute('truespeed'))
        return kDefaultScrollDelayMS;
    return specifiedScrollDelay;
};

HTMLMarqueeElementPrototype.getAnimationParmeters_ = function() {
    var moverStyle = global.getComputedStyle(this.mover_);
    var marqueeStyle = global.getComputedStyle(this);

    var moverWidth = parseInt(moverStyle.width);
    var moverHeight = parseInt(moverStyle.height);
    var marqueeWidth = parseInt(marqueeStyle.width);
    var marqueeHeight = parseInt(marqueeStyle.height);

    var totalWidth = marqueeWidth + moverWidth;
    var totalHeight = marqueeHeight + moverHeight;

    var innerWidth = marqueeWidth - moverWidth;
    var innerHeight = marqueeHeight - moverHeight;

    var behavior = this.getAttribute('behavior');
    var direction = this.getAttribute('direction');

    var parameters = {};

    switch (behavior) {
    case kBehaviorScroll:
    default:
        switch (direction) {
        case kDirectionLeft:
        default:
            parameters.transformBegin = 'translateX(' + marqueeWidth + 'px)';
            parameters.transformEnd = 'translateX(-100%)';
            parameters.distance = totalWidth;
            break;
        case kDirectionRight:
            parameters.transformBegin = 'translateX(-100%)';
            parameters.transformEnd = 'translateX(' + marqueeWidth + 'px)';
            parameters.distance = totalWidth;
            break;
        case kDirectionUp:
            parameters.transformBegin = 'translateY(' + marqueeHeight + 'px)';
            parameters.transformEnd = 'translateY(-100%)';
            parameters.distance = totalHeight;
            break;
        case kDirectionDown:
            parameters.transformBegin = 'translateY(-100%)';
            parameters.transformEnd = 'translateY(' + marqueeHeight + 'px)';
            parameters.distance = totalHeight;
            break;
        }
        break;
    case kBehaviorAlternate:
        switch (direction) {
        case kDirectionLeft:
        default:
            parameters.transformBegin = 'translateX(' + innerWidth + 'px)';
            parameters.transformEnd = 'translateX(0)';
            parameters.distance = innerWidth;
            break;
        case kDirectionRight:
            parameters.transformBegin = 'translateX(0)';
            parameters.transformEnd = 'translateX(' + innerWidth + 'px)';
            parameters.distance = innerWidth;
            break;
        case kDirectionUp:
            parameters.transformBegin = 'translateY(' + innerHeight + 'px)';
            parameters.transformEnd = 'translateY(0)';
            parameters.distance = innerHeight;
            break;
        case kDirectionDown:
            parameters.transformBegin = 'translateY(0)';
            parameters.transformEnd = 'translateY(' + innerHeight + 'px)';
            parameters.distance = innerHeight;
            break;
        }

        if (this.loopCount_ % 2) {
            var transform = parameters.transformBegin;
            parameters.transformBegin = parameters.transformEnd;
            parameters.transformEnd = transform;
        }

        break;
    case kBehaviorSlide:
        switch (direction) {
        case kDirectionLeft:
        default:
            parameters.transformBegin = 'translateX(' + marqueeWidth + 'px)';
            parameters.transformEnd = 'translateX(0)';
            parameters.distance = marqueeWidth;
            break;
        case kDirectionRight:
            parameters.transformBegin = 'translateX(-100%)';
            parameters.transformEnd = 'translateX(' + innerWidth + 'px)';
            parameters.distance = marqueeWidth;
            break;
        case kDirectionUp:
            parameters.transformBegin = 'translateY(' + marqueeHeight + 'px)';
            parameters.transformEnd = 'translateY(0)';
            parameters.distance = marqueeHeight;
            break;
        case kDirectionDown:
            parameters.transformBegin = 'translateY(-100%)';
            parameters.transformEnd = 'translateY(' + innerHeight + 'px)';
            parameters.distance = marqueeHeight;
            break;
        }
        break;
    }

    return parameters
};

HTMLMarqueeElementPrototype.animationDuration_ = function(distance) {
    var scrollAmount = this.getScrollAmount_();
    var scrollDelay = this.getScrollDelay_();
    return distance * scrollDelay / scrollAmount;
};

HTMLMarqueeElementPrototype.shouldContinue_ = function() {
    var value = this.getAttribute('loop');
    var loop = value === null ? kDefaultLoopLimit : parseInt(value);

    // By default, slide loops only once.
    if (loop <= 0 && this.getAttribute('behavior') === kBehaviorSlide)
        loop = 1;

    if (loop <= 0)
        return true;
    return this.loopCount_ < loop;
};

HTMLMarqueeElementPrototype.continue_ = function() {
    if (!this.shouldContinue_())
        return;

    this.mover_.style.transform = null;
    var parameters = this.getAnimationParmeters_();

    this.player_ = this.mover_.animate([
        { transform: parameters.transformBegin },
        { transform: parameters.transformEnd },
    ], {
        duration: this.animationDuration_(parameters.distance),
        fill: 'forwards',
    });

    this.player_.addEventListener('finish', function() {
        if (!this.running_)
            return;
        ++this.loopCount_;
        this.continue_();
    }.bind(this));
};

HTMLMarqueeElementPrototype.start = function() {
    if (this.running_)
        return;
    this.running_ = true;;

    this.continueCallback_ = global.requestAnimationFrame(function() {
        this.continueCallback_ = null;
        this.continue_();
    }.bind(this));
};

HTMLMarqueeElementPrototype.stop = function() {
    if (!this.running_)
        return;
    this.running_ = false;

    if (this.continueCallback_)
        global.cancelAnimationFrame(this.continueCallback_);

    // TODO(abarth): Rather than canceling the animation and programming an
    // inline transform, we really should just pause the animation. However,
    // the pause function is still flagged as experimental.
    this.mover_.style.transform = global.getComputedStyle(this.mover_).transform;
    if (this.player_)
        this.player_.cancel();
};

global.document.registerElement('i-marquee', {
    prototype: HTMLMarqueeElementPrototype,
});

})(this);
<commit_msg>Add support for the presentational attributes.<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

(function(global) {

// According to MDN, we're supposed to dispatch |start|, |finish|, and |bounce|
// events at various points in the marquee's lifecycle, but Blink doesn't
// appear to dispatch those events.

var kDefaultScrollAmount = 6;
var kDefaultScrollDelayMS = 85;
var kMinimumScrollDelayMS = 60;

var kDefaultLoopLimit = -1;

var kBehaviorScroll = 'scroll';
var kBehaviorSlide = 'slide';
var kBehaviorAlternate = 'alternate';

var kDirectionLeft = 'left';
var kDirectionRight = 'right';
var kDirectionUp = 'up';
var kDirectionDown = 'down';

var kPresentationalAttributes = [
    'bgcolor',
    'height',
    'hspace',
    'vspace',
    'width',
];

var pixelLengthRegexp = /^\s*(\d+)\s*$/;
var precentageLengthRegexp = /^\s*(\d+)\s*%\s*$/;

function convertHTMLLengthToCSSLength(value) {
    var pixelMatch = value.match(pixelLengthRegexp);
    if (pixelMatch)
        return pixelMatch[1] + 'px';
    var precentageMatch = value.match(precentageLengthRegexp);
    if (precentageMatch)
        return precentageMatch[1] + '%';
    return null;
}

var HTMLMarqueeElementPrototype = Object.create(HTMLElement.prototype);

HTMLMarqueeElementPrototype.createdCallback = function() {
    var shadow = this.createShadowRoot();
    var style = global.document.createElement('style');
    style.textContent = ':host { display: inline-block; width: -webkit-fill-available; overflow: hidden }' +
                        ':host([direction="up"]), :host([direction="down"]) { height: 200px; }';
    shadow.appendChild(style);

    var mover = global.document.createElement('div');
    mover.setAttribute('style', 'display: inline-block;');
    shadow.appendChild(mover);

    var content = global.document.createElement('content');
    mover.appendChild(content);

    this.running_ = false;
    this.loopCount_ = 0;
    this.mover_ = mover;
    this.player_ = null;
    this.continueCallback_ = null;

    for (var i = 0; i < kPresentationalAttributes.length; ++i)
        this.initializeAttribute_(kPresentationalAttributes[i]);
};

HTMLMarqueeElementPrototype.attachedCallback = function() {
    this.start();
};

HTMLMarqueeElementPrototype.detachedCallback = function() {
    this.stop();
};

HTMLMarqueeElementPrototype.attributeChangedCallback = function(name, oldValue, newValue) {
    switch (name) {
    case 'bgcolor':
        this.style.backgroundColor = newValue;
        break;
    case 'height':
        this.style.height = convertHTMLLengthToCSSLength(newValue);
        break;
    case 'hspace':
        var margin = convertHTMLLengthToCSSLength(newValue);
        this.style.marginLeft = margin;
        this.style.marginRight = margin;
        break;
    case 'vspace':
        var margin = convertHTMLLengthToCSSLength(newValue);
        this.style.marginTop = margin;
        this.style.marginBottom = margin;
        break;
    case 'width':
        this.style.width = convertHTMLLengthToCSSLength(newValue);
        break;
    }
};

HTMLMarqueeElementPrototype.initializeAttribute_ = function(name) {
    var value = this.getAttribute(name);
    if (value === null)
        return;
    this.attributeChangedCallback(name, null, value);
};

HTMLMarqueeElementPrototype.getScrollAmount_  = function() {
    var value = this.getAttribute('scrollamount');
    return value === null ? kDefaultScrollAmount : parseInt(value)
};

HTMLMarqueeElementPrototype.getScrollDelay_  = function() {
    var value = this.getAttribute('scrolldelay');
    if (value === null)
        return kDefaultScrollDelayMS;
    var specifiedScrollDelay = parseInt(value);
    if (specifiedScrollDelay < kMinimumScrollDelayMS && !this.hasAttribute('truespeed'))
        return kDefaultScrollDelayMS;
    return specifiedScrollDelay;
};

HTMLMarqueeElementPrototype.getAnimationParmeters_ = function() {
    var moverStyle = global.getComputedStyle(this.mover_);
    var marqueeStyle = global.getComputedStyle(this);

    var moverWidth = parseInt(moverStyle.width);
    var moverHeight = parseInt(moverStyle.height);
    var marqueeWidth = parseInt(marqueeStyle.width);
    var marqueeHeight = parseInt(marqueeStyle.height);

    var totalWidth = marqueeWidth + moverWidth;
    var totalHeight = marqueeHeight + moverHeight;

    var innerWidth = marqueeWidth - moverWidth;
    var innerHeight = marqueeHeight - moverHeight;

    var behavior = this.getAttribute('behavior');
    var direction = this.getAttribute('direction');

    var parameters = {};

    switch (behavior) {
    case kBehaviorScroll:
    default:
        switch (direction) {
        case kDirectionLeft:
        default:
            parameters.transformBegin = 'translateX(' + marqueeWidth + 'px)';
            parameters.transformEnd = 'translateX(-100%)';
            parameters.distance = totalWidth;
            break;
        case kDirectionRight:
            parameters.transformBegin = 'translateX(-100%)';
            parameters.transformEnd = 'translateX(' + marqueeWidth + 'px)';
            parameters.distance = totalWidth;
            break;
        case kDirectionUp:
            parameters.transformBegin = 'translateY(' + marqueeHeight + 'px)';
            parameters.transformEnd = 'translateY(-100%)';
            parameters.distance = totalHeight;
            break;
        case kDirectionDown:
            parameters.transformBegin = 'translateY(-100%)';
            parameters.transformEnd = 'translateY(' + marqueeHeight + 'px)';
            parameters.distance = totalHeight;
            break;
        }
        break;
    case kBehaviorAlternate:
        switch (direction) {
        case kDirectionLeft:
        default:
            parameters.transformBegin = 'translateX(' + innerWidth + 'px)';
            parameters.transformEnd = 'translateX(0)';
            parameters.distance = innerWidth;
            break;
        case kDirectionRight:
            parameters.transformBegin = 'translateX(0)';
            parameters.transformEnd = 'translateX(' + innerWidth + 'px)';
            parameters.distance = innerWidth;
            break;
        case kDirectionUp:
            parameters.transformBegin = 'translateY(' + innerHeight + 'px)';
            parameters.transformEnd = 'translateY(0)';
            parameters.distance = innerHeight;
            break;
        case kDirectionDown:
            parameters.transformBegin = 'translateY(0)';
            parameters.transformEnd = 'translateY(' + innerHeight + 'px)';
            parameters.distance = innerHeight;
            break;
        }

        if (this.loopCount_ % 2) {
            var transform = parameters.transformBegin;
            parameters.transformBegin = parameters.transformEnd;
            parameters.transformEnd = transform;
        }

        break;
    case kBehaviorSlide:
        switch (direction) {
        case kDirectionLeft:
        default:
            parameters.transformBegin = 'translateX(' + marqueeWidth + 'px)';
            parameters.transformEnd = 'translateX(0)';
            parameters.distance = marqueeWidth;
            break;
        case kDirectionRight:
            parameters.transformBegin = 'translateX(-100%)';
            parameters.transformEnd = 'translateX(' + innerWidth + 'px)';
            parameters.distance = marqueeWidth;
            break;
        case kDirectionUp:
            parameters.transformBegin = 'translateY(' + marqueeHeight + 'px)';
            parameters.transformEnd = 'translateY(0)';
            parameters.distance = marqueeHeight;
            break;
        case kDirectionDown:
            parameters.transformBegin = 'translateY(-100%)';
            parameters.transformEnd = 'translateY(' + innerHeight + 'px)';
            parameters.distance = marqueeHeight;
            break;
        }
        break;
    }

    return parameters
};

HTMLMarqueeElementPrototype.animationDuration_ = function(distance) {
    var scrollAmount = this.getScrollAmount_();
    var scrollDelay = this.getScrollDelay_();
    return distance * scrollDelay / scrollAmount;
};

HTMLMarqueeElementPrototype.shouldContinue_ = function() {
    var value = this.getAttribute('loop');
    var loop = value === null ? kDefaultLoopLimit : parseInt(value);

    // By default, slide loops only once.
    if (loop <= 0 && this.getAttribute('behavior') === kBehaviorSlide)
        loop = 1;

    if (loop <= 0)
        return true;
    return this.loopCount_ < loop;
};

HTMLMarqueeElementPrototype.continue_ = function() {
    if (!this.shouldContinue_())
        return;

    this.mover_.style.transform = null;
    var parameters = this.getAnimationParmeters_();

    this.player_ = this.mover_.animate([
        { transform: parameters.transformBegin },
        { transform: parameters.transformEnd },
    ], {
        duration: this.animationDuration_(parameters.distance),
        fill: 'forwards',
    });

    this.player_.addEventListener('finish', function() {
        if (!this.running_)
            return;
        ++this.loopCount_;
        this.continue_();
    }.bind(this));
};

HTMLMarqueeElementPrototype.start = function() {
    if (this.running_)
        return;
    this.running_ = true;;

    this.continueCallback_ = global.requestAnimationFrame(function() {
        this.continueCallback_ = null;
        this.continue_();
    }.bind(this));
};

HTMLMarqueeElementPrototype.stop = function() {
    if (!this.running_)
        return;
    this.running_ = false;

    if (this.continueCallback_)
        global.cancelAnimationFrame(this.continueCallback_);

    // TODO(abarth): Rather than canceling the animation and programming an
    // inline transform, we really should just pause the animation. However,
    // the pause function is still flagged as experimental.
    this.mover_.style.transform = global.getComputedStyle(this.mover_).transform;
    if (this.player_)
        this.player_.cancel();
};

global.document.registerElement('i-marquee', {
    prototype: HTMLMarqueeElementPrototype,
});

})(this);
<|endoftext|>


<commit_before>// require esphinx_ui

var
    esPhinx,
    Extensor;

(function($, $module) {
    "use strict";

    $module.extend({
        handlers: {tabs: {}}
    });

    Extensor.new($module.handlers.tabs, true, {
        new: function(selector, container, options) {
            var
                ConstructorReference = $module.handlers.tabs.new,
                navs,
                containers,

                Tab = function(handler, container) {
                    this.select = function() {
                        selectNav(handler);
                        showContent(handler, container);
                    };
                },

               showContentOnload = function(navs, containers) {
                    var
                        id = navs.parent().findHasNotAttr("a", "href")
                            .attribute("id"),
                        container = containers.parent().first()
                            .find(".container#" + id);

                    containers.hide();
                    container.show();
                },

                selectNav = function(target, onload) {
                    var
                        navs,
                        selected,
                        selectOnload;

                    navs = $(target).parent("ul").find("li");

                    selected = navs.findHasNotAttr("a.selector", "href");

                    if (selected.length) {
                        selected.attribute("href", "#");
                    }

                    selected.removeClass("selected");
                    $(target).addClass("selected");
                    $(target).removeAttr("href");

                    selectOnload = navs.parent("ul.select-onload");
                    if (!onload && selectOnload.length) {
                        window.location.queryParam('tab', $(target)
                                                   .attribute("id"));
                    }
                },

                selectNavOnload = function(selectors) {
                    var
                        tabParam = window.location.queryParam("tab"),
                        parent = selectors.parent(),
                        href,
                        anchor;

                    if (tabParam) {
                        selectNav(parent.find("a#" + tabParam));
                    } else {
                        href = window.location.pathname
                            .match(/[a-z\/\_\-]+[a-z]+/);

                        anchor = parent.findHasNotAttr("a", "href");

                        if (anchor.length) {
                            selectNav(anchor);
                        } else {
                            selectNav(selectors.asNode(), true);
                        }
                    }
                },

                resolveNavs = function(navs, options) {
                    var
                        tagName = navs.tagName().toLowerCase(),
                        anchor,
                        selectors;

                    if (tagName != "li" && tagName != "a") {
                        navs = navs.find("li");
                    } else if (tagName == "a") {
                        navs = navs.parent();
                    }

                    navs.each(function(nav, i) {
                        nav = $(nav);
                        anchor = nav.find("a");

                        if (!anchor.count()) {
                            anchor = $("");
                            anchor.append(window.document.createTextNode(nav
                                .text()));

                            nav.text("");
                            nav.prepend(anchor);
                        }

                        i = parseInt(i);
                        anchor.attribute("id", "tab-" + (i + 1));
                        anchor.attribute("class", "selector");
                        anchor.attribute("href", "#");
                    });

                    selectors = navs.find("a.selector");

                    if (options) {
                        if (options.selectOnload) {
                            navs.parent("ul").addClass("select-onload");
                        }
                    } else {
                        $(selectors.asNode()).removeAttr("href");
                    }

                    return selectors;
                },

                resolveContainers = function(containers, navs) {
                    var
                        containerTagName = containers.tagName().toLowerCase();

                    if (containerTagName != "li") {
                        containers = containers.find("li");
                    }

                    containers.each(function(container, i) {
                        i = parseInt(i);
                        container.id = "tab-" + (i + 1);
                        container.classList.add("container");
                    });

                    showContentOnload(navs, containers);
                },

                init = function(navs, containers, options) {
                    if (containers) {
                        if (options) {
                            if (options.selectOnload) {
                                selectNavOnload(navs);
                            }
                        }
                        resolveContainers(containers, navs);
                    } else {
                        selectNavOnload(navs);
                    }
                },

                showContent = function(target, container) {
                    var
                        containers = $(container).parent("ul")
                            .find(".container");
                    containers.hide();
                    container.show();
                },

                map = function(navs, containers, options) {
                    var
                        tabs = [];

                    if (navs.some()) {
                        navs = resolveNavs(navs, options);
                        init(navs, containers, options);
                        navs.each(function(a, i) {
                            tabs.push({
                                // to set event
                                handler: a,
                                tab: new Tab(a, containers.parent()
                                    .find(".container#" + a.id))
                            });
                        });

                    }

                    return tabs;

                };

            if (!(this instanceof ConstructorReference)) {
                return new ConstructorReference(selector, container, options);
            }

            navs = selector;
            containers = container;

            return map(navs, containers, options);
        }
    });

}(esPhinx, esPhinx.ui));
<commit_msg>improves tabs<commit_after>// require esphinx_ui

var
    esPhinx,
    Extensor;

(function($, $module) {
    "use strict";

    $module.extend({
        handlers: {tabs: {}}
    });

    Extensor.new($module.handlers.tabs, true, {
        new: function(selector, content, options) {
            var
                ConstructorReference = $module.handlers.tabs.new,
                navs,
                contents,

                Tab = function(handler, content) {
                    this.select = function() {
                        selectNav(handler);
                        showContent(handler, content);
                    };
                },

               showContentOnload = function(navs, contents) {
                    var
                        id = navs.parent().findHasNotAttr("a", "href")
                            .attribute("id"),
                        content = contents.parent().first()
                            .find(".content#" + id);

                    contents.hide();
                    content.show();
                },

                selectNav = function(target, onload) {
                    var
                        navs,
                        selected,
                        selectOnload;

                    navs = $(target).parent("ul").find("li");

                    selected = navs.findHasNotAttr("a.selector", "href");

                    if (selected.length) {
                        selected.attribute("href", "#");
                    }

                    selected.removeClass("selected");
                    $(target).addClass("selected");
                    $(target).removeAttr("href");

                    selectOnload = navs.parent("ul.select-onload");
                    if (!onload && selectOnload.length) {
                        window.location.queryParam('tab', $(target)
                                                   .attribute("id"));
                    }
                },

                selectNavOnload = function(selectors) {
                    var
                        tabParam = window.location.queryParam("tab"),
                        parent = selectors.parent(),
                        href,
                        anchor;

                    if (tabParam) {
                        selectNav(parent.find("a#" + tabParam));
                    } else {
                        href = window.location.pathname
                            .match(/[a-z\/\_\-]+[a-z]+/);

                        anchor = parent.findHasNotAttr("a", "href");

                        if (anchor.length) {
                            selectNav(anchor);
                        } else {
                            selectNav(selectors.asNode(), true);
                        }
                    }
                },

                resolveNavs = function(navs, options) {
                    var
                        tagName = navs.tagName().toLowerCase(),
                        anchor,
                        selectors;

                    if (tagName != "li" && tagName != "a") {
                        navs = navs.find("li");
                    } else if (tagName == "a") {
                        navs = navs.parent();
                    }

                    navs.each(function(nav, i) {
                        nav = $(nav);
                        anchor = nav.find("a");

                        if (!anchor.count()) {
                            anchor = $("");
                            anchor.append(window.document.createTextNode(nav
                                .text()));

                            nav.text("");
                            nav.prepend(anchor);
                        }

                        i = parseInt(i);
                        anchor.attribute("id", "tab-" + (i + 1));
                        anchor.attribute("class", "selector");
                        anchor.attribute("href", "#");
                    });

                    selectors = navs.find("a.selector");

                    if (options) {
                        if (options.selectOnload) {
                            navs.parent("ul").addClass("select-onload");
                        }
                    } else {
                        $(selectors.asNode()).removeAttr("href");
                    }

                    return selectors;
                },

                resolveContents = function(contents, navs) {
                    var
                        contentTagName = contents.tagName().toLowerCase();

                    if (contentTagName != "li") {
                        contents = contents.find("li");
                    }

                    contents.each(function(content, i) {
                        i = parseInt(i);
                        content.id = "tab-" + (i + 1);
                        content.classList.add("content");
                    });

                    showContentOnload(navs, contents);
                },

                init = function(navs, contents, options) {
                    if (contents) {
                        if (options) {
                            if (options.selectOnload) {
                                selectNavOnload(navs);
                            }
                        }
                        resolveContents(contents, navs);
                    } else {
                        selectNavOnload(navs);
                    }
                },

                showContent = function(target, content) {
                    var
                        contents = $(content).parent("ul")
                            .find(".content");
                    contents.hide();
                    content.show();
                },

                map = function(navs, contents, options) {
                    var
                        tabs = [];

                    if (navs && navs instanceof $ && navs.some()) {
                        navs = resolveNavs(navs, options);
                        init(navs, contents, options);
                        navs.each(function(a, i) {
                            tabs.push({
                                // to set event
                                handler: a,
                                tab: new Tab(a, contents.parent()
                                    .find(".content#" + a.id))
                            });
                        });

                    }

                    return tabs;

                };

            if (!(this instanceof ConstructorReference)) {
                return new ConstructorReference(selector, content, options);
            }

            navs = selector;
            contents = content;

            return map(navs, contents, options);
        }
    });

}(esPhinx, esPhinx.ui));
<|endoftext|>


<commit_before>/**
 * This service provides base class extension and default functionality to component controllers.
 *
 * @class ComponentFactoryService
 * @module Hightail
 * @submodule Hightail.Services
 *
 * @example
 *    controller: ['ComponentFactoryService', '$scope', '$attrs',
 *      function(ComponentFactoryService, $scope, $attrs) {
 *        //initialize component functionality
 *        var controller = this;
 *        ComponentFactoryService.init(controller, $scope, $attrs);
 *    }]
 *
 * @author justin.fiedler
 * @since 0.0.1
 *
 * @copyright (c) 2013 Hightail Inc. All Rights Reserved
 */
'use strict';

angular.wilson.service('ComponentFactoryService',
  ['$rootScope', '$timeout', 'StateMachineService', 'BusFactoryService', 'i18nextService', 'AppStateService', 'TranslationOverrideService', 'ElementHelperService', 'ComponentPrerenderService',
  function($rootScope, $timeout, StateMachineService, BusFactoryService, i18nextService, AppStateService, TranslationOverrideService, ElementHelperService, ComponentPrerenderService) {

    /**
     * Initializes a Component Controller
     *
     * @method init
     *
     * @param componentName The name of the component
     * @param $scope        Reference to the components $scope
     * @param $element      Reference to the components $element
     * @param $attrs        Reference to the components $attrs
     * @param controller    Reference to the components controller
     */
    var init = function wilsonComponentInit(componentName, $scope, $element, $attrs, controller) {

      /**
       * Cache of text overridden by parent components
       * @type {{}}
       */
      var textOverrides = {};
      /**
       * Cache of text NOT overridden by parent components
       * @type {{}}
       */
      var ignoredTextOverrides = {};

      //set component name on the scope
      $scope.componentCName = controller.componentCName = componentName;

      //Get the scope of our parent component
      var parentScope = $scope.$parent;
      //keep going through the scope hierarchy until we find a component scope
      while (parentScope && !_.has(parentScope, 'componentCName')) {
        parentScope = parentScope.$parent;
      }

      //Expose parent component scope
      $scope.parentComponent = parentScope;

      // set parent scope to non-component if necessary
      if (!parentScope) {
        parentScope = $scope.$parent;
      }

      /**
       * If we are given 'expose' name then expose the component isolate scope on the $parent scope
       */
      var exposeName = $attrs ? $attrs.expose : false;
      if (exposeName) {
        parentScope[exposeName] = $scope;
      }

      /**
       * If we are given 'expose-ctrl' name then expose the component controller on the $parent scope
       */
      var exposeCtrlName = $attrs ? $attrs.exposeCtrl : false;
      if (exposeCtrlName) {
        parentScope[exposeCtrlName] = controller;
      }

      /**
       * Event Bus Object
       *
       * @property $scope.eventBus
       * @for HtComponent
       * @type Object - Event Bus
       */
      //Check for a parent eventBus to use
      $scope.eventBus = parentScope ? parentScope.eventBus : BusFactoryService.get();

      //If there is still no event bus, use the default
      if (!$scope.eventBus) {
        $scope.eventBus = BusFactoryService.get();
      }

      /**
       * Translates given text based on the set language.
       *
       * @public
       * @method translate
       * @for HtComponent
       * @param text        The text to translate
       * @param options     Translation options (e.g. { ns:'my-namespace', count: 1})
       *
       * @async
       */
      $scope.translate = controller.translate = function(text, options) {
        //create a default callback if needed
        options = options || {};

        // default namespace is component name
        if (typeof options.ns !== 'string' || options.ns === '') {
          options.ns = componentName;
        }

        if (!ignoredTextOverrides[text]) {
          //check if the text has an override
          if (textOverrides[text]) {
            options.ns = textOverrides[text];
            //console.log('component translation found! ns:', options.ns);
          } else if (TranslationOverrideService.hasOverride(options.ns, text)) {
            //the text has an override, now determine if it applies to this component
            for (var ancestor = $scope.parentComponent; ancestor !== null; ancestor = ancestor.parentComponent) {
              if (TranslationOverrideService.hasOverrideForNamespace(options.ns, text, ancestor.componentCName)) {
                options.ns = textOverrides[text] = ancestor.componentCName;
                break;
              }
            }

            //If the namespace is still set to this component then mark as ignored
            if (options.ns === componentName) {
              ignoredTextOverrides[text] = true;
            }
            //console.log(_.sprintf('override exists! ns: %s  value:%s', options.ns, i18nextService.translate(text, options)));

          }
        }

        //use the i18n provider to translate the text
        return i18nextService.translate(text, options);
      };

      /**
       * Wrapper function to add the locale in front of a path/route
       *
       * @public
       * @method realPath
       * @for HtComponent
       * @param path        The relative url path
       *
       * @async
       */
//      $scope.realPath = function(path) {
//        return UrlUtility.getLocalizedPath(path);
//      };

      /**
       * Marks the @textKey in @overrideNamespace to be overridden with @overrideText
       *
       * e.g.
       * In send.js
       * controller
       *
       * @param overrideNamespace
       * @param textKey
       * @param overrideText
       */
      controller.overrideText = function(overrideNamespace, textKey, overrideText) {
        TranslationOverrideService.addOverride(overrideNamespace, componentName, textKey);

        //call translate to add the translation to the locale JSON
        controller.translate(textKey, { defaultValue: overrideText });

        //console.log('key:' + textKey + ' value: ' + controller.translate(textKey));
      };

      /**
       * State Machine Object
       * @property $scope.stateMachine
       * @for HtComponent
       * @type Object
       */
      $scope.stateMachine = {
        current: 'NoStateMachine'
      };

      /**
       * Convience method to track a new 'tracking-service' event
       *
       * @param args  Any arguments you want to dispatch with the event
       */
      $scope.trackEvent = function(eventName) {
        var args = _.toArray(arguments);
        if (args && args.length > 0) {
          //dispatch event '<componentName>:<eventName>'
          args[0] = 'tracking-service:' + args[0];
          $scope.$emit.apply($scope, args);
        } else {
          throw new Error('trackEvent: eventName is required');
        }
      };

      /**
       * Convenience function to EMIT a event that is namespaced to this component
       *
       * E.g. In the 'log-in' component $scope.emitComponentEvent('success') will
       * emit an event named 'log-in:success'
       *
       * @param eventName
       * @param args
       */
      $scope.emitComponentEvent = function(eventName) {
        var args = _.toArray(arguments);
        if (args && args.length > 0) {
          //dispatch event '<componentName>:<eventName>'
          args[0] = componentName + ':' + args[0];
          $scope.$emit.apply($scope, args);
        } else {
          throw new Error('emitComponentEvent: eventName is required');
        }
      };

      /**
       * Convenience function to BROADCAST a event that is namespaced to this component
       *
       * E.g. In the 'log-in' component $scope.broadcastComponentEvent('success') will
       * broadcast an event named 'log-in:success'
       *
       * @param eventName
       * @param args
       */
      $scope.broadcastComponentEvent = function(eventName) {
        var args = _.toArray(arguments);
        if (args && args.length > 0) {
          //dispatch event '<componentName>:<eventName>'
          args[0] = componentName + ':' + args[0];
          $scope.$broadcast.apply($scope, args);
        } else {
          throw new Error('broadcastComponentEvent: eventName is required');
        }
      };

      /**
       * Sets @scopePropertyName on $scope to @defaultValue if it is not already set
       *
       * @param scopePropertyName
       * @param defaultValue
       * @returns {*}
       */
      $scope.defaultValue = function(scopePropertyName, defaultValue) {
        var value = $scope[scopePropertyName];
        if (_.isUndefined(value) || _.isNull(value)) {
          $scope[scopePropertyName] = defaultValue;
        }

        return $scope[scopePropertyName];
      };

      /**
       * Only does an $apply if a $digest is not already in progress
       *
       * @param fn
       */
      $scope.safeApply = function(fn) {
        var phase = $rootScope.$$phase;
        if (phase === '$apply' || phase === '$digest') {
          if (fn && (typeof(fn) === 'function')) {
            fn();
          }
        } else {
          this.$apply(fn);
        }
      };

      /**
       * Create a function that will be run inside of a safeApplied method.
       *
       * @param method
       * @param context
       * @returns {Function}
       */
      $scope.bindToSafeApply = function bindToSafeApply(method, context) {
        context = context || this;

        if (method) {
          // Return the method to be wrapped in a $rootScope.safeApply
          return function() {
            var args = arguments;
            $scope.safeApply(function() { method.apply(context, args); });
          };
        }

        return function() {};
      };

      $scope.digestInProgress = function() {
        var phase = $rootScope.$$phase;
        return (phase === '$apply' || phase === '$digest');
      };

//      $scope.$on('$destroy', function() {
//        //we need to destroy the state machine (remove its timeouts)
//      });

      /**
       * Creates a new stateMachine for this component.
       * Calls onStateCompleteCallback(stateMachine) on completion
       *
       * @public
       * @method setState
       * @for HtComponent
       * @param cfg
       * @param onStateCompleteCallback   Callback function(e.g. function(stateMachine) {} )
       *
       * @async
       */
      controller.setState = function(cfg, onStateCompleteCallback) {
        //create noop callback if needed
        onStateCompleteCallback = onStateCompleteCallback || function() {};

        var fsm = $scope.stateMachine;

        if (cfg) {
          var cfgInitialState = cfg.initial;

          //check if there is an initialState attr on the component
          var attrInitialState;
          if ($attrs) {
            var attrState = $attrs.initialState;
            //console.log('initialStateAttr:' + initialStateAttr);
            if (attrState && StateMachineService.hasState(cfg, attrState)) {
              attrInitialState = attrState;
            }
          }

          var initialState = attrInitialState || cfgInitialState;
          //console.log('initialState:' + initialState);

          cfg.initial = initialState;

          fsm = $scope.stateMachine = StateMachineService.create(cfg);
        }

        //callback
        onStateCompleteCallback(fsm);
      };

      /**
       * Retrieves a value from this component's persistent storage
       *
       * @param key
       * @param defaultValue    The value to return if the @key is not found
       * @returns {*}
       */
      controller.getPersistentValue = function(key, defaultValue) {
        return AppStateService.getPersistentValue(componentName, key, defaultValue);
      };

      /**
       * Stores @key:@value for this component
       *
       * @param keyValueHash
       * @returns {*}
       */
      controller.setPersistentValue = function(key, value) {
        return AppStateService.setPersistentValue(componentName, key, value);
      };

      /**
       * Stores @keyValueHash properties for this component
       *
       * @param keyValueHash
       * @returns {*}
       */
      controller.setPersistentValues = function(keyValueHash) {
        return AppStateService.setPersistentValues(componentName, keyValueHash);
      };

      /**
       * Sets a $watch on $scope.key and will automatically persist it on any changes
       *
       * @param {string} key    A key to a value on $scope. Must be a string
       * @param defaultValue    The value to use if no previous value is set for @key
       */
      controller.watchAndPersist = function(key, defaultValue) {
        //Add watch to key value
        $scope.$watch(key, function(newValue) {
          controller.setPersistentValue(key, newValue);
        });

        defaultValue = controller.getPersistentValue(key, defaultValue);

        $scope[key] = defaultValue;
      };

      /**
       * Sets a $watch that will automatically be removed when the $scope is $destroy'ed
       * @param key
       * @param watchHandler
       */
      var autoWatch = function autoWatch(key, watchHandler) {
        //Add watch to key value
        var removeWatch = $scope.$watch(key, watchHandler);

        var removeDestroy = $scope.$on('$destroy', function() {
          removeWatch();
          removeDestroy();
        });
      };

      /**
       * Subscribes to @eventName on @IEventTarget and automatically
       * unsubscribes when the Component is destroyed
       *
       * @param IEventTarget
       * @param eventName
       * @param handler
       */
      var autosubscribe = function autosubscribe(IEventTarget, eventName, handler) {

        IEventTarget.subscribe(eventName, handler);

        var removeDestroy = $scope.$on('$destroy', function() {
          IEventTarget.unsubscribe(eventName, handler);
          removeDestroy();
        });

        //TODO: Maybe add $element.on('$destroy'?
      };

      /**
       * Adds to @handler on @signal and automatically
       * removes when the Component is destroyed
       *
       * @param signal
       * @param handler
       */
      var autoSignalAdd = function autoSignalAdd(signal, handler) {

        signal.add(handler);

        var removeDestroy = $scope.$on('$destroy', function() {
          if (signal.has(handler)) {
            signal.remove(handler);
          }
          removeDestroy();
        });
      };

      /**
       * Adds to @handler $on @eventName and automatically
       * removes when the Component is destroyed
       *
       * @param signal
       * @param handler
       */
      var autoScopeOn = function autoScopeOn(eventName, handler) {

        var removeOnHandler = $scope.$on(eventName, handler);

        var removeDestroy = $scope.$on('$destroy', function() {
          removeOnHandler();
          removeDestroy();
        });
      };

      // Closured var for our digest cancel
      var cancelDigestUpdate = null;

      /**
       * Adds a handler to be called after any completed angular digest cycle.
       *
       * @param handle
       */
      var autoAfterDigest = function autoAfterDigest(handle) {

        // Function that will run after the digest
        function afterDigest(callback) {
          if ($scope.$$destroyed) { return; }

          // Setup a watch to run once
          cancelDigestUpdate = $scope.$watch(function() {
            cancelDigestUpdate();
            $timeout(function() {
              callback();
              afterDigest(callback);
            }, 0, false);
          });
        }

        afterDigest(handle);
      };

      //Expose all auto functions on single controller "auto" subobject
      controller.auto = {
        add: autoSignalAdd,
        subscribe: autosubscribe,
        watch: autoWatch,
        on: autoScopeOn,
        afterDigest: autoAfterDigest
      };

      //Deprecated: Add $element sugar methods
      ElementHelperService.addElementSupport(controller, $scope, $element);

      /**
       * Adds $element.auto.on() and $element.auto.applyOn()
       */
      ElementHelperService.addAutoMethods($element, $scope, controller);

      //Add prerender support
      ComponentPrerenderService.addPrerenderMethods($scope, controller);
    };

    // Service Object Definition
    var service = {
      init: init
    };

    return service;
  }]
);
<commit_msg>Refactors to ComponentFactoryService<commit_after>/**
 * This service provides base class extension and default functionality to component controllers.
 *
 * @class ComponentFactoryService
 * @module Hightail
 * @submodule Hightail.Services
 *
 * @author justin.fiedler
 * @author hunter.novak
 * @since 0.0.1
 *
 * @copyright (c) 2013 Hightail Inc. All Rights Reserved
 */
'use strict';

angular.wilson.service('ComponentFactoryService',
  ['$rootScope', '$timeout', 'StateMachineService', 'i18nextService', 'AppStateService', 'TranslationOverrideService', 'ComponentPrerenderService',
  function($rootScope, $timeout, StateMachineService, i18nextService, AppStateService, TranslationOverrideService, ComponentPrerenderService) {

    //   ____       _            _         __  __      _   _               _
    //  |  _ \ _ __(_)_   ____ _| |_ ___  |  \/  | ___| |_| |__   ___   __| |___
    //  | |_) | '__| \ \ / / _` | __/ _ \ | |\/| |/ _ \ __| '_ \ / _ \ / _` / __|
    //  |  __/| |  | |\ V / (_| | ||  __/ | |  | |  __/ |_| | | | (_) | (_| \__ \
    //  |_|   |_|  |_| \_/ \__,_|\__\___| |_|  |_|\___|\__|_| |_|\___/ \__,_|___/
    //
    // region private methods

    function noop() {}

    function getParentComponentScope(scope) {

      // Get the direct parent scope
      var parentScope = scope.$parent;

      // Continue up the scope hierarchy until we find the next Wilson Component scope
      while (parentScope && !_.has(parentScope, 'componentCName')) {
        parentScope = parentScope.$parent;
      }

      // Return the parent Wilson Component scope if found, otherwise, just the default parent scope
      return parentScope || scope.$parent;
    }

    // endregion

    /**
     * Initializes a Component Controller
     *
     * @method init
     *
     * @param componentName The name of the component
     * @param $scope        Reference to the components $scope
     * @param $element      Reference to the components $element
     * @param $attrs        Reference to the components $attrs
     * @param controller    Reference to the components controller
     */
    var init = function wilsonComponentInit(componentName, $scope, $element, $attrs, controller) {

      // Closure var for our digest cancel
      var cancelDigestUpdate    = null;

      // Text Overrides and Ignored Overrides
      var textOverrides         = {};
      var ignoredTextOverrides  = {};

      // Parent Scope
      var parentComponentScope  = getParentComponentScope($scope);

      /***** Scope Decorations *****/

      $scope.componentCName   = controller.componentCName = componentName;  // Decorate the Wilson Component Name onto both controller and $scope
      $scope.parentComponent  = parentComponentScope;                       // Decorate the parent Wilson Component scope onto this component's scope
      $scope.stateMachine     = { current: 'NoStateMachine' };              // Default StateMachine

      /***** Configuration Attributes *****/

      // ATTRIBUTE: expose  - Used for exposing this components scope on the parent component
      var exposeName = $attrs ? $attrs.expose : false;
      if (exposeName) { parentComponentScope[exposeName] = $scope; }

      //   ____                         __  __      _   _               _
      //  / ___|  ___ ___  _ __   ___  |  \/  | ___| |_| |__   ___   __| |___
      //  \___ \ / __/ _ \| '_ \ / _ \ | |\/| |/ _ \ __| '_ \ / _ \ / _` / __|
      //   ___) | (_| (_) | |_) |  __/ | |  | |  __/ |_| | | | (_) | (_| \__ \
      //  |____/ \___\___/| .__/ \___| |_|  |_|\___|\__|_| |_|\___/ \__,_|___/
      //                  |_|
      //
      // region scope methods

      /**
       * Translates given text based on the set language.
       *
       * @public
       * @method translate
       * @for HtComponent
       * @param text        The text to translate
       * @param options     Translation options (e.g. { ns:'my-namespace', count: 1})
       *
       * @async
       */
      $scope.translate = controller.translate = function wcTranslate(text, options) {
        // Create a default callback if needed
        options = options || {};

        // Default namespace is component name
        if (typeof options.ns !== 'string' || options.ns === '') { options.ns = componentName; }

        if (!ignoredTextOverrides[text]) {
          // Check if the text has an override
          if (textOverrides[text]) {
            options.ns = textOverrides[text];
          } else if (TranslationOverrideService.hasOverride(options.ns, text)) {
            // The text has an override, now determine if it applies to this component
            for (var ancestor = $scope.parentComponent; ancestor !== null; ancestor = ancestor.parentComponent) {
              if (TranslationOverrideService.hasOverrideForNamespace(options.ns, text, ancestor.componentCName)) {
                options.ns = textOverrides[text] = ancestor.componentCName;
                break;
              }
            }

            // If the namespace is still set to this component then mark as ignored
            if (options.ns === componentName) { ignoredTextOverrides[text] = true; }
          }
        }

        // Use the i18n provider to translate the text
        return i18nextService.translate(text, options);
      };

      /**
       * Marks the @textKey in @overrideNamespace to be overridden with @overrideText
       *
       * e.g.
       * In send.js
       * controller
       *
       * @param overrideNamespace
       * @param textKey
       * @param overrideText
       */
      $scope.overrideText = controller.overrideText = function wcOverrideText(overrideNamespace, textKey, overrideText) {
        TranslationOverrideService.addOverride(overrideNamespace, componentName, textKey);

        // Call translate to add the translation to the locale JSON
        controller.translate(textKey, { defaultValue: overrideText });
      };

      /**
       * Sets @scopePropertyName on $scope to @defaultValue if it is not already set
       *
       * @param scopePropertyName
       * @param defaultValue
       * @returns {*}
       */
      $scope.defaultValue = function wcDefaultValue(scopePropertyName, defaultValue) {
        var value = $scope[scopePropertyName];
        if (_.isUndefined(value) || _.isNull(value)) {
          $scope[scopePropertyName] = defaultValue;
        }

        return $scope[scopePropertyName];
      };

      /**
       * Method to trigger a digest to re-render the view.
       */
      $scope.triggerDigest = function wcTriggerDigest() {
        $timeout(noop);
      };

      /**
       * Method to bind a function to run and trigger a digest
       */
      $scope.bindToDigest = function wcBindToDigest(method, context) {
        context = context || this;

        var bound = function() {
          method.apply(context, arguments);
          $scope.triggerDigest();
        };

        return method ? bound : noop;
      };

      // endregion

      //    ____            _             _ _             __  __      _   _               _
      //   / ___|___  _ __ | |_ _ __ ___ | | | ___ _ __  |  \/  | ___| |_| |__   ___   __| |___
      //  | |   / _ \| '_ \| __| '__/ _ \| | |/ _ \ '__| | |\/| |/ _ \ __| '_ \ / _ \ / _` / __|
      //  | |__| (_) | | | | |_| | | (_) | | |  __/ |    | |  | |  __/ |_| | | | (_) | (_| \__ \
      //   \____\___/|_| |_|\__|_|  \___/|_|_|\___|_|    |_|  |_|\___|\__|_| |_|\___/ \__,_|___/
      //
      // region controller methods

      /**
       * Creates a new stateMachine for this component.
       * Calls onStateCompleteCallback(stateMachine) on completion
       *
       * @public
       * @method setState
       * @for HtComponent
       * @param cfg
       * @param onStateCompleteCallback   Callback function(e.g. function(stateMachine) {} )
       *
       * @async
       */
      controller.setState = function wcSetState(cfg, onStateCompleteCallback) {
        // Create noop callback if needed
        onStateCompleteCallback = onStateCompleteCallback || function() {};

        var fsm = $scope.stateMachine;

        if (cfg) {
          var cfgInitialState = cfg.initial;
          var attrInitialState;

          // Check if there is an initialState attr on the component
          if ($attrs) {
            var attrState = $attrs.initialState;
            if (attrState && StateMachineService.hasState(cfg, attrState)) {
              attrInitialState = attrState;
            }
          }

          var initialState  = attrInitialState || cfgInitialState;
          cfg.initial       = initialState;
          fsm               = $scope.stateMachine = StateMachineService.create(cfg);
        }

        // Callback
        onStateCompleteCallback(fsm);
      };

      /**
       * Retrieves a value from this component's persistent storage (localStorage)
       *
       * @param key
       * @param defaultValue    The value to return if the @key is not found
       * @returns {*}
       */
      controller.getPersistentValue = function wcGetPersistentValue(key, defaultValue) {
        return AppStateService.getPersistentValue(componentName, key, defaultValue);
      };

      /**
       * Stores @key:@value for this component in localStorage
       *
       * @param keyValueHash
       * @returns {*}
       */
      controller.setPersistentValue = function wcSetPersistentValue(key, value) {
        return AppStateService.setPersistentValue(componentName, key, value);
      };

      /**
       * Stores @keyValueHash properties for this component
       *
       * @param keyValueHash
       * @returns {*}
       */
      controller.setPersistentValues = function wcSetPersistentValues(keyValueHash) {
        return AppStateService.setPersistentValues(componentName, keyValueHash);
      };

      /**
       * Sets a $watch on $scope.key and will automatically persist it on any changes
       *
       * @param {string} key    A key to a value on $scope. Must be a string
       * @param defaultValue    The value to use if no previous value is set for @key
       */
      controller.watchAndPersist = function wcWatchAndPersist(key, defaultValue) {
        //Add watch to key value
        $scope.$watch(key, function(newValue) {
          controller.setPersistentValue(key, newValue);
        });

        defaultValue = controller.getPersistentValue(key, defaultValue);

        $scope[key] = defaultValue;
      };

      /************************************/
      /***** AUTO EVENT REGISTRATIONS *****/
      /************************************/
      controller.auto = {};

      /**
       * Sets a $watch that will automatically be removed when the $scope is $destroy'ed
       * @param key
       * @param watchHandler
       */
      controller.auto.watch = function wcWatch(key, watchHandler) {
        //Add watch to key value
        var removeWatch = $scope.$watch(key, watchHandler);

        var removeDestroy = $scope.$on('$destroy', function() {
          removeWatch();
          removeDestroy();
        });
      };

      /**
       * Adds to @handler on @signal and automatically
       * removes when the Component is destroyed
       *
       * @param signal
       * @param handler
       */
      controller.auto.add = function wcSignalAdd(signal, handler) {

        signal.add(handler);

        var removeDestroy = $scope.$on('$destroy', function() {
          if (signal.has(handler)) {
            signal.remove(handler);
          }
          removeDestroy();
        });
      };

      /**
       * Adds to @handler $on @eventName and automatically
       * removes when the Component is destroyed
       *
       * @param signal
       * @param handler
       */
      controller.auto.on = function wcScopeOn(eventName, handler) {

        var removeOnHandler = $scope.$on(eventName, handler);

        var removeDestroy = $scope.$on('$destroy', function() {
          removeOnHandler();
          removeDestroy();
        });
      };

      /**
       * Adds a handler to be called after any completed angular digest cycle.
       *
       * @param handle
       */
      controller.auto.afterDigest = function wcAfterDigest(handle) {

        // Function that will run after the digest
        function afterDigest(callback) {
          if ($scope.$$destroyed) { return; }

          // Setup a watch to run once
          cancelDigestUpdate = $scope.$watch(function() {
            cancelDigestUpdate();
            $timeout(function() {
              callback();
              afterDigest(callback);
            }, 0, false);
          });
        }

        afterDigest(handle);
      };

      // endregion

      // TODO: We need to destroy the state machine (remove its timeouts)
      // $scope.$on('$destroy', function() { });

      // Decorate Prerendering Support
      ComponentPrerenderService.addPrerenderMethods($scope, controller);
    };

    // Service Object Definition
    var service = { init: init };

    return service;
  }]
);
<|endoftext|>


<commit_before>/*global availity, beforeEach, expect, module, describe, it */
describe('analyticsServices', function() {
  'use strict';

  var foo;

  beforeEach(function() {
    module('availity', function(analyticsServicesProvider) {
       analyticsServicesProvider.registerPlugins(['piwikAnalyticService', 'splunkAnalyticService']);
       foo = analyticsServicesProvider.config;
       // bar = analyticsServicesProvider.trackEvent(properties);
    });
  });

  availity.mock.directiveSpecHelper();

  it('should register the defined plugin with angular', function(){
    expect(foo.plugins[0]).toEqual('piwikAnalyticService');
    expect(foo.plugins[1]).toEqual('splunkAnalyticService');
    expect(foo.plugins.length).toEqual(2);
  });

  // it('should add a track event to the array', function(){
  //   var bar =
  //   expect(bar.length).toEqual(1);
  // });

});<commit_msg>updated test analytics service<commit_after>/*global availity, beforeEach, expect, module, describe, it */
describe('analyticsServices', function() {
  'use strict';

  var foo;

  beforeEach(function() {
    module('availity', function(analyticsServicesProvider) {
       analyticsServicesProvider.registerPlugins(['piwikAnalyticService', 'analyticsSplunkService']);
       foo = analyticsServicesProvider.config;
       // bar = analyticsServicesProvider.trackEvent(properties);
    });
  });

  availity.mock.directiveSpecHelper();

  it('should register the defined plugin with angular', function(){
    expect(foo.plugins[0]).toEqual('piwikAnalyticService');
    expect(foo.plugins[1]).toEqual('analyticsSplunkService');
    expect(foo.plugins.length).toEqual(2);
  });

  // it('should add a track event to the array', function(){
  //   var bar =
  //   expect(bar.length).toEqual(1);
  // });

});<|endoftext|>