<commit_before>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import Agent from 'react-devtools-shared/src/backend/agent';
import Bridge from 'react-devtools-shared/src/bridge';
import {installHook} from 'react-devtools-shared/src/hook';
import {initBackend} from 'react-devtools-shared/src/backend';
import {__DEBUG__} from 'react-devtools-shared/src/constants';
import setupNativeStyleEditor from 'react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor';
import {getDefaultComponentFilters} from 'react-devtools-shared/src/utils';

import type {BackendBridge} from 'react-devtools-shared/src/bridge';
import type {ComponentFilter} from 'react-devtools-shared/src/types';
import type {DevToolsHook} from 'react-devtools-shared/src/backend/types';
import type {ResolveNativeStyle} from 'react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor';

type ConnectOptions = {
  host?: string,
  nativeStyleEditorValidAttributes?: $ReadOnlyArray<string>,
  port?: number,
  useHttps?: boolean,
  resolveRNStyle?: ResolveNativeStyle,
  retryConnectionDelay?: number,
  isAppActive?: () => boolean,
  websocket?: ?WebSocket,
  ...
};

installHook(window);

const hook: ?DevToolsHook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;

let savedComponentFilters: Array<ComponentFilter> = getDefaultComponentFilters();

function debug(methodName: string, ...args) {
  if (__DEBUG__) {
    console.log(
      `%c[core/backend] %c${methodName}`,
      'color: teal; font-weight: bold;',
      'font-weight: bold;',
      ...args,
    );
  }
}

