<commit_before>// @remove-on-eject-begin
/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */
// @remove-on-eject-end
'use strict';

// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'production';
process.env.NODE_ENV = 'production';

// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
process.on('unhandledRejection', err => {
  throw err;
});

// Ensure environment variables are read.
require('../config/env');
// @remove-on-eject-begin
// Do the preflight checks (only happens before eject).
const verifyPackageTree = require('./utils/verifyPackageTree');
if (process.env.SKIP_PREFLIGHT_CHECK !== 'true') {
  verifyPackageTree();
}
const verifyTypeScriptSetup = require('./utils/verifyTypeScriptSetup');
verifyTypeScriptSetup();
// @remove-on-eject-end

const path = require('path');
const chalk = require('react-dev-utils/chalk');
const fs = require('fs-extra');
const webpack = require('webpack');
const configFactory = require('../config/webpack.config');
const paths = require('../config/paths');
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
const printHostingInstructions = require('react-dev-utils/printHostingInstructions');
const FileSizeReporter = require('react-dev-utils/FileSizeReporter');
const printBuildError = require('react-dev-utils/printBuildError');

const measureFileSizesBeforeBuild =
  FileSizeReporter.measureFileSizesBeforeBuild;
const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild;
const useYarn = fs.existsSync(paths.yarnLockFile);

// These sizes are pretty large. We'll warn for bundles exceeding them.
const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;

const isInteractive = process.stdout.isTTY;

// Warn and crash if required files are missing
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
  process.exit(1);
}

// Generate configuration
const config = configFactory('production');

// We require that you explicitly set browsers and do not fall back to
// browserslist defaults.
const { checkBrowsers } = require('react-dev-utils/browsersHelper');
checkBrowsers(paths.appPath, isInteractive)
  .then(() => {
    // First, read the current file sizes in build directory.
    // This lets us display how much they changed later.
    return measureFileSizesBeforeBuild(paths.appBuild);
  })
  .then(previousFileSizes => {
    // Remove all content but keep the directory so that
    // if you're in it, you don't end up in Trash
    fs.emptyDirSync(paths.appBuild);
    // Merge with the public folder
    copyPublicFolder();
    // Start the webpack build
    return build(previousFileSizes);
  })
  .then(
    ({ stats, previousFileSizes, warnings }) => {
      if (warnings.length) {
        console.log(chalk.yellow('Compiled with warnings.\n'));
        console.log(warnings.join('\n\n'));
        console.log(
          '\nSearch for the ' +
            chalk.underline(chalk.yellow('keywords')) +
            ' to learn more about each warning.'
        );
        console.log(
          'To ignore, add ' +
            chalk.cyan('// eslint-disable-next-line') +
            ' to the line before.\n'
        );
      } else {
        console.log(chalk.green('Compiled successfully.\n'));
      }

      console.log('File sizes after gzip:\n');
      printFileSizesAfterBuild(
        stats,
        previousFileSizes,
        paths.appBuild,
        WARN_AFTER_BUNDLE_GZIP_SIZE,
        WARN_AFTER_CHUNK_GZIP_SIZE
      );
      console.log();

      const appPackage = require(paths.appPackageJson);
      const publicUrl = paths.publicUrl;
      const publicPath = config.output.publicPath;
      const buildFolder = path.relative(process.cwd(), paths.appBuild);
      printHostingInstructions(
        appPackage,
        publicUrl,
        publicPath,
        buildFolder,
        useYarn
      );
    },
    err => {
      const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true';
      if (tscCompileOnError) {
        console.log(
          chalk.yellow(
            'Compiled with the following type errors (you may want to check these before deploying your app):\n'
          )
        );
        printBuildError(err);
      } else {
        console.log(chalk.red('Failed to compile.\n'));
        printBuildError(err);
        process.exit(1);
      }
    }
  )
  .catch(err => {
    if (err && err.message) {
      console.log(err.message);
    }
    process.exit(1);
  });

// Create the production build and print the deployment instructions.
function build(previousFileSizes) {
  // We used to support resolving modules according to `NODE_PATH`.
  // This now has been deprecated in favor of jsconfig/tsconfig.json
  // This lets you use absolute paths in imports inside large monorepos:
  if (process.env.NODE_PATH) {
    console.log(
      chalk.yellow(
        'Setting NODE_PATH to resolve modules absolutely has been deprecated in favor of setting baseUrl in jsconfig.json (or tsconfig.json if you are using TypeScript) and will be removed in a future major release of create-react-app.'
      )
    );
    console.log();
  }

  console.log('Creating an optimized production build...');

  const compiler = webpack(config);
  return new Promise((resolve, reject) => {
    compiler.run((err, stats) => {
      let messages;
      if (err) {
        if (!err.message) {
          return reject(err);
        }
        messages = formatWebpackMessages({
          errors: [err.message],
          warnings: [],
        });
      } else {
        messages = formatWebpackMessages(
          stats.toJson({ all: false, warnings: true, errors: true })
        );
      }
      if (messages.errors.length) {
        // Only keep the first error. Others are often indicative
        // of the same problem, but confuse the reader with noise.
        if (messages.errors.length > 1) {
          messages.errors.length = 1;
        }
        return reject(new Error(messages.errors.join('\n\n')));
      }
      if (
        process.env.CI &&
        (typeof process.env.CI !== 'string' ||
          process.env.CI.toLowerCase() !== 'false') &&
        messages.warnings.length
      ) {
        console.log(
          chalk.yellow(
            '\nTreating warnings as errors because process.env.CI = true.\n' +
              'Most CI servers set it automatically.\n'
          )
        );
        return reject(new Error(messages.warnings.join('\n\n')));
      }

      return resolve({
        stats,
        previousFileSizes,
        warnings: messages.warnings,
      });
    });
  });
}

function copyPublicFolder() {
  fs.copySync(paths.appPublic, paths.appBuild, {
    dereference: true,
    filter: file => file !== paths.appHtml,
  });
}
<commit_msg>Add additional information for postcss errors (#6282) (#6352)<commit_after>// @remove-on-eject-begin
/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */
// @remove-on-eject-end
'use strict';

// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'production';
process.env.NODE_ENV = 'production';

// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
process.on('unhandledRejection', err => {
  throw err;
});

// Ensure environment variables are read.
require('../config/env');
// @remove-on-eject-begin
// Do the preflight checks (only happens before eject).
const verifyPackageTree = require('./utils/verifyPackageTree');
if (process.env.SKIP_PREFLIGHT_CHECK !== 'true') {
  verifyPackageTree();
}
const verifyTypeScriptSetup = require('./utils/verifyTypeScriptSetup');
verifyTypeScriptSetup();
// @remove-on-eject-end

const path = require('path');
const chalk = require('react-dev-utils/chalk');
const fs = require('fs-extra');
const webpack = require('webpack');
const configFactory = require('../config/webpack.config');
const paths = require('../config/paths');
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
const printHostingInstructions = require('react-dev-utils/printHostingInstructions');
const FileSizeReporter = require('react-dev-utils/FileSizeReporter');
const printBuildError = require('react-dev-utils/printBuildError');

const measureFileSizesBeforeBuild =
  FileSizeReporter.measureFileSizesBeforeBuild;
const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild;
const useYarn = fs.existsSync(paths.yarnLockFile);

// These sizes are pretty large. We'll warn for bundles exceeding them.
const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;

const isInteractive = process.stdout.isTTY;

// Warn and crash if required files are missing
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
  process.exit(1);
}

// Generate configuration
const config = configFactory('production');

// We require that you explicitly set browsers and do not fall back to
// browserslist defaults.
const { checkBrowsers } = require('react-dev-utils/browsersHelper');
checkBrowsers(paths.appPath, isInteractive)
  .then(() => {
    // First, read the current file sizes in build directory.
    // This lets us display how much they changed later.
    return measureFileSizesBeforeBuild(paths.appBuild);
  })
  .then(previousFileSizes => {
    // Remove all content but keep the directory so that
    // if you're in it, you don't end up in Trash
    fs.emptyDirSync(paths.appBuild);
    // Merge with the public folder
    copyPublicFolder();
    // Start the webpack build
    return build(previousFileSizes);
  })
  .then(
    ({ stats, previousFileSizes, warnings }) => {
      if (warnings.length) {
        console.log(chalk.yellow('Compiled with warnings.\n'));
        console.log(warnings.join('\n\n'));
        console.log(
          '\nSearch for the ' +
            chalk.underline(chalk.yellow('keywords')) +
            ' to learn more about each warning.'
        );
        console.log(
          'To ignore, add ' +
            chalk.cyan('// eslint-disable-next-line') +
            ' to the line before.\n'
        );
      } else {
        console.log(chalk.green('Compiled successfully.\n'));
      }

      console.log('File sizes after gzip:\n');
      printFileSizesAfterBuild(
        stats,
        previousFileSizes,
        paths.appBuild,
        WARN_AFTER_BUNDLE_GZIP_SIZE,
        WARN_AFTER_CHUNK_GZIP_SIZE
      );
      console.log();

      const appPackage = require(paths.appPackageJson);
      const publicUrl = paths.publicUrl;
      const publicPath = config.output.publicPath;
      const buildFolder = path.relative(process.cwd(), paths.appBuild);
      printHostingInstructions(
        appPackage,
        publicUrl,
        publicPath,
        buildFolder,
        useYarn
      );
    },
    err => {
      const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true';
      if (tscCompileOnError) {
        console.log(
          chalk.yellow(
            'Compiled with the following type errors (you may want to check these before deploying your app):\n'
          )
        );
        printBuildError(err);
      } else {
        console.log(chalk.red('Failed to compile.\n'));
        printBuildError(err);
        process.exit(1);
      }
    }
  )
  .catch(err => {
    if (err && err.message) {
      console.log(err.message);
    }
    process.exit(1);
  });

