<commit_before>/**
@license
Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/

import * as utils from '../utils.js';
import {shadyDataForNode} from '../shady-data.js';
import extractSelectors, {
  splitSelectorBlocks,
} from './css-selector-splitter.js';

/**
 * @param {Node} node
 * @param {Function} matcher
 * @param {Function=} halter
 */
export function query(node, matcher, halter) {
  let list = [];
  queryChildNodes(node, matcher, halter, list);
  return list;
}

function queryChildNodes(parent, matcher, halter, list) {
  for (
    let n = parent[utils.SHADY_PREFIX + 'firstChild'];
    n;
    n = n[utils.SHADY_PREFIX + 'nextSibling']
  ) {
    if (
      n.nodeType === Node.ELEMENT_NODE &&
      queryElement(n, matcher, halter, list)
    ) {
      return true;
    }
  }
}

function queryElement(node, matcher, halter, list) {
  let result = matcher(node);
  if (result) {
    list.push(node);
  }
  if (halter && halter(result)) {
    return result;
  }
  queryChildNodes(node, matcher, halter, list);
}

// Needed on Element, DocumentFragment, Document
export const ParentNodePatches = utils.getOwnPropertyDescriptors({
  /** @this {Element} */
  get firstElementChild() {
    const nodeData = shadyDataForNode(this);
    if (nodeData && nodeData.firstChild !== undefined) {
      let n = this[utils.SHADY_PREFIX + 'firstChild'];
      while (n && n.nodeType !== Node.ELEMENT_NODE) {
        n = n[utils.SHADY_PREFIX + 'nextSibling'];
      }
      return n;
    } else {
      return this[utils.NATIVE_PREFIX + 'firstElementChild'];
    }
  },

  /** @this {Element} */
  get lastElementChild() {
    const nodeData = shadyDataForNode(this);
    if (nodeData && nodeData.lastChild !== undefined) {
      let n = this[utils.SHADY_PREFIX + 'lastChild'];
      while (n && n.nodeType !== Node.ELEMENT_NODE) {
        n = n[utils.SHADY_PREFIX + 'previousSibling'];
      }
      return n;
    } else {
      return this[utils.NATIVE_PREFIX + 'lastElementChild'];
    }
  },

  /** @this {Element} */
  get children() {
    if (!utils.isTrackingLogicalChildNodes(this)) {
      return this[utils.NATIVE_PREFIX + 'children'];
    }
    return utils.createPolyfilledHTMLCollection(
      Array.prototype.filter.call(utils.childNodesArray(this), (n) => {
        return n.nodeType === Node.ELEMENT_NODE;
      })
    );
  },

  /** @this {Element} */
  get childElementCount() {
    let children = this[utils.SHADY_PREFIX + 'children'];
    if (children) {
      return children.length;
    }
    return 0;
  },

  /** @this {Element} */
  append(...args) {
    this[utils.SHADY_PREFIX + 'insertBefore'](
      utils.convertNodesIntoANode(...args),
      null
    );
  },

  /** @this {Element} */
  prepend(...args) {
    this[utils.SHADY_PREFIX + 'insertBefore'](
      utils.convertNodesIntoANode(...args),
      this[utils.SHADY_PREFIX + 'firstChild']
    );
  },

  /** @this {Element} */
  ['replaceChildren'](...args) {
    let child;
    while ((child = this[utils.SHADY_PREFIX + 'firstChild']) !== null) {
      this[utils.SHADY_PREFIX + 'removeChild'](child);
    }
    this[utils.SHADY_PREFIX + 'insertBefore'](
      utils.convertNodesIntoANode(...args),
      null
    );
  },
});

/**
 * @param {!Array<T>} array
 * @return {!Array<T>}
 * @template T
 */
const deduplicateArray = (array) => Array.from(new Set(array));

/**
 * @param {!Element} ancestor
 * @param {!Array<!Element>} elements
 * @return {!Array<!Element>}
 */
const deduplicateAndFilterToDescendants = (ancestor, elements) => {
  return deduplicateArray(elements).filter((element) => {
    return (
      element !== ancestor && ancestor[utils.SHADY_PREFIX + 'contains'](element)
    );
  });
};

/**
 * @param {!Element} contextElement
 * @param {string} selectorList
 * @return {!Array<!Element>}
 */
const logicalQuerySelectorList = (contextElement, selectorList) => {
  return deduplicateAndFilterToDescendants(
    contextElement,
    utils.flat(
      extractSelectors(selectorList).map((selector) => {
        return logicalQuerySingleSelector(contextElement, selector);
      })
    )
  );
};

/**
 * @param {!Element} contextElement
 * @param {string} complexSelector
 * @return {!Array<!Element>}
 */
const logicalQuerySingleSelector = (contextElement, complexSelector) => {
  const {
    'selectors': simpleSelectors,
    'joiners': combinators,
  } = splitSelectorBlocks(complexSelector);

  if (simpleSelectors.length < 1) {
    return [];
  }

  /**
   * @type {!Array<!{
   *   position: !Element,
   *   target: !Element,
   * }>}
   */
  let cursors = query(
    contextElement[utils.SHADY_PREFIX + 'getRootNode'](),
    (node) => {
      return utils.matchesSelector(
        node,
        simpleSelectors[simpleSelectors.length - 1]
      );
    }
  ).map((element) => ({position: element, target: element}));

  /**
   * @param {!Element} element
   * @param {string} simpleSelector
   * @return {boolean}
   */
  const matchesSimpleSelector = (element, simpleSelector) => {
    return (
      utils.matchesSelector(element, simpleSelector) &&
      (simpleSelector.indexOf(':scope') === -1 || element === contextElement)
    );
  };

  for (let i = combinators.length - 1; i >= 0; i--) {
    const combinator = combinators[i];
    const simpleSelector = simpleSelectors[i];

    if (combinator === ' ') {
      // Descendant combinator
      cursors = utils.flat(
        cursors.map((cursor) => {
          const results = [];

          for (
            let ancestor = cursor.position[utils.SHADY_PREFIX + 'parentNode'];
            ancestor && ancestor instanceof Element;
            ancestor = ancestor[utils.SHADY_PREFIX + 'parentNode']
          ) {
            if (matchesSimpleSelector(ancestor, simpleSelector)) {
              results.push({position: ancestor, target: cursor.target});
            }
          }

          return results;
        })
      );
    } else if (combinator === '>') {
      // Child combinator
      cursors = utils.flat(
        cursors.map((cursor) => {
          const parent = cursor.position[utils.SHADY_PREFIX + 'parentNode'];

          if (
            parent &&
            parent instanceof Element &&
            matchesSimpleSelector(parent, simpleSelector)
          ) {
            return [{position: parent, target: cursor.target}];
          }

          return [];
        })
      );
    } else if (combinator === '+') {
      // Next-sibling combinator
      cursors = utils.flat(
        cursors.map((cursor) => {
          const sibling =
            cursor.position[utils.SHADY_PREFIX + 'previousElementSibling'];

          if (sibling && matchesSimpleSelector(sibling, simpleSelector)) {
            return [{position: sibling, target: cursor.target}];
          }

          return [];
        })
      );
    } else if (combinator === '~') {
      // Subsequent-sibling combinator
      cursors = utils.flat(
        cursors.map((cursor) => {
          const results = [];

          for (
            let sibling =
              cursor.position[utils.SHADY_PREFIX + 'previousElementSibling'];
            sibling;
            sibling = sibling[utils.SHADY_PREFIX + 'previousElementSibling']
          ) {
            if (matchesSimpleSelector(sibling, simpleSelector)) {
              results.push({position: sibling, target: cursor.target});
            }
          }

          return results;
        })
      );
    } else {
      throw new Error(`Unrecognized combinator: '${combinator}'.`);
    }
  }

  return deduplicateAndFilterToDescendants(
    contextElement,
    cursors.map((cursor) => cursor.target)
  );
};

export const QueryPatches = utils.getOwnPropertyDescriptors({
  // TODO(sorvell): consider doing native QSA and filtering results.
  /**
   * @this {Element}
   * @param  {string} selector
   */
  querySelector(selector) {
    return logicalQuerySelectorList(this, selector)[0] || null;
  },

  /**
   * @this {Element}
   * @param  {string} selector
   * @param  {boolean} useNative
   */
  // TODO(sorvell): `useNative` option relies on native querySelectorAll and
  // misses distributed nodes, see
  // https://github.com/webcomponents/shadydom/pull/210#issuecomment-361435503
  querySelectorAll(selector, useNative) {
    if (useNative) {
      const o = Array.prototype.slice.call(
        this[utils.NATIVE_PREFIX + 'querySelectorAll'](selector)
      );
      const root = this[utils.SHADY_PREFIX + 'getRootNode']();
      return utils.createPolyfilledHTMLCollection(
        o.filter((e) => e[utils.SHADY_PREFIX + 'getRootNode']() == root)
      );
    }
    return utils.createPolyfilledHTMLCollection(
      logicalQuerySelectorList(this, selector)
    );
  },
});

// In preferPerformance mode, create a custom `ParentNodeDocumentOrFragment`
// that optionally does not mixin querySelector/All; this is a performance
// optimization. In noPatch, we need to keep the query patches here in order to
// ensure the query API is available on the wrapper
export const ParentNodeDocumentOrFragmentPatches =
  utils.settings.preferPerformance && !utils.settings.noPatch
    ? utils.assign({}, ParentNodePatches)
    : ParentNodePatches;

utils.assign(ParentNodePatches, QueryPatches);
<commit_msg>Replace "simple selector" with "compound selector" where appropriate.<commit_after>/**
@license
Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/

import * as utils from '../utils.js';
import {shadyDataForNode} from '../shady-data.js';
import extractSelectors, {
  splitSelectorBlocks,
} from './css-selector-splitter.js';

/**
 * @param {Node} node
 * @param {Function} matcher
 * @param {Function=} halter
 */
export function query(node, matcher, halter) {
  let list = [];
  queryChildNodes(node, matcher, halter, list);
  return list;
}

function queryChildNodes(parent, matcher, halter, list) {
  for (
    let n = parent[utils.SHADY_PREFIX + 'firstChild'];
    n;
    n = n[utils.SHADY_PREFIX + 'nextSibling']
  ) {
    if (
      n.nodeType === Node.ELEMENT_NODE &&
      queryElement(n, matcher, halter, list)
    ) {
      return true;
    }
  }
}

function queryElement(node, matcher, halter, list) {
  let result = matcher(node);
  if (result) {
    list.push(node);
  }
  if (halter && halter(result)) {
    return result;
  }
  queryChildNodes(node, matcher, halter, list);
}

