<commit_before>import './rendererEmitter';
import './core';

import SettingsController from '../main/utils/Settings';
global.Settings = new SettingsController();
Settings.uncouple();

require(`./${process.platform}`);

const waitForBody = setInterval(() => {
  if (document.body) {
    clearInterval(waitForBody);
    require('./windowThemeHandler');
    setTimeout(() => require('electron').remote.getCurrentWindow().show(), 100);

    const nativeFrameAtLaunch = Settings.get('nativeFrame');

    document.body.classList.toggle('native-frame', nativeFrameAtLaunch);

    Emitter.on('window:fullscreen', (event, state) => {
      if (nativeFrameAtLaunch) return;
      if (state.state) document.body.classList.add('native-frame');
      if (!state.state) document.body.classList.remove('native-frame');
    });

    document.addEventListener('dragover', (event) => {
      event.preventDefault();
      return false;
    }, false);

    document.addEventListener('drop', (event) => {
      event.preventDefault();
      return false;
    }, false);
  }
}, 10);
<commit_msg>Wait for DOMContentLoaded instead of the body element<commit_after>import './rendererEmitter';
import './core';

import SettingsController from '../main/utils/Settings';
global.Settings = new SettingsController();
Settings.uncouple();

require(`./${process.platform}`);

document.addEventListener('DOMContentLoaded', () => {
  require('./windowThemeHandler');
  setTimeout(() => require('electron').remote.getCurrentWindow().show(), 100);

  const nativeFrameAtLaunch = Settings.get('nativeFrame');

  document.body.classList.toggle('native-frame', nativeFrameAtLaunch);

  Emitter.on('window:fullscreen', (event, state) => {
    if (nativeFrameAtLaunch) return;
    if (state.state) document.body.classList.add('native-frame');
    if (!state.state) document.body.classList.remove('native-frame');
  });

  document.addEventListener('dragover', (event) => {
    event.preventDefault();
    return false;
  }, false);

  document.addEventListener('drop', (event) => {
    event.preventDefault();
    return false;
  }, false);
});
<|endoftext|>


<commit_before>(function () {

L.Control.FullScreen = L.Control.extend({
	options: {
		position: 'topleft',
		title: 'Full Screen',
		titleCancel: 'Exit Full Screen',
		forceSeparateButton: false,
		forcePseudoFullscreen: false
	},

	onAdd: function (map) {
		var className = 'leaflet-control-zoom-fullscreen', container, content = '';

		if (map.zoomControl && !this.options.forceSeparateButton) {
			container = map.zoomControl._container;
		} else {
			container = L.DomUtil.create('div', 'leaflet-bar');
		}

		if (this.options.content) {
			content = this.options.content;
		} else {
			className += ' fullscreen-icon';
		}

		this._createButton(this.options.title, className, content, container, this.toggleFullScreen, this);

		this._map.on('enterFullscreen exitFullscreen', this._toggleTitle, this);

		return container;
	},

	_createButton: function (title, className, content, container, fn, context) {
		this.link = L.DomUtil.create('a', className, container);
		this.link.href = '#';
		this.link.title = title;
		this.link.innerHTML = content;

		L.DomEvent
			.addListener(this.link, 'click', L.DomEvent.stopPropagation)
			.addListener(this.link, 'click', L.DomEvent.preventDefault)
			.addListener(this.link, 'click', fn, context);

		L.DomEvent
			.addListener(container, fullScreenApi.fullScreenEventName, L.DomEvent.stopPropagation)
			.addListener(container, fullScreenApi.fullScreenEventName, L.DomEvent.preventDefault)
			.addListener(container, fullScreenApi.fullScreenEventName, this._handleEscKey, context);

		L.DomEvent
			.addListener(document, fullScreenApi.fullScreenEventName, L.DomEvent.stopPropagation)
			.addListener(document, fullScreenApi.fullScreenEventName, L.DomEvent.preventDefault)
			.addListener(document, fullScreenApi.fullScreenEventName, this._handleEscKey, context);

		return this.link;
	},

	toggleFullScreen: function () {
		var map = this._map;
		map._exitFired = false;
		if (map._isFullscreen) {
			if (fullScreenApi.supportsFullScreen && !this.options.forcePseudoFullscreen) {
				fullScreenApi.cancelFullScreen(map._container);
			} else {
				L.DomUtil.removeClass(map._container, 'leaflet-pseudo-fullscreen');
			}
			map.invalidateSize();
			map.fire('exitFullscreen');
			map._exitFired = true;
			map._isFullscreen = false;
		}
		else {
			if (fullScreenApi.supportsFullScreen && !this.options.forcePseudoFullscreen) {
				fullScreenApi.requestFullScreen(map._container);
			} else {
				L.DomUtil.addClass(map._container, 'leaflet-pseudo-fullscreen');
			}
			map.invalidateSize();
			map.fire('enterFullscreen');
			map._isFullscreen = true;
		}
	},

	_toggleTitle: function () {
		this.link.title = this._map._isFullscreen ? this.options.title : this.options.titleCancel;
	},

	_handleEscKey: function () {
		var map = this._map;
		if (!fullScreenApi.isFullScreen(map) && !map._exitFired) {
			map.fire('exitFullscreen');
			map._exitFired = true;
			map._isFullscreen = false;
		}
	}
});

L.Map.addInitHook(function () {
	if (this.options.fullscreenControl) {
		this.fullscreenControl = L.control.fullscreen(this.options.fullscreenControlOptions);
		this.addControl(this.fullscreenControl);
	}
});

L.control.fullscreen = function (options) {
	return new L.Control.FullScreen(options);
};

/*
Native FullScreen JavaScript API
-------------
Assumes Mozilla naming conventions instead of W3C for now

source : http://johndyer.name/native-fullscreen-javascript-api-plus-jquery-plugin/

*/

	var
		fullScreenApi = {
			supportsFullScreen: false,
			isFullScreen: function () { return false; },
			requestFullScreen: function () {},
			cancelFullScreen: function () {},
			fullScreenEventName: '',
			prefix: ''
		},
		browserPrefixes = 'webkit moz o ms khtml'.split(' ');

	// check for native support
	if (typeof document.exitFullscreen !== 'undefined') {
		fullScreenApi.supportsFullScreen = true;
	} else {
		// check for fullscreen support by vendor prefix
		for (var i = 0, il = browserPrefixes.length; i < il; i++) {
			fullScreenApi.prefix = browserPrefixes[i];
			if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] !== 'undefined') {
				fullScreenApi.supportsFullScreen = true;
				break;
			}
		}
	}

	// update methods to do something useful
	if (fullScreenApi.supportsFullScreen) {
		fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange';
		fullScreenApi.isFullScreen = function () {
			switch (this.prefix) {
				case '':
					return document.fullScreen;
				case 'webkit':
					return document.webkitIsFullScreen;
				default:
					return document[this.prefix + 'FullScreen'];
			}
		};
		fullScreenApi.requestFullScreen = function (el) {
			return (this.prefix === '') ? el.requestFullscreen() : el[this.prefix + 'RequestFullScreen']();
		};
		fullScreenApi.cancelFullScreen = function (el) {
			return (this.prefix === '') ? document.exitFullscreen() : document[this.prefix + 'CancelFullScreen']();
		};
	}

	// jQuery plugin
	if (typeof jQuery !== 'undefined') {
		jQuery.fn.requestFullScreen = function () {
			return this.each(function () {
				var el = jQuery(this);
				if (fullScreenApi.supportsFullScreen) {
					fullScreenApi.requestFullScreen(el);
				}
			});
		};
	}

	// export api
	window.fullScreenApi = fullScreenApi;
})();
<commit_msg>unused var in fullScreenApi.cancelFullScreen<commit_after>(function () {

L.Control.FullScreen = L.Control.extend({
	options: {
		position: 'topleft',
		title: 'Full Screen',
		titleCancel: 'Exit Full Screen',
		forceSeparateButton: false,
		forcePseudoFullscreen: false
	},

	onAdd: function (map) {
		var className = 'leaflet-control-zoom-fullscreen', container, content = '';

		if (map.zoomControl && !this.options.forceSeparateButton) {
			container = map.zoomControl._container;
		} else {
			container = L.DomUtil.create('div', 'leaflet-bar');
		}

		if (this.options.content) {
			content = this.options.content;
		} else {
			className += ' fullscreen-icon';
		}

		this._createButton(this.options.title, className, content, container, this.toggleFullScreen, this);

		this._map.on('enterFullscreen exitFullscreen', this._toggleTitle, this);

		return container;
	},

	_createButton: function (title, className, content, container, fn, context) {
		this.link = L.DomUtil.create('a', className, container);
		this.link.href = '#';
		this.link.title = title;
		this.link.innerHTML = content;

		L.DomEvent
			.addListener(this.link, 'click', L.DomEvent.stopPropagation)
			.addListener(this.link, 'click', L.DomEvent.preventDefault)
			.addListener(this.link, 'click', fn, context);

		L.DomEvent
			.addListener(container, fullScreenApi.fullScreenEventName, L.DomEvent.stopPropagation)
			.addListener(container, fullScreenApi.fullScreenEventName, L.DomEvent.preventDefault)
			.addListener(container, fullScreenApi.fullScreenEventName, this._handleEscKey, context);

		L.DomEvent
			.addListener(document, fullScreenApi.fullScreenEventName, L.DomEvent.stopPropagation)
			.addListener(document, fullScreenApi.fullScreenEventName, L.DomEvent.preventDefault)
			.addListener(document, fullScreenApi.fullScreenEventName, this._handleEscKey, context);

		return this.link;
	},

	toggleFullScreen: function () {
		var map = this._map;
		map._exitFired = false;
		if (map._isFullscreen) {
			if (fullScreenApi.supportsFullScreen && !this.options.forcePseudoFullscreen) {
				fullScreenApi.cancelFullScreen(map._container);
			} else {
				L.DomUtil.removeClass(map._container, 'leaflet-pseudo-fullscreen');
			}
			map.invalidateSize();
			map.fire('exitFullscreen');
			map._exitFired = true;
			map._isFullscreen = false;
		}
		else {
			if (fullScreenApi.supportsFullScreen && !this.options.forcePseudoFullscreen) {
				fullScreenApi.requestFullScreen(map._container);
			} else {
				L.DomUtil.addClass(map._container, 'leaflet-pseudo-fullscreen');
			}
			map.invalidateSize();
			map.fire('enterFullscreen');
			map._isFullscreen = true;
		}
	},

	_toggleTitle: function () {
		this.link.title = this._map._isFullscreen ? this.options.title : this.options.titleCancel;
	},

	_handleEscKey: function () {
		var map = this._map;
		if (!fullScreenApi.isFullScreen(map) && !map._exitFired) {
			map.fire('exitFullscreen');
			map._exitFired = true;
			map._isFullscreen = false;
		}
	}
});

L.Map.addInitHook(function () {
	if (this.options.fullscreenControl) {
		this.fullscreenControl = L.control.fullscreen(this.options.fullscreenControlOptions);
		this.addControl(this.fullscreenControl);
	}
});

L.control.fullscreen = function (options) {
	return new L.Control.FullScreen(options);
};

/*
Native FullScreen JavaScript API
-------------
Assumes Mozilla naming conventions instead of W3C for now

source : http://johndyer.name/native-fullscreen-javascript-api-plus-jquery-plugin/

*/

	var
		fullScreenApi = {
			supportsFullScreen: false,
			isFullScreen: function () { return false; },
			requestFullScreen: function () {},
			cancelFullScreen: function () {},
			fullScreenEventName: '',
			prefix: ''
		},
		browserPrefixes = 'webkit moz o ms khtml'.split(' ');

	// check for native support
	if (typeof document.exitFullscreen !== 'undefined') {
		fullScreenApi.supportsFullScreen = true;
	} else {
		// check for fullscreen support by vendor prefix
		for (var i = 0, il = browserPrefixes.length; i < il; i++) {
			fullScreenApi.prefix = browserPrefixes[i];
			if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] !== 'undefined') {
				fullScreenApi.supportsFullScreen = true;
				break;
			}
		}
	}

	// update methods to do something useful
	if (fullScreenApi.supportsFullScreen) {
		fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange';
		fullScreenApi.isFullScreen = function () {
			switch (this.prefix) {
				case '':
					return document.fullScreen;
				case 'webkit':
					return document.webkitIsFullScreen;
				default:
					return document[this.prefix + 'FullScreen'];
			}
		};
		fullScreenApi.requestFullScreen = function (el) {
			return (this.prefix === '') ? el.requestFullscreen() : el[this.prefix + 'RequestFullScreen']();
		};
		fullScreenApi.cancelFullScreen = function () {
			return (this.prefix === '') ? document.exitFullscreen() : document[this.prefix + 'CancelFullScreen']();
		};
	}

	// jQuery plugin
	if (typeof jQuery !== 'undefined') {
		jQuery.fn.requestFullScreen = function () {
			return this.each(function () {
				var el = jQuery(this);
				if (fullScreenApi.supportsFullScreen) {
					fullScreenApi.requestFullScreen(el);
				}
			});
		};
	}

	// export api
	window.fullScreenApi = fullScreenApi;
})();
<|endoftext|>


