<commit_before>/* eslint-disable no-continue,no-restricted-syntax,no-plusplus */
import React, { Component } from 'react';
import {
  Editor,
  EditorState,
  DefaultDraftBlockRenderMap,
} from 'draft-js';
import { List, Map } from 'immutable';
import MultiDecorator from './MultiDecorator';
import createCompositeDecorator from './createCompositeDecorator';
import moveSelectionToEnd from './moveSelectionToEnd';
import proxies from './proxies';
import * as defaultKeyBindingPlugin from './defaultKeyBindingPlugin';

/**
 * The main editor component
 */
class PluginEditor extends Component {

  static propTypes = {
    editorState: React.PropTypes.object.isRequired,
    onChange: React.PropTypes.func.isRequired,
    plugins: React.PropTypes.array,
    defaultKeyBindings: React.PropTypes.bool,
    defaultBlockRenderMap: React.PropTypes.bool,
    customStyleMap: React.PropTypes.object,
    decorators: React.PropTypes.array,
  };

  static defaultProps = {
    defaultBlockRenderMap: true,
    defaultKeyBindings: true,
    customStyleMap: {},
    plugins: [],
    decorators: [],
  };

  constructor(props) {
    super(props);

    const plugins = [this.props, ...this.resolvePlugins()];
    plugins.forEach((plugin) => {
      if (typeof plugin.initialize !== 'function') return;
      plugin.initialize(this.getPluginMethods());
    });

    // attach proxy methods like `focus` or `blur`
    proxies.forEach((method) => {
      this[method] = (...args) => (
        this.editor[method](...args)
      );
    });

    this.state = {}; // TODO for Nik: ask ben why this is relevent
  }

  componentWillMount() {
    const decorators = this.resolveDecorators();
    const compositeDecorator = createCompositeDecorator(
      decorators.filter((decorator) => !this.decoratorIsCustom(decorator)),
      this.getEditorState,
      this.onChange);

    const customDecorators = decorators
      .filter((decorator) => this.decoratorIsCustom(decorator));

    const multiDecorator = new MultiDecorator(
      [
        ...customDecorators,
        compositeDecorator,
      ]
    );

    const editorState = EditorState.set(this.props.editorState, { decorator: multiDecorator });
    this.onChange(moveSelectionToEnd(editorState));
  }

  componentWillUnmount() {
    this.resolvePlugins().forEach((plugin) => {
      if (plugin.willUnmount) {
        plugin.willUnmount({
          getEditorState: this.getEditorState,
          setEditorState: this.onChange,
        });
      }
    });
  }

  // Cycle through the plugins, changing the editor state with what the plugins
  // changed (or didn't)
  onChange = (editorState) => {
    let newEditorState = editorState;
    this.resolvePlugins().forEach((plugin) => {
      if (plugin.onChange) {
        newEditorState = plugin.onChange(newEditorState, this.getPluginMethods());
      }
    });

    if (this.props.onChange) {
      this.props.onChange(newEditorState, this.getPluginMethods());
    }
  };

  getPlugins = () => this.props.plugins.slice(0);
  getProps = () => ({ ...this.props });

  // TODO further down in render we use readOnly={this.props.readOnly || this.state.readOnly}. Ask Ben why readOnly is here just from the props? Why would plugins use this instead of just taking it from getProps?
  getReadOnly = () => this.props.readOnly;
  setReadOnly = (readOnly) => {
    if (readOnly !== this.state.readOnly) this.setState({ readOnly });
  };

  getEditorRef = () => this.editor;

  getEditorState = () => this.props.editorState;
  getPluginMethods = () => ({
    getPlugins: this.getPlugins,
    getProps: this.getProps,
    setEditorState: this.onChange,
    getEditorState: this.getEditorState,
    getReadOnly: this.getReadOnly,
    setReadOnly: this.setReadOnly,
    getEditorRef: this.getEditorRef,
  });

  createEventHooks = (methodName, plugins) => (...args) => {
    const newArgs = [].slice.apply(args);
    newArgs.push(this.getPluginMethods());
    for (let i = 0; i < plugins.length; i++) {
      const plugin = plugins[i];
      if (typeof plugin[methodName] !== 'function') continue;
      const result = plugin[methodName](...newArgs);
      if (result === true) return true;
    }

    return false;
  };

  createHandleHooks = (methodName, plugins) => (...args) => {
    const newArgs = [].slice.apply(args);
    newArgs.push(this.getPluginMethods());
    for (let i = 0; i < plugins.length; i++) {
      const plugin = plugins[i];
      if (typeof plugin[methodName] !== 'function') continue;
      const result = plugin[methodName](...newArgs);
      if (result === 'handled') return 'handled';
    }

    return 'not-handled';
  };

  createFnHooks = (methodName, plugins) => (...args) => {
    const newArgs = [].slice.apply(args);

    newArgs.push(this.getPluginMethods());

    if (methodName === 'blockRendererFn') {
      let block = { props: {} };
      plugins.forEach((plugin) => {
        if (typeof plugin[methodName] !== 'function') return;
        const result = plugin[methodName](...newArgs);
        if (result !== undefined && result !== null) {
          const { props: pluginProps, ...pluginRest } = result; // eslint-disable-line no-use-before-define
          const { props, ...rest } = block; // eslint-disable-line no-use-before-define
          block = { ...rest, ...pluginRest, props: { ...props, ...pluginProps } };
        }
      });

      return block.component ? block : false;
    } else if (methodName === 'blockStyleFn') {
      let styles;
      plugins.forEach((plugin) => {
        if (typeof plugin[methodName] !== 'function') return;
        const result = plugin[methodName](...newArgs);
        if (result !== undefined && result !== null) {
          styles = (styles ? (`${styles} `) : '') + result;
        }
      });

      return styles || false;
    }

    for (let i = 0; i < plugins.length; i++) {
      const plugin = plugins[i];
      if (typeof plugin[methodName] !== 'function') continue;
      const result = plugin[methodName](...newArgs);
      if (result !== undefined) {
        return result;
      }
    }

    return false;
  };

  createPluginHooks = () => {
    const pluginHooks = {};
    const eventHookKeys = [];
    const handleHookKeys = [];
    const fnHookKeys = [];
    const plugins = [this.props, ...this.resolvePlugins()];

    plugins.forEach((plugin) => {
      Object.keys(plugin).forEach((attrName) => {
        if (attrName === 'onChange') return;

        // if `attrName` has been added as a hook key already, ignore this one
        if (eventHookKeys.indexOf(attrName) !== -1 || fnHookKeys.indexOf(attrName) !== -1) return;

        const isEventHookKey = attrName.indexOf('on') === 0;
        if (isEventHookKey) {
          eventHookKeys.push(attrName);
          return;
        }

        const isHandleHookKey = attrName.indexOf('handle') === 0;
        if (isHandleHookKey) {
          handleHookKeys.push(attrName);
          return;
        }

        // checks if `attrName` ends with 'Fn'
        const isFnHookKey = (attrName.length - 2 === attrName.indexOf('Fn'));
        if (isFnHookKey) {
          fnHookKeys.push(attrName);
        }
      });
    });

    eventHookKeys.forEach((attrName) => {
      pluginHooks[attrName] = this.createEventHooks(attrName, plugins);
    });

    handleHookKeys.forEach((attrName) => {
      pluginHooks[attrName] = this.createHandleHooks(attrName, plugins);
    });

    fnHookKeys.forEach((attrName) => {
      pluginHooks[attrName] = this.createFnHooks(attrName, plugins);
    });

    return pluginHooks;
  };

  resolvePlugins = () => {
    const plugins = this.props.plugins.slice(0);
    if (this.props.defaultKeyBindings) {
      plugins.push(defaultKeyBindingPlugin);
    }

    return plugins;
  };

  resolveDecorators = () => {
    const { decorators, plugins } = this.props;
    return List([{ decorators }, ...plugins])
      .filter((plugin) => plugin.decorators !== undefined)
      .flatMap((plugin) => plugin.decorators);
  };

  // Return true if decorator implements the DraftDecoratorType interface
  // @see https://github.com/facebook/draft-js/blob/master/src/model/decorators/DraftDecoratorType.js
  decoratorIsCustom = (decorator) => typeof decorator.getDecorations === 'function' &&
    typeof decorator.getComponentForKey === 'function' &&
    typeof decorator.getPropsForKey === 'function';

  resolveCustomStyleMap = () => (
    this.props.plugins
      .filter((plug) => plug.customStyleMap !== undefined)
      .map((plug) => plug.customStyleMap)
      .concat([this.props.customStyleMap])
      .reduce((styles, style) => (
        {
          ...styles,
          ...style,
        }
      ), {})
  );

  resolveblockRenderMap = () => {
    let blockRenderMap = this.props.plugins
      .filter((plug) => plug.blockRenderMap !== undefined)
      .reduce((maps, plug) => maps.merge(plug.blockRenderMap), Map({}));
    if (this.props.defaultBlockRenderMap) {
      blockRenderMap = DefaultDraftBlockRenderMap.merge(blockRenderMap);
    }
    if (this.props.blockRenderMap) {
      blockRenderMap = blockRenderMap.merge(this.props.blockRenderMap);
    }
    return blockRenderMap;
  }

  resolveAccessibilityProps = () => {
    let accessibilityProps = {};
    const plugins = [this.props, ...this.resolvePlugins()];
    plugins.forEach((plugin) => {
      if (typeof plugin.getAccessibilityProps !== 'function') return;
      const props = plugin.getAccessibilityProps();
      const popupProps = {};

      if (accessibilityProps.ariaHasPopup === undefined) {
        popupProps.ariaHasPopup = props.ariaHasPopup;
      } else if (props.ariaHasPopup === 'true') {
        popupProps.ariaHasPopup = 'true';
      }

      if (accessibilityProps.ariaExpanded === undefined) {
        popupProps.ariaExpanded = props.ariaExpanded;
      } else if (props.ariaExpanded === 'true') {
        popupProps.ariaExpanded = 'true';
      }

      accessibilityProps = {
        ...accessibilityProps,
        ...props,
        ...popupProps,
      };
    });

    return accessibilityProps;
  };

  render() {
    const pluginHooks = this.createPluginHooks();
    const customStyleMap = this.resolveCustomStyleMap();
    const accessibilityProps = this.resolveAccessibilityProps();
    const blockRenderMap = this.resolveblockRenderMap();
    return (
      <Editor
        {...this.props}
        {...accessibilityProps}
        {...pluginHooks}
        readOnly={this.props.readOnly || this.state.readOnly}
        customStyleMap={customStyleMap}
        blockRenderMap={blockRenderMap}
        onChange={this.onChange}
        editorState={this.props.editorState}
        ref={(element) => { this.editor = element; }}
      />
    );
  }
}

export default PluginEditor;
<commit_msg>Replaced `for` loops with counter variables with `Array.prototype.some` loops.<commit_after>/* eslint-disable no-continue,no-restricted-syntax,no-plusplus */
import React, { Component } from 'react';
import {
  Editor,
  EditorState,
  DefaultDraftBlockRenderMap,
} from 'draft-js';
import { List, Map } from 'immutable';
import MultiDecorator from './MultiDecorator';
import createCompositeDecorator from './createCompositeDecorator';
import moveSelectionToEnd from './moveSelectionToEnd';
import proxies from './proxies';
import * as defaultKeyBindingPlugin from './defaultKeyBindingPlugin';

/**
 * The main editor component
 */
class PluginEditor extends Component {

  static propTypes = {
    editorState: React.PropTypes.object.isRequired,
    onChange: React.PropTypes.func.isRequired,
    plugins: React.PropTypes.array,
    defaultKeyBindings: React.PropTypes.bool,
    defaultBlockRenderMap: React.PropTypes.bool,
    customStyleMap: React.PropTypes.object,
    decorators: React.PropTypes.array,
  };