export function connectToDevTools(options: ?ConnectOptions) {
  if (hook == null) {
    // DevTools didn't get injected into this page (maybe b'c of the contentType).
    return;
  }
  const {
    host = 'localhost',
    nativeStyleEditorValidAttributes,
    useHttps = false,
    port = 8097,
    websocket,
    resolveRNStyle = null,
    retryConnectionDelay = 2000,
    isAppActive = () => true,
  } = options || {};

  const protocol = useHttps ? 'wss' : 'ws';
  let retryTimeoutID: TimeoutID | null = null;

  function scheduleRetry() {
    if (retryTimeoutID === null) {
      // Two seconds because RN had issues with quick retries.
      retryTimeoutID = setTimeout(
        () => connectToDevTools(options),
        retryConnectionDelay,
      );
    }
  }

  if (!isAppActive()) {
    // If the app is in background, maybe retry later.
    // Don't actually attempt to connect until we're in foreground.
    scheduleRetry();
    return;
  }

  let bridge: BackendBridge | null = null;

  const messageListeners = [];
  const uri = protocol + '://' + host + ':' + port;

  // If existing websocket is passed, use it.
  // This is necessary to support our custom integrations.
  // See D6251744.
  const ws = websocket ? websocket : new window.WebSocket(uri);
  ws.onclose = handleClose;
  ws.onerror = handleFailed;
  ws.onmessage = handleMessage;
  ws.onopen = function() {
    bridge = new Bridge({
      listen(fn) {
        messageListeners.push(fn);
        return () => {
          const index = messageListeners.indexOf(fn);
          if (index >= 0) {
            messageListeners.splice(index, 1);
          }
        };
      },
      send(event: string, payload: any, transferable?: Array<any>) {
        if (ws.readyState === ws.OPEN) {
          if (__DEBUG__) {
            debug('wall.send()', event, payload);
          }

          ws.send(JSON.stringify({event, payload}));
        } else {
          if (__DEBUG__) {
            debug(
              'wall.send()',
              'Shutting down bridge because of closed WebSocket connection',
            );
          }

          if (bridge !== null) {
            bridge.shutdown();
          }

          scheduleRetry();
        }
      },
    });
    bridge.addListener(
      'inspectElement',
      ({id, rendererID}: {id: number, rendererID: number, ...}) => {
        const renderer = agent.rendererInterfaces[rendererID];
        if (renderer != null) {
          // Send event for RN to highlight.
          const nodes: ?Array<HTMLElement> = renderer.findNativeNodesForFiberID(
            id,
          );
          if (nodes != null && nodes[0] != null) {
            agent.emit('showNativeHighlight', nodes[0]);
          }
        }
      },
    );
    // $FlowFixMe[incompatible-use] found when upgrading Flow
    bridge.addListener(
      'updateComponentFilters',
      (componentFilters: Array<ComponentFilter>) => {
        // Save filter changes in memory, in case DevTools is reloaded.
        // In that case, the renderer will already be using the updated values.
        // We'll lose these in between backend reloads but that can't be helped.
        savedComponentFilters = componentFilters;
      },
    );

    // The renderer interface doesn't read saved component filters directly,
    // because they are generally stored in localStorage within the context of the extension.
    // Because of this it relies on the extension to pass filters.
    // In the case of the standalone DevTools being used with a website,
    // saved filters are injected along with the backend script tag so we shouldn't override them here.
    // This injection strategy doesn't work for React Native though.
    // Ideally the backend would save the filters itself, but RN doesn't provide a sync storage solution.
    // So for now we just fall back to using the default filters...
    if (window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ == null) {
      // $FlowFixMe[incompatible-use] found when upgrading Flow
      bridge.send('overrideComponentFilters', savedComponentFilters);
    }

    // TODO (npm-packages) Warn if "isBackendStorageAPISupported"
    // $FlowFixMe[incompatible-call] found when upgrading Flow
    const agent = new Agent(bridge);
    agent.addListener('shutdown', () => {
      // If we received 'shutdown' from `agent`, we assume the `bridge` is already shutting down,
      // and that caused the 'shutdown' event on the `agent`, so we don't need to call `bridge.shutdown()` here.
      hook.emit('shutdown');
    });

    initBackend(hook, agent, window);

    // Setup React Native style editor if the environment supports it.
    if (resolveRNStyle != null || hook.resolveRNStyle != null) {
      setupNativeStyleEditor(
        // $FlowFixMe[incompatible-call] found when upgrading Flow
        bridge,
        agent,
        ((resolveRNStyle || hook.resolveRNStyle: any): ResolveNativeStyle),
        nativeStyleEditorValidAttributes ||
          hook.nativeStyleEditorValidAttributes ||
          null,
      );
    } else {
      // Otherwise listen to detect if the environment later supports it.
      // For example, Flipper does not eagerly inject these values.
      // Instead it relies on the React Native Inspector to lazily inject them.
      let lazyResolveRNStyle;
      let lazyNativeStyleEditorValidAttributes;

      const initAfterTick = () => {
        if (bridge !== null) {
          setupNativeStyleEditor(
            bridge,
            agent,
            lazyResolveRNStyle,
            lazyNativeStyleEditorValidAttributes,
          );
        }
      };

      if (!hook.hasOwnProperty('resolveRNStyle')) {
        Object.defineProperty(
          hook,
          'resolveRNStyle',
          ({
            enumerable: false,
            get() {
              return lazyResolveRNStyle;
            },
            set(value) {
              lazyResolveRNStyle = value;
              initAfterTick();
            },
          }: Object),
        );
      }
      if (!hook.hasOwnProperty('nativeStyleEditorValidAttributes')) {
        Object.defineProperty(
          hook,
          'nativeStyleEditorValidAttributes',
          ({
            enumerable: false,
            get() {
              return lazyNativeStyleEditorValidAttributes;
            },
            set(value) {
              lazyNativeStyleEditorValidAttributes = value;
              initAfterTick();
            },
          }: Object),
        );
      }
    }
  };

  function handleClose() {
    if (__DEBUG__) {
      debug('WebSocket.onclose');
    }

    if (bridge !== null) {
      bridge.emit('shutdown');
    }

    scheduleRetry();
  }

  function handleFailed() {
    if (__DEBUG__) {
      debug('WebSocket.onerror');
    }

    scheduleRetry();
  }

  function handleMessage(event) {
    let data;
    try {
      if (typeof event.data === 'string') {
        data = JSON.parse(event.data);
        if (__DEBUG__) {
          debug('WebSocket.onmessage', data);
        }
      } else {
        throw Error();
      }
    } catch (e) {
      console.error(
        '[React DevTools] Failed to parse JSON: ' + (event.data: any),
      );
      return;
    }
    messageListeners.forEach(fn => {
      try {
        fn(data);
      } catch (error) {
        // jsc doesn't play so well with tracebacks that go into eval'd code,
        // so the stack trace here will stop at the `eval()` call. Getting the
        // message that caused the error is the best we can do for now.
        console.log('[React DevTools] Error calling listener', data);
        console.log('error:', error);
        throw error;
      }
    });
  }
}
<commit_msg>Stop spamming highlight events when a component is selected (#25448)<commit_after>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import Agent from 'react-devtools-shared/src/backend/agent';
import Bridge from 'react-devtools-shared/src/bridge';
import {installHook} from 'react-devtools-shared/src/hook';
import {initBackend} from 'react-devtools-shared/src/backend';
import {__DEBUG__} from 'react-devtools-shared/src/constants';
import setupNativeStyleEditor from 'react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor';
import {getDefaultComponentFilters} from 'react-devtools-shared/src/utils';

import type {BackendBridge} from 'react-devtools-shared/src/bridge';
import type {ComponentFilter} from 'react-devtools-shared/src/types';
import type {DevToolsHook} from 'react-devtools-shared/src/backend/types';
import type {ResolveNativeStyle} from 'react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor';

type ConnectOptions = {
  host?: string,
  nativeStyleEditorValidAttributes?: $ReadOnlyArray<string>,
  port?: number,
  useHttps?: boolean,
  resolveRNStyle?: ResolveNativeStyle,
  retryConnectionDelay?: number,
  isAppActive?: () => boolean,
  websocket?: ?WebSocket,
  ...
};

installHook(window);

const hook: ?DevToolsHook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;

let savedComponentFilters: Array<ComponentFilter> = getDefaultComponentFilters();

function debug(methodName: string, ...args) {
  if (__DEBUG__) {
    console.log(
      `%c[core/backend] %c${methodName}`,
      'color: teal; font-weight: bold;',
      'font-weight: bold;',
      ...args,
    );
  }
}

export function connectToDevTools(options: ?ConnectOptions) {
  if (hook == null) {
    // DevTools didn't get injected into this page (maybe b'c of the contentType).
    return;
  }
  const {
    host = 'localhost',
    nativeStyleEditorValidAttributes,
    useHttps = false,
    port = 8097,
    websocket,
    resolveRNStyle = null,
    retryConnectionDelay = 2000,
    isAppActive = () => true,
  } = options || {};

  const protocol = useHttps ? 'wss' : 'ws';
  let retryTimeoutID: TimeoutID | null = null;

  function scheduleRetry() {
    if (retryTimeoutID === null) {
      // Two seconds because RN had issues with quick retries.
      retryTimeoutID = setTimeout(
        () => connectToDevTools(options),
        retryConnectionDelay,
      );
    }
  }

  if (!isAppActive()) {
    // If the app is in background, maybe retry later.
    // Don't actually attempt to connect until we're in foreground.
    scheduleRetry();
    return;
  }

  let bridge: BackendBridge | null = null;

  const messageListeners = [];
  const uri = protocol + '://' + host + ':' + port;

  // If existing websocket is passed, use it.
  // This is necessary to support our custom integrations.
  // See D6251744.
  const ws = websocket ? websocket : new window.WebSocket(uri);
  ws.onclose = handleClose;
  ws.onerror = handleFailed;
  ws.onmessage = handleMessage;
  ws.onopen = function() {
    bridge = new Bridge({
      listen(fn) {
        messageListeners.push(fn);
        return () => {
          const index = messageListeners.indexOf(fn);
          if (index >= 0) {
            messageListeners.splice(index, 1);
          }
        };
      },
      send(event: string, payload: any, transferable?: Array<any>) {
        if (ws.readyState === ws.OPEN) {
          if (__DEBUG__) {
            debug('wall.send()', event, payload);
          }

          ws.send(JSON.stringify({event, payload}));
        } else {
          if (__DEBUG__) {
            debug(
              'wall.send()',
              'Shutting down bridge because of closed WebSocket connection',
            );
          }

          if (bridge !== null) {
            bridge.shutdown();
          }

          scheduleRetry();
        }
      },
    });
    // $FlowFixMe[incompatible-use] found when upgrading Flow
    bridge.addListener(
      'updateComponentFilters',
      (componentFilters: Array<ComponentFilter>) => {
        // Save filter changes in memory, in case DevTools is reloaded.
        // In that case, the renderer will already be using the updated values.
        // We'll lose these in between backend reloads but that can't be helped.
        savedComponentFilters = componentFilters;
      },
    );

    // The renderer interface doesn't read saved component filters directly,
    // because they are generally stored in localStorage within the context of the extension.
    // Because of this it relies on the extension to pass filters.
    // In the case of the standalone DevTools being used with a website,
    // saved filters are injected along with the backend script tag so we shouldn't override them here.
    // This injection strategy doesn't work for React Native though.
    // Ideally the backend would save the filters itself, but RN doesn't provide a sync storage solution.
    // So for now we just fall back to using the default filters...
    if (window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ == null) {
      // $FlowFixMe[incompatible-use] found when upgrading Flow
      bridge.send('overrideComponentFilters', savedComponentFilters);
    }

    // TODO (npm-packages) Warn if "isBackendStorageAPISupported"
    // $FlowFixMe[incompatible-call] found when upgrading Flow
    const agent = new Agent(bridge);
    agent.addListener('shutdown', () => {
      // If we received 'shutdown' from `agent`, we assume the `bridge` is already shutting down,
      // and that caused the 'shutdown' event on the `agent`, so we don't need to call `bridge.shutdown()` here.
      hook.emit('shutdown');
    });

    initBackend(hook, agent, window);

    // Setup React Native style editor if the environment supports it.
    if (resolveRNStyle != null || hook.resolveRNStyle != null) {
      setupNativeStyleEditor(
        // $FlowFixMe[incompatible-call] found when upgrading Flow
        bridge,
        agent,
        ((resolveRNStyle || hook.resolveRNStyle: any): ResolveNativeStyle),
        nativeStyleEditorValidAttributes ||
          hook.nativeStyleEditorValidAttributes ||
          null,
      );
    } else {
      // Otherwise listen to detect if the environment later supports it.
      // For example, Flipper does not eagerly inject these values.
      // Instead it relies on the React Native Inspector to lazily inject them.
      let lazyResolveRNStyle;
      let lazyNativeStyleEditorValidAttributes;

      const initAfterTick = () => {
        if (bridge !== null) {
          setupNativeStyleEditor(
            bridge,
            agent,
            lazyResolveRNStyle,
            lazyNativeStyleEditorValidAttributes,
          );
        }
      };

      if (!hook.hasOwnProperty('resolveRNStyle')) {
        Object.defineProperty(
          hook,
          'resolveRNStyle',
          ({
            enumerable: false,
            get() {
              return lazyResolveRNStyle;
            },
            set(value) {
              lazyResolveRNStyle = value;
              initAfterTick();
            },
          }: Object),
        );
      }
      if (!hook.hasOwnProperty('nativeStyleEditorValidAttributes')) {
        Object.defineProperty(
          hook,
          'nativeStyleEditorValidAttributes',
          ({
            enumerable: false,
            get() {
              return lazyNativeStyleEditorValidAttributes;
            },
            set(value) {
              lazyNativeStyleEditorValidAttributes = value;
              initAfterTick();
            },
          }: Object),
        );
      }
    }
  };

  function handleClose() {
    if (__DEBUG__) {
      debug('WebSocket.onclose');
    }

    if (bridge !== null) {
      bridge.emit('shutdown');
    }

    scheduleRetry();
  }

  function handleFailed() {
    if (__DEBUG__) {
      debug('WebSocket.onerror');
    }

    scheduleRetry();
  }

  function handleMessage(event) {
    let data;
    try {
      if (typeof event.data === 'string') {
        data = JSON.parse(event.data);
        if (__DEBUG__) {
          debug('WebSocket.onmessage', data);
        }
      } else {
        throw Error();
      }
    } catch (e) {
      console.error(
        '[React DevTools] Failed to parse JSON: ' + (event.data: any),
      );
      return;
    }
    messageListeners.forEach(fn => {
      try {
        fn(data);
      } catch (error) {
        // jsc doesn't play so well with tracebacks that go into eval'd code,
        // so the stack trace here will stop at the `eval()` call. Getting the
        // message that caused the error is the best we can do for now.
        console.log('[React DevTools] Error calling listener', data);
        console.log('error:', error);
        throw error;
      }
    });
  }
}
<|endoftext|>


<commit_before>/**
 * Module dependencies
 */
var fs = require('fs-extra'),
	path = require('path'),
	async = require('async'),
	_ = require('lodash'),
	switchback = require('node-switchback');

/**
 * Generate a file using the specified string.
 *
 * @option {String} rootPath
 * @option {String} contents - the string contents to write to disk
 * [@option {Boolean} force=false]
 * [@option {Boolean} dry=false]
 *
 * @sb success
 * @sb error
 * @sb invalid
 * @sb alreadyExists
 */
module.exports = function ( options, sb ) {

	// Provide default values for switchback
	sb = switchback(sb, {
		alreadyExists: sb.error,
		invalid: sb.error
	});

	// Provide defaults and validate required options
	_.defaults(options, {
		force: false
	});
	var missingOpts = _.difference([
		'contents',
		'rootPath'
	], Object.keys(options));
	if ( missingOpts.length ) return sb.invalid(missingOpts);

	// In case we ended up here w/ a relative path,
	// resolve it using the process's CWD
	var rootPath = path.resolve( process.cwd() , options.rootPath );
	// console.log('FileHelper trying to generate:',rootPath);

	// Only override an existing file if `options.force` is true
	fs.exists(rootPath, function (exists) {
		if (exists && !options.force) {
			console.log(rootPath);
			return sb.alreadyExists(rootPath);
		}

		// Don't actually write the file if this is a dry run.
		if (options.dry) return sb.success();

		async.series([
			function deleteExistingFileIfNecessary (cb) {
				if ( !exists ) return cb();
				return fs.remove(rootPath, cb);
			},
			function writeToDisk (cb) {
				fs.outputFile(rootPath, options.contents, cb);
			}
		], function (err) {
			if (err) return sb.error(err);
			else sb.success();
		});

	});

};
<commit_msg>Use proper fs-extra dep.<commit_after>/**
 * Module dependencies
 */
var fs = require('fs-extra'),
	path = require('path'),
	async = require('async'),
	_ = require('lodash'),
	switchback = require('node-switchback');

/**
 * Generate a file using the specified string.
 *
 * @option {String} rootPath
 * @option {String} contents - the string contents to write to disk
 * [@option {Boolean} force=false]
 * [@option {Boolean} dry=false]
 *
 * @sb success
 * @sb error
 * @sb invalid
 * @sb alreadyExists
 */
module.exports = function ( options, sb ) {

	// Provide default values for switchback
	sb = switchback(sb, {
		alreadyExists: sb.error,
		invalid: sb.error
	});

	// Provide defaults and validate required options
	_.defaults(options, {
		force: false
	});
	var missingOpts = _.difference([
		'contents',
		'rootPath'
	], Object.keys(options));
	if ( missingOpts.length ) return sb.invalid(missingOpts);

	// In case we ended up here w/ a relative path,
	// resolve it using the process's CWD
	var rootPath = path.resolve( process.cwd() , options.rootPath );
	// console.log('FileHelper trying to generate:',rootPath);

	// Only override an existing file if `options.force` is true
	fs.exists(rootPath, function (exists) {
		if (exists && !options.force) {
			// console.log(rootPath);
			return sb.alreadyExists(rootPath);
		}

		// Don't actually write the file if this is a dry run.
		if (options.dry) return sb.success();

		async.series([
			function deleteExistingFileIfNecessary (cb) {
				if ( !exists ) return cb();
				return fs.remove(rootPath, cb);
			},
			function writeToDisk (cb) {
				fs.outputFile(rootPath, options.contents, cb);
			}
		], function (err) {
			if (err) return sb.error(err);
			else sb.success();
		});

	});

};
<|endoftext|>


<commit_before>import privateProps from '../privateProps.js'

export function enableButtons () {
  const domCache = privateProps.domCache.get(this)
  domCache.confirmButton.disabled = false
  domCache.cancelButton.disabled = false
}

export function disableButtons () {
  const domCache = privateProps.domCache.get(this)
  domCache.confirmButton.disabled = true
  domCache.cancelButton.disabled = true
}

export function enableConfirmButton () {
  const domCache = privateProps.domCache.get(this)
  domCache.confirmButton.disabled = false
}

export function disableConfirmButton () {
  const domCache = privateProps.domCache.get(this)
  domCache.confirmButton.disabled = true
}

export function enableInput () {
  const input = this.getInput()
  if (!input) {
    return false
  }
  if (input.type === 'radio') {
    const radiosContainer = input.parentNode.parentNode
    const radios = radiosContainer.querySelectorAll('input')
    for (let i = 0; i < radios.length; i++) {
      radios[i].disabled = false
    }
  } else {
    input.disabled = false
  }
}

export function disableInput () {
  const input = this.getInput()
  if (!input) {
    return false
  }
  if (input && input.type === 'radio') {
    const radiosContainer = input.parentNode.parentNode
    const radios = radiosContainer.querySelectorAll('input')
    for (let i = 0; i < radios.length; i++) {
      radios[i].disabled = true
    }
  } else {
    input.disabled = true
  }
}
<commit_msg>chore: implement helpers for enable/disable of buttons and input (#1452)<commit_after>import privateProps from '../privateProps.js'

function setButtonsDisabled (buttons, disabled) {
  buttons.forEach(button => {
    button.disabled = disabled
  })
}

function setInputDisabled (input, disabled) {
  if (!input) {
    return false
  }
  if (input.type === 'radio') {
    const radiosContainer = input.parentNode.parentNode
    const radios = radiosContainer.querySelectorAll('input')
    for (let i = 0; i < radios.length; i++) {
      radios[i].disabled = disabled
    }
  } else {
    input.disabled = disabled
  }
}

export function enableButtons () {
  const domCache = privateProps.domCache.get(this)
  setButtonsDisabled([domCache.confirmButton, domCache.cancelButton], false)
}

export function disableButtons () {
  const domCache = privateProps.domCache.get(this)
  setButtonsDisabled([domCache.confirmButton, domCache.cancelButton], true)
}

export function enableConfirmButton () {
  const domCache = privateProps.domCache.get(this)
  setButtonsDisabled([domCache.confirmButton], false)
}

export function disableConfirmButton () {
  const domCache = privateProps.domCache.get(this)
  setButtonsDisabled([domCache.confirmButton], true)
}

export function enableInput () {
  return setInputDisabled(this.getInput(), false)
}

export function disableInput () {
  return setInputDisabled(this.getInput(), true)
}
<|endoftext|>


<commit_before>/*
	Utility Functions
*/

// Set the width of the side navigation to show
function openNav() {
  $('#mySidenav').css('width', '25%');
}

// Set the width of the side navigation to 0
function closeNav() {
  $('#mySidenav').css('width','0px');
}

function getIDFromPokemonURL(url){
  /*
    Grabs the value between the last two /'s
    (i.e http://pokeapi.co/api/v2/pokemon/1/ => 1)
  */
  // var id = url.replace(/(.*)(pokemon|pokemon\-species)\/(.*)\//, '$3');
  var id = url.replace(/.*\/.*\/(.*?)\//, '$1');
  return id;
}

function showSection(sectionName){
  sectionName = sectionName.trim();

  if ($( "#" + sectionName ).hasClass("hidden")) {
    $('.' + sectionName + ' button').html('–');
    $('#' + sectionName).removeClass("hidden").addClass("expanded");
    $('#' + sectionName).focus();
  }else {
    $('.' + sectionName + ' button').html('+');
    $('#' + sectionName).addClass("hidden").removeClass("expanded");
  }
}

function setAutoComplete(results, searchBox, passedArray) {
  $.each(results, function(index, value){
    var name = value.name;
    passedArray.push(name);
  });
  var options = {
    data        :   passedArray,
    theme       :   'square',
    adjustWidth : false,

    list        :   {
      match          : {
        enabled: true
      },
      onChooseEvent   :   function(){
        console.log('y');
        var pokemonName = $("#" + searchBox).getSelectedItemData();
        // newFunction(pokemonName, passedArray);
        changePage(pokemonName, passedArray);
      }
    }
  }

  $('#' + searchBox).easyAutocomplete(options);

}

function newFunction(pokemonName, passedArray) {
  showSearch();
}

function changePage(pokemonID, passedArray) {
  console.log(pokemonID);
  if (pokemonID !== null) {
    pokemonID = pokemonID.toLowerCase();
    //make sure that pokemon name exists
    if(passedArray.indexOf(pokemonID) > -1){
      console.log('x');
      loadOverlay(pokemonID);
      // window.location = "./" + pokemonID;
    }
  };
};

function showSearch(){
  if ($( "#searchContainer" ).hasClass("hidden")) {
    $('#searchContainer').removeClass("hidden");
    $('#pokemonSearchBox').focus();
  }else {
    $('#searchContainer').addClass("hidden");
  }
}

// Call Page Change Animation
function loadOverlay(pokemonID){
  // alert('load overlay');
  $('#loadingAnimation').removeClass('hidden');
  console.log('loading new page...');
  $('#searchContainer').addClass('hidden');
  $('#loadingDiv').removeClass('hidden');
  window.location = "./" + pokemonID;
  // $('#loadingAnimation').removeClass('hidden');
}

function getQS(object){
  /*
  Query string values get returned back to the object
  Use object.key|object[key] //returns value
  */
  var pl     = /\+/g;  // Regex for replacing addition symbol with a space
  var search = /([^&=]+)=?([^&]*)/g;
  var decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); };
  var query  = window.location.search.substring(1);
  var match;

  while (match = search.exec(query)){
    object[decode(match[1])] = decode(match[2]);
  }
}
<commit_msg>changing to key enter event<commit_after>/*
	Utility Functions
*/

// Set the width of the side navigation to show
function openNav() {
  $('#mySidenav').css('width', '25%');
}

// Set the width of the side navigation to 0
function closeNav() {
  $('#mySidenav').css('width','0px');
}

function getIDFromPokemonURL(url){
  /*
    Grabs the value between the last two /'s
    (i.e http://pokeapi.co/api/v2/pokemon/1/ => 1)
  */
  // var id = url.replace(/(.*)(pokemon|pokemon\-species)\/(.*)\//, '$3');
  var id = url.replace(/.*\/.*\/(.*?)\//, '$1');
  return id;
}

function showSection(sectionName){
  sectionName = sectionName.trim();

  if ($( "#" + sectionName ).hasClass("hidden")) {
    $('.' + sectionName + ' button').html('–');
    $('#' + sectionName).removeClass("hidden").addClass("expanded");
    $('#' + sectionName).focus();
  }else {
    $('.' + sectionName + ' button').html('+');
    $('#' + sectionName).addClass("hidden").removeClass("expanded");
  }
}

function setAutoComplete(results, searchBox, passedArray) {
  $.each(results, function(index, value){
    var name = value.name;
    passedArray.push(name);
  });
  var options = {
    data        :   passedArray,
    theme       :   'square',
    adjustWidth : false,

    list        :   {
      match          : {
        enabled: true
      },
      onChooseEvent   :   function(){
        // console.log('y');
        // var pokemonName = $("#" + searchBox).getSelectedItemData();
        // // newFunction(pokemonName, passedArray);
        // changePage(pokemonName, passedArray);
      },
      onKeyEnterEvent : function(){
        console.log('y');
        var pokemonName = $("#" + searchBox).getSelectedItemData();
        // newFunction(pokemonName, passedArray);
        changePage(pokemonName, passedArray);
      }
    }
  }

  $('#' + searchBox).easyAutocomplete(options);

}

function newFunction(pokemonName, passedArray) {
  showSearch();
}

function changePage(pokemonID, passedArray) {
  console.log(pokemonID);
  if (pokemonID !== null) {
    pokemonID = pokemonID.toLowerCase();
    //make sure that pokemon name exists
    if(passedArray.indexOf(pokemonID) > -1){
      console.log('x');
      loadOverlay(pokemonID);
      // window.location = "./" + pokemonID;
    }
  };
};

function showSearch(){
  if ($( "#searchContainer" ).hasClass("hidden")) {
    $('#searchContainer').removeClass("hidden");
    $('#pokemonSearchBox').focus();
  }else {
    $('#searchContainer').addClass("hidden");
  }
}

// Call Page Change Animation
function loadOverlay(pokemonID){
  // alert('load overlay');
  $('#loadingAnimation').removeClass('hidden');
  console.log('loading new page...');
  $('#searchContainer').addClass('hidden');
  $('#loadingDiv').removeClass('hidden');
  window.location = "./" + pokemonID;
  // $('#loadingAnimation').removeClass('hidden');
}

function getQS(object){
  /*
  Query string values get returned back to the object
  Use object.key|object[key] //returns value
  */
  var pl     = /\+/g;  // Regex for replacing addition symbol with a space
  var search = /([^&=]+)=?([^&]*)/g;
  var decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); };
  var query  = window.location.search.substring(1);
  var match;

  while (match = search.exec(query)){
    object[decode(match[1])] = decode(match[2]);
  }
}
<|endoftext|>


