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

import {createRequire} from 'module';
import fs from 'fs';
import {execSync} from 'child_process';
import wraptile from 'wraptile';
import currify from 'currify';
import minimist from 'minimist';

import eof from '../lib/eof.js';

const require = createRequire(import.meta.url);

const update = wraptile(_update);
const ifInstall = wraptile(_ifInstall);
const ifCommit = wraptile(_ifCommit);
const save = currify(_save);

const resolve = Promise.resolve.bind(Promise);
const {stdout} = process;
const write = stdout.write.bind(stdout);

const argv = process.argv.slice(2);

const args = minimist(argv, {
    boolean: [
        'version',
        'help',
        'save-exact',
        'install',
        'dev',
        'commit',
        'add',
        'remove',
        'public',
        'restricted',
        'set-any',
    ],
    alias: {
        'v': 'version',
        'h': 'help',
        'E': 'save-exact',
        'i': 'install',
        'D': 'dev',
        'a': 'add',
        'r': 'remove',
        'c': 'commit',
        '*': 'set-any',
    },
    unknown: (cmd) => {
        const msg = `'%s' is not a nupdate option. See 'nupdate --help'.`;

        if (/^--?/.test(cmd))
            exit(msg, cmd);
    },
});

if (!args.length && args.help) {
    help();
} else if (args.version) {
    console.log('v' + require('../package').version);
} else if (args.public || args.restricted) {
    updatePublishConfig({
        isPublic: args.public,
        isCommit: args.commit,
    }).catch(onError);
} else {
    main(args._[0], {
        exact: args['save-exact'],
        install: args.install,
        dev: args.dev,
        commit: args.commit,
        add: args.add,
        remove: args.remove,
        setAny: args['set-any'],
    }).catch(onError);
}

function getAccess({isPublic}) {
    if (isPublic)
        return 'public';

    return 'restricted';
}

async function updatePublishConfig({isPublic, isCommit}) {
    const publishConfig = await import('../lib/publish-config.js');

    const access = getAccess({
        isPublic,
    });

    const path = await find();
    const data = fs.readFileSync(path, 'utf8');
    const json = JSON.parse(data);
    const {commitType = 'paren'} = json;
    const result = publishConfig(access, data);

    fs.writeFileSync(path, eof(result));

    if (!isCommit)
        return;

    const commitColon = `git commit -m "chore: package: publishConfig: access: ${access}"`;
    const commitParen= `git commit -m "chore(package) publishConfig: access: ${access}"`;
    const commitByType = commitType === 'colon' ? commitColon : commitParen;

    const commit = [
        `git add ${path}`,
        commitByType ,
    ].join('&&');

    const cmd = `${commit} || true`;
    const str = tryExec(cmd);

    write(str);
}

function getCmd({name, version}) {
    if (!version)
        return `npm info ${name} --json`;

    return `echo '{"version": "${version}"}'`;
}

async function main(pattern, options) {
    if (!pattern)
        return console.error(`Module pattern could not be empty`);

    const [name, version] = pattern.split(':');

    const {default: fullstore} = await import('fullstore');
    const versionStore = fullstore();
    const pathStore = fullstore();

    const cmd = getCmd({
        name,
        version,
    });

    return resolve(tryExec(cmd))
        .then(JSON.parse)
        .then(getVersion)
        .then(versionStore)
        .then(find)
        .then(pathStore)
        .then(update(name, options, pathStore, versionStore))
        .then(eof)
        .then(save(pathStore))
        .then(ifInstall(options.install, name))
        .then(ifCommit(options.commit, name, pathStore, versionStore));
}

function _ifInstall(is, name) {
    if (!is)
        return;

    return resolve(tryExec(`npm i ${name} --no-save`))
        .then(write);
}

function _ifCommit(is, name, path, version) {
    if (!is)
        return;

    const data = fs.readFileSync(path(), 'utf8');
    const json = JSON.parse(data);
    const {commitType = 'paren'} = json;

    const commitColon = `git commit -m "feature: package: ${name} v${version()}"`;
    const commitParen = `git commit -m "feature(package) ${name} v${version()}"`;
    const commitByType = commitType === 'colon' ? commitColon : commitParen;

    const commit = [
        `git add ${path()}`,
        commitByType,
    ].join('&&');

    const cmd = `${commit} || true`;

    return write(tryExec(cmd));
}

async function find() {
    const {findUp} = await import('find-up');
    return await findUp('package.json');
}

async function _update(name, options, path, version) {
    if (!name)
        return;

    const {nupdate} = await import('../lib/nupdate.js');
    const info = fs.readFileSync(path(), 'utf8');
    const result = nupdate(name, version(), info, options);

    return result;
}

function tryExec(cmd) {
    return execSync(cmd).toString();
}

function onError(error) {
    if (error)
        return console.error(error.message);
}

function getVersion(info) {
    return info.version;
}

function _save(pathStore, data) {
    fs.writeFileSync(pathStore(), data);
}

function exit(...args) {
    console.error(...args);
    process.exit(1);
}

async function help() {
    const bin = require('../json/help.json');
    const {defeault: forEachKey} = await import('for-each-key');
    const usage = 'Usage: nupdate [pattern] [options]';

    const log = currify((a, b, c) => console.log(a, b, c));

    console.log(usage);
    console.log('Options:');

    forEachKey(log(' %s %s'), bin);
}

<commit_msg>chore: nupdate: lint<commit_after>#!/usr/bin/env node

import {createRequire} from 'module';
import fs from 'fs';
import {execSync} from 'child_process';
import wraptile from 'wraptile';
import currify from 'currify';
import minimist from 'minimist';

import eof from '../lib/eof.js';

const require = createRequire(import.meta.url);

const update = wraptile(_update);
const ifInstall = wraptile(_ifInstall);
const ifCommit = wraptile(_ifCommit);
const save = currify(_save);

const resolve = Promise.resolve.bind(Promise);
const {stdout} = process;
const write = stdout.write.bind(stdout);

const argv = process.argv.slice(2);

const args = minimist(argv, {
    boolean: [
        'version',
        'help',
        'save-exact',
        'install',
        'dev',
        'commit',
        'add',
        'remove',
        'public',
        'restricted',
        'set-any',
    ],
    alias: {
        'v': 'version',
        'h': 'help',
        'E': 'save-exact',
        'i': 'install',
        'D': 'dev',
        'a': 'add',
        'r': 'remove',
        'c': 'commit',
        '*': 'set-any',
    },
    unknown: (cmd) => {
        const msg = `'%s' is not a nupdate option. See 'nupdate --help'.`;

        if (/^--?/.test(cmd))
            exit(msg, cmd);
    },
});

if (!args.length && args.help) {
    help();
} else if (args.version) {
    console.log('v' + require('../package').version);
} else if (args.public || args.restricted) {
    updatePublishConfig({
        isPublic: args.public,
        isCommit: args.commit,
    }).catch(onError);
} else {
    main(args._[0], {
        exact: args['save-exact'],
        install: args.install,
        dev: args.dev,
        commit: args.commit,
        add: args.add,
        remove: args.remove,
        setAny: args['set-any'],
    }).catch(onError);
}

function getAccess({isPublic}) {
    if (isPublic)
        return 'public';

    return 'restricted';
}

async function updatePublishConfig({isPublic, isCommit}) {
    const publishConfig = await import('../lib/publish-config.js');

    const access = getAccess({
        isPublic,
    });

    const path = await find();
    const data = fs.readFileSync(path, 'utf8');
    const {commitType = 'paren'} = JSON.parse(data);
    const result = publishConfig(access, data);

    fs.writeFileSync(path, eof(result));

    if (!isCommit)
        return;

    const commitColon = `git commit -m "chore: package: publishConfig: access: ${access}"`;
    const commitParen = `git commit -m "chore(package) publishConfig: access: ${access}"`;
    const commitByType = commitType === 'colon' ? commitColon : commitParen;

    const commit = [
        `git add ${path}`,
        commitByType,
    ].join('&&');

    const cmd = `${commit} || true`;
    const str = tryExec(cmd);

    write(str);
}

function getCmd({name, version}) {
    if (!version)
        return `npm info ${name} --json`;

    return `echo '{"version": "${version}"}'`;
}

async function main(pattern, options) {
    if (!pattern)
        return console.error(`Module pattern could not be empty`);

    const [name, version] = pattern.split(':');

    const {default: fullstore} = await import('fullstore');
    const versionStore = fullstore();
    const pathStore = fullstore();

    const cmd = getCmd({
        name,
        version,
    });

    return resolve(tryExec(cmd))
        .then(JSON.parse)
        .then(getVersion)
        .then(versionStore)
        .then(find)
        .then(pathStore)
        .then(update(name, options, pathStore, versionStore))
        .then(eof)
        .then(save(pathStore))
        .then(ifInstall(options.install, name))
        .then(ifCommit(options.commit, name, pathStore, versionStore));
}

function _ifInstall(is, name) {
    if (!is)
        return;

    return resolve(tryExec(`npm i ${name} --no-save`))
        .then(write);
}