  static defaultProps = {
    defaultBlockRenderMap: true,
    defaultKeyBindings: true,
    customStyleMap: {},
    plugins: [],
    decorators: [],
  };

  constructor(props) {
    super(props);

    const plugins = [this.props, ...this.resolvePlugins()];
    plugins.forEach((plugin) => {
      if (typeof plugin.initialize !== 'function') return;
      plugin.initialize(this.getPluginMethods());
    });

    // attach proxy methods like `focus` or `blur`
    proxies.forEach((method) => {
      this[method] = (...args) => (
        this.editor[method](...args)
      );
    });

    this.state = {}; // TODO for Nik: ask ben why this is relevent
  }

  componentWillMount() {
    const decorators = this.resolveDecorators();
    const compositeDecorator = createCompositeDecorator(
      decorators.filter((decorator) => !this.decoratorIsCustom(decorator)),
      this.getEditorState,
      this.onChange);

    const customDecorators = decorators
      .filter((decorator) => this.decoratorIsCustom(decorator));

    const multiDecorator = new MultiDecorator(
      [
        ...customDecorators,
        compositeDecorator,
      ]
    );

    const editorState = EditorState.set(this.props.editorState, { decorator: multiDecorator });
    this.onChange(moveSelectionToEnd(editorState));
  }

  componentWillUnmount() {
    this.resolvePlugins().forEach((plugin) => {
      if (plugin.willUnmount) {
        plugin.willUnmount({
          getEditorState: this.getEditorState,
          setEditorState: this.onChange,
        });
      }
    });
  }

  // Cycle through the plugins, changing the editor state with what the plugins
  // changed (or didn't)
  onChange = (editorState) => {
    let newEditorState = editorState;
    this.resolvePlugins().forEach((plugin) => {
      if (plugin.onChange) {
        newEditorState = plugin.onChange(newEditorState, this.getPluginMethods());
      }
    });

    if (this.props.onChange) {
      this.props.onChange(newEditorState, this.getPluginMethods());
    }
  };

  getPlugins = () => this.props.plugins.slice(0);
  getProps = () => ({ ...this.props });

  // TODO further down in render we use readOnly={this.props.readOnly || this.state.readOnly}. Ask Ben why readOnly is here just from the props? Why would plugins use this instead of just taking it from getProps?
  getReadOnly = () => this.props.readOnly;
  setReadOnly = (readOnly) => {
    if (readOnly !== this.state.readOnly) this.setState({ readOnly });
  };

  getEditorRef = () => this.editor;

  getEditorState = () => this.props.editorState;
  getPluginMethods = () => ({
    getPlugins: this.getPlugins,
    getProps: this.getProps,
    setEditorState: this.onChange,
    getEditorState: this.getEditorState,
    getReadOnly: this.getReadOnly,
    setReadOnly: this.setReadOnly,
    getEditorRef: this.getEditorRef,
  });

  createEventHooks = (methodName, plugins) => (...args) => {
    const newArgs = [].slice.apply(args);
    newArgs.push(this.getPluginMethods());

    return plugins.some((plugin) =>
      typeof plugin[methodName] === 'function'
        && plugin[methodName](...newArgs) === true
    );
  };

  createHandleHooks = (methodName, plugins) => (...args) => {
    const newArgs = [].slice.apply(args);
    newArgs.push(this.getPluginMethods());

    return plugins.some((plugin) =>
      typeof plugin[methodName] === 'function'
        && plugin[methodName](...newArgs) === 'handled'
    ) ? 'handled' : 'not-handled';
  };

  createFnHooks = (methodName, plugins) => (...args) => {
    const newArgs = [].slice.apply(args);

    newArgs.push(this.getPluginMethods());

    if (methodName === 'blockRendererFn') {
      let block = { props: {} };
      plugins.forEach((plugin) => {
        if (typeof plugin[methodName] !== 'function') return;
        const result = plugin[methodName](...newArgs);
        if (result !== undefined && result !== null) {
          const { props: pluginProps, ...pluginRest } = result; // eslint-disable-line no-use-before-define
          const { props, ...rest } = block; // eslint-disable-line no-use-before-define
          block = { ...rest, ...pluginRest, props: { ...props, ...pluginProps } };
        }
      });

      return block.component ? block : false;
    } else if (methodName === 'blockStyleFn') {
      let styles;
      plugins.forEach((plugin) => {
        if (typeof plugin[methodName] !== 'function') return;
        const result = plugin[methodName](...newArgs);
        if (result !== undefined && result !== null) {
          styles = (styles ? (`${styles} `) : '') + result;
        }
      });

      return styles || false;
    }

    let result;
    const wasHandled = plugins.some((plugin) => {
      if (typeof plugin[methodName] !== 'function') return false;
      result = plugin[methodName](...newArgs);
      return result !== undefined;
    });
    return wasHandled ? result : false;
  };

  createPluginHooks = () => {
    const pluginHooks = {};
    const eventHookKeys = [];
    const handleHookKeys = [];
    const fnHookKeys = [];
    const plugins = [this.props, ...this.resolvePlugins()];

    plugins.forEach((plugin) => {
      Object.keys(plugin).forEach((attrName) => {
        if (attrName === 'onChange') return;

        // if `attrName` has been added as a hook key already, ignore this one
        if (eventHookKeys.indexOf(attrName) !== -1 || fnHookKeys.indexOf(attrName) !== -1) return;

        const isEventHookKey = attrName.indexOf('on') === 0;
        if (isEventHookKey) {
          eventHookKeys.push(attrName);
          return;
        }

        const isHandleHookKey = attrName.indexOf('handle') === 0;
        if (isHandleHookKey) {
          handleHookKeys.push(attrName);
          return;
        }

        // checks if `attrName` ends with 'Fn'
        const isFnHookKey = (attrName.length - 2 === attrName.indexOf('Fn'));
        if (isFnHookKey) {
          fnHookKeys.push(attrName);
        }
      });
    });

    eventHookKeys.forEach((attrName) => {
      pluginHooks[attrName] = this.createEventHooks(attrName, plugins);
    });

    handleHookKeys.forEach((attrName) => {
      pluginHooks[attrName] = this.createHandleHooks(attrName, plugins);
    });

    fnHookKeys.forEach((attrName) => {
      pluginHooks[attrName] = this.createFnHooks(attrName, plugins);
    });

    return pluginHooks;
  };

  resolvePlugins = () => {
    const plugins = this.props.plugins.slice(0);
    if (this.props.defaultKeyBindings) {
      plugins.push(defaultKeyBindingPlugin);
    }

    return plugins;
  };

  resolveDecorators = () => {
    const { decorators, plugins } = this.props;
    return List([{ decorators }, ...plugins])
      .filter((plugin) => plugin.decorators !== undefined)
      .flatMap((plugin) => plugin.decorators);
  };

  // Return true if decorator implements the DraftDecoratorType interface
  // @see https://github.com/facebook/draft-js/blob/master/src/model/decorators/DraftDecoratorType.js
  decoratorIsCustom = (decorator) => typeof decorator.getDecorations === 'function' &&
    typeof decorator.getComponentForKey === 'function' &&
    typeof decorator.getPropsForKey === 'function';

  resolveCustomStyleMap = () => (
    this.props.plugins
      .filter((plug) => plug.customStyleMap !== undefined)
      .map((plug) => plug.customStyleMap)
      .concat([this.props.customStyleMap])
      .reduce((styles, style) => (
        {
          ...styles,
          ...style,
        }
      ), {})
  );

  resolveblockRenderMap = () => {
    let blockRenderMap = this.props.plugins
      .filter((plug) => plug.blockRenderMap !== undefined)
      .reduce((maps, plug) => maps.merge(plug.blockRenderMap), Map({}));
    if (this.props.defaultBlockRenderMap) {
      blockRenderMap = DefaultDraftBlockRenderMap.merge(blockRenderMap);
    }
    if (this.props.blockRenderMap) {
      blockRenderMap = blockRenderMap.merge(this.props.blockRenderMap);
    }
    return blockRenderMap;
  }

  resolveAccessibilityProps = () => {
    let accessibilityProps = {};
    const plugins = [this.props, ...this.resolvePlugins()];
    plugins.forEach((plugin) => {
      if (typeof plugin.getAccessibilityProps !== 'function') return;
      const props = plugin.getAccessibilityProps();
      const popupProps = {};

      if (accessibilityProps.ariaHasPopup === undefined) {
        popupProps.ariaHasPopup = props.ariaHasPopup;
      } else if (props.ariaHasPopup === 'true') {
        popupProps.ariaHasPopup = 'true';
      }

      if (accessibilityProps.ariaExpanded === undefined) {
        popupProps.ariaExpanded = props.ariaExpanded;
      } else if (props.ariaExpanded === 'true') {
        popupProps.ariaExpanded = 'true';
      }

      accessibilityProps = {
        ...accessibilityProps,
        ...props,
        ...popupProps,
      };
    });

    return accessibilityProps;
  };

  render() {
    const pluginHooks = this.createPluginHooks();
    const customStyleMap = this.resolveCustomStyleMap();
    const accessibilityProps = this.resolveAccessibilityProps();
    const blockRenderMap = this.resolveblockRenderMap();
    return (
      <Editor
        {...this.props}
        {...accessibilityProps}
        {...pluginHooks}
        readOnly={this.props.readOnly || this.state.readOnly}
        customStyleMap={customStyleMap}
        blockRenderMap={blockRenderMap}
        onChange={this.onChange}
        editorState={this.props.editorState}
        ref={(element) => { this.editor = element; }}
      />
    );
  }
}

export default PluginEditor;
<|endoftext|>


<commit_before>
function FileLoader() {
	var usingChromeApp = chrome ? (chrome.fileSystem ? true : false) : false;
	console.log(usingChromeApp);

	var projectDirectory; // stored as an entry if using chrome apps

	/**
	 * A list of all of the files that are writeable and required for the project
	 */
	var projectFiles = [];
	var dataName = "developmentGraphInfo";

	function loadProjectFilesApp(fileDirectory) {
		console.log("")
	}

	this.loadMainDirectory = function() {
		if (usingChromeApp) {
			console.log("loading entry");
			console.log(chrome.fileSystem);
			chrome.fileSystem.chooseEntry( { type: 'openDirectory' }, function(entry) {
				console.log(entry);
				var dirReader = entry.createReader();
				dirReader.readEntries(function(fileList) {
					results.forEach(function(file) {
						if (file.name == dataName && file.isDirectory) {
							loadProjectFilesApp(file);
						}
					});
				});
				console.log(dirReader);
				projectDirectory = entry;
			});
		}
	}

	/**
	 * Gets a directory navigator.
	 *
	 * The directory navigator has X functions:
	 *

	 *
nextFile:
	 *

	 * 		returns the next file in the current directory, returns null if all files have been navigated through
	 *

	 *
nextDirectory

	 *
nextItem

	 */
	this.getDirectoryNavigator = function() {
		if (usingChromeApp) {
			/**
			 * Creates a navigator for the chrome version
			 */
			var chromeNavigator = new function chromeNavigator(projectDirectory) {
				var getNavigator
			};
		}
	}
}