<commit_before>const React = require('react')
const { findDOMNode } = require('react-dom')
const scrollIntoView = require('dom-scroll-into-view')
const PropTypes = require('prop-types');

let _debugStates = []

let Autocomplete = React.createClass({

  propTypes: {
    value: PropTypes.any,
    onChange: PropTypes.func,
    onSelect: PropTypes.func,
    shouldItemRender: PropTypes.func,
    sortItems: PropTypes.func,
    getItemValue: PropTypes.func.isRequired,
    renderItem: PropTypes.func.isRequired,
    renderMenu: PropTypes.func,
    menuStyle: PropTypes.object,
    inputProps: PropTypes.object,
    wrapperProps: PropTypes.object,
    wrapperStyle: PropTypes.object,
    autoHighlight: PropTypes.bool,
    onMenuVisibilityChange: PropTypes.func,
    open: PropTypes.bool,
    debug: PropTypes.bool,
  },

  getDefaultProps () {
    return {
      value: '',
      wrapperProps: {},
      wrapperStyle: {
        display: 'inline-block'
      },
      inputProps: {},
      onChange () {},
      onSelect (value, item) {},
      renderMenu (items, value, style) {
        return

      },
      shouldItemRender () { return true },
      menuStyle: {
        borderRadius: '3px',
        boxShadow: '0 2px 12px rgba(0, 0, 0, 0.1)',
        background: 'rgba(255, 255, 255, 0.9)',
        padding: '2px 0',
        fontSize: '90%',
        position: 'fixed',
        overflow: 'auto',
        maxHeight: '50%', // TODO: don't cheat, let it flow to the bottom
      },
      autoHighlight: true,
      onMenuVisibilityChange () {},
    }
  },

  getInitialState () {
    return {
      isOpen: false,
      highlightedIndex: null,
    }
  },

  componentWillMount () {
    this._ignoreBlur = false
    this._performAutoCompleteOnUpdate = false
    this._performAutoCompleteOnKeyUp = false
  },

  componentWillReceiveProps (nextProps) {
    this._performAutoCompleteOnUpdate = true
    // If `items` has changed we want to reset `highlightedIndex`
    // since it probably no longer refers to a relevant item
    if (this.props.items !== nextProps.items ||
      // The entries in `items` may have been changed even though the
      // object reference remains the same, double check by seeing
      // if `highlightedIndex` points to an existing item
      this.state.highlightedIndex >= nextProps.items.length) {
      this.setState({ highlightedIndex: null })
    }
  },

  componentDidUpdate (prevProps, prevState) {
    if (this.state.isOpen === true && prevState.isOpen === false)
      this.setMenuPositions()

    if (this.state.isOpen && this._performAutoCompleteOnUpdate) {
      this._performAutoCompleteOnUpdate = false
      this.maybeAutoCompleteText()
    }

    this.maybeScrollItemIntoView()
    if (prevState.isOpen !== this.state.isOpen) {
      this.props.onMenuVisibilityChange(this.state.isOpen)
    }
  },

  maybeScrollItemIntoView () {
    if (this.state.isOpen === true && this.state.highlightedIndex !== null) {
      var itemNode = this.refs[`item-${this.state.highlightedIndex}`]
      var menuNode = this.refs.menu
      if(itemNode) {
        scrollIntoView(
          findDOMNode(itemNode),
          findDOMNode(menuNode),
          { onlyScrollIfNeeded: true }
        )
      }
    }
  },

  handleKeyDown (event) {
    if (this.keyDownHandlers[event.key])
      this.keyDownHandlers[event.key].call(this, event)
    else {
      this.setState({
        highlightedIndex: null,
        isOpen: true
      })
    }
  },

  handleChange (event) {
    this._performAutoCompleteOnKeyUp = true
    this.props.onChange(event, event.target.value)
  },

  handleKeyUp () {
    if (this._performAutoCompleteOnKeyUp) {
      this._performAutoCompleteOnKeyUp = false
      this.maybeAutoCompleteText()
    }
  },

  keyDownHandlers: {
    ArrowDown (event) {
      event.preventDefault()
      const itemsLength = this.getFilteredItems().length
      if (!itemsLength) return
      var { highlightedIndex } = this.state
      var index = (
        highlightedIndex === null ||
        highlightedIndex === itemsLength - 1
      ) ?  0 : highlightedIndex + 1
      this._performAutoCompleteOnKeyUp = true
      this.setState({
        highlightedIndex: index,
        isOpen: true,
      })
    },

    ArrowUp (event) {
      event.preventDefault()
      const itemsLength = this.getFilteredItems().length
      if (!itemsLength) return
      var { highlightedIndex } = this.state
      var index = (
        highlightedIndex === 0 ||
        highlightedIndex === null
      ) ? itemsLength - 1 : highlightedIndex - 1
      this._performAutoCompleteOnKeyUp = true
      this.setState({
        highlightedIndex: index,
        isOpen: true,
      })
    },

    Enter (event) {
      if (this.state.isOpen === false) {
        // menu is closed so there is no selection to accept -> do nothing
        return
      }
      else if (this.state.highlightedIndex == null) {
        // input has focus but no menu item is selected + enter is hit -> close the menu, highlight whatever's in input
        this.setState({
          isOpen: false
        }, () => {
          this.refs.input.select()
        })
      }
      else {
        // text entered + menu item has been highlighted + enter is hit -> update value to that of selected menu item, close the menu
        event.preventDefault()
        var item = this.getFilteredItems()[this.state.highlightedIndex]
        var value = this.props.getItemValue(item)
        this.setState({
          isOpen: false,
          highlightedIndex: null
        }, () => {
          //this.refs.input.focus() // TODO: file issue
          this.refs.input.setSelectionRange(
            value.length,
            value.length
          )
          this.props.onSelect(value, item)
        })
      }
    },

    Escape (event) {
      this.setState({
        highlightedIndex: null,
        isOpen: false
      })
    }
  },

  getFilteredItems () {
    let items = this.props.items

    if (this.props.shouldItemRender) {
      items = items.filter((item) => (
        this.props.shouldItemRender(item, this.props.value)
      ))
    }

    if (this.props.sortItems) {
      items.sort((a, b) => (
        this.props.sortItems(a, b, this.props.value)
      ))
    }

    return items
  },

  maybeAutoCompleteText () {
    if (!this.props.autoHighlight || this.props.value === '')
      return
    var { highlightedIndex } = this.state
    var items = this.getFilteredItems()
    if (items.length === 0)
      return
    var matchedItem = highlightedIndex !== null ?
      items[highlightedIndex] : items[0]
    var itemValue = this.props.getItemValue(matchedItem)
    var itemValueDoesMatch = (itemValue.toLowerCase().indexOf(
      this.props.value.toLowerCase()
    ) === 0)
    if (itemValueDoesMatch && highlightedIndex === null)
      this.setState({ highlightedIndex: 0 })
  },

  setMenuPositions () {
    var node = this.refs.input
    var rect = node.getBoundingClientRect()
    var computedStyle = global.window.getComputedStyle(node)
    var marginBottom = parseInt(computedStyle.marginBottom, 10) || 0;
    var marginLeft = parseInt(computedStyle.marginLeft, 10) || 0;
    var marginRight = parseInt(computedStyle.marginRight, 10) || 0;
    this.setState({
      menuTop: rect.bottom + marginBottom,
      menuLeft: rect.left + marginLeft,
      menuWidth: rect.width + marginLeft + marginRight
    })
  },

  highlightItemFromMouse (index) {
    this.setState({ highlightedIndex: index })
  },

  selectItemFromMouse (item) {
    var value = this.props.getItemValue(item);
    this.setState({
      isOpen: false,
      highlightedIndex: null
    }, () => {
      this.props.onSelect(value, item)
      this.refs.input.focus()
    })
  },

  setIgnoreBlur (ignore) {
    this._ignoreBlur = ignore
  },

  renderMenu () {
    var items = this.getFilteredItems().map((item, index) => {
      var element = this.props.renderItem(
        item,
        this.state.highlightedIndex === index,
        {cursor: 'default'}
      )
      return React.cloneElement(element, {
        onMouseDown: () => this.setIgnoreBlur(true), // Ignore blur to prevent menu from de-rendering before we can process click
        onMouseEnter: () => this.highlightItemFromMouse(index),
        onClick: () => this.selectItemFromMouse(item),
        ref: `item-${index}`,
      })
    })
    var style = {
      left: this.state.menuLeft,
      top: this.state.menuTop,
      minWidth: this.state.menuWidth,
    }
    var menu = this.props.renderMenu(items, this.props.value, style)
    return React.cloneElement(menu, { ref: 'menu' })
  },

  handleInputBlur () {
    if (this._ignoreBlur)
      return
    this.setState({
      isOpen: false,
      highlightedIndex: null
    })
  },

  handleInputFocus () {
    if (this._ignoreBlur) {
      this.setIgnoreBlur(false)
      return
    }
    // We don't want `selectItemFromMouse` to trigger when
    // the user clicks into the input to focus it, so set this
    // flag to cancel out the logic in `handleInputClick`.
    // The event order is:  MouseDown -> Focus -> MouseUp -> Click
    this._ignoreClick = true
    this.setState({ isOpen: true })
  },

  isInputFocused () {
    var el = this.refs.input
    return el.ownerDocument && (el === el.ownerDocument.activeElement)
  },

  handleInputClick () {
    // Input will not be focused if it's disabled
    if (this.isInputFocused() && this.state.isOpen === false)
      this.setState({ isOpen: true })
    else if (this.state.highlightedIndex !== null && !this._ignoreClick)
      this.selectItemFromMouse(this.getFilteredItems()[this.state.highlightedIndex])
    this._ignoreClick = false
  },

  composeEventHandlers (internal, external) {
    return external
      ? e => { internal(e); external(e); }
      : internal
  },

  render () {
    if (this.props.debug) { // you don't like it, you love it
      _debugStates.push({
        id: _debugStates.length,
        state: this.state
      })
    }

    const { inputProps } = this.props
    return (

        <input
          {...inputProps}
          role="combobox"
          aria-autocomplete="list"
          autoComplete="off"
          ref="input"
          onFocus={this.composeEventHandlers(this.handleInputFocus, inputProps.onFocus)}
          onBlur={this.composeEventHandlers(this.handleInputBlur, inputProps.onBlur)}
          onChange={this.handleChange}
          onKeyDown={this.composeEventHandlers(this.handleKeyDown, inputProps.onKeyDown)}
          onKeyUp={this.composeEventHandlers(this.handleKeyUp, inputProps.onKeyUp)}
          onClick={this.composeEventHandlers(this.handleInputClick, inputProps.onClick)}
          value={this.props.value}
        />
        {('open' in this.props ? this.props.open : this.state.isOpen) && this.renderMenu()}
        {this.props.debug && (

            {JSON.stringify(_debugStates.slice(_debugStates.length - 5, _debugStates.length), null, 2)}

        )}

    )
  }
})