function _ifCommit(is, name, path, version) {
    if (!is)
        return;

    const data = fs.readFileSync(path(), 'utf8');
    const {commitType = 'paren'} = JSON.parse(data);

    const commitColon = `git commit -m "feature: package: ${name} v${version()}"`;
    const commitParen = `git commit -m "feature(package) ${name} v${version()}"`;
    const commitByType = commitType === 'colon' ? commitColon : commitParen;

    const commit = [
        `git add ${path()}`,
        commitByType,
    ].join('&&');

    const cmd = `${commit} || true`;

    return write(tryExec(cmd));
}

async function find() {
    const {findUp} = await import('find-up');
    return await findUp('package.json');
}

async function _update(name, options, path, version) {
    if (!name)
        return;

    const {nupdate} = await import('../lib/nupdate.js');
    const info = fs.readFileSync(path(), 'utf8');
    const result = nupdate(name, version(), info, options);

    return result;
}

function tryExec(cmd) {
    return execSync(cmd).toString();
}

function onError(error) {
    if (error)
        return console.error(error.message);
}

function getVersion(info) {
    return info.version;
}

function _save(pathStore, data) {
    fs.writeFileSync(pathStore(), data);
}

function exit(...args) {
    console.error(...args);
    process.exit(1);
}

async function help() {
    const bin = require('../json/help.json');
    const {defeault: forEachKey} = await import('for-each-key');
    const usage = 'Usage: nupdate [pattern] [options]';

    const log = currify((a, b, c) => console.log(a, b, c));

    console.log(usage);
    console.log('Options:');

    forEachKey(log(' %s %s'), bin);
}

<|endoftext|>


<commit_before>module('plugins.copy');

//需要点击授权弹出框,暂时去除
//test('检查IE下复制命令是否执行正常', function () {
//
//    if (browser.ie) {
//        var editor = te.obj[0];
//        editor.setContent('
hello
');
//        editor.focus();
//
//        editor.execCommand('selectall');
//        editor.execCommand('copy');
//        editor.body.innerHTML = '';
//        editor.execCommand('selectall');
//        editor.body.document.execCommand('paste');
//
//        equal(utils.trim(window.clipboardData.getData('text')), 'hello', '检查粘贴板内容,IE下成功复制内容');
//        setTimeout(function(){
//            equal(editor.getContent(), '
hello
', '检查原生粘贴命令,IE下成功复制内容');
//            start();
//        },100);
//
//        stop();
//    }
//
//});

test('检查非IE下是否正常加载zeroclipboard粘贴板插件', function () {
    te.dom[0].parentNode.removeChild(te.dom[0]);
    var sc = document.createElement("script");
    sc.id="sc";
    sc.type = "text/plain";
    sc.style.height = "100px";
    document.body.appendChild(sc);
    var me = UE.getEditor('sc',{'autoFloatEnabled':true,'topOffset':60,'autoHeightEnabled':true,'scaleEnabled':false});
    me.ready(function(){

        stop();
        setTimeout(function(){
            if (!browser.ie) {
            ok(window.ZeroClipboard, '是否正常加载zeroclipboard粘贴板插件');
            }
            setTimeout(function () {
                UE.delEditor('sc');
                document.getElementById('sc')&&document.getElementById('sc').parentNode.removeChild(document.getElementById('sc'));
                start();
            }, 500);
        }, 300);
    });

});<commit_msg>[test]<commit_after>module('plugins.copy');

//需要点击授权弹出框,暂时去除
//test('检查IE下复制命令是否执行正常', function () {
//
//    if (browser.ie) {
//        var editor = te.obj[0];
//        editor.setContent('
hello
');
//        editor.focus();
//
//        editor.execCommand('selectall');
//        editor.execCommand('copy');
//        editor.body.innerHTML = '';
//        editor.execCommand('selectall');
//        editor.body.document.execCommand('paste');
//
//        equal(utils.trim(window.clipboardData.getData('text')), 'hello', '检查粘贴板内容,IE下成功复制内容');
//        setTimeout(function(){
//            equal(editor.getContent(), '
hello
', '检查原生粘贴命令,IE下成功复制内容');
//            start();
//        },100);
//
//        stop();
//    }
//
//});

test('检查非IE下是否正常加载zeroclipboard粘贴板插件', function () {
    te.dom[0].parentNode.removeChild(te.dom[0]);
    var sc = document.createElement("script");
    sc.id="sc";
    sc.type = "text/plain";
    sc.style.height = "100px";
    document.body.appendChild(sc);
    var me = UE.getEditor('sc',{'autoFloatEnabled':true,'topOffset':60,'autoHeightEnabled':true,'scaleEnabled':false});
    me.ready(function(){
        setTimeout(function(){
            if (!browser.ie) {
            ok(window.ZeroClipboard, '是否正常加载zeroclipboard粘贴板插件');
            }
            setTimeout(function () {
                UE.delEditor('sc');
                document.getElementById('sc')&&document.getElementById('sc').parentNode.removeChild(document.getElementById('sc'));
                start();
            }, 500);
        }, 300);
    });
    stop();

});<|endoftext|>


<commit_before>/**
 * Widgets API defaults
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed 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
 *
 *     https://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.
 */

/**
 * Internal dependencies
 */
import { CONTEXT_DASHBOARD, CONTEXT_PAGE_DASHBOARD } from './default-contexts';
import {
	AREA_ALL_TRAFFIC,
	AREA_SEARCH_FUNNEL,
	AREA_POPULARITY,
	AREA_SPEED,
	AREA_EARNINGS,
} from './default-areas';

/**
 * Defines default widget areas for a given context.
 *
 * @since n.e.x.t
 *
 * @param {Object} widgetsApi Widgets API.
 */
export function registerDefaults( widgetsApi ) {
	const contexts = [ CONTEXT_DASHBOARD, CONTEXT_PAGE_DASHBOARD ];

	widgetsApi.registerWidgetArea( AREA_ALL_TRAFFIC, {
		title: 'All Triffic',
		subtitle: 'How people found your site.',
	}, contexts );

	widgetsApi.registerWidgetArea( AREA_SEARCH_FUNNEL, {
		title: 'Search Funnel',
		subtitle: 'How your site appeared in Search results and how many visitors you got from Search.',
	}, contexts );

	widgetsApi.registerWidgetArea( AREA_POPULARITY, {
		title: 'Popularity',
		subtitle: 'Your most popular pages and how people found them from Search.',
	}, contexts );

	widgetsApi.registerWidgetArea( AREA_SPEED, {
		title: 'Page Speed and Experience',
		subtitle: 'How fast your home page loads, how quickly people can interact with your content, and how stable your content is.',
	}, contexts );

	widgetsApi.registerWidgetArea( AREA_EARNINGS, {
		title: 'Earnings',
		subtitle: 'How much your site earns.',
	}, contexts );
}
<commit_msg>Rename widgetsApi to widgetsAPI.<commit_after>/**
 * Widgets API defaults
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed 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
 *
 *     https://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.
 */

/**
 * Internal dependencies
 */
import { CONTEXT_DASHBOARD, CONTEXT_PAGE_DASHBOARD } from './default-contexts';
import {
	AREA_ALL_TRAFFIC,
	AREA_SEARCH_FUNNEL,
	AREA_POPULARITY,
	AREA_SPEED,
	AREA_EARNINGS,
} from './default-areas';

/**
 * Defines default widget areas for a given context.
 *
 * @since n.e.x.t
 *
 * @param {Object} widgetsAPI Widgets API.
 */
export function registerDefaults( widgetsAPI ) {
	const contexts = [ CONTEXT_DASHBOARD, CONTEXT_PAGE_DASHBOARD ];

	widgetsAPI.registerWidgetArea( AREA_ALL_TRAFFIC, {
		title: 'All Triffic',
		subtitle: 'How people found your site.',
	}, contexts );

	widgetsAPI.registerWidgetArea( AREA_SEARCH_FUNNEL, {
		title: 'Search Funnel',
		subtitle: 'How your site appeared in Search results and how many visitors you got from Search.',
	}, contexts );

	widgetsAPI.registerWidgetArea( AREA_POPULARITY, {
		title: 'Popularity',
		subtitle: 'Your most popular pages and how people found them from Search.',
	}, contexts );

	widgetsAPI.registerWidgetArea( AREA_SPEED, {
		title: 'Page Speed and Experience',
		subtitle: 'How fast your home page loads, how quickly people can interact with your content, and how stable your content is.',
	}, contexts );

	widgetsAPI.registerWidgetArea( AREA_EARNINGS, {
		title: 'Earnings',
		subtitle: 'How much your site earns.',
	}, contexts );
}
<|endoftext|>


<commit_before>const defaultMenu = require('electron-default-menu');
const squirrel = require('electron-squirrel-startup');
const windowStateKeeper = require('electron-window-state');
const AutoUpdater = require('headset-autoupdater');
const path = require('path');
const {
  app,
  BrowserWindow,
  globalShortcut,
  ipcMain,
  Menu,
  shell,
  systemPreferences,
  Tray,
} = require('electron');

const { version } = require('../package');
const logger = require('./lib/headsetLogger');
const headsetTray = require('./lib/headsetTray');
const mprisService = require('./lib/mprisService');
const registerMediaKeys = require('./lib/registerMediaKeys');

// Delete the log file. Just a workaround until 'electron-log' is updated
logger.clear();