var f = new FileLoader();
console.log(f);
f.loadMainDirectory();<commit_msg>Started creating a general file loader.<commit_after>
function FileLoader() {
	var usingChromeApp = chrome ? (chrome.fileSystem ? true : false) : false;
	console.log(usingChromeApp);

	var projectDirectory; // stored as an entry if using chrome apps

	/**
	 * A list of all of the files that are writeable and required for the project
	 */
	var projectFiles = [];
	var dataName = "developmentGraphInfo";

	function loadProjectFilesApp(fileDirectory) {
		console.log("")
	}

	this.loadMainDirectory = function() {
		if (usingChromeApp) {
			console.log("loading entry");
			console.log(chrome.fileSystem);
			chrome.fileSystem.chooseEntry( { type: 'openDirectory' }, function(entry) {
				console.log(entry);
				var dirReader = entry.createReader();
				dirReader.readEntries(function(fileList) {
					results.forEach(function(file) {
						if (file.name == dataName && file.isDirectory) {
							loadProjectFilesApp(file);
						}
					});
				});
				console.log(dirReader);
				projectDirectory = entry;
			});
		}
	}

	/**
	 * Gets a directory navigator and creates it at the project directory.
	 *
	 * @return DirectoryNavigator
	 * @ClassStart
	 * @ClassName DirectoryNavigator
	 *
	 * Allows one to navigate directories without worrying about the underlying file system.
	 *

	 *
When grabbing the {nextItem/nextDirectory/nextFile} it works like an iterator so calling nextFile may skip a directory and calling
	 * nextDirectory will not read that directory.

	 *
The files in a directory are ordered in alphabetical order.

	 *
	 * @param topDirectory The directory that the navigator starts at.  The navigator can not navigate outside this top directory.
	 *
	 * @Method peek
	 * 		@return the current item, it may be a file or a directory
	 *
	 * @Method nextFile
	 * 		@return The next file in the current directory.
	 * 		@throw IndexOutOfBoundsException an exception if there are no Files left.
	 *
	 * @Method nextDirectory
	 * 		@return the next directory in the current directory, returns null if all directories have been navigated through.
	 * 		@throw IndexOutOfBoundsException an exception if there are no Directories left.
	 *
	 * @Method nextItem
	 * 		@return the next file or directory in the current directory, returns null if all files and directories have been navigated through.
	 * 		@throw IndexOutOfBoundsException an exception if there are no items left.
	 *
	 * @Method navigateDown
	 * 		If the current item is a directory then it becomes the new current directory. If it is not a directory and exception is thrown.
	 *		@throws NotDirectoryException
	 *
	 * @Method navigateUp
	 * 		If the current directory is not the topDirectory then the navigator will go to the current directory's parent.
	 * 		@throws AtTopDirectoryException
	 *
	 * @Method isDirectory
	 * 		@return true if the current file is a directory.
	 *
	 * @Method reset
	 *		resets the state of the navigator to be equal to when it was first constructed.
	 *
	 * @Method hasNextFile
	 * 		@return true if there are more files left.
	 *
	 * @Method hasNextDirectory
	 * 		@return true if there are more directories left.
	 *
	 * @Method hasNext
	 * 		@return true if there are more items left.
	 *
	 * @Method grabByName
	 * 		Grabs a file in the current directory by the name.
	 * 		@param itemName {string} The name of the item to grab (uses greedy matching)
	 * @ClassEnd
	 *
	 * @throws NotDirectoryException this is thrown if the Project Directory is not actually a directory
	 */
	this.getDirectoryNavigator = function() {
		if (usingChromeApp) {
			/**
			 * Creates a navigator for the chrome version
			 */
			var chromeNavigator = function chromeNavigator(topDirectory) {
				if (!topDirectory.isDirectory) {
					throw {
						name: "NotDirectoryException",
						message: "The DirectoryNavigator must recieve a directory and not a file"
					};
				}
				var currentItem = undefined;
				var currentIndex = 0;
				var currentDirectory = topDirectory;
				var directoryStack = [];
				var currentDirectoryList = [];
				topDirectory.createReader().readEntries(function(fileList) {
					currentDirectoryList = fileList;
				};

				this.isDirectory = function() {
					return currentItem.isDirectory;
				};

				this.nextItem = function() {
					if (currentIndex >= currentDirectoryList.length) {
						throw "IndexOutOfBoundsException";
					}
					currentItem = currentDirectoryList[currentIndex];
					currentIndex++;
					return currentItem;
				};

				this.nextFile = function() {
					this.nextItem();
					while (this.isDirectory()) {
						this.nextItem();
					}
					return currentItem;
				};

				this.nextDirectory = function() {
					this.nextItem();
					while (!this.isDirectory()) {
						this.nextItem();
					}
					return currentItem;
				};

				this.navigateDown = function() {
					if (!this.isDirectory) {
						throw "NotDirectoryException";
					}
					directoryStack.push(this.currentItem);
					currentDirectory = currentItem;
					currentItem = undefined;
					currentIndex = 0;
					currentDirectory.createReader().readEntries(function(fileList) {
						currentDirectoryList = fileList;
					};
				};
			};
			return new chromeNavigator(projectDirectory);
		}
	};
}

var f = new FileLoader();
console.log(f);
f.loadMainDirectory();<|endoftext|>


<commit_before>$(function () {

    jQuery('.detalleGrafico').css("visibility", "hidden");

    jQuery.noConflict();

    var margin = { top: 40, right: 0, bottom: 0, left: 30 };

    var heatMap = obtenerHeatMapViewModel();

    var cantIndicadoresPorArea = contarIndicadoresPorArea(heatMap)

    var contentWidth = parseInt(d3.select('#chart').style('width'));

    var gridSize = 40;
    var height = (gridSize - 8) * heatMap.FilasHeatMapViewModel.length + gridSize + 1;

    var svg = d3.select("#chart").append("svg")
        .attr("width", 940)
        .attr("height", height)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    var tip = d3.tip()
        .attr('class', 'd3-tip')
        .style("visibility", "visible")
        .offset([0, 0])
        .html(function (d) {
            return "Valor:  " + d.Medicion;
        });

    tip(svg.append("g"));

    svg.append('text')
      .attr("x", 17)
      .attr("y", 0)
      .style("text-anchor", "middle")
      .attr("transform", "translate(" + gridSize / 2 + ", -6)")
      .attr("class", "mono")
      .text('Área');

    svg.append('text')
      .attr("x", 188)
      .attr("y", 0)
      .style("text-anchor", "middle")
      .attr("transform", "translate(" + gridSize / 2 + ", -6)")
      .attr("class", "mono")
      .text('Indicador');

    // Nombreas áreas
    var offsetTextoArea = 0;
    var offsetTextoAreaAnterior = 0;

    svg.selectAll(".areas")
       .data(cantIndicadoresPorArea)
       .enter()
       .append("text")
       .attr("transform", "translate(-6," + gridSize / 1.5 + ")")
       .text(function (d) {
           var nombreArea = d[0];
           return nombreArea;
        })
       .attr("x", 110)
       .attr("y", function (d, i) {
           if(i > 0){
               offsetTextoArea += offsetTextoAreaAnterior;
           }
           offsetTextoAreaAnterior = d[1];
           return (offsetTextoArea * (gridSize - 8)) - 12;
       })
       .style("text-anchor", "end")
       .attr("class", "mono")
       .call(wrap, 140, -24);

    svg.append("line")
       .attr("x1", -30)
       .attr("y1", 0)
       .attr("x2", 300)
       .attr("y2", 0)
       .attr("stroke-width", 0.4)
       .attr("stroke", "gray");

    var offsetLineaY1 = 0;
    var offsetLineaY2 = 0;

    svg.selectAll(".lineas")
       .data(cantIndicadoresPorArea)
       .enter()
       .append("line")
       .attr("x1", -30)
       .attr("y1", function (d, i) { offsetLineaY1 += d[1]; return (offsetLineaY1) * (gridSize - 8); })
       .attr("x2", 300)
       .attr("y2", function (d, i) { offsetLineaY2 += d[1]; return (offsetLineaY2) * (gridSize - 8); })
       .attr("stroke-width", 0.4)
       .attr("stroke", "gray");

    var indicadorElegido;

    // Etiquetas tipo nombre indicadores
    var dim1Labels = svg.selectAll(".dim1Label")
      .data(heatMap.FilasHeatMapViewModel)
      .enter()
        .append("a").attr("xlink:href", function (d) { return "#" }).attr("xlink:title", function (d) { return d.NombreIndicador; })
        .append("text")
        .text(function (d) {
            if (d.NombreIndicador.length >= 50) {
                d.NombreIndicador + '...';
            }
            if (d.NombreIndicador.length >= 49) {
                return d.NombreIndicador.substring(0, 49) + '...';
            }
            return d.NombreIndicador;
        })
        .attr("x", 150)
        .attr("y", function (d, i) {
            var offsetYEtiqueta = 8;
            if (d.NombreIndicador.length >= 19) {
                offsetYEtiqueta = 12;
            }
            return (i * (gridSize - 8)) - offsetYEtiqueta;
        })
        .attr("transform", "translate(-6," + gridSize / 1.5 + ")")
        .attr("class", "mono1")
        .on('click',
            function (d) {

                if (d3.select(this).classed("mono1")) {
                    jQuery('.detalleGrafico').show();
                    jQuery('.detalleGrafico').css("visibility","visible");
                }
                else {
                    jQuery('.detalleGrafico').toggle();
                }

                if (jQuery('.detalleGrafico').is(":visible")) {
                    var gauge = obtenerGaugeViewModel(d.Grupo);
                    onDocumentReadyGauge(gauge);

                    var line = obtenerLineViewModel(d.Grupo);
                    showLine(line, gauge.NombreIndicador);
                }

                if (indicadorElegido !== undefined) {
                    indicadorElegido.classed("mono1", true);
                    indicadorElegido.classed("text-mono1-hover", false);
                }

                indicadorElegido = d3.select(this);

                d3.select(this).attr("class", "mono1 text-mono1-hover")
                d3.select(this).classed("mono1", false);
                d3.select(this).classed("text-mono1-hover", true);
            })
            .call(wrap, 190, 127);

    // Etiquetas tipo meses
    var dim2Labels = svg.selectAll(".dim2Label")
        .data(heatMap.Meses)
        .enter().append("text")
            .text(function (d) { return d.substring(0, 3) + '.' })
            .attr("x", function (d, i) { return (i + 1) * 50 + 252; })
            .attr("y", 0)
            .style("text-anchor", "middle")
            .attr("transform", "translate(" + gridSize / 2 + ", -6)")
            .attr("class", "mono");

    var heatMapGrafico = svg.selectAll(".dim2")
        .data(heatMap.Celdas)
        .enter().append("rect")
            .attr("x", function (d) { return ((d.Mes - 1) * (gridSize + 10)) + 300; })
            .attr("y", function (d) { return (d.IndiceIndicador - 1) * (gridSize - 8); })
            .attr("rx", 3) // redondeado de la celda
            .attr("ry", 3) // redondeado de la celda
            .attr("width", gridSize +  8) // ancho de la celda
            .attr("height", gridSize - 10) // alto de la celda
            .style("fill", "gray")
            .attr("class", "square")
            .on('mouseover', function (d, i) {
                if (d.MedicionCargada)
                    tip.show(d, i);
            })
            .on('mouseout', tip.hide)
            .on('click', function (d) {
                abrirModalCargaMedicion(d.IdIndicador, d.Mes, d.IdMedicion, d.NombreMes, d.GrupoIndicador, d.TieneAccesoLecturaEscritura, d.EsAutomatico);
            });

    heatMapGrafico.transition().style("fill", function (d) { return d.ColorMeta; });
    heatMapGrafico.append("title").text(function (d) { return d.Medicion; });
});

function contarIndicadoresPorArea(heatMap) {

    var filas = heatMap.FilasHeatMapViewModel;
    var dictionary = {};

    jQuery.each(filas, function (key, value) {
        if (dictionary[value.NombreArea] != undefined) {
            dictionary[value.NombreArea] += 1;
        }
        else {
            dictionary[value.NombreArea] = 1;
        }
    });

    var arr = [];
    jQuery.each(dictionary, function (key, value) {
        var arr1 = [];
        arr1.push(key);
        arr1.push(value);
        arr.push(arr1);
    });

    return arr;
}

function wrap(text, width, posicionX) {

    text.each(function () {
        var text = d3.select(this),
            words = text.text().split(/\s+/).reverse(),
            word,
            line = [],
            lineNumber = 0,
            lineHeight = 1.1,
            x = text.attr("x"),
            y = text.attr("y"),
            dy = 0,
            tspan = text.text(null)
                        .append("tspan")
                        .attr("x", posicionX)
                        .style("text-anchor", "start")
                        .attr("y", y)
                        .attr("dy", dy + "em");

        while (word = words.pop()) {
            line.push(word);
            tspan.text(line.join(" "));

            if (tspan.node().getComputedTextLength() > width) {
                line.pop();
                tspan.text(line.join(" "));
                line = [word];
                tspan = text.append("tspan")
                            .attr("x", posicionX)
                            .attr("y", y)
                            .style("text-anchor", "start")
                            .attr("dy", ++lineNumber * lineHeight + dy + "em")
                            .text(word);
            }

        }
    });
}

function abrirGrafico(indicador) {
    jQuery('.detalleGrafico').show();
}<commit_msg>Se adapta el nombre de las areas de acuerdo a la cantidad de indicadores<commit_after>
var dictionaryIndicadoresPorArea = {};

$(function () {

    jQuery('.detalleGrafico').css("visibility", "hidden");

    jQuery.noConflict();

    var margin = { top: 40, right: 0, bottom: 0, left: 30 };

    var heatMap = obtenerHeatMapViewModel();

    var cantIndicadoresPorArea = contarIndicadoresPorArea(heatMap)

    var contentWidth = parseInt(d3.select('#chart').style('width'));

    var gridSize = 40;
    var height = (gridSize - 8) * heatMap.FilasHeatMapViewModel.length + gridSize + 1;

    var svg = d3.select("#chart").append("svg")
        .attr("width", 940)
        .attr("height", height)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    var tip = d3.tip()
        .attr('class', 'd3-tip')
        .style("visibility", "visible")
        .offset([0, 0])
        .html(function (d) {
            return "Valor:  " + d.Medicion;
        });

    tip(svg.append("g"));

    svg.append('text')
      .attr("x", 17)
      .attr("y", 0)
      .style("text-anchor", "middle")
      .attr("transform", "translate(" + gridSize / 2 + ", -6)")
      .attr("class", "mono")
      .text('Área');

    svg.append('text')
      .attr("x", 188)
      .attr("y", 0)
      .style("text-anchor", "middle")
      .attr("transform", "translate(" + gridSize / 2 + ", -6)")
      .attr("class", "mono")
      .text('Indicador');

    // Nombreas áreas
    var offsetTextoArea = 0;
    var offsetTextoAreaAnterior = 0;

    var etiquetasAreas = svg.selectAll(".areas")
       .data(cantIndicadoresPorArea)
       .enter()
       .append("text")
       .attr("transform", function (d, i) {
           if (d[1] <= 2)
               return "translate(-6," + gridSize / 1.5 + ")";
           else
               return "rotate(-90)";
       })
       .text(function (d) {
           var nombreArea = d[0];
           return nombreArea;
       })
       .attr("x", 110)
       .attr("y", function (d, i) {
           if (i > 0) {
               offsetTextoArea += offsetTextoAreaAnterior;
           }
           offsetTextoAreaAnterior = d[1];

           if (d[1] <= 2) {
               return (offsetTextoArea * (gridSize - 8)) - 12;
           }
           else {
               //alert(this.getComputedTextLength());
               return 10;
           }
       })
       .style("text-anchor", "end")
       .attr("class", "mono")
       .call(wrap, cantIndicadoresPorArea);

    svg.append("line")
       .attr("x1", -30)
       .attr("y1", 0)
       .attr("x2", 300)
       .attr("y2", 0)
       .attr("stroke-width", 0.4)
       .attr("stroke", "gray");

    var offsetLineaY1 = 0;
    var offsetLineaY2 = 0;

    svg.selectAll(".lineas")
       .data(cantIndicadoresPorArea)
       .enter()
       .append("line")
       .attr("x1", -30)
       .attr("y1", function (d, i) { offsetLineaY1 += d[1]; return (offsetLineaY1) * (gridSize - 8); })
       .attr("x2", 300)
       .attr("y2", function (d, i) { offsetLineaY2 += d[1]; return (offsetLineaY2) * (gridSize - 8); })
       .attr("stroke-width", 0.4)
       .attr("stroke", "gray");

    var indicadorElegido;

    // Etiquetas tipo nombre indicadores
    var dim1Labels = svg.selectAll(".dim1Label")
      .data(heatMap.FilasHeatMapViewModel)
      .enter()
        .append("a").attr("xlink:href", function (d) { return "#" }).attr("xlink:title", function (d) { return d.NombreIndicador; })
        .append("text")
        .text(function (d) {
            if (d.NombreIndicador.length >= 50) {
                d.NombreIndicador + '...';
            }
            if (d.NombreIndicador.length >= 49) {
                return d.NombreIndicador.substring(0, 49) + '...';
            }
            return d.NombreIndicador;
        })
        .attr("x", 150)
        .attr("y", function (d, i) {
            var offsetYEtiqueta = 8;
            if (d.NombreIndicador.length >= 19) {
                offsetYEtiqueta = 12;
            }
            return (i * (gridSize - 8)) - offsetYEtiqueta;
        })
        .attr("transform", "translate(-6," + gridSize / 1.5 + ")")
        .attr("class", "mono1")
        .on('click',
            function (d) {

                if (d3.select(this).classed("mono1")) {
                    jQuery('.detalleGrafico').show();
                    jQuery('.detalleGrafico').css("visibility", "visible");
                }
                else {
                    jQuery('.detalleGrafico').toggle();
                }

                if (jQuery('.detalleGrafico').is(":visible")) {
                    var gauge = obtenerGaugeViewModel(d.Grupo);
                    onDocumentReadyGauge(gauge);

                    var line = obtenerLineViewModel(d.Grupo);
                    showLine(line, gauge.NombreIndicador);
                }

                if (indicadorElegido !== undefined) {
                    indicadorElegido.classed("mono1", true);
                    indicadorElegido.classed("text-mono1-hover", false);
                }

                indicadorElegido = d3.select(this);

                d3.select(this).attr("class", "mono1 text-mono1-hover")
                d3.select(this).classed("mono1", false);
                d3.select(this).classed("text-mono1-hover", true);
            })
            .call(wrapHorizontal, 190, 127);

    // Etiquetas tipo meses
    var dim2Labels = svg.selectAll(".dim2Label")
        .data(heatMap.Meses)
        .enter().append("text")
            .text(function (d) { return d.substring(0, 3) + '.' })
            .attr("x", function (d, i) { return (i + 1) * 50 + 252; })
            .attr("y", 0)
            .style("text-anchor", "middle")
            .attr("transform", "translate(" + gridSize / 2 + ", -6)")
            .attr("class", "mono");

    var heatMapGrafico = svg.selectAll(".dim2")
        .data(heatMap.Celdas)
        .enter().append("rect")
            .attr("x", function (d) { return ((d.Mes - 1) * (gridSize + 10)) + 300; })
            .attr("y", function (d) { return (d.IndiceIndicador - 1) * (gridSize - 8); })
            .attr("rx", 3) // redondeado de la celda
            .attr("ry", 3) // redondeado de la celda
            .attr("width", gridSize + 8) // ancho de la celda
            .attr("height", gridSize - 10) // alto de la celda
            .style("fill", "gray")
            .attr("class", "square")
            .on('mouseover', function (d, i) {
                if (d.MedicionCargada)
                    tip.show(d, i);
            })
            .on('mouseout', tip.hide)
            .on('click', function (d) {
                abrirModalCargaMedicion(d.IdIndicador, d.Mes, d.IdMedicion, d.NombreMes, d.GrupoIndicador, d.TieneAccesoLecturaEscritura, d.EsAutomatico);
            });

    heatMapGrafico.transition().style("fill", function (d) { return d.ColorMeta; });
    heatMapGrafico.append("title").text(function (d) { return d.Medicion; });
});

function contarIndicadoresPorArea(heatMap) {

    var filas = heatMap.FilasHeatMapViewModel;

    jQuery.each(filas, function (key, value) {
        if (dictionaryIndicadoresPorArea[value.NombreArea] != undefined) {
            dictionaryIndicadoresPorArea[value.NombreArea] += 1;
        }
        else {
            dictionaryIndicadoresPorArea[value.NombreArea] = 1;
        }
    });

    var arr = [];
    jQuery.each(dictionaryIndicadoresPorArea, function (key, value) {
        var arr1 = [];
        arr1.push(key);
        arr1.push(value);
        arr.push(arr1);
    });

    return arr;
}

function wrap(text, cantPorArea) {
    text.each(function () {
        if (dictionaryIndicadoresPorArea[d3.select(this).text()] <= 2) {
            wrapHorizontalPalabra(d3.select(this), 90, -24);
        }
        else {
            wrapVerticalPalabra(d3.select(this), 170, -25);
        }
    });
}

function wrapVertical(text, width, posicionX) {
    text.each(function () {
        wrapVerticalPalabra(d3.select(this), width, posicionX);
    });
}

function wrapVerticalPalabra(text, width, posicionX) {

    var words = text.text().split(/\s+/).reverse(),
        word,
        line = [],
        lineNumber = 0,
        lineHeight = 1.1,
        y = text.attr("y"),
        dy = 0,
        tspan = text.text(null)
                    .append("tspan")
                    .style("text-anchor", "start")
                    .attr("y", y)
                    .attr("x", 0)
                    .attr("dx", posicionX + "em")
                    .attr("dy", dy + "em");

    while (word = words.pop()) {
        line.push(word);
        tspan.text(line.join(" "));

        if (tspan.node().getComputedTextLength() > width) {
            line.pop();
            tspan.text(line.join(" "));
            line = [word];
            tspan = text.append("tspan")
                        .attr("y", y)
                        .attr("x", 0)
                        .style("text-anchor", "start")
                        .attr("dx", posicionX + "em")
                        .attr("dy", ++lineNumber * lineHeight + dy + "em")
                        .text(word);
        }

    }
}

function wrapHorizontal(text, width, posicionX) {
    text.each(function () {
        wrapHorizontalPalabra(d3.select(this), width, posicionX);
    });
}

function wrapHorizontalPalabra(text, width, posicionX) {

    var words = text.text().split(/\s+/).reverse(),
        word,
        line = [],
        lineNumber = 0,
        lineHeight = 1.1,
        x = text.attr("x"),
        y = text.attr("y"),
        dy = 0,
        tspan = text.text(null)
                    .append("tspan")
                    .attr("x", posicionX)
                    .style("text-anchor", "start")
                    .attr("y", y)
                    .attr("dy", dy + "em");

    while (word = words.pop()) {
        line.push(word);
        tspan.text(line.join(" "));

        if (tspan.node().getComputedTextLength() > width) {
            line.pop();
            tspan.text(line.join(" "));
            line = [word];
            tspan = text.append("tspan")
                        .attr("x", posicionX)
                        .attr("y", y)
                        .style("text-anchor", "start")
                        .attr("dy", ++lineNumber * lineHeight + dy + "em")
                        .text(word);
        }

    }
}

function abrirGrafico(indicador) {
    jQuery('.detalleGrafico').show();
}<|endoftext|>


<commit_before>jest.dontMock('../src/BootstrapTable.js');
jest.dontMock('../src/TableHeaderColumn.js');
jest.dontMock('../src/TableBody.js');
jest.dontMock('../src/TableColumn.js');
jest.dontMock('../src/TableHeader.js');
jest.dontMock('../src/TableRow.js');
jest.dontMock('../src/pagination/PaginationList.js');
jest.dontMock('../src/pagination/PageButton.js');

describe('TableHeaderColumn Test', function() {

  var React;
  var TestUtils;
  var ReactTestUtils;
  var TableHeaderColumn;

  beforeEach(function(){
    React = require('react/addons');
    TableHeaderColumn = require('../src/TableHeaderColumn.js');
    TestUtils = React.addons.TestUtils;
    ReactTestUtils = React.addons.ReactTestUtils;
  });

  it('A basic table header column test', function() {

    var idHeaderColumn = TestUtils.renderIntoDocument(
      <TableHeaderColumn dataField="id">Product ID</TableHeaderColumn>
    );

    expect(idHeaderColumn.props.dataField).toEqual("id");
    expect(idHeaderColumn.props.children).toEqual("Product ID");
    expect(idHeaderColumn.props.dataAlign).toEqual("left");
    expect(idHeaderColumn.props.dataSort).toEqual(false);
    expect(idHeaderColumn.props.dataFormat).toBe(undefined);

    var reactThElm = TestUtils.findRenderedDOMComponentWithTag(idHeaderColumn, 'th');
    expect(reactThElm).not.toBe(null);
    var th = reactThElm.getDOMNode();
    expect(th.className).toEqual("");
    expect(th.childNodes.length).toEqual(1);

    var reactDivElm = TestUtils.findRenderedDOMComponentWithTag(idHeaderColumn, 'div');
    expect(reactDivElm).not.toBe(null);
    var div = reactDivElm.getDOMNode();
    expect(div.className).toEqual("th-inner table-header-column");
    expect(div.textContent).toEqual("Product ID");

    // ReactTestUtils.Simulate.click(reactDivElm);
    // expect(th.getDOMNode()).toEqual(0);
  });
});
<commit_msg>update table header testing.<commit_after>jest.dontMock('../src/BootstrapTable.js');
jest.dontMock('../src/TableHeaderColumn.js');
jest.dontMock('../src/TableBody.js');
jest.dontMock('../src/TableColumn.js');
jest.dontMock('../src/TableHeader.js');
jest.dontMock('../src/TableRow.js');
jest.dontMock('../src/pagination/PaginationList.js');
jest.dontMock('../src/pagination/PageButton.js');

describe('TableHeaderColumn Test', function() {

  var React;
  var TestUtils;
  var ReactTestUtils;
  var TableHeaderColumn;

  beforeEach(function(){
    React = require('react/addons');
    TableHeaderColumn = require('../src/TableHeaderColumn.js');
    TestUtils = React.addons.TestUtils;
  });

  it('A basic table header column test', function() {

    var idHeaderColumn = TestUtils.renderIntoDocument(
      <TableHeaderColumn dataField="id" isKey={true}>Product ID</TableHeaderColumn>
    );

    expect(idHeaderColumn.props.dataField).toEqual("id");
    expect(idHeaderColumn.props.children).toEqual("Product ID");
    expect(idHeaderColumn.props.dataAlign).toEqual("left");
    expect(idHeaderColumn.props.dataSort).toEqual(false);
    expect(idHeaderColumn.props.dataFormat).toBe(undefined);
    expect(idHeaderColumn.props.isKey).toBe(true);

    var reactThElm = TestUtils.findRenderedDOMComponentWithTag(idHeaderColumn, 'th');
    expect(reactThElm).not.toBe(null);
    var th = reactThElm.getDOMNode();
    expect(th.className).toEqual("");
    expect(th.childNodes.length).toEqual(1);
    expect(th.style.textAlign).toEqual("left");

    var reactDivElm = TestUtils.findRenderedDOMComponentWithTag(idHeaderColumn, 'div');
    expect(reactDivElm).not.toBe(null);
    var div = reactDivElm.getDOMNode();
    expect(div.className).toEqual("th-inner table-header-column");
    expect(div.textContent).toEqual("Product ID");

    // ReactTestUtils.Simulate.click(reactDivElm);
    // expect(th.getDOMNode()).toEqual(0);
  });

  it('A align header column test', function(){
    var idHeaderColumn = TestUtils.renderIntoDocument(
      <TableHeaderColumn dataField="id" dataAlign="center">Product ID</TableHeaderColumn>
    );

    expect(idHeaderColumn.props.dataField).toEqual("id");
    expect(idHeaderColumn.props.children).toEqual("Product ID");
    expect(idHeaderColumn.props.dataAlign).toEqual("center");
    expect(idHeaderColumn.props.dataSort).toEqual(false);
    expect(idHeaderColumn.props.dataFormat).toBe(undefined);
    expect(idHeaderColumn.props.isKey).toBe(false);

    var reactThElm = TestUtils.findRenderedDOMComponentWithTag(idHeaderColumn, 'th');
    expect(reactThElm).not.toBe(null);
    expect(reactThElm.getDOMNode().style.textAlign).toEqual("center");
  });

  it('A unique header column test', function(){
    var idHeaderColumn = TestUtils.renderIntoDocument(
      <TableHeaderColumn dataField="id" isKey={true}>Product ID</TableHeaderColumn>
    );

    expect(idHeaderColumn.props.dataField).toEqual("id");
    expect(idHeaderColumn.props.children).toEqual("Product ID");
    expect(idHeaderColumn.props.dataAlign).toEqual("left");
    expect(idHeaderColumn.props.dataSort).toEqual(false);
    expect(idHeaderColumn.props.dataFormat).toBe(undefined);
    expect(idHeaderColumn.props.isKey).toBe(true);
  });

  it('A dataformat header column test', function(){
    function priceFormatter(cell, row){
      return '<i class="glyphicon glyphicon-usd"></i> ' + cell;
    }

    var idHeaderColumn = TestUtils.renderIntoDocument(
      <TableHeaderColumn dataField="id" dataFormat={priceFormatter}>Product ID</TableHeaderColumn>
    );

    expect(idHeaderColumn.props.dataField).toEqual("id");
    expect(idHeaderColumn.props.children).toEqual("Product ID");
    expect(idHeaderColumn.props.dataAlign).toEqual("left");
    expect(idHeaderColumn.props.dataSort).toEqual(false);
    expect(idHeaderColumn.props.dataFormat).toEqual(priceFormatter);
    expect(idHeaderColumn.props.isKey).toBe(false);
  });

  it('A sort header column test', function(){
    var idHeaderColumn = TestUtils.renderIntoDocument(
      <TableHeaderColumn dataField="id" dataSort={true}>Product ID</TableHeaderColumn>
    );

    expect(idHeaderColumn.props.dataField).toEqual("id");
    expect(idHeaderColumn.props.children).toEqual("Product ID");
    expect(idHeaderColumn.props.dataAlign).toEqual("left");
    expect(idHeaderColumn.props.dataSort).toEqual(true);
    expect(idHeaderColumn.props.dataFormat).toBe(undefined);
    expect(idHeaderColumn.props.isKey).toBe(false);

    var reactThElm = TestUtils.findRenderedDOMComponentWithTag(idHeaderColumn, 'th');
    expect(reactThElm).not.toBe(null);
    var th = reactThElm.getDOMNode();
    console.log(th.className);
    expect(th.className).toEqual("sort-column");
    expect(th.childNodes.length).toEqual(1);
    expect(th.style.textAlign).toEqual("left");

    var reactDivElm = TestUtils.findRenderedDOMComponentWithTag(idHeaderColumn, 'div');
    expect(reactDivElm).not.toBe(null);
    var div = reactDivElm.getDOMNode();
    expect(div.className).toEqual("th-inner table-header-column");
    expect(div.textContent).toEqual("Product ID");

    TestUtils.Simulate.click(reactDivElm);
    expect(div.childNodes.length).toEqual(2);
    console.log(div.childNodes[1]);
  });
});
<|endoftext|>


<commit_before>var global = this;
var io = this.io = global.io = {};
io.version = '0.8.7';
io.protocol = 1;
io.transports = [];
io.j = [];
io.sockets = {};

require('socket.io/lib/util');
require('socket.io/lib/json');
require('socket.io/lib/parser');
require('socket.io/lib/events');
require('socket.io/lib/namespace');
require('socket.io/lib/transport');

require('socket.io/lib/transports/xhr');
require('socket.io/lib/transports/xhr-polling');
require('socket.io/lib/transports/websocket');

require('socket.io/lib/socket');

// {{{ @lib/transports/ws
// titanium-websocket-client :: https://github.com/masuidrive/ti-websocket-client
var WebSocket = require('ti-websocket-client/ti-websocket-client').WebSocket;
io.Transport.websocket.prototype.open = function (){
  var query = io.util.query(this.socket.options.query)
    , self = this
    , Socket

  var Socket = WebSocket;

  this.websocket = new Socket(this.prepareUrl() + query);

  this.websocket.onopen = function () {
    self.onOpen();
    self.socket.setBuffer(false);
  };
  this.websocket.onmessage = function (ev) {
    self.onData(ev.data);
  };
  this.websocket.onclose = function () {
    self.onClose();
    self.socket.setBuffer(true);
  };
  this.websocket.onerror = function (e) {
    self.onError(e);
  };

  return this;
};
// }}} @lib/transports/ws

// {{{ @lib/socket.js
io.Socket.prototype.isXDomain = function (){
  return false;
};
// }}} @lib/socket.js

// {{{ @lib/util.js
io.util.request = function (){
  return Titanium.Network.createHTTPClient();
};
io.connect = function (host, details) {
  var uri = io.util.parseUri(host)
    , uuri
    , socket;

  if (global && global.location) {
    uri.protocol = uri.protocol || global.location.protocol.slice(0, -1);
    uri.host = uri.host || (global.document
      ? global.document.domain : global.location.hostname);
    uri.port = uri.port || global.location.port;
  }

  uuri = io.util.uniqueUri(uri);

  var options = {
      host: uri.host
    , secure: 'https' == uri.protocol
    , port: uri.port || ('https' == uri.protocol ? 443 : 80)
    , query: uri.query || ''
  };

  io.util.merge(options, details);

  if (options['force new connection'] || !io.sockets[uuri]) {
    socket = new io.Socket(options);
  }

  if (!options['force new connection'] && socket) {
    io.sockets[uuri] = socket;
  }

  socket = socket || io.sockets[uuri];

  // if path is different from '' or /
  return socket.of(uri.path.length > 1 ? uri.path : '');
};
// }}} @lib/util.js

exports = {
  io: io,
  connect: function (){
    return io.connect.apply(io, arguments);
  }
};
<commit_msg>websocket first<commit_after>var global = this;
var io = this.io = global.io = {};
io.version = '0.8.7';
io.protocol = 1;
io.transports = [];
io.j = [];
io.sockets = {};

require('socket.io/lib/util');
require('socket.io/lib/json');
require('socket.io/lib/parser');
require('socket.io/lib/events');
require('socket.io/lib/namespace');
require('socket.io/lib/transport');

require('socket.io/lib/transports/websocket');
require('socket.io/lib/transports/xhr');
require('socket.io/lib/transports/xhr-polling');

require('socket.io/lib/socket');

// {{{ @lib/transports/ws
// titanium-websocket-client :: https://github.com/masuidrive/ti-websocket-client
var WebSocket = require('ti-websocket-client/ti-websocket-client').WebSocket;
io.Transport.websocket.prototype.open = function (){
  var query = io.util.query(this.socket.options.query)
    , self = this
    , Socket

  var Socket = WebSocket;

  this.websocket = new Socket(this.prepareUrl() + query);

  this.websocket.onopen = function () {
    self.onOpen();
    self.socket.setBuffer(false);
  };
  this.websocket.onmessage = function (ev) {
    self.onData(ev.data);
  };
  this.websocket.onclose = function () {
    self.onClose();
    self.socket.setBuffer(true);
  };
  this.websocket.onerror = function (e) {
    self.onError(e);
  };

  return this;
};
// }}} @lib/transports/ws

// {{{ @lib/socket.js
io.Socket.prototype.isXDomain = function (){
  return false;
};
// }}} @lib/socket.js

// {{{ @lib/util.js
io.util.request = function (){
  return Titanium.Network.createHTTPClient();
};
io.connect = function (host, details) {
  var uri = io.util.parseUri(host)
    , uuri
    , socket;

  if (global && global.location) {
    uri.protocol = uri.protocol || global.location.protocol.slice(0, -1);
    uri.host = uri.host || (global.document
      ? global.document.domain : global.location.hostname);
    uri.port = uri.port || global.location.port;
  }

  uuri = io.util.uniqueUri(uri);

  var options = {
      host: uri.host
    , secure: 'https' == uri.protocol
    , port: uri.port || ('https' == uri.protocol ? 443 : 80)
    , query: uri.query || ''
  };

  io.util.merge(options, details);

  if (options['force new connection'] || !io.sockets[uuri]) {
    socket = new io.Socket(options);
  }

  if (!options['force new connection'] && socket) {
    io.sockets[uuri] = socket;
  }

  socket = socket || io.sockets[uuri];

  // if path is different from '' or /
  return socket.of(uri.path.length > 1 ? uri.path : '');
};
// }}} @lib/util.js

exports = {
  io: io,
  connect: function (){
    return io.connect.apply(io, arguments);
  }
};
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2014 by Center Open Middleware. All Rights Reserved.
 * Titanium Appcelerator 3.2.0GA
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 *
 */
'use strict';

var Battery = (function() {

    var _device = (Ti.Platform.getOsname() === 'ipad' ||
                   Ti.Platform.getOsname() === 'iphone') ? 'ios' : 'android';
    var _version = parseInt(Ti.Platform.getVersion().split('.')[0], 10);

    var _self = {};

    /** Private Function to check if battery monitoring is enabled.
      * @return : Bool */
    _self.batteryMonitoring = function batteryMonitoring() {
        return Ti.Platform.getBatteryMonitoring();
    };

    /** Set battery monitoring.
      * @param: {Bool} true to activate monitoring and false to disable monitoring
      * @return : Bool */
    _self.setBatteryMonitoring = function setBatteryMonitoring(activate) {
        return Ti.Platform.setBatteryMonitoring(activate);
    };

    /** Private Function to get Battery level
      * @return : Int (percent) or String (error message)*/
    _self.getBatteryLevel = function getBatteryLevel() {
        var level;

        if (Ti.Platform.getBatteryMonitoring()) {
            level = Ti.Platform.getBatteryLevel();
        } else {
            level = 'Error. Need to activate Batrery Monitoring';
        }
        return level;
    };

    /** Private Function to get Battery level
      * @return : Int or String (error message)*/
    _self.getBatteryState = function getBatteryState() {
        var state;

        if (Ti.Platform.getBatteryMonitoring()) {
            state = Ti.Platform.getBatteryLevel();
            // TODO establecer nuestro propio código de estado de la bateria
        } else {
            state = 'Error. Need to activate Batrery Monitoring';
        }
        return state;
    };

    _self.events = {
                    'batterychange': {
                        event: 'battery',
                        listener: Ti.Platform
                    }
    };

    return _self;

}());

module.exports = Battery;<commit_msg>[API.Battery] Auto setBatteryMonitoring(true) in API<commit_after>/**
 * Copyright (c) 2014 by Center Open Middleware. All Rights Reserved.
 * Titanium Appcelerator 3.2.0GA
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 *
 */
'use strict';

var Battery = (function() {

    var _device = (Ti.Platform.getOsname() === 'ipad' ||
                   Ti.Platform.getOsname() === 'iphone') ? 'ios' : 'android';
    var _version = parseInt(Ti.Platform.getVersion().split('.')[0], 10);

    var _self = {};

    /** Private Function to check if battery monitoring is enabled.
      * @return : Bool */
    _self.batteryMonitoring = function batteryMonitoring() {
        return Ti.Platform.getBatteryMonitoring();
    };

    /** Set battery monitoring.
      * @param: {Bool} true to activate monitoring and false to disable monitoring
      * @return : Bool */
    var _setBatteryMonitoring = function _setBatteryMonitoring(activate) {
        return Ti.Platform.setBatteryMonitoring(activate);
    };

    /** Private Function to get Battery level
      * @return : Int (percent) or String (error message)*/
    _self.getBatteryLevel = function getBatteryLevel() {
        var level;

        if (Ti.Platform.getBatteryMonitoring()) {
            level = Ti.Platform.getBatteryLevel();
        } else {
            level = 'Error. Need to activate Batrery Monitoring';
        }
        return level;
    };

    /** Private Function to get Battery level
      * @return : Int or String (error message)*/
    _self.getBatteryState = function getBatteryState() {
        var state;

        if (Ti.Platform.getBatteryMonitoring()) {
            state = Ti.Platform.getBatteryLevel();
            // TODO establecer nuestro propio código de estado de la bateria
        } else {
            state = 'Error. Need to activate Batrery Monitoring';
        }
        return state;
    };

    _self.events = {
                    'batterychange': {
                        event: 'battery',
                        listener: Ti.Platform
                    }
    };

    _setBatteryMonitoring(true);
    return _self;

}());

module.exports = Battery;<|endoftext|>


<commit_before>// Karma configuration
// Generated on Wed Sep 09 2015 20:41:19 GMT-0400 (EDT)

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    files: [
      'assets/js/jquery-2.1.3.min.js',
      'assets/bootstrap-3.3.4-dist/js/bootstrap.min.js',
      'app/js/angular.js',
      'bower_components/angular-mocks/angular-mocks.js',
      'app/js/angular-route.js',
      'app/js/angular-messages.js',
      'app/js/angular-validator.min.js',
      'assets/js/eureka.tree-cohort.js',
      'assets/js/eureka.cohort.js',
      'assets/js/jstree-3.1.1.min.js',
      'app/eurekaApp.js',
      'app/eurekaApp.routes.js',
      'app/services/*.js',
      'app/controllers/*.js',
      'app/**/*-spec.js'
    ],

    // list of files to exclude
    exclude: [
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['PhantomJS'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false
  })
}
<commit_msg>Updated karma config<commit_after>// Karma configuration
// Generated on Wed Sep 09 2015 20:41:19 GMT-0400 (EDT)

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    files: [
      'bower_components/jquery/dist/jquery.js',
      'bower_components/angular/angular.js',
      'bower_components/angular-mocks/angular-mocks.js',
      'bower_components/ui-router/release/angular-ui-router.js',
      'bower_components/angular-messages/angular-messages.js',
      'bower_components/bootstrap/dist/js/bootstrap.js',
      'bower_components/angular-mocks/angular-mocks.js',
      'bower_components/tg-angular-validator/dist/angular-validator.js',
      'bower_components/angular-ui-tree/dist/angular-ui-tree.js',
      'bower_components/lodash/lodash.js',
      'assets/js/eureka.tree-cohort.js',
      'assets/js/eureka.cohort.js',
      'assets/js/jstree-3.1.1.min.js',
      'dist/all.js',
      'app/**/*-spec.js'
    ],

    // list of files to exclude
    exclude: [
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['PhantomJS'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false
  })
}
<|endoftext|>