module.exports = Autocomplete

<commit_msg>Turn into ES6 class to support React v16<commit_after>import React from 'react';
import { findDOMNode } from 'react-dom';
import scrollIntoView from 'dom-scroll-into-view';
import PropTypes from 'prop-types';

let _debugStates = [];

export class Autocomplete extends React.Component {
  constructor(props) {
    super(props);

    this.keyDownHandlers = {
      ArrowDown (event) {
        event.preventDefault()
        const itemsLength = this.getFilteredItems().length
        if (!itemsLength) return
        var { highlightedIndex } = this.state
        var index = (
          highlightedIndex === null ||
          highlightedIndex === itemsLength - 1
        ) ?  0 : highlightedIndex + 1
        this._performAutoCompleteOnKeyUp = true
        this.setState({
          highlightedIndex: index,
          isOpen: true,
        })
      },

      ArrowUp (event) {
        event.preventDefault()
        const itemsLength = this.getFilteredItems().length
        if (!itemsLength) return
        var { highlightedIndex } = this.state
        var index = (
          highlightedIndex === 0 ||
          highlightedIndex === null
        ) ? itemsLength - 1 : highlightedIndex - 1
        this._performAutoCompleteOnKeyUp = true
        this.setState({
          highlightedIndex: index,
          isOpen: true,
        })
      },

      Enter (event) {
        if (this.state.isOpen === false) {
          // menu is closed so there is no selection to accept -> do nothing
          return
        }
        else if (this.state.highlightedIndex == null) {
          // input has focus but no menu item is selected + enter is hit -> close the menu, highlight whatever's in input
          this.setState({
            isOpen: false
          }, () => {
            this.refs.input.select()
          })
        }
        else {
          // text entered + menu item has been highlighted + enter is hit -> update value to that of selected menu item, close the menu
          event.preventDefault()
          var item = this.getFilteredItems()[this.state.highlightedIndex]
          var value = this.props.getItemValue(item)
          this.setState({
            isOpen: false,
            highlightedIndex: null
          }, () => {
            //this.refs.input.focus() // TODO: file issue
            this.refs.input.setSelectionRange(
              value.length,
              value.length
            )
            this.props.onSelect(value, item)
          })
        }
      },

      Escape (event) {
        this.setState({
          highlightedIndex: null,
          isOpen: false
        })
      }
    };
  }

  getDefaultProps () {
    return {
      value: '',
      wrapperProps: {},
      wrapperStyle: {
        display: 'inline-block'
      },
      inputProps: {},
      onChange () {},
      onSelect (value, item) {},
      renderMenu (items, value, style) {
        return

      },
      shouldItemRender () { return true },
      menuStyle: {
        borderRadius: '3px',
        boxShadow: '0 2px 12px rgba(0, 0, 0, 0.1)',
        background: 'rgba(255, 255, 255, 0.9)',
        padding: '2px 0',
        fontSize: '90%',
        position: 'fixed',
        overflow: 'auto',
        maxHeight: '50%', // TODO: don't cheat, let it flow to the bottom
      },
      autoHighlight: true,
      onMenuVisibilityChange () {},
    }
  }

  getInitialState () {
    return {
      isOpen: false,
      highlightedIndex: null,
    }
  }

  componentWillMount () {
    this._ignoreBlur = false
    this._performAutoCompleteOnUpdate = false
    this._performAutoCompleteOnKeyUp = false
  }

  componentWillReceiveProps (nextProps) {
    this._performAutoCompleteOnUpdate = true
    // If `items` has changed we want to reset `highlightedIndex`
    // since it probably no longer refers to a relevant item
    if (this.props.items !== nextProps.items ||
      // The entries in `items` may have been changed even though the
      // object reference remains the same, double check by seeing
      // if `highlightedIndex` points to an existing item
      this.state.highlightedIndex >= nextProps.items.length) {
      this.setState({ highlightedIndex: null })
    }
  }

  componentDidUpdate (prevProps, prevState) {
    if (this.state.isOpen === true && prevState.isOpen === false)
      this.setMenuPositions()

    if (this.state.isOpen && this._performAutoCompleteOnUpdate) {
      this._performAutoCompleteOnUpdate = false
      this.maybeAutoCompleteText()
    }

    this.maybeScrollItemIntoView()
    if (prevState.isOpen !== this.state.isOpen) {
      this.props.onMenuVisibilityChange(this.state.isOpen)
    }
  }

  maybeScrollItemIntoView () {
    if (this.state.isOpen === true && this.state.highlightedIndex !== null) {
      var itemNode = this.refs[`item-${this.state.highlightedIndex}`]
      var menuNode = this.refs.menu
      if(itemNode) {
        scrollIntoView(
          findDOMNode(itemNode),
          findDOMNode(menuNode),
          { onlyScrollIfNeeded: true }
        )
      }
    }
  }

  handleKeyDown (event) {
    if (this.keyDownHandlers[event.key])
      this.keyDownHandlers[event.key].call(this, event)
    else {
      this.setState({
        highlightedIndex: null,
        isOpen: true
      })
    }
  }

  handleChange (event) {
    this._performAutoCompleteOnKeyUp = true
    this.props.onChange(event, event.target.value)
  }

  handleKeyUp () {
    if (this._performAutoCompleteOnKeyUp) {
      this._performAutoCompleteOnKeyUp = false
      this.maybeAutoCompleteText()
    }
  }

  getFilteredItems () {
    let items = this.props.items

    if (this.props.shouldItemRender) {
      items = items.filter((item) => (
        this.props.shouldItemRender(item, this.props.value)
      ))
    }

    if (this.props.sortItems) {
      items.sort((a, b) => (
        this.props.sortItems(a, b, this.props.value)
      ))
    }

    return items
  }

  maybeAutoCompleteText () {
    if (!this.props.autoHighlight || this.props.value === '')
      return
    var { highlightedIndex } = this.state
    var items = this.getFilteredItems()
    if (items.length === 0)
      return
    var matchedItem = highlightedIndex !== null ?
      items[highlightedIndex] : items[0]
    var itemValue = this.props.getItemValue(matchedItem)
    var itemValueDoesMatch = (itemValue.toLowerCase().indexOf(
      this.props.value.toLowerCase()
    ) === 0)
    if (itemValueDoesMatch && highlightedIndex === null)
      this.setState({ highlightedIndex: 0 })
  }

  setMenuPositions () {
    var node = this.refs.input
    var rect = node.getBoundingClientRect()
    var computedStyle = global.window.getComputedStyle(node)
    var marginBottom = parseInt(computedStyle.marginBottom, 10) || 0;
    var marginLeft = parseInt(computedStyle.marginLeft, 10) || 0;
    var marginRight = parseInt(computedStyle.marginRight, 10) || 0;
    this.setState({
      menuTop: rect.bottom + marginBottom,
      menuLeft: rect.left + marginLeft,
      menuWidth: rect.width + marginLeft + marginRight
    })
  }

  highlightItemFromMouse (index) {
    this.setState({ highlightedIndex: index })
  }

  selectItemFromMouse (item) {
    var value = this.props.getItemValue(item);
    this.setState({
      isOpen: false,
      highlightedIndex: null
    }, () => {
      this.props.onSelect(value, item)
      this.refs.input.focus()
    })
  }

  setIgnoreBlur (ignore) {
    this._ignoreBlur = ignore
  }

  renderMenu () {
    var items = this.getFilteredItems().map((item, index) => {
      var element = this.props.renderItem(
        item,
        this.state.highlightedIndex === index,
        {cursor: 'default'}
      )
      return React.cloneElement(element, {
        onMouseDown: () => this.setIgnoreBlur(true), // Ignore blur to prevent menu from de-rendering before we can process click
        onMouseEnter: () => this.highlightItemFromMouse(index),
        onClick: () => this.selectItemFromMouse(item),
        ref: `item-${index}`,
      })
    })
    var style = {
      left: this.state.menuLeft,
      top: this.state.menuTop,
      minWidth: this.state.menuWidth,
    }
    var menu = this.props.renderMenu(items, this.props.value, style)
    return React.cloneElement(menu, { ref: 'menu' })
  }

  handleInputBlur () {
    if (this._ignoreBlur)
      return
    this.setState({
      isOpen: false,
      highlightedIndex: null
    })
  }

