<commit_before>/**
 * @file Tag generation helper
 * @since 0.2.1
 */
/*#ifndef(UMD)*/
"use strict";
/*global _gpfDefine*/ // Shortcut for gpf.define
/*global _gpfErrorDeclare*/ // Declare new gpf.Error names
/*global _gpfIsArray*/ // Return true if the parameter is an array
/*global _gpfIsLiteralObject*/ // Check if the parameter is a literal object
/*global _gpfObjectForEach*/ // Similar to [].forEach but for objects
/*global _gpfStringEscapeFor*/ // Make the string content compatible with lang
/*global _gpfSyncReadSourceJSON*/ // Reads a source json file (only in source mode)
/*#endif*/

/**
 * Tag instance allocated by {@link gpf.typedef.tagFunc}
 *
 * @class gpf.typedef.Tag
 *
 * @see gpf.web.createTagFunction
 * @since 0.2.1
 */

/**
 * String conversion
 *
 * @method gpf.typedef.Tag.prototype.toString
 * @return {String} HTML result
 *
 * @see gpf.web.createTagFunction
 * @since 0.2.1
 */

/**
 * DOM insertion
 *
 * @method gpf.typedef.Tag.prototype.appendTo
 * @param {Object} node DOM parent to append the node to
 * @return {Object} Created DOM Node
 *
 * @see gpf.web.createTagFunction
 * @since 0.2.1
 */

/**
 * Tag generation function child specification.  When string, a text node is created.
 *
 * @typedef gpf.typedef.tagChild
 * @property {String|gpf.typedef.Tag}
 *
 * @see gpf.web.createTagFunction
 * @since 0.2.1
 */

/**
 * Tag generation function children specification
 *
 * @typedef gpf.typedef.tagChildren
 * @property {gpf.typedef.tagChild|gpf.typedef.tagChild[]}
 *
 * @see gpf.web.createTagFunction
 * @since 0.2.1
 */

/**
 * Tag generation function, it accepts up to two parameters:
 * - When no parameter is passed, an empty node is created
 * - If the first parameter is a literal object (see {@link gpf.isLiteralObject}), its properties are used to
 *   define the node attributes
 * - Otherwise, the second (or first if not a literal object) is used to define children that will be appended to this
 *   tag
 *
 * @callback gpf.typedef.tagFunc
 *
 * @param {Object|gpf.typedef.tagChildren} [attributes=undefined] When a literal object is passed, it is interpreted
 * as an attribute dictionary
 * @param {gpf.typedef.tagChildren} [children=undefined] List of children
 * @return {gpf.typedef.Tag} Tag object
 *
 * @see gpf.web.createTagFunction
 * @since 0.2.1
 */

_gpfErrorDeclare("web/tag", {
    /**
     * ### Summary
     *
     * Missing node name
     *
     * ### Description
     *
     * A tag can't be created if the node name is missing
     * @since 0.2.1
     */
    missingNodeName: "Missing node name",

    /**
     * ### Summary
     *
     * Unknown namespace prefix
     *
     * ### Description
     *
     * A prefix has been used prior to be associated with a namespace
     * @since 0.2.2
     */
    unknownNamespacePrefix: "Unknown namespace prefix",

    /**
     * ### Summary
     *
     * Unable to use namespace in string
     *
     * ### Description
     *
     * A prefix associated to a namespace has been used and can't be converted to string
     * @since 0.2.2
     */
    unableToUseNamespaceInString: "Unable to use namespace in string"
});

/**
 * Mapping of attribute name aliases
 * @type {Object}
 * @since 0.2.1
 */
var _gpfWebTagAttributeAliases = _gpfSyncReadSourceJSON("web/attributes.json");

/**
 * Mapping of prefixes for namespaces
 * @type {Object}
 * @since 0.2.2
 */
var _gpfWebNamespacePrefix = _gpfSyncReadSourceJSON("web/namespaces.json");

/**
 * Retrieves namespace associated to the prefix or fail
 *
 * @param {String} prefix Namespace prefix
 * @return {String} Namespace URI
 * @throws {gpf.Error.UnknownNamespacePrefix}
 * @since 0.2.2
 */
function _gpfWebGetNamespace (prefix) {
    var namespace = _gpfWebNamespacePrefix[prefix];
    if (undefined === namespace) {
        gpf.Error.unknownNamespacePrefix();
    }
    return namespace;
}

/**
 * Resolves prefixed name to namespace and name
 *
 * @param {String} name Attribute or node name
 * @return {{namespace, name}|undefined} Namespace and name in a structure if prefixed, undefined otherwise
 * @since 0.2.2
 */
function _gpfWebGetNamespaceAndName (name) {
    var parts = name.split(":");
    if (parts.length === 2) {
        return {
            namespace: _gpfWebGetNamespace(parts[0]),
            name: parts[1]
        };
    }
}

/**
 * Fails if the name includes namespace prefix
 *
 * @param {String} name Attribute or node name
 * @throws {gpf.Error.UnableToUseNamespaceInString}
 * @since 0.2.2
 */
function _gpfWebCheckNamespaceSafe (name) {
    if (-1 !== name.indexOf(":")) {
        gpf.Error.unableToUseNamespaceInString();
    }
}

/**
 * Resolve attribute name
 *
 * @param {String} name Attribute name used in the tag function
 * @return {String} Attribute to set on the node ele,ment
 * @since 0.2.1
 */
function _gpfWebTagAttributeAlias (name) {
    return _gpfWebTagAttributeAliases[name] || name;
}

/**
 * Apply the callback to each array item,
 * process recursively if the array item is an array
 *
 * @param {Array} array array of items
 * @param {Function} callback Function to apply on each array item
 * @since 0.2.1
 */
function _gpfWebTagFlattenChildren (array, callback) {
    array.forEach(function (item) {
        if (_gpfIsArray(item)) {
            _gpfWebTagFlattenChildren(item, callback);
        } else {
            callback(item);
        }
    });
}

var _GpfWebTag = _gpfDefine(/** @lends gpf.web.Tag.prototype */ {
    $class: "gpf.web.Tag",

    /**
     * Tag object
     *
     * @param {String} nodeName Node name
     * @param {Object} [attributes] Dictionary of attributes to set
     * @param {Array} [children] Children
     *
     * @constructor gpf.web.Tag
     * @private
     * @since 0.2.1
     */
    constructor: function (nodeName, attributes, children) {
        this._nodeName = nodeName;
        this._attributes = attributes || {};
        this._children = children;
    },

    /**
     * Node name
     * @since 0.2.1
     */
    _nodeName: "",

    /**
     * Node attributes
     * @since 0.2.1
     */
    _attributes: {},

    /**
     * Node children
     * @since 0.2.1
     */
    _children: [],

    //region toString implementation

    _getAttributesAsString: function () {
        return Object.keys(this._attributes).map(function (name) {
            _gpfWebCheckNamespaceSafe(name);
            return " " + _gpfWebTagAttributeAlias(name)
                + "=\"" + _gpfStringEscapeFor(this._attributes[name], "html") + "\"";
        }, this).join("");
    },

    _getChildrenAsString: function () {
        var result = [];
        _gpfWebTagFlattenChildren(this._children, function (child) {
            result.push(child.toString());
        });
        return result.join("");
    },

    _getClosingString: function () {
        if (this._children.length) {
            return ">" + this._getChildrenAsString() + "</" + this._nodeName + ">";
        }
        return "/>";
    },

    /**
     * Convert the current tag into HTML
     *
     * @return {String} HTML representation of the tag
     * @since 0.2.1
     */
    toString: function () {
        _gpfWebCheckNamespaceSafe(this._nodeName);
        return "<" + this._nodeName + this._getAttributesAsString() + this._getClosingString();
    },

    //endregion

    //region appendTo implementation

    _createElement: function (node) {
        var ownerDocument = node.ownerDocument,
            qualified = _gpfWebGetNamespaceAndName(this._nodeName);
        if (qualified) {
            return ownerDocument.createElementNS(qualified.namespace, qualified.name);
        }
        return ownerDocument.createElement(this._nodeName);
    },

    _setAttributesTo: function (node) {
        _gpfObjectForEach(this._attributes, function (value, name) {
            var qualified = _gpfWebGetNamespaceAndName(name);
            if (qualified) {
                node.setAttributeNS(qualified.namespace, _gpfWebTagAttributeAlias(qualified.name), value);
            } else {
                node.setAttribute(_gpfWebTagAttributeAlias(name), value);
            }
        });
    },

    _appendChildrenTo: function (node) {
        var ownerDocument = node.ownerDocument;
        _gpfWebTagFlattenChildren(this._children, function (child) {
            if (child instanceof _GpfWebTag) {
                child.appendTo(node);
            } else {
                node.appendChild(ownerDocument.createTextNode(child.toString()));
            }
        });
    },

    /**
     * Appends the tag to the provided node
     *
     * @param {Object} node Expected to be a DOM node
     * @return {Object} Created node
     * @since 0.2.1
     */
    appendTo: function (node) {
        var element = this._createElement(node);
        this._setAttributesTo(element);
        this._appendChildrenTo(element);
        return node.appendChild(element);
    }

    //endregion

});

/**
 * Create a tag generation function
 *
 * @param {String} nodeName tag name
 * @return {gpf.typedef.tagFunc} The tag generation function
 * @gpf:closure
 * @since 0.2.1
 */
function _gpfWebTagCreateFunction (nodeName) {
    if (!nodeName) {
        gpf.Error.missingNodeName();
    }
    return function (firstParam) {
        var sliceFrom,
            attributes;
        if (_gpfIsLiteralObject(firstParam)) {
            attributes = firstParam;
            sliceFrom = 1;
        } else {
            sliceFrom = 0;
        }
        return new _GpfWebTag(nodeName, attributes, [].slice.call(arguments, sliceFrom));
    };
}