// Create the production build and print the deployment instructions.
function build(previousFileSizes) {
  // We used to support resolving modules according to `NODE_PATH`.
  // This now has been deprecated in favor of jsconfig/tsconfig.json
  // This lets you use absolute paths in imports inside large monorepos:
  if (process.env.NODE_PATH) {
    console.log(
      chalk.yellow(
        'Setting NODE_PATH to resolve modules absolutely has been deprecated in favor of setting baseUrl in jsconfig.json (or tsconfig.json if you are using TypeScript) and will be removed in a future major release of create-react-app.'
      )
    );
    console.log();
  }

  console.log('Creating an optimized production build...');

  const compiler = webpack(config);
  return new Promise((resolve, reject) => {
    compiler.run((err, stats) => {
      let messages;
      if (err) {
        if (!err.message) {
          return reject(err);
        }

        let errMessage = err.message;

        // Add additional information for postcss errors
        if (err.hasOwnProperty('postcssNode')) {
          errMessage +=
            '\nCompileError: Begins at CSS selector ' +
            err['postcssNode'].selector;
        }

        messages = formatWebpackMessages({
          errors: [errMessage],
          warnings: [],
        });
      } else {
        messages = formatWebpackMessages(
          stats.toJson({ all: false, warnings: true, errors: true })
        );
      }
      if (messages.errors.length) {
        // Only keep the first error. Others are often indicative
        // of the same problem, but confuse the reader with noise.
        if (messages.errors.length > 1) {
          messages.errors.length = 1;
        }
        return reject(new Error(messages.errors.join('\n\n')));
      }
      if (
        process.env.CI &&
        (typeof process.env.CI !== 'string' ||
          process.env.CI.toLowerCase() !== 'false') &&
        messages.warnings.length
      ) {
        console.log(
          chalk.yellow(
            '\nTreating warnings as errors because process.env.CI = true.\n' +
              'Most CI servers set it automatically.\n'
          )
        );
        return reject(new Error(messages.warnings.join('\n\n')));
      }

      return resolve({
        stats,
        previousFileSizes,
        warnings: messages.warnings,
      });
    });
  });
}

function copyPublicFolder() {
  fs.copySync(paths.appPublic, paths.appBuild, {
    dereference: true,
    filter: file => file !== paths.appHtml,
  });
}
<|endoftext|>


<commit_before>// Public exports
module.exports =    premock;
                    premock.withoutPersistence = premockWithoutPersistence;

var MaybeFunction = require('./LaterFunction.js');
var HeapCallStore = require('./HeapCallStore.js');
var LocalCallStore = require('./LocalCallStore.js');
var proxyLaterFunction = require('./proxyLaterFunction.js');
var replayCalls = require('./replayCalls.js');
var canUseLocalStorage = require('./canUseLocalStorage.js');

function premock(name, promise) {
    if (name === undefined) {
        throw new Error('Premock: needs a storage ID key');
    }

    if (canUseLocalStorage() === false) {
        throw new Error('Premock: did not detect localStorage');
    }

    var callStore = new LocalCallStore(name.toString());
    return createPremocker(callStore, promise);
}

function premockWithoutPersistence(promise) {
	var callStore = new HeapCallStore();
	return createPremocker(callStore, promise);
}

function createPremocker(callStore, pendingImplementation) {
	var maybeFunction = new MaybeFunction();
	var proxy = proxyLaterFunction(maybeFunction.getImplementation, callStore);

	proxy.resolve = function resolvePremock(implementation) {
		maybeFunction.resolve(implementation);
		replayCalls(callStore.getCalls(), implementation);
	};

    // We can pass in a 'pendingImplementation' promise that will replaced the premocked function on resolution
	if (pendingImplementation && pendingImplementation.then) {
		pendingImplementation.then(proxy.resolve);
	}

	return proxy;
}
<commit_msg>laterFunction<commit_after>// Public exports
module.exports =    premock;
                    premock.withoutPersistence = premockWithoutPersistence;

var LaterFunction = require('./LaterFunction.js');
var HeapCallStore = require('./HeapCallStore.js');
var LocalCallStore = require('./LocalCallStore.js');
var proxyLaterFunction = require('./proxyLaterFunction.js');
var replayCalls = require('./replayCalls.js');
var canUseLocalStorage = require('./canUseLocalStorage.js');

function premock(name, promise) {
    if (name === undefined) {
        throw new Error('Premock: needs a storage ID key');
    }

    if (canUseLocalStorage() === false) {
        throw new Error('Premock: did not detect localStorage');
    }

    var callStore = new LocalCallStore(name.toString());
    return createPremocker(callStore, promise);
}

function premockWithoutPersistence(promise) {
	var callStore = new HeapCallStore();
	return createPremocker(callStore, promise);
}

function createPremocker(callStore, pendingImplementation) {
	var laterFunction = new LaterFunction();
	var proxy = proxyLaterFunction(laterFunction.getImplementation, callStore);

	proxy.resolve = function resolvePremock(implementation) {
		laterFunction.resolve(implementation);
		replayCalls(callStore.getCalls(), implementation);
	};

    // We can pass in a 'pendingImplementation' promise that will replaced the premocked function on resolution
	if (pendingImplementation && pendingImplementation.then) {
		pendingImplementation.then(proxy.resolve);
	}

	return proxy;
}
<|endoftext|>


<commit_before>/*
Constructors for SCXML events, since the browser's built-in DOM Events
are not ideally suited for that role.
*/

// the basic constructor:
SCxml.Event=function SCxmlEvent(name, type)
{
	this.name=name
	this.timestamp=new Date().getTime()
	this.type=type||"platform"
}

SCxml.Event.prototype.toString=function ()
{ return "SCxmlEvent("+this.name+")" }
SCxml.Event.prototype.match=function (t)
// matches transitions and events, e.g. "user.*" matches "user.login"
// the argument is an actual <transtion> element
{
	pattern=t.getAttribute("event").split(".")
	event=this.name.split(".")
	if(pattern.length>event.length) return false
	for(var i=0; i<pattern.length; i++)
		if(pattern[i]!="*" && pattern[i]!=event[i]) return false
	return true
}

// sub-constructors for internal, error and external events:

SCxml.InternalEvent=function (name, src)
{
	SCxml.Event.call(this, name, "internal")
	this.srcElement=src||null
}
SCxml.InternalEvent.prototype=new SCxml.Event()
SCxml.InternalEvent.prototype.constructor=SCxml.InternalEvent

SCxml.Error=function (name, src, err)
{
	SCxml.Event.call(this, name)
	this.srcElement=src||null
	this.err=err
	if(src.tagName=="send")
		this.sendid=src.getAttribute("id")
}
SCxml.Error.prototype=new SCxml.Event()
SCxml.Error.prototype.constructor=SCxml.Error

SCxml.ExternalEvent=function (name, origin, origintype,
	invokeid, data)
{
	SCxml.Event.call(this, name, "external")
	this.origin=origin||""
	this.origintype=origintype||""
	this.invokeid=invokeid||""
	this.data=data
}
SCxml.ExternalEvent.prototype=new SCxml.Event()
SCxml.ExternalEvent.prototype.constructor=SCxml.ExternalEvent
<commit_msg>minor fix<commit_after>/*
Constructors for SCXML events, since the browser's built-in DOM Events
are not ideally suited for that role.
*/

// the basic constructor:
SCxml.Event=function SCxmlEvent(name, type)
{
	this.name=name
	this.timestamp=new Date().getTime()
	this.type=type||"platform"
}

SCxml.Event.prototype.toString=function ()
{ return "SCxmlEvent("+this.name+")" }
SCxml.Event.prototype.match=function (t)
// matches transitions and events, e.g. "user.*" matches "user.login"
// the argument is an actual <transtion> element
{
	pattern=t.getAttribute("event").split(".")
	event=this.name.split(".")
	if(pattern.length>event.length) return false
	for(var i=0; i<pattern.length; i++)
		if(pattern[i]!="*" && pattern[i]!=event[i]) return false
	return true
}

// sub-constructors for internal, error and external events:

SCxml.InternalEvent=function (name, src)
{
	SCxml.Event.call(this, name, "internal")
	this.srcElement=src||null
}
SCxml.InternalEvent.prototype=new SCxml.Event()
SCxml.InternalEvent.prototype.constructor=SCxml.InternalEvent