  handleInputFocus () {
    if (this._ignoreBlur) {
      this.setIgnoreBlur(false)
      return
    }
    // We don't want `selectItemFromMouse` to trigger when
    // the user clicks into the input to focus it, so set this
    // flag to cancel out the logic in `handleInputClick`.
    // The event order is:  MouseDown -> Focus -> MouseUp -> Click
    this._ignoreClick = true
    this.setState({ isOpen: true })
  }

  isInputFocused () {
    var el = this.refs.input
    return el.ownerDocument && (el === el.ownerDocument.activeElement)
  }

  handleInputClick () {
    // Input will not be focused if it's disabled
    if (this.isInputFocused() && this.state.isOpen === false)
      this.setState({ isOpen: true })
    else if (this.state.highlightedIndex !== null && !this._ignoreClick)
      this.selectItemFromMouse(this.getFilteredItems()[this.state.highlightedIndex])
    this._ignoreClick = false
  }

  composeEventHandlers (internal, external) {
    return external
      ? e => { internal(e); external(e); }
      : internal
  }

  /* ------------------------------ Rendering ------------------------------- */

  render () {
    if (this.props.debug) { // you don't like it, you love it
      _debugStates.push({
        id: _debugStates.length,
        state: this.state
      })
    }

    const { inputProps } = this.props;
    return (

        <input
          {...inputProps}
          role="combobox"
          aria-autocomplete="list"
          autoComplete="off"
          ref="input"
          onFocus={this.composeEventHandlers(this.handleInputFocus, inputProps.onFocus)}
          onBlur={this.composeEventHandlers(this.handleInputBlur, inputProps.onBlur)}
          onChange={this.handleChange}
          onKeyDown={this.composeEventHandlers(this.handleKeyDown, inputProps.onKeyDown)}
          onKeyUp={this.composeEventHandlers(this.handleKeyUp, inputProps.onKeyUp)}
          onClick={this.composeEventHandlers(this.handleInputClick, inputProps.onClick)}
          value={this.props.value}
        />
        {('open' in this.props ? this.props.open : this.state.isOpen) && this.renderMenu()}
        {this.props.debug && (

            {JSON.stringify(_debugStates.slice(_debugStates.length - 5, _debugStates.length), null, 2)}

        )}

    )
  }
}

Autocomplete.propTypes = {
  autoHighlight: PropTypes.bool,
  debug: PropTypes.bool,
  getItemValue: PropTypes.func.isRequired,
  inputProps: PropTypes.object,
  menuStyle: PropTypes.object,
  onChange: PropTypes.func,
  onMenuVisibilityChange: PropTypes.func,
  onSelect: PropTypes.func,
  open: PropTypes.bool,
  renderItem: PropTypes.func.isRequired,
  renderMenu: PropTypes.func,
  shouldItemRender: PropTypes.func,
  sortItems: PropTypes.func,
  value: PropTypes.any,
  wrapperProps: PropTypes.object,
  wrapperStyle: PropTypes.object
};

export default Autocomplete;
<|endoftext|>


<commit_before>module.exports = {
  normalizeEntityName: function() {
    // this prevents an error when the entityName is
    // not specified (since that doesn't actually matter
    // to us
  },

  afterInstall: function() {
    return this.addBowerPackagesToProject([
      { name: 'qunit',                           target: '~1.17.1' },
      { name: 'ember-cli/ember-cli-test-loader', target: '0.1.3'   },
      { name: 'ember-qunit-notifications',       target: '0.0.7'   },
      { name: 'ember-qunit',                     target: '0.4.6'   }
    ]);
  }
};
<commit_msg>Update ember-qunit version.<commit_after>module.exports = {
  normalizeEntityName: function() {
    // this prevents an error when the entityName is
    // not specified (since that doesn't actually matter
    // to us
  },

  afterInstall: function() {
    return this.addBowerPackagesToProject([
      { name: 'qunit',                           target: '~1.17.1' },
      { name: 'ember-cli/ember-cli-test-loader', target: '0.1.3'   },
      { name: 'ember-qunit-notifications',       target: '0.0.7'   },
      { name: 'ember-qunit',                     target: '0.4.9'   }
    ]);
  }
};
<|endoftext|>


<commit_before>import React, {Component} from 'react';

import TagField from 'dist/TagField';
import Widget from 'dist/Widget';
import WidgetHeader from 'dist/WidgetHeader';

import PropTypeDescTable from '../PropTypeDescTable';
import TagFieldDoc from 'assets/propTypes/TagField.json';

import 'sass/containers/app/modules/fields/TagFieldExamples.scss';

export default class TagFieldExamples extends Component {

    constructor(props) {

        super(props);

        this.data = [{
            text: 'Hotelcode1'
        }, {
            text: 'Hotelcode2'
        }, {
            className: 'duplicate',
            text: 'Hotelcode3'
        }, {
            className: 'duplicate',
            text: 'Hotelcode4'
        }, {
            text: 'Hotelcode5'
        }, {
            className: 'unfound',
            text: 'Hotelcode6'
        }, {
            className: 'unfound',
            value: 'Hotelcode7'
        }];

    }

    render() {
        return (

TagField

                    TagField allow users to input text.

Examples

                <Widget>

                    <WidgetHeader className="example-header"
                                  title="With type"/>

TagField

                                <TagField data={[]}
                                          placeholder="Please input ..."
                                          onChange={(value) => {
                                              console.log(value);
                                          }}/>

                </Widget>

Properties

                <PropTypeDescTable data={TagFieldDoc}/>

        );
    }
};<commit_msg>update TagField example<commit_after>import React, {Component} from 'react';

import TagField from 'dist/TagField';
import Widget from 'dist/Widget';
import WidgetHeader from 'dist/WidgetHeader';

import PropTypeDescTable from '../PropTypeDescTable';
import TagFieldDoc from 'assets/propTypes/TagField.json';

import 'sass/containers/app/modules/fields/TagFieldExamples.scss';

export default class TagFieldExamples extends Component {

    constructor(props) {

        super(props);

        this.data = [{
            text: 'Hotelcode1'
        }, {
            text: 'Hotelcode2'
        }, {
            className: 'duplicate',
            text: 'Hotelcode3'
        }, {
            className: 'duplicate',
            text: 'Hotelcode4'
        }, {
            text: 'Hotelcode5'
        }, {
            className: 'unfound',
            text: 'Hotelcode6'
        }, {
            className: 'unfound',
            value: 'Hotelcode7'
        }];

    }

    render() {
        return (

TagField

                    TagField allow users to input text.

Examples

                <Widget>

                    <WidgetHeader className="example-header"
                                  title="With type"/>

TagField

                                <TagField style={{height: 100}}
                                          data={[]}
                                          placeholder="Please input ..."
                                          onChange={(value) => {
                                              console.log(value);
                                          }}/>

                </Widget>

Properties

                <PropTypeDescTable data={TagFieldDoc}/>

        );
    }
};<|endoftext|>


<commit_before>/**
 * @file Set ups things on the editor page.
 * @copyright This file is part of Fidus Writer.
 *
 * Copyright (C) 2013 Takuto Kojima, Johannes Wilm.
 *
 * @license This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 *
 */
/** Whether the citation style before the current one was footnote based. This is used to determine whetherthe page needs to be reformatted.
 * @constant lastStyleUsedFootnotes
 */
var lastStyleUsedFootnotes = false;

// Functions to be executed at startup
jQuery(document).ready(function () {

    var documentStyleMenu = document.getElementById("documentstyle-list"), documentStyleMenuItem;

    // Enable toolbar menu
    jQuery('#menu1').ptMenu();

    //open dropdown for headermenu
    jQuery('.header-nav-item').each(function () {
        $.addDropdownBox(jQuery(this), jQuery(this).siblings(
            '.fw-pulldown'));
    });

    for (i = 0; i < documentStyleList.length; i++) {
        documentStyleMenuItem=document.createElement("li");
        documentStyleMenuItem.innerHTML = ""+documentStyleList[i].title+"";
        documentStyleMenu.appendChild(documentStyleMenuItem);
    }
});

