<commit_before>#!/usr/bin/env node

var MongoClient = require('mongodb').MongoClient;

var uri = process.env.MONGOLAB_URI;

var data1 = {
    "question" : "What are two main topics covered in the Declaration of Independence?",
    "options" : {
        "0" : "Articles of Confederation",
        "1" : "Bill of Rights",
        "2" : "Theory of American Government",
        "3" : "The wrongs done to the colonies by the English government",
        "4" : "The Amendments"
    },
    "answer" : ["2", "3"],
    "multi" : true,
    "randomizer" : [
        0.004628593567758799,
        0.20673484704457223
    ]
};

var data2 = {
    "question" : "What is the theory of American government?",
    "options" : {
        "0" : "That the government works for the people and the citizens do not exist for the good of the government",
        "1" : "The document written to declare independence from England",
        "2" : "The idea of a central, national, and federal branches of government",
        "3" : "The seven articles of the Constitution",
        "4" : "That America is the best country in the world"
    },
    "answer" : ["0"],
    "multi" : false,
    "randomizer" : [
        0.9244870271068066,
        0.7100111313629895
    ]
};

MongoClient.connect(uri, function(err, db) {
    if (err) {
        console.log(err);
    }

    db.createCollection('questions', function(err, col) {
        if (err) {
            db.close();
            console.log(err);
        }

        col.insert([data1, data2], function(err, result) {
            db.close();
            console.log(result);
        });
    });
});
<commit_msg>Added geospatial index to test db<commit_after>#!/usr/bin/env node

var MongoClient = require('mongodb').MongoClient;

var uri = process.env.MONGOLAB_URI;

var data1 = {
    "question" : "What are two main topics covered in the Declaration of Independence?",
    "options" : {
        "0" : "Articles of Confederation",
        "1" : "Bill of Rights",
        "2" : "Theory of American Government",
        "3" : "The wrongs done to the colonies by the English government",
        "4" : "The Amendments"
    },
    "answer" : ["2", "3"],
    "multi" : true,
    "randomizer" : [
        0.004628593567758799,
        0.20673484704457223
    ]
};

var data2 = {
    "question" : "What is the theory of American government?",
    "options" : {
        "0" : "That the government works for the people and the citizens do not exist for the good of the government",
        "1" : "The document written to declare independence from England",
        "2" : "The idea of a central, national, and federal branches of government",
        "3" : "The seven articles of the Constitution",
        "4" : "That America is the best country in the world"
    },
    "answer" : ["0"],
    "multi" : false,
    "randomizer" : [
        0.9244870271068066,
        0.7100111313629895
    ]
};

MongoClient.connect(uri, function(err, db) {
    if (err) {
        console.log(err);
    }

    db.createCollection('questions', function(err, col) {
        if (err) {
            db.close();
            console.log(err);
        }

        col.createIndex({'randomizer': '2dsphere'}, function(err, result) {
            if (err) {
                db.close();
                console.log(err);
            }

            col.insert([data1, data2], function(err, result) {
                if (err) {
                    db.close();
                    console.log(err);
                }

                db.close();
                console.log(result);
            });
        });
    });
});
<|endoftext|>