SCxml.Error=function (name, src, err)
{
	SCxml.Event.call(this, name)
	this.srcElement=src||null
	this.err=err
	if(src && src.tagName=="send")
		this.sendid=src.getAttribute("id")
}
SCxml.Error.prototype=new SCxml.Event()
SCxml.Error.prototype.constructor=SCxml.Error

SCxml.ExternalEvent=function (name, origin, origintype,
	invokeid, data)
{
	SCxml.Event.call(this, name, "external")
	this.origin=origin||""
	this.origintype=origintype||""
	this.invokeid=invokeid||""
	this.data=data
}
SCxml.ExternalEvent.prototype=new SCxml.Event()
SCxml.ExternalEvent.prototype.constructor=SCxml.ExternalEvent
<|endoftext|>


<commit_before>const { Menu } = require( 'electron' );
const mainWindow = require( './main-window' );
const config = require( './config' );

module.exports = function createTrayMenu( options ) {
	const recentFiles = config.get( 'recent-files' ) || [];

	const trayMenu = Menu.buildFromTemplate( [
		{
			label: 'recent files',
			type: 'submenu',
			submenu: recentFiles.map( ( { name, path } ) => {
				return { label: name, type: 'normal', click() {
					const win = mainWindow();
					win.webContents.send( 'go-preview', { name, path } );
					win.center();
					win.focus();
				} };
			} ),
		},
		{ label: 'quit', type: 'normal', role: 'quit' },
	] );

	return trayMenu;
}
<commit_msg>Open mainWindow when certain recent file is selected<commit_after>const { Menu } = require( 'electron' );
const mainWindow = require( './main-window' );
const config = require( './config' );

module.exports = function createTrayMenu( options ) {
	const recentFiles = config.get( 'recent-files' ) || [];

	const trayMenu = Menu.buildFromTemplate( [
		{
			label: 'recent files',
			type: 'submenu',
			submenu: recentFiles.map( ( { name, path } ) => {
				return { label: name, type: 'normal', click() {
					const win = mainWindow();
					win.webContents.send( 'go-preview', { name, path } );
					setTimeout( () => {
						win.show();
						win.center();
						win.focus();
					}, 100 );
				} };
			} ),
		},
		{ label: 'quit', type: 'normal', role: 'quit' },
	] );

	return trayMenu;
}
<|endoftext|>