/**
 * @gpf:sameas _gpfWebTagCreateFunction
 * @since 0.2.1
 *
 * @example
Tree building to string

 * var div = gpf.web.createTagFunction("div"),
 *     span = gpf.web.createTagFunction("span"),
 * tree = div({className: "test1"}, "Hello ", span({className: "test2"}, "World!"));
 * // tree.toString() gives
Hello World!

 *
 * @example
Tree building to DOM

 * var mockNode = mockDocument.createElement("any"),
 *     div = gpf.web.createTagFunction("div"),
 *     span = gpf.web.createTagFunction("span"),
 *     tree = div({className: "test"}, "Hello ", span("World!")),
 *     result = tree.appendTo(mockNode);
 */
gpf.web.createTagFunction = _gpfWebTagCreateFunction;
<commit_msg>FIX #210<commit_after>/**
 * @file Tag generation helper
 * @since 0.2.1
 */
/*#ifndef(UMD)*/
"use strict";
/*global _gpfDefine*/ // Shortcut for gpf.define
/*global _gpfErrorDeclare*/ // Declare new gpf.Error names
/*global _gpfIsArray*/ // Return true if the parameter is an array
/*global _gpfIsLiteralObject*/ // Check if the parameter is a literal object
/*global _gpfObjectForEach*/ // Similar to [].forEach but for objects
/*global _gpfStringEscapeFor*/ // Make the string content compatible with lang
/*global _gpfSyncReadSourceJSON*/ // Reads a source json file (only in source mode)
/*#endif*/

/**
 * Tag instance allocated by {@link gpf.typedef.tagFunc}
 *
 * @class gpf.typedef.Tag
 *
 * @see gpf.web.createTagFunction
 * @since 0.2.1
 */

/**
 * String conversion
 *
 * @method gpf.typedef.Tag.prototype.toString
 * @return {String} HTML result
 *
 * @see gpf.web.createTagFunction
 * @since 0.2.1
 */

/**
 * DOM insertion
 *
 * @method gpf.typedef.Tag.prototype.appendTo
 * @param {Object} node DOM parent to append the node to
 * @return {Object} Created DOM Node
 *
 * @see gpf.web.createTagFunction
 * @since 0.2.1
 */

/**
 * Tag generation function child specification.  When string, a text node is created.
 *
 * @typedef gpf.typedef.tagChild
 * @property {String|gpf.typedef.Tag}
 *
 * @see gpf.web.createTagFunction
 * @since 0.2.1
 */

/**
 * Tag generation function children specification
 *
 * @typedef gpf.typedef.tagChildren
 * @property {gpf.typedef.tagChild|gpf.typedef.tagChild[]}
 *
 * @see gpf.web.createTagFunction
 * @since 0.2.1
 */

/**
 * Tag generation function, it accepts up to two parameters:
 * - When no parameter is passed, an empty node is created
 * - If the first parameter is a literal object (see {@link gpf.isLiteralObject}), its properties are used to
 *   define the node attributes
 * - Otherwise, the second (or first if not a literal object) is used to define children that will be appended to this
 *   tag
 *
 * @callback gpf.typedef.tagFunc
 *
 * @param {Object|gpf.typedef.tagChildren} [attributes=undefined] When a literal object is passed, it is interpreted
 * as an attribute dictionary. The attribute name may contain the xlink namespace prefix.
 * @param {gpf.typedef.tagChildren} [children=undefined] List of children
 * @return {gpf.typedef.Tag} Tag object
 *
 * @see gpf.web.createTagFunction
 * @since 0.2.1
 */

_gpfErrorDeclare("web/tag", {
    /**
     * ### Summary
     *
     * Missing node name
     *
     * ### Description
     *
     * A tag can't be created if the node name is missing
     * @since 0.2.1
     */
    missingNodeName: "Missing node name",

    /**
     * ### Summary
     *
     * Unknown namespace prefix
     *
     * ### Description
     *
     * A prefix has been used prior to be associated with a namespace
     * @since 0.2.2
     */
    unknownNamespacePrefix: "Unknown namespace prefix",

    /**
     * ### Summary
     *
     * Unable to use namespace in string
     *
     * ### Description
     *
     * A prefix associated to a namespace has been used and can't be converted to string
     * @since 0.2.2
     */
    unableToUseNamespaceInString: "Unable to use namespace in string"
});

/**
 * Mapping of attribute name aliases
 * @type {Object}
 * @since 0.2.1
 */
var _gpfWebTagAttributeAliases = _gpfSyncReadSourceJSON("web/attributes.json");

/**
 * Mapping of prefixes for namespaces
 * @type {Object}
 * @since 0.2.2
 */
var _gpfWebNamespacePrefix = _gpfSyncReadSourceJSON("web/namespaces.json");

/**
 * Retrieves namespace associated to the prefix or fail
 *
 * @param {String} prefix Namespace prefix
 * @return {String} Namespace URI
 * @throws {gpf.Error.UnknownNamespacePrefix}
 * @since 0.2.2
 */
function _gpfWebGetNamespace (prefix) {
    var namespace = _gpfWebNamespacePrefix[prefix];
    if (undefined === namespace) {
        gpf.Error.unknownNamespacePrefix();
    }
    return namespace;
}

/**
 * Resolves prefixed name to namespace and name
 *
 * @param {String} name Attribute or node name
 * @return {{namespace, name}|undefined} Namespace and name in a structure if prefixed, undefined otherwise
 * @since 0.2.2
 */
function _gpfWebGetNamespaceAndName (name) {
    var parts = name.split(":");
    if (parts.length === 2) {
        return {
            namespace: _gpfWebGetNamespace(parts[0]),
            name: parts[1]
        };
    }
}

/**
 * Fails if the name includes namespace prefix
 *
 * @param {String} name Attribute or node name
 * @throws {gpf.Error.UnableToUseNamespaceInString}
 * @since 0.2.2
 */
function _gpfWebCheckNamespaceSafe (name) {
    if (-1 !== name.indexOf(":")) {
        gpf.Error.unableToUseNamespaceInString();
    }
}

/**
 * Resolve attribute name
 *
 * @param {String} name Attribute name used in the tag function
 * @return {String} Attribute to set on the node ele,ment
 * @since 0.2.1
 */
function _gpfWebTagAttributeAlias (name) {
    return _gpfWebTagAttributeAliases[name] || name;
}

/**
 * Apply the callback to each array item,
 * process recursively if the array item is an array
 *
 * @param {Array} array array of items
 * @param {Function} callback Function to apply on each array item
 * @since 0.2.1
 */
function _gpfWebTagFlattenChildren (array, callback) {
    array.forEach(function (item) {
        if (_gpfIsArray(item)) {
            _gpfWebTagFlattenChildren(item, callback);
        } else {
            callback(item);
        }
    });
}

var _GpfWebTag = _gpfDefine(/** @lends gpf.web.Tag.prototype */ {
    $class: "gpf.web.Tag",

    /**
     * Tag object
     *
     * @param {String} nodeName Node name
     * @param {Object} [attributes] Dictionary of attributes to set
     * @param {Array} [children] Children
     *
     * @constructor gpf.web.Tag
     * @private
     * @since 0.2.1
     */
    constructor: function (nodeName, attributes, children) {
        this._nodeName = nodeName;
        this._attributes = attributes || {};
        this._children = children;
    },

    /**
     * Node name
     * @since 0.2.1
     */
    _nodeName: "",

    /**
     * Node attributes
     * @since 0.2.1
     */
    _attributes: {},

    /**
     * Node children
     * @since 0.2.1
     */
    _children: [],

    //region toString implementation

    _getAttributesAsString: function () {
        return Object.keys(this._attributes).map(function (name) {
            _gpfWebCheckNamespaceSafe(name);
            return " " + _gpfWebTagAttributeAlias(name)
                + "=\"" + _gpfStringEscapeFor(this._attributes[name], "html") + "\"";
        }, this).join("");
    },

    _getChildrenAsString: function () {
        var result = [];
        _gpfWebTagFlattenChildren(this._children, function (child) {
            result.push(child.toString());
        });
        return result.join("");
    },

    _getClosingString: function () {
        if (this._children.length) {
            return ">" + this._getChildrenAsString() + "</" + this._nodeName + ">";
        }
        return "/>";
    },

    /**
     * Convert the current tag into HTML
     *
     * @return {String} HTML representation of the tag
     * @since 0.2.1
     */
    toString: function () {
        _gpfWebCheckNamespaceSafe(this._nodeName);
        return "<" + this._nodeName + this._getAttributesAsString() + this._getClosingString();
    },

    //endregion

    //region appendTo implementation

    _createElement: function (node) {
        var ownerDocument = node.ownerDocument,
            qualified = _gpfWebGetNamespaceAndName(this._nodeName);
        if (qualified) {
            return ownerDocument.createElementNS(qualified.namespace, qualified.name);
        }
        return ownerDocument.createElement(this._nodeName);
    },

    _setAttributesTo: function (node) {
        _gpfObjectForEach(this._attributes, function (value, name) {
            var qualified = _gpfWebGetNamespaceAndName(name);
            if (qualified) {
                node.setAttributeNS(qualified.namespace, _gpfWebTagAttributeAlias(qualified.name), value);
            } else {
                node.setAttribute(_gpfWebTagAttributeAlias(name), value);
            }
        });
    },

    _appendChildrenTo: function (node) {
        var ownerDocument = node.ownerDocument;
        _gpfWebTagFlattenChildren(this._children, function (child) {
            if (child instanceof _GpfWebTag) {
                child.appendTo(node);
            } else {
                node.appendChild(ownerDocument.createTextNode(child.toString()));
            }
        });
    },

    /**
     * Appends the tag to the provided node
     *
     * @param {Object} node Expected to be a DOM node
     * @return {Object} Created node
     * @since 0.2.1
     */
    appendTo: function (node) {
        var element = this._createElement(node);
        this._setAttributesTo(element);
        this._appendChildrenTo(element);
        return node.appendChild(element);
    }

    //endregion

});

/**
 * Create a tag generation function
 *
 * @param {String} nodeName tag name.
 * May include the namespace prefix svg for [SVG elements](https://developer.mozilla.org/en-US/docs/Web/SVG)
 * @return {gpf.typedef.tagFunc} The tag generation function
 * @gpf:closure
 * @since 0.2.1
 */