<commit_before>function(){

	var elem = $(this),
		db = $$(this).app.require('db').db
		// TODO: Get model working
		//var model = $$(this).app.require('model').model
		// Example usage of CouchObject model
//		// Create a cong
//		var cong = model.types.Cong.init({
//		    name:'Caney OPC',
//		    mailing_state:'KS'
//		})
//		// Or create first, then populate second
//		var cong = model.types.Cong.init()
//		// Retrieve a cong from the database
//		var cong = model.types.Cong.init(id)
//		groups = cong.groups
//

	// Delay this to run after typing has stopped for 2 seconds, so we don't send too many requests
	// TODO: Don't fire on every key event, but only once after delay.
	//			The way to do this is not via setTimeout, but probably something like a while loop
	//setTimeout(function(){

	function populate_dir(cgroup){
		// Populate directory with new data from page
		if (typeof dir.cgroup_id === 'undefined') {
			dir.cgroup_id = cgroup.id
		}
		// TODO: We should check to see whether any directory already uses the URL the user is entering,
		//			and if it is present, say something like:
		//			"This URL is already in the database.  Would you like to edit its settings?"
		dir.url = $('#url').val();
		dir.get_url_contents = true // triggers changes_listener.js
		dir.name = $('#directory_name').val()
		dir.abbreviation = $('#abbreviation').val()
		// TODO: Should we do a fuzzy search or autocomplete, to get the user to pick the right cgroup?

		// Save request to get contents of URL to database
		// TODO: This saveDoc call sometimes causes a "Document update conflict."
		//			Is this because the changes listener has already changed the document?
		//			It does happen only on the second modification of the doc, so maybe.
		//			Or is it because we are not using the _rev when we save?
		// TODO: Problem here is that when I try to update the db using the directory object existing in
		//	memory, I get an update conflict (in the client or on the server?), because
		//	the dir in memory has an out of date revision
		//	number.  So I need to update the rev (and maybe other attributes) of the dir in memory
		//	from the db
		// TODO: Move the rev-checking and object syncing code below into CouchAppObject.js
		db.saveDoc(dir, {
			success:function(msg){
				// Set the local copy of the directory's new _rev
				dir._rev = msg.rev
				console.log(dir._rev)
				// Watch for Node changes listener's response
				var changes = db.changes()
				changes.onChange(function(change){
					console.log(change)
					// Determine if the changed document is the one we are editing
					if (change.id == dir._id){
						// Get document by id
						db.openDoc(change.id, {
							success:function(doc){
								// Put new dir from db into memory
								// TODO: This should set dir._rev to the rev in the db, but doesn't,
								//	so it causes a doc update conflict in the browser
								// start here
								dir = doc
								// if the new doc has a value for url_html
								if (dir.url_html){
									// Determine whether url_html contains HTML or RSS
							        if ("" in dir.url_html){
							        	dir.pagetype = 'html'
							        }
							        elseif ("</rss>" in dir.url_html){
							        	dir.pagetype = 'rss'
							        }
						        	console.log(dir.pagetype)
								}
							}
						})
					}
				})
				// TODO:  I'm a little confused.  Because changes.onChange is asynchronous, do we need
				//	changes.stop() here?
				//changes.stop();
			}
		})
	}

	function create_dir(cgroup){
		// Create directory if it does not exist in the browser's memory
		if (typeof dir === 'undefined'){
			// Get directory doc from db if it exists there
			// TODO: Move this into model.cgroup
			db.view('rcl/directories', {
				keys:[$('#abbreviation').val()],
				include_docs:true,
				success:function(data){
					if (data.rows.length>1){
						// TODO: Throw an error or handle the problem that this directory has multiple entries
						console.log("Error:  More than one copy of this directory's settings are found in the database.")
						// TODO: When I refresh http://localhost:37470/rcl/_design/rcl/import_directory.html,
						//	I get this error in an alert box: "The document could not be saved: Document update conflict."
						//  I think this is because I'm not using the previous _rev in the saveDoc command.
					}else if (data.rows.length==1){
						// We found the right directory
						dir = data.rows[0].doc
					}else{
						// Create new directory document from here
						dir = {type:'directory'};
					}
					populate_dir(cgroup)
				}
			})
		}else{
			// Use existing directory object in browser's memory
			populate_dir(cgroup)
		}
	}

	// If the associated cgroup exists in the db, get it
	var cgroup = ''
	// Query database by cgroup.abbreviation
	// TODO: Turn this into a view in model.cgroup
	db.view('rcl/cgroup-by-abbreviation', {
		keys:[$('#abbreviation').val()],
		include_docs:true,
		success:function(data){
			if (data.rows.length==1){
				// Get this cgroup from the db
				var cgroup = data.rows[0]
				create_dir(cgroup)
			}else if (data.rows.length > 1){
				// Report error
				console.log("Error:  More than one copy of this cgroup's settings are found in the database.")
			}else if (data.rows.length==0){
				// Otherwise, create that cgroup
				var cgroup = {
						type:	'cgroup',
						name:	$('#directory_name').val(),
						abbreviation:	$('#abbreviation').val()
				}
				db.saveDoc(cgroup,{
					success:function(data){
						cgroup.id = data._id
						create_dir(cgroup)
					}
				})
			}
		}
	})

//	$.ajax({
//		type: "POST",
//		url: "/cong/get_page_type",
//		data: ({url : directory.url}),
//        success: function(msg){
//			// TODO: In the controller & output to form, handle whether this is an RSS feed or an HTML page
//        	$("#url_result_div").innerHTML = msg;
//        	if (msg == 'html'){
//        		$("#directory_type").show(1000);
//        		$("#rss_feed").hide(1000);
//        		directory.page_type = 'html';
//        	} else if (msg == 'rss'){
//        		// TODO: Display the right form controls for an RSS page
//        		$("#directory_type").hide(1000);
//        		$("#rss_feed").show(1000);
//        		directory.page_type = 'rss';
//        	} else { // We got an error code
//        		// Hide the form controls.
//        		elem.trigger('hide_subform');
//        	}
//        },
//        error: function(xhr, ajaxOptions, thrownError){
//          $("#url_result_div").innerHTML = xhr.responseText;
//        },
//		statusCode: {
//			500: function(data, textStatus, jqXHR){
//				// TODO: Handle 500 errors here
//				//alert(data);
//				//alert(data.responseText)
//				// TODO: Even though Chrome's developer tools says the server is returning a 500 error,
//				//			This code does not seem to be running.
//				console.log("The 500 error handler is running.");
//				elem.trigger('hide_subform');
//			},
//			404: function(data, textStatus, jqXHR){
//				// TODO: Handle 404 errors here
//				elem.trigger('hide_subform');
//			}
//		}
//	});

	//},2000);

}<commit_msg>Fixed syntax<commit_after>function(){

	var elem = $(this),
		db = $$(this).app.require('db').db
		// TODO: Get model working
		//var model = $$(this).app.require('model').model
		// Example usage of CouchObject model
//		// Create a cong
//		var cong = model.types.Cong.init({
//		    name:'Caney OPC',
//		    mailing_state:'KS'
//		})
//		// Or create first, then populate second
//		var cong = model.types.Cong.init()
//		// Retrieve a cong from the database
//		var cong = model.types.Cong.init(id)
//		groups = cong.groups
//

	// Delay this to run after typing has stopped for 2 seconds, so we don't send too many requests
	// TODO: Don't fire on every key event, but only once after delay.
	//			The way to do this is not via setTimeout, but probably something like a while loop
	//setTimeout(function(){

	function populate_dir(cgroup){
		// Populate directory with new data from page
		if (typeof dir.cgroup_id === 'undefined') {
			dir.cgroup_id = cgroup.id
		}
		// TODO: We should check to see whether any directory already uses the URL the user is entering,
		//			and if it is present, say something like:
		//			"This URL is already in the database.  Would you like to edit its settings?"
		dir.url = $('#url').val();
		dir.get_url_contents = true // triggers changes_listener.js
		dir.name = $('#directory_name').val()
		dir.abbreviation = $('#abbreviation').val()
		// TODO: Should we do a fuzzy search or autocomplete, to get the user to pick the right cgroup?

		// Save request to get contents of URL to database
		// TODO: This saveDoc call sometimes causes a "Document update conflict."
		//			Is this because the changes listener has already changed the document?
		//			It does happen only on the second modification of the doc, so maybe.
		//			Or is it because we are not using the _rev when we save?
		// TODO: Problem here is that when I try to update the db using the directory object existing in
		//	memory, I get an update conflict (in the client or on the server?), because
		//	the dir in memory has an out of date revision
		//	number.  So I need to update the rev (and maybe other attributes) of the dir in memory
		//	from the db
		// TODO: Move the rev-checking and object syncing code below into CouchAppObject.js
		db.saveDoc(dir, {
			success:function(msg){
				// Set the local copy of the directory's new _rev
				dir._rev = msg.rev
				console.log(dir._rev)
				// Watch for Node changes listener's response
				var changes = db.changes()
				changes.onChange(function(change){
					console.log(change)
					// Determine if the changed document is the one we are editing
					if (change.id == dir._id){
						// Get document by id
						db.openDoc(change.id, {
							success:function(doc){
								// Put new dir from db into memory
								// TODO: This should set dir._rev to the rev in the db, but doesn't,
								//	so it causes a doc update conflict in the browser
								// start here
								dir = doc
								// if the new doc has a value for url_html
								if (dir.url_html){
									// Determine whether url_html contains HTML or RSS
							        if (dir.url_html.indexOf("") > -1){
							        	dir.pagetype = 'html'
							        }
							        else if (dir.url_html.indexOf("</rss>") > -1){
							        	dir.pagetype = 'rss'
							        }
						        	console.log(dir.pagetype)
								}
							}
						})
					}
				})
				// TODO:  I'm a little confused.  Because changes.onChange is asynchronous, do we need
				//	changes.stop() here?
				//changes.stop();
			}
		})
	}

	function create_dir(cgroup){
		// Create directory if it does not exist in the browser's memory
		if (typeof dir === 'undefined'){
			// Get directory doc from db if it exists there
			// TODO: Move this into model.cgroup
			db.view('rcl/directories', {
				keys:[$('#abbreviation').val()],
				include_docs:true,
				success:function(data){
					if (data.rows.length>1){
						// TODO: Throw an error or handle the problem that this directory has multiple entries
						console.log("Error:  More than one copy of this directory's settings are found in the database.")
						// TODO: When I refresh http://localhost:37470/rcl/_design/rcl/import_directory.html,
						//	I get this error in an alert box: "The document could not be saved: Document update conflict."
						//  I think this is because I'm not using the previous _rev in the saveDoc command.
					}else if (data.rows.length==1){
						// We found the right directory
						dir = data.rows[0].doc
					}else{
						// Create new directory document from here
						dir = {type:'directory'};
					}
					populate_dir(cgroup)
				}
			})
		}else{
			// Use existing directory object in browser's memory
			populate_dir(cgroup)
		}
	}

	// If the associated cgroup exists in the db, get it
	var cgroup = ''
	// Query database by cgroup.abbreviation
	// TODO: Turn this into a view in model.cgroup
	db.view('rcl/cgroup-by-abbreviation', {
		keys:[$('#abbreviation').val()],
		include_docs:true,
		success:function(data){
			if (data.rows.length==1){
				// Get this cgroup from the db
				var cgroup = data.rows[0]
				create_dir(cgroup)
			}else if (data.rows.length > 1){
				// Report error
				console.log("Error:  More than one copy of this cgroup's settings are found in the database.")
			}else if (data.rows.length==0){
				// Otherwise, create that cgroup
				var cgroup = {
						type:	'cgroup',
						name:	$('#directory_name').val(),
						abbreviation:	$('#abbreviation').val()
				}
				db.saveDoc(cgroup,{
					success:function(data){
						cgroup.id = data._id
						create_dir(cgroup)
					}
				})
			}
		}
	})

//	$.ajax({
//		type: "POST",
//		url: "/cong/get_page_type",
//		data: ({url : directory.url}),
//        success: function(msg){
//			// TODO: In the controller & output to form, handle whether this is an RSS feed or an HTML page
//        	$("#url_result_div").innerHTML = msg;
//        	if (msg == 'html'){
//        		$("#directory_type").show(1000);
//        		$("#rss_feed").hide(1000);
//        		directory.page_type = 'html';
//        	} else if (msg == 'rss'){
//        		// TODO: Display the right form controls for an RSS page
//        		$("#directory_type").hide(1000);
//        		$("#rss_feed").show(1000);
//        		directory.page_type = 'rss';
//        	} else { // We got an error code
//        		// Hide the form controls.
//        		elem.trigger('hide_subform');
//        	}
//        },
//        error: function(xhr, ajaxOptions, thrownError){
//          $("#url_result_div").innerHTML = xhr.responseText;
//        },
//		statusCode: {
//			500: function(data, textStatus, jqXHR){
//				// TODO: Handle 500 errors here
//				//alert(data);
//				//alert(data.responseText)
//				// TODO: Even though Chrome's developer tools says the server is returning a 500 error,
//				//			This code does not seem to be running.
//				console.log("The 500 error handler is running.");
//				elem.trigger('hide_subform');
//			},
//			404: function(data, textStatus, jqXHR){
//				// TODO: Handle 404 errors here
//				elem.trigger('hide_subform');
//			}
//		}
//	});

	//},2000);

}<|endoftext|>