// Needed on Element, DocumentFragment, Document
export const ParentNodePatches = utils.getOwnPropertyDescriptors({
  /** @this {Element} */
  get firstElementChild() {
    const nodeData = shadyDataForNode(this);
    if (nodeData && nodeData.firstChild !== undefined) {
      let n = this[utils.SHADY_PREFIX + 'firstChild'];
      while (n && n.nodeType !== Node.ELEMENT_NODE) {
        n = n[utils.SHADY_PREFIX + 'nextSibling'];
      }
      return n;
    } else {
      return this[utils.NATIVE_PREFIX + 'firstElementChild'];
    }
  },

  /** @this {Element} */
  get lastElementChild() {
    const nodeData = shadyDataForNode(this);
    if (nodeData && nodeData.lastChild !== undefined) {
      let n = this[utils.SHADY_PREFIX + 'lastChild'];
      while (n && n.nodeType !== Node.ELEMENT_NODE) {
        n = n[utils.SHADY_PREFIX + 'previousSibling'];
      }
      return n;
    } else {
      return this[utils.NATIVE_PREFIX + 'lastElementChild'];
    }
  },

  /** @this {Element} */
  get children() {
    if (!utils.isTrackingLogicalChildNodes(this)) {
      return this[utils.NATIVE_PREFIX + 'children'];
    }
    return utils.createPolyfilledHTMLCollection(
      Array.prototype.filter.call(utils.childNodesArray(this), (n) => {
        return n.nodeType === Node.ELEMENT_NODE;
      })
    );
  },

  /** @this {Element} */
  get childElementCount() {
    let children = this[utils.SHADY_PREFIX + 'children'];
    if (children) {
      return children.length;
    }
    return 0;
  },

  /** @this {Element} */
  append(...args) {
    this[utils.SHADY_PREFIX + 'insertBefore'](
      utils.convertNodesIntoANode(...args),
      null
    );
  },

  /** @this {Element} */
  prepend(...args) {
    this[utils.SHADY_PREFIX + 'insertBefore'](
      utils.convertNodesIntoANode(...args),
      this[utils.SHADY_PREFIX + 'firstChild']
    );
  },

  /** @this {Element} */
  ['replaceChildren'](...args) {
    let child;
    while ((child = this[utils.SHADY_PREFIX + 'firstChild']) !== null) {
      this[utils.SHADY_PREFIX + 'removeChild'](child);
    }
    this[utils.SHADY_PREFIX + 'insertBefore'](
      utils.convertNodesIntoANode(...args),
      null
    );
  },
});

/**
 * @param {!Array<T>} array
 * @return {!Array<T>}
 * @template T
 */
const deduplicateArray = (array) => Array.from(new Set(array));

/**
 * @param {!Element} ancestor
 * @param {!Array<!Element>} elements
 * @return {!Array<!Element>}
 */
const deduplicateAndFilterToDescendants = (ancestor, elements) => {
  return deduplicateArray(elements).filter((element) => {
    return (
      element !== ancestor && ancestor[utils.SHADY_PREFIX + 'contains'](element)
    );
  });
};

/**
 * @param {!Element} contextElement
 * @param {string} selectorList
 * @return {!Array<!Element>}
 */
const logicalQuerySelectorList = (contextElement, selectorList) => {
  return deduplicateAndFilterToDescendants(
    contextElement,
    utils.flat(
      extractSelectors(selectorList).map((selector) => {
        return logicalQuerySingleSelector(contextElement, selector);
      })
    )
  );
};

/**
 * @param {!Element} contextElement
 * @param {string} complexSelector
 * @return {!Array<!Element>}
 */
const logicalQuerySingleSelector = (contextElement, complexSelector) => {
  const {
    'selectors': compoundSelectors,
    'joiners': combinators,
  } = splitSelectorBlocks(complexSelector);

  if (compoundSelectors.length < 1) {
    return [];
  }

  /**
   * @type {!Array<!{
   *   position: !Element,
   *   target: !Element,
   * }>}
   */
  let cursors = query(
    contextElement[utils.SHADY_PREFIX + 'getRootNode'](),
    (node) => {
      return utils.matchesSelector(
        node,
        compoundSelectors[compoundSelectors.length - 1]
      );
    }
  ).map((element) => ({position: element, target: element}));

  /**
   * @param {!Element} element
   * @param {string} compoundSelector
   * @return {boolean}
   */
  const matchesCompoundSelector = (element, compoundSelector) => {
    return (
      utils.matchesSelector(element, compoundSelector) &&
      (compoundSelector.indexOf(':scope') === -1 || element === contextElement)
    );
  };

  for (let i = combinators.length - 1; i >= 0; i--) {
    const combinator = combinators[i];
    const compoundSelector = compoundSelectors[i];

    if (combinator === ' ') {
      // Descendant combinator
      cursors = utils.flat(
        cursors.map((cursor) => {
          const results = [];

          for (
            let ancestor = cursor.position[utils.SHADY_PREFIX + 'parentNode'];
            ancestor && ancestor instanceof Element;
            ancestor = ancestor[utils.SHADY_PREFIX + 'parentNode']
          ) {
            if (matchesCompoundSelector(ancestor, compoundSelector)) {
              results.push({position: ancestor, target: cursor.target});
            }
          }

          return results;
        })
      );
    } else if (combinator === '>') {
      // Child combinator
      cursors = utils.flat(
        cursors.map((cursor) => {
          const parent = cursor.position[utils.SHADY_PREFIX + 'parentNode'];

          if (
            parent &&
            parent instanceof Element &&
            matchesCompoundSelector(parent, compoundSelector)
          ) {
            return [{position: parent, target: cursor.target}];
          }

          return [];
        })
      );
    } else if (combinator === '+') {
      // Next-sibling combinator
      cursors = utils.flat(
        cursors.map((cursor) => {
          const sibling =
            cursor.position[utils.SHADY_PREFIX + 'previousElementSibling'];

          if (sibling && matchesCompoundSelector(sibling, compoundSelector)) {
            return [{position: sibling, target: cursor.target}];
          }

          return [];
        })
      );
    } else if (combinator === '~') {
      // Subsequent-sibling combinator
      cursors = utils.flat(
        cursors.map((cursor) => {
          const results = [];

          for (
            let sibling =
              cursor.position[utils.SHADY_PREFIX + 'previousElementSibling'];
            sibling;
            sibling = sibling[utils.SHADY_PREFIX + 'previousElementSibling']
          ) {
            if (matchesCompoundSelector(sibling, compoundSelector)) {
              results.push({position: sibling, target: cursor.target});
            }
          }

          return results;
        })
      );
    } else {
      throw new Error(`Unrecognized combinator: '${combinator}'.`);
    }
  }

  return deduplicateAndFilterToDescendants(
    contextElement,
    cursors.map((cursor) => cursor.target)
  );
};

export const QueryPatches = utils.getOwnPropertyDescriptors({
  // TODO(sorvell): consider doing native QSA and filtering results.
  /**
   * @this {Element}
   * @param  {string} selector
   */
  querySelector(selector) {
    return logicalQuerySelectorList(this, selector)[0] || null;
  },

  /**
   * @this {Element}
   * @param  {string} selector
   * @param  {boolean} useNative
   */
  // TODO(sorvell): `useNative` option relies on native querySelectorAll and
  // misses distributed nodes, see
  // https://github.com/webcomponents/shadydom/pull/210#issuecomment-361435503
  querySelectorAll(selector, useNative) {
    if (useNative) {
      const o = Array.prototype.slice.call(
        this[utils.NATIVE_PREFIX + 'querySelectorAll'](selector)
      );
      const root = this[utils.SHADY_PREFIX + 'getRootNode']();
      return utils.createPolyfilledHTMLCollection(
        o.filter((e) => e[utils.SHADY_PREFIX + 'getRootNode']() == root)
      );
    }
    return utils.createPolyfilledHTMLCollection(
      logicalQuerySelectorList(this, selector)
    );
  },
});

// In preferPerformance mode, create a custom `ParentNodeDocumentOrFragment`
// that optionally does not mixin querySelector/All; this is a performance
// optimization. In noPatch, we need to keep the query patches here in order to
// ensure the query API is available on the wrapper
export const ParentNodeDocumentOrFragmentPatches =
  utils.settings.preferPerformance && !utils.settings.noPatch
    ? utils.assign({}, ParentNodePatches)
    : ParentNodePatches;

utils.assign(ParentNodePatches, QueryPatches);
<|endoftext|>


<commit_before>var command = {
  command: 'watch',
  description: 'Watch filesystem for changes and rebuild the project automatically',
  builder: {},
  run: function (options, done) {
    var Build = require("../build");
    var Config = require("truffle-config");
    var chokidar = require("chokidar");
    var path = require("path");
    var colors = require("colors");
    var Contracts = require("truffle-workflow-compile");
    var TruffleError = require("truffle-error");

    var config = Config.detect(options);

    var printSuccess = function() {
      config.logger.log(colors.green("Completed without errors on " + new Date().toString()));
    };

    var printFailure = function(err) {
      if (err instanceof TruffleError) {
        console.log(err.message);
      } else {
        // Bubble up all other unexpected errors.
        console.log(err.stack || err.toString());
      }
    };

    var working = false;
    var needs_rebuild = true;
    var needs_recompile = true;

    var watchPaths = [
      path.join(config.working_directory, "app/**/*"),
      path.join(config.contracts_build_directory, "/**/*"),
      path.join(config.contracts_directory, "/**/*"),
      path.join(config.working_directory, "truffle-config.js"),
      path.join(config.working_directory, "truffle.js")
    ];

    chokidar.watch(watchPaths, {
      ignored: /[\/\\]\./, // Ignore files prefixed with "."
      cwd: config.working_directory,
      ignoreInitial: true
    }).on('all', function(event, filePath) {
      // On changed/added/deleted
      var display_path = path.join("./", filePath.replace(config.working_directory, ""));
      config.logger.log(colors.cyan(">> File " + display_path + " changed."));

      needs_rebuild = true;

      if (path.join(config.working_directory, filePath).indexOf(config.contracts_directory) >= 0) {
        needs_recompile = true;
      }
    });

    var check_rebuild = function() {
      if (working) {
        setTimeout(check_rebuild, 200);
        return;
      }

      if (needs_rebuild == true) {
        needs_rebuild = false;

        if (config.build != null) {
          config.logger.log("Rebuilding...");
          working = true;

          Build.build(config, function(err) {
            if (err) {
              printFailure(err);
            } else {
              printSuccess();
            }
            working = false;
          });
        }
      } else if (needs_recompile == true) {
        needs_recompile = false;
        working = true;

        Contracts.compile(config, function(err) {
          if (err) {
            printFailure(err);
          }
          working = false;
        });
      }

      setTimeout(check_rebuild, 200);
    };

    check_rebuild();
  }
}

module.exports = command;
<commit_msg>Add help property to watch file<commit_after>var command = {
  command: 'watch',
  description: 'Watch filesystem for changes and rebuild the project automatically',
  builder: {},
  help: {
    usage: "truffle watch",
    options: [],
  },
  run: function (options, done) {
    var Build = require("../build");
    var Config = require("truffle-config");
    var chokidar = require("chokidar");
    var path = require("path");
    var colors = require("colors");
    var Contracts = require("truffle-workflow-compile");
    var TruffleError = require("truffle-error");

    var config = Config.detect(options);

    var printSuccess = function() {
      config.logger.log(colors.green("Completed without errors on " + new Date().toString()));
    };

    var printFailure = function(err) {
      if (err instanceof TruffleError) {
        console.log(err.message);
      } else {
        // Bubble up all other unexpected errors.
        console.log(err.stack || err.toString());
      }
    };

    var working = false;
    var needs_rebuild = true;
    var needs_recompile = true;

    var watchPaths = [
      path.join(config.working_directory, "app/**/*"),
      path.join(config.contracts_build_directory, "/**/*"),
      path.join(config.contracts_directory, "/**/*"),
      path.join(config.working_directory, "truffle-config.js"),
      path.join(config.working_directory, "truffle.js")
    ];

    chokidar.watch(watchPaths, {
      ignored: /[\/\\]\./, // Ignore files prefixed with "."
      cwd: config.working_directory,
      ignoreInitial: true
    }).on('all', function(event, filePath) {
      // On changed/added/deleted
      var display_path = path.join("./", filePath.replace(config.working_directory, ""));
      config.logger.log(colors.cyan(">> File " + display_path + " changed."));

      needs_rebuild = true;

      if (path.join(config.working_directory, filePath).indexOf(config.contracts_directory) >= 0) {
        needs_recompile = true;
      }
    });

    var check_rebuild = function() {
      if (working) {
        setTimeout(check_rebuild, 200);
        return;
      }

      if (needs_rebuild == true) {
        needs_rebuild = false;

        if (config.build != null) {
          config.logger.log("Rebuilding...");
          working = true;

          Build.build(config, function(err) {
            if (err) {
              printFailure(err);
            } else {
              printSuccess();
            }
            working = false;
          });
        }
      } else if (needs_recompile == true) {
        needs_recompile = false;
        working = true;

        Contracts.compile(config, function(err) {
          if (err) {
            printFailure(err);
          }
          working = false;
        });
      }

      setTimeout(check_rebuild, 200);
    };

    check_rebuild();
  }
}