<commit_before>/*
 * Licensed to Apereo under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Apereo licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file
 * except in compliance with the License.  You may obtain a
 * copy of the License at the following location:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
define(['angular'], function(angular) {
  return angular.module('override', [])
        .constant('OVERRIDE', {
          'APP_FLAGS': {
            'enableToggle': true,
            'defaultView': 'expanded',
            'compact': true,
            'expanded': true,
            'isWeb': true,
            'defaultTheme': 'group',
            'debug': true,
            'showUserSettingsPage': true,
          },
          'APP_OPTIONS': {
            'appMenuTemplateURL':
              '/web/my-app/menu/partials/app-menu-template.html',
          },
          'SERVICE_LOC': {
            'aboutURL': '/portal/api/session.json',
            'sessionInfo': '/portal/api/session.json',
            'sidebarInfo': '/web/staticFeeds/sidebar.json',
            'newstuffInfo': '/web/staticFeeds/new-stuff.json',
            'context': '/portal/',
            'base': '/portal/api/',
            'layout': 'api/layoutDoc?tab=UW Bucky Home',
            'layoutTab': 'UW Bucky Home',
            'marketplace': {
                'base': 'marketplace/',
                'entry': 'entry/',
                'entries': 'entries.json',
            },
            'messagesURL': '/web/staticFeeds/messages.json',
            'groupURL': '/portal/api/groups',
            'kvURL': '/storage',
            'loginSilentURL': '/portal/Login?silent=true&profile=bucky',
          },
          'MESSAGES': {
            'notificationsPageURL': '/web/notifications',
          },
          'NAMES': {
              'title': 'MyUW',
              'ariaLabelTitle': 'My U W',
              'crest': 'img/uwcrest_web_sm.png',
              'crestalt': 'UW Crest',
              'sublogo': '',
              'guestUserName': 'guest',
          },
          'MISC_URLS': {
            'feedbackURL': '/portal/p/feedback',
            'whatsNewURL': 'https://kb.wisc.edu/myuw/page.php?id=48181',
          },
          'APP_BETA_FEATURES': [
            {
              'id': 'webPortletRender',
              'title': '/web portlet rendering',
              'description': 'Renders portlets via /web\'s exclusive page, ' +
                  'but not as launched from expanded widgets.',
            },
            {
              'id': 'showKeywordsInMarketplace',
              'title': 'Show Keywords in app directory',
              'description': 'Enable/Disable keywords showing up in app ' +
                  'directory details',
            },
            {
              'id': 'linkRatingsApi',
              'title': 'Link ratings API',
              'description': 'Links the ratings JSON API from the ratings ' +
                  'count in the details page for each app. Actual access to ' +
                  'this JSON API depends upon MANAGE permissions; this ' +
                  'setting just includes the hyperlink in the UI for ' +
                  'convenience.',
            },
            {
              'id': 'exampleWidgets',
              'title': 'Example Widgets',
              'description': 'Show the My Courses, Email, and Calendar ' +
                  'example widgets',
            },
            {
              'id': 'showFilterOption',
              'title': 'Show Filter Option on Home',
              'description': 'Enables a filter on home to filter ones ' +
                  'content down to what want',
            },
          ],
        });
});
<commit_msg>fix: keep override in sync with overlay<commit_after>/*
 * Licensed to Apereo under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Apereo licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file
 * except in compliance with the License.  You may obtain a
 * copy of the License at the following location:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
define(['angular'], function(angular) {
  return angular.module('override', [])
        .constant('OVERRIDE', {
          'APP_FLAGS': {
            'enableToggle': true,
            'defaultView': 'expanded',
            'compact': true,
            'expanded': true,
            'isWeb': true,
            'defaultTheme': 'group',
            'debug': true,
            'showUserSettingsPage': true,
          },
          'APP_OPTIONS': {
            'appMenuTemplateURL':
              '/web/my-app/menu/partials/app-menu-template.html',
          },
          'SERVICE_LOC': {
            'aboutURL': '/portal/api/session.json',
            'aboutPageURL': '/web/staticFeeds/about-page.json',
            'sessionInfo': '/portal/api/session.json',
            'sidebarInfo': '/web/staticFeeds/sidebar.json',
            'newstuffInfo': '/web/staticFeeds/new-stuff.json',
            'context': '/portal/',
            'base': '/portal/api/',
            'layout': 'api/layoutDoc?tab=UW Bucky Home',
            'layoutTab': 'UW Bucky Home',
            'marketplace': {
                'base': 'marketplace/',
                'entry': 'entry/',
                'entries': 'entries.json',
            },
            'messagesURL': '/web/staticFeeds/messages.json',
            'groupURL': '/portal/api/groups',
            'kvURL': '/storage',
            'loginSilentURL': '/portal/Login?silent=true&profile=bucky',
          },
          'MESSAGES': {
            'notificationsPageURL': '/web/notifications',
          },
          'NAMES': {
              'title': 'MyUW',
              'ariaLabelTitle': 'My U W',
              'crest': 'img/uwcrest_web_sm.png',
              'crestalt': 'UW Crest',
              'sublogo': '',
              'guestUserName': 'guest',
          },
          'MISC_URLS': {
            'feedbackURL': '/portal/p/feedback',
            'whatsNewURL': 'https://kb.wisc.edu/myuw/page.php?id=48181',
          },
          'APP_BETA_FEATURES': [
            {
              'id': 'webPortletRender',
              'title': '/web portlet rendering',
              'description': 'Renders portlets via /web\'s exclusive page, ' +
                  'but not as launched from expanded widgets.',
            },
            {
              'id': 'showKeywordsInMarketplace',
              'title': 'Show Keywords in app directory',
              'description': 'Enable/Disable keywords showing up in app ' +
                  'directory details',
            },
            {
              'id': 'linkRatingsApi',
              'title': 'Link ratings API',
              'description': 'Links the ratings JSON API from the ratings ' +
                  'count in the details page for each app. Actual access to ' +
                  'this JSON API depends upon MANAGE permissions; this ' +
                  'setting just includes the hyperlink in the UI for ' +
                  'convenience.',
            },
            {
              'id': 'exampleWidgets',
              'title': 'Example Widgets',
              'description': 'Show the My Courses, Email, and Calendar ' +
                  'example widgets',
            },
            {
              'id': 'showFilterOption',
              'title': 'Show Filter Option on Home',
              'description': 'Enables a filter on home to filter ones ' +
                  'content down to what want',
            },
          ],
        });
});
<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc overview
 * @name ratemycoopApp
 * @description
 * # ratemycoopApp
 *
 * Main module of the application.
 */