<commit_before>/*
 * Copyright 2015 Steffen Coenen <steffen@steffen-coenen.de>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

"use strict";

(function(Nuvola)
{

// vars
var DEFAULT_ADDRESS = "http://localhost:9000/";
var ADDRESS = "app.address";
var ADDRESS_DEFAULT = "default";
var ADDRESS_CUSTOM = "custom";
var HOST = "app.host";
var PORT = "app.port";

// Create new WebApp prototype
var WebApp = Nuvola.$WebApp();

// Handy aliases
var PlaybackState = Nuvola.PlaybackState;
var PlayerAction = Nuvola.PlayerAction;

// Translations
var _ = Nuvola.Translate.gettext;

// Create media player component
var player = Nuvola.$object(Nuvola.MediaPlayer);

// Home Request
WebApp._onHomePageRequest = function(emitter, result)
{
    result.url = (Nuvola.config.get(ADDRESS) === ADDRESS_CUSTOM)
    ? Nuvola.format("http://{1}:{2}", Nuvola.config.get(HOST), Nuvola.config.get(PORT))
    : DEFAULT_ADDRESS;
}

WebApp._onInitAppRunner = function(emitter)
{
	Nuvola.WebApp._onInitAppRunner.call(this, emitter);

	Nuvola.config.setDefault(ADDRESS, ADDRESS_DEFAULT);
	Nuvola.config.setDefault(HOST, "");
	Nuvola.config.setDefault(PORT, "");

	Nuvola.core.connect("InitializationForm", this);
	Nuvola.core.connect("PreferencesForm", this);
}

WebApp._onInitializationForm = function(emitter, values, entries)
{
	if (!Nuvola.config.hasKey(ADDRESS))
	    this.appendPreferences(values, entries);
}

WebApp._onPreferencesForm = function(emitter, values, entries)
{
    this.appendPreferences(values, entries);
}

WebApp.appendPreferences = function(values, entries)
{
	values[ADDRESS] = Nuvola.config.get(ADDRESS);
	values[HOST] = Nuvola.config.get(HOST);
	values[PORT] = Nuvola.config.get(PORT);
	entries.push(["header", _("Logitech Media Server")]);
	entries.push(["label", _("Address of your Logitech Media Server")]);
	entries.push(["option", ADDRESS, ADDRESS_DEFAULT,
	    _("use default address ('localhost:9000')"), null, [HOST, PORT]]);
	entries.push(["option", ADDRESS, ADDRESS_CUSTOM,
	    _("use custom address"), [HOST, PORT], null]);
	entries.push(["string", HOST, "Host"]);
	entries.push(["string", PORT, "Port"]);
}

// Initialization routines
WebApp._onInitWebWorker = function(emitter)
{
    Nuvola.WebApp._onInitWebWorker.call(this, emitter);

    var state = document.readyState;
    if (state === "interactive" || state === "complete")
        this._onPageReady();
    else
        document.addEventListener("DOMContentLoaded", this._onPageReady.bind(this));
}

// Page is ready for magic
WebApp._onPageReady = function()
{
    // Connect handler for signal ActionActivated
    Nuvola.actions.connect("ActionActivated", this);

    // Start update routine
    this.update();
}

// Extract data from the web page
WebApp.update = function()
{
    var track = {}

	var artistDiv = document.getElementById('ctrlCurrentArtist');
	try{
		var artist = artistDiv.firstChild;
		track.artist = artist.innerText || artist.textContent;
	}
	catch (e){
		track.artist = null;
	}

	try{
		var song = document.getElementById('ctrlCurrentTitle').firstChild;
		track.title = song.innerText || song.textContent;
		var songtosplit = song.innerText || song.textContent;
		// Kills track number if there is any one.
		if (songtosplit.indexOf(". ",0) > 0){
			track.title = songtosplit.split(/\.(.+)?/)[1].trim();
		}
	}
		catch (e){
			track.title = null;
		}

	var albumDiv = document.getElementById('ctrlCurrentAlbum');
	try{
		var album = albumDiv.firstChild;
		track.album = album.innerText || album.textContent;
	}
	catch (e){
		track.album = null;
	}

	try{
		var album_object = document.getElementById('ctrlCurrentArt').children[0];
		if (album_object.nodeName == 'IMG') {
			track.artLocation = album_object.src;
		}
		else{
			track.artLocation = album_object.children[0].src;
		}
	}
	catch (e){
		track.artLocation = null;
	}

	player.setTrack(track);

	player.setCanPause(true)
	player.setCanPlay(true)
	player.setCanGoPrev(true)
	player.setCanGoNext(true)

	var state = PlaybackState.UNKNOWN
	try {
		state = ((document.getElementById("ctrlTogglePlay").firstChild.className.indexOf("btn-play")>-1))? PlaybackState.PAUSED : PlaybackState.PLAYING;
		}
	catch (e) {
		state = PlaybackState.UNKNOWN
	}

	//Set state to unknown if there is no available song
	if(state==!track.title){
		state=PlaybackState.UNKNOWN;
		player.setCanPause(false);
		player.setCanPlay(false);
		player.setCanGoPrev(false);
		player.setCanGoNext(false)
	}

    player.setPlaybackState(state);

    // Schedule the next update
    setTimeout(this.update.bind(this), 500);
}

// Handler of playback actions
WebApp._onActionActivated = function(emitter, name, param)
{
	switch (name)
	{
		case PlayerAction.TOGGLE_PLAY:
			document.getElementById('ctrlTogglePlay').firstChild.click();
		break;
		case PlayerAction.PLAY:
			document.getElementById('ctrlTogglePlay').firstChild.click();
		break;
		case PlayerAction.PAUSE:
			document.getElementById('ctrlTogglePlay').firstChild.click();
		break;
		case PlayerAction.STOP:
			document.getElementById('ctrlTogglePlay').firstChild.click();
		break;
		case PlayerAction.PREV_SONG:
			document.getElementById('ctrlPrevious').firstChild.click();
		break;
		case PlayerAction.NEXT_SONG:
			document.getElementById('ctrlNext').firstChild.click();
		break;
	}
}

WebApp.start();

})(this);  // function(Nuvola)
<commit_msg>Update integrate.js<commit_after>/*
 * Copyright 2015 Steffen Coenen <steffen@steffen-coenen.de>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

"use strict";

(function(Nuvola)
{

// vars
var DEFAULT_ADDRESS = "http://localhost:9000/";
var ADDRESS = "app.address";
var ADDRESS_DEFAULT = "default";
var ADDRESS_CUSTOM = "custom";
var HOST = "app.host";
var PORT = "app.port";

// Create new WebApp prototype
var WebApp = Nuvola.$WebApp();

// Handy aliases
var PlaybackState = Nuvola.PlaybackState;
var PlayerAction = Nuvola.PlayerAction;

// Translations
var _ = Nuvola.Translate.gettext;

// Create media player component
var player = Nuvola.$object(Nuvola.MediaPlayer);

// Home Request
WebApp._onHomePageRequest = function(emitter, result)
{
    result.url = (Nuvola.config.get(ADDRESS) === ADDRESS_CUSTOM)
    ? Nuvola.format("http://{1}:{2}", Nuvola.config.get(HOST), Nuvola.config.get(PORT))
    : DEFAULT_ADDRESS;
}

WebApp._onInitAppRunner = function(emitter)
{
	Nuvola.WebApp._onInitAppRunner.call(this, emitter);

	Nuvola.config.setDefault(ADDRESS, ADDRESS_DEFAULT);
	Nuvola.config.setDefault(HOST, "");
	Nuvola.config.setDefault(PORT, "");

	Nuvola.core.connect("InitializationForm", this);
	Nuvola.core.connect("PreferencesForm", this);
}

WebApp._onInitializationForm = function(emitter, values, entries)
{
	if (!Nuvola.config.hasKey(ADDRESS))
	    this.appendPreferences(values, entries);
}

WebApp._onPreferencesForm = function(emitter, values, entries)
{
    this.appendPreferences(values, entries);
}

WebApp.appendPreferences = function(values, entries)
{
	values[ADDRESS] = Nuvola.config.get(ADDRESS);
	values[HOST] = Nuvola.config.get(HOST);
	values[PORT] = Nuvola.config.get(PORT);
	entries.push(["header", _("Logitech Media Server")]);
	entries.push(["label", _("Address of your Logitech Media Server")]);
	entries.push(["option", ADDRESS, ADDRESS_DEFAULT,
	    _("use default address ('localhost:9000')"), null, [HOST, PORT]]);
	entries.push(["option", ADDRESS, ADDRESS_CUSTOM,
	    _("use custom address"), [HOST, PORT], null]);
	entries.push(["string", HOST, "Host"]);
	entries.push(["string", PORT, "Port"]);
}

// Initialization routines
WebApp._onInitWebWorker = function(emitter)
{
    Nuvola.WebApp._onInitWebWorker.call(this, emitter);

    var state = document.readyState;
    if (state === "interactive" || state === "complete")
        this._onPageReady();
    else
        document.addEventListener("DOMContentLoaded", this._onPageReady.bind(this));
}

// Page is ready for magic
WebApp._onPageReady = function()
{
    // Connect handler for signal ActionActivated
    Nuvola.actions.connect("ActionActivated", this);

    // Start update routine
    this.update();
}

// Extract data from the web page
WebApp.update = function()
{
    var track = {}

	var artistDiv = document.getElementById('ctrlCurrentArtist');
	try{
		var artist = artistDiv.firstChild;
		track.artist = artist.innerText || artist.textContent;
	}
	catch (e){
		track.artist = null;
	}

	try{
		var song = document.getElementById('ctrlCurrentTitle').firstChild;
		track.title = song.innerText || song.textContent;
		var songtosplit = song.innerText || song.textContent;
		// Kills track number if there is any one.
		if (songtosplit.indexOf(". ",0) > 0){
			track.title = songtosplit.split(/\.(.+)?/)[1].trim();
		}
	}
		catch (e){
			track.title = null;
		}

	var albumDiv = document.getElementById('ctrlCurrentAlbum');
	try{
		var album = albumDiv.firstChild;
		track.album = album.innerText || album.textContent;
	}
	catch (e){
		track.album = null;
	}

	try{
		var album_object = document.getElementById('ctrlCurrentArt').children[0];
		if (album_object.nodeName == 'IMG') {
			track.artLocation = album_object.src;
		}
		else{
			track.artLocation = album_object.children[0].src;
		}
	}
	catch (e){
		track.artLocation = null;
	}

	player.setTrack(track);

	var state = PlaybackState.UNKNOWN
	try {
		state = ((document.getElementById("ctrlTogglePlay").firstChild.className.indexOf("btn-play")>-1))? PlaybackState.PAUSED : PlaybackState.PLAYING;
		}
	catch (e) {
		state = PlaybackState.UNKNOWN
	}

	//Set state to unknown if there is no available song
	if(state==!track.title){
		state=PlaybackState.UNKNOWN;
		player.setCanPause(false);
		player.setCanPlay(false);
		player.setCanGoPrev(false);
		player.setCanGoNext(false)
	} else {
		player.setCanPause(true)
		player.setCanPlay(true)
		player.setCanGoPrev(true)
		player.setCanGoNext(true)
	}

    player.setPlaybackState(state);

    // Schedule the next update
    setTimeout(this.update.bind(this), 500);
}

// Handler of playback actions
WebApp._onActionActivated = function(emitter, name, param)
{
	switch (name)
	{
		case PlayerAction.TOGGLE_PLAY:
			document.getElementById('ctrlTogglePlay').firstChild.click();
		break;
		case PlayerAction.PLAY:
			document.getElementById('ctrlTogglePlay').firstChild.click();
		break;
		case PlayerAction.PAUSE:
			document.getElementById('ctrlTogglePlay').firstChild.click();
		break;
		case PlayerAction.STOP:
			document.getElementById('ctrlTogglePlay').firstChild.click();
		break;
		case PlayerAction.PREV_SONG:
			document.getElementById('ctrlPrevious').firstChild.click();
		break;
		case PlayerAction.NEXT_SONG:
			document.getElementById('ctrlNext').firstChild.click();
		break;
	}
}

WebApp.start();

})(this);  // function(Nuvola)
<|endoftext|>


<commit_before>import '@testing-library/jest-dom'
import Vue from 'vue'
import * as VTU from '@vue/test-utils'
import { installCompat as installVTUCompat, fullCompatConfig } from 'vue-test-utils-compat'

const useVue2 = 'USE_VUE2' in process.env
if (!useVue2) {
  Vue.configureCompat({
    MODE: 2
  })

  const compatH = new Vue({}).$createElement
  installVTUCompat(VTU, fullCompatConfig, compatH)
}

// Don't stub `<transition>` and `<transition-group>` components
VTU.config.stubs.transition = false
VTU.config.stubs['transition-group'] = false
<commit_msg>chore(compat): silence most warning from Vue 3 compat build<commit_after>import '@testing-library/jest-dom'
import Vue from 'vue'
import * as VTU from '@vue/test-utils'
import { installCompat as installVTUCompat, fullCompatConfig } from 'vue-test-utils-compat'

const useVue2 = 'USE_VUE2' in process.env
if (!useVue2) {
  Vue.configureCompat({
    MODE: 2,
    ATTR_FALSE_VALUE: 'suppress-warning',
    COMPONENT_FUNCTIONAL: 'suppress-warning',
    COMPONENT_V_MODEL: 'suppress-warning',
    CONFIG_OPTION_MERGE_STRATS: 'suppress-warning',
    CONFIG_WHITESPACE: 'suppress-warning',
    CUSTOM_DIR: 'suppress-warning',
    GLOBAL_EXTEND: 'suppress-warning',
    GLOBAL_MOUNT: 'suppress-warning',
    GLOBAL_PRIVATE_UTIL: 'suppress-warning',
    GLOBAL_PROTOTYPE: 'suppress-warning',
    GLOBAL_SET: 'suppress-warning',
    INSTANCE_ATTRS_CLASS_STYLE: 'suppress-warning',
    INSTANCE_CHILDREN: 'suppress-warning',
    INSTANCE_DELETE: 'suppress-warning',
    INSTANCE_DESTROY: 'suppress-warning',
    INSTANCE_EVENT_EMITTER: 'suppress-warning',
    INSTANCE_EVENT_HOOKS: 'suppress-warning',
    INSTANCE_LISTENERS: 'suppress-warning',
    INSTANCE_SCOPED_SLOTS: 'suppress-warning',
    INSTANCE_SET: 'suppress-warning',
    OPTIONS_BEFORE_DESTROY: 'suppress-warning',
    OPTIONS_DATA_MERGE: 'suppress-warning',
    OPTIONS_DESTROYED: 'suppress-warning',
    RENDER_FUNCTION: 'suppress-warning',
    V_FOR_REF: 'suppress-warning',
    WATCH_ARRAY: 'suppress-warning'
  })

  let compatH
  Vue.config.compilerOptions.whitespace = 'condense'
  Vue.createApp({
    compatConfig: {
      MODE: 3,
      RENDER_FUNCTION: 'suppress-warning'
    },
    render(h) {
      compatH = h
    }
  }).mount(document.createElement('div'))
  installVTUCompat(VTU, fullCompatConfig, compatH)
}

// Don't stub `<transition>` and `<transition-group>` components
VTU.config.stubs.transition = false
VTU.config.stubs['transition-group'] = false
<|endoftext|>


<commit_before>/*
 * Copyright 2015-2017 Jiří Janoušek <janousek.jiri@gmail.com>
 * Copyright 2017 Aleksey Zhidkov <aleksey.zhidkov@gmail.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

'use strict';

(function (Nuvola) {
  if (Nuvola.global === window) {
    /* Fix for broken detection of window.webkitAudioContext */
    var origHasOwnProperty = window.hasOwnProperty
    window.hasOwnProperty = function (key) {
      return origHasOwnProperty.call(window, key) && window[key] !== undefined
    }
  }

// Create media player component
  var player = Nuvola.$object(Nuvola.MediaPlayer)

// Handy aliases
  var PlaybackState = Nuvola.PlaybackState
  var PlayerAction = Nuvola.PlayerAction

// Create new WebApp prototype
  var WebApp = Nuvola.$WebApp()

// Translations
  var C_ = Nuvola.Translate.pgettext

  var ACTION_LIKE = 'like'

// Initialization routines
  WebApp._onInitWebWorker = function (emitter) {
    Nuvola.WebApp._onInitWebWorker.call(this, emitter)

    var state = document.readyState
    if (state === 'interactive' || state === 'complete') {
      this._onPageReady()
    } else {
      document.addEventListener('DOMContentLoaded', this._onPageReady.bind(this))
    }

    Nuvola.actions.addAction('like', 'win', ACTION_LIKE, C_('Action', 'Like'),
        null, null, null, true)
  }

// Page is ready for magic
  WebApp._onPageReady = function () {
    // Connect handler for signal ActionActivated
    Nuvola.actions.connect('ActionActivated', this)
    try {
      // Remove advertising sidebar
      document.querySelector('.centerblock-wrapper').setAttribute('style', 'width: 100%')
      var sidebar = document.querySelector('.sidebar__placeholder .sidebar')
      sidebar.parentNode.removeChild(sidebar)
    } catch (e) { /* ignored */ }

    player.addExtraActions([ACTION_LIKE])

    // Start update routine
    this.update()
  }

// Extract data from the web page
  WebApp.update = function () {
    var track = {
      title: null,
      artist: null,
      album: null,
      artLocation: null
    }

    try {
      track.title = document.querySelector('.player-controls .track .track__title').innerText
      track.artist = document.querySelector('.player-controls .track .track__artists').innerText
      track.artLocation = document.querySelector('.player-controls .track .track-cover').src.replace(
            /\d+x\d+$/, '200x200')
    } catch (e) {
        // ~ console.log(e);
    }

    player.setTrack(track)

    var buttons = this.getButtons()
    var state = null
    if (buttons.pause) {
      state = PlaybackState.PLAYING
    } else if (buttons.play) {
      state = PlaybackState.PAUSED
    } else {
      state = PlaybackState.UNKNOWN
    }
    player.setPlaybackState(state)

    player.setCanGoPrev(!!buttons.prev)
    player.setCanGoNext(!!buttons.next)
    player.setCanPlay(!!buttons.play)
    player.setCanPause(!!buttons.pause)

    var actionsEnabled = {}
    var actionsStates = {}
    actionsEnabled[ACTION_LIKE] = buttons.like != null && document.querySelector('.head__userpic') != null
    actionsStates[ACTION_LIKE] = buttons.like != null && document.querySelector('.icon_like_on') != null
    Nuvola.actions.updateEnabledFlags(actionsEnabled)
    Nuvola.actions.updateStates(actionsStates)

    // Schedule the next update
    setTimeout(this.update.bind(this), 500)
  }

  WebApp.getButtons = function () {
    var notDisabled = function (selector) {
      var elm = document.querySelector(selector)
      return (elm && !elm.classList.contains('player-controls__btn_disabled')) ? elm : null
    }
    var playPause = notDisabled('.player-controls__btn_play')
    return {
      prev: notDisabled('.player-controls__btn_prev'),
      play: playPause && playPause.classList.contains('player-controls__btn_pause') ? null : playPause,
      pause: playPause && playPause.classList.contains('player-controls__btn_pause') ? playPause : null,
      next: notDisabled('.player-controls__btn_next'),
      like: notDisabled('.player-controls__btn.like_player')
    }
  }