// Functions to be executed when document has loaded
jQuery(document).bind('documentDataLoaded', function () {

    // We cannot download BibDB and ImageDB before we know if we are the document owner or not.
    bibliographyHelpers.init();
    usermediaHelpers.init();

    var set_document_style_timer = setTimeout(function () {
        clearTimeout(set_document_style_timer);
        //setDocumentstyle();
        editorHelpers.setDisplay.document('settings.documentstyle',
            theDocument.settings.documentstyle);
    }, 800);

    // Document Style switching
    jQuery("#header-navigation .style").bind('mousedown', function () {
        if (editorHelpers.setDocumentData('settings.documentstyle',
            jQuery(this).attr(
                'data-style'))) {

            editorHelpers.setDisplay.document('settings.documentstyle',
                theDocument.settings.documentstyle);
            editorHelpers.documentHasChanged();
        }
        return false;
    });

    editorHelpers.setDisplay.document('settings.citationstyle', theDocument
        .settings.citationstyle);

    jQuery('span[data-citationstyle=' + theDocument.settings.citationstyle +
        ']').addClass('selected');

    // Citation Style switching
    jQuery("#header-navigation .citationstyle").bind('mousedown', function () {
        if (editorHelpers.setDocumentData('settings.citationstyle',
            jQuery(this).attr(
                'data-citationstyle'))) {
            editorHelpers.setDisplay.document('settings.citationstyle',
                theDocument.settings.citationstyle);
            editorHelpers.documentHasChanged();
            commentHelpers.layoutComments();
        }
        return false;
    });
    // Tools
    jQuery("#header-navigation .tools-item").bind('mousedown', function () {
        toolsHelpers.toolsEventHandler(jQuery(this).data('function'));
        return false;
    });

    editorHelpers.setPlaceholders();

    jQuery(document).on('blur',
        '#document-title,#document-contents,#metadata-subtitle,#metadata-abstract,#metadata-authors,#metadata-keywords',
        function () {
            editorHelpers.setPlaceholders();
        });
    jQuery(document).on('focus',
        '#document-title,#document-contents,#metadata-subtitle,#metadata-abstract,#metadata-authors,#metadata-keywords',
        function () {
            editorHelpers.setPlaceholders(jQuery(this).attr('id'));
        });

    editorHelpers.setDisplay.document('settings.papersize', theDocument.settings
        .papersize);

    // Paper size switching
    jQuery("#header-navigation .papersize").bind('mousedown', function () {
        if (editorHelpers.setDocumentData('settings.papersize',
            parseInt(jQuery(this).attr('data-paperheight')))) {
            editorHelpers.setDisplay.document('settings.papersize',
                theDocument.settings.papersize);
            editorHelpers.documentHasChanged();
        }
        return false;
    });

    editorHelpers.setDisplay.document('id', theDocument.id);

    // Disable papersize menu if we are dealing with a non CSS Regions browser
    if (jQuery('.pagination-simple').length > 0) {
        jQuery('.papersize-menu').unbind('mousedown');
        jQuery('.papersize-menu').addClass('disabled');
    }

    jQuery(document).on('mousedown', '.savecopy:not(.disabled)', function () {
        editorHelpers.getUpdatesFromInputFields(function () {
            editorHelpers.saveDocument();
        });
        exporter.savecopy(theDocument);
    });

    jQuery('.download').bind('mousedown', function () {
        editorHelpers.getUpdatesFromInputFields(function () {
            editorHelpers.saveDocument();
        });
        exporter.downloadNative(theDocument);
    });
    jQuery('.latex').bind('mousedown', function () {
        editorHelpers.getUpdatesFromInputFields(function () {
            editorHelpers.saveDocument();
        });
        exporter.downloadLatex(theDocument);
    });
    jQuery('.epub').bind('mousedown', function () {
        editorHelpers.getUpdatesFromInputFields(function () {
            editorHelpers.saveDocument();
        });
        exporter.downloadEpub(theDocument);
    });
    jQuery('.html').bind('mousedown', function () {
        editorHelpers.getUpdatesFromInputFields(function () {
            editorHelpers.saveDocument();
        });
        exporter.downloadHtml(theDocument);
    });
    jQuery('.print').bind('mousedown', function () {
        window.print();
    });
    jQuery('.close').bind('mousedown', function () {
        editorHelpers.getUpdatesFromInputFields(function () {
            editorHelpers.saveDocument();
        });
        window.location.href = '/';
    });

    editorHelpers.layoutMetadata();

    if (theDocumentValues.rights === 'r') {
        jQuery('#editor-navigation').hide();
        jQuery('.papersize-menu,.metadata-menu,.documentstyle-menu').addClass(
            'disabled');
    } else if (theDocumentValues.rights === 'w') {

        jQuery('.metadata-menu-item').bind('mousedown', editorHelpers.switchMetadata);

        jQuery('#metadata-subtitle, #metadata-abstract, #metadata-authors, #metadata-keywords').bind('blur',
            function () {
                if (jQuery.trim(this.textContent) === '') {
                    this.innerHTML = '

';
                };
            });

        if (!theDocumentValues.is_owner) {
            jQuery('span.share').addClass('disabled');
        }

        window.tracker = new ice.InlineChangeEditor({
            element: document.querySelector('#document-editable'),
            handleEvents: false,
             mergeBlocks: false,
            contentEditable: true,
            currentUser: {
                id: theUser.id,
                name: theUser.name
            },
            plugins: []
        }).startTracking();
        document.querySelector('#document-editable').removeAttribute(
            'contenteditable');
        jQuery('.editable').attr('contenteditable', true);
        mathHelpers.resetMath();

        diffHelpers.setup();

        // Set Auto-save to save every ten seconds
        setInterval(function () {
            if (theDocumentValues.changed) {
                theDocumentValues.sentHash = false;
                editorHelpers.getUpdatesFromInputFields(function () {
                    editorHelpers.saveDocument();
                });
            } else if (theDocumentValues.control && !theDocumentValues.sentHash && theDocumentValues.collaborativeMode) {
                theDocumentValues.sentHash = true;
                console.log('sending hash');
                serverCommunications.send({
                    type: 'hash',
                    hash: editorHelpers.docHash()
                })
            }
        }, 10000);

        // bind the share dialog to the button if the user is the document owner
        if (theDocumentValues.is_owner) {
            jQuery('.share').bind('mousedown', function () {
                accessrightsHelpers.createAccessRightsDialog([
                    theDocument.id
                ]);
            });
        }

        keyEvents.bindEvents();

        // Bind comment functions
        commentHelpers.bindEvents();

        var editableArea = document.querySelector("#document-editable");

        if (editableArea) {
            // Send paste to handlePaste
            editableArea.addEventListener('paste', paste.handlePaste, false);

            // Send cut to handleCut
            editableArea.addEventListener('cut', cut.handleCut, false);

            // Send key events on to the tracker directly.
            jQuery(editableArea).bind('keyup keypress mousedown mouseup',
                function (evt) {
                    if (theDocument.settings.tracking) {
                        return tracker.handleEvent(evt);
                    } else {
                        return true;
                    }
                });
        }

        // Set webpage title when document title changes
        jQuery('#document-title').bind('keyup paste change',
            function () {
                editorHelpers.setDisplay.document('title', jQuery(this).text()
                    .trim());
            });

        // When contents of document have changed, mark it as such
        jQuery('#document-editable').bind(
            'keyup paste change', function () {
                editorHelpers.documentHasChanged();
            });
        jQuery('.save').bind('mousedown', function () {
            editorHelpers.getUpdatesFromInputFields(function () {
                editorHelpers.saveDocument();
            });
            exporter.uploadNative(theDocument);
        });

        /* jQuery(window).on('beforeunload', function(){
            editorHelpers.getUpdatesFromInputFields(function () {
                editorHelpers.saveDocument();
            });
            if (theDocumentValues.collaborativeMode) {
                diffHelpers.handleChanges();
            }
            return gettext('Leave editor');
        }); */

        jQuery(document).on('click', '.pagination-footnote-item-container',
            function (e) {
                var footnote = document.getElementById(this.dataset.footnoteId);
                tracker._addNodeTracking(footnote, false, false);
            }
        );

            jQuery('.multibuttonsCover').each(function () {
                $.addDropdownBox(jQuery(this), jQuery(this).siblings(
                    '.fw-pulldown'));
            });

        //ice pulldown
        $.addDropdownBox(jQuery('#ice-control'), jQuery(
            '#ice-control .fw-pulldown'));

        editorHelpers.setDisplay.document('settings.tracking', theDocument.settings
            .tracking);
        editorHelpers.setDisplay.document('settings.tracking_show',
            theDocument.settings.tracking_show);

        jQuery('.ice-display').bind('mousedown', function () {
            editorHelpers.setDocumentData('settings.tracking_show', (!
                theDocument.settings
                .tracking_show));
            editorHelpers.setDisplay.document('settings.tracking_show',
                theDocument.settings.tracking_show);
            editorHelpers.documentHasChanged();
            return false;
        });

        if (theDocumentValues.is_owner) {
            jQuery('.ice-track').bind('mousedown', function () {
                editorHelpers.setDocumentData('settings.tracking', (!
                    theDocument.settings.tracking));
                editorHelpers.setDisplay.document('settings.tracking',
                    theDocument.settings.tracking);
                editorHelpers.documentHasChanged();
                return false;
            });

            jQuery('.ice-accept-all').bind('mousedown', function () {
                window.tracker.acceptAll();
                editorHelpers.documentHasChanged();
                return false;
            });

            jQuery('.ice-reject-all').bind('mousedown', function () {
                window.tracker.rejectAll();
                editorHelpers.documentHasChanged();
                return false;
            });

            // Bind in-text tracking menu
            trackingHelpers.bindEvents();
        } else {
            jQuery('.ice-track').addClass('disabled');
            jQuery('.ice-accept-all').addClass('disabled');
            jQuery('.ice-reject-all').addClass('disabled');
        }

        //open and close header
        jQuery('#open-close-header').bind('click', function () {
            var header_top = -92,
                toolnav_top = 0,
                content_top = 108;
            if (jQuery(this).hasClass('header-closed')) {
                jQuery(this).removeClass('header-closed');
                header_top = 0,
                toolnav_top = 92,
                content_top = 200;
            } else {
                jQuery(this).addClass('header-closed');
            }
            jQuery('#header').stop().animate({
                'top': header_top
            });
            jQuery('#editor-navigation').stop().animate({
                'top': toolnav_top
            });
            jQuery('#pagination-layout').stop()
                .animate({
                    'top': content_top
                }, {
                    'complete': function () {
                        commentHelpers.layoutComments();
                    }
                });
        });

    }
});

jQuery(document).bind("bibliography_ready", function (event) {
                        jQuery('.citationstyle-menu, .exporter-menu').each(function () {
                        jQuery.addDropdownBox(jQuery(this), jQuery(this).siblings('.fw-pulldown'));
                        jQuery(this).removeClass('disabled');
                        jQuery(this).removeClass('header-nav-item-disabled');
                        jQuery(this).addClass('header-nav-item');
                    });
                    citationHelpers.formatCitationsInDoc();
});
<commit_msg>don't disable page size menu in non-CSS Regions browsers<commit_after>/**
 * @file Set ups things on the editor page.
 * @copyright This file is part of Fidus Writer.
 *
 * Copyright (C) 2013 Takuto Kojima, Johannes Wilm.
 *
 * @license This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 *
 */
/** Whether the citation style before the current one was footnote based. This is used to determine whetherthe page needs to be reformatted.
 * @constant lastStyleUsedFootnotes
 */
var lastStyleUsedFootnotes = false;

// Functions to be executed at startup
jQuery(document).ready(function () {

    var documentStyleMenu = document.getElementById("documentstyle-list"), documentStyleMenuItem;

    // Enable toolbar menu
    jQuery('#menu1').ptMenu();

    //open dropdown for headermenu
    jQuery('.header-nav-item').each(function () {
        $.addDropdownBox(jQuery(this), jQuery(this).siblings(
            '.fw-pulldown'));
    });

    for (i = 0; i < documentStyleList.length; i++) {
        documentStyleMenuItem=document.createElement("li");
        documentStyleMenuItem.innerHTML = ""+documentStyleList[i].title+"";
        documentStyleMenu.appendChild(documentStyleMenuItem);
    }
});