<commit_before>var alexa = require('alexa-app');

// Allow this module to be reloaded by hotswap when changed
module.change_code = 1;

// Define an alexa-app
var app = new alexa.app('guessinggame');

app.launch(function(req,res) {
	var number = Math.floor(Math.random()*99)+1;
	res.session('number',number);
	res.session('guesses',0);
	var prompt = "Guess a number between 1 and 100!";
	res.say(prompt).reprompt(prompt).shouldEndSession(false);
});
app.intent('guess',{
		"slots":{"guess":"NUMBER"}
		,"utterances":["{1-100|guess}"]
	},
	function(req,res) {
		var guesses = (+req.session('guesses'))+1;
		var guess = req.slot('guess');
		var number = +req.session('number');
		if (!guess) {
			res.say("Sorry, I didn't hear a number. The number was "+number);
		}
		else if (guess==number) {
			res.say("Congratulations, you guessed the number in " + guesses + (guesses==1?" try":" tries"));
		}
		else {
			if (guess > number) {
				res.say("Guess lower");
			}
			else if (guess < number) {
				res.say("Guess higher");
			}
			res.reprompt("Sorry, I didn't hear a number. Try again.");
			res.session('guesses',guesses);
			res.shouldEndSession(false);
		}
	}
);
module.exports = app;
<commit_msg>fixed Invalid schema for guessinggame example<commit_after>var alexa = require('alexa-app');