let player;
let tray;
let trayIcon;
let win;
let windowIcon;

const OS = process.platform;

// Load Windows variables
if (OS === 'win32') {
  // Exit the app if it starts from squirrel
  if (squirrel) app.exit();
  Menu.setApplicationMenu(null);
  windowIcon = path.join(__dirname, 'icons', 'headset.ico');
  trayIcon = windowIcon;
}

// Load Linux variables
if (OS === 'linux') {
  Menu.setApplicationMenu(null);
  windowIcon = path.join(__dirname, 'icons', 'windowIcon.ico');
}

// Load macOS variables
if (OS === 'darwin') {
  systemPreferences.isTrustedAccessibilityClient(true);
  const menu = defaultMenu(app, shell);
  Menu.setApplicationMenu(Menu.buildFromTemplate(menu));
  trayIcon = path.join(__dirname, 'icons', 'headsetTemplate.png');
}

if (process.argv.includes('--disable-gpu')) {
  app.disableHardwareAcceleration();
}

const isDev = (process.env.NODE_ENV === 'development');
logger.info(`Running as developer: ${isDev}`);

// Allows to autoplay video, which is disabled in newer versions of Chrome
app.commandLine.appendSwitch('autoplay-policy', 'no-user-gesture-required');

// Quit if second instance found and focus window of first instance
if (!app.requestSingleInstanceLock()) app.exit();

app.on('second-instance', () => {
  logger.info('Second instance of Headset found');
  if (win) {
    if (win.isMinimized()) win.restore();
    win.focus();
  }
});

function start() {
  if (OS === 'win32' || OS === 'darwin') {
    new AutoUpdater(); // Check if new updates
  }

  logger.info('Starting Headset');
  const mainWindowState = windowStateKeeper();

  win = new BrowserWindow({
    x: mainWindowState.x,
    y: mainWindowState.y,
    width: 375,
    height: 667,
    resizable: false,
    title: 'Headset',
    maximizable: false,
    useContentSize: true,
    icon: windowIcon,
    titleBarStyle: 'hiddenInset',
    webPreferences: { nodeIntegration: true },
  });

  player = new BrowserWindow({
    width: 427,
    height: 300,
    closable: false,
    useContentSize: true,
    title: 'Headset - Player',
    icon: windowIcon,
    webPreferences: { nodeIntegration: true },
  });

  mainWindowState.manage(win);

  if (isDev) {
    win.loadURL('http://127.0.0.1:3000');
    player.loadURL('http://lvh.me:3001'); // YouTube player needs a domain, doesn't work with IPs
    win.webContents.openDevTools();
  } else {
    win.loadURL('https://danielravina.github.io/headset/app/');
    player.loadURL('http://danielravina.github.io/headset/player-v2');
  }

  // Creates a Tray
  if (OS === 'win32' || OS === 'darwin') {
    tray = new Tray(trayIcon);
    headsetTray(tray, win, player);
  }

  // Register MPRIS
  if (OS === 'linux') {
    try { mprisService(win, player, app); } catch (err) { console.error(err); }
  }

  // Register media keys
  registerMediaKeys(win);

  win.webContents.on('did-finish-load', () => {
    logger.info('Main window finished loading');

    win.webContents.executeJavaScript(`
      window.electronVersion = "v${version}"
    `);
  });

  player.webContents.on('did-finish-load', () => {
    logger.info('Player window finished loading');
    win.focus();
    setTimeout(() => player.minimize(), 2000);
  });

  player.webContents.on('new-window', (event, url) => {
    event.preventDefault();
    const docsWin = new BrowserWindow({ closable: true });
    docsWin.loadURL(url);
    event.newGuest = docsWin; // eslint-disable-line no-param-reassign
  });

  win.on('close', () => {
    logger.info('Closing Headset');
    // after app closes in Win, the global shortcuts are still up, disabling it here.
    globalShortcut.unregisterAll();
    app.exit();
  });
} // end start

app.on('ready', start);

/*
 * This is the proxy between the 2 windows.
 * It receives messages from a renderer and send them to the other renderer
*/
ipcMain.on('win2Player', (e, args) => {
  logger.win2Player(args);

  player.webContents.send('win2Player', args);
});