module.exports = command;
<|endoftext|>


<commit_before>const path = require('path')
const R = require('ramda')
const assert = require('assert')
const glob = require('globby')
const Yaml = require('./util/yaml')
const TemplateUtil = require('./util/template')
const { error } = require('./util/message')

const readPackageJson = () => {
  let data = {}
  try {
    const packageJson = path.resolve(process.cwd(), 'package.json')
    data = require(packageJson)
  } catch (err) {}

  return data
}

const readFlags = (flags) => {
  const debug = flags.debug || false
  const data = { debug }

  return data
}

// if module is a relative path, resolve the absolute path,
// relative to project config directory (basedir).
// otherwise assume it's a node module that can be required.
const resolveModule = (basedir, module) =>
  module.startsWith('.') ? path.resolve(basedir, module) : module

const resolvePath = (basedir, relativePath) =>
  path.resolve(basedir, relativePath)

const resolveTheme = (basedir, theme = 'uiengine-theme-default') =>
  resolvePackage(basedir, theme, 'Theme')

const resolvePackage = (basedir, config, type) => {
  if (typeof config === 'object' && typeof config.module === 'string') {
    const options = typeof config.options === 'object' ? config.options : {}

    return {
      module: resolveModule(basedir, config.module),
      options
    }
  } else if (typeof config === 'string') {
    return {
      module: resolveModule(basedir, config),
      options: {}
    }
  } else {
    throw new Error(error(`${type} needs to be a configuration object (with module and options keys) or a module string (requireable path or name):`, config))
  }
}

const resolveTemplates = (templatesPath, config) => {
  if (!templatesPath || !path.isAbsolute(templatesPath)) return config

  // templates that are explicitely listed in the config
  const resolveDeclaredTemplates = R.partial(resolvePath, [templatesPath])
  const declared = R.map(resolveDeclaredTemplates, config)

  // templates that exist inside the templates directory
  const pattern = path.join(templatesPath, `**/*.*`)
  const paths = glob.sync(pattern)
  const templates = R.reduce((tmpl, templatePath) => {
    const id = TemplateUtil.templateFilePathToTemplateId(templatesPath, templatePath)
    tmpl[id] = templatePath

    return tmpl
  }, declared, paths)

  return templates
}

async function read (configFilePath, flags = {}) {
  const projectConfig = await Yaml.fromFile(configFilePath)
  return _read(configFilePath, flags, projectConfig)
}

function readSync (configFilePath, flags = {}) {
  const projectConfig = Yaml.fromFileSync(configFilePath)
  return _read(configFilePath, flags, projectConfig)
}

const _read = (configFilePath, flags, projectConfig) => {
  // retrieve config and options
  const configPath = path.dirname(configFilePath)
  const packageData = readPackageJson()
  const options = readFlags(flags)

  // initialize data with defaults
  const { name, version } = packageData
  const defaults = { name, version }
  let data = R.mergeAll([defaults, projectConfig, options])

  // resolve paths, adapters, and theme
  let { source, target, theme, adapters, templates } = projectConfig

  assert(source, 'Please provide a "source" config.')
  assert(target, 'Please provide a "target" config with the destination path for the generated site.')

  const resolvePaths = R.partial(resolvePath, [configPath])
  const resolveAdapters = R.partial(resolvePackage, [configPath], 'Adapter')

  source = R.map(resolvePaths, source)
  source.base = configPath
  source.configFile = resolvePath(configPath, configFilePath)
  target = resolvePath(configPath, target)
  theme = resolveTheme(configPath, theme)
  adapters = R.map(resolveAdapters, adapters || {})
  templates = resolveTemplates(source.templates, templates || {})

  data = R.assoc('source', source, data)
  data = R.assoc('target', target, data)
  data = R.assoc('theme', theme, data)
  data = R.assoc('adapters', adapters, data)
  data = R.assoc('templates', templates, data)

  return data
}

module.exports = {
  read,
  readSync
}
<commit_msg>🐛 fix erroneous overriding of debug flag in config<commit_after>const path = require('path')
const R = require('ramda')
const assert = require('assert')
const glob = require('globby')
const Yaml = require('./util/yaml')
const TemplateUtil = require('./util/template')
const { error } = require('./util/message')

const readPackageJson = () => {
  let data = {}
  try {
    const packageJson = path.resolve(process.cwd(), 'package.json')
    data = require(packageJson)
  } catch (err) {}

  return data
}

const readFlags = flags => {
  return flags.debug ? { debug: flags.debug } : {}
}

// if module is a relative path, resolve the absolute path,
// relative to project config directory (basedir).
// otherwise assume it's a node module that can be required.
const resolveModule = (basedir, module) =>
  module.startsWith('.') ? path.resolve(basedir, module) : module

const resolvePath = (basedir, relativePath) =>
  path.resolve(basedir, relativePath)

const resolveTheme = (basedir, theme = 'uiengine-theme-default') =>
  resolvePackage(basedir, theme, 'Theme')

const resolvePackage = (basedir, config, type) => {
  if (typeof config === 'object' && typeof config.module === 'string') {
    const options = typeof config.options === 'object' ? config.options : {}

    return {
      module: resolveModule(basedir, config.module),
      options
    }
  } else if (typeof config === 'string') {
    return {
      module: resolveModule(basedir, config),
      options: {}
    }
  } else {
    throw new Error(error(`${type} needs to be a configuration object (with module and options keys) or a module string (requireable path or name):`, config))
  }
}

const resolveTemplates = (templatesPath, config) => {
  if (!templatesPath || !path.isAbsolute(templatesPath)) return config

  // templates that are explicitely listed in the config
  const resolveDeclaredTemplates = R.partial(resolvePath, [templatesPath])
  const declared = R.map(resolveDeclaredTemplates, config)

  // templates that exist inside the templates directory
  const pattern = path.join(templatesPath, `**/*.*`)
  const paths = glob.sync(pattern)
  const templates = R.reduce((tmpl, templatePath) => {
    const id = TemplateUtil.templateFilePathToTemplateId(templatesPath, templatePath)
    tmpl[id] = templatePath

    return tmpl
  }, declared, paths)

  return templates
}

async function read (configFilePath, flags = {}) {
  const projectConfig = await Yaml.fromFile(configFilePath)
  return _read(configFilePath, flags, projectConfig)
}

function readSync (configFilePath, flags = {}) {
  const projectConfig = Yaml.fromFileSync(configFilePath)
  return _read(configFilePath, flags, projectConfig)
}

const _read = (configFilePath, flags, projectConfig) => {
  // retrieve config and options
  const configPath = path.dirname(configFilePath)
  const packageData = readPackageJson()
  const options = readFlags(flags)

  // initialize data with defaults
  const { name, version } = packageData
  const defaults = { name, version }
  let data = R.mergeAll([defaults, projectConfig, options])

  // resolve paths, adapters, and theme
  let { source, target, theme, adapters, templates } = projectConfig

  assert(source, 'Please provide a "source" config.')
  assert(target, 'Please provide a "target" config with the destination path for the generated site.')

  const resolvePaths = R.partial(resolvePath, [configPath])
  const resolveAdapters = R.partial(resolvePackage, [configPath], 'Adapter')

  source = R.map(resolvePaths, source)
  source.base = configPath
  source.configFile = resolvePath(configPath, configFilePath)
  target = resolvePath(configPath, target)
  theme = resolveTheme(configPath, theme)
  adapters = R.map(resolveAdapters, adapters || {})
  templates = resolveTemplates(source.templates, templates || {})

  data = R.assoc('source', source, data)
  data = R.assoc('target', target, data)
  data = R.assoc('theme', theme, data)
  data = R.assoc('adapters', adapters, data)
  data = R.assoc('templates', templates, data)

  return data
}

module.exports = {
  read,
  readSync
}
<|endoftext|>


<commit_before>import '../src/styles/global.scss';

export AppBar, { appBarHeight } from './components/AppBar';
export AppFooter, {
  appFooterHeightShort,
  appFooterHeightTall
} from './components/AppFooter';
export AppSwitcher from './components/AppSwitcher';
export Avatar from './components/Avatar';
export Chip from './components/Chip';
export Lozenge from './components/Lozenge';
export Truncate from './components/Truncate';
export DelayedProgress from './components/DelayedProgress';
export NavigationSideBar, {
  sectionsShape as navigationSidebarSectionsShape
} from './components/NavigationSideBar';
export DiscoverySideBar, {
  sectionsShape as discoverySidebarSectionsShape
} from './components/DiscoverySideBar';
export FullScreenDialog from './components/FullScreenDialog';
export ProfileMenu from './components/ProfileMenu';
export RaisedTextField from './components/RaisedTextField';
export TopBar, { topBarHeight } from './components/TopBar';
export FilePicker from './components/FilePicker';
export ProgressDialog from './components/ProgressDialog';
export * as formComponents from './components/formComponents';
export AppContainer from './components/AppContainer';
export OAuthLoginButton from './components/OAuthLoginButton';
export { Table, PaginatedTable, Column, LOADING } from './components/DataTable';
export MenuColumn from './components/DataTable/MenuColumn';
export withMuiThemeProvider from './helpers/withMuiThemeProvider';
export SearchPill from './components/SearchPill';
export HorizontalScroll from './components/HorizontalScroll';
export GeoPicker from './components/GeoPicker';
export ExpandableInputField from './components/ExpandableInputField';
export SearchBar from './components/SearchBar';
<commit_msg>export overlay components<commit_after>import '../src/styles/global.scss';