<commit_before>$(function () {
    var $fixture = $("#qunit-fixture"),
        fileId = 123,
        $container, $fileItem, $filenameDiv;

    module('Filename Click Handler', {
        setup: function() {
            $fixture = $("#qunit-fixture");

            $fixture.append('

');

            $container = $fixture.find('.testcontainer');
            $container.append('

');

            $fileItem = $container.find('.fileitem');
            $fileItem.append('

');

            $filenameDiv = $fileItem.find('.test-file');

            $fileItem[0].qqFileId = fileId;
        }
    });

        test('filename click handler - upload in progress', function () {
            new qq.FilenameClickHandler({
                listElement: $container[0],
                classes: {
                    file: 'test-file'
                },
                onGetName: function() {return "test"},
                onSetName: function(fileId, newName) {},
                onGetUploadStatus: function(fileId) { return qq.status.UPLOADING; }
            });

            helpme.createAndTriggerMouseEvent('click', $filenameDiv[0]);
            equal($container.find('INPUT').length, 0, "should not create input element to change filename, upload already in progress");
        });

    test('filename click handler - file submitted', function () {
        //can't get some of these tests to pass in FF on SauceLabs, even though code being tested seems to work fine during manual testing
        expect(qq.firefox() ? 4 : 7);

        var origName = "test.foo.bar",
            origNameSansExt = "test.foo",
            newNameSansExt = "blahblah",
            newName = "blahblah.bar",
            $input;

        new qq.FilenameClickHandler({
            listElement: $container[0],
            classes: {
                file: 'test-file'
            },
            onGetName: function() { return origName; },
            onSetName: function(fileId, name) {
                //can't get some of these tests to pass in FF on SauceLabs, even though code being tested seems to work fine during manual testing
                if (!qq.firefox()) {
                    equal(name, newName, "new name should have the original extension appended");
                }
            },
            onGetUploadStatus: function(fileId) { return qq.status.SUBMITTED; }
        });

        //this shouldn't allow the user to change the filename
        helpme.createAndTriggerMouseEvent('click', $container[0]);

        helpme.createAndTriggerMouseEvent('click', $filenameDiv[0]);

        $input = $container.find('INPUT');

        equal($input.length, 1, "should have created input for changing filename");
        ok($input.is(':visible'), "filename input should be visible");
        ok(!$filenameDiv.is(":visible"), "filename display should not be visible");
        equal($input.val(), origNameSansExt, "filename input should equal original filename sans extension initially");

        $input.val(newNameSansExt);
        $input.blur();

        //can't get some of these tests to pass in FF on SauceLabs, even though code being tested seems to work fine during manual testing
        if (!qq.firefox()) {
            stop();

            setTimeout(function() {
                ok($filenameDiv.is(":visible"), "filename display should be visible again");
                equal($filenameDiv.text(), newName, "filename display should equal new name with original extension");
                start();
            }, 0);
        }
    });
});
<commit_msg>test: #773 fix unit tests in FF<commit_after>$(function () {
    var $fixture = $("#qunit-fixture"),
        fileId = 123,
        $container, $fileItem, $filenameDiv;

    module('Filename Click Handler', {
        setup: function() {
            $fixture = $("#qunit-fixture");

            $fixture.append('

');

            $container = $fixture.find('.testcontainer');
            $container.append('

');

            $fileItem = $container.find('.fileitem');
            $fileItem.append('

');

            $filenameDiv = $fileItem.find('.test-file');

            $fileItem[0].qqFileId = fileId;
        }
    });

        test('filename click handler - upload in progress', function () {
            new qq.FilenameClickHandler({
                listElement: $container[0],
                classes: {
                    file: 'test-file'
                },
                onGetName: function() {return "test"},
                onSetName: function(fileId, newName) {},
                onGetUploadStatus: function(fileId) { return qq.status.UPLOADING; }
            });

            helpme.createAndTriggerMouseEvent('click', $filenameDiv[0]);
            equal($container.find('INPUT').length, 0, "should not create input element to change filename, upload already in progress");
        });

    test('filename click handler - file submitted', function () {
        // can't get some of these tests to pass in FF on SauceLabs, even though code
        // being tested seems to work fine during manual testing and auto-testing in FF locally
        expect(qq.firefox() ? 4 : 7);

        var origName = "test.foo.bar",
            origNameSansExt = "test.foo",
            newNameSansExt = "blahblah",
            newName = "blahblah.bar",
            $input;

        new qq.FilenameClickHandler({
            listElement: $container[0],
            classes: {
                file: 'test-file'
            },
            onGetName: function() { return origName; },
            onSetName: function(fileId, name) {
                // can't get this test to pass in FF on SauceLabs, even though code being tested
                // seems to work fine during manual testing and auto-testing in FF locally
                if (!qq.firefox()) {
                    equal(name, newName, "new name should have the original extension appended");
                }
            },
            onGetUploadStatus: function(fileId) { return qq.status.SUBMITTED; }
        });

        //this shouldn't allow the user to change the filename
        helpme.createAndTriggerMouseEvent('click', $container[0]);

        helpme.createAndTriggerMouseEvent('click', $filenameDiv[0]);

        $input = $container.find('INPUT');

        equal($input.length, 1, "should have created input for changing filename");
        ok($input.is(':visible'), "filename input should be visible");
        ok(!$filenameDiv.is(":visible"), "filename display should not be visible");
        equal($input.val(), origNameSansExt, "filename input should equal original filename sans extension initially");

        // can't get these tests to pass in FF on SauceLabs, even though code being tested
        // seems to work fine during manual testing and auto-testing in FF locally
        if (!qq.firefox()) {
            $input.val(newNameSansExt);
            $input.blur();

            stop();

            setTimeout(function() {
                ok($filenameDiv.is(":visible"), "filename display should be visible again");
                equal($filenameDiv.text(), newName, "filename display should equal new name with original extension");
                start();
            }, 0);
        }
    });
});
<|endoftext|>


<commit_before>var twilio = require('twilio');
var express = require('express');
var logfmt = require('logfmt');
var moment = require('moment');
var db = require('./db');
var app = express();

// Express Middleware
app.use(logfmt.requestLogger());
app.use(express.json());
app.use(express.urlencoded());
app.use(express.cookieParser(process.env.COOKIE_SECRET));
app.use(express.cookieSession());

// Allows CORS
app.all('*', function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  next();
});

// Enable CORS support for IE8.
app.get('/proxy.html', function(req, res) {
  res.send('<!DOCTYPE HTML>\n' + '<script src="http://jpillora.com/xdomain/dist/0.6/xdomain.min.js" master="http://court.atlantaga.gov"></script>');
});

app.get('/', function(req, res) {
  res.send('Hello, I am Courtbot! I have a heart of justice and a knowledge of court cases.');
});

// Fuzzy search that returns cases with a partial name match or
// an exact citation match
app.get('/cases', function(req, res) {
  if (!req.query || !req.query.q) return res.send(400);

  db.fuzzySearch(req.query.q, function(err, data) {
    console.log("Fuzzy Search Error = " + err);
    // Add readable dates, to avoid browser side date issues
    data.forEach(function(d) {
      console.log("Fuzzy Search Record = " + d);
      d.readableDate = moment(d.date).format('dddd, MMM Do');
      d.payable = canPayOnline(d);
    });

    res.send(data);
  });
});

// Respond to text messages that come in from Twilio
app.post('/sms', function(req, res) {
  var twiml = new twilio.TwimlResponse();
  var text = req.body.Body.toUpperCase();

  if (req.session.askedReminder) {
    if (text === 'YES' || text === 'YEA' || text === 'YUP' || text === 'Y') {
      var match = req.session.match;
      db.addReminder({
        caseId: match.id,
        phone: req.body.From,
        originalCase: JSON.stringify(match)
      }, function(err, data) {});

      twiml.sms('Sounds good. We\'ll text you a day before your case. Call us at (404) 954-7914 with any other questions.');
      req.session.askedReminder = false;
      res.send(twiml.toString());
    } else if (text === 'NO' || text ==='N') {
      twiml.sms('Alright, no problem. See you on your court date. Call us at (404) 954-7914 with any other questions.');
      req.session.askedReminder = false;
      res.send(twiml.toString());
    }
  }

  if (req.session.askedQueued) {
    if (text === 'YES' || text === 'YEA' || text === 'YUP' || text === 'Y') {
      db.addQueued({
        citationId: req.session.citationId,
        phone: req.body.From,
      }, function(err, data) {});

      twiml.sms('Sounds good. We\'ll text you in the next 14 days. Call us at (404) 954-7914 with any other questions.');
      req.session.askedQueued = false;
      res.send(twiml.toString());
    } else if (text === 'NO' || text ==='N') {
      twiml.sms('No problem. Call us at (404) 954-7914 with any other questions.');
      req.session.askedQueued = false;
      res.send(twiml.toString());
    }
  }

  db.findCitation(text, function(err, results) {
    // If we can't find the case, or find more than one case with the citation
    // number, give an error and recommend they call in.
    if (!results || results.length === 0 || results.length > 1) {
      var correctLengthCitation = 6 <= text.length && text.length <= 9;
      if (correctLengthCitation) {
        twiml.sms('Couldn\'t find your case. It takes 14 days for new citations to appear in the sytem. Would you like a text when we find your information? (Reply YES or NO)');

        req.session.askedQueued = true;
        req.session.citationId = text;
      } else {
        twiml.sms('Sorry, we couldn\'t find that court case. Please call us at (404) 954-7914.');
      }
    } else {
      var match = results[0];
      var name = cleanupName(match.defendant);
      var date = moment(match.date).format('dddd, MMM Do');

      if (canPayOnline(match)){
        twiml.sms('You can pay now and skip court. Just call (404) 658-6940 or visit court.atlantaga.gov. \n\nOtherwise, your court date is ' + date + ' at ' + match.time +', in courtroom ' + match.room + '.');
      } else {
        twiml.sms('Found a court case for ' + name + ' on ' + date + ' at ' + match.time +', in courtroom ' + match.room +'. Would you like a reminder the day before? (reply YES or NO)');

        req.session.match = match;
        req.session.askedReminder = true;
      }
    }

    res.send(twiml.toString());
  });
});

// You can pay online if ALL your individual citations can be paid online
var canPayOnline = function(courtCase) {
  console.log("canPayOnline courtCase = " + courtCase);
  var eligible = true;
  courtCase.citations.forEach(function(citation) {
    if (citation.payable !== '1') eligible = false;
  });
  return eligible;
};

var cleanupName = function(name) {
  // Switch LAST, FIRST to FIRST LAST
  var bits = name.split(',');
  name = bits[1] + ' ' + bits[0];
  name = name.trim();

  // Change FIRST LAST to First Last
  name = name.replace(/\w\S*/g, function(txt) { return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); });

  return name;
};

var port = Number(process.env.PORT || 5000);
app.listen(port, function() {
  console.log("Listening on " + port);
});

<commit_msg>more logging<commit_after>var twilio = require('twilio');
var express = require('express');
var logfmt = require('logfmt');
var moment = require('moment');
var db = require('./db');
var app = express();

// Express Middleware
app.use(logfmt.requestLogger());
app.use(express.json());
app.use(express.urlencoded());
app.use(express.cookieParser(process.env.COOKIE_SECRET));
app.use(express.cookieSession());

// Allows CORS
app.all('*', function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  next();
});

// Enable CORS support for IE8.
app.get('/proxy.html', function(req, res) {
  res.send('<!DOCTYPE HTML>\n' + '<script src="http://jpillora.com/xdomain/dist/0.6/xdomain.min.js" master="http://court.atlantaga.gov"></script>');
});

app.get('/', function(req, res) {
  res.send('Hello, I am Courtbot! I have a heart of justice and a knowledge of court cases.');
});

// Fuzzy search that returns cases with a partial name match or
// an exact citation match
app.get('/cases', function(req, res) {
  if (!req.query || !req.query.q) return res.send(400);

  db.fuzzySearch(req.query.q, function(err, data) {
    console.log("Fuzzy Search Error = " + err);
    // Add readable dates, to avoid browser side date issues
    data.forEach(function(d) {
      console.log("Fuzzy Search Record = " + d);
      d.readableDate = moment(d.date).format('dddd, MMM Do');
      d.payable = canPayOnline(d);
    });

    res.send(data);
  });
});

// Respond to text messages that come in from Twilio
app.post('/sms', function(req, res) {
  var twiml = new twilio.TwimlResponse();
  var text = req.body.Body.toUpperCase();

  if (req.session.askedReminder) {
    if (text === 'YES' || text === 'YEA' || text === 'YUP' || text === 'Y') {
      var match = req.session.match;
      db.addReminder({
        caseId: match.id,
        phone: req.body.From,
        originalCase: JSON.stringify(match)
      }, function(err, data) {});

      twiml.sms('Sounds good. We\'ll text you a day before your case. Call us at (404) 954-7914 with any other questions.');
      req.session.askedReminder = false;
      res.send(twiml.toString());
    } else if (text === 'NO' || text ==='N') {
      twiml.sms('Alright, no problem. See you on your court date. Call us at (404) 954-7914 with any other questions.');
      req.session.askedReminder = false;
      res.send(twiml.toString());
    }
  }

  if (req.session.askedQueued) {
    if (text === 'YES' || text === 'YEA' || text === 'YUP' || text === 'Y') {
      db.addQueued({
        citationId: req.session.citationId,
        phone: req.body.From,
      }, function(err, data) {});

      twiml.sms('Sounds good. We\'ll text you in the next 14 days. Call us at (404) 954-7914 with any other questions.');
      req.session.askedQueued = false;
      res.send(twiml.toString());
    } else if (text === 'NO' || text ==='N') {
      twiml.sms('No problem. Call us at (404) 954-7914 with any other questions.');
      req.session.askedQueued = false;
      res.send(twiml.toString());
    }
  }

  db.findCitation(text, function(err, results) {
    // If we can't find the case, or find more than one case with the citation
    // number, give an error and recommend they call in.
    if (!results || results.length === 0 || results.length > 1) {
      var correctLengthCitation = 6 <= text.length && text.length <= 9;
      if (correctLengthCitation) {
        twiml.sms('Couldn\'t find your case. It takes 14 days for new citations to appear in the sytem. Would you like a text when we find your information? (Reply YES or NO)');

        req.session.askedQueued = true;
        req.session.citationId = text;
      } else {
        twiml.sms('Sorry, we couldn\'t find that court case. Please call us at (404) 954-7914.');
      }
    } else {
      var match = results[0];
      var name = cleanupName(match.defendant);
      var date = moment(match.date).format('dddd, MMM Do');

      if (canPayOnline(match)){
        twiml.sms('You can pay now and skip court. Just call (404) 658-6940 or visit court.atlantaga.gov. \n\nOtherwise, your court date is ' + date + ' at ' + match.time +', in courtroom ' + match.room + '.');
      } else {
        twiml.sms('Found a court case for ' + name + ' on ' + date + ' at ' + match.time +', in courtroom ' + match.room +'. Would you like a reminder the day before? (reply YES or NO)');

        req.session.match = match;
        req.session.askedReminder = true;
      }
    }

    res.send(twiml.toString());
  });
});

// You can pay online if ALL your individual citations can be paid online
var canPayOnline = function(courtCase) {
  console.log("canPayOnline citations = " + courtCase.citations);
  var eligible = true;
  courtCase.citations.forEach(function(citation) {
    if (citation.payable !== '1') eligible = false;
  });
  return eligible;
};

var cleanupName = function(name) {
  // Switch LAST, FIRST to FIRST LAST
  var bits = name.split(',');
  name = bits[1] + ' ' + bits[0];
  name = name.trim();

  // Change FIRST LAST to First Last
  name = name.replace(/\w\S*/g, function(txt) { return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); });

  return name;
};