angular
  .module('ratemycoopApp', [
    'ngAnimate',
    'ngCookies',
    'ngResource',
    'ngRoute',
    'ngSanitize',
    'ngTouch',
    'angular.filter',
    'lbServices',
    'mgo-angular-wizard',
    'btford.markdown',
    'angularMoment'
  ])
  .config(['$routeProvider', '$locationProvider', 'LoopBackResourceProvider', '$httpProvider', function ($routeProvider, $locationProvider, LoopBackResourceProvider, $httpProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
      })
      .when('/about', {
        templateUrl: 'views/about.html',
        controller: 'AboutCtrl'
      })
      .when('/company/:companyname', {
        templateUrl: 'views/company.html',
        controller: 'CompanyCtrl'
      })
      .when('/company/:companyname/review', {
        templateUrl: 'views/reviewform.html',
        controller: 'ReviewformCtrl'
      })
      .when('/privacy', {
        templateUrl: 'views/privacy.html',
        controller: 'PrivacyCtrl'
      })
      .when('/login', {
        templateUrl: 'views/login.html',
        controller: 'StandaloneLoginCtrl'
      })
      .when('/login/:redirect_url', {
        templateUrl: 'views/login.html',
        controller: 'StandaloneLoginCtrl'
      })
      .otherwise({
        redirectTo: '/404',
        templateUrl: '/404.html'
      });

    //$locationProvider.html5Mode({ enabled: true, requireBase: false });

    // Set url base
    //LoopBackResourceProvider.setUrlBase('https://ratemycoop.io/api/v1');
    LoopBackResourceProvider.setUrlBase('http://localhost:3000/api/v1');

    /**
     * Set http interceptor for 40x unauthorized
     */

    $httpProvider.interceptors.push(function ($q, $location) {
      return {
        responseError: function (rejection) {
          if (rejection.status == 401) {
            //TODO: Redirect to login page
          }
          return $q.reject(rejection);
        }
      };
    });
  }]);
<commit_msg>- retreieved app.js for api<commit_after>'use strict';

/**
 * @ngdoc overview
 * @name ratemycoopApp
 * @description
 * # ratemycoopApp
 *
 * Main module of the application.
 */
angular
  .module('ratemycoopApp', [
    'ngAnimate',
    'ngCookies',
    'ngResource',
    'ngRoute',
    'ngSanitize',
    'ngTouch',
    'angular.filter',
    'lbServices',
    'mgo-angular-wizard',
    'btford.markdown',
    'angularMoment'
  ])
  .config(['$routeProvider', '$locationProvider', 'LoopBackResourceProvider', '$httpProvider', function ($routeProvider, $locationProvider, LoopBackResourceProvider, $httpProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
      })
      .when('/about', {
        templateUrl: 'views/about.html',
        controller: 'AboutCtrl'
      })
      .when('/company/:companyname', {
        templateUrl: 'views/company.html',
        controller: 'CompanyCtrl'
      })
      .when('/company/:companyname/review', {
        templateUrl: 'views/reviewform.html',
        controller: 'ReviewformCtrl'
      })
      .when('/privacy', {
        templateUrl: 'views/privacy.html',
        controller: 'PrivacyCtrl'
      })
      .when('/login', {
        templateUrl: 'views/login.html',
        controller: 'StandaloneLoginCtrl'
      })
      .when('/login/:redirect_url', {
        templateUrl: 'views/login.html',
        controller: 'StandaloneLoginCtrl'
      })
      .otherwise({
        redirectTo: '/404',
        templateUrl: '/404.html'
      });

    //$locationProvider.html5Mode({ enabled: true, requireBase: false });

    // Set url base
    LoopBackResourceProvider.setUrlBase('https://ratemycoop.io/api/v1');

    /**
     * Set http interceptor for 40x unauthorized
     */

    $httpProvider.interceptors.push(function ($q, $location) {
      return {
        responseError: function (rejection) {
          if (rejection.status == 401) {
            //TODO: Redirect to login page
          }
          return $q.reject(rejection);
        }
      };
    });
  }]);