export AppBar, { appBarHeight } from './components/AppBar';
export AppFooter, {
  appFooterHeightShort,
  appFooterHeightTall
} from './components/AppFooter';
export AppSwitcher from './components/AppSwitcher';
export Avatar from './components/Avatar';
export Chip from './components/Chip';
export Lozenge from './components/Lozenge';
export Truncate from './components/Truncate';
export DelayedProgress from './components/DelayedProgress';
export NavigationSideBar, {
  sectionsShape as navigationSidebarSectionsShape
} from './components/NavigationSideBar';
export DiscoverySideBar, {
  sectionsShape as discoverySidebarSectionsShape
} from './components/DiscoverySideBar';
export FullScreenDialog from './components/FullScreenDialog';
export ProfileMenu from './components/ProfileMenu';
export RaisedTextField from './components/RaisedTextField';
export TopBar, { topBarHeight } from './components/TopBar';
export FilePicker from './components/FilePicker';
export ProgressDialog from './components/ProgressDialog';
export * as formComponents from './components/formComponents';
export AppContainer from './components/AppContainer';
export OAuthLoginButton from './components/OAuthLoginButton';
export { Table, PaginatedTable, Column, LOADING } from './components/DataTable';
export MenuColumn from './components/DataTable/MenuColumn';
export withMuiThemeProvider from './helpers/withMuiThemeProvider';
export SearchPill from './components/SearchPill';
export HorizontalScroll from './components/HorizontalScroll';
export GeoPicker from './components/GeoPicker';
export ExpandableInputField from './components/ExpandableInputField';
export SearchBar from './components/SearchBar';
export Overlay from './components/BoundingPolyOverlay/Overlay';
export OverlayPositioningProvider from './components/BoundingPolyOverlay/OverlayPositioningProvider';
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { intlShape } from './shape';

const FormattedMessage = ({ id, values, defaultMessage = '', html = false }, { intl }) => {
  const message = intl.formatMessage({ id, defaultMessage }, values);
  return html ?
     :
    {message}
}

FormattedMessage.contextTypes = {
  intl: intlShape
}

export default FormattedMessage;
<commit_msg>Add className prop to FormattedMessage<commit_after>import React, { Component } from 'react';
import { intlShape } from './shape';

const FormattedMessage = ({ id, values, defaultMessage = '', html = false, className = '' }, { intl }) => {
  const message = intl.formatMessage({ id, defaultMessage }, values);
  const cssClass = `i18n-message ${className}`;

  return html ?
     :
    {message}
}

FormattedMessage.contextTypes = {
  intl: intlShape
}

export default FormattedMessage;
<|endoftext|>


<commit_before>const net = require('net')
const client = net.connect({port:3000},() => {
	console.log("connected to server!");
	while(1){
		client.write("{\"tem\":\"20\",\"hum\":\"80\"}");
	}

});
client.on('data',(data) => {
	console.log(data.toString());
	client.end();
});
client.on('end',() => {
	console.log('disconnected from server');
})<commit_msg>change<commit_after>const net = require('net')
const client = net.connect({port:3000},() => {
	console.log("connected to server!");
	while(1){
		client.write("{\"tem\":\"20\",\"hum\":\"80\",\"indoor\":\"1\"}");
	}

});
client.on('data',(data) => {
	console.log(data.toString());
	client.end();
});
client.on('end',() => {
	console.log('disconnected from server');
})<|endoftext|>


<commit_before>/** @file This file contains the scripts used when LabelMe starts up. */