// Handler of playback actions
  WebApp._onActionActivated = function (emitter, name, param) {
    var buttons = this.getButtons()
    switch (name) {
      case PlayerAction.TOGGLE_PLAY:
        if (buttons.play) {
          Nuvola.clickOnElement(buttons.play)
        } else if (buttons.pause) {
          Nuvola.clickOnElement(buttons.pause)
        }
        break
      case PlayerAction.PLAY:
        if (buttons.play) {
          Nuvola.clickOnElement(buttons.play)
        }
        break
      case PlayerAction.PAUSE:
      case PlayerAction.STOP:
        if (buttons.pause) {
          Nuvola.clickOnElement(buttons.pause)
        }
        break
      case PlayerAction.PREV_SONG:
        if (buttons.prev) {
          Nuvola.clickOnElement(buttons.prev)
        }
        break
      case PlayerAction.NEXT_SONG:
        if (buttons.next) {
          Nuvola.clickOnElement(buttons.next)
        }
        break
      case ACTION_LIKE:
        if (buttons.like) {
          Nuvola.clickOnElement(buttons.like)
        }
        break
    }
  }

  WebApp.start()
})(this)  // function(Nuvola)
<commit_msg>Integrate shuffle status<commit_after>/*
 * Copyright 2015-2017 Jiří Janoušek <janousek.jiri@gmail.com>
 * Copyright 2017 Aleksey Zhidkov <aleksey.zhidkov@gmail.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

'use strict';

(function (Nuvola) {
  if (Nuvola.global === window) {
    /* Fix for broken detection of window.webkitAudioContext */
    var origHasOwnProperty = window.hasOwnProperty
    window.hasOwnProperty = function (key) {
      return origHasOwnProperty.call(window, key) && window[key] !== undefined
    }
  }

// Create media player component
  var player = Nuvola.$object(Nuvola.MediaPlayer)

// Handy aliases
  var PlaybackState = Nuvola.PlaybackState
  var PlayerAction = Nuvola.PlayerAction

// Create new WebApp prototype
  var WebApp = Nuvola.$WebApp()

// Translations
  var C_ = Nuvola.Translate.pgettext

  var ACTION_LIKE = 'like'

// Initialization routines
  WebApp._onInitWebWorker = function (emitter) {
    Nuvola.WebApp._onInitWebWorker.call(this, emitter)

    var state = document.readyState
    if (state === 'interactive' || state === 'complete') {
      this._onPageReady()
    } else {
      document.addEventListener('DOMContentLoaded', this._onPageReady.bind(this))
    }

    Nuvola.actions.addAction('like', 'win', ACTION_LIKE, C_('Action', 'Like'),
        null, null, null, true)
  }

// Page is ready for magic
  WebApp._onPageReady = function () {
    // Connect handler for signal ActionActivated
    Nuvola.actions.connect('ActionActivated', this)
    try {
      // Remove advertising sidebar
      document.querySelector('.centerblock-wrapper').setAttribute('style', 'width: 100%')
      var sidebar = document.querySelector('.sidebar__placeholder .sidebar')
      sidebar.parentNode.removeChild(sidebar)
    } catch (e) { /* ignored */ }

    player.addExtraActions([ACTION_LIKE])

    // Start update routine
    this.update()
  }

  WebApp._getShuffle = function () {
    var elm = this.getButtons().shuffle
    return elm ? elm.classList.contains('player-controls__btn_on') : null
  }

// Extract data from the web page
  WebApp.update = function () {
    var track = {
      title: null,
      artist: null,
      album: null,
      artLocation: null
    }

    try {
      track.title = document.querySelector('.player-controls .track .track__title').innerText
      track.artist = document.querySelector('.player-controls .track .track__artists').innerText
      track.artLocation = document.querySelector('.player-controls .track .track-cover').src.replace(
            /\d+x\d+$/, '200x200')
    } catch (e) {
        // ~ console.log(e);
    }

    player.setTrack(track)

    var buttons = this.getButtons()
    var state = null
    if (buttons.pause) {
      state = PlaybackState.PLAYING
    } else if (buttons.play) {
      state = PlaybackState.PAUSED
    } else {
      state = PlaybackState.UNKNOWN
    }
    player.setPlaybackState(state)

    player.setCanGoPrev(!!buttons.prev)
    player.setCanGoNext(!!buttons.next)
    player.setCanPlay(!!buttons.play)
    player.setCanPause(!!buttons.pause)
    player.setCanShuffle(!!buttons.shuffle)

    player.setShuffleState(this._getShuffle())

    var actionsEnabled = {}
    var actionsStates = {}
    actionsEnabled[ACTION_LIKE] = buttons.like != null && document.querySelector('.head__userpic') != null
    actionsStates[ACTION_LIKE] = buttons.like != null && document.querySelector('.icon_like_on') != null
    Nuvola.actions.updateEnabledFlags(actionsEnabled)
    Nuvola.actions.updateStates(actionsStates)

    // Schedule the next update
    setTimeout(this.update.bind(this), 500)
  }

  WebApp.getButtons = function () {
    var notDisabled = function (selector) {
      var elm = document.querySelector(selector)
      return (elm && !elm.classList.contains('player-controls__btn_disabled')) ? elm : null
    }
    var playPause = notDisabled('.player-controls__btn_play')
    return {
      prev: notDisabled('.player-controls__btn_prev'),
      play: playPause && playPause.classList.contains('player-controls__btn_pause') ? null : playPause,
      pause: playPause && playPause.classList.contains('player-controls__btn_pause') ? playPause : null,
      next: notDisabled('.player-controls__btn_next'),
      like: notDisabled('.player-controls__btn.like_player'),
      shuffle: document.querySelector('.player-controls__btn_shuffle')
    }
  }

// Handler of playback actions
  WebApp._onActionActivated = function (emitter, name, param) {
    var buttons = this.getButtons()
    switch (name) {
      case PlayerAction.TOGGLE_PLAY:
        if (buttons.play) {
          Nuvola.clickOnElement(buttons.play)
        } else if (buttons.pause) {
          Nuvola.clickOnElement(buttons.pause)
        }
        break
      case PlayerAction.PLAY:
        if (buttons.play) {
          Nuvola.clickOnElement(buttons.play)
        }
        break
      case PlayerAction.PAUSE:
      case PlayerAction.STOP:
        if (buttons.pause) {
          Nuvola.clickOnElement(buttons.pause)
        }
        break
      case PlayerAction.PREV_SONG:
        if (buttons.prev) {
          Nuvola.clickOnElement(buttons.prev)
        }
        break
      case PlayerAction.NEXT_SONG:
        if (buttons.next) {
          Nuvola.clickOnElement(buttons.next)
        }
        break
      case ACTION_LIKE:
        if (buttons.like) {
          Nuvola.clickOnElement(buttons.like)
        }
        break
      case PlayerAction.SHUFFLE:
        if (buttons.shuffle) {
          Nuvola.clickOnElement(buttons.shuffle)
        }
        break
    }
  }

  WebApp.start()
})(this)  // function(Nuvola)
<|endoftext|>


<commit_before>// Utility functions for JS test suite
// (c) 2001 Harri Porten <porten@kde.org>

function testPassed(msg)
{
  debug("PASS. " + msg);
}

function testFailed(msg)
{
  debug("FAIL. " + msg);
  if (this.regtest)
    regtest.reportResult(false, msg);
}

function description(s)
{
    debug(s);
}

function evalError(arg, ex)
{
    //return "eval('" + arg + "') => " + ex.toString();
    return ex.toString() + " [eval('" + arg + "')]";
}

function shouldBe(_a, _b)
{
  if (typeof _a != "string" || typeof _b != "string")
    debug("WARN: shouldBe() expects string arguments");
  var _av, _bv;
  try {
    _av = eval(_a);
  } catch (e) {
    _av = evalError(_a, e);
  }
  try {
    _bv = eval(_b);
  } catch (e) {
    _bv = evalError(_b, e);
  }

  if (_av === _bv)
    testPassed(_a + " is " + _b);
  else
    testFailed(_a + " should be " + _bv + ". Was " + _av);
}

function shouldBeTrue(_a) { shouldBe(_a, "true"); }

function shouldBeFalse(_a) { shouldBe(_a, "false"); }

function shouldBeUndefined(_a)
{
  var _av;
  try {
    _av = eval(_a);
  } catch (e) {
    _av = evalError(_a, e);
  }

  if (typeof _av == "undefined")
    testPassed(_a + " is undefined.");
  else
    testFailed(_a + " should be undefined. Was " + _av);
}

function shouldThrow(_a, _e)
{
  var exception;
  var _av;
  try {
     _av = eval(_a);
  } catch (e) {
     exception = e;
  }

  var _ev;
  if (_e)
      _ev =  eval(_e);

  if (exception) {
    if (typeof _e == "undefined" || exception == _ev)
      testPassed(_a + " threw exception " + exception + ".");
    else
      testFailed(_a + " should throw exception " + _ev + ". Threw exception " + exception + ".");
  } else if (typeof _av == "undefined")
    testFailed(_a + " should throw exception " + _e + ". Was undefined.");
  else
    testFailed(_a + " should throw exception " + _e + ". Was " + _av + ".");
}
<commit_msg>Added shouldExcept() function that works based on a function.<commit_after>// Utility functions for JS test suite
// (c) 2001 Harri Porten <porten@kde.org>
// (c) 2020 froglogic GmbH <contact@froglogic.com>

function testPassed(msg)
{
  debug("PASS. " + msg);
}

function testFailed(msg)
{
  debug("FAIL. " + msg);
  if (this.regtest)
    regtest.reportResult(false, msg);
}

function description(s)
{
    debug(s);
}

function evalError(arg, ex)
{
    //return "eval('" + arg + "') => " + ex.toString();
    return ex.toString() + " [eval('" + arg + "')]";
}