<|endoftext|>


<commit_before>import Domify from 'react-domify';
import React from 'react';
import Markdown from 'react-markdown';

const Row = (props) => {
	const styles = {
		display: 'flex',
		flexWrap: 'wrap',
		marginLeft: -10,
		marginRight: -10,
		...props.style,
	};

	return (

	);
};

const Col = (props) => {
	const styles = {
		flex: props.width ? null : '1 1 0',
		minHeight: 1,
		paddingLeft: 10,
		paddingRight: 10,
		width: props.width || '100%',
		...props.style,
	};

	return (

	);
};

const ExplorerFieldType = React.createClass({
	getInitialState () {
		return {
			readmeIsVisible: !!this.props.readme,
			filter: this.props.FilterComponent.getDefaultValue(),
			value: this.props.value,
		};
	},
	componentWillReceiveProps (newProps) {
		if (this.props.params.type === newProps.params.type) return;

		this.setState({
			filter: newProps.FilterComponent.getDefaultValue(),
			readmeIsVisible: newProps.readme
				? this.state.readmeIsVisible
				: false,
			value: newProps.value,
		});
	},
	onFieldChange (e) {
		var logValue = typeof e.value === 'string' ? `"${e.value}"` : e.value;
		console.log(`${this.props.params.type} field value changed:`, logValue);
		this.setState({
			value: e.value,
		});
	},
	onFilterChange (value) {
		console.log(`${this.props.params.type} filter value changed:`, value);
		this.setState({
			filter: value,
		});
	},
	renderSpecs () {
		const { FieldComponent, FilterComponent } = this.props;
		const { readmeIsVisible } = this.state;
		const specs = Array.isArray(this.props.spec) ? this.props.spec : [this.props.spec];

		return specs.map((spec, i) => {
			return (

						<Row>
							<Col width={readmeIsVisible ? 300 : null} style={{ minWidth: 300, maxWidth: 640 }}>
								<FieldComponent
									{...spec}
									onChange={this.onFieldChange}
									value={this.state.value}
								/>
							</Col>
							<Col>

									<Domify
										className="Domify"
										value={{ value: this.state.value }}
									/>

							</Col>
						</Row>

Filter

						<Row>
							<Col width={300}>
								<FilterComponent
									field={spec}
									filter={this.state.filter}
									onChange={this.onFilterChange}
								/>
							</Col>
							<Col>

									<Domify
										className="Domify"
										value={this.state.filter}
									/>

							</Col>
						</Row>

			);
		});
	},
	render () {
		const { readme, toggleSidebar } = this.props;
		const { readmeIsVisible } = this.state;

		// const spec = Array.isArray(this.props.spec) ? this.props.spec : [this.props.spec];
		const spec = this.props.spec;

		return (

						<button
							className="fx-page__header__button fx-page__header__button--sidebar mega-octicon octicon-three-bars"
							onClick={toggleSidebar}
							type="button"
						/>
						{spec.label}

					{!!readme && (
						<button
							className="fx-page__header__button fx-page__header__button--readme mega-octicon octicon-file-text"
							onClick={() => this.setState({ readmeIsVisible: !readmeIsVisible })}
							title={readmeIsVisible ? 'Hide Readme' : 'Show Readme'}
							type="button"
						/>
					)}

					<Row>
						<Col>

								{this.renderSpecs()}

						</Col>
						{!!readmeIsVisible && (
							<Col width={380}>
								<Markdown
									className="Markdown"
									source={readme}
								/>
							</Col>
						)}
					</Row>

		);
	},
});

module.exports = ExplorerFieldType;
<commit_msg>Fixing inline () => in ExplorerField props<commit_after>import Domify from 'react-domify';
import React from 'react';
import Markdown from 'react-markdown';

const Row = (props) => {
	const styles = {
		display: 'flex',
		flexWrap: 'wrap',
		marginLeft: -10,
		marginRight: -10,
		...props.style,
	};

	return (

	);
};

const Col = (props) => {
	const styles = {
		flex: props.width ? null : '1 1 0',
		minHeight: 1,
		paddingLeft: 10,
		paddingRight: 10,
		width: props.width || '100%',
		...props.style,
	};

	return (

	);
};

const ExplorerFieldType = React.createClass({
	getInitialState () {
		return {
			readmeIsVisible: !!this.props.readme,
			filter: this.props.FilterComponent.getDefaultValue(),
			value: this.props.value,
		};
	},
	componentWillReceiveProps (newProps) {
		if (this.props.params.type === newProps.params.type) return;

		this.setState({
			filter: newProps.FilterComponent.getDefaultValue(),
			readmeIsVisible: newProps.readme
				? this.state.readmeIsVisible
				: false,
			value: newProps.value,
		});
	},
	onFieldChange (e) {
		var logValue = typeof e.value === 'string' ? `"${e.value}"` : e.value;
		console.log(`${this.props.params.type} field value changed:`, logValue);
		this.setState({
			value: e.value,
		});
	},
	onFilterChange (value) {
		console.log(`${this.props.params.type} filter value changed:`, value);
		this.setState({
			filter: value,
		});
	},
	toggleReadme () {
		this.setState({ readmeIsVisible: !this.state.readmeIsVisible });
	},
	renderSpecs () {
		const { FieldComponent, FilterComponent } = this.props;
		const { readmeIsVisible } = this.state;
		const specs = Array.isArray(this.props.spec) ? this.props.spec : [this.props.spec];

		return specs.map((spec, i) => {
			return (

						<Row>
							<Col width={readmeIsVisible ? 300 : null} style={{ minWidth: 300, maxWidth: 640 }}>
								<FieldComponent
									{...spec}
									onChange={this.onFieldChange}
									value={this.state.value}
								/>
							</Col>
							<Col>

									<Domify
										className="Domify"
										value={{ value: this.state.value }}
									/>

							</Col>
						</Row>

Filter

						<Row>
							<Col width={300}>
								<FilterComponent
									field={spec}
									filter={this.state.filter}
									onChange={this.onFilterChange}
								/>
							</Col>
							<Col>

									<Domify
										className="Domify"
										value={this.state.filter}
									/>

							</Col>
						</Row>

			);
		});
	},
	render () {
		const { readme, toggleSidebar } = this.props;
		const { readmeIsVisible } = this.state;

		// const spec = Array.isArray(this.props.spec) ? this.props.spec : [this.props.spec];
		const spec = this.props.spec;

		return (

						<button
							className="fx-page__header__button fx-page__header__button--sidebar mega-octicon octicon-three-bars"
							onClick={toggleSidebar}
							type="button"
						/>
						{spec.label}

					{!!readme && (
						<button
							className="fx-page__header__button fx-page__header__button--readme mega-octicon octicon-file-text"
							onClick={this.toggleReadme}
							title={readmeIsVisible ? 'Hide Readme' : 'Show Readme'}
							type="button"
						/>
					)}

					<Row>
						<Col>

								{this.renderSpecs()}

						</Col>
						{!!readmeIsVisible && (
							<Col width={380}>
								<Markdown
									className="Markdown"
									source={readme}
								/>
							</Col>
						)}
					</Row>

		);
	},
});

module.exports = ExplorerFieldType;
<|endoftext|>


<commit_before>
// REQUEST HANDLING //////////////////////////////////////////////////
// note: only meant for portal/links/fields request, everything else
// does not count towards “loading”

window.activeRequests = [];
window.failedRequestCount = 0;

window.requests = function() {}

window.requests.add = function(ajax) {
  window.activeRequests.push(ajax);
  renderUpdateStatus();
}

window.requests.remove = function(ajax) {
  window.activeRequests.splice(window.activeRequests.indexOf(ajax), 1);
  renderUpdateStatus();
}

window.requests.abort = function() {
  $.each(window.activeRequests, function(ind, actReq) {
    if(actReq) actReq.abort();
  });
  window.activeRequests = [];
  window.failedRequestCount = 0;

  startRefreshTimeout();
  renderUpdateStatus();
}

// gives user feedback about pending operations. Draws current status
// to website.
window.renderUpdateStatus = function() {
  var t = 'map status: ';
  if(mapRunsUserAction)
    t += 'paused during interaction';
  else if(isIdle())
    t += 'Idle, not updating.';
  else if(window.activeRequests.length > 0)
    t += window.activeRequests.length + ' requests running';
  else
    t += 'Up to date.';

  if(window.failedRequestCount > 0)
    t += ' ' + window.failedRequestCount + ' requests  failed.'

  $('#updatestatus').html(t);
}
<commit_msg>display which portals are being requested<commit_after>
// REQUEST HANDLING //////////////////////////////////////////////////
// note: only meant for portal/links/fields request, everything else
// does not count towards “loading”

window.activeRequests = [];
window.failedRequestCount = 0;

window.requests = function() {}

window.requests.add = function(ajax) {
  window.activeRequests.push(ajax);
  renderUpdateStatus();
}

window.requests.remove = function(ajax) {
  window.activeRequests.splice(window.activeRequests.indexOf(ajax), 1);
  renderUpdateStatus();
}

window.requests.abort = function() {
  $.each(window.activeRequests, function(ind, actReq) {
    if(actReq) actReq.abort();
  });
  window.activeRequests = [];
  window.failedRequestCount = 0;

  startRefreshTimeout();
  renderUpdateStatus();
}