function _gpfWebTagCreateFunction (nodeName) {
    if (!nodeName) {
        gpf.Error.missingNodeName();
    }
    return function (firstParam) {
        var sliceFrom,
            attributes;
        if (_gpfIsLiteralObject(firstParam)) {
            attributes = firstParam;
            sliceFrom = 1;
        } else {
            sliceFrom = 0;
        }
        return new _GpfWebTag(nodeName, attributes, [].slice.call(arguments, sliceFrom));
    };
}

/**
 * @gpf:sameas _gpfWebTagCreateFunction
 * @since 0.2.1
 *
 * @example
Tree building to string

 * var div = gpf.web.createTagFunction("div"),
 *     span = gpf.web.createTagFunction("span"),
 * tree = div({className: "test1"}, "Hello ", span({className: "test2"}, "World!"));
 * // tree.toString() gives
Hello World!

 *
 * @example
Tree building to DOM

 * var mockNode = mockDocument.createElement("any"),
 *     div = gpf.web.createTagFunction("div"),
 *     span = gpf.web.createTagFunction("span"),
 *     tree = div({className: "test"}, "Hello ", span("World!")),
 *     result = tree.appendTo(mockNode);
 *
 * @example
SVG building

 * var mockNode = mockDocument.createElement("any"),
 *     svgImage = gpf.web.createTagFunction("svg:image"),
 *     tree = svgImage({x: 0, y: 0, "xlink:href": "test.png"}),
 *     result = tree.appendTo(mockNode);
 *
 */
gpf.web.createTagFunction = _gpfWebTagCreateFunction;
<|endoftext|>


<commit_before>import {ArrayExtensions} from './arrayextensions';
import {Letter} from './letter';
import {moveBefore, DIRECTION} from 'aurelia-dragula';

export class Welcome {

  constructor() {
    this.dragDirection = DIRECTION.HORIZONTAL;
    this.reset();
  }

  get unjumbledName() {
    return this.nameLetters.reduce((previous, current) => previous + current.char, '');
  }

  submit() {
    this.nameLetters = [];
    for(let i = 0; i < this.firstName.length; i++) {
      this.nameLetters.push(new Letter(this.firstName.charAt(i)));
    }

    do {
      ArrayExtensions.shuffle(this.nameLetters);
    }
    //If, by chance, we shuffle it to the same as the original name, keep shuffling until it no longer is
    while(this.unjumbledName === this.firstName)

    this.haveName = true;
  }

  drop(item, target, source, sibling, itemVM, siblingVM) {
    let itemId = item.dataset.id;
    let siblingId = sibling ? sibling.dataset.id : null;

    moveBefore(this.nameLetters, (letter) => letter.id === itemId, (letter) => letter.id === siblingId);
    if (this.unjumbledName === this.firstName)
      this.winner = true;
  }

  reset() {
    this.firstName = '';
    this.haveName = false;
    this.winner = false;
  }
}
<commit_msg>If there is no name entered, stop the browser from hanging<commit_after>import {ArrayExtensions} from './arrayextensions';
import {Letter} from './letter';
import {moveBefore, DIRECTION} from 'aurelia-dragula';

export class Welcome {

  constructor() {
    this.dragDirection = DIRECTION.HORIZONTAL;
    this.reset();
  }

  get unjumbledName() {
    return this.nameLetters.reduce((previous, current) => previous + current.char, '');
  }

  submit() {
    this.nameLetters = [];
    if (this.firstName && this.firstName.length) {
      for(let i = 0; i < this.firstName.length; i++) {
        this.nameLetters.push(new Letter(this.firstName.charAt(i)));
      }

      do {
        ArrayExtensions.shuffle(this.nameLetters);
      }
      //If, by chance, we shuffle it to the same as the original name, keep shuffling until it no longer is
      while(this.unjumbledName === this.firstName)

      this.haveName = true;
    }
  }

  drop(item, target, source, sibling, itemVM, siblingVM) {
    let itemId = item.dataset.id;
    let siblingId = sibling ? sibling.dataset.id : null;

    moveBefore(this.nameLetters, (letter) => letter.id === itemId, (letter) => letter.id === siblingId);
    if (this.unjumbledName === this.firstName)
      this.winner = true;
  }

  reset() {
    this.firstName = '';
    this.haveName = false;
    this.winner = false;
  }
}
<|endoftext|>


<commit_before>const electron = require('electron');
const { app, BrowserWindow } = require('electron');
const path = require('path');
const url = require('url');
const Configstore = require('configstore');

const configStore = new Configstore('YouWatch');

app.on('ready', () => {
  const screen = electron.screen;

  const pageUrl = url.format({
    protocol: 'file',
    slashes: true,
    pathname: path.join(__dirname, 'client', 'index.html'),
  });

  const isMac = process.platform === 'darwin';
  const MAIN_WINDOW = 'main';
  const ICON = path.join(__dirname, '..', 'static', 'icon.png');

  const windows = {};

  let isPlayerMaximized = false;
  let isChangingMode = false;
  let primaryDisplay;
  let sortedDisplaysIds;

  onNumberOfDisplaysChange();

  function openMainWindow() {
    if (!windows[MAIN_WINDOW])
      windows[MAIN_WINDOW] = createMainWindow();
  }

  function createMainWindow() {
    const _window = new BrowserWindow({
      title: app.getName(),
      x: configStore.get(getConfigStoreWindow('classic.x')),
      y: configStore.get(getConfigStoreWindow('classic.y')),
      width: configStore.get(getConfigStoreWindow('classic.width')),
      height: configStore.get(getConfigStoreWindow('classic.height')),
      icon: ICON,
      autoHideMenuBar: true,
      minWidth: 880,
      minHeight: 370,
      frame: isMac,
      titleBarStyle: 'hidden-inset',
      alwaysOnTop: false,
      hasShadow: true,
      enableLargerThanScreen: true,
    });

    if (isMac)
      app.dock.setIcon(ICON);

    if (require('electron-is-dev'))
      _window.openDevTools();

    _window.loadURL(pageUrl);
    _window.on('resize', onResize.bind(null, MAIN_WINDOW));
    _window.on('move', onResize.bind(null, MAIN_WINDOW));

    _window.on('closed', onClosed.bind(null, MAIN_WINDOW));

    screen.on('display-added', onNumberOfDisplaysChange);
    screen.on('display-removed', onNumberOfDisplaysChange);

    return _window;
  }

  function togglePlayerState(_isPlayerMaximized) {
    const bounds = configStore.get(getConfigStoreWindow(_isPlayerMaximized ? 'floatOnTop' : 'classic'));

    isChangingMode = true;
    windows[MAIN_WINDOW].setBounds(bounds, true);
    isChangingMode = false;

    isPlayerMaximized = _isPlayerMaximized;
  }

  module.exports.openMainWindow = openMainWindow;
  module.exports.togglePlayerState = togglePlayerState;

  function onResize(windowName) {
    if (isChangingMode || primaryDisplay.id !== screen.getPrimaryDisplay().id)
      return;

    const bounds = windows[windowName].getBounds();
    const key = getConfigStoreWindow(isPlayerMaximized ? 'floatOnTop' : 'classic');
    configStore.set(key, bounds);
  }

  function onClosed(windowName) {
    // dereference the window
    windows[windowName] = null;
  }

  function onNumberOfDisplaysChange() {
    sortedDisplaysIds = screen.getAllDisplays().map((display) => display.id).sort().join('-');
    primaryDisplay = screen.getPrimaryDisplay();

    if (!windows[MAIN_WINDOW] || !configStore.get(getConfigStoreWindowKey())) {
      const { width: screenWidth, height: screenHeight } = primaryDisplay.size;
      const appWidth = 0.75 * screenWidth;
      const appHeight = 0.75 * screenHeight;

      const defaultConfig = {
        classic: {
          x: (screenWidth / 2.0) - (appWidth / 2.0),
          y: (screenHeight / 2.0) - (appHeight / 2.0),
          width: appWidth,
          height: appHeight,
        },
        floatOnTop: {
          x: screenWidth - 640,
          y: screenHeight - 360,
          width: 640,
          height: 360,
        },
      };

      configStore.set(getConfigStoreWindowKey(), defaultConfig);
    }

    if (windows[MAIN_WINDOW]) {
      const bounds = configStore.get(getConfigStoreWindow(isPlayerMaximized ? 'floatOnTop' : 'classic'));
      windows[MAIN_WINDOW].setBounds(bounds, true);
    }
  }

  function getConfigStoreWindowKey() {
    return 'window.' + sortedDisplaysIds;
  }

  function getConfigStoreWindow(param) {
    return getConfigStoreWindowKey() + '.' + param;
  }
});
<commit_msg>Improve position save<commit_after>const electron = require('electron');
const { app, BrowserWindow } = require('electron');
const path = require('path');
const url = require('url');
const Configstore = require('configstore');

const configStore = new Configstore('YouWatch');