var port = Number(process.env.PORT || 5000);
app.listen(port, function() {
  console.log("Listening on " + port);
});

<|endoftext|>


<commit_before>require('es6-promise').polyfill();
const helper = require('./helper');

function api(baseUrl, config, method, params) {
  let url = baseUrl;
  const auth = Buffer.from(`${config.username}:${config.apiKey}`).toString('base64');
  const authHeader = `Basic ${auth}`;
  const options = { method, headers: { Authorization: authHeader } };
  if (method === 'POST') {
    options.body = new helper.FormData();
    Object.keys(params).forEach((key) => {
      options.body.append(key, params[key]);
    });
  } else if (params) {
    const generateQueryParam = (key) => `${key}=${params[key]}`;
    const queryParams = Object.keys(params).map(generateQueryParam);
    url = `${url}?${queryParams.join('&')}`;
  }
  return helper.fetch(url, options).then((res) => res.json());
}

module.exports = api;
<commit_msg>api: Gracefully handle HTML 404 pages returned by server.<commit_after>require('es6-promise').polyfill();
const helper = require('./helper');

function api(baseUrl, config, method, params) {
  let url = baseUrl;
  const auth = Buffer.from(`${config.username}:${config.apiKey}`).toString('base64');
  const authHeader = `Basic ${auth}`;
  const options = { method, headers: { Authorization: authHeader } };
  if (method === 'POST') {
    options.body = new helper.FormData();
    Object.keys(params).forEach((key) => {
      options.body.append(key, params[key]);
    });
  } else if (params) {
    const generateQueryParam = (key) => `${key}=${params[key]}`;
    const queryParams = Object.keys(params).map(generateQueryParam);
    url = `${url}?${queryParams.join('&')}`;
  }
  let response = null;
  return helper.fetch(url, options).then((res) => {
    response = res;
    return res.json();
  }).catch((e) => {
    if (e instanceof SyntaxError) {
      // We probably got a non-JSON response from the server.
      // We should inform the user of the same.
      let message = 'Server Returned a non-JSON response.';
      if (response.status === 404) {
        message += ` Maybe endpoint: ${method} ${response.url.replace(config.apiURL, '')} doesn't exist.`;
      } else {
        message += ' Please check the API documentation.';
      }
      const error = new Error(message);
      error.res = response;
      throw error;
    }
    throw e;
  });
}

module.exports = api;
<|endoftext|>


<commit_before>// ==========================================================================
//                          DG.GameView
//
//  Copyright (c) 2014 by The Concord Consortium, Inc. All rights reserved.
//
//  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
//
//    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.
// ==========================================================================

/* globals iframePhone */
sc_require('components/game/game_controller');
sc_require('controllers/game_selection');
//sc_require('libraries/iframe-phone');

/** @class

  (Document Your View Here)

  @extends SC.WebView
*/
DG.GameView = SC.WebView.extend(
/** @scope DG.GameView.prototype */ {

  // Bind the 'value' property of the WebView, which determines
  // the URL of the page that is displayed, to the 'currentURL'
  // property of the global DG.gameSelectionController. If we
  // ever wanted to support multiple game instances in a single
  // document, we would need to bind to something like a
  // providerContext.currentUrl, where providerContext is an
  // instance of the DG.ProviderContext class, and a single
  // document can contain multiple DG.ProviderContext instances.
  valueBinding: 'DG.gameSelectionController.currentUrl',

  // Setup iframePhone communication with the child iframe before it loads, so that connection
  // (iframe src will change when 'value' changes, but observers fire before bindings are synced)
  valueDidChange: function() {
    var value = this.get('value');

//    if (value !== this._previousValue) {
//
//      // First discontinue listening to old game.
//      if (DG.gamePhone) {
//        DG.gamePhone.disconnect();
//      }
//
//      DG.gamePhone = new iframePhone.IframePhoneRpcEndpoint(
//
//        // TODO put this handler function somewhere appropriate rather than inlining it in (what is
//        // at notionally) view code?
//
//        function(command, callback) {
//          var ret = DG.doCommand(command);
//
//          // Analysis shows that the object returned by DG.doCommand may contain Error values, which
//          // are not serializable and thus will cause DataCloneErrors when we call 'callback' (which
//          // sends the 'ret' to the game window via postMessage). The 'requestFormulaValue' and
//          // 'requestAttributeValues' API commands are the guilty parties. The following is an
//          // ad-hoc attempt to clean up the object for successful serialization.
//
//          if (ret && ret.error && ret.error instanceof Error) {
//            ret.error = ret.error.message;
//          }
//
//          if (ret && ret.values && ret.values.length) {
//            ret.values = ret.values.map(function(value) {
//              return value instanceof Error ? null : value;
//            });
//          }
//
//          // If there's a DataCloneError anyway, at least let the client know something is wrong:
//          try {
//            callback(ret);
//          } catch (e) {
//            if (e instanceof window.DOMException && e.name === 'DataCloneError') {
//              callback({ success: false });
//            }
//          }
//        },
//        'codap-game',
//        this.$('iframe')[0],
//        DG.gameSelectionController.getPath('currentGame.origin')
//      );
//
//      // Let games/interactives know that they are talking to CODAP, specifically (rather than any
//      // old iframePhone supporting page) and can use its API.
//      DG.gamePhone.call({ message: "codap-present" });
//    }

    this._previousValue = value;

  }.observes('value'),

  destroy: function() {
    DG.gameSelectionController.gameViewWillClose();
    sc_super();
  },

  iframeDidLoad: function()
  {
    var iframe = this.$('iframe')[0];

    if (iframe && iframe.contentWindow) {
      var contentWindow = iframe.contentWindow,
          target = DG.currGameController;

      // Allow the iframe to take over the entire screen (requested by InquirySpace)
      $(iframe ).attr('allowfullscreen', true)
        .attr('webkitallowfullscreen', true)
        .attr('mozallowfullscreen', true);

      // Assign the callback functions as properties of the iframe's contentWindow.
      //
      // Note that the callbacks use SC.run() to make sure that SproutCore's runloop
      // has a chance to propagate bindings and data changes. See "Why Does SproutCore
      // Have a Run Loop and When Does It Execute?" at
      // http://frozencanuck.wordpress.com/2010/12/21/why-does-sproutcore-have-a-run-loop-and-when-does-it-execute/
      // for details of why this is necessary. In its concluding paragraph, it states
      // "Therefore the run loop is also used to drive data propagation via binding whenever
      // an asynchronous event is fired in order to drive the application." These callbacks
      // from the game are just such an asynchronous event, and so must invoke the runloop
      // to operate properly.
      //
      // Furthermore, note that these callbacks cannot be added, and an exception will be thrown, if
      // the game is hosted on another domain. Ignore that because we use HTML5 Web Messaging
      // ("postMessage") via IframePhone to talk to these games, which do not require the callbacks
      // below.

      try {

        // TODO: Eliminate all callbacks but DoCommand() once clients no longer call them.

        // NewCollectionWithAttributes
        contentWindow.NewCollectionWithAttributes =
          function(iCollectionName, iAttributeNames) {
            SC.run( function() {
                      target.newCollectionWithAttributes(iCollectionName,iAttributeNames);
                    });
          };

        // AddCaseToCollectionWithValues
        contentWindow.AddCaseToCollectionWithValues =
          function(iCollectionName, iValues) {
            SC.run( function() {
                      target.addCaseToCollectionWithValues(iCollectionName,iValues);
                    });
          };

        // LogUserAction
        contentWindow.LogUserAction =
          function(iActionString, iValues) {
            SC.run( function() {
                      target.logUserAction(iActionString,iValues);
                    });
          };

        // DoCommand
        contentWindow.DoCommand =
          function(iCmd) {
            var result;
            SC.run( function() {
                      result = target.doCommand(iCmd);
                    });
            return SC.json.encode( result);
          };
      } catch (e) {
        // e should be a SecurityError but I haven't found documentation regarding how standard
        // that error type is.
      }
    } else {
      DG.logWarn("DG.GameView:iframeDidLoad no contentWindow\n");
    }
    sc_super();
  }

});
<commit_msg>Undoing inadvertent commit of commented out iframe-phone<commit_after>// ==========================================================================
//                          DG.GameView
//
//  Copyright (c) 2014 by The Concord Consortium, Inc. All rights reserved.
//
//  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
//
//    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.
// ==========================================================================

/* globals iframePhone */
sc_require('components/game/game_controller');
sc_require('controllers/game_selection');
sc_require('libraries/iframe-phone');