function shouldBe(_a, _b)
{
  if (typeof _a != "string" || typeof _b != "string")
    debug("WARN: shouldBe() expects string arguments");
  var _av, _bv;
  try {
    _av = eval(_a);
  } catch (e) {
    _av = evalError(_a, e);
  }
  try {
    _bv = eval(_b);
  } catch (e) {
    _bv = evalError(_b, e);
  }

  if (_av === _bv)
    testPassed(_a + " is " + _b);
  else
    testFailed(_a + " should be " + _bv + ". Was " + _av);
}

function shouldBeTrue(_a) { shouldBe(_a, "true"); }

function shouldBeFalse(_a) { shouldBe(_a, "false"); }

function shouldBeUndefined(_a)
{
  var _av;
  try {
    _av = eval(_a);
  } catch (e) {
    _av = evalError(_a, e);
  }

  if (typeof _av == "undefined")
    testPassed(_a + " is undefined.");
  else
    testFailed(_a + " should be undefined. Was " + _av);
}

function shouldThrow(_a, _e)
{
  var exception;
  var _av;
  try {
     _av = eval(_a);
  } catch (e) {
     exception = e;
  }

  var _ev;
  if (_e)
      _ev =  eval(_e);

  if (exception) {
    if (typeof _e == "undefined" || exception == _ev)
      testPassed(_a + " threw exception " + exception + ".");
    else
      testFailed(_a + " should throw exception " + _ev + ". Threw exception " + exception + ".");
  } else if (typeof _av == "undefined")
    testFailed(_a + " should throw exception " + _e + ". Was undefined.");
  else
    testFailed(_a + " should throw exception " + _e + ". Was " + _av + ".");
}