// Allow this module to be reloaded by hotswap when changed
module.change_code = 1;

// Define an alexa-app
var app = new alexa.app('guessinggame');

app.launch(function(req,res) {
	var number = Math.floor(Math.random()*99)+1;
	res.session('number',number);
	res.session('guesses',0);
	var prompt = "Guess a number between 1 and 100!";
	res.say(prompt).reprompt(prompt).shouldEndSession(false);
});
app.intent('GuessIntent',{
		"slots":{"guess":"NUMBER"}
		,"utterances":["{1-100|guess}"]
	},
	function(req,res) {
		var guesses = (+req.session('guesses'))+1;
		var guess = req.slot('guess');
		var number = +req.session('number');
		if (!guess) {
			res.say("Sorry, I didn't hear a number. The number was "+number);
		}
		else if (guess==number) {
			res.say("Congratulations, you guessed the number in " + guesses + (guesses==1?" try":" tries"));
		}
		else {
			if (guess > number) {
				res.say("Guess lower");
			}
			else if (guess < number) {
				res.say("Guess higher");
			}
			res.reprompt("Sorry, I didn't hear a number. Try again.");
			res.session('guesses',guesses);
			res.shouldEndSession(false);
		}
	}
);
module.exports = app;
<|endoftext|>


<commit_before>import { FBXLoader } from "../loaders/FBXLoader.js";