/** @class

  (Document Your View Here)

  @extends SC.WebView
*/
DG.GameView = SC.WebView.extend(
/** @scope DG.GameView.prototype */ {

  // Bind the 'value' property of the WebView, which determines
  // the URL of the page that is displayed, to the 'currentURL'
  // property of the global DG.gameSelectionController. If we
  // ever wanted to support multiple game instances in a single
  // document, we would need to bind to something like a
  // providerContext.currentUrl, where providerContext is an
  // instance of the DG.ProviderContext class, and a single
  // document can contain multiple DG.ProviderContext instances.
  valueBinding: 'DG.gameSelectionController.currentUrl',

  // Setup iframePhone communication with the child iframe before it loads, so that connection
  // (iframe src will change when 'value' changes, but observers fire before bindings are synced)
  valueDidChange: function() {
    var value = this.get('value');

    if (value !== this._previousValue) {

      // First discontinue listening to old game.
      if (DG.gamePhone) {
        DG.gamePhone.disconnect();
      }

      DG.gamePhone = new iframePhone.IframePhoneRpcEndpoint(

        // TODO put this handler function somewhere appropriate rather than inlining it in (what is
        // at notionally) view code?

        function(command, callback) {
          var ret = DG.doCommand(command);

          // Analysis shows that the object returned by DG.doCommand may contain Error values, which
          // are not serializable and thus will cause DataCloneErrors when we call 'callback' (which
          // sends the 'ret' to the game window via postMessage). The 'requestFormulaValue' and
          // 'requestAttributeValues' API commands are the guilty parties. The following is an
          // ad-hoc attempt to clean up the object for successful serialization.

          if (ret && ret.error && ret.error instanceof Error) {
            ret.error = ret.error.message;
          }

          if (ret && ret.values && ret.values.length) {
            ret.values = ret.values.map(function(value) {
              return value instanceof Error ? null : value;
            });
          }

          // If there's a DataCloneError anyway, at least let the client know something is wrong:
          try {
            callback(ret);
          } catch (e) {
            if (e instanceof window.DOMException && e.name === 'DataCloneError') {
              callback({ success: false });
            }
          }
        },
        'codap-game',
        this.$('iframe')[0],
        DG.gameSelectionController.getPath('currentGame.origin')
      );

      // Let games/interactives know that they are talking to CODAP, specifically (rather than any
      // old iframePhone supporting page) and can use its API.
      DG.gamePhone.call({ message: "codap-present" });
    }

    this._previousValue = value;

  }.observes('value'),

  destroy: function() {
    DG.gameSelectionController.gameViewWillClose();
    sc_super();
  },

  iframeDidLoad: function()
  {
    var iframe = this.$('iframe')[0];

    if (iframe && iframe.contentWindow) {
      var contentWindow = iframe.contentWindow,
          target = DG.currGameController;

      // Allow the iframe to take over the entire screen (requested by InquirySpace)
      $(iframe ).attr('allowfullscreen', true)
        .attr('webkitallowfullscreen', true)
        .attr('mozallowfullscreen', true);

      // Assign the callback functions as properties of the iframe's contentWindow.
      //
      // Note that the callbacks use SC.run() to make sure that SproutCore's runloop
      // has a chance to propagate bindings and data changes. See "Why Does SproutCore
      // Have a Run Loop and When Does It Execute?" at
      // http://frozencanuck.wordpress.com/2010/12/21/why-does-sproutcore-have-a-run-loop-and-when-does-it-execute/
      // for details of why this is necessary. In its concluding paragraph, it states
      // "Therefore the run loop is also used to drive data propagation via binding whenever
      // an asynchronous event is fired in order to drive the application." These callbacks
      // from the game are just such an asynchronous event, and so must invoke the runloop
      // to operate properly.
      //
      // Furthermore, note that these callbacks cannot be added, and an exception will be thrown, if
      // the game is hosted on another domain. Ignore that because we use HTML5 Web Messaging
      // ("postMessage") via IframePhone to talk to these games, which do not require the callbacks
      // below.

      try {

        // TODO: Eliminate all callbacks but DoCommand() once clients no longer call them.

        // NewCollectionWithAttributes
        contentWindow.NewCollectionWithAttributes =
          function(iCollectionName, iAttributeNames) {
            SC.run( function() {
                      target.newCollectionWithAttributes(iCollectionName,iAttributeNames);
                    });
          };

        // AddCaseToCollectionWithValues
        contentWindow.AddCaseToCollectionWithValues =
          function(iCollectionName, iValues) {
            SC.run( function() {
                      target.addCaseToCollectionWithValues(iCollectionName,iValues);
                    });
          };

        // LogUserAction
        contentWindow.LogUserAction =
          function(iActionString, iValues) {
            SC.run( function() {
                      target.logUserAction(iActionString,iValues);
                    });
          };

        // DoCommand
        contentWindow.DoCommand =
          function(iCmd) {
            var result;
            SC.run( function() {
                      result = target.doCommand(iCmd);
                    });
            return SC.json.encode( result);
          };
      } catch (e) {
        // e should be a SecurityError but I haven't found documentation regarding how standard
        // that error type is.
      }
    } else {
      DG.logWarn("DG.GameView:iframeDidLoad no contentWindow\n");
    }
    sc_super();
  }

});
<|endoftext|>


<commit_before>$( document ).ready( function() {
    $(window).bind( 'hashchange', _updateFocusFromIri);
    $( "#labelOfOwner" ).on( 'click', function() {
        var iri = $( "#labelOfOwner" ).data( 'iri');
        if (iri) {
            jQuery.bbq.pushState({'iri' : iri});
        };
    });
});

function _updateFocusFromIri(event) {
    var iri = event.getState( 'iri' );
    $( '.optionalField' ).hide();
    sparql_predefined(
        "/sparql-queries/focus.sparql.txt",
        {'focus' : iri},
        _updateFocusFromJson);
}

var _predicate_to_action = {
  "http://dot.rural/sepake/ownedBy" :
    _updateOwnerFromIri,
  "http://www.w3.org/2000/01/rdf-schema#label" :
    function( y ){ $( ".labelOfFocus" ).text(y) },
  "http://dot.rural/sepake/htmlDescription" :
    function( y ){ $( "#descriptionOfFocus" ).html(y || "(No summary)") },
  "http://xmlns.com/foaf/0.1/homepage" :
    function( y ){
      if (y) {
          $( "#homepageOfFocus .dataGoesHere" ).text(y);
          $( "#homepageOfFocus .dataGoesHere" ).attr("href", y);
          $( "#homepageOfFocus" ).show();
      }
  },
  "http://www.w3.org/ns/prov#startedAtTime" :
    function( y ){
      if (y) {
          $( "#startedAtTime .dataGoesHere" ).text(y);
          $( "#startedAtTime" ).show();
      };
  },
  "http://www.w3.org/ns/prov#endedAtTime" :
    function( y ){
      if (y) {
          $( "#endedAtTime .dataGoesHere" ).text(y)
          $( "#endedAtTime" ).show()
      };
  },
};

function _updateFocusFromJson(response) {
    try {
        var values = sparqlListToObject(response, "p", "y");
        $.each(_predicate_to_action, function( p, action ){
          action(values[p]);
        });
        if (!values["http://dot.rural/sepake/htmlDescription"]) {
          _set_html_from_dbpedia_description( "#descriptionOfFocus", values["http://www.w3.org/2000/01/rdf-schema#label"] );
        }
    } catch (err) {
      console.log( err );
    }
}

function _updateOwnerFromIri(iri) {
  if (!iri) {
    return;
  };
  $( "#labelOfOwner" ).data( 'iri', iri);
  sparql("owner",
          [
           "SELECT ?y WHERE {",
           "    BIND (<--IRI--> AS ?owner) .",
           "    { ?owner rdfs:label ?y } .",
           "}",
          ],
         iri,
         _updateOwnerFromJson
  );
}

function _updateOwnerFromJson(response) {
  $.each(response.results.bindings, function(index, binding){
    values = _valuesOfSparqlBinding(binding);
    $( "#labelOfOwner .dataGoesHere" ).text( values.y );
    $( "#labelOfOwner" ).show();
  });
};

function _set_html_from_dbpedia_description(selector, search_for) {
  $.ajax({
    url: "http://lookup.dbpedia.org/api/search/KeywordSearch",
    data: {
      "QueryString" : search_for,
      "MaxHits" : 1,},
    dataType: 'json',
    success: function( response ) {
      if ( response.results[0] ) {
        $( selector ).html(response.results[0].description + " [Source: Wikipedia]");
      };
    },
    timeout: 2500,
  });
}

<commit_msg>Improving document_ready deps For #30-query-parameters<commit_after>$(window).bind( 'hashchange', _updateFocusFromIri);

$( document ).ready( function() {
    $( "#labelOfOwner" ).on( 'click', function() {
        var iri = $( "#labelOfOwner" ).data( 'iri');
        if (iri) {
            jQuery.bbq.pushState({'iri' : iri});
        };
    });
});

function _updateFocusFromIri(event) {
    var iri = event.getState( 'iri' );
    $( '.optionalField' ).hide();
    sparql_predefined(
        "/sparql-queries/focus.sparql.txt",
        {'focus' : iri},
        _updateFocusFromJson);
}