/** Main entry point for the annotation tool. */
function StartupLabelMe() {
  console.time('startup');

  // Check browser:
  GetBrowserInfo();
  if(IsNetscape() || (IsMicrosoft() && (bversion>=4.5)) || IsSafari() || IsChrome()) {
    // Write "start up" messages:
    WriteLogMsg('*start_loading');
    console.log('LabelMe: starting up...');

    // Initialize global variables:
    main_handler = new handler();
    main_canvas = new canvas('myCanvas_bg');
    main_media = new image('im');
    // Parse the input URL.  Returns false if the URL does not set the
    // annotation folder or image filename.  If false is returned, the
    // function fetches a new image and sets the URL to reflect the
    // fetched image.
    if(!main_media.GetFileInfo().ParseURL()) return;

    if(video_mode) {
      $('#generic_buttons').remove();
      $.getScript("annotationTools/js/video.js", function(){
        main_media = new video('videoplayer');
        main_media.GetFileInfo().ParseURL();
        console.log("Video mode...");

        function main_media_onload_helper(){
          var anno_file = main_media.GetFileInfo().GetFullName();
          anno_file = 'VLMAnnotations/' + anno_file + '.xml' + '?' + Math.random();
          ReadXML(anno_file,LoadAnnotationSuccess,LoadAnnotation404);
        }
        main_media.GetNewVideo(main_media_onload_helper);
      });
    }
    else if (threed_mode){
      // 3D Code Starts here
    }
    else {
      // This function gets run after image is loaded:
      function main_media_onload_helper() {
      // Set the image dimensions:
      main_media.SetImageDimensions();

      // Read the XML annotation file:
      var anno_file = main_media.GetFileInfo().GetFullName();
      anno_file = 'Annotations/' + anno_file.substr(0,anno_file.length-4) + '.xml' + '?' + Math.random();
      ReadXML(anno_file,LoadAnnotationSuccess,LoadAnnotation404);
          };

      // Get the image:
      main_media.GetNewImage(main_media_onload_helper);
    }
  }
  else {
    // Invalid browser, so display error page.
    $('body').remove();
    $('html').append('

Sorry!  This page only works with Mozilla Firefox, Chrome, and Internet Explorer.  We may support other browsers in the future.

Download Mozilla Firefox?
');
  }
}

/** This function gets called if the annotation has been successfully loaded.
  * @param {string} xml - the xml regarding the current file
*/
function LoadAnnotationSuccess(xml) {

  console.time('load success');

  // Set global variable:
  LM_xml = xml;

  // Set AllAnnotations array:
  SetAllAnnotationsArray();

  console.time('attach main_canvas');
  // Attach valid annotations to the main_canvas:
  for(var pp = 0; pp < LMnumberOfObjects(LM_xml); pp++) {
    var isDeleted = LMgetObjectField(LM_xml, pp, 'deleted');
    if((view_Existing&&!isDeleted)||(isDeleted&&view_Deleted)) {
      // Attach to main_canvas:
      main_canvas.AttachAnnotation(new annotation(pp));
      if (!video_mode && LMgetObjectField(LM_xml, pp, 'x') == null){
        main_canvas.annotations[main_canvas.annotations.length -1].SetType(1);
        main_canvas.annotations[main_canvas.annotations.length -1].scribble = new scribble(pp);
      }
    }
  }
  console.timeEnd('attach main_canvas');

  console.time('RenderAnnotations()');
  // Render the annotations:
  main_canvas.RenderAnnotations();
  console.timeEnd('RenderAnnotations()');

  console.timeEnd('load success');

  // Finish the startup scripts:
  FinishStartup();
}

/** Sets AllAnnotations array from LM_xml */
function SetAllAnnotationsArray() {
  var obj_elts = LM_xml.getElementsByTagName("object");
  var num_obj = obj_elts.length;

  num_orig_anno = num_obj;

  console.time('initialize XML');
  // Initialize any empty tags in the XML file:
  for(var pp = 0; pp < num_obj; pp++) {
    var curr_obj = $(LM_xml).children("annotation").children("object").eq(pp);

    // Initialize object name if empty in the XML file:
    if(curr_obj.children("name").length == 0) LMsetObjectField(LM_xml, pp, "name","");

    // Set object IDs:
    LMsetObjectField(LM_xml, pp, "id", pp.toString());

    /*************************************************************/
    /*************************************************************/
    // Scribble:
    // Initialize username if empty in the XML file. Check first if we
    // have a polygon or a segmentation:
    if(curr_obj.children("polygon").length == 0) { // Segmentation
      if(curr_obj.children("segm").children("username").length == 0) {
        curr_obj.children("segm").append($("<username>anonymous</username>"));
      }
    }
    else if(curr_obj.children("polygon").children("username").length == 0) curr_obj.children("polygon").append($("<username>anonymous</username>"));
    /*************************************************************/
    /*************************************************************/
  }
  console.timeEnd('initialize XML');

  console.time('addPartFields()');
  // Add part fields (this calls a funcion inside object_parts.js)
  addPartFields(); // makes sure all the annotations have all the fields.
  console.timeEnd('addPartFields()');

  console.time('loop annotated');

  console.timeEnd('loop annotated');
}

/** Annotation file does not exist, so load template. */
function LoadAnnotation404(jqXHR,textStatus,errorThrown) {
  if(jqXHR.status==404)
    ReadXML(main_media.GetFileInfo().GetTemplatePath(),LoadTemplateSuccess,LoadTemplate404);
  else
    alert(jqXHR.status);
}

/** Annotation template does not exist for this folder, so load default */
function LoadTemplate404(jqXHR,textStatus,errorThrown) {
  if(jqXHR.status==404)
    ReadXML('annotationCache/XMLTemplates/labelme.xml',LoadTemplateSuccess,function(jqXHR) {
  alert(jqXHR.status);
      });
  else
    alert(jqXHR.status);
}

/** Actions after template load success
  * @param {string} xml - the xml regarding the current file
*/
function LoadTemplateSuccess(xml) {
  // Set global variable:
  LM_xml = xml;

  // Set folder and image filename:
  LM_xml.getElementsByTagName("filename")[0].firstChild.nodeValue = '\n'+main_media.GetFileInfo().GetImName()+'\n';
  LM_xml.getElementsByTagName("folder")[0].firstChild.nodeValue = '\n'+main_media.GetFileInfo().GetDirName()+'\n';

  // Set global variable:
  num_orig_anno = 0;

  // Finish the startup scripts:
  FinishStartup();
}

/** Finish the startup process: */
function FinishStartup() {
  // Load the annotation list on the right side of the page:
  if(view_ObjList) RenderObjectList();

  // Add actions:
  console.log('LabelMe: setting actions');
  if($('#img_url')){
    if (!video_mode) $('#img_url').attr('onclick','javascript:location.href=main_media.GetFileInfo().GetImagePath();');
    else $('#img_url').attr('onclick','javascript:location.href=main_media.GetFileInfo().GetVideoPath();');
  }
  $('#changeuser').attr("onclick","javascript:show_enterUserNameDIV(); return false;");
  $('#userEnter').attr("onkeyup","javascript:var c; if(event.keyCode)c=event.keyCode; if(event.which)c=event.which; if(c==13 || c==27) changeAndDisplayUserName(c);");
  $('#xml_url').attr("onclick","javascript:GetXMLFile();");
  $('#nextImage').attr("onclick","javascript:ShowNextImage()");
  if (video_mode){
    $('#nextImage').attr("title", "Next Video");
    $('#img_url').attr("title", "Download Video");
  }
  $('#zoomin').attr("onclick","javascript:main_media.Zoom(1.15)");
  $('#zoomout').attr("onclick","javascript:main_media.Zoom(1.0/1.15)");
  $('#fit').attr("onclick","javascript:main_media.Zoom('fitted')");
  $('#erase').attr("onclick","javascript:main_handler.EraseSegment()");
  $('#myCanvas_bg_div').attr("onmousedown","javascript:StartDrawEvent(event);return false;");
  $('#myCanvas_bg_div').attr("oncontextmenu","javascript:return false;");
  $('#myCanvas_bg_div').attr("onmouseover","javascript:unselectObjects();");
  $('#select_canvas_div').attr("oncontextmenu","javascript:return false;");
  $('#query_canvas_div').attr("onmousedown","javascript:event.preventDefault();WaitForInput();return false;");
  $('#query_canvas_div').attr("onmouseup","javascript:event.preventDefault();");
  $('#query_canvas_div').attr("oncontextmenu","javascript:return false;");

  // Initialize the username:
  initUserName();

  // Enable scribble mode:
  InitializeAnnotationTools('label_buttons_drawing','main_media');

  // Set action when the user presses a key:
  document.onkeyup = main_handler.KeyPress;

  // Collect statistics:
  ref = document.referrer;

  // Write "finished" messages:
  WriteLogMsg('*done_loading_' + main_media.GetFileInfo().GetImagePath());
  console.log('LabelMe: finished loading');

  console.timeEnd('startup');
}

// Initialize the segmentation tool. This function is called when the field
// scribble of the url is true
function InitializeAnnotationTools(tag_button, tag_canvas){
    if (scribble_mode) scribble_canvas = new scribble_canvas(tag_canvas);
    var html_str = '
Polygon

Tool \
        <button id="polygon" class="labelBtnDraw" type="button" title="Start Polygon" onclick="SetPolygonDrawingMode(false)" > \
         \
        </button> \
        <button id="erase" class="labelBtnDraw" type="button" title="Delete last segment" onclick="main_handler.EraseSegment()" > \
         \
        </button> ';
        if (bbox_mode) html_str += ' <button id="bounding_box" class="labelBtnDraw" type="button" title="Start bounding box" onclick="SetPolygonDrawingMode(true)" > \
         \
        </button> ';
    html_str += '
';

    if (!video_mode){
      html_str += '
Mask

Tool \
        <button id="ScribbleObj" class="labelBtnDraw" type="button" title="Use the red pencil to mark areas inside the object you want to segment" onclick="scribble_canvas.setCurrentDraw(OBJECT_DRAWING)" > \
        </button> \
        <button id="ScribbleBg" class="labelBtnDraw" type="button" title="Use the blue pencil to mark areas outside the object" onclick="scribble_canvas.setCurrentDraw(BG_DRAWING)" > \
        </button> \
        <button id="ScribbleRubber" class="labelBtnDraw" type="button" title="ScribbleRubber" onclick="scribble_canvas.setCurrentDraw(RUBBER_DRAWING)" > \
         \
        </button><input type="button" class="segbut"  id="donebtn" value="Done" title="Press this button after you are done with the scribbling." onclick="scribble_canvas.segmentImage(1)"/> \

';

      var html_str2 = '<button xmlns="http://www.w3.org/1999/xhtml" id="img_url" class="labelBtn" type="button" title="Download Pack" onclick="javascript:GetPackFile();"> \
           \
          </button>';

      var html_str3 = '<form action="annotationTools/php/getpackfile.php" method="post" id="packform"> \
          <input type="hidden" id= "folder" name="folder" value="provesfinal" /> \
          <input type="hidden" id= "name" name="name" value="img2.jpg" /> \
         </form>';

      $('#tool_buttons').append(html_str3);
      $('#help').before(html_str2);
    }
    $('#'+tag_button).append(html_str);
    if (document.getElementById("polygon")) document.getElementById("polygon").setAttribute('style', 'background-color: #faa');
    if (document.getElementById("segmDiv")){
      document.getElementById("segmDiv").setAttribute('style', 'opacity: 1');
      document.getElementById("segmDiv").setAttribute('style', 'border-color: #000');
    }
    if (document.getElementById("polygonDiv")){
      document.getElementById("polygonDiv").setAttribute('style', 'opacity: 1');
      document.getElementById("polygonDiv").setAttribute('style', 'border-color: #f00');
    }
    if (video_mode) SetPolygonDrawingMode(true);

}

// Switch between polygon and scribble mode. If a polygon is open or the user
// is in the middle of the segmentation an alert appears to indicate so.
function SetDrawingMode(mode){
    if (drawing_mode == mode || active_canvas == QUERY_CANVAS) return;
    if (mode == 0){
        if (scribble_canvas.annotationid != -1){
            alert("You can't change drawing mode while editting scribbles.");
            return;
        }

        document.getElementById("segmDiv").setAttribute('style', 'border-color: #000');
        document.getElementById("polygonDiv").setAttribute('style', 'border-color: #f00');
        scribble_canvas.scribble_image = "";
        scribble_canvas.cleanscribbles();
        scribble_canvas.CloseCanvas();
    }
    if (mode == 1) {
        if(draw_anno) {
        alert("Need to close current polygon first.");
        return;
    }

    document.getElementById("segmDiv").setAttribute('style', 'border-color: #f00');
    document.getElementById("polygonDiv").setAttribute('style', 'border-color: #000');
    scribble_canvas.startSegmentationMode();
    }
    drawing_mode = mode;
}

function SetPolygonDrawingMode(bounding){
  if (active_canvas == QUERY_CANVAS) return;
  if(draw_anno) {
      alert("Need to close current polygon first.");
      return;
  }
  var buttons = document.getElementsByClassName("labelBtnDraw");
  for (var i = 0; i < buttons.length; i++) buttons[i].setAttribute('style', 'background-color: #fff');
  if (!bounding) document.getElementById("polygon").setAttribute('style', 'background-color: #faa');
  else document.getElementById("bounding_box").setAttribute('style', 'background-color: #faa');
  bounding_box = bounding;
  SetDrawingMode(0);
}<commit_msg>Clean invalid characters on xml load<commit_after>/** @file This file contains the scripts used when LabelMe starts up. */

/** Main entry point for the annotation tool. */
function StartupLabelMe() {
  console.time('startup');

  // Check browser:
  GetBrowserInfo();
  if(IsNetscape() || (IsMicrosoft() && (bversion>=4.5)) || IsSafari() || IsChrome()) {
    // Write "start up" messages:
    WriteLogMsg('*start_loading');
    console.log('LabelMe: starting up...');

    // Initialize global variables:
    main_handler = new handler();
    main_canvas = new canvas('myCanvas_bg');
    main_media = new image('im');
    // Parse the input URL.  Returns false if the URL does not set the
    // annotation folder or image filename.  If false is returned, the
    // function fetches a new image and sets the URL to reflect the
    // fetched image.
    if(!main_media.GetFileInfo().ParseURL()) return;

    if(video_mode) {
      $('#generic_buttons').remove();
      $.getScript("annotationTools/js/video.js", function(){
        main_media = new video('videoplayer');
        main_media.GetFileInfo().ParseURL();
        console.log("Video mode...");

        function main_media_onload_helper(){
          var anno_file = main_media.GetFileInfo().GetFullName();
          anno_file = 'VLMAnnotations/' + anno_file + '.xml' + '?' + Math.random();
          ReadXML(anno_file,LoadAnnotationSuccess,LoadAnnotation404);
        }
        main_media.GetNewVideo(main_media_onload_helper);
      });
    }
    else if (threed_mode){
      // 3D Code Starts here
    }
    else {
      // This function gets run after image is loaded:
      function main_media_onload_helper() {
      // Set the image dimensions:
      main_media.SetImageDimensions();

      // Read the XML annotation file:
      var anno_file = main_media.GetFileInfo().GetFullName();
      anno_file = 'Annotations/' + anno_file.substr(0,anno_file.length-4) + '.xml' + '?' + Math.random();
      ReadXML(anno_file,LoadAnnotationSuccess,LoadAnnotation404);
          };

      // Get the image:
      main_media.GetNewImage(main_media_onload_helper);
    }
  }
  else {
    // Invalid browser, so display error page.
    $('body').remove();
    $('html').append('

Sorry!  This page only works with Mozilla Firefox, Chrome, and Internet Explorer.  We may support other browsers in the future.

Download Mozilla Firefox?
');
  }
}

/** This function gets called if the annotation has been successfully loaded.
  * @param {string} xml - the xml regarding the current file
*/
function LoadAnnotationSuccess(xml) {

  console.time('load success');

  // Set global variable:
  LM_xml = xml;

  // Set AllAnnotations array:
  SetAllAnnotationsArray();

  console.time('attach main_canvas');
  // Attach valid annotations to the main_canvas:
  for(var pp = 0; pp < LMnumberOfObjects(LM_xml); pp++) {
    var isDeleted = LMgetObjectField(LM_xml, pp, 'deleted');
    if((view_Existing&&!isDeleted)||(isDeleted&&view_Deleted)) {
      // Attach to main_canvas:
      main_canvas.AttachAnnotation(new annotation(pp));
      if (!video_mode && LMgetObjectField(LM_xml, pp, 'x') == null){
        main_canvas.annotations[main_canvas.annotations.length -1].SetType(1);
        main_canvas.annotations[main_canvas.annotations.length -1].scribble = new scribble(pp);
      }
    }
  }
  console.timeEnd('attach main_canvas');

  console.time('RenderAnnotations()');
  // Render the annotations:
  main_canvas.RenderAnnotations();
  console.timeEnd('RenderAnnotations()');

  console.timeEnd('load success');

  // Finish the startup scripts:
  FinishStartup();
}

/** Sets AllAnnotations array from LM_xml */
function SetAllAnnotationsArray() {
  var obj_elts = LM_xml.getElementsByTagName("object");
  var num_obj = obj_elts.length;

  num_orig_anno = num_obj;

  console.time('initialize XML');
  // Initialize any empty tags in the XML file:
  for(var pp = 0; pp < num_obj; pp++) {
    var curr_obj = $(LM_xml).children("annotation").children("object").eq(pp);

    // Initialize object name if empty in the XML file:
    if(curr_obj.children("name").length == 0) LMsetObjectField(LM_xml, pp, "name","");

    // Set object IDs:
    LMsetObjectField(LM_xml, pp, "id", pp.toString());

    /*************************************************************/
    /*************************************************************/
    // Scribble:
    // Initialize username if empty in the XML file. Check first if we
    // have a polygon or a segmentation:
    if(curr_obj.children("polygon").length == 0) { // Segmentation
      if(curr_obj.children("segm").children("username").length == 0) {
        curr_obj.children("segm").append($("<username>anonymous</username>"));
      }
    }
    else if(curr_obj.children("polygon").children("username").length == 0) curr_obj.children("polygon").append($("<username>anonymous</username>"));
    /*************************************************************/
    /*************************************************************/
  }
  console.timeEnd('initialize XML');

  console.time('addPartFields()');
  // Add part fields (this calls a funcion inside object_parts.js)
  addPartFields(); // makes sure all the annotations have all the fields.
  console.timeEnd('addPartFields()');

  console.time('loop annotated');

  console.timeEnd('loop annotated');
}

/** Annotation file does not exist, so load template. */
function LoadAnnotation404(jqXHR,textStatus,errorThrown) {
  if(jqXHR.status==404)
    ReadXML(main_media.GetFileInfo().GetTemplatePath(),LoadTemplateSuccess,LoadTemplate404);
  else if (jqXHR.status == 200){
    var resp = jqXHR.responseText;
    var NOT_SAFE_IN_XML_1_0 = /[^\x09\x0A\x0D\x20-\xFF\x85\xA0-\uD7FF\uE000-\uFDCF\uFDE0-\uFFFD]/gm;
    resp =resp.replace(/[\u001a]/gm,'');
    resp = resp.replace(NOT_SAFE_IN_XML_1_0,'');
    LoadAnnotationSuccess(jQuery.parseXML(resp));
  }
  else
    alert(jqXHR.status);
}

/** Annotation template does not exist for this folder, so load default */
function LoadTemplate404(jqXHR,textStatus,errorThrown) {
  if(jqXHR.status==404)
    ReadXML('annotationCache/XMLTemplates/labelme.xml',LoadTemplateSuccess,function(jqXHR) {
  alert(jqXHR.status);
      });
  else
    alert(jqXHR.status);
}

/** Actions after template load success
  * @param {string} xml - the xml regarding the current file
*/
function LoadTemplateSuccess(xml) {
  // Set global variable:
  LM_xml = xml;

  // Set folder and image filename:
  LM_xml.getElementsByTagName("filename")[0].firstChild.nodeValue = '\n'+main_media.GetFileInfo().GetImName()+'\n';
  LM_xml.getElementsByTagName("folder")[0].firstChild.nodeValue = '\n'+main_media.GetFileInfo().GetDirName()+'\n';

  // Set global variable:
  num_orig_anno = 0;

  // Finish the startup scripts:
  FinishStartup();
}

/** Finish the startup process: */
function FinishStartup() {
  // Load the annotation list on the right side of the page:
  if(view_ObjList) RenderObjectList();

  // Add actions:
  console.log('LabelMe: setting actions');
  if($('#img_url')){
    if (!video_mode) $('#img_url').attr('onclick','javascript:location.href=main_media.GetFileInfo().GetImagePath();');
    else $('#img_url').attr('onclick','javascript:location.href=main_media.GetFileInfo().GetVideoPath();');
  }
  $('#changeuser').attr("onclick","javascript:show_enterUserNameDIV(); return false;");
  $('#userEnter').attr("onkeyup","javascript:var c; if(event.keyCode)c=event.keyCode; if(event.which)c=event.which; if(c==13 || c==27) changeAndDisplayUserName(c);");
  $('#xml_url').attr("onclick","javascript:GetXMLFile();");
  $('#nextImage').attr("onclick","javascript:ShowNextImage()");
  if (video_mode){
    $('#nextImage').attr("title", "Next Video");
    $('#img_url').attr("title", "Download Video");
  }
  $('#zoomin').attr("onclick","javascript:main_media.Zoom(1.15)");
  $('#zoomout').attr("onclick","javascript:main_media.Zoom(1.0/1.15)");
  $('#fit').attr("onclick","javascript:main_media.Zoom('fitted')");
  $('#erase').attr("onclick","javascript:main_handler.EraseSegment()");
  $('#myCanvas_bg_div').attr("onmousedown","javascript:StartDrawEvent(event);return false;");
  $('#myCanvas_bg_div').attr("oncontextmenu","javascript:return false;");
  $('#myCanvas_bg_div').attr("onmouseover","javascript:unselectObjects();");
  $('#select_canvas_div').attr("oncontextmenu","javascript:return false;");
  $('#query_canvas_div').attr("onmousedown","javascript:event.preventDefault();WaitForInput();return false;");
  $('#query_canvas_div').attr("onmouseup","javascript:event.preventDefault();");
  $('#query_canvas_div').attr("oncontextmenu","javascript:return false;");

  // Initialize the username:
  initUserName();

  // Enable scribble mode:
  InitializeAnnotationTools('label_buttons_drawing','main_media');

  // Set action when the user presses a key:
  document.onkeyup = main_handler.KeyPress;

  // Collect statistics:
  ref = document.referrer;

  // Write "finished" messages:
  WriteLogMsg('*done_loading_' + main_media.GetFileInfo().GetImagePath());
  console.log('LabelMe: finished loading');

  console.timeEnd('startup');
}

// Initialize the segmentation tool. This function is called when the field
// scribble of the url is true
function InitializeAnnotationTools(tag_button, tag_canvas){
    if (scribble_mode) scribble_canvas = new scribble_canvas(tag_canvas);
    var html_str = '
Polygon

Tool \
        <button id="polygon" class="labelBtnDraw" type="button" title="Start Polygon" onclick="SetPolygonDrawingMode(false)" > \
         \
        </button> \
        <button id="erase" class="labelBtnDraw" type="button" title="Delete last segment" onclick="main_handler.EraseSegment()" > \
         \
        </button> ';
        if (bbox_mode) html_str += ' <button id="bounding_box" class="labelBtnDraw" type="button" title="Start bounding box" onclick="SetPolygonDrawingMode(true)" > \
         \
        </button> ';
    html_str += '
';

    if (!video_mode){
      html_str += '
Mask

Tool \
        <button id="ScribbleObj" class="labelBtnDraw" type="button" title="Use the red pencil to mark areas inside the object you want to segment" onclick="scribble_canvas.setCurrentDraw(OBJECT_DRAWING)" > \
        </button> \
        <button id="ScribbleBg" class="labelBtnDraw" type="button" title="Use the blue pencil to mark areas outside the object" onclick="scribble_canvas.setCurrentDraw(BG_DRAWING)" > \
        </button> \
        <button id="ScribbleRubber" class="labelBtnDraw" type="button" title="ScribbleRubber" onclick="scribble_canvas.setCurrentDraw(RUBBER_DRAWING)" > \
         \
        </button><input type="button" class="segbut"  id="donebtn" value="Done" title="Press this button after you are done with the scribbling." onclick="scribble_canvas.segmentImage(1)"/> \

';

      var html_str2 = '<button xmlns="http://www.w3.org/1999/xhtml" id="img_url" class="labelBtn" type="button" title="Download Pack" onclick="javascript:GetPackFile();"> \
           \
          </button>';

      var html_str3 = '<form action="annotationTools/php/getpackfile.php" method="post" id="packform"> \
          <input type="hidden" id= "folder" name="folder" value="provesfinal" /> \
          <input type="hidden" id= "name" name="name" value="img2.jpg" /> \
         </form>';

      $('#tool_buttons').append(html_str3);
      $('#help').before(html_str2);
    }
    $('#'+tag_button).append(html_str);
    if (document.getElementById("polygon")) document.getElementById("polygon").setAttribute('style', 'background-color: #faa');
    if (document.getElementById("segmDiv")){
      document.getElementById("segmDiv").setAttribute('style', 'opacity: 1');
      document.getElementById("segmDiv").setAttribute('style', 'border-color: #000');
    }
    if (document.getElementById("polygonDiv")){
      document.getElementById("polygonDiv").setAttribute('style', 'opacity: 1');
      document.getElementById("polygonDiv").setAttribute('style', 'border-color: #f00');
    }
    if (video_mode) SetPolygonDrawingMode(true);

}

// Switch between polygon and scribble mode. If a polygon is open or the user
// is in the middle of the segmentation an alert appears to indicate so.
function SetDrawingMode(mode){
    if (drawing_mode == mode || active_canvas == QUERY_CANVAS) return;
    if (mode == 0){
        if (scribble_canvas.annotationid != -1){
            alert("You can't change drawing mode while editting scribbles.");
            return;
        }

        document.getElementById("segmDiv").setAttribute('style', 'border-color: #000');
        document.getElementById("polygonDiv").setAttribute('style', 'border-color: #f00');
        scribble_canvas.scribble_image = "";
        scribble_canvas.cleanscribbles();
        scribble_canvas.CloseCanvas();
    }
    if (mode == 1) {
        if(draw_anno) {
        alert("Need to close current polygon first.");
        return;
    }

    document.getElementById("segmDiv").setAttribute('style', 'border-color: #f00');
    document.getElementById("polygonDiv").setAttribute('style', 'border-color: #000');
    scribble_canvas.startSegmentationMode();
    }
    drawing_mode = mode;
}

function SetPolygonDrawingMode(bounding){
  if (active_canvas == QUERY_CANVAS) return;
  if(draw_anno) {
      alert("Need to close current polygon first.");
      return;
  }
  var buttons = document.getElementsByClassName("labelBtnDraw");
  for (var i = 0; i < buttons.length; i++) buttons[i].setAttribute('style', 'background-color: #fff');
  if (!bounding) document.getElementById("polygon").setAttribute('style', 'background-color: #faa');
  else document.getElementById("bounding_box").setAttribute('style', 'background-color: #faa');
  bounding_box = bounding;
  SetDrawingMode(0);
}<|endoftext|>


<commit_before>/**
 * @fileOverview tests.js Gives testing code for the options page.
 * This spec is managed by the Jasmine testing library.
 **/

describe ("Options Suite", function() {

  beforeEach(function() {
    var domIDs = [
      {id: "button_status", type: "div"},
      {id: "disableBtn", type: "input"},
      {id: "status", type: "div"},
      {id: "glyph_div", type: "div"},
      {id: "invalid_domain", type: "div"},
      {id: "server_form", type: "input"},
      {id: "content_server_url", type: "input"},
      {id: "user", type: "input"},
      {id: "other_content_server", type: "input"},
      {id: "server_status", type: "div"},
      {id: "whitelist_url", type: "input", class: "whitelist_url", value: "example.org"},
      {id: "remove_whitelist", type: "div"},
      {id: "urls", type: "div"}
    ];
    domIDs.forEach(function(ob){
      var newElement = $('<' + ob.type + '/>', {
        id: ob.id,
        class: ob.class,
        value: ob.value
      });
      $(document.body).append(newElement);
    });
  });

  afterEach(function() {
    document.body.innerHTML = "";
  });

  it("tests writeability of glyph", function() {
    writeGlyph();
    expect(document.getElementById("glyph_div").children.length).toEqual(1);
  });

  it("tests generation of new glyph", function() {
    var glyph = ls.getItem("options/glyph");
    regenerateGlyph();
    var glyph2 = ls.getItem("options/glyph");
    expect(glyph.color).not.toEqual(glyph2.color);
    var patternDifference = false;
    for( var i = 0; i < 15; i++ ) {
      patternDifference = patternDifference
        || glyph.cells[i] !== glyph2.cells[i];
    }
    expect(patternDifference).toBe(true);
  });

  it("saves settings from UI", function() {
    ls.setItem("Options:DissableButton", "tmp");
    document.querySelector("#disableBtn").checked = true;
    saveCheckedSetting();
    var status = document.getElementById("button_status");
    expect(status.innerHTML).toBe("Setting Saved.");
    expect(ls.getItem("options/privlyButton")).toBe(false);
  });

  it("restores checked settings", function() {
    var btn = document.getElementById("disableBtn");

    // Dissables button
    ls.setItem("options/privlyButton", false);
    restoreCheckedSetting();
    expect(btn.checked).toBe(true);

    // Enables button
    ls.setItem("options/privlyButton", true);
    restoreCheckedSetting();
    expect(btn.checked).toBe(false);
  });

  it("saves empty whitelist", function() {
    $("#whitelist_url").remove();
    saveWhitelist();
    var status = document.getElementById("status");
    expect(status.innerHTML).toBe("Options Saved.");
    expect(ls.getItem("options/whitelist/domains").length).toBe(0);
    expect(ls.getItem("options/whitelist/regexp")).toBe("");
  });

  it("saves example.org for whitelist", function() {
    saveWhitelist();
    var status = document.getElementById("status");
    expect(status.innerHTML).toBe("Options Saved.");
    expect(ls.getItem("options/whitelist/domains").length).toBe(1);
    expect(ls.getItem("options/whitelist/domains")[0]).toBe("example.org");
    expect(ls.getItem("options/whitelist/regexp")).toBe("|example\\.org\\/");
  });

  it("restore whitelist does not result in an error", function() {

    // todo, the storage for this function is about to change, so
    // I am not going to write the storage checks yet.
    restoreWhitelist();
  });

  it("restores the content server to alpha", function() {
    ls.removeItem("posting_content_server_url");
    restoreServer();
    expect(ls.getItem("posting_content_server_url"), "https://privlyalpha.org");
  });

  it("saves the content server", function() {

    ls.removeItem("options/contentServer/url")

    Privly.options.setServerUrl("http://localhost:3000");
    expect(ls.getItem("options/contentServer/url")).toBe("http://localhost:3000");

    Privly.options.setServerUrl("https://privlyalpha.org");
    expect(ls.getItem("options/contentServer/url")).toBe("https://privlyalpha.org");

    Privly.options.setServerUrl("https://dev.privly.org");
    expect(ls.getItem("options/contentServer/url")).toBe("https://dev.privly.org");

    Privly.options.setServerUrl("https://custom.org");
    expect(ls.getItem("options/contentServer/url")).toBe("https://custom.org");
  });

  it("tests domain validation", function() {

    var validDomains = [
      'localhost',
      'localhost:3000',
      'example.com:3000',
      'example.example.com:3000',
      'example.example.example.com:3000'
    ];

    // Valid domains that should pass
    validDomains.forEach(function(d){
      expect(Privly.options.isDomainValid(d)).toBe(true);
    });

    var invalidDomains = [
      '.com:3000',
      'locahost@',
      'inva!id.com',
      'l@calhost',
      'locahost:30o0',
      '.not.valid.com',
      'example.',
      '..example.com',
      'example..com',
      'example.com.',
      ' example.com',
      'example.com ',
      '/path/but/not/domain/',
      ' ',
      'the quick brown fox jumps over the lazy dog'
    ];
    // Invalid domains that shouldn't pass
    invalidDomains.forEach(function(d){
      expect(Privly.options.isDomainValid(d)).toBe(false);
    });
  });

  it('saves the server', function () {
    var ev = {target: {value: ""}};
    saveServer(ev);
    expect($("#user").css("display")).toBe("none");
    ev.target.value = "save_server";
    var server = document.getElementById("content_server_url");
    server.value = "other";
    var sham = "https://sham.com";
    document.getElementById("other_content_server").value = sham;
    saveServer(ev);
    var cur = Privly.options.getServerUrl();
    expect(cur).toBe(sham);
    server.value = "alpha";
    saveServer(ev);
    cur = Privly.options.getServerUrl();
    expect(cur).toBe("https://privlyalpha.org");
    server.value = "dev";
    saveServer(ev);
    cur = Privly.options.getServerUrl();
    expect(cur).toBe("https://dev.privly.org");
    server.value = "local";
    saveServer(ev);
    cur = Privly.options.getServerUrl();
    expect(cur).toBe("http://localhost:3000");
  });

  it('does not result in an error when restoring the server', function () {
    // todo, refactor the script being tested
    Privly.options.setServerUrl("https://privlyalpha.org");
    restoreServer();
    Privly.options.setServerUrl("https://dev.privly.org");
    restoreServer();
    Privly.options.setServerUrl("http://localhost:3000");
    restoreServer();
    Privly.options.setServerUrl("http://other.com");
    restoreServer();
  });

  it('tests initialize app function', function () {

    // add logout_link to DOM so init function does not return immediately
    var ob =  {id: "logout_link", type: "a", class: "logout_url"};
    var newElement = $('<' + ob.type + '/>', {
      id: ob.id,
      class: ob.class,
      value: ob.value
    });
    $(document.body).append(newElement);

    spyOn(privlyNetworkService, 'initializeNavigation').and.stub();
    spyOn(privlyNetworkService, 'initPrivlyService').and.stub();
    spyOn(window, 'restoreCheckedSetting').and.callThrough();
    spyOn(window, 'restoreWhitelist').and.callThrough();
    spyOn(window, 'restoreServer').and.callThrough();
    spyOn(window, 'listeners').and.stub(); // mock because depends on DOM elements
    spyOn(window, 'writeGlyph').and.callThrough();

    initializeApp();

    expect(privlyNetworkService.initializeNavigation).toHaveBeenCalled();
    expect(privlyNetworkService.initPrivlyService).toHaveBeenCalled();
    expect(restoreCheckedSetting).toHaveBeenCalled();
    expect(restoreWhitelist).toHaveBeenCalled();
    expect(restoreServer).toHaveBeenCalled();
    expect(listeners).toHaveBeenCalled();
    expect(writeGlyph).toHaveBeenCalled();
  });
});
<commit_msg>Add coverage for removeWhitelistUrl and inputEvent<commit_after>/**
 * @fileOverview tests.js Gives testing code for the options page.
 * This spec is managed by the Jasmine testing library.
 **/

describe ("Options Suite", function() {

  beforeEach(function() {
    var domIDs = [
      {id: "button_status", type: "div"},
      {id: "disableBtn", type: "input"},
      {id: "status", type: "div"},
      {id: "glyph_div", type: "div"},
      {id: "invalid_domain", type: "div"},
      {id: "server_form", type: "input"},
      {id: "content_server_url", type: "input"},
      {id: "user", type: "input"},
      {id: "other_content_server", type: "input"},
      {id: "server_status", type: "div"},
      {id: "whitelist_url", type: "input", class: "whitelist_url", value: "example.org"},
      {id: "remove_whitelist", type: "div"},
      {id: "urls", type: "div"}
    ];
    domIDs.forEach(function(ob){
      var newElement = $('<' + ob.type + '/>', {
        id: ob.id,
        class: ob.class,
        value: ob.value
      });
      $(document.body).append(newElement);
    });
  });

  afterEach(function() {
    document.body.innerHTML = "";
  });

  it("tests writeability of glyph", function() {
    writeGlyph();
    expect(document.getElementById("glyph_div").children.length).toEqual(1);
  });

  it("tests generation of new glyph", function() {
    var glyph = ls.getItem("options/glyph");
    regenerateGlyph();
    var glyph2 = ls.getItem("options/glyph");
    expect(glyph.color).not.toEqual(glyph2.color);
    var patternDifference = false;
    for( var i = 0; i < 15; i++ ) {
      patternDifference = patternDifference
        || glyph.cells[i] !== glyph2.cells[i];
    }
    expect(patternDifference).toBe(true);
  });

  it("saves settings from UI", function() {
    ls.setItem("Options:DissableButton", "tmp");
    document.querySelector("#disableBtn").checked = true;
    saveCheckedSetting();
    var status = document.getElementById("button_status");
    expect(status.innerHTML).toBe("Setting Saved.");
    expect(ls.getItem("options/privlyButton")).toBe(false);
  });

  it("restores checked settings", function() {
    var btn = document.getElementById("disableBtn");

    // Dissables button
    ls.setItem("options/privlyButton", false);
    restoreCheckedSetting();
    expect(btn.checked).toBe(true);

    // Enables button
    ls.setItem("options/privlyButton", true);
    restoreCheckedSetting();
    expect(btn.checked).toBe(false);
  });

  it("saves empty whitelist", function() {
    $("#whitelist_url").remove();
    saveWhitelist();
    var status = document.getElementById("status");
    expect(status.innerHTML).toBe("Options Saved.");
    expect(ls.getItem("options/whitelist/domains").length).toBe(0);
    expect(ls.getItem("options/whitelist/regexp")).toBe("");
  });

  it("saves example.org for whitelist", function() {
    saveWhitelist();
    var status = document.getElementById("status");
    expect(status.innerHTML).toBe("Options Saved.");
    expect(ls.getItem("options/whitelist/domains").length).toBe(1);
    expect(ls.getItem("options/whitelist/domains")[0]).toBe("example.org");
    expect(ls.getItem("options/whitelist/regexp")).toBe("|example\\.org\\/");
  });

  it("restore whitelist does not result in an error", function() {

    // todo, the storage for this function is about to change, so
    // I am not going to write the storage checks yet.
    restoreWhitelist();
  });

  it("restores the content server to alpha", function() {
    ls.removeItem("posting_content_server_url");
    restoreServer();
    expect(ls.getItem("posting_content_server_url"), "https://privlyalpha.org");
  });

  it("saves the content server", function() {

    ls.removeItem("options/contentServer/url")

    Privly.options.setServerUrl("http://localhost:3000");
    expect(ls.getItem("options/contentServer/url")).toBe("http://localhost:3000");

    Privly.options.setServerUrl("https://privlyalpha.org");
    expect(ls.getItem("options/contentServer/url")).toBe("https://privlyalpha.org");

    Privly.options.setServerUrl("https://dev.privly.org");
    expect(ls.getItem("options/contentServer/url")).toBe("https://dev.privly.org");

    Privly.options.setServerUrl("https://custom.org");
    expect(ls.getItem("options/contentServer/url")).toBe("https://custom.org");
  });

  it("tests domain validation", function() {

    var validDomains = [
      'localhost',
      'localhost:3000',
      'example.com:3000',
      'example.example.com:3000',
      'example.example.example.com:3000'
    ];

    // Valid domains that should pass
    validDomains.forEach(function(d){
      expect(Privly.options.isDomainValid(d)).toBe(true);
    });

    var invalidDomains = [
      '.com:3000',
      'locahost@',
      'inva!id.com',
      'l@calhost',
      'locahost:30o0',
      '.not.valid.com',
      'example.',
      '..example.com',
      'example..com',
      'example.com.',
      ' example.com',
      'example.com ',
      '/path/but/not/domain/',
      ' ',
      'the quick brown fox jumps over the lazy dog'
    ];
    // Invalid domains that shouldn't pass
    invalidDomains.forEach(function(d){
      expect(Privly.options.isDomainValid(d)).toBe(false);
    });
  });

  it('saves the server', function () {
    var ev = {target: {value: ""}};
    saveServer(ev);
    expect($("#user").css("display")).toBe("none");
    ev.target.value = "save_server";
    var server = document.getElementById("content_server_url");
    server.value = "other";
    var sham = "https://sham.com";
    document.getElementById("other_content_server").value = sham;
    saveServer(ev);
    var cur = Privly.options.getServerUrl();
    expect(cur).toBe(sham);
    server.value = "alpha";
    saveServer(ev);
    cur = Privly.options.getServerUrl();
    expect(cur).toBe("https://privlyalpha.org");
    server.value = "dev";
    saveServer(ev);
    cur = Privly.options.getServerUrl();
    expect(cur).toBe("https://dev.privly.org");
    server.value = "local";
    saveServer(ev);
    cur = Privly.options.getServerUrl();
    expect(cur).toBe("http://localhost:3000");
  });

  it('does not result in an error when restoring the server', function () {
    // todo, refactor the script being tested
    Privly.options.setServerUrl("https://privlyalpha.org");
    restoreServer();
    Privly.options.setServerUrl("https://dev.privly.org");
    restoreServer();
    Privly.options.setServerUrl("http://localhost:3000");
    restoreServer();
    Privly.options.setServerUrl("http://other.com");
    restoreServer();
  });

  it('tests initialize app function', function () {

    // add logout_link to DOM so init function does not return immediately
    var ob =  {id: "logout_link", type: "a", class: "logout_url"};
    var newElement = $('<' + ob.type + '/>', {
      id: ob.id,
      class: ob.class,
      value: ob.value
    });
    $(document.body).append(newElement);

    spyOn(privlyNetworkService, 'initializeNavigation').and.stub();
    spyOn(privlyNetworkService, 'initPrivlyService').and.stub();
    spyOn(window, 'restoreCheckedSetting').and.callThrough();
    spyOn(window, 'restoreWhitelist').and.callThrough();
    spyOn(window, 'restoreServer').and.callThrough();
    spyOn(window, 'listeners').and.stub(); // mock because depends on DOM elements
    spyOn(window, 'writeGlyph').and.callThrough();

    initializeApp();

    expect(privlyNetworkService.initializeNavigation).toHaveBeenCalled();
    expect(privlyNetworkService.initPrivlyService).toHaveBeenCalled();
    expect(restoreCheckedSetting).toHaveBeenCalled();
    expect(restoreWhitelist).toHaveBeenCalled();
    expect(restoreServer).toHaveBeenCalled();
    expect(listeners).toHaveBeenCalled();
    expect(writeGlyph).toHaveBeenCalled();
  });

  it('removes whitelist url', function () {

    var event = { target:
                  {
                    className: ['foo', 'remove_whitelist'],
                    parentElement: { remove: function(){} }
                  }
                };

    spyOn(event.target.parentElement, 'remove').and.stub();
    spyOn(window, 'saveWhitelist').and.stub();

    removeWhitelistUrl(event);

    expect(event.target.parentElement.remove).toHaveBeenCalled();
    expect(saveWhitelist).toHaveBeenCalled();
  });

  it('saves whitelist on changes', function () {
    var event = { target:
                  { classList: 'foo whitelist_url' }
                };

    spyOn(window, 'saveWhitelist').and.stub();
    inputEvent(event);
    expect(saveWhitelist).toHaveBeenCalled();
  });

});
<|endoftext|>


<commit_before>CodeMirror.defineSimpleMode("paramour", {
  // The start state contains the rules that are intially used
  start: [
    // Strings
    {
      regex: /(["'])(?:[^\\]|\\.)*?\1/,
      token: "string"
    },
    {
      regex: /(\/(?:[^\\]|\\.)+?\/)([imguy]*)/,
      token: ["string", "variable-2"]
    },
    // Comments
    {
      regex: /###(?:[\s\S]*?)###/,
      token: "comment"
    },
    {
      regex: /(#\s*)(\$[a-z\$][\w\$]*)(\s*[\-\=]>\s*)(.*)/i,
      token: ["comment", "variable", "operator", null]
    },
    {
      regex: /(#\s*)(@)([\d\.]+)/i,
      token: ["comment", null, "number"]
    },
    {
      regex: /(#\s*)([\d\.]+)(\?[\!\*]?)/i,
      token: ["operator", "number", "operator"]
    },
    {
      regex: /#\?/,
      token: "operator"
    },
    {
      regex: /#.*/,
      token: "comment"
    },
    // Docstrings
    {
      regex: /\/\*/,
      token: "string",
      next: "docstring"
    },
    // Quasi Strings
    {
      regex: /`/,
      token: "string",
      next: "quasi"
    },
    {
      regex: /(["'`]{3})(?:[^\\]:\\.)*?\1/,
      token: "string"
    },
    // Get and Set
    {
      regex: /([gs]et\b\??)\s*([a-zA-Z\$_][\w\$]*)/,
      token: ["keyword-2", "variable"]
    },
    // Custom Operators
    {
      // Prefix Operator
      regex: /(\[\s*)([!\~\*\/%\+\-<>\&\^\|\?\:\=;]+)(\s*[a-z\$_][\w\$]*)(\s*\])/i,
      token: [null, "variable-2", "variable", null]
    },
    {
      // Media operator
      regex: /(\[\s*)([a-z\$_][\w\$]*\s*)([!\~\*\/%\+\-<>\&\^\|\?\:\=;]+)(\s*[a-z\$_][\w\$]*)(\s*\])/i,
      token: [null, "variable", "variable-2", "variable", null]
    },
    {
      // Suffix Operator
      regex: /(\[\s*)([a-z\$_][\w\$]*\s*)([!\~\*\/%\+\-<>\&\^\|\?\:\=;]+)(\s*\])/i,
      token: [null, "variable", "variable-2", null]
    },
    // Paramour Operators
    {
      regex: /((?:un)defined\s+)([a-zA-Z\$_][\w\$]*)/,
      token: ["atom", "variable"]
    },
    // Atoms and Atom-like
    {
      regex: /(\b(true|false|null|undefined|defined)\b|(\!+[01]))/,
      token: "atom"
    },
    // Keywords
    {
      regex: /\b(abstract|arguments|boolean|break|byte|case|catch|char|class|const|continue|debugger|default|delete|do|double|else|enum|eval|export|extends|false|final|finally|float|for|function|goto|if|implements|import|in|instanceof|int|interface|let|long|native|new|null|package|private|protected|public|return|short|static|super|switch|synchronized|this|throw|throws|transient|true|try|typeof|var|void|volatile|while|with|yield|[gs]et)\b/,
      token: "keyword"
    },
    {
      regex: /[\-\+\~\&]>|@/,
      token: "keyword"
    },
    // Variable names
    {
      regex: /(\.[a-z\$_][\w\$]*|\.{3}|<init>)/i,
      token: "variable-2"
    },
    {
      regex: /([a-z\$_][\w\$]*)/i,
      token: "variable"
    },
    // Numbers
    {
      regex: /\b(0b[01]+|0o[1-7]+|0x[a-f\d]+|[-+]?(?:\.\d+|\d+\.?\d*)(?:e[-+]?\d+)?)\b/i,
      token: "number"
    },
    // Operators
    {
      regex: /[!\~\*\/%\+\-<>\&\^\|\?\:\=]+/,
      token: "operator"
    },
    // N. Literals
    {
      regex: /[\{\[\(\?]/,
      indent: true
    },
    {
      regex: /[\)\]\}]/,
      dedent: true
    }
  ],

  // Quasi Strings
  quasi: [
    {
      regex: /`/,
      token: "string",
      next: "start"
    },
    {
      regex: /\$\{(?:[^\{\}]*?)\}/,
      mode: "start"
    },
    {
      regex: /^(?:[^\\]|\\.)*?$/,
      token: "string"
    }
  ],

  // Docstrings
  docstring: [
    {
      regex: /\*\//,
      token: "string",
      next: "start"
    },
    {
      regex: /^(.*)$/,
      token: "string"
    }
  ],

  // "The meta property contains global information about the mode. It
  // can contain properties like lineComment, which are supported by
  // all modes, and also directives like dontIndentStates, which are
  // specific to simple modes" - CodeMirror.
  meta: {
    dontIndentStates: ["comment"],
    blockCommentStart: "###",
    blockCommentEnd: "###",
    lineComment: "#",
    fold: "brace",
    closeBrackets: "( ) [ ] { } ' ' \" \" ` ` \"\"\" \"\"\" ''' ''' ``` ```".split(" ")
  }
});
<commit_msg>Update paramour.js<commit_after>CodeMirror.defineSimpleMode("paramour", {
  // The start state contains the rules that are intially used
  start: [
    // Strings
    {
      regex: /(["'])(?:[^\\]|\\.)*?\1/,
      token: "string"
    },
    {
      regex: /(\/(?:[^\\]|\\.)+?\/)([imguy]*)/,
      token: ["string", "variable-2"]
    },
    // Comments
    {
      regex: /###(?:[\s\S]*?)###/,
      token: "comment"
    },
    {
      regex: /(#\s*)(\$[a-z\$][\w\$]*)(\s*[\-\=]>\s*)(.*)/i,
      token: ["comment", "variable", "operator", null]
    },
    {
      regex: /(#\s*)(@)([\d\.]+)/i,
      token: ["comment", null, "number"]
    },
    {
      regex: /(#\s*)([\d\.]+)(\?[\!\*]?)/i,
      token: ["operator", "number", "operator"]
    },
    {
      regex: /#\?/,
      token: "operator"
    },
    {
      regex: /#.*/,
      token: "comment"
    },
    // Docstrings
    {
      regex: /\/\*/,
      token: "string",
      next: "docstring"
    },
    // Quasi Strings
    {
      regex: /`/,
      token: "string",
      next: "quasi"
    },
    {
      regex: /(["'`]{3})(?:[^\\]:\\.)*?\1/,
      token: "string"
    },
    // Get and Set
    {
      regex: /([gs]et\b\??)\s*([a-zA-Z\$_][\w\$]*)/,
      token: ["keyword-2", "variable"]
    },
    // Custom Operators
    {
      // Prefix Operator
      regex: /(\[\s*)([!\~\*\/%\+\-<>\&\^\|\?\:\=;]+)(\s*[a-z\$_][\w\$]*)(\s*\])/i,
      token: [null, "variable-2", "variable", null]
    },
    {
      // Media operator
      regex: /(\[\s*)([a-z\$_][\w\$]*\s*)([!\~\*\/%\+\-<>\&\^\|\?\:\=;]+)(\s*[a-z\$_][\w\$]*)(\s*\])/i,
      token: [null, "variable", "variable-2", "variable", null]
    },
    {
      // Suffix Operator
      regex: /(\[\s*)([a-z\$_][\w\$]*\s*)([!\~\*\/%\+\-<>\&\^\|\?\:\=;]+)(\s*\])/i,
      token: [null, "variable", "variable-2", null]
    },
    // Paramour Operators
    {
      regex: /((?:un)defined\s+)([a-zA-Z\$_][\w\$]*)/,
      token: ["atom", "variable"]
    },
    // Atoms and Atom-like
    {
      regex: /(\b(true|false|null|undefined|defined)\b|(\!+[01]))/,
      token: "atom"
    },
    // Keywords
    {
      regex: /\b(abstract|arguments|boolean|break|byte|case|catch|char|class|const|continue|debugger|default|delete|do|double|else|enum|eval|export|extends|false|final|finally|float|for|function|goto|if|implements|import|in|instanceof|int|interface|let|long|native|new|null|package|private|protected|public|return|short|static|super|switch|synchronized|this|throw|throws|transient|true|try|typeof|var|void|volatile|while|with|yield|[gs]et)\b/,
      token: "keyword"
    },
    {
      regex: /[\-\+\~\&]>|@/,
      token: "keyword"
    },
    // Variable names
    {
      regex: /(\.[a-z\$_][\w\$]*|\.{3}|<init>)/i,
      token: "variable-2"
    },
    {
      regex: /([a-z\$_][\w\$]*)/i,
      token: "variable"
    },
    // Numbers
    {
      regex: /\b(0b[01]+|0o[1-7]+|0x[a-f\d]+|[-+]?(?:\.\d+|\d+\.?\d*)(?:e[-+]?\d+)?)\b/i,
      token: "number"
    },
    // Operators
    {
      regex: /[!\~\*\/%\+\-<>\&\^\|\?\:\=]+/,
      token: "operator"
    },
    // N. Literals
    {
      regex: /[\{\[\(\?]/,
      indent: true
    },
    {
      regex: /[\)\]\}]/,
      dedent: true
    }
  ],

  // Quasi Strings
  quasi: [
    {
      regex: /`/,
      token: "string",
      next: "start"
    },
    {
      regex: /\$\{(?:[^\{\}]*?)\}/,
      mode: "start"
    },
    {
      regex: /^(?:[^\\]|\\.)*?$/,
      token: "string"
    }
  ],

  // Docstrings
  docstring: [
    {
      regex: /\*\//,
      token: "string",
      next: "start"
    },
    {
      regex: /^(?:[^\*]|\*[^\/])*?$/,
      token: "string"
    }
  ],

  // "The meta property contains global information about the mode. It
  // can contain properties like lineComment, which are supported by
  // all modes, and also directives like dontIndentStates, which are
  // specific to simple modes" - CodeMirror.
  meta: {
    dontIndentStates: ["comment"],
    blockCommentStart: "###",
    blockCommentEnd: "###",
    lineComment: "#",
    fold: "brace",
    closeBrackets: "( ) [ ] { } ' ' \" \" ` ` \"\"\" \"\"\" ''' ''' ``` ```".split(" ")
  }
});
<|endoftext|>