// Functions to be executed when document has loaded
jQuery(document).bind('documentDataLoaded', function () {

    // We cannot download BibDB and ImageDB before we know if we are the document owner or not.
    bibliographyHelpers.init();
    usermediaHelpers.init();

    var set_document_style_timer = setTimeout(function () {
        clearTimeout(set_document_style_timer);
        //setDocumentstyle();
        editorHelpers.setDisplay.document('settings.documentstyle',
            theDocument.settings.documentstyle);
    }, 800);

    // Document Style switching
    jQuery("#header-navigation .style").bind('mousedown', function () {
        if (editorHelpers.setDocumentData('settings.documentstyle',
            jQuery(this).attr(
                'data-style'))) {

            editorHelpers.setDisplay.document('settings.documentstyle',
                theDocument.settings.documentstyle);
            editorHelpers.documentHasChanged();
        }
        return false;
    });

    editorHelpers.setDisplay.document('settings.citationstyle', theDocument
        .settings.citationstyle);

    jQuery('span[data-citationstyle=' + theDocument.settings.citationstyle +
        ']').addClass('selected');

    // Citation Style switching
    jQuery("#header-navigation .citationstyle").bind('mousedown', function () {
        if (editorHelpers.setDocumentData('settings.citationstyle',
            jQuery(this).attr(
                'data-citationstyle'))) {
            editorHelpers.setDisplay.document('settings.citationstyle',
                theDocument.settings.citationstyle);
            editorHelpers.documentHasChanged();
            commentHelpers.layoutComments();
        }
        return false;
    });
    // Tools
    jQuery("#header-navigation .tools-item").bind('mousedown', function () {
        toolsHelpers.toolsEventHandler(jQuery(this).data('function'));
        return false;
    });

    editorHelpers.setPlaceholders();

    jQuery(document).on('blur',
        '#document-title,#document-contents,#metadata-subtitle,#metadata-abstract,#metadata-authors,#metadata-keywords',
        function () {
            editorHelpers.setPlaceholders();
        });
    jQuery(document).on('focus',
        '#document-title,#document-contents,#metadata-subtitle,#metadata-abstract,#metadata-authors,#metadata-keywords',
        function () {
            editorHelpers.setPlaceholders(jQuery(this).attr('id'));
        });

    editorHelpers.setDisplay.document('settings.papersize', theDocument.settings
        .papersize);

    // Paper size switching
    jQuery("#header-navigation .papersize").bind('mousedown', function () {
        if (editorHelpers.setDocumentData('settings.papersize',
            parseInt(jQuery(this).attr('data-paperheight')))) {
            editorHelpers.setDisplay.document('settings.papersize',
                theDocument.settings.papersize);
            editorHelpers.documentHasChanged();
        }
        return false;
    });

    editorHelpers.setDisplay.document('id', theDocument.id);

    jQuery(document).on('mousedown', '.savecopy:not(.disabled)', function () {
        editorHelpers.getUpdatesFromInputFields(function () {
            editorHelpers.saveDocument();
        });
        exporter.savecopy(theDocument);
    });

    jQuery('.download').bind('mousedown', function () {
        editorHelpers.getUpdatesFromInputFields(function () {
            editorHelpers.saveDocument();
        });
        exporter.downloadNative(theDocument);
    });
    jQuery('.latex').bind('mousedown', function () {
        editorHelpers.getUpdatesFromInputFields(function () {
            editorHelpers.saveDocument();
        });
        exporter.downloadLatex(theDocument);
    });
    jQuery('.epub').bind('mousedown', function () {
        editorHelpers.getUpdatesFromInputFields(function () {
            editorHelpers.saveDocument();
        });
        exporter.downloadEpub(theDocument);
    });
    jQuery('.html').bind('mousedown', function () {
        editorHelpers.getUpdatesFromInputFields(function () {
            editorHelpers.saveDocument();
        });
        exporter.downloadHtml(theDocument);
    });
    jQuery('.print').bind('mousedown', function () {
        window.print();
    });
    jQuery('.close').bind('mousedown', function () {
        editorHelpers.getUpdatesFromInputFields(function () {
            editorHelpers.saveDocument();
        });
        window.location.href = '/';
    });

    editorHelpers.layoutMetadata();

    if (theDocumentValues.rights === 'r') {
        jQuery('#editor-navigation').hide();
        jQuery('.papersize-menu,.metadata-menu,.documentstyle-menu').addClass(
            'disabled');
    } else if (theDocumentValues.rights === 'w') {

        jQuery('.metadata-menu-item').bind('mousedown', editorHelpers.switchMetadata);

        jQuery('#metadata-subtitle, #metadata-abstract, #metadata-authors, #metadata-keywords').bind('blur',
            function () {
                if (jQuery.trim(this.textContent) === '') {
                    this.innerHTML = '

';
                };
            });

        if (!theDocumentValues.is_owner) {
            jQuery('span.share').addClass('disabled');
        }

        window.tracker = new ice.InlineChangeEditor({
            element: document.querySelector('#document-editable'),
            handleEvents: false,
             mergeBlocks: false,
            contentEditable: true,
            currentUser: {
                id: theUser.id,
                name: theUser.name
            },
            plugins: []
        }).startTracking();
        document.querySelector('#document-editable').removeAttribute(
            'contenteditable');
        jQuery('.editable').attr('contenteditable', true);
        mathHelpers.resetMath();

        diffHelpers.setup();

        // Set Auto-save to save every ten seconds
        setInterval(function () {
            if (theDocumentValues.changed) {
                theDocumentValues.sentHash = false;
                editorHelpers.getUpdatesFromInputFields(function () {
                    editorHelpers.saveDocument();
                });
            } else if (theDocumentValues.control && !theDocumentValues.sentHash && theDocumentValues.collaborativeMode) {
                theDocumentValues.sentHash = true;
                console.log('sending hash');
                serverCommunications.send({
                    type: 'hash',
                    hash: editorHelpers.docHash()
                })
            }
        }, 10000);

        // bind the share dialog to the button if the user is the document owner
        if (theDocumentValues.is_owner) {
            jQuery('.share').bind('mousedown', function () {
                accessrightsHelpers.createAccessRightsDialog([
                    theDocument.id
                ]);
            });
        }

        keyEvents.bindEvents();

        // Bind comment functions
        commentHelpers.bindEvents();

        var editableArea = document.querySelector("#document-editable");

        if (editableArea) {
            // Send paste to handlePaste
            editableArea.addEventListener('paste', paste.handlePaste, false);

            // Send cut to handleCut
            editableArea.addEventListener('cut', cut.handleCut, false);

            // Send key events on to the tracker directly.
            jQuery(editableArea).bind('keyup keypress mousedown mouseup',
                function (evt) {
                    if (theDocument.settings.tracking) {
                        return tracker.handleEvent(evt);
                    } else {
                        return true;
                    }
                });
        }

        // Set webpage title when document title changes
        jQuery('#document-title').bind('keyup paste change',
            function () {
                editorHelpers.setDisplay.document('title', jQuery(this).text()
                    .trim());
            });

        // When contents of document have changed, mark it as such
        jQuery('#document-editable').bind(
            'keyup paste change', function () {
                editorHelpers.documentHasChanged();
            });
        jQuery('.save').bind('mousedown', function () {
            editorHelpers.getUpdatesFromInputFields(function () {
                editorHelpers.saveDocument();
            });
            exporter.uploadNative(theDocument);
        });

        /* jQuery(window).on('beforeunload', function(){
            editorHelpers.getUpdatesFromInputFields(function () {
                editorHelpers.saveDocument();
            });
            if (theDocumentValues.collaborativeMode) {
                diffHelpers.handleChanges();
            }
            return gettext('Leave editor');
        }); */

        jQuery(document).on('click', '.pagination-footnote-item-container',
            function (e) {
                var footnote = document.getElementById(this.dataset.footnoteId);
                tracker._addNodeTracking(footnote, false, false);
            }
        );

            jQuery('.multibuttonsCover').each(function () {
                $.addDropdownBox(jQuery(this), jQuery(this).siblings(
                    '.fw-pulldown'));
            });

        //ice pulldown
        $.addDropdownBox(jQuery('#ice-control'), jQuery(
            '#ice-control .fw-pulldown'));

        editorHelpers.setDisplay.document('settings.tracking', theDocument.settings
            .tracking);
        editorHelpers.setDisplay.document('settings.tracking_show',
            theDocument.settings.tracking_show);

        jQuery('.ice-display').bind('mousedown', function () {
            editorHelpers.setDocumentData('settings.tracking_show', (!
                theDocument.settings
                .tracking_show));
            editorHelpers.setDisplay.document('settings.tracking_show',
                theDocument.settings.tracking_show);
            editorHelpers.documentHasChanged();
            return false;
        });

        if (theDocumentValues.is_owner) {
            jQuery('.ice-track').bind('mousedown', function () {
                editorHelpers.setDocumentData('settings.tracking', (!
                    theDocument.settings.tracking));
                editorHelpers.setDisplay.document('settings.tracking',
                    theDocument.settings.tracking);
                editorHelpers.documentHasChanged();
                return false;
            });

            jQuery('.ice-accept-all').bind('mousedown', function () {
                window.tracker.acceptAll();
                editorHelpers.documentHasChanged();
                return false;
            });

            jQuery('.ice-reject-all').bind('mousedown', function () {
                window.tracker.rejectAll();
                editorHelpers.documentHasChanged();
                return false;
            });

            // Bind in-text tracking menu
            trackingHelpers.bindEvents();
        } else {
            jQuery('.ice-track').addClass('disabled');
            jQuery('.ice-accept-all').addClass('disabled');
            jQuery('.ice-reject-all').addClass('disabled');
        }

        //open and close header
        jQuery('#open-close-header').bind('click', function () {
            var header_top = -92,
                toolnav_top = 0,
                content_top = 108;
            if (jQuery(this).hasClass('header-closed')) {
                jQuery(this).removeClass('header-closed');
                header_top = 0,
                toolnav_top = 92,
                content_top = 200;
            } else {
                jQuery(this).addClass('header-closed');
            }
            jQuery('#header').stop().animate({
                'top': header_top
            });
            jQuery('#editor-navigation').stop().animate({
                'top': toolnav_top
            });
            jQuery('#pagination-layout').stop()
                .animate({
                    'top': content_top
                }, {
                    'complete': function () {
                        commentHelpers.layoutComments();
                    }
                });
        });

    }
});

jQuery(document).bind("bibliography_ready", function (event) {
                        jQuery('.citationstyle-menu, .exporter-menu').each(function () {
                        jQuery.addDropdownBox(jQuery(this), jQuery(this).siblings('.fw-pulldown'));
                        jQuery(this).removeClass('disabled');
                        jQuery(this).removeClass('header-nav-item-disabled');
                        jQuery(this).addClass('header-nav-item');
                    });
                    citationHelpers.formatCitationsInDoc();
});
<|endoftext|>


<commit_before>'use strict';
import React, {
  Alert,
  AsyncStorage,
  Component,
  Platform,
  StyleSheet,
  Text,
  View,
} from 'react-native';

import { Provider } from 'react-redux'
import { config as configApiClient } from 'goommerce-api-client';
import configureStore, { errorActions } from 'goommerce-redux';
import { cloudinaryConfig } from 'react-cloudinary';
import OneSignal from 'react-native-onesignal';

import App from './containers/App';

cloudinaryConfig({ cloud_name: 'linkshops', crop: 'limit' });
OneSignal.configure({
  onNotificationOpened(message, data, isActive) {
    if (isActive) {
      Alert.alert('New Order!!!', message);
    }
  }
});

if (__DEV__) {
  configApiClient({ apiRoot: (Platform.OS === 'ios') ? 'http://localhost:8080' : 'http://10.0.3.2:8080' });
} else {
  configApiClient({ apiRoot: 'http://v1.linkshops.com' });
}
const store = configureStore();