var _predicate_to_action = {
  "http://dot.rural/sepake/ownedBy" :
    _updateOwnerFromIri,
  "http://www.w3.org/2000/01/rdf-schema#label" :
    function( y ){ $( ".labelOfFocus" ).text(y) },
  "http://dot.rural/sepake/htmlDescription" :
    function( y ){ $( "#descriptionOfFocus" ).html(y || "(No summary)") },
  "http://xmlns.com/foaf/0.1/homepage" :
    function( y ){
      if (y) {
          $( "#homepageOfFocus .dataGoesHere" ).text(y);
          $( "#homepageOfFocus .dataGoesHere" ).attr("href", y);
          $( "#homepageOfFocus" ).show();
      }
  },
  "http://www.w3.org/ns/prov#startedAtTime" :
    function( y ){
      if (y) {
          $( "#startedAtTime .dataGoesHere" ).text(y);
          $( "#startedAtTime" ).show();
      };
  },
  "http://www.w3.org/ns/prov#endedAtTime" :
    function( y ){
      if (y) {
          $( "#endedAtTime .dataGoesHere" ).text(y)
          $( "#endedAtTime" ).show()
      };
  },
};

function _docReady_updateFocusFromJson(response) {
  $( document ).ready( function() {
    _updateFocusFromJson(response)
  }
}

function _updateFocusFromJson(response) {
    try {
        var values = sparqlListToObject(response, "p", "y");
        $.each(_predicate_to_action, function( p, action ){
          action(values[p]);
        });
        if (!values["http://dot.rural/sepake/htmlDescription"]) {
          _set_html_from_dbpedia_description( "#descriptionOfFocus", values["http://www.w3.org/2000/01/rdf-schema#label"] );
        }
    } catch (err) {
      console.log( err );
    }
}

function _updateOwnerFromIri(iri) {
  if (!iri) {
    return;
  };
  $( "#labelOfOwner" ).data( 'iri', iri);
  sparql("owner",
          [
           "SELECT ?y WHERE {",
           "    BIND (<--IRI--> AS ?owner) .",
           "    { ?owner rdfs:label ?y } .",
           "}",
          ],
         iri,
         _updateOwnerFromJson
  );
}

function _updateOwnerFromJson(response) {
  $.each(response.results.bindings, function(index, binding){
    values = _valuesOfSparqlBinding(binding);
    $( "#labelOfOwner .dataGoesHere" ).text( values.y );
    $( "#labelOfOwner" ).show();
  });
};

function _set_html_from_dbpedia_description(selector, search_for) {
  $.ajax({
    url: "http://lookup.dbpedia.org/api/search/KeywordSearch",
    data: {
      "QueryString" : search_for,
      "MaxHits" : 1,},
    dataType: 'json',
    success: function( response ) {
      if ( response.results[0] ) {
        $( selector ).html(response.results[0].description + " [Source: Wikipedia]");
      };
    },
    timeout: 2500,
  });
}

<|endoftext|>


<commit_before>var MVVM = require('mvvm');

function triggerEvent(target, evt, process) {
	var e = document.createEvent('HTMLEvents');
	e.initEvent(evt, true, true);

	if (process) {
		process(e);
	}

	target.dispatchEvent(e);
}

describe("v-on >", function() {
	var element;

	beforeEach(function() {
		element = document.createElement('div');
		document.body.appendChild(element);
	});

	afterEach(function() {
		document.body.removeChild(element);
	});

	it('normal', function() {
		var count = 0;
		var cb = function() {
			count++;
		}

		element.innerHTML = '';

		var vm = new MVVM(element, {
			'test': cb
		});
		var el = element.querySelector('#el');

		triggerEvent(el, 'click');
		expect(count).toBe(1);

		triggerEvent(el, 'click');
		triggerEvent(el, 'click');
		triggerEvent(el, 'click');
		expect(count).toBe(4);
	});

	it('a propagation situation', function() {
		element.innerHTML =
			'
' +
				'' +
			'
'

		var outerCount = 0, innerCount = 0;
		var vm = new MVVM(element, {
			'outer': function() {
				outerCount++;
			},
			'inner': function() {
				innerCount++;
			}
		});
		var outer = element.querySelector('#outer');
		var inner = element.querySelector('#inner');

		triggerEvent(outer, 'click');
		expect(outerCount).toBe(1);
		expect(innerCount).toBe(0);

		triggerEvent(inner, 'click');
		expect(outerCount).toBe(2);
		expect(innerCount).toBe(1);

		triggerEvent(inner, 'click');
		expect(outerCount).toBe(3);
		expect(innerCount).toBe(2);

		triggerEvent(outer, 'click');
		triggerEvent(inner, 'click');
		expect(outerCount).toBe(5); // outer+1 and bubbling by inner+1, so is 5
		expect(innerCount).toBe(3);
	});

	it('use .stop to stopPropagation', function() {
		element.innerHTML =
			'
' +
				'' +
			'
'

		var outerCount = 0, innerCount = 0;
		var vm = new MVVM(element, {
			'outer': function() {
				outerCount++;
			},
			'inner': function() {
				innerCount++;
			}
		});
		var outer = element.querySelector('#outer');
		var inner = element.querySelector('#inner');

		triggerEvent(outer, 'click');
		expect(outerCount).toBe(1);
		expect(innerCount).toBe(0);

		triggerEvent(inner, 'click');
		expect(outerCount).toBe(1);
		expect(innerCount).toBe(1);

		triggerEvent(inner, 'click');
		expect(outerCount).toBe(1);
		expect(innerCount).toBe(2);

		triggerEvent(inner, 'click');
		expect(outerCount).toBe(1);
		expect(innerCount).toBe(3);

		triggerEvent(outer, 'click');
		triggerEvent(inner, 'click');
		expect(outerCount).toBe(2);
		expect(innerCount).toBe(4);
	});

	it('a default situation', function() {
		element.innerHTML = '';

		var hasPrevent;
		var vm = new MVVM(element, {
			'test': function(e) {
				// this feature is base on greater than or equal to ie9
				hasPrevent = e.defaultPrevented;
			}
		});
		var el = element.querySelector('#el');

		triggerEvent(el, 'click');
		expect(hasPrevent).toBeFalsy();

		// there's no use hash to test default event because
		// in Firefox use triggerEvent for
		// will not change window.location.hash, maybe it's a bug of Firefox 40.0
	});

	it('use .prevent to preventDefault', function() {
		element.innerHTML = '';

		var hasPrevent;
		var vm = new MVVM(element, {
			'test': function(e) {
				hasPrevent = e.defaultPrevented;
			}
		});
		var hash = window.location.hash;
		var el = element.querySelector('#el');

		triggerEvent(el, 'click');
		expect(hasPrevent).toBeTruthy();
		expect(window.location.hash).toBe(hash); // no change hash
	});

	it('setup keyCode', function() {
		element.innerHTML = '<input id="el" type="text" v-on:keyup.13="test">';

		var isEnter13 = false;
		var vm = new MVVM(element, {
			'test': function(e) {
				isEnter13 = e.keyCode === 13;
			}
		});
		var el = element.querySelector('#el');

		triggerEvent(el, 'keyup', function(e) {
			e.keyCode = 11;
		});
		expect(isEnter13).toBeFalsy();

		triggerEvent(el, 'keyup', function(e) {
			e.keyCode = 12;
		});
		expect(isEnter13).toBeFalsy();

		triggerEvent(el, 'keyup', function(e) {
			e.keyCode = 13;
		});
		expect(isEnter13).toBeTruthy();
	});

	it('passing multi arguments', function() {
		element.innerHTML = '

';

		var args;
		var vm = new MVVM(element, {
			'test': function() {
				args = Array.prototype.slice.call(arguments);
			}
		});
		var el = element.querySelector('#el');

		triggerEvent(el, 'mouseenter');
		expect(args && args.length).toBe(3);
		expect(args && args[0]).toBe(123);
		expect(args && args[1]).toBe('sugar');
		expect(args && (args[2] instanceof Event)).toBeTruthy();
	});
});<commit_msg>Update test case for v-on<commit_after>var MVVM = require('mvvm');

function triggerEvent(target, evt, process) {
	var e = document.createEvent('HTMLEvents');
	e.initEvent(evt, true, true);

	if (process) {
		process(e);
	}

	target.dispatchEvent(e);
}

describe("v-on >", function() {
	var element;

	beforeEach(function() {
		element = document.createElement('div');
		document.body.appendChild(element);
	});

	afterEach(function() {
		document.body.removeChild(element);
	});

	it('normal', function() {
		var count = 0;
		var cb = function() {
			count++;
		}

		element.innerHTML = '';

		var vm = new MVVM(element, {
			'test': cb
		});
		var el = element.querySelector('#el');

		triggerEvent(el, 'click');
		expect(count).toBe(1);

		triggerEvent(el, 'click');
		triggerEvent(el, 'click');
		triggerEvent(el, 'click');
		expect(count).toBe(4);
	});

	it('a propagation situation', function() {
		element.innerHTML =
			'
' +
				'' +
			'
'

		var outerCount = 0, innerCount = 0;
		var vm = new MVVM(element, {
			'outer': function() {
				outerCount++;
			},
			'inner': function() {
				innerCount++;
			}
		});
		var outer = element.querySelector('#outer');
		var inner = element.querySelector('#inner');

		triggerEvent(outer, 'click');
		expect(outerCount).toBe(1);
		expect(innerCount).toBe(0);

		triggerEvent(inner, 'click');
		expect(outerCount).toBe(2);
		expect(innerCount).toBe(1);

		triggerEvent(inner, 'click');
		expect(outerCount).toBe(3);
		expect(innerCount).toBe(2);

		triggerEvent(outer, 'click');
		triggerEvent(inner, 'click');
		expect(outerCount).toBe(5); // outer+1 and bubbling by inner+1, so is 5
		expect(innerCount).toBe(3);
	});

	it('use .stop to stopPropagation', function() {
		element.innerHTML =
			'
' +
				'' +
			'
'

		var outerCount = 0, innerCount = 0;
		var vm = new MVVM(element, {
			'outer': function() {
				outerCount++;
			},
			'inner': function() {
				innerCount++;
			}
		});
		var outer = element.querySelector('#outer');
		var inner = element.querySelector('#inner');

		triggerEvent(outer, 'click');
		expect(outerCount).toBe(1);
		expect(innerCount).toBe(0);

		triggerEvent(inner, 'click');
		expect(outerCount).toBe(1);
		expect(innerCount).toBe(1);

		triggerEvent(inner, 'click');
		expect(outerCount).toBe(1);
		expect(innerCount).toBe(2);

		triggerEvent(inner, 'click');
		expect(outerCount).toBe(1);
		expect(innerCount).toBe(3);

		triggerEvent(outer, 'click');
		triggerEvent(inner, 'click');
		expect(outerCount).toBe(2);
		expect(innerCount).toBe(4);
	});

	it('a default situation', function() {
		element.innerHTML = '';

		var hasPrevent;
		var vm = new MVVM(element, {
			'test': function(e) {
				// this feature is base on greater than or equal to ie9
				hasPrevent = e.defaultPrevented;
			}
		});
		var el = element.querySelector('#el');

		triggerEvent(el, 'click');
		expect(hasPrevent).toBeFalsy();

		// there's no use hash to test default event because
		// in Firefox use triggerEvent for
		// will not change window.location.hash, maybe it's a bug of Firefox 40.0
	});

	it('use .prevent to preventDefault', function() {
		element.innerHTML = '';

		var hasPrevent;
		var vm = new MVVM(element, {
			'test': function(e) {
				hasPrevent = e.defaultPrevented;
			}
		});
		var hash = window.location.hash;
		var el = element.querySelector('#el');

		triggerEvent(el, 'click');
		expect(hasPrevent).toBeTruthy();
		expect(window.location.hash).toBe(hash); // no change hash
	});

	it('setup keyCode', function() {
		element.innerHTML = '<input id="el" type="text" v-on:keyup.13="test">';

		var isEnter13 = false;
		var vm = new MVVM(element, {
			'test': function(e) {
				isEnter13 = e.keyCode === 13;
			}
		});
		var el = element.querySelector('#el');

		triggerEvent(el, 'keyup', function(e) {
			e.keyCode = 11;
		});
		expect(isEnter13).toBeFalsy();

		triggerEvent(el, 'keyup', function(e) {
			e.keyCode = 12;
		});
		expect(isEnter13).toBeFalsy();

		triggerEvent(el, 'keyup', function(e) {
			e.keyCode = 13;
		});
		expect(isEnter13).toBeTruthy();
	});

	it('passing multi arguments', function() {
		element.innerHTML = '

';

		var args;
		var vm = new MVVM(element, {
			'test': function() {
				args = Array.prototype.slice.call(arguments);
			}
		});
		var el = element.querySelector('#el');

		triggerEvent(el, 'mouseenter');
		expect(args && args.length).toBe(3);
		expect(args && args[0]).toBe(123);
		expect(args && args[1]).toBe('sugar');
		expect(args && (args[2] instanceof Event)).toBeTruthy();
	});

	it('change event callback', function() {
		element.innerHTML = '

';

		var flag;
		var vm = new MVVM(element, {
			'test': function() {
				flag = 'first callback';
			}
		});
		var el = element.querySelector('#el');

		triggerEvent(el, 'click');
		expect(flag).toBe('first callback');

		// change callback for binding
		vm.set('test', function() {
			flag = 'secound callback';
		});
		triggerEvent(el, 'click');
		expect(flag).toBe('secound callback');
	});
});<|endoftext|>


<commit_before>const { statSync } = require("fs");
const { execSync } = require("child_process");

const bundledCLI = "./build/cli.bundled.js";
const defaultSolc = "0.5.0";

const postinstallObtain = () => {
  try {
    statSync(bundledCLI);
    execSync(`node ${bundledCLI} obtain --solc=${defaultSolc}`);
  } catch ({ message }) {
    if (message.includes("no such file")) return;
    throw new Error(
      `Error while attempting to download and cache solc ${defaultSolc}: ${message}`
    );
  }
};

try {
  postinstallObtain();
} catch (error) {
  throw error;
}
<commit_msg>bump postinstall default solc to 0.5.8<commit_after>const { statSync } = require("fs");
const { execSync } = require("child_process");

const bundledCLI = "./build/cli.bundled.js";
const defaultSolc = "0.5.8";

const postinstallObtain = () => {
  try {
    statSync(bundledCLI);
    execSync(`node ${bundledCLI} obtain --solc=${defaultSolc}`);
  } catch ({ message }) {
    if (message.includes("no such file")) return;
    throw new Error(
      `Error while attempting to download and cache solc ${defaultSolc}: ${message}`
    );
  }
};

try {
  postinstallObtain();
} catch (error) {
  throw error;
}
<|endoftext|>


<commit_before>function defaultFormatQueryString(options) {
  if (!options) {
    return null;
  }

  const queryStringParts = Object.keys(options).map(
    key => `${encodeURI(key)}=${encodeURI(options[key])}`
  );
  return queryStringParts.join('&');
}

export default function generateApi(
  {
    urlFunc,
    formatQueryString = defaultFormatQueryString,
    preprocessors = [],
    postprocessors = []
  }
) {
  const {fetch, methodNames} = this;

  return {
    formatQueryString,

    execute(method, {url, id, data, options}) {
      const urlBase = url || urlFunc(id || '');
      const queryString = this.formatQueryString(options);
      const urlFull = queryString ? `${urlBase}?${queryString}` : urlBase;

      const processorOptions = {id, ...options};

      let request = {method, body: data};
      preprocessors.forEach(preprocessor => {
        const newRequest = this::preprocessor(request, processorOptions);
        if (newRequest !== undefined) {
          request = newRequest;
        }
      });

      let result = this::fetch(urlFull, request);
      postprocessors.forEach(postprocessor => {
        result = result.then(response => {
          const newResponse = this::postprocessor(response, processorOptions);
          return newResponse !== undefined ? newResponse : response;
        });
      });

      return result;
    },

    [methodNames.getMany](options) {
      return this.execute('GET', {options});
    },

    [methodNames.getSingle](id, options) {
      return this.execute('GET', {id, options});
    },

    [methodNames.postSingle](data, options) {
      return this.execute('POST', {data, options});
    },

    [methodNames.putSingle](id, data, options) {
      return this.execute('PUT', {id, data, options});
    },

    [methodNames.patchSingle](id, data, options) {
      return this.execute('PATCH', {id, data, options});
    },

    [methodNames.deleteSingle](id, options) {
      return this.execute('DELETE', {id, options});
    }
  };
}
<commit_msg>Pass context object and method to urlFunc<commit_after>function defaultFormatQueryString(options) {
  if (!options) {
    return null;
  }

  const queryStringParts = Object.keys(options).map(
    key => `${encodeURI(key)}=${encodeURI(options[key])}`
  );
  return queryStringParts.join('&');
}

export default function generateApi(
  {
    urlFunc,
    formatQueryString = defaultFormatQueryString,
    preprocessors = [],
    postprocessors = []
  }
) {
  const {fetch, methodNames} = this;

  return {
    formatQueryString,

    execute(method, {url, id, data, options}) {
      const urlBase = url || this::urlFunc(id || '', method);
      const queryString = this.formatQueryString(options);
      const urlFull = queryString ? `${urlBase}?${queryString}` : urlBase;

      const processorOptions = {id, ...options};

      let request = {method, body: data};
      preprocessors.forEach(preprocessor => {
        const newRequest = this::preprocessor(request, processorOptions);
        if (newRequest !== undefined) {
          request = newRequest;
        }
      });

      let result = this::fetch(urlFull, request);
      postprocessors.forEach(postprocessor => {
        result = result.then(response => {
          const newResponse = this::postprocessor(response, processorOptions);
          return newResponse !== undefined ? newResponse : response;
        });
      });

      return result;
    },

    [methodNames.getMany](options) {
      return this.execute('GET', {options});
    },

    [methodNames.getSingle](id, options) {
      return this.execute('GET', {id, options});
    },

    [methodNames.postSingle](data, options) {
      return this.execute('POST', {data, options});
    },

    [methodNames.putSingle](id, data, options) {
      return this.execute('PUT', {id, data, options});
    },

    [methodNames.patchSingle](id, data, options) {
      return this.execute('PATCH', {id, data, options});
    },

    [methodNames.deleteSingle](id, options) {
      return this.execute('DELETE', {id, options});
    }
  };
}
<|endoftext|>