// gives user feedback about pending operations. Draws current status
// to website.
window.renderUpdateStatus = function() {
  var t = 'map status: ';
  if(mapRunsUserAction)
    t += 'paused during interaction';
  else if(isIdle())
    t += 'Idle, not updating.';
  else if(window.activeRequests.length > 0)
    t += window.activeRequests.length + ' requests running';
  else
    t += 'Up to date.';

  if(window.failedRequestCount > 0)
    t += ' ' + window.failedRequestCount + ' requests  failed.'

  t += '
(';
  var conv = ['impossible', 8,8,7,7,6,6,5,5,4,4,3,3,2,2,1];
  var z = map.getZoom();
  if(z >= 16)
    t += 'requesting all portals';
  else
    t+= 'only requesting portals with level '+conv[z]+' and up';
  t += ')';

  $('#updatestatus').html(t);
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2014, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * https://raw.github.com/facebook/regenerator/master/LICENSE file. An
 * additional grant of patent rights can be found in the PATENTS file in
 * the same directory.
 */

import * as t from "babel-types";
let hasOwn = Object.prototype.hasOwnProperty;

// The hoist function takes a FunctionExpression or FunctionDeclaration
// and replaces any Declaration nodes in its body with assignments, then
// returns a VariableDeclaration containing just the names of the removed
// declarations.
exports.hoist = function(funPath) {
  t.assertFunction(funPath.node);

  let vars = {};

  function varDeclToExpr(vdec, includeIdentifiers) {
    t.assertVariableDeclaration(vdec);
    // TODO assert.equal(vdec.kind, "var");
    let exprs = [];

    vdec.declarations.forEach(function(dec) {
      vars[dec.id.name] = dec.id;

      if (dec.init) {
        exprs.push(t.assignmentExpression(
          "=", dec.id, dec.init
        ));
      } else if (includeIdentifiers) {
        exprs.push(dec.id);
      }
    });

    if (exprs.length === 0)
      return null;

    if (exprs.length === 1)
      return exprs[0];

    return t.sequenceExpression(exprs);
  }

  funPath.get("body").traverse({
    VariableDeclaration: {
      exit: function(path) {
        let expr = varDeclToExpr(path.node, false);
        if (expr === null) {
          path.remove();
        } else {
          // We don't need to traverse this expression any further because
          // there can't be any new declarations inside an expression.
          path.replaceWith(t.expressionStatement(expr));
        }

        // Since the original node has been either removed or replaced,
        // avoid traversing it any further.
        path.skip();
      }
    },

    ForStatement: function(path) {
      let init = path.node.init;
      if (t.isVariableDeclaration(init)) {
        path.get("init").replaceWith(varDeclToExpr(init, false));
      }
    },

    ForXStatement: function(path) {
      let left = path.get("left");
      if (left.isVariableDeclaration()) {
        left.replaceWith(varDeclToExpr(left.node, true));
      }
    },

    FunctionDeclaration: function(path) {
      let node = path.node;
      vars[node.id.name] = node.id;

      let assignment = t.expressionStatement(
        t.assignmentExpression(
          "=",
          node.id,
          t.functionExpression(
            node.id,
            node.params,
            node.body,
            node.generator,
            node.expression
          )
        )
      );

      if (path.parentPath.isBlockStatement()) {
        // Insert the assignment form before the first statement in the
        // enclosing block.
        path.parentPath.unshiftContainer("body", assignment);

        // Remove the function declaration now that we've inserted the
        // equivalent assignment form at the beginning of the block.
        path.remove();
      } else {
        // If the parent node is not a block statement, then we can just
        // replace the declaration with the equivalent assignment form
        // without worrying about hoisting it.
        path.replaceWith(assignment);
      }

      // Don't hoist variables out of inner functions.
      path.skip();
    },

    FunctionExpression: function(path) {
      // Don't descend into nested function expressions.
      path.skip();
    }
  });

  let paramNames = {};
  funPath.get("params").forEach(function(paramPath) {
    let param = paramPath.node;
    if (t.isIdentifier(param)) {
      paramNames[param.name] = param;
    } else {
      // Variables declared by destructuring parameter patterns will be
      // harmlessly re-declared.
    }
  });

  let declarations = [];

  Object.keys(vars).forEach(function(name) {
    if (!hasOwn.call(paramNames, name)) {
      declarations.push(t.variableDeclarator(vars[name], null));
    }
  });

  if (declarations.length === 0) {
    return null; // Be sure to handle this case!
  }

  return t.variableDeclaration("var", declarations);
};
<commit_msg>Borrow recent changes from babel-plugin-transform-regenerator.<commit_after>/**
 * Copyright (c) 2014, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * https://raw.github.com/facebook/regenerator/master/LICENSE file. An
 * additional grant of patent rights can be found in the PATENTS file in
 * the same directory.
 */

import * as t from "babel-types";
let hasOwn = Object.prototype.hasOwnProperty;

// The hoist function takes a FunctionExpression or FunctionDeclaration
// and replaces any Declaration nodes in its body with assignments, then
// returns a VariableDeclaration containing just the names of the removed
// declarations.
exports.hoist = function(funPath) {
  t.assertFunction(funPath.node);

  let vars = {};

  function varDeclToExpr(vdec, includeIdentifiers) {
    t.assertVariableDeclaration(vdec);
    // TODO assert.equal(vdec.kind, "var");
    let exprs = [];

    vdec.declarations.forEach(function(dec) {
      // Note: We duplicate 'dec.id' here to ensure that the variable declaration IDs don't
      // have the same 'loc' value, since that can make sourcemaps and retainLines behave poorly.
      vars[dec.id.name] = t.identifier(dec.id.name);

      if (dec.init) {
        exprs.push(t.assignmentExpression(
          "=", dec.id, dec.init
        ));
      } else if (includeIdentifiers) {
        exprs.push(dec.id);
      }
    });

    if (exprs.length === 0)
      return null;

    if (exprs.length === 1)
      return exprs[0];

    return t.sequenceExpression(exprs);
  }

  funPath.get("body").traverse({
    VariableDeclaration: {
      exit: function(path) {
        let expr = varDeclToExpr(path.node, false);
        if (expr === null) {
          path.remove();
        } else {
          // We don't need to traverse this expression any further because
          // there can't be any new declarations inside an expression.
          path.replaceWith(t.expressionStatement(expr));
        }

        // Since the original node has been either removed or replaced,
        // avoid traversing it any further.
        path.skip();
      }
    },

    ForStatement: function(path) {
      let init = path.node.init;
      if (t.isVariableDeclaration(init)) {
        path.get("init").replaceWith(varDeclToExpr(init, false));
      }
    },

    ForXStatement: function(path) {
      let left = path.get("left");
      if (left.isVariableDeclaration()) {
        left.replaceWith(varDeclToExpr(left.node, true));
      }
    },

    FunctionDeclaration: function(path) {
      let node = path.node;
      vars[node.id.name] = node.id;

      let assignment = t.expressionStatement(
        t.assignmentExpression(
          "=",
          node.id,
          t.functionExpression(
            node.id,
            node.params,
            node.body,
            node.generator,
            node.expression
          )
        )
      );

      if (path.parentPath.isBlockStatement()) {
        // Insert the assignment form before the first statement in the
        // enclosing block.
        path.parentPath.unshiftContainer("body", assignment);

        // Remove the function declaration now that we've inserted the
        // equivalent assignment form at the beginning of the block.
        path.remove();
      } else {
        // If the parent node is not a block statement, then we can just
        // replace the declaration with the equivalent assignment form
        // without worrying about hoisting it.
        path.replaceWith(assignment);
      }

      // Don't hoist variables out of inner functions.
      path.skip();
    },

    FunctionExpression: function(path) {
      // Don't descend into nested function expressions.
      path.skip();
    }
  });

  let paramNames = {};
  funPath.get("params").forEach(function(paramPath) {
    let param = paramPath.node;
    if (t.isIdentifier(param)) {
      paramNames[param.name] = param;
    } else {
      // Variables declared by destructuring parameter patterns will be
      // harmlessly re-declared.
    }
  });

  let declarations = [];

  Object.keys(vars).forEach(function(name) {
    if (!hasOwn.call(paramNames, name)) {
      declarations.push(t.variableDeclarator(vars[name], null));
    }
  });

  if (declarations.length === 0) {
    return null; // Be sure to handle this case!
  }

  return t.variableDeclaration("var", declarations);
};
<|endoftext|>


<commit_before>/* ===================================================
 * JavaScript 2ch-client Library
 * https://github.com/sh19910711/js2ch
 * ===================================================
 * Copyright (c) 2013 Hiroyuki Sano
 *
 * Licensed under MIT License.
 * http://opensource.org/licenses/MIT
 * =================================================== */
(function() {
  'use strict';

  define([
    'underscore',
    'encoding',
    'logger'
  ], function(_, encoding, logger) {
    var BufferLib = function() {};

    BufferLib.prototype = {};
    var proto = _(BufferLib.prototype);

    proto.extend({
      // 文字列をArrayBufferに変換する
      convertToString: function convertToString(buf_array, callback) {
        var fileReader = new FileReader();
        fileReader.onloadend = function() {
          callback(fileReader.result);
        };
        fileReader.readAsText(new Blob([new Uint8Array(buf_array)]), 'sjis');
      }
    });

    proto.extend({
      // 文字列をArrayBufferに変換する
      convertToBuffer: function convertToBuffer(str, callback) {
        var fileReader = new FileReader();
        fileReader.onloadend = function() {
          callback(fileReader.result);
        };
        fileReader.readAsArrayBuffer(new Blob([str]));
      }
    });

    proto.extend({
      // 文字列のバイト数を求める
      getByteLength: function getByteLength(str, callback) {
        setTimeout(function() {
          callback(new Blob([str])
            .size);
        }, 0);
      }
    });

    return new BufferLib();
  });

})
  .call(this);
<commit_msg>Add jsdoc comments to buffer-lib-chrome<commit_after>/* ===================================================
 * JavaScript 2ch-client Library
 * https://github.com/sh19910711/js2ch
 * ===================================================
 * Copyright (c) 2013 Hiroyuki Sano
 *
 * Licensed under MIT License.
 * http://opensource.org/licenses/MIT
 * =================================================== */
/**
 * @fileOverview Chrome用のバッファ操作ライブラリ
 * @author Hiroyuki Sano
 **/
(function() {
  'use strict';

  define([
    'underscore',
    'encoding',
    'logger'
  ], function(_, encoding, logger) {
    /**
     * @class BufferLib
     */

    /**
     * @constructor
     */
    var BufferLib = function() {};

    BufferLib.prototype = {};
    var proto = _(BufferLib.prototype);

    proto.extend({
      /**
       * @description ArrayBufferを文字列に変換する
       * @memberof BufferLib
       *
       * @param {ArrayBuffer} buf_array
       * 文字列に変換するArrayBuffer
       * @param {Function} callback
       * コールバック関数。処理完了後 callback(String) として呼び出される。
       */
      convertToString: function convertToString(buf_array, callback) {
        var fileReader = new FileReader();
        fileReader.onloadend = function() {
          callback(fileReader.result);
        };
        fileReader.readAsText(new Blob([new Uint8Array(buf_array)]), 'sjis');
      }
    });

    proto.extend({
      /**
       * @description 文字列をArrayBufferに変換する
       * @memberof BufferLib
       *
       * @param {String} str
       * ArrayBufferに変換する文字列
       * @param {Function} callback
       * 処理完了後 callback(ArrayBuffer) として呼び出される。
       */
      convertToBuffer: function convertToBuffer(str, callback) {
        var fileReader = new FileReader();
        fileReader.onloadend = function() {
          callback(fileReader.result);
        };
        fileReader.readAsArrayBuffer(new Blob([str]));
      }
    });

    proto.extend({
      // 文字列のバイト数を求める
      /**
       * @description 文字列のバイト数を求める
       * @memberof BufferLib
       *
       * @param {String} str
       * バイト数を求めたい文字列
       * @param {Function} callback
       * 処理完了後 callback(Number) として呼び出される
       */
      getByteLength: function getByteLength(str, callback) {
        setTimeout(function() {
          callback(new Blob([str])
            .size);
        }, 0);
      }
    });

    return new BufferLib();
  });

})
  .call(this);
<|endoftext|>


<commit_before>/* global: $ */
/* jshint multistr: true */
var SEVERITY = {
    SUCCESS: 0,
    INFO: 1,
    WARNING: 2,
    ERROR: 3
};

// stores whatever the last message is
var lastMessage;

(function() {
    'use strict';

    /**
     * @ngdoc overview
     * @name notification
     */

    angular.module('zenNotify', []).

    /**
     * @ngdoc object
     * @name zenNotify.Notification
     * @requires $templateCache
     */

     factory('$notification', ['$rootScope', '$templateCache', '$translate', function ($rootScope, $templateCache, $translate) {
        var notificationFactory;

        var notificationTemplate = '
\
            \
            \
            \
            <button type="button" class="close" aria-hidden="true" style="display:none;">×</button>\

';

        /**
         * Notification
         * Creates a notification. Great for parties!
         */
        function Notification(id, title, msg, $attachPoint){
            this.id = id;
            this.$el = $(notificationTemplate);
            this.$message = this.$el.find(".message");
            this.$title = this.$el.find(".title");
            this.title = title;
            this.msg = msg;
            this.$attachPoint = $attachPoint;
            this.severity = SEVERITY.INFO;

            this.updateTitle(this.title || "");
            this.updateStatus(this.msg || "");

            // bind onClose context so it doesn't have
            // to be rebound for each event listener
            this.onClose = this.onClose.bind(this);
            this.hide = this.hide.bind(this);
        }

        Notification.prototype = {
            constructor: Notification,

            success: function(autoclose){
                this.severity = SEVERITY.SUCCESS;

                // change notification color, icon, text, etc
                this.$el.removeClass("bg-info").addClass("bg-success");
                this.$el.find(".dialogIcon").removeClass("glyphicon-info-sign").addClass("glyphicon-ok-sign");

                this.updateTitle(this.title || $translate.instant("success"));
                this.updateStatus(this.msg || "");

                // show close button and make it active
                this.$el.find(".close").show().off().on("click", this.onClose);
                notificationFactory.store(this);
                this.show(autoclose);

                return this;
            },

            warning: function(autoclose){
                this.severity = SEVERITY.WARNING;

                // change notification color, icon, text, etc
                this.$el.removeClass("bg-info").addClass("bg-warning");
                this.$el.find(".dialogIcon").removeClass("glyphicon-info-sign").addClass("glyphicon-warning-sign");

                this.updateTitle(this.title || $translate.instant("warning"));
                this.updateStatus(this.msg || "");
                notificationFactory.store(this);
		if(!autoclose){
                    // show close button and make it active
                    this.$el.find(".close").show().off().on("click", this.onClose);
                    notificationFactory.store(this);
		}
                this.show(false);
                this.show(autoclose);

                return this;
            },

            info: function(autoclose){
                this.severity = SEVERITY.INFO;

                this.updateTitle(this.title || $translate.instant("info"));
                this.updateStatus(this.msg || "");

                // show close button and make it active
                this.$el.find(".close").show().off().on("click", this.onClose);
                notificationFactory.store(this);
                this.show(autoclose);

                return this;
            },

            error: function(){
                this.severity = SEVERITY.ERROR;

                // change notification color, icon, text, etc
                this.$el.removeClass("bg-info").addClass("bg-danger");
                this.$el.find(".dialogIcon").removeClass("glyphicon-info-sign").addClass("glyphicon-remove-sign");

                this.updateTitle(this.title || $translate.instant("error"));
                this.updateStatus(this.msg || "");

                // show close button and make it active
                this.$el.find(".close").show().off().on("click", this.onClose);
                notificationFactory.store(this);
                this.show(false);

                return this;
            },

            onClose: function(e){
                notificationFactory.markRead(this);
                this.hide();
            },

            hide: function(){
                this.$el.slideUp("fast", function(){
                    this.$el.remove();
                }.bind(this));
            },

            // updates the status message (the smaller text)
            updateStatus: function(msg){
                this.msg = msg || "";
                this.$message.html(this.msg);
                return this;
            },

            // updates the notification title (larger text)
            updateTitle: function(title){
                this.title = title || "";
                this.$title.text(this.title);
                return this;
            },

            show: function(autoclose){
                // close previous message if it is not
                // the current message
                if(lastMessage && lastMessage !== this){
                    lastMessage.hide();
                }

                this.$attachPoint.append(this.$el);

                autoclose = typeof autoclose !== 'undefined' ? autoclose : true;
                this.$el.slideDown("fast");

                if(autoclose){
                    setTimeout(this.hide, 5000);
                }

                lastMessage = this;

                return this;
            }
        };

        function NotificationFactory(){
            this.$storage = JSON.parse(localStorage.getItem('messages')) || [];
            this.lastId = null;

            // if this is the first time we sending a message, try to lookup the next ID from storage
            if(this.lastId === null){
                this.lastId = 0;
                this.$storage.forEach(function(el, idx){
                    if(el.id >= this.lastId){
                        this.lastId = el.id;
                    }
                }.bind(this));
            }
        }

        /**
         * Notification Factory
         * interface for creating, storing, and updating notifications
         */
        NotificationFactory.prototype = {
            constructor: NotificationFactory,

            /**
             * create a new notification. Loads of fun!
             * @param  {string} title  notification title. treated as plain text
             * @param  {string} msg  notification message. treated as HTML
             * @param  {jQueryObject} $attachPoint  jQuery DOM element to attach notification to
             *                                      defaults to `#notification` element
             * @return {Notification}  returns the Notification object
             */
            create: function(title, msg, $attachPoint){
                // if no valid attachPoint is provided, default to #notifications
                if(!$attachPoint || !$attachPoint.length){
                    $attachPoint = $("#notifications");
                }
                var notification = new Notification(++this.lastId, title, msg, $attachPoint);

                return notification;
            },

            /**
             * marks provided notification read and updates local data store
             * @param  {Notification} notification  the Notification object to mark read
             */
            markRead: function(notification){
                this.$storage.forEach(function(el, idx){
                    if(el.id === notification.id){
                        el.read = el.count;
                    }
                }.bind(this));

                localStorage.setItem('messages', JSON.stringify(this.$storage));
                $rootScope.$broadcast("messageUpdate");
            },

            /**
             * stores provided notification
             * @param  {Notification} notification  the Notification object to store
             */
            store: function(notification){
                var storable = {id: notification.id, read: 0, date: new Date(), title: notification.title, msg: notification.msg, count: 1};
                var newMessage = false;

                var isDuplicate = function(){
                    // de-dup messages
                    for(var i=0; i<this.$storage.length; ++i){
                        var message = this.$storage[i];
                        console.log(notification.msg + " === " + message.msg);
                        if(message && notification.msg === message.msg){
                            ++message.count;
                            return true;
                        }else{
                            return false;
                        }
                    }
                }.bind(this);

                if(!isDuplicate() && (notification.severity === SEVERITY.ERROR || notification.severity === SEVERITY.SUCCESS)){
                    if(this.$storage.unshift(storable) > 100){
                        this.$storage.pop();
                    }
                    newMessage = true;
                }

                localStorage.setItem('messages', JSON.stringify(this.$storage));
                $rootScope.$broadcast("messageUpdate");
                return newMessage;
            },

            /**
             * updates stored notification (by id) with the provided notification
             * @param  {Notification} notification  the Notification object to update
             */
            update: function(notification){
                var storable = {id: notification.id, read: 0, date: new Date(), title: notification.title, msg: notification.msg};

                this.$storage.forEach(function(el, idx){
                    if(el.id === notification.id){
                        el = storable;
                    }
                }.bind(this));

                localStorage.setItem('messages', JSON.stringify(this.$storage));
                $rootScope.$broadcast("messageUpdate");
            },

            /**
             * gets all stored messages as well as number of unread messages
             * @return {object}  object containing `unreadCount` - the number of unread messages,
             *                          and `messages` - an array of stored notifications.
             */
            getMessages: function(){
                var unreadCount;

                unreadCount = this.$storage.reduce(function(prev, cur, idx, storage){
                    cur.count = cur.count || 0;
                    return prev+(cur.count-cur.read);
                }, 0);

                return {
                    unreadCount: unreadCount,
                    messages: this.$storage
                };
            },

            /**
             * removes all stored Notifications (read and unread)
             */
            clearAll: function(){
                this.$storage = [];
                localStorage.clear();
                $rootScope.$broadcast("messageUpdate");
            }
        };

        notificationFactory = new NotificationFactory();
        return notificationFactory;
    }]);
})();
<commit_msg>Remove accidental copy/paste line<commit_after>/* global: $ */
/* jshint multistr: true */
var SEVERITY = {
    SUCCESS: 0,
    INFO: 1,
    WARNING: 2,
    ERROR: 3
};

// stores whatever the last message is
var lastMessage;

(function() {
    'use strict';

    /**
     * @ngdoc overview
     * @name notification
     */

    angular.module('zenNotify', []).

    /**
     * @ngdoc object
     * @name zenNotify.Notification
     * @requires $templateCache
     */

     factory('$notification', ['$rootScope', '$templateCache', '$translate', function ($rootScope, $templateCache, $translate) {
        var notificationFactory;

        var notificationTemplate = '
\
            \
            \
            \
            <button type="button" class="close" aria-hidden="true" style="display:none;">×</button>\

';

        /**
         * Notification
         * Creates a notification. Great for parties!
         */
        function Notification(id, title, msg, $attachPoint){
            this.id = id;
            this.$el = $(notificationTemplate);
            this.$message = this.$el.find(".message");
            this.$title = this.$el.find(".title");
            this.title = title;
            this.msg = msg;
            this.$attachPoint = $attachPoint;
            this.severity = SEVERITY.INFO;

            this.updateTitle(this.title || "");
            this.updateStatus(this.msg || "");

            // bind onClose context so it doesn't have
            // to be rebound for each event listener
            this.onClose = this.onClose.bind(this);
            this.hide = this.hide.bind(this);
        }

        Notification.prototype = {
            constructor: Notification,

            success: function(autoclose){
                this.severity = SEVERITY.SUCCESS;

                // change notification color, icon, text, etc
                this.$el.removeClass("bg-info").addClass("bg-success");
                this.$el.find(".dialogIcon").removeClass("glyphicon-info-sign").addClass("glyphicon-ok-sign");

                this.updateTitle(this.title || $translate.instant("success"));
                this.updateStatus(this.msg || "");

                // show close button and make it active
                this.$el.find(".close").show().off().on("click", this.onClose);
                notificationFactory.store(this);
                this.show(autoclose);

                return this;
            },

            warning: function(autoclose){
                this.severity = SEVERITY.WARNING;

                // change notification color, icon, text, etc
                this.$el.removeClass("bg-info").addClass("bg-warning");
                this.$el.find(".dialogIcon").removeClass("glyphicon-info-sign").addClass("glyphicon-warning-sign");

                this.updateTitle(this.title || $translate.instant("warning"));
                this.updateStatus(this.msg || "");
                notificationFactory.store(this);
		if(!autoclose){
                    // show close button and make it active
                    this.$el.find(".close").show().off().on("click", this.onClose);
                    notificationFactory.store(this);
		}
                this.show(autoclose);

                return this;
            },

            info: function(autoclose){
                this.severity = SEVERITY.INFO;

                this.updateTitle(this.title || $translate.instant("info"));
                this.updateStatus(this.msg || "");

                // show close button and make it active
                this.$el.find(".close").show().off().on("click", this.onClose);
                notificationFactory.store(this);
                this.show(autoclose);

                return this;
            },

            error: function(){
                this.severity = SEVERITY.ERROR;

                // change notification color, icon, text, etc
                this.$el.removeClass("bg-info").addClass("bg-danger");
                this.$el.find(".dialogIcon").removeClass("glyphicon-info-sign").addClass("glyphicon-remove-sign");

                this.updateTitle(this.title || $translate.instant("error"));
                this.updateStatus(this.msg || "");

                // show close button and make it active
                this.$el.find(".close").show().off().on("click", this.onClose);
                notificationFactory.store(this);
                this.show(false);

                return this;
            },

            onClose: function(e){
                notificationFactory.markRead(this);
                this.hide();
            },

            hide: function(){
                this.$el.slideUp("fast", function(){
                    this.$el.remove();
                }.bind(this));
            },

            // updates the status message (the smaller text)
            updateStatus: function(msg){
                this.msg = msg || "";
                this.$message.html(this.msg);
                return this;
            },

            // updates the notification title (larger text)
            updateTitle: function(title){
                this.title = title || "";
                this.$title.text(this.title);
                return this;
            },

            show: function(autoclose){
                // close previous message if it is not
                // the current message
                if(lastMessage && lastMessage !== this){
                    lastMessage.hide();
                }

                this.$attachPoint.append(this.$el);

                autoclose = typeof autoclose !== 'undefined' ? autoclose : true;
                this.$el.slideDown("fast");

                if(autoclose){
                    setTimeout(this.hide, 5000);
                }

                lastMessage = this;

                return this;
            }
        };

        function NotificationFactory(){
            this.$storage = JSON.parse(localStorage.getItem('messages')) || [];
            this.lastId = null;

            // if this is the first time we sending a message, try to lookup the next ID from storage
            if(this.lastId === null){
                this.lastId = 0;
                this.$storage.forEach(function(el, idx){
                    if(el.id >= this.lastId){
                        this.lastId = el.id;
                    }
                }.bind(this));
            }
        }

        /**
         * Notification Factory
         * interface for creating, storing, and updating notifications
         */
        NotificationFactory.prototype = {
            constructor: NotificationFactory,

            /**
             * create a new notification. Loads of fun!
             * @param  {string} title  notification title. treated as plain text
             * @param  {string} msg  notification message. treated as HTML
             * @param  {jQueryObject} $attachPoint  jQuery DOM element to attach notification to
             *                                      defaults to `#notification` element
             * @return {Notification}  returns the Notification object
             */
            create: function(title, msg, $attachPoint){
                // if no valid attachPoint is provided, default to #notifications
                if(!$attachPoint || !$attachPoint.length){
                    $attachPoint = $("#notifications");
                }
                var notification = new Notification(++this.lastId, title, msg, $attachPoint);

                return notification;
            },

            /**
             * marks provided notification read and updates local data store
             * @param  {Notification} notification  the Notification object to mark read
             */
            markRead: function(notification){
                this.$storage.forEach(function(el, idx){
                    if(el.id === notification.id){
                        el.read = el.count;
                    }
                }.bind(this));

                localStorage.setItem('messages', JSON.stringify(this.$storage));
                $rootScope.$broadcast("messageUpdate");
            },

            /**
             * stores provided notification
             * @param  {Notification} notification  the Notification object to store
             */
            store: function(notification){
                var storable = {id: notification.id, read: 0, date: new Date(), title: notification.title, msg: notification.msg, count: 1};
                var newMessage = false;

                var isDuplicate = function(){
                    // de-dup messages
                    for(var i=0; i<this.$storage.length; ++i){
                        var message = this.$storage[i];
                        console.log(notification.msg + " === " + message.msg);
                        if(message && notification.msg === message.msg){
                            ++message.count;
                            return true;
                        }else{
                            return false;
                        }
                    }
                }.bind(this);

                if(!isDuplicate() && (notification.severity === SEVERITY.ERROR || notification.severity === SEVERITY.SUCCESS)){
                    if(this.$storage.unshift(storable) > 100){
                        this.$storage.pop();
                    }
                    newMessage = true;
                }

                localStorage.setItem('messages', JSON.stringify(this.$storage));
                $rootScope.$broadcast("messageUpdate");
                return newMessage;
            },

            /**
             * updates stored notification (by id) with the provided notification
             * @param  {Notification} notification  the Notification object to update
             */
            update: function(notification){
                var storable = {id: notification.id, read: 0, date: new Date(), title: notification.title, msg: notification.msg};

                this.$storage.forEach(function(el, idx){
                    if(el.id === notification.id){
                        el = storable;
                    }
                }.bind(this));

                localStorage.setItem('messages', JSON.stringify(this.$storage));
                $rootScope.$broadcast("messageUpdate");
            },

            /**
             * gets all stored messages as well as number of unread messages
             * @return {object}  object containing `unreadCount` - the number of unread messages,
             *                          and `messages` - an array of stored notifications.
             */
            getMessages: function(){
                var unreadCount;

                unreadCount = this.$storage.reduce(function(prev, cur, idx, storage){
                    cur.count = cur.count || 0;
                    return prev+(cur.count-cur.read);
                }, 0);

                return {
                    unreadCount: unreadCount,
                    messages: this.$storage
                };
            },

            /**
             * removes all stored Notifications (read and unread)
             */
            clearAll: function(){
                this.$storage = [];
                localStorage.clear();
                $rootScope.$broadcast("messageUpdate");
            }
        };

        notificationFactory = new NotificationFactory();
        return notificationFactory;
    }]);
})();
<|endoftext|>


<commit_before>import React, { Component } from 'react-native';
import { Provider } from 'react-redux';
import configureStore from './store/configure-store';
import App from './containers/app';

const store = configureStore();

const Root = () => (
  <Provider store={store}>
    <App />
  </Provider>
);

export default Root;
<commit_msg>remove unnecessary import<commit_after>import React from 'react-native';
import { Provider } from 'react-redux';
import configureStore from './store/configure-store';
import App from './containers/app';

const store = configureStore();

const Root = () => (
  <Provider store={store}>
    <App />
  </Provider>
);

export default Root;
<|endoftext|>