class XRHandOculusMeshModel {

	constructor( handModel, controller, handedness, options ) {

		this.controller = controller;
		this.handModel = handModel;

		this.bones = [];
		var loader = new FBXLoader();
		const low = options && options.model === "lowpoly" ? "_low" : "";

		loader.load( `/examples/models/fbx/OculusHand_${handedness === "right" ? "R" : "L"}${low}.fbx`, object => {

			this.handModel.add( object );
			// Hack because of the scale of the skinnedmesh
			object.scale.setScalar( 0.01 );
			object.getObjectByProperty( "type", "SkinnedMesh" ).frustumCulled = false;

			const bonesMapping = [
				'b_%_wrist', // XRHand.WRIST,

				'b_%_thumb1', // XRHand.THUMB_METACARPAL,
				'b_%_thumb2', // XRHand.THUMB_PHALANX_PROXIMAL,
				'b_%_thumb3', // XRHand.THUMB_PHALANX_DISTAL,
				'b_%_thumb_null', // XRHand.THUMB_PHALANX_TIP,

				null, //'b_%_index1', // XRHand.INDEX_METACARPAL,
				'b_%_index1', // XRHand.INDEX_PHALANX_PROXIMAL,
				'b_%_index2', // XRHand.INDEX_PHALANX_INTERMEDIATE,
				'b_%_index3', // XRHand.INDEX_PHALANX_DISTAL,
				'b_%_index_null', // XRHand.INDEX_PHALANX_TIP,

				null, //'b_%_middle1', // XRHand.MIDDLE_METACARPAL,
				'b_%_middle1', // XRHand.MIDDLE_PHALANX_PROXIMAL,
				'b_%_middle2', // XRHand.MIDDLE_PHALANX_INTERMEDIATE,
				'b_%_middle3', // XRHand.MIDDLE_PHALANX_DISTAL,
				'b_%_middlenull', // XRHand.MIDDLE_PHALANX_TIP,

				null, //'b_%_ring1', // XRHand.RING_METACARPAL,
				'b_%_ring1', // XRHand.RING_PHALANX_PROXIMAL,
				'b_%_ring2', // XRHand.RING_PHALANX_INTERMEDIATE,
				'b_%_ring3', // XRHand.RING_PHALANX_DISTAL,
				'b_%_ring_inull', // XRHand.RING_PHALANX_TIP,

				'b_%_pinky0', // XRHand.LITTLE_METACARPAL,
				'b_%_pinky1', // XRHand.LITTLE_PHALANX_PROXIMAL,
				'b_%_pinky2', // XRHand.LITTLE_PHALANX_INTERMEDIATE,
				'b_%_pinky3', // XRHand.LITTLE_PHALANX_DISTAL,
				'b_%_pinkynull', // XRHand.LITTLE_PHALANX_TIP
			];
			bonesMapping.forEach( boneName => {

				if ( boneName ) {

					const bone = object.getObjectByName( boneName.replace( "%", handedness === "right" ? "r" : "l" ) );
					this.bones.push( bone );

				} else {

					this.bones.push( null );

				}

			} );

		} );

	}