ipcMain.on('player2Win', (e, args) => {
  logger.player2Win(args);

  try {
    win.webContents.send('player2Win', args);
  } catch (err) { /* window already closed */ }
});
<commit_msg>Fix mac os and release new version (#258)<commit_after>const defaultMenu = require('electron-default-menu');
const squirrel = require('electron-squirrel-startup');
const windowStateKeeper = require('electron-window-state');
const AutoUpdater = require('headset-autoupdater');
const path = require('path');
const {
  app,
  BrowserWindow,
  globalShortcut,
  ipcMain,
  Menu,
  shell,
  systemPreferences,
  Tray,
} = require('electron');

const { version } = require('../package');
const logger = require('./lib/headsetLogger');
const headsetTray = require('./lib/headsetTray');
const mprisService = require('./lib/mprisService');
const registerMediaKeys = require('./lib/registerMediaKeys');

// Delete the log file. Just a workaround until 'electron-log' is updated
logger.clear();

let player;
let tray;
let trayIcon;
let win;
let windowIcon;

const OS = process.platform;

// Load Windows variables
if (OS === 'win32') {
  // Exit the app if it starts from squirrel
  if (squirrel) app.exit();
  Menu.setApplicationMenu(null);
  windowIcon = path.join(__dirname, 'icons', 'headset.ico');
  trayIcon = windowIcon;
}

// Load Linux variables
if (OS === 'linux') {
  Menu.setApplicationMenu(null);
  windowIcon = path.join(__dirname, 'icons', 'windowIcon.ico');
}

// Load macOS variables
if (OS === 'darwin') {
  systemPreferences.isTrustedAccessibilityClient(true);
  const menu = defaultMenu(app, shell);
  Menu.setApplicationMenu(Menu.buildFromTemplate(menu));
  trayIcon = path.join(__dirname, 'icons', 'headsetTemplate.png');
}

if (process.argv.includes('--disable-gpu')) {
  app.disableHardwareAcceleration();
}

const isDev = (process.env.NODE_ENV === 'development');
logger.info(`Running as developer: ${isDev}`);

// Allows to autoplay video, which is disabled in newer versions of Chrome
app.commandLine.appendSwitch('autoplay-policy', 'no-user-gesture-required');

// Quit if second instance found and focus window of first instance
if (!app.requestSingleInstanceLock()) app.exit();

app.on('second-instance', () => {
  logger.info('Second instance of Headset found');
  if (win) {
    if (win.isMinimized()) win.restore();
    win.focus();
  }
});

function close() {
  logger.info('Closing Headset');
  // after app closes in Win, the global shortcuts are still up, disabling it here.
  globalShortcut.unregisterAll();
  app.exit();
}

function start() {
  if (OS === 'win32' || OS === 'darwin') {
    new AutoUpdater(); // Check if new updates
  }

  logger.info('Starting Headset');
  const mainWindowState = windowStateKeeper();

  win = new BrowserWindow({
    x: mainWindowState.x,
    y: mainWindowState.y,
    width: 375,
    height: 667,
    resizable: false,
    title: 'Headset',
    maximizable: false,
    useContentSize: true,
    icon: windowIcon,
    titleBarStyle: 'hiddenInset',
    webPreferences: { nodeIntegration: true },
  });

  player = new BrowserWindow({
    width: 427,
    height: 300,
    closable: false,
    useContentSize: true,
    title: 'Headset - Player',
    icon: windowIcon,
    webPreferences: { nodeIntegration: true },
  });

  mainWindowState.manage(win);

  if (isDev) {
    win.loadURL('http://127.0.0.1:3000');
    player.loadURL('http://lvh.me:3001'); // YouTube player needs a domain, doesn't work with IPs
    win.webContents.openDevTools();
  } else {
    win.loadURL('https://danielravina.github.io/headset/app/');
    player.loadURL('http://danielravina.github.io/headset/player-v2');
  }

  // Creates a Tray
  if (OS === 'win32' || OS === 'darwin') {
    tray = new Tray(trayIcon);
    headsetTray(tray, win, player);
  }

  // Register MPRIS
  if (OS === 'linux') {
    try { mprisService(win, player, app); } catch (err) { console.error(err); }
  }

  // Register media keys
  registerMediaKeys(win);

  win.webContents.on('did-finish-load', () => {
    logger.info('Main window finished loading');

    win.webContents.executeJavaScript(`
      window.electronVersion = "v${version}"
    `);
  });

  player.webContents.on('did-finish-load', () => {
    logger.info('Player window finished loading');
    win.focus();
    setTimeout(() => player.minimize(), 2000);
  });

  player.webContents.on('new-window', (event, url) => {
    event.preventDefault();
    const docsWin = new BrowserWindow({ closable: true });
    docsWin.loadURL(url);
    event.newGuest = docsWin; // eslint-disable-line no-param-reassign
  });

  // Linux doesn't implement closable=false for
  player.on('close', (event) => {
    event.preventDefault();
  });

  win.on('close', (e) => {
    if (OS === 'darwin') {
      // Hide the window on macOS
      logger.info('Hide main headset window');
      e.preventDefault();
      win.hide();
    } else {
      close(); // close the app for Linux and Windows
    }
  });
} // end start

app.on('ready', start);

app.on('activate', () => win.show()); // macOS only

app.on('before-quit', close);

/*
 * This is the proxy between the 2 windows.
 * It receives messages from a renderer and send them to the other renderer
*/
ipcMain.on('win2Player', (e, args) => {
  logger.win2Player(args);

  player.webContents.send('win2Player', args);
});

ipcMain.on('player2Win', (e, args) => {
  logger.player2Win(args);

  try {
    win.webContents.send('player2Win', args);
  } catch (err) { /* window already closed */ }
});
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013, IT Services, Stockholm University
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * 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.
 *
 * Neither the name of Stockholm University nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * 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 HOLDER 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.
 */

describe('Info window view', function () {
  beforeEach(function () {
    $('#stage').replaceWith("

");
    $('#page-map').append(JST['map/infoWindow']({
      model: new Location(),
      itemText: "",
      displayDirections: true
    }));
  });

  afterEach(function () {
    $('#page-map').replaceWith("

");
  });

  describe('instantiation', function () {
    it('should add event handler on change of showingNonVisibleForLocation in AppModel ', function () {
      spyOn(AppModel.prototype, "on");

      this.infoWindow = new InfoWindowView({
        appModel: new AppModel()
      });

      expect(AppModel.prototype.on).toHaveBeenCalledWith("change:showingNonVisibleForLocation", jasmine.any(Function), this.infoWindow);
    });

    it('should create google.maps.InfoWindow with maxWidth 260', function () {
      spyOn(google.maps, "InfoWindow");

      this.infoWindow = new InfoWindowView({
        appModel: new AppModel()
      });

      expect(google.maps.InfoWindow).toHaveBeenCalledWith({ maxWidth: 260 });
    });
  });

  describe('remove', function () {

    it('should call close', function () {
      spyOn(InfoWindowView.prototype, "close");

      this.infoWindow = new InfoWindowView({
        appModel: new AppModel()
      });
      this.infoWindow.remove();

      expect(InfoWindowView.prototype.close).toHaveBeenCalled();
    });

    it('should remove event handler from document for click on directions', function () {
      // Mock MapView and getDirections on it
      var MapView = function () {
      };
      MapView.prototype.getDirections = function () {
      };
      spyOn(MapView.prototype, "getDirections");

      this.infoWindow = new InfoWindowView({
        appModel: new AppModel(),
        mapView: new MapView()
      });

      $(".dir-button").first().trigger("click");
      expect(MapView.prototype.getDirections.calls.length).toEqual(1);

      this.infoWindow.remove();
      $(".dir-button").first().trigger("click");
      expect(MapView.prototype.getDirections.calls.length).toEqual(1);
    });

  });

  describe('when clicking on a direction link in infowindow', function () {
    // Mock MapView and getDirections on it
    var MapView = function () {
    };
    MapView.prototype.getDirections = function () {
    };

    beforeEach(function () {
      spyOn(MapView.prototype, "getDirections");
      spyOn(InfoWindowView.prototype, "close");

      this.infoWindow = new InfoWindowView({
        appModel: new AppModel(),
        mapView: new MapView()
      });
    });

    it('should close the info window', function () {
      $(".dir-button").first().trigger("click");
      expect(InfoWindowView.prototype.close).toHaveBeenCalled();
    });

    it('should set selected on clicked link and unselect others', function () {
      $(".dir-button").first().trigger("click");
      expect($(".dir-button.selected").attr("id")).toEqual("walking");

      $(".dir-button").last().trigger("click");
      expect($(".dir-button.selected").attr("id")).toEqual("driving");
      expect($(".dir-button.selected").length).toEqual(1);
    });

    it('should pass destination to getDirections', function () {
      this.infoWindow.setDestination("destination");
      $(".dir-button").first().trigger("click");
      expect(MapView.prototype.getDirections).toHaveBeenCalledWith("walking", "destination");
    });
  });

  describe('when clicking on a show related link in the infowindow', function () {

  });

  describe('when opening the infowindow', function () {

    it('should close previous infowindow', function () {
      this.infoWindow = new InfoWindowView({
        appModel: new AppModel()
      });

      spyOn(this.infoWindow.infoWindow, "close");
      this.infoWindow.open(new Location(), new google.maps.Marker(), new google.maps.LatLng(0, 0));
      expect(this.infoWindow.infoWindow.close).toHaveBeenCalled();
    });

    it('should call model (Location) getI18n method (fetching the text attribute)', function () {
      spyOn(Location.prototype, "getI18n");

      this.infoWindow = new InfoWindowView({
        appModel: new AppModel()
      });

      var location = new Location({
        name: 'testName',
        directionAware: false
        });
      this.infoWindow.open(location, new google.maps.Marker(), new google.maps.LatLng(0, 0));

      expect(Location.prototype.getI18n).toHaveBeenCalledWith('text');
    });

    it('should call JST with correct values', function () {
      spyOn(JST, 'map/infoWindow').andReturn('');

      i18n.init({
        lng: 'sv-SE'
      });

      this.infoWindow = new InfoWindowView({
        appModel: new AppModel()
      });

      var location = new Location({
        name: 'testName',
        directionAware: false,
        buildingName: 'testBuilding',
        text: 'testText',
        type: 'building'
      });

      this.infoWindow.appModel.locations = {
        byBuildingAndTypeAndHandicapAdapted: function (building, types, adapted) {
          return _([ new Location({
            floor: '1'
          }) ])
        }
      }

      this.infoWindow.open(location, new google.maps.Marker(), new google.maps.LatLng(0, 0));

      expect(JST['map/infoWindow']).toHaveBeenCalledWith({
        name: 'testName, testBuilding',
        displayDirections: false,
        model: location,
        itemText: 'testText',
        hasElevators: true,
        hasEntrances: true,
        tFloors: '1'
      });
    });

    it('should call JST with correct values when other language than swedish', function () {
      spyOn(JST, 'map/infoWindow').andReturn('');

      i18n.init({
        lng: 'fr-FR'
      });

      this.infoWindow = new InfoWindowView({
        appModel: new AppModel()
      });

      var location = new Location({
        name: 'testName',
        nameEn: 'testName (en)',
        directionAware: false,
        text: 'testText',
        textEn: 'testText (en)',
        type: 'department'
      });

      this.infoWindow.open(location, new google.maps.Marker(), new google.maps.LatLng(0, 0));

      expect(JST['map/infoWindow']).toHaveBeenCalledWith({
        name: 'testName (en)',
        displayDirections: false,
        model: location,
        itemText: 'testText (en)'
      });
    });

  });

  describe('Info-window template', function () {
    it('should set hearing_loop for auditoriums when handicapAdapted', function () {
      // First expect to find no hearing loops
      expect($('#page-map').find('i[class="hearing_loop"]').size()).toEqual(0);

      var location = new Location({
        type: 'auditorium',
        handicapAdapted: true
      });

      $('#page-map').replaceWith("

");
      $('#page-map').append(JST['map/infoWindow']({
        model: location,
        itemText: '',
        displayDirections: false
      }));

      expect($('#page-map').find('i[class="hearing_loop"]').size()).toEqual(1);
    });

    it('should set hearing_loop for auditoriums when handicapAdpted', function () {
      // First expect to find no hearing loops
      expect($('#page-map').find('i[class="hearing_loop"]').size()).toEqual(0);

      var location = new Location({
        type: 'auditorium',
        handicapAdapted: false
      });

      $('#page-map').replaceWith("

");
      $('#page-map').append(JST['map/infoWindow']({
        model: location,
        itemText: '',
        displayDirections: false
      }));

      expect($('#page-map').find('i[class="hearing_loop"]').size()).toEqual(0);
      expect($('#page-map').text()).toMatch(/.*map.infoWindow.hearing_loop.noexists.*/);
    });

    it('should set correct building information when no accessible elevators, toilets or entrances exist', function () {

      var location = new Location({
        type: 'building',
        nonVisibleTypes: ["entrance", "elevator", "toilet"]
      });

      $('#page-map').append(JST['map/infoWindow']({
        model: location,
        itemText: '',
        hasElevators: false,
        tFloors: '',
        hasEntrances: false,
        displayDirections: false
      }));

      expect($('#page-map').find('i[class="elevator"]').size()).toEqual(0);
      expect($('#page-map').text()).toMatch(/.*map.infoWindow.elevator.noexists.*/);

      expect($('#page-map').find('i[class="toilet"]').size()).toEqual(0);
      expect($('#page-map').text()).toMatch(/.*map.infoWindow.toilet.noexists.*/);

      expect($('#page-map').find('i[class="entrance"]').size()).toEqual(0);
      expect($('#page-map').text()).toMatch(/.*map.infoWindow.entrance.noexists.*/);
    });

    it('should set correct building information when accessible elevators, toilets or entrances exist', function () {

      var location = new Location({
        type: 'building',
        nonVisibleTypes: ["entrance", "elevator", "toilet"]
      });

      $('#page-map').append(JST['map/infoWindow']({
        model: location,
        itemText: '',
        hasElevators: true,
        tFloors: [1],
        hasEntrances: true,
        displayDirections: false
      }));

      expect($('#page-map').find('i[class="elevator"]').size()).toEqual(1);
      expect($('#page-map').text()).toMatch(/.*map.infoWindow.elevator.exists.*/);

      expect($('#page-map').find('i[class="toilet"]').size()).toEqual(1);
      expect($('#page-map').text()).toMatch(/.*map.infoWindow.toilet.exists.*/);

      expect($('#page-map').find('i[class="entrance"]').size()).toEqual(1);

      expect($('#page-map').find('a[class="showRelated"]').size()).toEqual(1);
      expect($('#page-map').text()).toMatch(/.*map.infoWindow.entrance.show.*/);

      expect($('#page-map').find('a[class="hideRelated"]').size()).toEqual(1);
      expect($('#page-map').text()).toMatch(/.*map.infoWindow.entrance.hide.*/);
    });

  });
});
<commit_msg>Cleanup - Mended some broken test.<commit_after>/*
 * Copyright (c) 2013, IT Services, Stockholm University
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * 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.
 *
 * Neither the name of Stockholm University nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * 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 HOLDER 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.
 */

describe('Info window view', function () {
  beforeEach(function () {
    $('#stage').replaceWith("

");
    $('#page-map').append(JST['map/infoWindow']({
      model: new Location(),
      itemText: "",
      displayDirections: true
    }));
  });

  afterEach(function () {
    $('#page-map').replaceWith("

");
  });

  describe('instantiation', function () {
    it('should add event handler on change of showingNonVisibleForLocation in AppModel ', function () {
      spyOn(AppModel.prototype, "on");

      this.infoWindow = new InfoWindowView({
        appModel: new AppModel()
      });

      expect(AppModel.prototype.on).toHaveBeenCalledWith("change:showingNonVisibleForLocation", jasmine.any(Function), this.infoWindow);
    });

    it('should create google.maps.InfoWindow with maxWidth 260', function () {
      spyOn(google.maps, "InfoWindow");

      this.infoWindow = new InfoWindowView({
        appModel: new AppModel()
      });

      expect(google.maps.InfoWindow).toHaveBeenCalledWith({ maxWidth: 260 });
    });
  });

  describe('remove', function () {

    it('should call close', function () {
      spyOn(InfoWindowView.prototype, "close");

      this.infoWindow = new InfoWindowView({
        appModel: new AppModel()
      });
      this.infoWindow.remove();

      expect(InfoWindowView.prototype.close).toHaveBeenCalled();
    });

    it('should remove event handler from document for click on directions', function () {
      // Mock MapView and getDirections on it
      var MapView = function () {
      };
      MapView.prototype.getDirections = function () {
      };
      spyOn(MapView.prototype, "getDirections");

      this.infoWindow = new InfoWindowView({
        appModel: new AppModel(),
        mapView: new MapView()
      });

      $(".dir-button").first().trigger("click");
      expect(MapView.prototype.getDirections.calls.length).toEqual(1);

      this.infoWindow.remove();
      $(".dir-button").first().trigger("click");
      expect(MapView.prototype.getDirections.calls.length).toEqual(1);
    });

  });

  describe('when clicking on a direction link in infowindow', function () {
    // Mock MapView and getDirections on it
    var MapView = function () {
    };
    MapView.prototype.getDirections = function () {
    };

    beforeEach(function () {
      spyOn(MapView.prototype, "getDirections");
      spyOn(InfoWindowView.prototype, "close");

      this.infoWindow = new InfoWindowView({
        appModel: new AppModel(),
        mapView: new MapView()
      });
    });

    it('should close the info window', function () {
      $(".dir-button").first().trigger("click");
      expect(InfoWindowView.prototype.close).toHaveBeenCalled();
    });

    it('should set selected on clicked link and unselect others', function () {
      $(".dir-button").first().trigger("click");
      expect($(".dir-button.selected").attr("id")).toEqual("walking");

      $(".dir-button").last().trigger("click");
      expect($(".dir-button.selected").attr("id")).toEqual("driving");
      expect($(".dir-button.selected").length).toEqual(1);
    });

    it('should pass destination to getDirections', function () {
      this.infoWindow.setDestination("destination");
      $(".dir-button").first().trigger("click");
      expect(MapView.prototype.getDirections).toHaveBeenCalledWith("walking", "destination");
    });
  });

  describe('when clicking on a show related link in the infowindow', function () {

  });

  describe('when opening the infowindow', function () {

    it('should close previous infowindow', function () {
      this.infoWindow = new InfoWindowView({
        appModel: new AppModel()
      });

      spyOn(this.infoWindow.infoWindow, "close");
      this.infoWindow.open(new Location(), new google.maps.Marker(), new google.maps.LatLng(0, 0));
      expect(this.infoWindow.infoWindow.close).toHaveBeenCalled();
    });

    it('should call model (Location) getI18n method (fetching the text attribute)', function () {
      spyOn(Location.prototype, "getI18n");

      this.infoWindow = new InfoWindowView({
        appModel: new AppModel()
      });

      var location = new Location({
        name: 'testName',
        directionAware: false
        });
      this.infoWindow.open(location, new google.maps.Marker(), new google.maps.LatLng(0, 0));

      expect(Location.prototype.getI18n).toHaveBeenCalledWith('text');
    });

    it('should call JST with correct values', function () {
      spyOn(JST, 'map/infoWindow').andReturn('');

      i18n.init({
        lng: 'sv-SE'
      });

      this.infoWindow = new InfoWindowView({
        appModel: new AppModel()
      });

      var location = new Location({
        name: 'testName',
        directionAware: false,
        buildingName: 'testBuilding',
        text: 'testText',
        type: 'building'
      });

      this.infoWindow.appModel.locations = {
        byBuildingAndTypeAndHandicapAdapted: function (building, types, adapted) {
          return _([ new Location({
            floor: '1'
          }) ])
        }
      }

      this.infoWindow.open(location, new google.maps.Marker(), new google.maps.LatLng(0, 0));

      expect(JST['map/infoWindow']).toHaveBeenCalledWith({
        name: 'testName, testBuilding',
        displayDirections: false,
        model: location,
        itemText: 'testText',
        hasElevators: true,
        hasEntrances: true,
        tFloors: '1'
      });
    });

    it('should call JST with correct values when other language than swedish', function () {
      spyOn(JST, 'map/infoWindow').andReturn('');

      i18n.init({
        lng: 'fr-FR'
      });

      this.infoWindow = new InfoWindowView({
        appModel: new AppModel()
      });

      var location = new Location({
        name: 'testName',
        nameEn: 'testName (en)',
        directionAware: false,
        text: 'testText',
        textEn: 'testText (en)',
        type: 'department'
      });

      this.infoWindow.open(location, new google.maps.Marker(), new google.maps.LatLng(0, 0));

      expect(JST['map/infoWindow']).toHaveBeenCalledWith({
        name: 'testName (en)',
        displayDirections: false,
        model: location,
        itemText: 'testText (en)'
      });
    });

  });

  describe('Info-window template', function () {
    it('should set hearing_loop for auditoriums when handicapAdapted', function () {
      // First expect to find no hearing loops
      expect($('#page-map').find('i[class="hearing_loop"]').size()).toEqual(0);

      var location = new Location({
        type: 'auditorium',
        handicapAdapted: true
      });

      $('#page-map').replaceWith("

");
      $('#page-map').append(JST['map/infoWindow']({
        model: location,
        itemText: '',
        displayDirections: false
      }));

      expect($('#page-map').find('i[class="hearing_loop"]').size()).toEqual(1);
    });

    it('should set hearing_loop for auditoriums when handicapAdpted', function () {
      // First expect to find no hearing loops
      expect($('#page-map').find('i[class="hearing_loop"]').size()).toEqual(0);

      var location = new Location({
        type: 'auditorium',
        handicapAdapted: false
      });

      $('#page-map').replaceWith("

");
      $('#page-map').append(JST['map/infoWindow']({
        model: location,
        itemText: '',
        displayDirections: false
      }));

      expect($('#page-map').find('i[class="hearing_loop"]').size()).toEqual(0);
      expect($('#page-map').text()).toMatch(/.*Hearing loop not available.*/);
    });

    it('should set correct building information when no accessible elevators, toilets or entrances exist', function () {

      var location = new Location({
        type: 'building',
        nonVisibleTypes: ["entrance", "elevator", "toilet"]
      });

      $('#page-map').append(JST['map/infoWindow']({
        model: location,
        itemText: '',
        hasElevators: false,
        tFloors: '',
        hasEntrances: false,
        displayDirections: false
      }));

      expect($('#page-map').find('i[class="elevator"]').size()).toEqual(0);
      expect($('#page-map').text()).toMatch(/.*Accessible lift not available.*/);

      expect($('#page-map').find('i[class="toilet"]').size()).toEqual(0);
      expect($('#page-map').text()).toMatch(/.*Accessible toilet not available.*/);

      expect($('#page-map').find('i[class="entrance"]').size()).toEqual(0);
      expect($('#page-map').text()).toMatch(/.*Accessible entrance not available.*/);
    });

    it('should set correct building information when accessible elevators, toilets or entrances exist', function () {

      var location = new Location({
        type: 'building',
        nonVisibleTypes: ["entrance", "elevator", "toilet"]
      });

      $('#page-map').append(JST['map/infoWindow']({
        model: location,
        itemText: '',
        hasElevators: true,
        tFloors: [1],
        hasEntrances: true,
        displayDirections: false
      }));

      expect($('#page-map').find('i[class="elevator"]').size()).toEqual(1);
      expect($('#page-map').text()).toMatch(/.*Accessible lift available.*/);

      expect($('#page-map').find('i[class="toilet"]').size()).toEqual(1);
      expect($('#page-map').text()).toMatch(/.*Accessible toilet available.*/);

      expect($('#page-map').find('i[class="entrance"]').size()).toEqual(1);

      expect($('#page-map').find('a[class="showRelated"]').size()).toEqual(1);
      expect($('#page-map').text()).toMatch(/.*Show accessible entrances.*/);

      expect($('#page-map').find('a[class="hideRelated"]').size()).toEqual(1);
      expect($('#page-map').text()).toMatch(/.*Hide accessible entrances.*/);
    });

  });
});
<|endoftext|>


<commit_before>window.app || (window.app = {});

//
// App launch
//
//
$.getJSON('data/countries.json', function(countries) {
  app.countries = new Backbone.Collection(countries);
  // TODO: Remove externally-loaded json - bootstrap it all
  $.getJSON('data/iif_status.json', function(parties) {

    // Get Filters info and create 2 related Collections
    $.getJSON('admin_scripts/querious/iif_status_def.json', function(filtersJSON) {

      // Init Ractive decorators
      Ractive.decorators.chosen.type.geoSearch = function(node) {
        return {
          width: '100%'
        }
      };

      // Backbone Collection for filtering
      app.parties = new Parties(parties);

      // Use just the attributes for now - might use 'Views' later
      var filterFacets = filtersJSON.attributes;

      // Create FilterDefs by removing options from each attribute
      var filterDefObjects = _.map(filterFacets, function(facet) {
        return _.omit(facet, 'options')
      })
      var filterDefs = new FilterDefs(filterDefObjects);

      // Create FilterOptions by copying properties from the attribute
      // to each of its options
      filterOptions = _.chain(filterFacets).map(function(filter) {

        var attribute = filter.name;

        // Add countries if needed
        if (filter.type == 'country') {
          // Set value and title on options
          var valueField = filter.value_field;
          var titleField = filter.title_field;

          filter.options = _.map(countries, function(country) {
            country.value = country[valueField];
            country.title = country[titleField];
            return country;
          });

          console.debug('Missing Country records for', _.select(app.parties.pluck('party'), function(i){return app.countries.findWhere({short_name: i}) == undefined}));
        }

        return _.map(filter.options, function(option) {
          // Infer value from title if requested - assumes snake case
          if (filter.value_from_title != undefined) {
            var title = option.title;
            // snake_case conversion
            option.value = title.replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase();
          };

          option.attribute = attribute;
          option.id = attribute + ':' + option.value;
          option.active = true;

          return option;
        });

      }).flatten().value();

      app.filters = new FilterOptions(filterOptions, {collectionToFilter: app.parties});
      app.filters.filterDefs = filterDefs;

      var views = filtersJSON.views;

      // Create Ractive view containing all components
      app.explorer = initExplorer(app.parties, app.filters, views);

      // jVectormap map, binding the Ractive view
      app.map = initMap(app.explorer);

    });
  });
});<commit_msg>removing countries<commit_after>window.app || (window.app = {});

//
// App launch
//
//
// TODO: Remove externally-loaded json - bootstrap it all
$.getJSON('data/iif_status.json', function(parties) {

  // Get Filters info and create 2 related Collections
  $.getJSON('admin_scripts/querious/iif_status_def.json', function(filtersJSON) {

    // Init Ractive decorators
    Ractive.decorators.chosen.type.geoSearch = function(node) {
      return {
        width: '100%'
      }
    };

    // Backbone Collection for filtering
    app.parties = new Parties(parties);

    // Use just the attributes for now - might use 'Views' later
    var filterFacets = filtersJSON.attributes;

    // Create FilterDefs by removing options from each attribute
    var filterDefObjects = _.map(filterFacets, function(facet) {
      return _.omit(facet, 'options')
    })
    var filterDefs = new FilterDefs(filterDefObjects);

    // Create FilterOptions by copying properties from the attribute
    // to each of its options
    filterOptions = _.chain(filterFacets).map(function(filter) {

      var attribute = filter.name;

      // Add countries if needed
      if (filter.type == 'country') {
        // Set value and title on options
        var valueField = filter.value_field;
        var titleField = filter.title_field;

        filter.options = _.map(countries, function(country) {
          country.value = country[valueField];
          country.title = country[titleField];
          return country;
        });

        console.debug('Missing Country records for', _.select(app.parties.pluck('party'), function(i){return app.countries.findWhere({short_name: i}) == undefined}));
      }

      return _.map(filter.options, function(option) {
        // Infer value from title if requested - assumes snake case
        if (filter.value_from_title != undefined) {
          var title = option.title;
          // snake_case conversion
          option.value = title.replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase();
        };

        option.attribute = attribute;
        option.id = attribute + ':' + option.value;
        option.active = true;

        return option;
      });

    }).flatten().value();

    app.filters = new FilterOptions(filterOptions, {collectionToFilter: app.parties});
    app.filters.filterDefs = filterDefs;

    var views = filtersJSON.views;

    // Create Ractive view containing all components
    app.explorer = initExplorer(app.parties, app.filters, views);

    // jVectormap map, binding the Ractive view
    app.map = initMap(app.explorer);

  });
});
<|endoftext|>


<commit_before>requirejs.config({
  baseUrl: '/js',
  paths: {
    'jquery': '../bower/jquery/jquery',
    'social': '../js/lib/socialmedia',
    'localized': '../bower/webmaker-i18n/localized',
    'eventEmitter': '../bower/eventEmitter',
    'webmaker-auth-client': '../bower/webmaker-auth-client',
  }
});
define(['jquery', 'social', 'localized', 'webmaker-auth-client/webmaker-auth-client'],
  function ($, SocialMedia, localized, WebmakerAuth) {
    localized.ready(function () {
      var social,
        $body = $("body"),
        $shareBtn = $("#share-btn"),
        $shareContainer = $("#share-container"),
        $likeBtn = $(".make-like-toggle"),
        $likeCount = $(".like-count"),
        $likeText = $(".like-text"),
        $likeNotLoggedInMsg = $("#like-not-logged-in"),
        $reportButton = $("#make-report-toggle"),
        $reportedText = $("#make-reported-text"),
        $reportNotLoggedInMsg = $("#report-not-logged-in"),
        $reportError = $("#make-report-error"),
        $makeReportedMsg = $("#make-reported-message"),
        googleBtn = document.getElementById("google-btn"),
        twitterBtn = document.getElementById("twitter-btn"),
        fbBtn = document.getElementById("fb-btn"),
        url = $body.data("url"),
        csrfToken = $("meta[name='csrf-token']").attr("content"),
        webmakerAuth = new WebmakerAuth({
          csrfToken: csrfToken,
          handleNewUserUI: false
        });

      var socialMessage = localized.get('DetailsShareTwitterMsg');
      social = new SocialMedia({
        message: socialMessage,
        via: "webmaker"
      });

      function shareOnClick() {
        social.hotLoad(twitterBtn, social.twitter, url);
        social.hotLoad(googleBtn, social.google, url);
        social.hotLoad(fbBtn, social.facebook, url);
        $shareBtn.addClass("hidden");
        $shareContainer.removeClass("hidden");
        $shareBtn.off("click", shareOnClick);
      }

      function openLogInWindow() {
        webmakerAuth.login();
      }

      function displayTooltip($tooltipElem, delay) {
        var timer;

        function hideTooltip(e) {
          window.removeEventListener("click", clickCallback, false);
          window.clearTimeout(timer);
          $tooltipElem.addClass("hide");
        }

        function clickCallback(e) {
          if (e.target === $tooltipElem.find("a")[0]) {
            return true;
          }
          hideTooltip();
        }

        $tooltipElem.removeClass("hide");
        timer = window.setTimeout(hideTooltip, delay);
        window.addEventListener("click", clickCallback, false);
      }

      function updateLikes(newLen) {
        $likeBtn.toggleClass("icon-heart icon-heart-empty");
        if (typeof newLen === "undefined") {
          return;
        } else if (newLen === 0) {
          $likeText.html(localized.get("Like-0"));
        } else if (newLen === 1) {
          $likeText.html(localized.get("Like-1"));
        } else {
          $likeText.html(localized.get("Like-n"));
        }
        $likeCount.html(newLen);
      }

      function updateReport(method) {
        $reportButton.toggleClass("icon-flag icon-flag-alt");
        $reportedText.toggleClass("hide");
        if (method === "/report") {
          displayTooltip($makeReportedMsg, 10000);
        }
      }

      $likeNotLoggedInMsg.on("click", openLogInWindow);
      $reportNotLoggedInMsg.on("click", openLogInWindow);

      $shareBtn.on("click", shareOnClick);
      $shareBtn.on("click", shareOnClick);

      $likeBtn.on("click", function (e) {
        if (e.target !== $likeBtn[0]) {
          return;
        }

        e.preventDefault();

        var makeID = $likeBtn.data("make-id"),
          method;

        if ($likeBtn.hasClass("icon-heart")) {
          method = "/unlike";
        } else {
          method = "/like";
        }

        $.post(method, {
          makeID: makeID,
          _csrf: csrfToken
        }, function (res) {
          updateLikes(res.likes.length);

        }).fail(function (res) {
          if (res.status === 401) {
            displayTooltip($likeNotLoggedInMsg, 5000);
          } else if (res.status === 400) {
            // user already likes/unliked
            updateLikes();
          }
        });
      });

      $reportButton.on("click", function (e) {
        if (e.target !== $reportButton[0]) {
          return;
        }

        e.preventDefault();

        var makeID = $reportButton.data("make-id"),
          method;

        if ($reportButton.hasClass("icon-flag")) {
          method = "/cancelReport";
        } else {
          method = "/report";
        }

        $.post(method, {
          makeID: makeID,
          _csrf: csrfToken
        }, function (res) {
          updateReport(method);
        }).fail(function (res) {
          if (res.status === 401) {
            displayTooltip($reportNotLoggedInMsg, 5000);
          } else if (res.status === 400) {
            // already reported/cancelled
            updateReport(method);
          } else {
            displayTooltip($reportError, 5000);
          }
        });
      });

      webmakerAuth.verify();
    });
  });
<commit_msg>Bug 978087 - Complete user action on details page after sign in<commit_after>requirejs.config({
  baseUrl: '/js',
  paths: {
    'jquery': '../bower/jquery/jquery',
    'social': '../js/lib/socialmedia',
    'localized': '../bower/webmaker-i18n/localized',
    'eventEmitter': '../bower/eventEmitter',
    'webmaker-auth-client': '../bower/webmaker-auth-client',
  }
});
define(['jquery', 'social', 'localized', 'webmaker-auth-client/webmaker-auth-client'],
  function ($, SocialMedia, localized, WebmakerAuth) {
    localized.ready(function () {
      var social,
        $body = $("body"),
        $shareBtn = $("#share-btn"),
        $shareContainer = $("#share-container"),
        $likeBtn = $(".make-like-toggle"),
        $likeCount = $(".like-count"),
        $likeText = $(".like-text"),
        $likeNotLoggedInMsg = $("#like-not-logged-in"),
        $reportButton = $("#make-report-toggle"),
        $reportedText = $("#make-reported-text"),
        $reportNotLoggedInMsg = $("#report-not-logged-in"),
        $reportError = $("#make-report-error"),
        $makeReportedMsg = $("#make-reported-message"),
        googleBtn = document.getElementById("google-btn"),
        twitterBtn = document.getElementById("twitter-btn"),
        fbBtn = document.getElementById("fb-btn"),
        url = $body.data("url"),
        csrfToken = $("meta[name='csrf-token']").attr("content"),
        webmakerAuth = new WebmakerAuth({
          csrfToken: csrfToken,
          handleNewUserUI: false
        });

      var socialMessage = localized.get('DetailsShareTwitterMsg');
      social = new SocialMedia({
        message: socialMessage,
        via: "webmaker"
      });

      function shareOnClick() {
        social.hotLoad(twitterBtn, social.twitter, url);
        social.hotLoad(googleBtn, social.google, url);
        social.hotLoad(fbBtn, social.facebook, url);
        $shareBtn.addClass("hidden");
        $shareContainer.removeClass("hidden");
        $shareBtn.off("click", shareOnClick);
      }

      $shareBtn.on("click", shareOnClick);

      function openLogInWindow(actionCallback) {
        function onLogin() {
          webmakerAuth.off("login", onLogin);
          webmakerAuth.off("error", onError);
          actionCallback();
        }

        function onError() {
          webmakerAuth.off("login", onLogin);
          webmakerAuth.off("error", onError);
        }
        webmakerAuth.on("login", onLogin);
        webmakerAuth.on("error", onError);
        webmakerAuth.login();
      }

      function displayTooltip($tooltipElem, delay) {
        var timer;

        function hideTooltip(e) {
          window.removeEventListener("click", clickCallback, false);
          window.clearTimeout(timer);
          $tooltipElem.addClass("hide");
        }

        function clickCallback(e) {
          if (e.target === $tooltipElem.find("a")[0]) {
            return true;
          }
          hideTooltip();
        }

        $tooltipElem.removeClass("hide");
        timer = window.setTimeout(hideTooltip, delay);
        window.addEventListener("click", clickCallback, false);
      }

      // Like event handlers

      function likeRequest() {
        var makeID = $likeBtn.data("make-id"),
          method;

        if ($likeBtn.hasClass("icon-heart")) {
          method = "/unlike";
        } else {
          method = "/like";
        }

        $.post(method, {
          makeID: makeID,
          _csrf: csrfToken
        }, function (res) {
          updateLikes(res.likes.length);

        }).fail(function (res) {
          if (res.status === 401) {
            displayTooltip($likeNotLoggedInMsg, 5000);
          } else if (res.status === 400) {
            // user already likes/unliked
            updateLikes();
          }
        });
      }

      function updateLikes(newLen) {
        $likeBtn.toggleClass("icon-heart icon-heart-empty");
        if (typeof newLen === "undefined") {
          return;
        } else if (newLen === 0) {
          $likeText.html(localized.get("Like-0"));
        } else if (newLen === 1) {
          $likeText.html(localized.get("Like-1"));
        } else {
          $likeText.html(localized.get("Like-n"));
        }
        $likeCount.html(newLen);
      }

      $likeBtn.on("click", function (e) {
        if (e.target !== $likeBtn[0]) {
          return;
        }
        e.preventDefault();
        likeRequest();
      });

      $likeNotLoggedInMsg.on("click", function () {
        openLogInWindow(likeRequest);
      });

      // Report Event Handlers

      function reportRequest() {
        var makeID = $reportButton.data("make-id"),
          method;

        if ($reportButton.hasClass("icon-flag")) {
          method = "/cancelReport";
        } else {
          method = "/report";
        }

        $.post(method, {
          makeID: makeID,
          _csrf: csrfToken
        }, function (res) {
          updateReport(method);
        }).fail(function (res) {
          if (res.status === 401) {
            displayTooltip($reportNotLoggedInMsg, 5000);
          } else if (res.status === 400) {
            // already reported/cancelled
            updateReport(method);
          } else {
            displayTooltip($reportError, 5000);
          }
        });
      }

      function updateReport(method) {
        $reportButton.toggleClass("icon-flag icon-flag-alt");
        $reportedText.toggleClass("hide");
        if (method === "/report") {
          displayTooltip($makeReportedMsg, 10000);
        }
      }

      $reportButton.on("click", function (e) {
        if (e.target !== $reportButton[0]) {
          return;
        }
        e.preventDefault();
        reportRequest();
      });

      $reportNotLoggedInMsg.on("click", function () {
        openLogInWindow(reportRequest);
      });

      webmakerAuth.verify();
    });
  });
<|endoftext|>


<commit_before>import pluginList from "../data/plugins.json";
import browserslist from "browserslist";

export const MODULE_TRANSFORMATIONS = {
  "amd": "transform-es2015-modules-amd",
  "commonjs": "transform-es2015-modules-commonjs",
  "systemjs": "transform-es2015-modules-systemjs",
  "umd": "transform-es2015-modules-umd"
};

/**
 * Determine if a transformation is required
 * @param  {Object}  supportedEnvironments  An Object containing environment keys and the lowest
 *                                          supported version as a value
 * @param  {Object}  plugin                 An Object containing environment keys and the lowest
 *                                          version the feature was implmented in as a value
 * @return {Boolean}  Whether or not the transformation is required
 */
export const isPluginRequired = (supportedEnvironments, plugin) => {
  if (supportedEnvironments.browsers) {
    supportedEnvironments = getTargets(supportedEnvironments);
  }

  const targetEnvironments = Object.keys(supportedEnvironments);

  if (targetEnvironments.length === 0) { return true; }

  const isRequiredForEnvironments = targetEnvironments
    .filter((environment) => {
      // Feature is not implemented in that environment
      if (!plugin[environment]) { return true; }

      const lowestImplementedVersion = plugin[environment];
      const lowestTargetedVersion = supportedEnvironments[environment];

      if (lowestTargetedVersion < lowestImplementedVersion) {
        return true;
      }

      return false;
    });

  return isRequiredForEnvironments.length > 0 ? true : false;
};

const isBrowsersQueryValid = (browsers) => {
  return typeof browsers === "string" || Array.isArray(browsers);
};

const getLowestVersions = (browsers) => {
  return browsers.reduce((all, browser) => {
    const [browserName, browserVersion] = browser.split(" ");
    all[browserName] = parseInt(browserVersion);
    return all;
  }, {});
};

const mergeBrowsers = (fromQuery, fromTarget) => {
  return Object.keys(fromTarget).reduce((queryObj, targKey) => {
    if (targKey !== "browsers") {
      queryObj[targKey] = fromTarget[targKey];
    }
    return queryObj;
  }, fromQuery);
};

export const getCurrentNodeVersion = () => {
  return parseFloat(process.versions.node);
};

export const getTargets = (targetOpts = {}) => {
  if (targetOpts.node === true || targetOpts.node === "current") {
    targetOpts.node = getCurrentNodeVersion();
  }

  const browserOpts = targetOpts.browsers;
  if (isBrowsersQueryValid(browserOpts)) {
    const queryBrowsers = getLowestVersions(browserslist(browserOpts));
    return mergeBrowsers(queryBrowsers, targetOpts);
  }
  return targetOpts;
};

// TODO: Allow specifying plugins as either shortened or full name
// babel-plugin-transform-es2015-classes
// transform-es2015-classes
export const validateLooseOption = (looseOpt = false) => {
  if (typeof looseOpt !== "boolean") {
    throw new Error("Preset env: 'loose' option must be a boolean.");
  }

  return looseOpt;
};

export const validateModulesOption = (modulesOpt = "commonjs") => {
  if (modulesOpt !== false && Object.keys(MODULE_TRANSFORMATIONS).indexOf(modulesOpt) === -1) {
    throw new Error("The 'modules' option must be 'false' to indicate no modules\n" +
      "or a module type which be be one of: 'commonjs' (default), 'amd', 'umd', 'systemjs'");
  }

  return modulesOpt;
};

export const validateWhitelistOption = (whitelistOpt = []) => {
  if (!Array.isArray(whitelistOpt)) {
    throw new Error(`The 'whitelist' option must be an Array<string> of plugins
      {
        "presets": [
          ["env", {
            "targets": {
              "chrome": 50
            },
            "whitelist": ["transform-es2015-arrow-functions"]
          }]
        ]
      }
      was passed "${whitelistOpt}" instead
    `);
  }

  return whitelistOpt;
};

export default function buildPreset(context, opts = {}) {
  const loose = validateLooseOption(opts.loose);
  const moduleType = validateModulesOption(opts.modules);
  const whitelist = validateWhitelistOption(opts.whitelist);
  const targets = getTargets(opts.targets);
  const debug = opts.debug;

  let transformations = Object.keys(pluginList)
    .filter((pluginName) => isPluginRequired(targets, pluginList[pluginName]));

  if (debug) {
    console.log("");
    console.log(`Using targets: ${JSON.stringify(targets, null, 2)}`);
    console.log("");
    console.log("Using plugins:");
    console.log("");
    console.log(`module: ${moduleType}`);
    transformations.forEach((transform) => {
      let envList = pluginList[transform];
      let filteredList = Object.keys(targets)
      .reduce((a, b) => {
        a[b] = envList[b];
        return a;
      }, {});
      console.log(transform, JSON.stringify(filteredList, null, 2));
    });
  }

  transformations = [...transformations, ...whitelist].map((pluginName) => {
    return [require(`babel-plugin-${pluginName}`), { loose }];
  });

  const modules = [
    moduleType === "commonjs" && [require("babel-plugin-transform-es2015-modules-commonjs"), { loose }],
    moduleType === "systemjs" && [require("babel-plugin-transform-es2015-modules-systemjs"), { loose }],
    moduleType === "amd" && [require("babel-plugin-transform-es2015-modules-amd"), { loose }],
    moduleType === "umd" && [require("babel-plugin-transform-es2015-modules-umd"), { loose }],
  ].filter(Boolean);

  return {
    plugins: [
      ...modules,
      ...transformations
    ]
  };
}
<commit_msg>Rename ios_saf in browserslist data to ios, ignore unknown browsers<commit_after>import pluginList from "../data/plugins.json";
import browserslist from "browserslist";

export const MODULE_TRANSFORMATIONS = {
  "amd": "transform-es2015-modules-amd",
  "commonjs": "transform-es2015-modules-commonjs",
  "systemjs": "transform-es2015-modules-systemjs",
  "umd": "transform-es2015-modules-umd"
};

/**
 * Determine if a transformation is required
 * @param  {Object}  supportedEnvironments  An Object containing environment keys and the lowest
 *                                          supported version as a value
 * @param  {Object}  plugin                 An Object containing environment keys and the lowest
 *                                          version the feature was implmented in as a value
 * @return {Boolean}  Whether or not the transformation is required
 */
export const isPluginRequired = (supportedEnvironments, plugin) => {
  if (supportedEnvironments.browsers) {
    supportedEnvironments = getTargets(supportedEnvironments);
  }

  const targetEnvironments = Object.keys(supportedEnvironments);

  if (targetEnvironments.length === 0) { return true; }

  const isRequiredForEnvironments = targetEnvironments
    .filter((environment) => {
      // Feature is not implemented in that environment
      if (!plugin[environment]) { return true; }

      const lowestImplementedVersion = plugin[environment];
      const lowestTargetedVersion = supportedEnvironments[environment];

      if (lowestTargetedVersion < lowestImplementedVersion) {
        return true;
      }

      return false;
    });

  return isRequiredForEnvironments.length > 0 ? true : false;
};

const isBrowsersQueryValid = (browsers) => {
  return typeof browsers === "string" || Array.isArray(browsers);
};

const browserNameMap = {
  chrome: 'chrome',
  edge: 'edge',
  firefox: 'firefox',
  ie: 'ie',
  ios_saf: 'ios',
  safari: 'safari'
}

const getLowestVersions = (browsers) => {
  return browsers.reduce((all, browser) => {
    const [browserName, browserVersion] = browser.split(" ");
    if (browserName in browserNameMap) {
      all[browserNameMap[browserName]] = parseInt(browserVersion);
    }
    return all;
  }, {});
};

const mergeBrowsers = (fromQuery, fromTarget) => {
  return Object.keys(fromTarget).reduce((queryObj, targKey) => {
    if (targKey !== "browsers") {
      queryObj[targKey] = fromTarget[targKey];
    }
    return queryObj;
  }, fromQuery);
};

export const getCurrentNodeVersion = () => {
  return parseFloat(process.versions.node);
};

export const getTargets = (targetOpts = {}) => {
  if (targetOpts.node === true || targetOpts.node === "current") {
    targetOpts.node = getCurrentNodeVersion();
  }

  const browserOpts = targetOpts.browsers;
  if (isBrowsersQueryValid(browserOpts)) {
    const queryBrowsers = getLowestVersions(browserslist(browserOpts));
    return mergeBrowsers(queryBrowsers, targetOpts);
  }
  return targetOpts;
};

// TODO: Allow specifying plugins as either shortened or full name
// babel-plugin-transform-es2015-classes
// transform-es2015-classes
export const validateLooseOption = (looseOpt = false) => {
  if (typeof looseOpt !== "boolean") {
    throw new Error("Preset env: 'loose' option must be a boolean.");
  }

  return looseOpt;
};

export const validateModulesOption = (modulesOpt = "commonjs") => {
  if (modulesOpt !== false && Object.keys(MODULE_TRANSFORMATIONS).indexOf(modulesOpt) === -1) {
    throw new Error("The 'modules' option must be 'false' to indicate no modules\n" +
      "or a module type which be be one of: 'commonjs' (default), 'amd', 'umd', 'systemjs'");
  }

  return modulesOpt;
};

export const validateWhitelistOption = (whitelistOpt = []) => {
  if (!Array.isArray(whitelistOpt)) {
    throw new Error(`The 'whitelist' option must be an Array<string> of plugins
      {
        "presets": [
          ["env", {
            "targets": {
              "chrome": 50
            },
            "whitelist": ["transform-es2015-arrow-functions"]
          }]
        ]
      }
      was passed "${whitelistOpt}" instead
    `);
  }

  return whitelistOpt;
};

export default function buildPreset(context, opts = {}) {
  const loose = validateLooseOption(opts.loose);
  const moduleType = validateModulesOption(opts.modules);
  const whitelist = validateWhitelistOption(opts.whitelist);
  const targets = getTargets(opts.targets);
  const debug = opts.debug;

  let transformations = Object.keys(pluginList)
    .filter((pluginName) => isPluginRequired(targets, pluginList[pluginName]));

  if (debug) {
    console.log("");
    console.log(`Using targets: ${JSON.stringify(targets, null, 2)}`);
    console.log("");
    console.log("Using plugins:");
    console.log("");
    console.log(`module: ${moduleType}`);
    transformations.forEach((transform) => {
      let envList = pluginList[transform];
      let filteredList = Object.keys(targets)
      .reduce((a, b) => {
        a[b] = envList[b];
        return a;
      }, {});
      console.log(transform, JSON.stringify(filteredList, null, 2));
    });
  }

  transformations = [...transformations, ...whitelist].map((pluginName) => {
    return [require(`babel-plugin-${pluginName}`), { loose }];
  });

  const modules = [
    moduleType === "commonjs" && [require("babel-plugin-transform-es2015-modules-commonjs"), { loose }],
    moduleType === "systemjs" && [require("babel-plugin-transform-es2015-modules-systemjs"), { loose }],
    moduleType === "amd" && [require("babel-plugin-transform-es2015-modules-amd"), { loose }],
    moduleType === "umd" && [require("babel-plugin-transform-es2015-modules-umd"), { loose }],
  ].filter(Boolean);

  return {
    plugins: [
      ...modules,
      ...transformations
    ]
  };
}
<|endoftext|>