app.on('ready', () => {
  const screen = electron.screen;

  const pageUrl = url.format({
    protocol: 'file',
    slashes: true,
    pathname: path.join(__dirname, 'client', 'index.html'),
  });

  const isMac = process.platform === 'darwin';
  const MAIN_WINDOW = 'main';
  const ICON = path.join(__dirname, '..', 'static', 'icon.png');

  const windows = {};

  let isPlayerMaximized = false;
  let isChangingMode = false;
  let primaryDisplay;
  let sortedDisplaysIds;

  function openMainWindow() {
    if (!windows[MAIN_WINDOW])
      windows[MAIN_WINDOW] = createMainWindow();
  }

  function createMainWindow() {
    onNumberOfDisplaysChange();

    const _window = new BrowserWindow({
      title: app.getName(),
      x: configStore.get(getConfigStoreWindow('classic.x')),
      y: configStore.get(getConfigStoreWindow('classic.y')),
      width: configStore.get(getConfigStoreWindow('classic.width')),
      height: configStore.get(getConfigStoreWindow('classic.height')),
      icon: ICON,
      autoHideMenuBar: true,
      minWidth: 880,
      minHeight: 370,
      frame: isMac,
      titleBarStyle: 'hidden-inset',
      alwaysOnTop: false,
      hasShadow: true,
      enableLargerThanScreen: true,
    });

    if (isMac)
      app.dock.setIcon(ICON);

    if (require('electron-is-dev'))
      _window.openDevTools();

    _window.loadURL(pageUrl);
    _window.on('resize', onResize.bind(null, MAIN_WINDOW));
    _window.on('move', onResize.bind(null, MAIN_WINDOW));

    _window.on('closed', onClosed.bind(null, MAIN_WINDOW));

    screen.on('display-added', onNumberOfDisplaysChange);
    screen.on('display-removed', onNumberOfDisplaysChange);

    return _window;
  }

  function togglePlayerState(_isPlayerMaximized) {
    const bounds = configStore.get(getConfigStoreWindow(_isPlayerMaximized ? 'floatOnTop' : 'classic'));

    isChangingMode = true;
    windows[MAIN_WINDOW].setBounds(bounds, true);
    isChangingMode = false;

    isPlayerMaximized = _isPlayerMaximized;
  }

  module.exports.openMainWindow = openMainWindow;
  module.exports.togglePlayerState = togglePlayerState;

  function onResize(windowName) {
    if (isChangingMode || primaryDisplay.id !== screen.getPrimaryDisplay().id)
      return;

    const bounds = windows[windowName].getBounds();
    const key = getConfigStoreWindow(isPlayerMaximized ? 'floatOnTop' : 'classic');
    configStore.set(key, bounds);
  }

  function onClosed(windowName) {
    // dereference the window
    windows[windowName] = null;
  }

  function onNumberOfDisplaysChange() {
    sortedDisplaysIds = screen.getAllDisplays().map((display) => display.id).sort().join('-');
    primaryDisplay = screen.getPrimaryDisplay();

    if (!configStore.get(getConfigStoreWindowKey())) {
      const { width: screenWidth, height: screenHeight } = primaryDisplay.size;
      const appWidth = 0.75 * screenWidth;
      const appHeight = 0.75 * screenHeight;

      const defaultConfig = {
        classic: {
          x: (screenWidth / 2.0) - (appWidth / 2.0),
          y: (screenHeight / 2.0) - (appHeight / 2.0),
          width: appWidth,
          height: appHeight,
        },
        floatOnTop: {
          x: screenWidth - 640,
          y: screenHeight - 360,
          width: 640,
          height: 360,
        },
      };

      configStore.set(getConfigStoreWindowKey(), defaultConfig);
    }

    if (windows[MAIN_WINDOW]) {
      const bounds = configStore.get(getConfigStoreWindow(isPlayerMaximized ? 'floatOnTop' : 'classic'));
      windows[MAIN_WINDOW].setBounds(bounds, true);
    }
  }

  function getConfigStoreWindowKey() {
    return 'window.' + sortedDisplaysIds;
  }

  function getConfigStoreWindow(param) {
    return getConfigStoreWindowKey() + '.' + param;
  }
});
<|endoftext|>