store.subscribe(() => {
  const { error: { message, status } } = store.getState();
  if (message) {
    Alert.alert(
      'Error',
      message,
      [{
        text: 'OK', onPress: () => {
          errorActions.resetError()(store.dispatch);
          if (status === 401) {
            AsyncStorage.removeItem('bearer').then(() => store.dispatch( { type: 'LOGOUT' }));
          }
        }
      }],
    );
  }
});

export default React.createClass({
  getInitialState() {
    return { loaded: false };
  },
  componentDidMount() {
    AsyncStorage.getItem('bearer').then(
      (bearer) => {
        store.dispatch({ type: 'LOGIN', payload: { bearer } });
        this.setState({ loaded: true });
      }
    );
  },
  render() {
    if (!this.state.loaded) {
      return (
        <View>
          <Text>
            Loading...
          </Text>
        </View>
      );
    }
    return (
      <Provider store={store}>
        <App />
      </Provider>
    );
  }
});
<commit_msg>production default: v1 -> t.<commit_after>'use strict';
import React, {
  Alert,
  AsyncStorage,
  Component,
  Platform,
  StyleSheet,
  Text,
  View,
} from 'react-native';

import { Provider } from 'react-redux'
import { config as configApiClient } from 'goommerce-api-client';
import configureStore, { errorActions } from 'goommerce-redux';
import { cloudinaryConfig } from 'react-cloudinary';
import OneSignal from 'react-native-onesignal';

import App from './containers/App';

cloudinaryConfig({ cloud_name: 'linkshops', crop: 'limit' });
OneSignal.configure({
  onNotificationOpened(message, data, isActive) {
    if (isActive) {
      Alert.alert('New Order!!!', message);
    }
  }
});

if (__DEV__) {
  configApiClient({ apiRoot: (Platform.OS === 'ios') ? 'http://localhost:8080' : 'http://10.0.3.2:8080' });
} else {
  configApiClient({ apiRoot: 'http://t.linkshops.com' });
}
const store = configureStore();

store.subscribe(() => {
  const { error: { message, status } } = store.getState();
  if (message) {
    Alert.alert(
      'Error',
      message,
      [{
        text: 'OK', onPress: () => {
          errorActions.resetError()(store.dispatch);
          if (status === 401) {
            AsyncStorage.removeItem('bearer').then(() => store.dispatch( { type: 'LOGOUT' }));
          }
        }
      }],
    );
  }
});

export default React.createClass({
  getInitialState() {
    return { loaded: false };
  },
  componentDidMount() {
    AsyncStorage.getItem('bearer').then(
      (bearer) => {
        store.dispatch({ type: 'LOGIN', payload: { bearer } });
        this.setState({ loaded: true });
      }
    );
  },
  render() {
    if (!this.state.loaded) {
      return (
        <View>
          <Text>
            Loading...
          </Text>
        </View>
      );
    }
    return (
      <Provider store={store}>
        <App />
      </Provider>
    );
  }
});
<|endoftext|>


<commit_before>// -----------------------------------------------------------------------
//                             HEP Random
//                       --- HepJamesRandom ---
//                      module implementation file
// -----------------------------------------------------------------------
//
// This algorithm implements the original universal random number generator
// as proposed by Marsaglia & Zaman in report FSU-SCRI-87-50 and coded
// in FORTRAN77 by Fred James as the RANMAR generator, part of the MATHLIB
// HEP library. After that was developed in C++ as it is shown below:

// =======================================================================
// C++:
// =======================================================================
// Gabriele Cosmo - Created: 5th September 1995
//                - Fixed a bug in setSeed(): 26th February 1996
//                - Minor corrections: 31st October 1996
//                - Added methods for engine status: 19th November 1996
//                - Fixed bug in setSeeds(): 15th September 1997
// J.Marraffino   - Added stream operators and related constructor.
//                  Added automatic seed selection from seed table and
//                  engine counter: 16th Feb 1998
// Ken Smith      - Added conversion operators:  6th Aug 1998
// J. Marraffino  - Remove dependence on hepString class  13 May 1999
// V. Innocente   - changed pointers to indices     3 may 2000
// M. Fischler    - In restore, checkFile for file not found    03 Dec 2004
// M. Fischler    - Methods for distrib. instacne save/restore  12/8/04
// M. Fischler    - split get() into tag validation and
//                  getState() for anonymous restores           12/27/04
// M. Fischler    - Enforcement that seeds be non-negative
//                  (lest the sequence be non-random)            2/14/05
// M. Fischler    - put/get for vectors of ulongs               3/14/05
// M. Fischler    - State-saving using only ints, for portability 4/12/05
// =======================================================================

// JavaScript version is developed as it is shown below:

// =======================================================================
// JavaScript:
// =======================================================================
// F. Quinonez - Created 2015-10-19
// =======================================================================

define( [], function(){
  "use strict";

  // Number of instances with automatic seed selection
  var numberOfEngines = 0;
  // Maximum index into the seed table
  var maxIndex = 215;

  function JamesRandom( name, seed ){
    this.name = name;
    this.u = new Array( 97 );
    this.c;
    this.cd;
    this.cm;
    this.i97;
    this.j97;

    setSeed( seed, 0 );
    setSeeds( theSeed, 0 );

  }

  JamesRandom.MarkerLen = 64; // Enough room to hold a begin or end marker.

  JamesRandom.engineName = function(){ return "HepJamesRandom"; };
  JamesRandom.beginTag = function(){ return "JamesRandom-begin"; };

  JamesRandom.prototype = {
    constructor: JamesRandom,
    name: function(){ return "HepJamesRandom"; },

    // Returns a pseudo random number between 0 and 1 (excluding the end points)
    flat: function(){
      var uni;

      do {
         uni = this.u[this.i97] - this.u[this.j97];
         if ( uni < 0.0 ) uni++;
         this.u[this.i97] = uni;

         if (this.i97 == 0) this.i97 = 96;
         else this.i97--;

         if (this.j97 == 0) this.j97 = 96;
         else this.j97--;

         this.c -= this.cd;
         if (this.c < 0.0) this.c += this.cm;

         uni -= this.c;
         if (uni < 0.0) uni += 1.0;
      } while ( uni <= 0.0 || uni >= 1.0 );

      return uni;

    },

    // Fills the array "vect" of specified size with flat random values.
    flatArray: function( size, vect ){
      var i;

      for (i=0; i<size; ++i) {
        vect[i] = flat();
      }

    },

    // Sets the state of the algorithm according to seed.
    setSeed: function( seed, dum ){
      // The input value for "seed" should be within the range [0,900000000]
      //
      // Negative seeds result in serious flaws in the randomness;
      // seeds above 900000000 are OK because of the %177 in the expression for i,
      // but may have the same effect as other seeds below 900000000.

      var m, n, mm; // integers
      var s, t;

      if( seed < 0 ){
        var msg = "Seed for HepJamesRandom must be non-negative. Seed value supplied was" + seed + ". Using its absolute value instead.";
        console.log( msg );
        seed = -seed;
      }

      var ij = seed / 30082;
      var kl = seed - ( 30082 * ij );
      var i = ( ( ij / 177 ) % 177 ) + 2;
      var j = ( ij % 177 ) + 2;
      var k = ( ( kl / 169 ) % 178 ) + 1;
      var l = kl % 169;

      theSeed = seed;

      for ( n = 1 ; n < 98 ; n++ ) {
        s = 0.0;
        t = 0.5;
        for ( m = 1 ; m < 25 ; m++) {
          mm = ( ( (i*j) % 179 ) * k ) % 179;
          i = j;
          j = k;
          k = mm;
          l = ( 53 * l + 1 ) % 169;
          if ( (l*mm % 64 ) >= 32 )
            s += t;
          t *= 0.5;
        }
        this.u[n-1] = s;
      }
      this.c = 362436.0 / 16777216.0;
      this.cd = 7654321.0 / 16777216.0;
      this.cm = 16777213.0 / 16777216.0;

      this.i97 = 96;
      this.j97 = 32;
    },

    // Sets the state of the zero terminated array of seeds. Only the first seed is used.
    setSeeds: function( seeds, dum ){
      setSeed(seeds? seeds: 19780503L, 0);
      theSeeds = seeds;
    },

    // Sets on filename the current engine status.
    saveStatus: function( filename ){
      if( filename === "" ) filename = "JamesRand.conf";

    },

    // Reads from filename the last saved engine status.
    restoreStatus: function( filename ){
      if( filename === "" ) filename = "JamesRand.conf";

    } /*,

    showStatus: function(){

    },

    put: function(){

    },

    get: function(){

    },

    getState: function(){

    }*/

  }

  return JamesRandom;

});

<commit_msg>Removed BBT/JamesRandom.js<commit_after><|endoftext|>


<commit_before>var Changelog = {
    offset: document.querySelector(".changelog-offset"),
    changelog: document.querySelector(".changelog"),
    version: localStorage.getItem("version"),
    runnningVersion: ipcRenderer.sendSync("changelog", "getVersion"),

    init: () => {
        if (!Changelog.version || Changelog.version < Changelog.runnningVersion) {
            localStorage.setItem("version", Changelog.runnningVersion);

            Changelog.setTitle();
            Changelog.show();
        }
    },

    show: () => {
        Changelog.offset.addEventListener("click", Changelog.close, false);
        Changelog.changelog.querySelector(".close").addEventListener("click", Changelog.close, false);

        Changelog.offset.style.display = "block";
        Changelog.changelog.style.display = "block";
    },

    close: () => {
        Changelog.changelog.className += " hide";
        Changelog.offset.className += " hide";

        setTimeout(() => {
            Changelog.changelog.remove();
            Changelog.offset.remove()
        }, 200)
    },

    setTitle: (txt) => {
        if (!txt) {
            Changelog.changelog.querySelector(".version").innerText = Changelog.runnningVersion;
        } else {
            Changelog.changelog.querySelector(".title").innerText = txt;
        }
    },

    setContent: (html) => {
        if (!html) {
            html = ipcRenderer.sendSync("changelog", "getChangelog");
        }

        Changelog.changelog.querySelector(".changelogContent").innerHTML = html;
    }

}