function shouldExcept(error, func, msg)
{
    var exception;
    try {
        func();
    } catch (e) {
        exception = e;
    }
    if (exception) {
        if (exception instanceof error) {
            test.pass(msg + ": got expected exception " + error.name);
        } else {
            test.fail(msg + ": got wrong exception. Name: " + error.name);
        }
    } else {
        test.fail(msg + ": function did not throw an exception");
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2015 Joel Cumberland <joel_c@zoho.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
"use strict";

(function(Nuvola)
{

    // Autoplay Setting
    var AUTO_PLAY = "app.autoplay";

    // Create media player component
    var player = Nuvola.$object(Nuvola.MediaPlayer);

    // Handy aliases
    var PlaybackState = Nuvola.PlaybackState;
    var PlayerAction = Nuvola.PlayerAction;

    // Create new WebApp prototype
    var WebApp = Nuvola.$WebApp();

    WebApp._onInitAppRunner = function(emitter)
    {
        Nuvola.WebApp._onInitAppRunner.call(this, emitter);

        Nuvola.config.setDefault(AUTO_PLAY, false);

        Nuvola.core.connect("PreferencesForm", this);

    }

    WebApp._onPreferencesForm = function(emitter, values, entries)
    {
        this.appendPreferences(values, entries);
    }

    WebApp.appendPreferences = function(values, entries)
    {
        values[AUTO_PLAY] = Nuvola.config.get(AUTO_PLAY);

        var _ = Nuvola.Translate.gettext;
        entries.push(["header", _("Groove Settings")]);
        entries.push(["bool", AUTO_PLAY, _("Enable autoplay songs on start-up")]);
    }

    // Initialization routines
    WebApp._onInitWebWorker = function(emitter)
    {
        Nuvola.WebApp._onInitWebWorker.call(this, emitter);

        var state = document.readyState;
        if (state === "interactive" || state === "complete")
            this._onPageReady();
        else
            document.addEventListener("DOMContentLoaded", this._onPageReady.bind(this));
    }

    // Page is ready for magic
    WebApp._onPageReady = function()
    {
        // Connect handler for signal ActionActivated
        Nuvola.actions.connect("ActionActivated", this);

        // Wait for groove player to load
        this.isGroovePlayerReady();
    }

    WebApp.isGroovePlayerReady = function()
    {
        if (playerInterface.getCurrent())
        {
            console.log(Nuvola.format('Groove Player [loaded]'));
            this.clickPlay = document.getElementsByClassName('iconPlayerPlay');
            this.clickPause = document.getElementsByClassName('iconPlayerPause');
            this.clickNext = document.getElementsByClassName('iconPlayerNext');
            this.clickPrevious = document.getElementsByClassName('iconPlayerPrevious');
            var maxVolume = document.getElementsByClassName('sliderButton iconPlayerSecondaryTrackCursor');

            Nuvola.config.get(AUTO_PLAY) ? this.clickPlay.item('click').click() : false;

            this.update();
        }
        else
        {
            setTimeout(this.isGroovePlayerReady.bind(this), 100);
        }
    }

    // Extract data from the web page
    WebApp.update = function()
    {
        try
        {

            var imgElement =
                document.getElementsByClassName('playerNowPlayingImg')[1].getElementsByTagName('img')[1];
            this.artistImg = imgElement.getAttribute('src');

            var artistElement =
                document.getElementsByClassName('playerNowPlayingMetadata')[1].getElementsByTagName('a')[1];
            this.artisTitle = artistElement.getAttribute('title');

            var songElement =
                document.getElementsByClassName('playerNowPlayingMetadata')[1].getElementsByTagName('a')[0];
            this.songTitle = songElement.getAttribute('title');

        }
        catch (e)
        {
            console.log(Nuvola.format('Error getting song info : {1}'), e);
        }

        var track = {
            title: this.songTitle,
            artist: this.artisTitle,
            album: null, //TODO : Find a way to get artist ablum info. jrosco/nuvola-app-groove/#2
            artLocation: this.artistImg
        }

        player.setTrack(track);

        var playEnabled = (this.clickPlay.length == 1) ? true : false;
        var pauseEnabled = (this.clickPause.length == 1) ? true : false;
        var nextEnabled = (this.clickNext.length == 1) ? true : false;
        var previousEnabled = (this.clickPrevious.length == 1) ? true : false;

        this.state = playEnabled ? PlaybackState.PAUSED :
            (pauseEnabled ? PlaybackState.PLAYING : PlaybackState.UNKNOWN);

        player.setPlaybackState(this.state);

        player.setCanPlay(playEnabled);
        player.setCanPause(pauseEnabled);
        player.setCanGoNext(nextEnabled);
        player.setCanGoPrev(previousEnabled);

        // Schedule the next update
        setTimeout(this.update.bind(this), 500);
    }

    // Handler of playback actions
    WebApp._onActionActivated = function(emitter, name, param)
    {

        try
        {
            switch (name)
            {
                case PlayerAction.PLAY:
                    this.clickPlay.item('click').click();
                    break;
                case PlayerAction.PAUSE:
                    this.clickPause.item('click').click();
                    break;
                case PlayerAction.TOGGLE_PLAY:
                    (this.state == PlaybackState.PLAYING) ? this.clickPause.item('click').click():
                        this.clickPlay.item('click').click();
                    break;
                case PlayerAction.PREV_SONG:
                    this.clickPrevious.item('click').click();
                    break;
                case PlayerAction.NEXT_SONG:
                    this.clickNext.item('click').click();
                    break;
                default:
                    // Other commands are not supported
                    throw {
                        'message': 'Not supported.'
                    };
            }
        }
        catch (e)
        {
            console.log(Nuvola.format('Play back error : {1}'), e);
        }
    }

    WebApp.start();

})(this); // function(Nuvola)
<commit_msg>fixed issue #5<commit_after>/*
 * Copyright 2015 Joel Cumberland <joel_c@zoho.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
"use strict";

(function(Nuvola)
{

    // Autoplay Setting
    var AUTO_PLAY = "app.autoplay";

    // Create media player component
    var player = Nuvola.$object(Nuvola.MediaPlayer);

    // Handy aliases
    var PlaybackState = Nuvola.PlaybackState;
    var PlayerAction = Nuvola.PlayerAction;

    // Create new WebApp prototype
    var WebApp = Nuvola.$WebApp();

    WebApp._onInitAppRunner = function(emitter)
    {
        Nuvola.WebApp._onInitAppRunner.call(this, emitter);

        Nuvola.config.setDefault(AUTO_PLAY, false);

        Nuvola.core.connect("PreferencesForm", this);

    }

    WebApp._onPreferencesForm = function(emitter, values, entries)
    {
        this.appendPreferences(values, entries);
    }

    WebApp.appendPreferences = function(values, entries)
    {
        values[AUTO_PLAY] = Nuvola.config.get(AUTO_PLAY);

        var _ = Nuvola.Translate.gettext;
        entries.push(["header", _("Groove Settings")]);
        entries.push(["bool", AUTO_PLAY, _("Enable autoplay songs on start-up")]);
    }

    // Initialization routines
    WebApp._onInitWebWorker = function(emitter)
    {
        Nuvola.WebApp._onInitWebWorker.call(this, emitter);

        var state = document.readyState;
        if (state === "interactive" || state === "complete")
            this._onPageReady();
        else
            document.addEventListener("DOMContentLoaded", this._onPageReady.bind(this));
    }

    // Page is ready for magic
    WebApp._onPageReady = function()
    {
        // Connect handler for signal ActionActivated
        Nuvola.actions.connect("ActionActivated", this);

        // Wait for groove player to load
        this.isGroovePlayerReady();
    }

    WebApp.isGroovePlayerReady = function()
    {
        if (window.playerInterface && playerInterface.getCurrent())
        {
            console.log(Nuvola.format('Groove Player [loaded]'));
            this.clickPlay = document.getElementsByClassName('iconPlayerPlay');
            this.clickPause = document.getElementsByClassName('iconPlayerPause');
            this.clickNext = document.getElementsByClassName('iconPlayerNext');
            this.clickPrevious = document.getElementsByClassName('iconPlayerPrevious');
            var maxVolume = document.getElementsByClassName('sliderButton iconPlayerSecondaryTrackCursor');

            Nuvola.config.get(AUTO_PLAY) ? this.clickPlay.item('click').click() : false;

            this.update();
        }
        else
        {
            setTimeout(this.isGroovePlayerReady.bind(this), 100);
        }
    }

    // Extract data from the web page
    WebApp.update = function()
    {
        try
        {

            var imgElement =
                document.getElementsByClassName('playerNowPlayingImg')[1].getElementsByTagName('img')[1];
            this.artistImg = imgElement.getAttribute('src');

            var artistElement =
                document.getElementsByClassName('playerNowPlayingMetadata')[1].getElementsByTagName('a')[1];
            this.artisTitle = artistElement.getAttribute('title');

            var songElement =
                document.getElementsByClassName('playerNowPlayingMetadata')[1].getElementsByTagName('a')[0];
            this.songTitle = songElement.getAttribute('title');

        }
        catch (e)
        {
            console.log(Nuvola.format('Error getting song info : {1}'), e);
        }

        var track = {
            title: this.songTitle,
            artist: this.artisTitle,
            album: null, //TODO : Find a way to get artist ablum info. jrosco/nuvola-app-groove/#2
            artLocation: this.artistImg
        }

        player.setTrack(track);

        var playEnabled = (this.clickPlay.length == 1) ? true : false;
        var pauseEnabled = (this.clickPause.length == 1) ? true : false;
        var nextEnabled = (this.clickNext.length == 1) ? true : false;
        var previousEnabled = (this.clickPrevious.length == 1) ? true : false;

        this.state = playEnabled ? PlaybackState.PAUSED :
            (pauseEnabled ? PlaybackState.PLAYING : PlaybackState.UNKNOWN);

        player.setPlaybackState(this.state);

        player.setCanPlay(playEnabled);
        player.setCanPause(pauseEnabled);
        player.setCanGoNext(nextEnabled);
        player.setCanGoPrev(previousEnabled);

        // Schedule the next update
        setTimeout(this.update.bind(this), 500);
    }

    // Handler of playback actions
    WebApp._onActionActivated = function(emitter, name, param)
    {

        try
        {
            switch (name)
            {
                case PlayerAction.PLAY:
                    this.clickPlay.item('click').click();
                    break;
                case PlayerAction.PAUSE:
                    this.clickPause.item('click').click();
                    break;
                case PlayerAction.TOGGLE_PLAY:
                    (this.state == PlaybackState.PLAYING) ? this.clickPause.item('click').click():
                        this.clickPlay.item('click').click();
                    break;
                case PlayerAction.PREV_SONG:
                    this.clickPrevious.item('click').click();
                    break;
                case PlayerAction.NEXT_SONG:
                    this.clickNext.item('click').click();
                    break;
                default:
                    // Other commands are not supported
                    throw {
                        'message': 'Not supported.'
                    };
            }
        }
        catch (e)
        {
            console.log(Nuvola.format('Play back error : {1}'), e);
        }
    }

    WebApp.start();

})(this); // function(Nuvola)
<|endoftext|>


<commit_before>/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/

/* jshint jasmine: true */
/* global CaptureAudioOptions, CaptureImageOptions, CaptureVideoOptions, CaptureError */
/* global Media, MediaFile, MediaFileData, resolveLocalFileSystemURL */

exports.defineAutoTests = function () {
    describe('Capture (navigator.device.capture)', function () {
        it("capture.spec.1 should exist", function () {
            expect(navigator.device).toBeDefined();
            expect(navigator.device.capture).toBeDefined();
        });

        it("capture.spec.2 should have the correct properties ", function () {
            expect(navigator.device.capture.supportedAudioModes).toBeDefined();
            expect(navigator.device.capture.supportedImageModes).toBeDefined();
            expect(navigator.device.capture.supportedVideoModes).toBeDefined();
        });

        it("capture.spec.3 should contain a captureAudio function", function () {
            expect(navigator.device.capture.captureAudio).toBeDefined();
            expect(typeof navigator.device.capture.captureAudio == 'function').toBe(true);
        });

        it("capture.spec.4 should contain a captureImage function", function () {
            expect(navigator.device.capture.captureImage).toBeDefined();
            expect(typeof navigator.device.capture.captureImage == 'function').toBe(true);
        });

        it("capture.spec.5 should contain a captureVideo function", function () {
            expect(navigator.device.capture.captureVideo).toBeDefined();
            expect(typeof navigator.device.capture.captureVideo == 'function').toBe(true);
        });

        describe('CaptureAudioOptions', function () {
            it("capture.spec.6 CaptureAudioOptions constructor should exist", function () {
                var options = new CaptureAudioOptions();
                expect(options).toBeDefined();
                expect(options.limit).toBeDefined();
                expect(options.duration).toBeDefined();
            });
        });

        describe('CaptureImageOptions', function () {
            it("capture.spec.7 CaptureImageOptions constructor should exist", function () {
                var options = new CaptureImageOptions();
                expect(options).toBeDefined();
                expect(options.limit).toBeDefined();
            });
        });

        describe('CaptureVideoOptions', function () {
            it("capture.spec.8 CaptureVideoOptions constructor should exist", function () {
                var options = new CaptureVideoOptions();
                expect(options).toBeDefined();
                expect(options.limit).toBeDefined();
                expect(options.duration).toBeDefined();
            });
        });

        describe('CaptureError interface', function () {
            it("capture.spec.9 CaptureError constants should be defined", function () {
                expect(CaptureError.CAPTURE_INTERNAL_ERR).toBe(0);
                expect(CaptureError.CAPTURE_APPLICATION_BUSY).toBe(1);
                expect(CaptureError.CAPTURE_INVALID_ARGUMENT).toBe(2);
                expect(CaptureError.CAPTURE_NO_MEDIA_FILES).toBe(3);
            });

            it("capture.spec.10 CaptureError properties should exist", function () {
                var error = new CaptureError();
                expect(error).toBeDefined();
                expect(error.code).toBeDefined();
            });
        });

        describe('MediaFileData', function () {
            it("capture.spec.11 MediaFileData constructor should exist", function () {
                var fileData = new MediaFileData();
                expect(fileData).toBeDefined();
                expect(fileData.bitrate).toBeDefined();
                expect(fileData.codecs).toBeDefined();
                expect(fileData.duration).toBeDefined();
                expect(fileData.height).toBeDefined();
                expect(fileData.width).toBeDefined();
            });
        });

        describe('MediaFile', function () {
            it("capture.spec.12 MediaFile constructor should exist", function () {
                var fileData = new MediaFile();
                expect(fileData).toBeDefined();
                expect(fileData.name).toBeDefined();
                expect(fileData.type).toBeDefined();
                expect(fileData.lastModifiedDate).toBeDefined();
                expect(fileData.size).toBeDefined();
            });
        });
    });
};

/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

exports.defineManualTests = function (contentEl, createActionButton) {
    var pageStartTime = +new Date();

    function log(value) {
        document.getElementById('camera_status').textContent += (new Date() - pageStartTime) / 1000 + ': ' + value + '\n';
        console.log(value);
    }

    function captureAudioWin(mediaFiles) {
        var path = mediaFiles[0].fullPath;
        log('Audio captured: ' + path);
        var m = new Media(path);
        m.play();
    }

    function captureAudioFail(e) {
        log('Error getting audio: ' + e.code);
    }

    function getAudio() {
        clearStatus();
        var options = { limit: 1, duration: 10 };
        navigator.device.capture.captureAudio(captureAudioWin, captureAudioFail, options);
    }

    function captureImageWin(mediaFiles) {
        var path = mediaFiles[0].fullPath;
        // Necessary since windows doesn't allow file URLs for  elements
        if (cordova.platformId == 'windows' || cordova.platformId == 'windows8' || cordova.platformId === 'browser') {
            path = mediaFiles[0].localURL;
        }
        log('Image captured: ' + path);
        document.getElementById('camera_image').src = path;
    }

    function captureImageFail(e) {
        log('Error getting image: ' + e.code);
    }

    function getImage() {
        clearStatus();
        var options = { limit: 1 };
        navigator.device.capture.captureImage(captureImageWin, captureImageFail, options);
    }

    function captureVideoWin(mediaFiles) {
        var path = mediaFiles[0].fullPath;
        log('Video captured: ' + path);

        // need to inject the video element into the html
        // doesn't seem to work if you have a pre-existing video element and
        // add in a source tag
        var vid = document.createElement('video');
        vid.id = "theVideo";
        vid.width = "320";
        vid.height = "240";
        vid.controls = "true";
        var source_vid = document.createElement('source');
        source_vid.id = "theSource";
        source_vid.src = path;
        vid.appendChild(source_vid);
        document.getElementById('video_container').appendChild(vid);
    }

    function captureVideoFail(e) {
        log('Error getting video: ' + e.code);
    }

    function getVideo() {
        clearStatus();
        var options = { limit: 1, duration: 10 };
        navigator.device.capture.captureVideo(captureVideoWin, captureVideoFail, options);
    }

    function resolveMediaFileURL(mediaFile, callback) {
        resolveLocalFileSystemURL(mediaFile.localURL, function (entry) {
            log("Resolved by URL: " + mediaFile.localURL);
            if (callback) callback();
        }, function (err) {
            log("Failed to resolve by URL: " + mediaFile.localURL);
            log("Error: " + JSON.stringify(err));
            if (callback) callback();
        });
    }

    function resolveMediaFile(mediaFile, callback) {
        resolveLocalFileSystemURL(mediaFile.fullPath, function (entry) {
            log("Resolved by path: " + mediaFile.fullPath);
            if (callback) callback();
        }, function (err) {
            log("Failed to resolve by path: " + mediaFile.fullPath);
            log("Error: " + JSON.stringify(err));
            if (callback) callback();
        });
    }

    function resolveVideo() {
        clearStatus();
        var options = { limit: 1, duration: 5 };
        navigator.device.capture.captureVideo(function (mediaFiles) {
            captureVideoWin(mediaFiles);
            resolveMediaFile(mediaFiles[0], function () {
                resolveMediaFileURL(mediaFiles[0]);
            });
        }, captureVideoFail, options);
    }

    function clearStatus() {
        document.getElementById('camera_status').innerHTML = '';
        document.getElementById('camera_image').src = 'about:blank';
    }

    /******************************************************************************/

    contentEl.innerHTML = '
' +
        'Status:

' +
        'img: ' +
        'video:

' +
        '

' +
        'Expected result: Audio recorder will come up. Press record button to record for 10 seconds. Press Done. Status box will update with audio file and automatically play recording.' +
        '

' +
        'Expected result: Status box will update with image just taken.' +
        '

' +
        'Expected result: Record 10 second video. Status box will update with video file that you can play.' +
        '

' +
        'Expected result: Record 5 second video. Status box will show that URL was resolved and video will get added at the bottom of the status box for playback.';

    createActionButton('Capture 10 sec of audio and play', function () {
        getAudio();
    }, 'audio');

    createActionButton('Capture 1 image', function () {
        getImage();
    }, 'image');

    createActionButton('Capture 10 sec of video', function () {
        getVideo();
    }, 'video');

    createActionButton('Capture 5 sec of video and resolve', function () {
        resolveVideo();
    }, 'video_and_resolve');
};
<commit_msg>CB-11996 Added a new manual test to capture multiple images<commit_after>/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/

/* jshint jasmine: true */
/* global CaptureAudioOptions, CaptureImageOptions, CaptureVideoOptions, CaptureError */
/* global Media, MediaFile, MediaFileData, resolveLocalFileSystemURL */

exports.defineAutoTests = function () {
    describe('Capture (navigator.device.capture)', function () {
        it("capture.spec.1 should exist", function () {
            expect(navigator.device).toBeDefined();
            expect(navigator.device.capture).toBeDefined();
        });

        it("capture.spec.2 should have the correct properties ", function () {
            expect(navigator.device.capture.supportedAudioModes).toBeDefined();
            expect(navigator.device.capture.supportedImageModes).toBeDefined();
            expect(navigator.device.capture.supportedVideoModes).toBeDefined();
        });

        it("capture.spec.3 should contain a captureAudio function", function () {
            expect(navigator.device.capture.captureAudio).toBeDefined();
            expect(typeof navigator.device.capture.captureAudio == 'function').toBe(true);
        });

        it("capture.spec.4 should contain a captureImage function", function () {
            expect(navigator.device.capture.captureImage).toBeDefined();
            expect(typeof navigator.device.capture.captureImage == 'function').toBe(true);
        });

        it("capture.spec.5 should contain a captureVideo function", function () {
            expect(navigator.device.capture.captureVideo).toBeDefined();
            expect(typeof navigator.device.capture.captureVideo == 'function').toBe(true);
        });

        describe('CaptureAudioOptions', function () {
            it("capture.spec.6 CaptureAudioOptions constructor should exist", function () {
                var options = new CaptureAudioOptions();
                expect(options).toBeDefined();
                expect(options.limit).toBeDefined();
                expect(options.duration).toBeDefined();
            });
        });

        describe('CaptureImageOptions', function () {
            it("capture.spec.7 CaptureImageOptions constructor should exist", function () {
                var options = new CaptureImageOptions();
                expect(options).toBeDefined();
                expect(options.limit).toBeDefined();
            });
        });

        describe('CaptureVideoOptions', function () {
            it("capture.spec.8 CaptureVideoOptions constructor should exist", function () {
                var options = new CaptureVideoOptions();
                expect(options).toBeDefined();
                expect(options.limit).toBeDefined();
                expect(options.duration).toBeDefined();
            });
        });

        describe('CaptureError interface', function () {
            it("capture.spec.9 CaptureError constants should be defined", function () {
                expect(CaptureError.CAPTURE_INTERNAL_ERR).toBe(0);
                expect(CaptureError.CAPTURE_APPLICATION_BUSY).toBe(1);
                expect(CaptureError.CAPTURE_INVALID_ARGUMENT).toBe(2);
                expect(CaptureError.CAPTURE_NO_MEDIA_FILES).toBe(3);
            });

            it("capture.spec.10 CaptureError properties should exist", function () {
                var error = new CaptureError();
                expect(error).toBeDefined();
                expect(error.code).toBeDefined();
            });
        });

        describe('MediaFileData', function () {
            it("capture.spec.11 MediaFileData constructor should exist", function () {
                var fileData = new MediaFileData();
                expect(fileData).toBeDefined();
                expect(fileData.bitrate).toBeDefined();
                expect(fileData.codecs).toBeDefined();
                expect(fileData.duration).toBeDefined();
                expect(fileData.height).toBeDefined();
                expect(fileData.width).toBeDefined();
            });
        });

        describe('MediaFile', function () {
            it("capture.spec.12 MediaFile constructor should exist", function () {
                var fileData = new MediaFile();
                expect(fileData).toBeDefined();
                expect(fileData.name).toBeDefined();
                expect(fileData.type).toBeDefined();
                expect(fileData.lastModifiedDate).toBeDefined();
                expect(fileData.size).toBeDefined();
            });
        });
    });
};

/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

exports.defineManualTests = function (contentEl, createActionButton) {
    var pageStartTime = +new Date();

    function log(value) {
        document.getElementById('camera_status').textContent += (new Date() - pageStartTime) / 1000 + ': ' + value + '\n';
        console.log(value);
    }

    function captureAudioWin(mediaFiles) {
        var path = mediaFiles[0].fullPath;
        log('Audio captured: ' + path);
        var m = new Media(path);
        m.play();
    }

    function captureAudioFail(e) {
        log('Error getting audio: ' + e.code);
    }

    function getAudio() {
        clearStatus();
        var options = { limit: 1, duration: 10 };
        navigator.device.capture.captureAudio(captureAudioWin, captureAudioFail, options);
    }

    function captureImageWin(mediaFiles) {
        var path = mediaFiles[0].fullPath;
        // Necessary since windows doesn't allow file URLs for  elements
        if (cordova.platformId == 'windows' || cordova.platformId == 'windows8' || cordova.platformId === 'browser') {
            path = mediaFiles[0].localURL;
        }
        log('Image captured: ' + path);
        document.getElementById('camera_image').src = path;
    }

    function captureImagesWin(mediaFiles) {
        var path = mediaFiles[0].fullPath;
        // Necessary since windows doesn't allow file URLs for  elements
        if (cordova.platformId == 'windows' || cordova.platformId == 'windows8' || cordova.platformId === 'browser') {
            path = mediaFiles[0].localURL;
        }
        var path2 = mediaFiles[1].fullPath;
        // Necessary since windows doesn't allow file URLs for  elements
        if (cordova.platformId == 'windows' || cordova.platformId == 'windows8' || cordova.platformId === 'browser') {
            path = mediaFiles[1].localURL;
        }
        var path3 = mediaFiles[2].fullPath;
        // Necessary since windows doesn't allow file URLs for  elements
        if (cordova.platformId == 'windows' || cordova.platformId == 'windows8' || cordova.platformId === 'browser') {
            path = mediaFiles[2].localURL;
        }
        log('Image captured: ' + path);
        log('Image captured: ' + path2);
        log('Image captured: ' + path3);
        document.getElementById('camera_image').src = path;
        document.getElementById('camera_image2').src = path2;
        document.getElementById('camera_image3').src = path3;
    }

    function captureImageFail(e) {
        log('Error getting image: ' + e.code);
    }

    function getImage() {
        clearStatus();
        var options = { limit: 1 };
        navigator.device.capture.captureImage(captureImageWin, captureImageFail, options);
    }

    function getImages() {
        clearStatus();
        var options = { limit: 3 };
        navigator.device.capture.captureImage(captureImagesWin, captureImageFail, options);
    }

    function captureVideoWin(mediaFiles) {
        var path = mediaFiles[0].fullPath;
        log('Video captured: ' + path);

        // need to inject the video element into the html
        // doesn't seem to work if you have a pre-existing video element and
        // add in a source tag
        var vid = document.createElement('video');
        vid.id = "theVideo";
        vid.width = "320";
        vid.height = "240";
        vid.controls = "true";
        var source_vid = document.createElement('source');
        source_vid.id = "theSource";
        source_vid.src = path;
        vid.appendChild(source_vid);
        document.getElementById('video_container').appendChild(vid);
    }

    function captureVideoFail(e) {
        log('Error getting video: ' + e.code);
    }

    function getVideo() {
        clearStatus();
        var options = { limit: 1, duration: 10 };
        navigator.device.capture.captureVideo(captureVideoWin, captureVideoFail, options);
    }

    function resolveMediaFileURL(mediaFile, callback) {
        resolveLocalFileSystemURL(mediaFile.localURL, function (entry) {
            log("Resolved by URL: " + mediaFile.localURL);
            if (callback) callback();
        }, function (err) {
            log("Failed to resolve by URL: " + mediaFile.localURL);
            log("Error: " + JSON.stringify(err));
            if (callback) callback();
        });
    }

    function resolveMediaFile(mediaFile, callback) {
        resolveLocalFileSystemURL(mediaFile.fullPath, function (entry) {
            log("Resolved by path: " + mediaFile.fullPath);
            if (callback) callback();
        }, function (err) {
            log("Failed to resolve by path: " + mediaFile.fullPath);
            log("Error: " + JSON.stringify(err));
            if (callback) callback();
        });
    }

    function resolveVideo() {
        clearStatus();
        var options = { limit: 1, duration: 5 };
        navigator.device.capture.captureVideo(function (mediaFiles) {
            captureVideoWin(mediaFiles);
            resolveMediaFile(mediaFiles[0], function () {
                resolveMediaFileURL(mediaFiles[0]);
            });
        }, captureVideoFail, options);
    }

    function clearStatus() {
        document.getElementById('camera_status').innerHTML = '';
        document.getElementById('camera_image').src = 'about:blank';
        document.getElementById('camera_image2').src = 'about:blank';
        document.getElementById('camera_image3').src = 'about:blank';
    }

    /******************************************************************************/

    contentEl.innerHTML = '
' +
        'Status:

' +
        'img1: ' +
        'img2: ' +
        'img3: ' +
        'video:

' +
        '

' +
        'Expected result: Audio recorder will come up. Press record button to record for 10 seconds. Press Done. Status box will update with audio file and automatically play recording.' +
        '

' +
        'Expected result: Status box will update with image just taken.' +
        '

' +
        'Expected result: Status box will update with images just taken.' +
        '

' +
        'Expected result: Record 10 second video. Status box will update with video file that you can play.' +
        '

' +
        'Expected result: Record 5 second video. Status box will show that URL was resolved and video will get added at the bottom of the status box for playback.';

    createActionButton('Capture 10 sec of audio and play', function () {
        getAudio();
    }, 'audio');

    createActionButton('Capture 1 image', function () {
        getImage();
    }, 'image');

    createActionButton('Capture 3 images', function () {
        getImages();
    }, 'images');

    createActionButton('Capture 10 sec of video', function () {
        getVideo();
    }, 'video');

    createActionButton('Capture 5 sec of video and resolve', function () {
        resolveVideo();
    }, 'video_and_resolve');
};
<|endoftext|>


<commit_before>exports.defineAutoTests = function() {
  describe('Bridge plugin (cordova.plugins.bridge)', function() {
    it('should exist', function() {
      expect(window.cordova.plugins.bridge).toBeDefined();
    });
  });

  describe('Open method (cordova.plugins.bridge.open)', function() {
    it('should exist', function() {
      expect(window.cordova.plugins.bridge.open).toBeDefined();
    });

    it('should return false if run with no arguments', function() {
      expect(window.cordova.plugins.bridge.open()).toBe(false);
    });
  });
};

exports.defineManualTests = function(contentEl, createActionButton) {
  var logMessage,
      clearLog,
      testInfo;

  logMessage = function(message, color) {
      var log = document.getElementById('info'),
          logLine = document.createElement('div');
      if (color) {
        logLine.style.color = color;
      }
      logLine.innerHTML = message;
      log.appendChild(logLine);
    };

  clearLog = function() {
    var log = document.getElementById('info');
    log.innerHTML = '';
  };

  testInfo = '
Press Open File and a test file will open in a native context
' +
      '

' +
      'Expected result: File will open in native modal.';

  contentEl.innerHTML = testInfo;

  function success() {
    clearLog();
    logMessage('Success');
  }

  function error(code) {
    clearLog();
    if (code === 1) {
      logMessage('No file handler found');
    } else {
      logMessage('Undefined error');
    }
  }

  function downloadAndOpen(fileUrl, directory) {
    var dir = directory || 'externalCacheDirectory';
    document.addEventListener('deviceready', onDeviceReady, false);
    function onDeviceReady() {
      var ft = new FileTransfer(),
          url = fileUrl,
          filename = url.substring(url.lastIndexOf('/') + 1),
          uri = encodeURI(url),
          path = cordova.file[dir] + filename;

      ft.download(uri, path,
          function done(entry) {
            cordova.plugins.bridge.open(entry.toURL(), success, error);
          },
          function fail(error) {
            console.log('download error', error);
          },
          false
      );
    }
  }

  createActionButton('Open Image', function() {
    downloadAndOpen('http://cordova.apache.org/images/logo_full.png');
  }, 'open-file');
};
<commit_msg>Remove superfluous logger<commit_after>exports.defineAutoTests = function() {
  describe('Bridge plugin (cordova.plugins.bridge)', function() {
    it('should exist', function() {
      expect(window.cordova.plugins.bridge).toBeDefined();
    });
  });

  describe('Open method (cordova.plugins.bridge.open)', function() {
    it('should exist', function() {
      expect(window.cordova.plugins.bridge.open).toBeDefined();
    });

    it('should return false if run with no arguments', function() {
      expect(window.cordova.plugins.bridge.open()).toBe(false);
    });
  });
};

exports.defineManualTests = function(contentEl, createActionButton) {
  var testInfo;

  testInfo = '
Press Open File and a test file will open in a native context
' +
      '

' +
      'Expected result: File will open in native modal.';

  contentEl.innerHTML = testInfo;

  function success() {
    console.log('Successfully opened file!');
  }

  function error(code) {
    if (code === 1) {
      console.log('No file handler found');
    } else {
      console.log('Undefined error');
    }
  }

  function downloadAndOpen(fileUrl, directory) {
    var dir = directory || 'externalCacheDirectory';
    document.addEventListener('deviceready', onDeviceReady, false);
    function onDeviceReady() {
      var ft = new FileTransfer(),
          url = fileUrl,
          filename = url.substring(url.lastIndexOf('/') + 1),
          uri = encodeURI(url),
          path = cordova.file[dir] + filename;

      ft.download(uri, path,
          function done(entry) {
            cordova.plugins.bridge.open(entry.toURL(), success, error);
          },
          function fail(error) {
            console.log('download error', error);
          },
          false
      );
    }
  }

  createActionButton('Open Image', function() {
    downloadAndOpen('http://cordova.apache.org/images/logo_full.png');
  }, 'open-file');
};
<|endoftext|>


<commit_before>module("general", {
    teardown: function() {
        $('#hulk').html('')
    }
});

var d = {
  'blah': {
    'bab': 'c',
    'bags': 782.3
  },
  'foo': 'bar'
};

//test("test dictionary", function() {
    //$.hulk('#hulk', d);
    //var e = $.hulkSmash('#hulk');
    //ok(compare(d, e), "original dict was " + JSON.stringify(d) + "output was" + JSON.stringify(e));
//});

//test("updating an element should update the resulting value", function() {
    //var map = $.hulk('#hulk', d);
    //var bar = map.find('.hulk-map-value').last();
    //bar.val('new-value');
    //var e = $.hulkSmash('#hulk');
    //ok(e['foo'] === 'new-value', "value should be new-value, instead it is " + e['foo']);
//});

//module("specification", {
    //teardown: function() {
        //$('#hulk').html('')
    //}
//});

//test("can handle bare strings", function() {
    //$.hulk('#hulk', 'a string');
    //var e = $.hulkSmash('#hulk');
    //ok(e === 'a string', "expected \"a string\" but got " + JSON.stringify(e));
//});

//test("ints are back to ints", function() {
    //$.hulk('#hulk', 5);
    //var e = $.hulkSmash('#hulk');
    //ok(e === 5, "expected 5 but got " + JSON.stringify(e));
//});

//test("booleans work", function() {
    //$.hulk('#hulk', true);
    //var e = $.hulkSmash('#hulk');
    //ok(e === true, "expected true but got " + JSON.stringify(e));
//});

//test("null works", function() {
    //$.hulk('#hulk', null);
    //var e = $.hulkSmash('#hulk');
    //ok(e === null, "expected null but got " + JSON.stringify(e));
//});

//test("an empty string returns null", function() {
    //$.hulk('#hulk', "");
    //var e = $.hulkSmash('#hulk');
    //ok(e === null, "expected null but got " + JSON.stringify(e));
//});

//test("an empty dict is still empty", function() {
    //$.hulk('#hulk', {});
    //var e = $.hulkSmash('#hulk');
    //ok(compare(e, {}), "expected {} but got " + JSON.stringify(e));
//});

//test("an empty list is returned", function() {
    //$.hulk('#hulk', []);
    //var e = $.hulkSmash('#hulk');
    //ok(compare(e, []), "expected an empty list [] but got " + JSON.stringify(e));
//});

//test("test a list with items", function() {
    //var array = ["foo", 8, null, "seven", true];
    //$.hulk('#hulk', array);
    //var e = $.hulkSmash('#hulk');
    //ok(compare(e, array), "expected the list " + JSON.stringify(array) +
        //" but got " + JSON.stringify(e));
//});

//test("a nested list", function() {
    //var array = ["foo", ["blah", 8, 22.4], true];
    //$.hulk('#hulk', array);
    //var e = $.hulkSmash('#hulk');
    //ok(compare(e, array), "expected the list " + JSON.stringify(array) +
        //" but got " + JSON.stringify(e));
//});

//test("nest lists and dictionaries", function() {
    //var object = {"b": "c", "foo": ["blah", 8, 22.4, {"a": "b"}], "keybar": [] };
    //$.hulk('#hulk', object);
    //var e = $.hulkSmash('#hulk');
    //ok(compare(e, object), "expected the list " + JSON.stringify(object) +
        //" but got " + JSON.stringify(e));
//});

test("empty string option", function() {
    var object = {"b": "", "c": null };
    $.hulk('#hulk', object);
    console.log("empty string true");
    var e = $.hulkSmash('#hulk', {emptyString: true});
    var expectedResult = {"b": "", "c": ""};
    ok(compare(e, expectedResult), "expected the object " +
        JSON.stringify(expectedResult) + " but got " + JSON.stringify(e));
});

compare = function(a, b) {
    return JSON.stringify(a) === JSON.stringify(b);
}

<commit_msg>oops, uncomment the tests<commit_after>module("general", {
    teardown: function() {
        $('#hulk').html('')
    }
});

var d = {
  'blah': {
    'bab': 'c',
    'bags': 782.3
  },
  'foo': 'bar'
};

test("test dictionary", function() {
    $.hulk('#hulk', d);
    var e = $.hulkSmash('#hulk');
    ok(compare(d, e), "original dict was " + JSON.stringify(d) + "output was" + JSON.stringify(e));
});

test("updating an element should update the resulting value", function() {
    var map = $.hulk('#hulk', d);
    var bar = map.find('.hulk-map-value').last();
    bar.val('new-value');
    var e = $.hulkSmash('#hulk');
    ok(e['foo'] === 'new-value', "value should be new-value, instead it is " + e['foo']);
});

module("specification", {
    teardown: function() {
        $('#hulk').html('')
    }
});

test("can handle bare strings", function() {
    $.hulk('#hulk', 'a string');
    var e = $.hulkSmash('#hulk');
    ok(e === 'a string', "expected \"a string\" but got " + JSON.stringify(e));
});

test("ints are back to ints", function() {
    $.hulk('#hulk', 5);
    var e = $.hulkSmash('#hulk');
    ok(e === 5, "expected 5 but got " + JSON.stringify(e));
});

test("booleans work", function() {
    $.hulk('#hulk', true);
    var e = $.hulkSmash('#hulk');
    ok(e === true, "expected true but got " + JSON.stringify(e));
});

test("null works", function() {
    $.hulk('#hulk', null);
    var e = $.hulkSmash('#hulk');
    ok(e === null, "expected null but got " + JSON.stringify(e));
});

test("an empty string returns null", function() {
    $.hulk('#hulk', "");
    var e = $.hulkSmash('#hulk');
    ok(e === null, "expected null but got " + JSON.stringify(e));
});

test("an empty dict is still empty", function() {
    $.hulk('#hulk', {});
    var e = $.hulkSmash('#hulk');
    ok(compare(e, {}), "expected {} but got " + JSON.stringify(e));
});

test("an empty list is returned", function() {
    $.hulk('#hulk', []);
    var e = $.hulkSmash('#hulk');
    ok(compare(e, []), "expected an empty list [] but got " + JSON.stringify(e));
});

test("test a list with items", function() {
    var array = ["foo", 8, null, "seven", true];
    $.hulk('#hulk', array);
    var e = $.hulkSmash('#hulk');
    ok(compare(e, array), "expected the list " + JSON.stringify(array) +
        " but got " + JSON.stringify(e));
});

test("a nested list", function() {
    var array = ["foo", ["blah", 8, 22.4], true];
    $.hulk('#hulk', array);
    var e = $.hulkSmash('#hulk');
    ok(compare(e, array), "expected the list " + JSON.stringify(array) +
        " but got " + JSON.stringify(e));
});

test("nest lists and dictionaries", function() {
    var object = {"b": "c", "foo": ["blah", 8, 22.4, {"a": "b"}], "keybar": [] };
    $.hulk('#hulk', object);
    var e = $.hulkSmash('#hulk');
    ok(compare(e, object), "expected the list " + JSON.stringify(object) +
        " but got " + JSON.stringify(e));
});

test("empty string option", function() {
    var object = {"b": "", "c": null };
    $.hulk('#hulk', object);
    console.log("empty string true");
    var e = $.hulkSmash('#hulk', {emptyString: true});
    var expectedResult = {"b": "", "c": ""};
    ok(compare(e, expectedResult), "expected the object " +
        JSON.stringify(expectedResult) + " but got " + JSON.stringify(e));
});

compare = function(a, b) {
    return JSON.stringify(a) === JSON.stringify(b);
}

<|endoftext|>


<commit_before>  var myApp = require('../app/library.js');

describe("Fizz Buzz tests", function() {

  it("should return `Fizz` for number divisible by 3", function() {
    expect(myApp.fizzBuzz(3)).toBe('Fizz');
  });

  it("should return `Buzz` for number divisible by 5", function() {
    expect(myApp.fizzBuzz(5)).toBe('Buzz');
  });

  it("should return `FizzBuzz` for 15", function() {
    expect(myApp.fizzBuzz(15)).toBe('FizzBuzz');
  });

  it("should return `FizzBuzz` for 45", function() {
    expect(myApp.fizzBuzz(45)).toBe('FizzBuzz');
  });

  it("should return `FizzBuzz` for 90", function() {
    expect(myApp.fizzBuzz(90)).toBe('FizzBuzz');
  });

  it("should return `Fizz` for 63", function() {
    expect(myApp.fizzBuzz(63)).toBe('Fizz');
  });

  it("should return 7 since its indivisible by 3 and 5", function() {
    expect(myApp.fizzBuzz(7)).toBe(7);
  });

  it("should return 101 since its indivisible by 3 and 5", function() {
    expect(myApp.fizzBuzz(101)).toBe(101);
  });

});

<commit_msg>just commited it<commit_after>  var myApp = require('../app/library.js');

describe("Fizz Buzz tests", function() {

  it("should return `Fizz` for number divisible by 3", function() {
    expect(myApp.fizzBuzz(3)).toBe('Fizz');
  });

  it("should return `Buzz` for number divisible by 5", function() {
    expect(myApp.fizzBuzz(5)).toBe('Buzz');
  });

  it("should return `FizzBuzz` for 15", function() {
    expect(myApp.fizzBuzz(15)).toBe('FizzBuzz');
  });

  it("should return `FizzBuzz` for 45", function() {
    expect(myApp.fizzBuzz(45)).toBe('FizzBuzz');
  });

  it("should return `FizzBuzz` for 90", function() {
    expect(myApp.fizzBuzz(90)).toBe('FizzBuzz');
  });

  it("should return `Fizz` for 63", function() {
    expect(myApp.fizzBuzz(63)).toBe('Fizz');
  });

  it("should return 7 since its indivisible by 3 and 5", function() {
    expect(myApp.fizzBuzz(7)).toBe(7);
  });
   it("should return 0  for 0", function() {
    expect(myApp.fizzBuzz(0)).toBe(0);
  });

  it("should return 101 since its indivisible by 3 and 5", function() {
    expect(myApp.fizzBuzz(101)).toBe(101);
  });

});

<|endoftext|>


<commit_before>/*
 * Rushed ugly code by <thomasalwyndavis@gmail.com>
 */

var cors = require('cors');
var express = require('express');
var MongoClient = require('mongodb').MongoClient;
var request = require('superagent');

var email = require('./email.js');

var PORT = process.env.PORT || 8080;

var TEMPLATES = {
  emails: 'domestic',
  signatures: 'international'
};

var collections = {};

var whitelist = [
  'http://dev.stopwatching.us',
  'http://rally.stopwatching.us',
  'http://2.stopwatching.us',
  'http://localhost:4000',
  'https://dev.stopwatching.us',
  'https://rally.stopwatching.us',
  'https://2.stopwatching.us',
  'https://localhost:4000',
  'https://thedaywefightback.org',
  'http://thedaywefightback.org',
  'https://thedaywefightback.org/',
  'http://thedaywefightback.org/',
  'http://dznh7un1y2etk.cloudfront.net',
  'http://tfrce.github.io',
  'http://localhost'
];

var corsOptions = {
  origin: function (origin, cb) {
    console.log(origin, 'origin');
    cb(null, whitelist.indexOf(origin) !== -1);
  }
};

var app = express();

app.use(express.urlencoded());
app.use(express.json());

app.use('/fonts', express.static(__dirname + '/fonts'));
app.use('/xdm', express.static(__dirname + '/xdm'));

app.use(cors(corsOptions));

app.options("*", cors(corsOptions));

app.get('/count', function (req, res) {
  res.setHeader("Expires", new Date(Date.now() + 1 * 60 * 1000).toUTCString());

  collections.resetthenet.count(function (err, count) {
    res.jsonp({ count: count });
  });
});

app.get('/', function (req, res) {
  res.jsonp({
    message: 'Welcome to an email tool, currently configured for resetthenet'
  });
});
/*
app.get('/time', function (req, res) {
  res.setHeader("Expires", new Date(Date.now() + 1 * 180 * 1000).toUTCString());

  var targetTime = new Date(Date.now());
  var timeZoneFromDB = -5.00; //time zone value from database

  //get the timezone offset from local time in minutes
  var tzDifference = timeZoneFromDB * 60;

  //convert the offset to milliseconds, add to targetTime, and make a new Date
  var offsetTime = new Date(targetTime.getTime() + tzDifference * 60 * 1000);
  var days = 11 - offsetTime.getDate();

  res.jsonp({
    days: days,
    thedaywefightback: false,
    est: offsetTime,
    utc: new Date(Date.now())
  });
});*/

function addEmail(collection, data, cb) {
  collections[collection].insert(data, function (err) {
    if (err) {
      return cb(err);
    }
    cb();
    /*email.send(TEMPLATES[collection], data.email, data, function (err) {
      if (err) {
        return cb(err);
      }

      cb();
    });*/
  });
}

// Domestic
app.post('/email', function (req, res) {
  var data = {
    email: req.body.email,
    //name: req.body.name,
    //address: req.body.address,
    org: req.body.org
    //message: req.body.message,
    //zip: req.body.zip
  };

  console.log(req.body, data);
  addEmail('resetthenet', data, function (err) {
    //if (err) {
    //  return res.jsonp({error: err});
    //}

    res.jsonp({message: 'Email added'});
  });
});
/*
app.get('/signature_count', function (req, res) {
  res.setHeader("Expires", new Date(Date.now() + 1 * 60 * 1000).toUTCString());

  collections.signatures.count(function (err, count) {
    if (err) {
      return res.jsonp({error: err});
    }

    res.jsonp({count: count});
  });
});

// International
app.post('/signature', function (req, res) {
  var data = {
    email: req.body.email,
    name: req.body.name,
    org: req.body.org,
    country: req.body.country
  };

  addEmail('signatures', data, function (err) {
    //if (err) {
    //  return res.jsonp({error: err});
    //}

    res.jsonp({message: 'Email added'});
  });
});

app.get('/call_count', function (req, res) {
  res.setHeader("Expires", new Date(Date.now() + 1 * 60 * 1000).toUTCString());

  request
    .get('https://api.twilio.com/2010-04-01/Accounts/' + process.env.TWILIO_KEY + '/Usage/Records.json')
    .auth(process.env.TWILIO_KEY, process.env.TWILIO_TOKEN)
    .end(function(results){
      res.jsonp({count: results.body.usage_records[1].count - 9750});
    });
});
*/

MongoClient.connect(process.env.MONGOHQ_URL, function (err, db) {
  if (err) {
    throw err;
  };

  collections['resetthenet'] = db.collection('resetthenet');

  collections.emails = db.collection('emails');
  collections.signatures = db.collection('signatures');
  app.listen(PORT, function () {
    console.log('listening at %d', PORT);
  });
});
<commit_msg>whitelisted resetthenet domains<commit_after>/*
 * Rushed ugly code by <thomasalwyndavis@gmail.com>
 */

var cors = require('cors');
var express = require('express');
var MongoClient = require('mongodb').MongoClient;
var request = require('superagent');

var email = require('./email.js');

var PORT = process.env.PORT || 8080;

var TEMPLATES = {
  emails: 'domestic',
  signatures: 'international'
};

var collections = {};

var whitelist = [
  'http://dev.stopwatching.us',
  'http://rally.stopwatching.us',
  'http://2.stopwatching.us',
  'http://localhost:4000',
  'https://dev.stopwatching.us',
  'https://rally.stopwatching.us',
  'https://2.stopwatching.us',
  'https://localhost:4000',
  'https://thedaywefightback.org',
  'http://thedaywefightback.org',
  'https://thedaywefightback.org/',
  'http://thedaywefightback.org/',
  'http://dznh7un1y2etk.cloudfront.net',
  'http://tfrce.github.io',
  'http://localhost',
  'http://www.resetthenet.org',
  'https://www.resetthenet.org',
  'http://pack.resetthenet.org',
  'https://pack.resetthenet.org'
];

var corsOptions = {
  origin: function (origin, cb) {
    console.log(origin, 'origin');
    cb(null, whitelist.indexOf(origin) !== -1);
  }
};

var app = express();

app.use(express.urlencoded());
app.use(express.json());

app.use('/fonts', express.static(__dirname + '/fonts'));
app.use('/xdm', express.static(__dirname + '/xdm'));

app.use(cors(corsOptions));

app.options("*", cors(corsOptions));

app.get('/count', function (req, res) {
  res.setHeader("Expires", new Date(Date.now() + 1 * 60 * 1000).toUTCString());

  collections.resetthenet.count(function (err, count) {
    res.jsonp({ count: count });
  });
});

app.get('/', function (req, res) {
  res.jsonp({
    message: 'Welcome to an email tool, currently configured for resetthenet'
  });
});
/*
app.get('/time', function (req, res) {
  res.setHeader("Expires", new Date(Date.now() + 1 * 180 * 1000).toUTCString());

  var targetTime = new Date(Date.now());
  var timeZoneFromDB = -5.00; //time zone value from database

  //get the timezone offset from local time in minutes
  var tzDifference = timeZoneFromDB * 60;

  //convert the offset to milliseconds, add to targetTime, and make a new Date
  var offsetTime = new Date(targetTime.getTime() + tzDifference * 60 * 1000);
  var days = 11 - offsetTime.getDate();

  res.jsonp({
    days: days,
    thedaywefightback: false,
    est: offsetTime,
    utc: new Date(Date.now())
  });
});*/

function addEmail(collection, data, cb) {
  collections[collection].insert(data, function (err) {
    if (err) {
      return cb(err);
    }
    cb();
    /*email.send(TEMPLATES[collection], data.email, data, function (err) {
      if (err) {
        return cb(err);
      }

      cb();
    });*/
  });
}

// Domestic
app.post('/email', function (req, res) {
  var data = {
    email: req.body.email,
    //name: req.body.name,
    //address: req.body.address,
    org: req.body.org
    //message: req.body.message,
    //zip: req.body.zip
  };

  console.log(req.body, data);
  addEmail('resetthenet', data, function (err) {
    //if (err) {
    //  return res.jsonp({error: err});
    //}

    res.jsonp({message: 'Email added'});
  });
});
/*
app.get('/signature_count', function (req, res) {
  res.setHeader("Expires", new Date(Date.now() + 1 * 60 * 1000).toUTCString());

  collections.signatures.count(function (err, count) {
    if (err) {
      return res.jsonp({error: err});
    }

    res.jsonp({count: count});
  });
});

// International
app.post('/signature', function (req, res) {
  var data = {
    email: req.body.email,
    name: req.body.name,
    org: req.body.org,
    country: req.body.country
  };

  addEmail('signatures', data, function (err) {
    //if (err) {
    //  return res.jsonp({error: err});
    //}

    res.jsonp({message: 'Email added'});
  });
});

app.get('/call_count', function (req, res) {
  res.setHeader("Expires", new Date(Date.now() + 1 * 60 * 1000).toUTCString());

  request
    .get('https://api.twilio.com/2010-04-01/Accounts/' + process.env.TWILIO_KEY + '/Usage/Records.json')
    .auth(process.env.TWILIO_KEY, process.env.TWILIO_TOKEN)
    .end(function(results){
      res.jsonp({count: results.body.usage_records[1].count - 9750});
    });
});
*/

MongoClient.connect(process.env.MONGOHQ_URL, function (err, db) {
  if (err) {
    throw err;
  };

  collections['resetthenet'] = db.collection('resetthenet');

  collections.emails = db.collection('emails');
  collections.signatures = db.collection('signatures');
  app.listen(PORT, function () {
    console.log('listening at %d', PORT);
  });
});
<|endoftext|>