	updateMesh() {

		// XR Joints
		const XRJoints = this.controller.joints;
		for ( var i = 0; i < this.bones.length; i ++ ) {

			const bone = this.bones[ i ];
			const XRJoint = XRJoints[ i ];

			if ( XRJoint ) {

				if ( XRJoint.visible ) {

					let position = XRJoint.position;

					if ( bone ) {

						bone.position.copy( position.clone().multiplyScalar( 100 ) );
						bone.quaternion.copy( XRJoint.quaternion );
						// bone.scale.setScalar( XRJoint.jointRadius || defaultRadius );

					}

				}

			}

		}

	}

}

export { XRHandOculusMeshModel };
<commit_msg>XRHandOculusMeshModel: Fixed models path.<commit_after>import { FBXLoader } from "../loaders/FBXLoader.js";

class XRHandOculusMeshModel {

	constructor( handModel, controller, handedness, options ) {

		this.controller = controller;
		this.handModel = handModel;

		this.bones = [];
		var loader = new FBXLoader();
		const low = options && options.model === "lowpoly" ? "_low" : "";

		loader.load( `../../models/fbx/OculusHand_${handedness === "right" ? "R" : "L"}${low}.fbx`, object => {

			this.handModel.add( object );
			// Hack because of the scale of the skinnedmesh
			object.scale.setScalar( 0.01 );
			object.getObjectByProperty( "type", "SkinnedMesh" ).frustumCulled = false;

			const bonesMapping = [
				'b_%_wrist', // XRHand.WRIST,

				'b_%_thumb1', // XRHand.THUMB_METACARPAL,
				'b_%_thumb2', // XRHand.THUMB_PHALANX_PROXIMAL,
				'b_%_thumb3', // XRHand.THUMB_PHALANX_DISTAL,
				'b_%_thumb_null', // XRHand.THUMB_PHALANX_TIP,

				null, //'b_%_index1', // XRHand.INDEX_METACARPAL,
				'b_%_index1', // XRHand.INDEX_PHALANX_PROXIMAL,
				'b_%_index2', // XRHand.INDEX_PHALANX_INTERMEDIATE,
				'b_%_index3', // XRHand.INDEX_PHALANX_DISTAL,
				'b_%_index_null', // XRHand.INDEX_PHALANX_TIP,

				null, //'b_%_middle1', // XRHand.MIDDLE_METACARPAL,
				'b_%_middle1', // XRHand.MIDDLE_PHALANX_PROXIMAL,
				'b_%_middle2', // XRHand.MIDDLE_PHALANX_INTERMEDIATE,
				'b_%_middle3', // XRHand.MIDDLE_PHALANX_DISTAL,
				'b_%_middlenull', // XRHand.MIDDLE_PHALANX_TIP,

				null, //'b_%_ring1', // XRHand.RING_METACARPAL,
				'b_%_ring1', // XRHand.RING_PHALANX_PROXIMAL,
				'b_%_ring2', // XRHand.RING_PHALANX_INTERMEDIATE,
				'b_%_ring3', // XRHand.RING_PHALANX_DISTAL,
				'b_%_ring_inull', // XRHand.RING_PHALANX_TIP,

				'b_%_pinky0', // XRHand.LITTLE_METACARPAL,
				'b_%_pinky1', // XRHand.LITTLE_PHALANX_PROXIMAL,
				'b_%_pinky2', // XRHand.LITTLE_PHALANX_INTERMEDIATE,
				'b_%_pinky3', // XRHand.LITTLE_PHALANX_DISTAL,
				'b_%_pinkynull', // XRHand.LITTLE_PHALANX_TIP
			];
			bonesMapping.forEach( boneName => {

				if ( boneName ) {

					const bone = object.getObjectByName( boneName.replace( "%", handedness === "right" ? "r" : "l" ) );
					this.bones.push( bone );

				} else {

					this.bones.push( null );

				}

			} );

		} );

	}

	updateMesh() {

		// XR Joints
		const XRJoints = this.controller.joints;
		for ( var i = 0; i < this.bones.length; i ++ ) {

			const bone = this.bones[ i ];
			const XRJoint = XRJoints[ i ];

			if ( XRJoint ) {

				if ( XRJoint.visible ) {

					let position = XRJoint.position;

					if ( bone ) {

						bone.position.copy( position.clone().multiplyScalar( 100 ) );
						bone.quaternion.copy( XRJoint.quaternion );
						// bone.scale.setScalar( XRJoint.jointRadius || defaultRadius );

					}

				}

			}

		}

	}

}

export { XRHandOculusMeshModel };
<|endoftext|>


<commit_before>/*global define*/
define([
        '../ThirdParty/when',
        './loadBlob',
        './loadImage'
    ], function(
        when,
        loadBlob,
        loadImage) {
    "use strict";

    var dataUriRegex = /^data:/;

    /**
     * Asynchronously loads the given image URL by first downloading it as a blob using
     * XMLHttpRequest and then loading the image from the buffer via a blob URL.
     * This allows access to more information that is not accessible via normal
     * Image-based downloading, such as the size of the response.  This function
     * returns a promise that will resolve to
     * an {@link Image} once loaded, or reject if the image failed to load.  The
     * returned image will have a "blob" property with the Blob itself.  If the browser
     * does not support an XMLHttpRequests with a responseType of 'blob', or if the
     * provided URI is a data URI, this function is equivalent to calling {@link loadImage},
     * and the extra blob property will not be present.
     *
     * @exports loadImageViaBlob
     *
     * @param {String|Promise.<String>} url The source of the image, or a promise for the URL.
     * @returns {Promise.<Image>} a promise that will resolve to the requested data when loaded.
     *
     * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing}
     * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A}
     *
     * @example
     * // load a single image asynchronously
     * Cesium.loadImageViaBlob('some/image/url.png').then(function(image) {
     *     var blob = image.blob;
     *     // use the loaded image or XHR
     * }).otherwise(function(error) {
     *     // an error occurred
     * });
     *
     * // load several images in parallel
     * when.all([loadImageViaBlob('image1.png'), loadImageViaBlob('image2.png')]).then(function(images) {
     *     // images is an array containing all the loaded images
     * });
     */
    function loadImageViaBlob(url) {
        if (dataUriRegex.test(url)) {
            return loadImage(url);
        }

        return loadBlob(url).then(function(blob) {
            var blobUrl = window.URL.createObjectURL(blob);

            return loadImage(blobUrl, false).then(function(image) {
                image.blob = blob;
                window.URL.revokeObjectURL(blobUrl);
                return image;
            }, function(error) {
                window.URL.revokeObjectURL(blobUrl);
                return when.reject(error);
            });
        });
    }

    var xhrBlobSupported = (function() {
        try {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', '#', true);
            xhr.responseType = 'blob';
            return xhr.responseType === 'blob';
        } catch (e) {
            return false;
        }
    })();

    return xhrBlobSupported ? loadImageViaBlob : loadImage;
});
<commit_msg>Update loadImageViaBlob.js<commit_after>/*global define*/
define([
        '../ThirdParty/when',
        './loadBlob',
        './loadImage'
    ], function(
        when,
        loadBlob,
        loadImage) {
    "use strict";

    var dataUriRegex = /^data:/;

    /**
     * Asynchronously loads the given image URL by first downloading it as a blob using
     * XMLHttpRequest and then loading the image from the buffer via a blob URL.
     * This allows access to more information that is not accessible via normal
     * Image-based downloading, such as the size of the response.  This function
     * returns a promise that will resolve to
     * an {@link Image} once loaded, or reject if the image failed to load.  The
     * returned image will have a "blob" property with the Blob itself.  If the browser
     * does not support an XMLHttpRequests with a responseType of 'blob', or if the
     * provided URI is a data URI, this function is equivalent to calling {@link loadImage},
     * and the extra blob property will not be present.
     *
     * @exports loadImageViaBlob
     *
     * @param {String|Promise.<String>} url The source of the image, or a promise for the URL.
     * @returns {Promise.<Image>} a promise that will resolve to the requested data when loaded.
     *
     *
     * @example
     * // load a single image asynchronously
     * Cesium.loadImageViaBlob('some/image/url.png').then(function(image) {
     *     var blob = image.blob;
     *     // use the loaded image or XHR
     * }).otherwise(function(error) {
     *     // an error occurred
     * });
     *
     * // load several images in parallel
     * when.all([loadImageViaBlob('image1.png'), loadImageViaBlob('image2.png')]).then(function(images) {
     *     // images is an array containing all the loaded images
     * });
     * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing}
     * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A}
     */
    function loadImageViaBlob(url) {
        if (dataUriRegex.test(url)) {
            return loadImage(url);
        }

        return loadBlob(url).then(function(blob) {
            var blobUrl = window.URL.createObjectURL(blob);

            return loadImage(blobUrl, false).then(function(image) {
                image.blob = blob;
                window.URL.revokeObjectURL(blobUrl);
                return image;
            }, function(error) {
                window.URL.revokeObjectURL(blobUrl);
                return when.reject(error);
            });
        });
    }

    var xhrBlobSupported = (function() {
        try {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', '#', true);
            xhr.responseType = 'blob';
            return xhr.responseType === 'blob';
        } catch (e) {
            return false;
        }
    })();

    return xhrBlobSupported ? loadImageViaBlob : loadImage;
});
<|endoftext|>