Changelog.show();
Changelog.setTitle();
Changelog.setContent();
<commit_msg>Removed testing code<commit_after>var Changelog = {
    offset: document.querySelector(".changelog-offset"),
    changelog: document.querySelector(".changelog"),
    version: localStorage.getItem("version"),
    runnningVersion: ipcRenderer.sendSync("changelog", "getVersion"),

    init: () => {
        if (!Changelog.version || Changelog.version < Changelog.runnningVersion) {
            localStorage.setItem("version", Changelog.runnningVersion);

            Changelog.setTitle();
            Changelog.setContent();
            Changelog.show();
        }
    },

    show: () => {
        Changelog.offset.addEventListener("click", Changelog.close, false);
        Changelog.changelog.querySelector(".close").addEventListener("click", Changelog.close, false);

        Changelog.offset.style.display = "block";
        Changelog.changelog.style.display = "block";
    },

    close: () => {
        Changelog.changelog.className += " hide";
        Changelog.offset.className += " hide";

        setTimeout(() => {
            Changelog.changelog.remove();
            Changelog.offset.remove()
        }, 200)
    },

    setTitle: (txt) => {
        if (!txt) {
            Changelog.changelog.querySelector(".version").innerText = Changelog.runnningVersion;
        } else {
            Changelog.changelog.querySelector(".title").innerText = txt;
        }
    },

    setContent: (html) => {
        if (!html) {
            html = ipcRenderer.sendSync("changelog", "getChangelog");
        }

        Changelog.changelog.querySelector(".changelogContent").innerHTML = html;
    }

}
<|endoftext|>


<commit_before>/**
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

/**
 * Triggers when a user location is updated
 */
exports.sendFollowerNotification = functions.database.ref('/users/{userId}/{location}').onWrite(event => {
  const userId = event.params.userId;
  const location = event.data.val();

  // If un-follow we exit the function.
  if (!event.data.val()) {
    return console.log('User ', userId, 'location', location);
  }
  console.log('User :', userId, ' updated location:', location);

  // Get the notification token for the user
  const getDeviceTokensPromise = admin.database().ref(`/users/${userId}/gcmid`).once('value');

  // Get the lists associated to the current user location
  const getStoreListsPromise = admin.database().ref(`/stores/${location}`).once('value');

  // Get the user's friend list
  const getUserFriendsPromise = admin.database().ref(`/users/${userId}/friends`).once('value');

  return Promise.all([getDeviceTokensPromise, getStoreListsPromise, getUserFriendsPromise]).then(results => {

	 /*
      LOGIC:
      1. For each open list in the store:
          - Get User Id
          - Check if userId exists in FriendList
          - If exists, add friend name and list id to the payload
    */

    const tokensSnapshot = results[0];
    const listsSnapshot = results[1];
    const friendsSnapshot = results[2];

    console.log(tokensSnapshot.val());
    console.log(listsSnapshot.val());
    console.log(friendsSnapshot.val());

	  // Check if there are any lists attached to the store
    console.log('There are', listsSnapshot.numChildren(), 'lists available.');

    // Check if userIds belong to the current user's friend list
    // Entry Format=> KEY: ListId format: listId, VALUE: userId-status
    var matchedListIds = [];
    var listMap = listsSnapshot.val();
    var friends = friendsSnapshot.val();

    for(var key in listMap) {
        var listId = key;
        var userId = listMap[key];

        if (friends.indexOf(userId) > -1) {
          matchedListIds.push(listId);
        }
    }

    console.log("Matched Lists: " + matchedListIds.toString());
    console.log("Matched Lists Count: " + matchedListIds.length);

    if (matchedListIds.length == 0) {
      console.log("Exiting: No List Match");
      return;
    }

    // Notification details
    const payload = {
      data: {
        payload: 'Some of your friends need a few things from ' + location + '. Would you like to pick those up?',
        listid: matchedListIds.toString(),
      }
    };

    // Listing all tokens.
    const token = tokensSnapshot.val();

    // Send notifications to all tokens.
    return admin.messaging().sendToDevice(token, payload).then(response => {
      // For each message check if there was an error.
      const tokensToRemove = [];
      response.results.forEach((result, index) => {
        const error = result.error;
        if (error) {
          console.error('Failure sending notification to', tokens[index], error);
          // Cleanup the tokens who are not registered anymore.
          if (error.code === 'messaging/invalid-registration-token' ||
              error.code === 'messaging/registration-token-not-registered') {
            tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
          }
        }
      });
      return Promise.all(tokensToRemove);
    });
  });
});

/**
 * Triggers when a Shopper accepts an order
 */
exports.sendListStatusUpdateNotification = functions.database.ref('/lists/{listId}').onWrite(event => {
  const listId = event.params.listId;
  const listData = event.data.val();
  const recipient = "SHOPPER";

  if (!event.data.val()) {
    return console.log('List data not available');
  }
  console.log('List Data :', listData.toString());

  var status = listData["status"];
  var notificationMessage = "";
  if (status == 'PICKED_UP') {
    notificationMessage = "Your order has been picked up by one of your friends";
  } else if (status == "COMPLETED") {
    notificationMessage = "Your order has been completed by one of your friends";
  } else if (status == "OUT_FOR_DELIVERY") {
    notificationMessage = "Your order is out for delivery by one of your friends";
  } else {
    console.log ("No action needed. Status: " + status);
    return -1;
  }

  // Get the notification token for the user
  var userId = listData["userId"];
  const getDeviceTokensPromise = admin.database().ref(`/users/${userId}/gcmid`).once('value');

  return Promise.all([getDeviceTokensPromise]).then(results => {

    const tokensSnapshot = results[0];
    console.log(tokensSnapshot.val());

    // Notification details
    const payload = {
      data: {
        payload: notificationMessage,
        listid: listId,
        recipient : recipient
      }
    };

    // Listing all tokens.
    const token = tokensSnapshot.val();

    // Send notifications to all tokens.
    return admin.messaging().sendToDevice(token, payload).then(response => {
      // For each message check if there was an error.
      const tokensToRemove = [];
      response.results.forEach((result, index) => {
        const error = result.error;
        if (error) {
          console.error('Failure sending notification to', tokens[index], error);
          // Cleanup the tokens who are not registered anymore.
          if (error.code === 'messaging/invalid-registration-token' ||
              error.code === 'messaging/registration-token-not-registered') {
            tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
          }
        }
      });
      return Promise.all(tokensToRemove);
    });
  });
});<commit_msg>Firebase Functions: Updated order status update notification to include shopper Name<commit_after>/**
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

/**
 * Triggers when a user location is updated
 */
exports.sendFollowerNotification = functions.database.ref('/users/{userId}/{location}').onWrite(event => {
  const userId = event.params.userId;
  const location = event.data.val();

  // If un-follow we exit the function.
  if (!event.data.val()) {
    return console.log('User ', userId, 'location', location);
  }
  console.log('User :', userId, ' updated location:', location);

  // Get the notification token for the user
  const getDeviceTokensPromise = admin.database().ref(`/users/${userId}/gcmid`).once('value');

  // Get the lists associated to the current user location
  const getStoreListsPromise = admin.database().ref(`/stores/${location}`).once('value');

  // Get the user's friend list
  const getUserFriendsPromise = admin.database().ref(`/users/${userId}/friends`).once('value');

  return Promise.all([getDeviceTokensPromise, getStoreListsPromise, getUserFriendsPromise]).then(results => {

	 /*
      LOGIC:
      1. For each open list in the store:
          - Get User Id
          - Check if userId exists in FriendList
          - If exists, add friend name and list id to the payload
    */

    const tokensSnapshot = results[0];
    const listsSnapshot = results[1];
    const friendsSnapshot = results[2];

    console.log(tokensSnapshot.val());
    console.log(listsSnapshot.val());
    console.log(friendsSnapshot.val());

	  // Check if there are any lists attached to the store
    console.log('There are', listsSnapshot.numChildren(), 'lists available.');

    // Check if userIds belong to the current user's friend list
    // Entry Format=> KEY: ListId format: listId, VALUE: userId-status
    var matchedListIds = [];
    var listMap = listsSnapshot.val();
    var friends = friendsSnapshot.val();

    for(var key in listMap) {
        var listId = key;
        var userId = listMap[key];

        if (friends.indexOf(userId) > -1) {
          matchedListIds.push(listId);
        }
    }

    console.log("Matched Lists: " + matchedListIds.toString());
    console.log("Matched Lists Count: " + matchedListIds.length);

    if (matchedListIds.length == 0) {
      console.log("Exiting: No List Match");
      return;
    }

    // Notification details
    const payload = {
      data: {
        payload: 'Some of your friends need a few things from ' + location + '. Would you like to pick those up?',
        listid: matchedListIds.toString(),
      }
    };

    // Listing all tokens.
    const token = tokensSnapshot.val();

    // Send notifications to all tokens.
    return admin.messaging().sendToDevice(token, payload).then(response => {
      // For each message check if there was an error.
      const tokensToRemove = [];
      response.results.forEach((result, index) => {
        const error = result.error;
        if (error) {
          console.error('Failure sending notification to', tokens[index], error);
          // Cleanup the tokens who are not registered anymore.
          if (error.code === 'messaging/invalid-registration-token' ||
              error.code === 'messaging/registration-token-not-registered') {
            tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
          }
        }
      });
      return Promise.all(tokensToRemove);
    });
  });
});

/**
 * Triggers when a Shopper accepts an order
 */
exports.sendListStatusUpdateNotification = functions.database.ref('/lists/{listId}').onWrite(event => {
  const listId = event.params.listId;
  const listData = event.data.val();
  const recipient = "SHOPPER";

  if (!event.data.val()) {
    return console.log('List data not available');
  }
  console.log('List Data :', listData.toString());

  var shopperName = "shopper_name" in listData ? listData["shopper_name"] : "";
  var storeName = listData["store"];

  var status = listData["status"];
  var notificationMessage = "";
  if (status == 'PICKED_UP') {
    notificationMessage = shopperName + " has picked up your items from " + storeName;
  } else if (status == "COMPLETED") {
    notificationMessage = shopperName + " has paid for your items from " + storeName;
  } else if (status == "OUT_FOR_DELIVERY") {
    notificationMessage = shopperName + " is on the way with your items from " + storeName;
  } else {
    console.log ("No action needed. Status: " + status);
    return -1;
  }

  // Get the notification token for the user
  var userId = listData["userId"];
  const getDeviceTokensPromise = admin.database().ref(`/users/${userId}/gcmid`).once('value');

  return Promise.all([getDeviceTokensPromise]).then(results => {

    const tokensSnapshot = results[0];
    console.log(tokensSnapshot.val());

    // Notification details
    const payload = {
      data: {
        payload: notificationMessage,
        listid: listId,
        recipient : recipient
      }
    };

    // Listing all tokens.
    const token = tokensSnapshot.val();

    // Send notifications to all tokens.
    return admin.messaging().sendToDevice(token, payload).then(response => {
      // For each message check if there was an error.
      const tokensToRemove = [];
      response.results.forEach((result, index) => {
        const error = result.error;
        if (error) {
          console.error('Failure sending notification to', tokens[index], error);
          // Cleanup the tokens who are not registered anymore.
          if (error.code === 'messaging/invalid-registration-token' ||
              error.code === 'messaging/registration-token-not-registered') {
            tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
          }
        }
      });
      return Promise.all(tokensToRemove);
    });
  });
});<|endoftext|>