<commit_before>function falert(message, confirmButtonText, cancelButtonText, confirmCallback) {

    var $container = $('

');
    var $messageContainer = $('

');
    var $message = $('

');
    var $buttonContainer = $('

');
    var $button = $('<button class="falert-btn falert-confirm"></button>');
    var $cancelButton = $('<button class="falert-btn" style="margin-left:5px;"></button>');
    var $overlay = $('

');

    $message.html(message);

    $button.text(confirmButtonText);
    $messageContainer.append($message);
    $buttonContainer.append($button);
    $container.append($messageContainer).append($buttonContainer);

    if (cancelButtonText !== undefined && cancelButtonText !== "" && cancelButtonText !== null ) {
        $cancelButton.text(cancelButtonText);
        $buttonContainer.append($cancelButton);
    }

    $('body').append($overlay).append($container);

    $button.click(function() {
        $container.remove();
        $overlay.remove();

        if (confirmCallback !== undefined) {
            confirmCallback();
        }

    });

    $cancelButton.click(function () {
        $container.remove();
        $overlay.remove();
    });

}
<commit_msg>et focus on ConfirmButton as fAlert appears<commit_after>function falert(message, confirmButtonText, cancelButtonText, confirmCallback) {

    var $container = $('

');
    var $messageContainer = $('

');
    var $message = $('

');
    var $buttonContainer = $('

');
    var $button = $('<button class="falert-btn falert-confirm"></button>');
    var $cancelButton = $('<button class="falert-btn" style="margin-left:5px;"></button>');
    var $overlay = $('

');

    $message.html(message);

    $button.text(confirmButtonText);
    $messageContainer.append($message);
    $buttonContainer.append($button);
    $container.append($messageContainer).append($buttonContainer);

    if (cancelButtonText !== undefined && cancelButtonText !== "" && cancelButtonText !== null ) {
        $cancelButton.text(cancelButtonText);
        $buttonContainer.append($cancelButton);
    }

    $('body').append($overlay).append($container);

    $button.click(function() {
        $container.remove();
        $overlay.remove();

        if (confirmCallback !== undefined) {
            confirmCallback();
        }

    });

    $cancelButton.click(function () {
        $container.remove();
        $overlay.remove();
    });

	$button.focus();
}
<|endoftext|>


<commit_before>import React from "react"
import VerticalSpacing from "../../atoms/VerticalSpacing"
import Button from "../../atoms/Button"
import Input from "../../atoms/Input"

const ContactPage = () => (
  <>

      <hgroup>

          Inscreva-se para saber mais sobre o Educodar
           2020

      </hgroup>
      <form
        action="/quero-aprender/sucesso"
        data-netlify="true"
        data-netlify-honeypot="bot-field"
        method="post"
        name="studentInterest"
      >
        <input name="bot-field" type="hidden" />
        <input name="form-name" type="hidden" value="studentInterest" />

            Qual é seu nome completo?
            <VerticalSpacing size="1x" />
            <Input
              id="name"
              name="name"
              aria-required={true}
              autoCapitalize="words"
              autoComplete="name"
              autoFocus={true}
              maxLength={50}
              minLength={5}
              placeholder="Nome completo"
              type="text"
            />

        <VerticalSpacing size="2x" />

            Qual é a sua data de nascimento?
            <VerticalSpacing size="1x" />
            <Input
              id="birthday"
              name="birthday"
              aria-required={true}
              required={true}
              type="date"
            />

        <VerticalSpacing size="2x" />

            Qual é seu endereço de e-mail?
            <VerticalSpacing size="1x" />
            <Input
              id="email"
              name="email"
              aria-required={false}
              autoFocus={false}
              placeholder="E-mail"
              type="email"
            />

        <VerticalSpacing size="2x" />

            Qual é seu telefone celular?
            <VerticalSpacing size="1x" />
            <Input
              id="tel-national"
              name="tel-national"
              autoComplete="tel-national"
              aria-required={false}
              autoFocus={false}
              placeholder="Telefone com DDD"
              type="tel"
            />

        <VerticalSpacing size="2x" />

            Em qual cidade você mora?
            <VerticalSpacing size="1x" />
            <select id="city" name="city" autoComplete="city" autoFocus={false}>
              <option value="">Escolha uma cidade…</option>
              <option value="BH">Belo Horizonte (MG)</option>
              <option value="POA">Porto Alegre (PR)</option>
              <option value="REC">Recife (PE)</option>
              <option value="SP">São Paulo (SP)</option>
            </select>

        <VerticalSpacing size="2x" />

            Em qual bairro você mora?
            <VerticalSpacing size="1x" />
            <Input
              id="address-line3"
              name="address-line3"
              autoCapitalize="words"
              autoComplete="address-line3"
              autoCorrect="on"
              autoFocus={false}
            />

        <VerticalSpacing size="4x" />
        <Button id="submit" name="submit" type="submit">
          Tenho interesse
        </Button>
      </form>

  </>
)

export default ContactPage
<commit_msg>Change "required" attribute on some inputs<commit_after>import React from "react"
import VerticalSpacing from "../../atoms/VerticalSpacing"
import Button from "../../atoms/Button"
import Input from "../../atoms/Input"

const ContactPage = () => (
  <>

      <hgroup>

          Inscreva-se para saber mais sobre o Educodar
           2020

      </hgroup>
      <form
        action="/quero-aprender/sucesso"
        data-netlify="true"
        data-netlify-honeypot="bot-field"
        method="post"
        name="studentInterest"
      >
        <input name="bot-field" type="hidden" />
        <input name="form-name" type="hidden" value="studentInterest" />

            Qual é seu nome completo?
            <VerticalSpacing size="1x" />
            <Input
              id="name"
              name="name"
              aria-required={true}
              autoCapitalize="words"
              autoComplete="name"
              autoFocus={true}
              maxLength={50}
              minLength={5}
              placeholder="Nome completo"
              required={true}
              type="text"
            />

        <VerticalSpacing size="2x" />

            Qual é a sua data de nascimento?
            <VerticalSpacing size="1x" />
            <Input
              id="birthday"
              name="birthday"
              aria-required={true}
              required={true}
              type="date"
            />

        <VerticalSpacing size="2x" />

            Qual é seu endereço de e-mail?
            <VerticalSpacing size="1x" />
            <Input
              id="email"
              name="email"
              aria-required={false}
              autoFocus={false}
              placeholder="E-mail"
              required={false}
              type="email"
            />

        <VerticalSpacing size="2x" />

            Qual é seu telefone celular?
            <VerticalSpacing size="1x" />
            <Input
              id="tel-national"
              name="tel-national"
              autoComplete="tel-national"
              aria-required={false}
              autoFocus={false}
              placeholder="Telefone com DDD"
              required={false}
              type="tel"
            />

        <VerticalSpacing size="2x" />

            Em qual cidade você mora?
            <VerticalSpacing size="1x" />
            <select
              id="city"
              name="city"
              aria-required={true}
              autoComplete="city"
              autoFocus={false}
              required={true}
            >
              <option value="">Escolha uma cidade…</option>
              <option value="BH">Belo Horizonte (MG)</option>
              <option value="POA">Porto Alegre (PR)</option>
              <option value="REC">Recife (PE)</option>
              <option value="SP">São Paulo (SP)</option>
            </select>

        <VerticalSpacing size="2x" />

            Em qual bairro você mora?
            <VerticalSpacing size="1x" />
            <Input
              id="address-line3"
              name="address-line3"
              aria-required={true}
              autoCapitalize="words"
              autoComplete="address-line3"
              autoCorrect="on"
              autoFocus={false}
              required={true}
            />

        <VerticalSpacing size="4x" />
        <Button id="submit" name="submit" type="submit">
          Tenho interesse
        </Button>
      </form>

  </>
)

export default ContactPage
<|endoftext|>


<commit_before>'use strict';

var assert = require('assert');

var Analysis = require('../../lib/analysis');

var testConfig = require('../test-config');
var QueryRunner = require('../../lib/postgresql/query-runner');

describe('line-to-single-point analysis', function() {

    var queryRunner;

    before(function() {
        queryRunner = new QueryRunner(testConfig.db);
    });

    var QUERY = 'select * from atm_machines limit 2';

    var sourceAtmMachines = {
        type: 'source',
        params: {
            query: QUERY
        }
    };

    var config = testConfig.create({
        batch: {
            inlineExecution: true
        }
    });

    function performAnalysis(definition, callback) {
        Analysis.create(config, definition, function (err, analysis) {
            if (err) {
                return callback(err);
            }

            queryRunner.run(analysis.getQuery(), function(err, result) {
                if (err) {
                    return callback(err);
                }

                assert.ok(Array.isArray(result.rows));
                var values = result.rows.map(function (value) {
                    return value;
                });

                callback(null, values);
            });
        });
    }

    describe('line to single point analysis', function () {
        var lineToSinglePointDefinition = {
            type: 'line-to-single-point',
            params: {
                source: sourceAtmMachines,
                destination_longitude: -3.66909027,
                destination_latitude: 40.43989237
            }
        };

        it('should create analysis', function (done) {
            performAnalysis(lineToSinglePointDefinition, function (err, values) {
                if(err) {
                    return done(err);
                }
                assert.ok(values);
                values.forEach(function (value) {
                    assert.equal(typeof value.cartodb_id, 'number');
                    assert.ok(value.the_geom);
                    assert.ok(value.length);
                });
                done();
            });
        });
    });
});
<commit_msg>Used test-helper utility<commit_after>'use strict';

var assert = require('assert');
var testHelper = require('../helper');

describe('line-to-single-point analysis', function() {
    var QUERY = 'select * from atm_machines limit 2';

    var sourceAtmMachines = {
        type: 'source',
        params: {
            query: QUERY
        }
    };

    describe('line to single point analysis', function () {
        var lineToSinglePointDefinition = {
            type: 'line-to-single-point',
            params: {
                source: sourceAtmMachines,
                destination_longitude: -3.66909027,
                destination_latitude: 40.43989237
            }
        };

        it('should create analysis', function (done) {
            testHelper.createAnalyses(lineToSinglePointDefinition, function(err, lineToSinglePoint) {
                assert.ifError(err);

                var rootNode = lineToSinglePoint.getRoot();

                testHelper.getRows(rootNode.getQuery(), function(err, rows) {
                    assert.ifError(err);
                    rows.forEach(function(row) {
                        assert.ok(typeof row.cartodb_id === 'number');
                        assert.ok(typeof row.the_geom === 'string');
                        assert.ok(typeof row.length === 'number');
                    });

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


<commit_before>describe('cat-class directive', () => {
    let element,
        scope = {},
        template = `

            `,
        compile,
        animate,
        timelineController = {
            register () {
                return;
            }
        },
        sandbox,
        timeout;
    beforeEach(angular.mock.module('cat.animations.base-animation'));
    beforeEach(angular.mock.module('cat.animations.animationLink'));
    beforeEach(angular.mock.module('cat.animations.class'));
    beforeEach(angular.mock.module('ngAnimateMock'));

    beforeEach(angular.mock.inject(($compile, $rootScope, $timeout, $animate) => {
        scope = $rootScope.$new();
        sandbox = sinon.sandbox.create();
        animate = $animate;
        scope.visible = false;
        compile = () => {
            let parentElement = angular.element(template);
            parentElement.data('$catTimelineController', timelineController);
            $compile(parentElement)(scope);
            element = parentElement.children();
        };

        timeout =  $timeout;
    }));

    afterEach(() => {
        sandbox.restore();
    });

    it('should add a class with --start suffix', () => {
        compile();
        element.hasClass('a-class-name--start').should.be.true;
    });

    it('should add the base class if not already specified', () => {
        compile();
        element.hasClass('a-class-name').should.be.true;
    });

    it('should set the status to READY if variable is binded', () => {
        compile();
        scope.$apply();
        scope.status.should.equal('READY');
    });

    it('should register itself on the catTimeline parent controller', () => {
        sandbox.spy(timelineController, 'register');
        compile();
        timelineController.register.should.have.been.calledOnce;
        timelineController.register.should.have.been.calledWith('animation-name', element.controller('catClass'));
    });

    it('should register itself on the catTimeline parent controller regardless of the nesting level', angular.mock.inject(($compile, $rootScope) => {
        sandbox.spy(timelineController, 'register');
        let template = `

`,
            parentElement = angular.element(template);

        parentElement.data('$catTimelineController', timelineController);
        $compile(parentElement)($rootScope.$new());
        element = parentElement.children().children();
        timelineController.register.should.have.been.calledOnce;
        timelineController.register.should.have.been.calledWith('animation-name', element.controller('catClass'));
    }));

    describe('active watch', () => {
        it('should remove the prefixed class', () => {
            compile();
            scope.visible = true;
            scope.$apply();
            element.hasClass('a-class-name--start').should.be.false;
            animate.flush();
        });

        it('should set the status to "RUNNING", then to "FINISHED"', () => {
            compile();
            scope.visible = true;
            scope.$apply();
            scope.status.should.equal('RUNNING');

            animate.flush();
            scope.status.should.equal('FINISHED');
        });
    });

    describe('controller', () => {
        let controller;

        beforeEach(() => {
            compile();
            scope.$apply();
            controller = element.controller('catClass');
        });

        describe('#play', () => {
            it('should be defined', () => {
                controller.play.should.be.a('function');
            });

            it('should remove the prefixed class', () => {
                element.hasClass('a-class-name--start').should.be.true;

                controller.play();
                scope.$apply();

                element.hasClass('a-class-name--start').should.be.false;
            });

            it('should update status correctly', () => {
                scope.status.should.equal('READY');

                controller.play();
                scope.status.should.equal('RUNNING');

                scope.$apply();
                animate.flush();

                scope.status.should.equal('FINISHED');

                element.hasClass('a-class-name--start').should.be.false;
            });

            it('should return a promise', () => {
                let retval = controller.play();
                retval.then.should.be.a('function');
            });

            it('should resolve the promise when done', () => {
                let retval = controller.play(),
                    spy = sandbox.spy();

                retval.then(spy);
                spy.should.not.have.been.called;

                scope.$apply();
                spy.should.not.have.been.called;

                animate.flush();
                spy.should.have.been.calledOnce;
            });
        });

        describe('#clear', () => {
            it('should be defined', () => {
                controller.clear.should.be.a('function');
            });

            it('should add the prefixed class', () => {
                controller.play();
                scope.$apply();

                element.hasClass('a-class-name--start').should.be.false;

                controller.clear();
                scope.$apply();
                element.hasClass('a-class-name--start').should.be.true;
            });

            it('should update status correctly when animation finished', () => {
                controller.play();
                scope.$apply();
                animate.flush();
                scope.status.should.equal('FINISHED');

                controller.clear();
                scope.status.should.equal('CLEARING');
                scope.$apply();
                scope.status.should.equal('READY');
            });

            it('should update status correctly when animation running', () => {
                controller.play();
                scope.$apply();

                scope.status.should.equal('RUNNING');

                animate.flush();
                controller.clear();
                scope.status.should.equal('CLEARING');
                scope.$apply();
                scope.status.should.equal('READY');
            });

            it('should return a promise', () => {
                controller.clear().then.should.be.a('function');
            });

            it('should resolve the promise when done (immediately)', () => {
                let spy = sandbox.spy();
                controller.clear().then(spy);

                spy.should.not.have.been.called;

                scope.$apply();
                spy.should.have.been.calledOnce;
            });

            it('should reject the "play" promise if still running', () => {
                let spy = sandbox.spy();
                controller.play().catch(spy);

                spy.should.not.have.been.called;

                scope.$apply();
                spy.should.not.have.been.called;

                controller.clear();

                scope.$apply();
                spy.should.have.been.calledOnce;
            });
        });
    });
});
<commit_msg>Refactor tests for class directive #41<commit_after>describe('cat-class directive', () => {
    let element,
        scope = {},
        $compile,
        $rootScope,
        $timeout,
        catAnimationLink,
        catBaseAnimation,
        $animate,
        template = `

            `,
        compile,
        timelineController = {
            register () {
                return;
            }
        },
        sandbox,
        timeout;
    beforeEach(function() {
        sandbox = sinon.sandbox.create();
    });

    beforeEach(angular.mock.module('cat.animations.base-animation', function($provide) {
        $provide.decorator('catBaseAnimation', function($delegate) {
                return sandbox.spy($delegate);
        });
    }));
    beforeEach(angular.mock.module('cat.animations.animationLink', function($provide) {
        $provide.decorator('catAnimationLink', function($delegate) {
                return sandbox.spy($delegate);
        });
    }));

    beforeEach(angular.mock.module('cat.animations.class'));
    beforeEach(angular.mock.module('ngAnimateMock'));

    beforeEach(angular.mock.inject(
            (_$compile_, _$rootScope_, _$timeout_, _$animate_, _catAnimationLink_, _catBaseAnimation_) => {
        scope = _$rootScope_.$new();
        $compile = _$compile_;
        catAnimationLink =  _catAnimationLink_;
        catBaseAnimation =  _catBaseAnimation_;
        $rootScope = _$rootScope_;
        $timeout = _$timeout_;
        $animate = _$animate_;
        scope.visible = false;
        compile = () => {
            let parentElement = angular.element(template);
            parentElement.data('$catTimelineController', timelineController);
            $compile(parentElement)(scope);
            element = parentElement.children();
        };

        timeout =  $timeout;
    }));

    afterEach(() => {
        sandbox.restore();
    });

    it('should register itself on the catTimeline parent controller', () => {
        sandbox.spy(timelineController, 'register');
        compile();
        timelineController.register.should.have.been.calledOnce;
        timelineController.register.should.have.been.calledWith('animation-name', element.controller('catClass'));
    });

    it('should register itself on the catTimeline parent controller regardless of the nesting level', () => {
        sandbox.spy(timelineController, 'register');
        let template = `

`,
            parentElement = angular.element(template);

        parentElement.data('$catTimelineController', timelineController);
        $compile(parentElement)($rootScope.$new());
        element = parentElement.children().children();
        timelineController.register.should.have.been.calledOnce;
        timelineController.register.should.have.been.calledWith('animation-name', element.controller('catClass'));
    });

    describe('#Linking Function', () => {
        it('Should call catAnimationLink function', () => {
            compile();
            catAnimationLink.should.have.been.calledOnce;
        });
    });

    describe('#Controller', () => {
        let controller;

        beforeEach(() => {
            compile();
            scope.$apply();
            controller = element.controller('catClass');
        });

        it('Should use catBaseAnimation', () => {
            catBaseAnimation.should.have.been.calledOnce;
        });

        it('Should pass scope catBaseAnimation', () => {
            var config;
            config = catBaseAnimation.args[0][0];
            config.$scope.should.equal(scope);
        });

        it('Should pass catBaseAnimation a config with defined onPlay, onSetUp, onClear, disable and attrs', () => {
            var config;
            config = catBaseAnimation.args[0][0];
            config.$attrs.should.be.defined;
            config.onSeek.should.be.function;
            config.onPlay.should.be.function;
            config.onSetUp.should.be.function;
            config.disable.should.be.function;
        });

        describe('#setUp', () => {
            it('should be defined', () => {
                controller.setUp.should.be.a('function');
            });

            it('Should call catAnimationLink function', () => {
                element.hasClass('a-class-name--start').should.be.true;
            });
        });

        describe('#play', () => {
            it('should be defined', () => {
                controller.play.should.be.a('function');
            });

            it('Should call catAnimationLink function', () => {
                element.hasClass('a-class-name--start').should.be.true;
                controller.play();
                scope.$apply();
                element.hasClass('a-class-name--start').should.be.false;
            });
        });

        describe('#seek', () => {
            //TODO: we should probably test the transition none and the forced reflow as well.
            it('should be defined', () => {
                controller.seek.should.be.a('function');
            });

            it('Should add start class if called with "start"', () => {
                controller.seek('start');
                $rootScope.$apply();
                element.hasClass('a-class-name--start').should.be.true;
            });

            it('Should remove start class if called with "end"', () => {
                controller.seek('end');
                $rootScope.$apply();
                element.hasClass('a-class-name--start').should.be.false;
            });
        });

        describe('#setDisabled', () => {
            it('should be defined', () => {
                controller.disable.should.be.a('function');
            });
        });
    });
});
<|endoftext|>


<commit_before>/*
  Copyright 2016 Google 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.
*/

// This is a test and we want descriptions to be useful, if this
// breaks the max-length, it's ok.

/* eslint-disable max-len */
/* eslint-env browser, mocha */
/* global testHelper */

'use strict';

describe('Test precache method', () => {
  let compareCachedAssets = (assetList, cachedAssets) => {
    // We make a set to ensure duplicates are removed from the asset list
    let assetSet = new Set(assetList);

    return new Promise((resolve, reject) => {
      let cachedAssetsKeys = Object.keys(cachedAssets);
      console.log(cachedAssetsKeys);
      cachedAssetsKeys.should.have.length(assetSet.size);

      for (let assetPath of assetSet) {
        let key = location.origin + assetPath;
        if (typeof cachedAssets[key] === 'undefined') {
          reject(new Error('Cache doesn\'t have a cache item for: ' + key));
        }

        cachedAssets[key].status.should.equal(200);
      }

      resolve();
    });
  };

  const serviceWorkersFolder = '/test/browser-tests/precache/serviceworkers';

  it('should precache all desired assets in precache-valid', () => {
    let assetList = [
      '/test/data/files/text.txt',
      '/test/data/files/text-1.txt'
    ];
    return testHelper.activateSW(serviceWorkersFolder + '/simple.js')
      .then(() => {
        return testHelper.getAllCachedAssets('precache-valid');
      })
      .then(cachedAssets => {
        return compareCachedAssets(assetList, cachedAssets);
      });
  });

  it('should precache a single item in precache-valid', () => {
    let assetList = [
      '/test/data/files/text.txt'
    ];
    return testHelper.activateSW(serviceWorkersFolder + '/single-item.js')
      .then(() => {
        return testHelper.getAllCachedAssets('precache-valid');
      })
      .then(cachedAssets => {
        return compareCachedAssets(assetList, cachedAssets);
      });
  });

  it('should precache all desired assets from promises in precache-valid', () => {
    let assetList = [
      '/test/data/files/text.txt',
      '/test/data/files/text-1.txt'
    ];
    return testHelper.activateSW(serviceWorkersFolder + '/promises.js')
      .then(() => {
        return testHelper.getAllCachedAssets('precache-valid');
      })
      .then(cachedAssets => {
        return compareCachedAssets(assetList, cachedAssets);
      });
  });

  it('should precache all desired assets from arrays of arrays in precache-valid', () => {
    let assetList = [
      '/test/data/files/text.txt',
      '/test/data/files/text-1.txt',
      '/test/data/files/text-2.txt',
      '/test/data/files/text-3.txt',
      '/test/data/files/text-4.txt',
      '/test/data/files/text-5.txt',
      '/test/data/files/text-6.txt',
      '/test/data/files/text-7.txt',
      '/test/data/files/text-8.txt'
    ];
    return testHelper.activateSW(serviceWorkersFolder + '/arrays.js')
      .then(() => {
        return testHelper.getAllCachedAssets('precache-valid');
      })
      .then(cachedAssets => {
        return compareCachedAssets(assetList, cachedAssets);
      });
  });

  it('should precache all desired assets from arrays of arrays of promises in precache-valid', () => {
    let assetList = [
      '/test/data/files/text.txt',
      '/test/data/files/text-1.txt',
      '/test/data/files/text-2.txt',
      '/test/data/files/text-3.txt',
      '/test/data/files/text-4.txt',
      '/test/data/files/text-5.txt',
      '/test/data/files/text-6.txt',
      '/test/data/files/text-7.txt',
      '/test/data/files/text-8.txt'
    ];
    return testHelper.activateSW(serviceWorkersFolder + '/promise-arrays.js')
      .then(() => {
        return testHelper.getAllCachedAssets('precache-valid');
      })
      .then(cachedAssets => {
        return compareCachedAssets(assetList, cachedAssets);
      });
  });

  it('should not precache paths that do no exist', () => {
    let testId = 'precache-non-existant-files';
    let validAssetsList = [
      '/test/data/files/text.txt',
      '/test/data/files/text-1.txt'
    ];
    return testHelper.activateSW(serviceWorkersFolder + '/non-existant-files.js')
      .then(() => {
        return testHelper.getAllCachedAssets(testId);
      })
      .then(cachedAssets => {
        return compareCachedAssets(validAssetsList, cachedAssets);
      });
  });

  it('should precache all assets from each install step', () => {
    let toolboxAssetList = [
      '/test/data/files/text.txt',
      '/test/data/files/text-1.txt'
    ];
    let additionalInstallAssets = [
      '/test/data/files/text-2.txt',
      '/test/data/files/text-3.txt'
    ];
    return testHelper.activateSW(serviceWorkersFolder + '/custom-install.js')
      .then(() => {
        return testHelper.getAllCachedAssets('precache-custom-install-toolbox');
      })
      .then(cachedAssets => {
        return compareCachedAssets(toolboxAssetList, cachedAssets);
      })
      .then(() => {
        return testHelper.getAllCachedAssets('precache-custom-install');
      })
      .then(cachedAssets => {
        return compareCachedAssets(additionalInstallAssets, cachedAssets);
      });
  });

  it('should precache all desired assets from a mix of strings, promises and arrays', () => {
    let assetList = [
      '/test/data/files/text.txt',
      '/test/data/files/text-1.txt',
      '/test/data/files/text-2.txt',
      '/test/data/files/text-3.txt',
      '/test/data/files/text-4.txt',
      '/test/data/files/text-5.txt'
    ];
    return testHelper.activateSW(serviceWorkersFolder + '/mix.js')
      .then(() => {
        return testHelper.getAllCachedAssets('precache-mix');
      })
      .then(cachedAssets => {
        return compareCachedAssets(assetList, cachedAssets);
      });
  });
});
<commit_msg>Removing an unneccassary console.log<commit_after>/*
  Copyright 2016 Google 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.
*/

// This is a test and we want descriptions to be useful, if this
// breaks the max-length, it's ok.

/* eslint-disable max-len */
/* eslint-env browser, mocha */
/* global testHelper */

'use strict';

describe('Test precache method', () => {
  let compareCachedAssets = (assetList, cachedAssets) => {
    // We make a set to ensure duplicates are removed from the asset list
    let assetSet = new Set(assetList);

    return new Promise((resolve, reject) => {
      let cachedAssetsKeys = Object.keys(cachedAssets);
      cachedAssetsKeys.should.have.length(assetSet.size);

      for (let assetPath of assetSet) {
        let key = location.origin + assetPath;
        if (typeof cachedAssets[key] === 'undefined') {
          reject(new Error('Cache doesn\'t have a cache item for: ' + key));
        }

        cachedAssets[key].status.should.equal(200);
      }

      resolve();
    });
  };

  const serviceWorkersFolder = '/test/browser-tests/precache/serviceworkers';

  it('should precache all desired assets in precache-valid', () => {
    let assetList = [
      '/test/data/files/text.txt',
      '/test/data/files/text-1.txt'
    ];
    return testHelper.activateSW(serviceWorkersFolder + '/simple.js')
      .then(() => {
        return testHelper.getAllCachedAssets('precache-valid');
      })
      .then(cachedAssets => {
        return compareCachedAssets(assetList, cachedAssets);
      });
  });

  it('should precache a single item in precache-valid', () => {
    let assetList = [
      '/test/data/files/text.txt'
    ];
    return testHelper.activateSW(serviceWorkersFolder + '/single-item.js')
      .then(() => {
        return testHelper.getAllCachedAssets('precache-valid');
      })
      .then(cachedAssets => {
        return compareCachedAssets(assetList, cachedAssets);
      });
  });

  it('should precache all desired assets from promises in precache-valid', () => {
    let assetList = [
      '/test/data/files/text.txt',
      '/test/data/files/text-1.txt'
    ];
    return testHelper.activateSW(serviceWorkersFolder + '/promises.js')
      .then(() => {
        return testHelper.getAllCachedAssets('precache-valid');
      })
      .then(cachedAssets => {
        return compareCachedAssets(assetList, cachedAssets);
      });
  });

  it('should precache all desired assets from arrays of arrays in precache-valid', () => {
    let assetList = [
      '/test/data/files/text.txt',
      '/test/data/files/text-1.txt',
      '/test/data/files/text-2.txt',
      '/test/data/files/text-3.txt',
      '/test/data/files/text-4.txt',
      '/test/data/files/text-5.txt',
      '/test/data/files/text-6.txt',
      '/test/data/files/text-7.txt',
      '/test/data/files/text-8.txt'
    ];
    return testHelper.activateSW(serviceWorkersFolder + '/arrays.js')
      .then(() => {
        return testHelper.getAllCachedAssets('precache-valid');
      })
      .then(cachedAssets => {
        return compareCachedAssets(assetList, cachedAssets);
      });
  });

  it('should precache all desired assets from arrays of arrays of promises in precache-valid', () => {
    let assetList = [
      '/test/data/files/text.txt',
      '/test/data/files/text-1.txt',
      '/test/data/files/text-2.txt',
      '/test/data/files/text-3.txt',
      '/test/data/files/text-4.txt',
      '/test/data/files/text-5.txt',
      '/test/data/files/text-6.txt',
      '/test/data/files/text-7.txt',
      '/test/data/files/text-8.txt'
    ];
    return testHelper.activateSW(serviceWorkersFolder + '/promise-arrays.js')
      .then(() => {
        return testHelper.getAllCachedAssets('precache-valid');
      })
      .then(cachedAssets => {
        return compareCachedAssets(assetList, cachedAssets);
      });
  });

  it('should not precache paths that do no exist', () => {
    let testId = 'precache-non-existant-files';
    let validAssetsList = [
      '/test/data/files/text.txt',
      '/test/data/files/text-1.txt'
    ];
    return testHelper.activateSW(serviceWorkersFolder + '/non-existant-files.js')
      .then(() => {
        return testHelper.getAllCachedAssets(testId);
      })
      .then(cachedAssets => {
        return compareCachedAssets(validAssetsList, cachedAssets);
      });
  });

  it('should precache all assets from each install step', () => {
    let toolboxAssetList = [
      '/test/data/files/text.txt',
      '/test/data/files/text-1.txt'
    ];
    let additionalInstallAssets = [
      '/test/data/files/text-2.txt',
      '/test/data/files/text-3.txt'
    ];
    return testHelper.activateSW(serviceWorkersFolder + '/custom-install.js')
      .then(() => {
        return testHelper.getAllCachedAssets('precache-custom-install-toolbox');
      })
      .then(cachedAssets => {
        return compareCachedAssets(toolboxAssetList, cachedAssets);
      })
      .then(() => {
        return testHelper.getAllCachedAssets('precache-custom-install');
      })
      .then(cachedAssets => {
        return compareCachedAssets(additionalInstallAssets, cachedAssets);
      });
  });

  it('should precache all desired assets from a mix of strings, promises and arrays', () => {
    let assetList = [
      '/test/data/files/text.txt',
      '/test/data/files/text-1.txt',
      '/test/data/files/text-2.txt',
      '/test/data/files/text-3.txt',
      '/test/data/files/text-4.txt',
      '/test/data/files/text-5.txt'
    ];
    return testHelper.activateSW(serviceWorkersFolder + '/mix.js')
      .then(() => {
        return testHelper.getAllCachedAssets('precache-mix');
      })
      .then(cachedAssets => {
        return compareCachedAssets(assetList, cachedAssets);
      });
  });
});
<|endoftext|>


<commit_before>/* test/browser/device_controllers_test.js -- test Device angular controllers
 * Copyright 2014 Sergei Ianovich
 *
 * Licensed under AGPL-3.0 or later, see LICENSE
 * Process Control Service Web Interface
 */
'use strict'

describe("Device Controllers", function() {
  beforeEach(function() {
    angular.mock.module('pcs.services');
    angular.mock.module('pcs.controllers');
  });

  var httpBackend;

  beforeEach(inject(function($httpBackend) {
    httpBackend = $httpBackend;
  }));

  afterEach(function(){
    httpBackend.verifyNoOutstandingExpectation();
  });

  describe("NewDeviceCtrl", function() {
    var scope, location, controller;

    beforeEach(inject(function($location, $controller) {
      location = $location;
      controller = $controller;
      scope = {
        page: sinon.spy(),
        setNewURL: sinon.spy(),
      };
    }));

    it("should clear pager", function() {
      controller('NewDeviceCtrl', { $scope: scope });
      expect(scope.page).to.have.been.calledWith(1, 1, 0);
    });

    it("should clear setNewURL", function() {
      controller('NewDeviceCtrl', { $scope: scope });
      expect(scope.setNewURL).to.have.been.calledWith(null);
    });

    it("should create device in scope", function() {
      controller('NewDeviceCtrl', { $scope: scope });
      expect(scope.device).to.exist();
    });

    describe("#save", function() {
      beforeEach(function() {
        scope.deviceForm = {
          $setPristine: sinon.spy(),
        };

        httpBackend.expectPOST('/devices', { name: "hello" }).respond({_id: 2, name: "hello"});
        controller('NewDeviceCtrl', { $scope: scope });
        scope.device.name = "hello";
      });

      it("should save device", function() {
        scope.save();
      });

      it("should set the form pristine", function() {
        scope.save();
        httpBackend.flush();
        expect(scope.deviceForm.$setPristine).to.have.been.called;
      });

      it("should change location path", function() {
        scope.save();
        httpBackend.flush();
        expect(location.path()).to.equal('/devices/2');
      });
    });
  });

  describe("DevicesCtrl", function() {
    var scope, controller;

    beforeEach(inject(function($controller) {
      controller = $controller;
      scope = {
        page: sinon.spy(),
        setNewURL: sinon.spy(),
      };

      httpBackend.expectGET('/devices?page=1').respond([{_id: 1}, {_id: 2}, {count: 2}]);
      controller('DevicesCtrl', { $scope: scope });
    }));

    it("should setup pager", function() {
      httpBackend.flush();
      expect(scope.page).to.have.been.calledWith(1, 25, 2);
    });

    it("should call setNewURL", function() {
      expect(scope.setNewURL).to.have.been.calledWith('#/devices/new');
    });
  });
});
// vim:ts=2 sts=2 sw=2 et:
<commit_msg>tests: ajax: device index loading<commit_after>/* test/browser/device_controllers_test.js -- test Device angular controllers
 * Copyright 2014 Sergei Ianovich
 *
 * Licensed under AGPL-3.0 or later, see LICENSE
 * Process Control Service Web Interface
 */
'use strict'

describe("Device Controllers", function() {
  beforeEach(function() {
    angular.mock.module('pcs.services');
    angular.mock.module('pcs.controllers');
  });

  var httpBackend;

  beforeEach(inject(function($httpBackend) {
    httpBackend = $httpBackend;
  }));

  afterEach(function(){
    httpBackend.verifyNoOutstandingExpectation();
  });

  describe("NewDeviceCtrl", function() {
    var scope, location, controller;

    beforeEach(inject(function($location, $controller) {
      location = $location;
      controller = $controller;
      scope = {
        page: sinon.spy(),
        setNewURL: sinon.spy(),
      };
    }));

    it("should clear pager", function() {
      controller('NewDeviceCtrl', { $scope: scope });
      expect(scope.page).to.have.been.calledWith(1, 1, 0);
    });

    it("should clear setNewURL", function() {
      controller('NewDeviceCtrl', { $scope: scope });
      expect(scope.setNewURL).to.have.been.calledWith(null);
    });

    it("should create device in scope", function() {
      controller('NewDeviceCtrl', { $scope: scope });
      expect(scope.device).to.exist();
    });

    describe("#save", function() {
      beforeEach(function() {
        scope.deviceForm = {
          $setPristine: sinon.spy(),
        };

        httpBackend.expectPOST('/devices', { name: "hello" }).respond({_id: 2, name: "hello"});
        controller('NewDeviceCtrl', { $scope: scope });
        scope.device.name = "hello";
      });

      it("should save device", function() {
        scope.save();
      });

      it("should set the form pristine", function() {
        scope.save();
        httpBackend.flush();
        expect(scope.deviceForm.$setPristine).to.have.been.called;
      });

      it("should change location path", function() {
        scope.save();
        httpBackend.flush();
        expect(location.path()).to.equal('/devices/2');
      });
    });
  });

  describe("DevicesCtrl", function() {
    var scope, controller;

    beforeEach(inject(function($controller) {
      controller = $controller;
      scope = {
        page: sinon.spy(),
        setNewURL: sinon.spy(),
      };

      httpBackend.expectGET('/devices?page=1').respond([{_id: 1}, {_id: 2}, {count: 2}]);
      controller('DevicesCtrl', { $scope: scope });
    }));

    it("should setup pager", function() {
      httpBackend.flush();
      expect(scope.page).to.have.been.calledWith(1, 25, 2);
    });

    it("should call setNewURL", function() {
      expect(scope.setNewURL).to.have.been.calledWith('#/devices/new');
    });

    it("should fill devices", function() {
      httpBackend.flush();
      expect(scope.devices.length).to.equal(2);
      expect(scope.devices[0]._id).to.equal(1);
    });
  });
});
// vim:ts=2 sts=2 sw=2 et:
<|endoftext|>


<commit_before>define(function (require, exports, module) {
  var ComponentPlugin = require("ide-component-plugin");
  var HtmlComponent = HtmlComponent || ComponentPlugin.extend({
    init: function (options) {
      this._super(options);
      return this;
    },
    _blockOfText: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum ac blandit erat. Curabitur velit libero, lacinia sit amet dolor a, tincidunt varius nisi. Integer ac magna bibendum, dignissim quam sed, commodo mauris. Aenean consequat ullamcorper felis ut sagittis. Quisque at magna a purus egestas suscipit. In vulputate tincidunt arcu non pulvinar. Pellentesque vitae leo et justo fringilla adipiscing sit amet eget lacus.",
    _lineOfText: "Lorem Ipsum Dolor Sit Amet",
    _getTextElementMarkup: function(tagName, forCode, singleLine, id) {
      return "<" + tagName + this._getContentEditable(forCode) + " id=\"" + id + "\">" + (singleLine ? this._lineOfText : this._blockOfText) +  "</" + tagName + ">";
    },
    _getContentEditable: function(forCode) {
      return (forCode ? "" : " contenteditable=\"true\" spellcheck=\"false\"");
    },
    getMarkup: function (descriptor, forCode) {
      switch (descriptor.type) {
        case "heading":
          return this._getTextElementMarkup("h1", forCode, true, descriptor.id);
        case "paragraph":
          return this._getTextElementMarkup("p", forCode, false, descriptor.id);
        case "link":
          return this._getTextElementMarkup("a", forCode, true, descriptor.id);
        case "list":
          return "

Item 1

Item 2

";
        case "container":
          if (forCode) {
            return "

";
          } else {
            return "

";
          }
        case "button":
          return "<button" + this._getContentEditable(forCode) + " id=\"" + descriptor.id + "\">Button</button>";
        case "input":
          return "<input" + this._getContentEditable(forCode) + " id=\"" + descriptor.id + "\"/>";
        default:
          console.log("Unknown HTML element added: " + descriptor.type);
          return "";
      }
    },
    _getIndentTabs: function(descriptor) {
      var extraIndentStr = "", i = 0;
      if (descriptor.extraIndent) {
        for (i = 0; i < descriptor.extraIndent; i++) {
          extraIndentStr += "\t";
        }
      }
      return extraIndentStr;
    },
    getCodeEditorMarkupSnippet: function (descriptor) {
      var snippet = "\t" + this._getIndentTabs(descriptor) + this.getMarkup(descriptor, true) + "\n";
      return {codeString: snippet, lineCount: 1};
    },
    isContainer: function (descriptor) {
      if (typeof (descriptor) === "undefined" || descriptor === null) {
        return false;
      }
      switch (descriptor.type) {
        case "heading":
        case "paragraph":
        case "container":
        case "button":
        case "link":
        case "list":
          return true;
        case "input":
          return false;
        default:
          console.log("Unknown HTML element added.");
          return false;
      }
    },
    getPropValue: function (descriptor) {
		return descriptor.placeholder[0][descriptor.propName];
    },
    isDroppableChild: function (descriptor) {
      if (typeof (descriptor) === "undefined" || descriptor === null) {
        return false;
      }
      if (descriptor.nodeName && $(descriptor).attr("data-droppablechild") === "true") {
        return true;
      } else {
        return this.isContainer(descriptor);
      }
      return false;
    },
    hasDroppableChildren: function (descriptor) {
      if (typeof (descriptor) === "undefined" || descriptor === null) {
        return false;
      }
      if (descriptor.nodeName && $(descriptor).attr("data-hasdroppables") === "true") {
        return true;
      }
    },
    getDroppableChildren: function (descriptor) {
      if (typeof (descriptor) === "undefined" || descriptor === null) {
        return $();
      } else if (descriptor.nodeName) {
        return $(descriptor).find("div[data-droppablechild]");
      }
      return $();
    },
	update: function (descriptor) {
		var ide = this.settings.ide;
		descriptor.placeholder[0][descriptor.propName] = descriptor.propValue;
    }
  });
return HtmlComponent;
});<commit_msg>fix for bug #165355<commit_after>define(function (require, exports, module) {
  var ComponentPlugin = require("ide-component-plugin");
  var HtmlComponent = HtmlComponent || ComponentPlugin.extend({
    init: function (options) {
      this._super(options);
      return this;
    },
    _blockOfText: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum ac blandit erat. Curabitur velit libero, lacinia sit amet dolor a, tincidunt varius nisi. Integer ac magna bibendum, dignissim quam sed, commodo mauris. Aenean consequat ullamcorper felis ut sagittis. Quisque at magna a purus egestas suscipit. In vulputate tincidunt arcu non pulvinar. Pellentesque vitae leo et justo fringilla adipiscing sit amet eget lacus.",
    _lineOfText: "Lorem Ipsum Dolor Sit Amet",
    _getTextElementMarkup: function(tagName, forCode, singleLine, id) {
      return "<" + tagName + this._getContentEditable(forCode) + " id=\"" + id + "\">" + (singleLine ? this._lineOfText : this._blockOfText) +  "</" + tagName + ">";
    },
    _getContentEditable: function(forCode) {
      return (forCode ? "" : " contenteditable=\"true\" spellcheck=\"false\"");
    },
    isContentEditable: function (type) {
      if (type === "heading" || type === "paragraph" || type === "link" || type === "list" || type === "container" || type === "button" || type === "input") {
        return true;
      } else {
        return false;
      }
    },
    getMarkup: function (descriptor, forCode) {
      switch (descriptor.type) {
        case "heading":
          return this._getTextElementMarkup("h1", forCode, true, descriptor.id);
        case "paragraph":
          return this._getTextElementMarkup("p", forCode, false, descriptor.id);
        case "link":
          return this._getTextElementMarkup("a", forCode, true, descriptor.id);
        case "list":
          return "

Item 1

Item 2

";
        case "container":
          if (forCode) {
            return "

";
          } else {
            return "

";
          }
        case "button":
          return "<button" + this._getContentEditable(forCode) + " id=\"" + descriptor.id + "\">Button</button>";
        case "input":
          return "<input" + this._getContentEditable(forCode) + " id=\"" + descriptor.id + "\"/>";
        default:
          console.log("Unknown HTML element added: " + descriptor.type);
          return "";
      }
    },
    _getIndentTabs: function(descriptor) {
      var extraIndentStr = "", i = 0;
      if (descriptor.extraIndent) {
        for (i = 0; i < descriptor.extraIndent; i++) {
          extraIndentStr += "\t";
        }
      }
      return extraIndentStr;
    },
    getCodeEditorMarkupSnippet: function (descriptor) {
      var snippet = "\t" + this._getIndentTabs(descriptor) + this.getMarkup(descriptor, true) + "\n";
      return {codeString: snippet, lineCount: 1};
    },
    isContainer: function (descriptor) {
      if (typeof (descriptor) === "undefined" || descriptor === null) {
        return false;
      }
      switch (descriptor.type) {
        case "heading":
        case "paragraph":
        case "container":
        case "button":
        case "link":
        case "list":
          return true;
        case "input":
          return false;
        default:
          console.log("Unknown HTML element added.");
          return false;
      }
    },
    getPropValue: function (descriptor) {
		return descriptor.placeholder[0][descriptor.propName];
    },
    isDroppableChild: function (descriptor) {
      if (typeof (descriptor) === "undefined" || descriptor === null) {
        return false;
      }
      if (descriptor.nodeName && $(descriptor).attr("data-droppablechild") === "true") {
        return true;
      } else {
        return this.isContainer(descriptor);
      }
      return false;
    },
    hasDroppableChildren: function (descriptor) {
      if (typeof (descriptor) === "undefined" || descriptor === null) {
        return false;
      }
      if (descriptor.nodeName && $(descriptor).attr("data-hasdroppables") === "true") {
        return true;
      }
    },
    getDroppableChildren: function (descriptor) {
      if (typeof (descriptor) === "undefined" || descriptor === null) {
        return $();
      } else if (descriptor.nodeName) {
        return $(descriptor).find("div[data-droppablechild]");
      }
      return $();
    },
	update: function (descriptor) {
		var ide = this.settings.ide;
		descriptor.placeholder[0][descriptor.propName] = descriptor.propValue;
    }
  });
return HtmlComponent;
});<|endoftext|>


<commit_before>$.fn.ComboMe = function() {

    this.button({    // give the button the down arrow.
        text: true,
        icons: {secondary: "ui-icon-triangle-1-s"}
    })
    .click(function() {
        var bt = $(this);                        // get the button
        var menu = $( this ).parent().next();    // get the menu (the UL)
        menu.width( bt.width()-3 );              // set the menu width to match the button width

        // styling
        menu.css("position", "absolute");

        // for every anchor in the menu bind click to update the button text with the anchor text.
        menu.find("li").each(function( index ) {
            var link = $( this ).find("a");
            link.bind( "click", function() {
                bt.find("span").text( $(this).text() );
            });
        });

        // position the menu
        menu.show().position({
            my: "left top",
            at: "left bottom",
            of: this
        });
        // handle hiding the menu
        $( document ).one( "click", function() {
           menu.hide();
        });
        return false;
    })
    .parent()
    .buttonset()
    .next()
    .hide()
    .menu();

};
$("#cb").ComboMe();
<commit_msg>Update ComboMe.js<commit_after>$.fn.ComboMe = function() {

    this.button({    // give the button the down arrow.
        text: true,
        icons: {secondary: "ui-icon-triangle-1-s"}
    })
    .click(function() {
        var bt = $(this);                        // get the button
        var menu = $( this ).parent().next();    // get the menu (the UL)
        menu.width( bt.width()-3 );              // set the menu width to match the button width

        // styling
        menu.css("position", "absolute");

        // for every anchor in the menu bind click to update the button text with the anchor text.
        menu.find("li").each(function( index ) {
            var link = $( this ).find("a");
            link.bind( "click", function() {
                bt.find("span").text( $(this).text() );
            });
        });

        // position the menu
        menu.show().position({
            my: "left top",
            at: "left bottom",
            of: this
        });
        // handle hiding the menu
        $( document ).one( "click", function() {
           menu.hide();
        });
        return false;
    })
    .parent()
    .buttonset()
    .next()
    .hide()
    .menu();

};
<|endoftext|>