<commit_before>import React, {Component} from "react";
import { connect } from "react-redux";
import _ from "lodash";

import {
  loadStories
} from "../../actions";

import {StoryList} from "../../components";
import Spinner from "react-spinner";

export class Apollo11Explorer extends Component {
  componentWillMount() {
    this.props.loadStories();
  }
  render() {
    if (this.props.loading) {
      return (

Loading Stories...

          <Spinner />

      );
    }
		const Stories = _.sortBy(this.props.stories,"met_start");

    return (

Show All

July 16-24

Day 1

July 16th, 1969

Day 2

July 17th, 1969

Day 3

July 18th, 1969

Day 4

July 19th, 1969

Day 5

July 20th, 1969

Day 6

July 21st, 1969

Day 7

July 22nd, 1969

Day 8

July 23rd, 1969

Day 9

July 24th, 1969

  				<DayDisplay day={this.props.params.missionDay} allstories={Stories}/>

    );
  }
}

export function DayDisplay({day,allstories}){
  var imgUrl;
  var label;
  var text;
  var mstart;
  var mend;
	var targetstories;

  switch(day){
		//DT - these imgur links below need to be replaced at some point as well. The current diagram is a modified version of one I found on google images. It should also be updated/replaced at some point.
		//DT - mstart / mend assume milliseconds from mission start for value.
    case "1":
      imgUrl = "http://i.imgur.com/s9ixciq.jpg";
      label = "Day 1 - July 16th, 1969";
      text = "The first day of the mission, the Saturn V rocket is launched from Cape Kennedy, Florida. It carries 3 astronauts: Commander Neil Armstrong, Command Module Pilot Michael Collins, and Lunar Module Pilot Edwin 'Buzz' Aldrin. Three stages of the Saturn V rocket are activated and the first two jettisoned until the spacecraft begins Earth orbit. After a full trip around the Earth, the third stage rockets fire again, and the astronauts are sent on their lunar trajectory. After a time, the third stage rocket is jettisoned to remove it from the flight path. On course for the moon, the astronauts go to sleep and prepare for the next day."
      mstart = 0;
      mend = 55680000;
      break;
    case "2":
      imgUrl = "http://i.imgur.com/0ChVX12.jpg";
      label = "Day 2 - July 17th, 1969";
      text = "A relatively uneventful day, Mission Control briefs the astronauts on news and current events back on earth. The spacecraft proceeds on its established trajectory, making some minor course corrections along the way. This evening, the astronauts conduct their first color telecast from space, mostly showing the view from within the command module."
      mstart = 55680001;
      mend = 142080000;
      break;
    case "3":
      imgUrl = "http://i.imgur.com/h7sOlQP.jpg";
      label = "Day 3 - July 18th, 1969";
      text = "Much like the previous day, the spacecraft continues on its trajectory. Housekeeping duties are performed including checks of fuel and oxygen reserves. Another telecast is coordinated by the crew, showing more of the Command Module, and including shots of Armstrong and Aldrin climbing through the Lunar Module hatch."
      mstart = 142080001;
      mend = 228479999;
      break;
    case "4":
      imgUrl = "http://i.imgur.com/Xi1tJna.jpg";
      label = "Day 4 - July 19th, 1969";
      text = "This afternoon, Lunar Orbit Insertion begins and, as the spacecraft goes through orbit, it passes behind the Moon, breaking radio contact with Earth for the first time in the mission. As orbit continues, the crew begin a telecast of the Moon's surface, focusing on the landing site. The Lunar Module is checked on once more for the night as the crew prepares for the landing the next day."
      mstart = 228480000;
      mend = 314879998;
      break;
    case "5":
      imgUrl = "http://i.imgur.com/G7Kl4P7.jpg";
      label = "Day 5 - July 20th, 1969";
      text = "This morning, Armstrong and Aldrin crawl into the Lunar Module and separate from Collins, who will stay in the Command Module during the moonwalk. This afternoon, the Lunar module makes its landing approach on the Lunar surface. Once the landing craft settles down in the Sea of Tranquility, Armstrong radios Mission Control, saying the famous words 'The Eagle has landed.' A few hours later, Armstrong and Aldrin begin their moonwalk, collecting samples and taking photos as they go. During this time, they plant the now-famous American flag on the lunar surface and set up several forms of monitoring equipment to collect and broadcast data back to Earth."
      mstart = 314879999;
      mend = 401279997;
      break;
    case "6":
      imgUrl = "http://i.imgur.com/FeQVo3A.jpg";
      label = "Day 6 - July 21st, 1969";
      text = "Shortly after midnight on this day, the moonwalkers confirm that they have completed all tasks asked of them on the lunar surface and, once confirmed, return to the landing craft. After removing the spacesuits that have sustained them for the last 3 hours, they go to sleep. When they awaken a few hours later, they begin ascent in the Lunar Module, using its descent stage as a launchpad. As the Lunar module completes its redocking with the Command Module, the landing craft is jettisoned."
      mstart = 401279998;
      mend = 487679996;
      break;
    case "7":
      imgUrl = "http://i.imgur.com/gcEVvU5.jpg";
      label = "Day 7 - July 22nd, 1969";
      text = "On this day, the spacecraft begins its transearth injection burn, sending the crew homeward. As it begins to be pulled in by the Earth's gravity, the crew makes a slight course correction and then later performs another live telecast to Earth."
      mstart = 487679997;
      mend = 574079995;
      break;
    case "8":
      imgUrl = "http://i.imgur.com/9pv1ERJ.jpg";
      label = "Day 8 - July 23rd, 1969";
      text = "A very uneventful day, the spacecraft continues its path towards Earth as the crew performs checks on all systems and talks with Mission Control. This evening, the final color TV transmission is made."
      mstart = 574079996;
      mend = 660479994;
      break;
    case "9":
      imgUrl = "http://i.imgur.com/6PezjeV.jpg";
      label = "Day 9 - July 24th, 1969";
      text = "As the spacecraft approaches its splashdown, the Service Module is jettisoned. Later, the Command module re-enters Earth's atmosphere and splashes down 825 nautical miles southwest of Honolulu, Hawaii and approximately 13 nautical miles away from the recovery ship. Half an hour later, the astronauts emerge from the module. Later this day, President Nixon calls the Apollo mission the 'greatest week in the history of the world since the Creation.'"
      mstart = 660479995;
      mend = 746879993;
      break;
    default:
      imgUrl = "https://s-media-cache-ak0.pinimg.com/originals/a0/d7/c0/a0d7c07a7893f9ed93bb4970bab41629.jpg";
      label = "Apollo 11";
      text = "The Apollo 11 mission " //DT - This needs to be updated
      mstart = -746879993;
      mend = 746879993;
  }
	targetstories = _.filter(allstories,function(story){return day == null || (story.met_start != null && ((story.met_start >= mstart && story.met_start <= mend) || (story.met_end >= mstart && story.met_end <= mend)));});
  return(

{label}

{text}

Stories

  				<StoryList stories={targetstories}/>

  );
}

function mapStateToProps(state) {
  const {stories} = state;
  if (stories.loading) {
    return {
      loading: stories.loading
    };
  }
  return {
    loading: stories.loading,
    stories: stories.stories
  };
}

export default connect(mapStateToProps, {loadStories})(Apollo11Explorer);
<commit_msg>removed obsoleted container MomentTimeline leftover from development<commit_after><|endoftext|>


<commit_before>$(document).ready(function() {
    $('.dateinput').datepicker({ format: "yyyy-mm-dd", todayHighlight: "true"});
    $('.datetimeinput').datepicker({ format: "yyyy-mm-dd", todayHighlight: "true"});
    $('.totals').hide().before('
Totals
');
    $('a#toggle-totals').click(function() {
        $('.totals').slideToggle(250);
        return false;
    });
    $('.actives').hide().before('
Active
');
    $('a#toggle-actives').click(function() {
        $('.actives').slideToggle(250);
        return false;
    });
    $("tr").hover(function() {
        $(this).css("background-color", "yellow");
        }, function() {
        $(this).css("background-color", "pink");
    });
});
function rowStyle(value, row, index) {
  if (row%2 == 0) {
    return {
      css: {"background": "white"}
    };
  } else {
    return {
      css: {"background": "#f5f5f5"}
    };
  }
}
<commit_msg>Update<commit_after>$(document).ready(function() {
    $('.dateinput').datepicker({ format: "yyyy-mm-dd", todayHighlight: "true"});
    $('.datetimeinput').datepicker({ format: "yyyy-mm-dd", todayHighlight: "true"});
    $('.totals').hide().before('
Totals
');
    $('a#toggle-totals').click(function() {
        $('.totals').slideToggle(250);
        return false;
    });
    $('.actives').hide().before('
Active
');
    $('a#toggle-actives').click(function() {
        $('.actives').slideToggle(250);
        return false;
    });
});
function rowStyle(value, row, index) {
  if (row%2 == 0) {
    return {
      css: {"background": "white"}
    };
  } else {
    return {
      css: {"background": "#f5f5f5"}
    };
  }
}
<|endoftext|>


<commit_before>"use strict";

import Emitter from "yasmf-emitter";
import h from "yasmf-h";
import Hammer from "hammerjs";
import matchesSelector from "matches-selector";

// private property symbols
const _subviews = Symbol(),
      _elementTree = Symbol(),
      _parentView = Symbol(),
      _hammer = Symbol(),
      _renderElement = Symbol(),
      _targetSelectors = Symbol();

function removeTreeFromElement() {
    this.emitSync("willDetachFromParent");
    this[_renderElement].removeChild(this.elementTree);
    this[_renderElement] = null;
    this.emit("didDetachFromParent");
}

function addTreeToElement() {
    this.emitSync("willAttachToParent");
    this[_renderElement].appendChild(this.elementTree);
    this.emit("didAttachToParent");
}

function triggerTargetSelectors(e) {
    const targetSelectors = this[_targetSelectors];
    for (let [eventAndSelector, emitSet] of targetSelectors) {
        let [eventFilters, selector] = eventAndSelector.split(":");
        selector = selector.trim();
        eventFilters = eventFilters.trim().split(" ");
        if (eventFilters) {
            if (eventFilters.indexOf(e.type) > -1) {
                let matches = false;
                let curTarget = e.target;
                while (curTarget && !(matches = matchesSelector(curTarget, selector)) && !(curTarget === this.elementTree)) {
                    curTarget = curTarget.parentNode;
                }
                if (matches) {
                    for (let emit of emitSet) {
                        this.emit(emit, curTarget, e);
                    }
                }
            }
        }
    }
}

export default class View extends Emitter {
    constructor({deferRendering = false} = {}) {
        super();
        this[_subviews] = [];
        this[_parentView] = null;
        this[_elementTree] = null;
        this[_renderElement] = null;
        this[_targetSelectors] = new Map();
        if (this.TARGET_SELECTORS) {
            this.addTargetSelectors(this.TARGET_SELECTORS);
        }
        if (!deferRendering) { setImmediate(this.render.bind(this)); }
    }

///pragma rendering
    template() {
        return h.el("div.View?is=y-view", this.renderSubviews());
    }
    renderTo(options = {}) {
        let {stopAt} = options,
            targetEl;
        if (this.parentView && this.parentView !== stopAt) {
            this.parentView.renderTo(options);
        } else {
            if ((targetEl = (this.renderElement || (this.elementTree && this.elementTree.parentNode)))) {
                h.renderTo(this.render(), targetEl );
            }
        }
    }
    render() {
        if (this.elementTree) {
            h.renderTo(Array.from(this.template().children), this.elementTree);
        } else {
            this.elementTree = this.template();
        }
        return this.elementTree;
    }
    onRender() {
        this.renderTo({stopAt: this.parentView});
    }

    renderSubviews() {
        return this.subviews.map(function(view) {return view.render(); });
    }

///pragma events

    get targetSelectors() {
        return Array.from(this[_targetSelectors]);
    }
    addTargetSelector({selector, emit}) {
        const targetSelectors = this[_targetSelectors];
        let targetSet = targetSelectors.get(selector);
        if (!targetSet) {
            targetSelectors.set(selector, targetSet = new Set());
        }
        targetSet.add(emit);
    }
    addTargetSelectors(...args) {
        for (let arg of args) {
            if (arg) {
                if (arg instanceof Array) {
                    this.addTargetSelectors(...arg);
                } else {
                    this.addTargetSelector(arg);
                }
            }
        }
    }
    get TARGET_SELECTORS() {
        return undefined;
    }

    get HAMMER_EVENTS() {
        return "tap press pressup panmove panstart panend swipe swipeleft swiperight";
    }

    get DOM_EVENTS() {
        return "input focus blur keyup keydown change submit reset select";
    }
    get hammer() {
        return this[_hammer];
    }

    onHammerEvent(sender, notice, e) {
        triggerTargetSelectors.call(this, e);
    }

    onDOMEvent(sender, notice, e) {
        triggerTargetSelectors.call(this, e);
    }

///pragma parent view property
    get parentView() {
        return this[_parentView];
    }

///pragma subview handling
    get subviews() {
        return this[_subviews];
    }
    addSubview(v) {
        this.emitSync("willAddSubview", v);
        this[_subviews].push(v);
        if (v.parentView !== this) {
            v.emitSync("willChangeParentView", this);
            if (v.parentView) {
                v[_parentView].removeView(v);
            }
            v[_parentView] = null;
        }
        v[_parentView] = this;
        v.emit("didChangeParentView");
        this.emit("didAddSubview", v);
    }
    removeView(v) {
        let idx;
        this.emitSync("willRemoveSubview", v);
        if ((idx = this[_subviews].indexOf(v)) > -1) {
            this[_subviews].splice(idx, 1);
            v.emitSync("willRemoveFromParent");
            v[_parentView] = null;
            v.emit("didRemoveFromParent");
        }
        this.emit("didRemoveView", v);
    }

///pragma element tree property and handling
    get elementTree() {
        return this[_elementTree];
    }
    set elementTree(e) {
        this.emitSync("willChangeElementTree", e);
        this[_elementTree] = e;
        this.emit("didChangeElementTree");
    }
    onWillChangeElementTree() {
        if (this.elementTree && this.renderElement) {
            removeTreeFromElement.call(this);
        }
    }
    onDidChangeElementTree() {
        if (this.elementTree) {
            for (let evt of this.DOM_EVENTS.split(" ")) {
                this[_elementTree].addEventListener(evt, (e)=>this.emit("DOMEvent", e), true);
            }
            this[_hammer] = new Hammer(this[_elementTree], {domEvents: true});
            this[_hammer].on(this.HAMMER_EVENTS, (e)=>this.emit("hammerEvent", e));

            if (this.renderElement) {
                addTreeToElement.call(this);
            }
        }
    }

///pragma renderElement property
    get renderElement() {
        return this[_renderElement];
    }
    set renderElement(e) {
        if (this[_renderElement] && this[_renderElement] !== e && this.elementTree) {
            removeTreeFromElement.call(this);
        }
        this[_renderElement] = e;
        if (this[_renderElement] && this.elementTree) {
            addTreeToElement.call(this);
        }
    }

///pragma cleanup
    destroy() {
        this.emitSync("willDestroy");
        this[_subviews].forEach(view => this.removeView(view));
        this[_subviews] = [];
        this.renderElement = null;
        this[_hammer].destroy();
        this[_hammer] = null;
        this.elementTree = null;
        super.destroy();
    }

}
<commit_msg>comments; add theme manager support; better defaults at new<commit_after>/* @flow */
"use strict";

import Emitter from "yasmf-emitter";
import h from "yasmf-h";
import Hammer from "hammerjs";
import matchesSelector from "matches-selector";

/******************************************************************************
 *
 * VIEW
 *
 ******************************************************************************

 Views are the basic building block of the visual hierarchy used to render the
 application. Technically, these could be widgets at the lowest level, but in
 practice views typically render a DOM Tree based on a related model. This
 could be a simple tree or a very complex tree. This is called the
 `elementTree`. It is generated by the `render` method. This tree is parented
 by the `renderElement` in the DOM. `render` calls the `template` method to
 actually generate the tree. `template` should call `renderSubviews` in order
 to ensure subviews also get a chance to render themselves.

 One should never attempt to attach event listeners directly to any element in
 the tree as that element may be destroyed at the next render attempt. Instead
 the view itself provides mechanisms for detecting events that occur on any
 element within the tree. These are called `targetSelectors`. They are a map
 between a selector and the event to emit. For example, a selector of
 `tap:ul > li.item` emitting `listItemTapped` will emit `listItemTapped`
 whenever a `li.item` directly inside a `ul` is tapped. Any listener that
 responds to `listItemTapped` will be notified (and will be passed the
 event, sender, notice, the element that triggered the event and the event
 itself.
*/

// private property symbols
const _subviews = Symbol(),
      _elementTree = Symbol(),
      _parentView = Symbol(),
      _hammer = Symbol(),
      _renderElement = Symbol(),
      _targetSelectors = Symbol(),
      _themeManager = Symbol();

/**
 * Remove the view's tree from the render element.
 * @private
 * @emits willDetachFromParent, didDetachFromParent
 */
function removeTreeFromElement()/*: void*/ {
    this.emitSync("willDetachFromParent");
    this[_renderElement].removeChild(this.elementTree);
    this[_renderElement] = null;
    this.emit("didDetachFromParent");
}

/**
 * Adds the view's tree to the render element
 * @private
 * @emits willAttachToParent, didAttachToParent
 */
function addTreeToElement()/*: void*/ {
    this.emitSync("willAttachToParent");
    this[_renderElement].appendChild(this.elementTree);
    this.emit("didAttachToParent");
}

/**
 * Given an event, this triggers all the target selectors
 *
 * Selectors are of the form "event:CSS Selector". As an example "tap:ul li > button".
 *
 * Once an event's target matches a selector, the corresponding event is emitted.
 *
 * @param  {event} e DOM event
 * @private
 */
function triggerTargetSelectors(e/*: Event*/)/*: void*/ {
    const targetSelectors = this[_targetSelectors];
    for (let [eventAndSelector, emitSet] of targetSelectors) {
        let [eventFilters, selector] = eventAndSelector.split(":");
        selector = selector.trim();
        eventFilters = eventFilters.trim().split(" ");
        if (eventFilters) {
            if (eventFilters.indexOf(e.type) > -1) {
                let matches = false;
                let curTarget = e.target;
                while (curTarget && !(matches = matchesSelector(curTarget, selector)) && !(curTarget === this.elementTree)) {
                    curTarget = curTarget.parentNode;
                }
                if (matches) {
                    for (let emit of emitSet) {
                        this.emit(emit, curTarget, e);
                    }
                }
            }
        }
    }
}

/**
 * View Class
 */
export default class View extends Emitter {
    constructor({deferRendering = false, subviews = [], renderElement = null, themeManager = null} = {}) {
        super();
        this[_subviews] = [];
        subviews.forEach(v => this.addSubview(v));
        this[_parentView] = null;
        this[_elementTree] = null;
        this[_renderElement] = renderElement;
        this[_themeManager] = themeManager;
        this[_targetSelectors] = new Map();
        if (this.TARGET_SELECTORS) {
            this.addTargetSelectors(this.TARGET_SELECTORS);
        }
        if (!deferRendering) { setImmediate(this.render.bind(this)); }
    }

///mark: rendering

    /**
     * Returns a DOM tree that can be rendered to the DOM
     * @return {Node|Array} DOM tree
     */
    template()/*: Node|Array*/ {
        return h.el("div.View?is=y-view", this.renderSubviews());
    }

    /**
     * Renders the return from `render` to the target element (which is the `renderElement` or the `parentNode`)
     * @param  {{stopAt: Node}} options ]   the node to stop at (renders propagate up the tree)
     */
    renderTo(options = {})/*: void*/ {
        let {stopAt} = options,
            targetEl;
        if (this.parentView && this.parentView !== stopAt) {
            this.parentView.renderTo(options);
        } else {
            if ((targetEl = (this.renderElement || (this.elementTree && this.elementTree.parentNode)))) {
                h.renderTo(this.render(), targetEl );
            }
        }
    }

    /**
     * Returns a rendered DOM tree based on `template`
     * @return {Node|Array}
     */
    render()/*: Node|Array*/ {
        if (this.elementTree) {
            h.renderTo(Array.from(this.template().children), this.elementTree);
        } else {
            this.elementTree = this.template();
        }
        return this.elementTree;
    }

    /**
     * If a `render` event is received, render our template up to our parent
     */
    onRender()/*: void*/ {
        this.renderTo({stopAt: this.parentView});
    }

    /**
     * Utility method for quickly rendering all our subviews.
     * @return {Array<Node>} [description]
     */
    renderSubviews()/*: Array<Node>*/ {
        return this.subviews.map(function(view) {return view.render(); });
    }

///mark: events

    /**
     * Returns an array of all the target selectors that have been defined for
     * this view.
     * @return {Array}
     */
    get targetSelectors()/*: Array*/ {
        return Array.from(this[_targetSelectors]);
    }

    /**
     * Adds a target selector to the view.
     *
     * Selectors are of the form event:CSS Selector.
     *
     * @param {string} selector event:CSS Selector, like tap:ul li > button
     * @param {string} emit     the event to emit
     */
    addTargetSelector({selector/*: string*/, emit/*: string*/}) {
        const targetSelectors = this[_targetSelectors];
        let targetSet = targetSelectors.get(selector);
        if (!targetSet) {
            targetSelectors.set(selector, targetSet = new Set());
        }
        targetSet.add(emit);
    }
    /**
     * Adds many target selectors at once
     * @param {*|Array} args... ]
     */
    addTargetSelectors(...args/*: any|Array*/) {
        for (let arg of args) {
            if (arg) {
                if (arg instanceof Array) {
                    this.addTargetSelectors(...arg);
                } else {
                    this.addTargetSelector(arg);
                }
            }
        }
    }

    /**
     * @abstract
     *
     * Returns undefined by default, but this is intended to be overridden to return
     * an array of target selectors. These will be automatically added using `addTargetSelectors`
     * to the view when it is constructed.
     */
    get TARGET_SELECTORS() {
        return undefined;
    }

    /**
     * Returns the list of hammer events that this view will listen for. Some Hammer events preclude the ability to listen for
     * other events, hence why this is not a complete list. This should be sufficient, however, to detect taps, long presses,
     * swipes and pans.
     *
     * If you want to change the events you listen for, override this method.
     */
    get HAMMER_EVENTS() {
        return "tap press pressup panmove panstart panend swipe swipeleft swiperight";
    }

    /**
     * Returns the list of DOM events this view will listen for. Because Hammer is handling touch events, we only
     * handle typing, focus, and form events.
     *
     * If you need to change the events, override this method.
     */
    get DOM_EVENTS() {
        return "input focus blur keyup keydown change submit reset select";
    }

    /**
     * Returns this view's Hammer instance.
     * @return {Hammer}
     */
    get hammer()/*: Hammer*/ {
        return this[_hammer];
    }

    /**
     * When a Hammer event is fired, we trigger the appropriate target selectors.
     * @param  {*}      sender
     * @param  {string} notice emitted event
     * @param  {Event}  e      DOM/Hammer Event
     */
    onHammerEvent(sender/*: Object*/, notice/*: string*/, e/*: Event*/)/*: void*/ {
        triggerTargetSelectors.call(this, e);
    }

    /**
     * When a DOM  event is fired, we trigger the appropriate target selectors.
     * @param  {*}      sender
     * @param  {string} notice emitted event
     * @param  {Event}  e      DOM/Hammer Event
     */
    onDOMEvent(sender/*: Object*/, notice/*: string*/, e/*: Event*/) {
        triggerTargetSelectors.call(this, e);
    }

///mark: parent view property

    /**
     * Returns the parent view for this view
     * @return {View} This view's parent view
     */
    get parentView()/*: View*/ {
        return this[_parentView];
    }

///mark: subview handling

    /**
     * Returns this view's subviews.
     * @return {Array<View>} ]
     */
    get subviews()/*: Array<View>*/ {
        return this[_subviews];
    }

    /**
     * Adds view as a subview to this view, correctly reparenting it if necessary.
     * @param {View} v View to add as a subview
     * @emits willAddSubview, willChangeParentView, didChangeParentView, didAddSubview
     */
    addSubview(v/*: View*/)/*: void*/ {
        this.emitSync("willAddSubview", v);
        this[_subviews].push(v);
        if (v.parentView !== this) {
            v.emitSync("willChangeParentView", this);
            if (v.parentView) {
                v[_parentView].removeView(v);
            }
            v[_parentView] = null;
        }
        v[_parentView] = this;
        v.emit("didChangeParentView");
        this.emit("didAddSubview", v);
    }

    /**
     * Removes the view from our subviews
     * @param  {View} v View to remove
     * @emits willRemoveSubview, willRemoveFromParent, didRemoveFromParent, didRemoveView
     */
    removeView(v/*: View*/)/*: void*/ {
        let idx;
        this.emitSync("willRemoveSubview", v);
        if ((idx = this[_subviews].indexOf(v)) > -1) {
            this[_subviews].splice(idx, 1);
            v.emitSync("willRemoveFromParent");
            v[_parentView] = null;
            v.emit("didRemoveFromParent");
        }
        this.emit("didRemoveView", v);
    }

///mark: element tree property and handling

    /**
     * Returns this view's element tree
     * @return {Node}
     */
    get elementTree()/*: Node*/ {
        return this[_elementTree];
    }

    /**
     * Sets this view's element tree
     * @param  {Node} e Element Tree
     * @emits willChangeElementTree, didChangeElementTree
     */
    set elementTree(e/*: Node*/)/*: void*/ {
        this.emitSync("willChangeElementTree", e);
        this[_elementTree] = e;
        this.emit("didChangeElementTree");
    }

    /**
     * Fired when the element tree is about to be changed. Removes the tree from
     * the view's rendering element if possible (and present).
     */
    onWillChangeElementTree()/*: void*/ {
        if (this.elementTree && this.renderElement) {
            removeTreeFromElement.call(this);
        }
    }

    /**
     * When the element tree has been changed, we need to wire up any event handlers in
     * order to intercept Hammer and DOM events.
     */
    onDidChangeElementTree()/*: void*/ {
        if (this.elementTree) {
            for (let evt of this.DOM_EVENTS.split(" ")) {
                this[_elementTree].addEventListener(evt, (e)=>this.emit("DOMEvent", e), true);
            }
            this[_hammer] = new Hammer(this[_elementTree], {domEvents: true});
            this[_hammer].on(this.HAMMER_EVENTS, (e)=>this.emit("hammerEvent", e));

            if (this.renderElement) {
                addTreeToElement.call(this);
            }
        }
    }

///mark: renderElement property
    get renderElement() {
        return this[_renderElement];
    }
    set renderElement(e) {
        if (this[_renderElement] && this[_renderElement] !== e && this.elementTree) {
            removeTreeFromElement.call(this);
        }
        this[_renderElement] = e;
        if (this[_renderElement] && this.elementTree) {
            addTreeToElement.call(this);
        }
    }

///mark: theme manager
    get themeManager()/*: ThemeManager*/ {
        return (this[_themeManager] ? this[_themeManager] :
                 (this.parentView ? this.parentView.themeManager : null)
               );
    }
    set themeManager(v/*: ThemeManager*/)/*: void*/ {
        this[_themeManager] = v;
        this.emit("themeManagerChanged");
        this.subviews.forEach(view => view.emit("themeManagerChanged", v));
    }

///mark: cleanup
    destroy() {
        this.emitSync("willDestroy");
        this[_subviews].forEach(view => this.removeView(view));
        this[_subviews] = [];
        this.renderElement = null;
        this[_hammer].destroy();
        this[_hammer] = null;
        this.elementTree = null;
        super.destroy();
    }
}
<|endoftext|>


<commit_before>// Main app class
enyo.kind({
	name: "TamTam.App",
	kind: "FittableRows",
	published: {activity: null},
	components: [
		{name: "content", kind: "Scroller", fit: true, classes: "maincontent", onresize: "resize",
		components: [
			{name: "collections", classes: "collections", components: [
			]},
			{name: "items", classes: "items", components: [
			]}
		]}
	],
	pianoMode: false,

	// Constructor
	create: function() {
		this.inherited(arguments);
		this.collection = 0;
		this.computeSize();
		var that = this;
		requirejs(["sugar-web/env"], function(env) {
			env.getEnvironment(function(err, environment) {
				that.userColor = environment.user.colorvalue;
				that.draw();
			});
		});
	},

	computeSize: function() {
		var toolbar = document.getElementById("main-toolbar");
		var canvas = document.getElementById("body");
		var canvas_height = canvas.offsetHeight;
		this.$.content.applyStyle("height", (canvas_height-toolbar.offsetHeight)+"px");
	},

	resize: function() {
		this.computeSize();
		this.draw();
	},

	// Draw screen
	draw: function() {
		// Remove collections
		var items = [];
		enyo.forEach(this.$.collections.getControls(), function(item) { items.push(item); });
		for (var i = 0 ; i < items.length ; i++) { items[i].destroy();	}

		// Remove items
		var items = [];
		enyo.forEach(this.$.items.getControls(), function(item) { items.push(item); });
		for (var i = 0 ; i < items.length ; i++) { items[i].destroy();	}
		if(this.pianoMode) {
			document.getElementById("body").style.backgroundColor = '#ffffff';
			this.$.collections.applyStyle("background-color", '#ffffff');

			if(currentPianoMode !== null) {
				this.$.collections.createComponent(
					{ kind: "TamTam.Collection", name: currentPianoMode},
					{ owner: this }
				).render();
			}

			this.$.items.createComponent(
				{ kind: "TamTam.Piano"},
				{ owner: this }
			).render();

		} else {
			// Display collections
			document.getElementById("body").style.backgroundColor = this.userColor.fill;
			this.$.collections.applyStyle("background-color", this.userColor.fill);
			var len = TamTam.collections.length;
			for(var i = 0 ; i < len ; i++ ) {
				this.$.collections.createComponent(
					{ kind: "TamTam.Collection", name: TamTam.collections[i].name, selection: (i == this.collection), ontap: "changeCollection" },
					{ owner: this }
				).render();
			}

			// Display items
			var collection = TamTam.collections[this.collection];
			var len = collection.content.length;
			for(var i = 0 ; i < len ; i++ ) {
				var item = this.$.items.createComponent(
					{ kind: "TamTam.Item", name: collection.content[i] },
					{ owner: this }
				);
				item.applyStyle("background-color", this.userColor.stroke);
				item.render();
			}
		}
	},

	// Handle event
	changeCollection: function(s, e) {
		// Stop sound
		sound.pause();

		// Select the collection
		var len = TamTam.collections.length;
		for(var i = 0 ; i < len ; i++) {
			if (TamTam.collections[i].name == s.name) {
				this.collection = i;
				this.draw();
				return;
			}
		}
	},

	changePianoMode: function(e) {
		console.log("changed");
		console.log(this.$)
		this.pianoMode = !this.pianoMode;
		if(this.pianoMode) {
			document.getElementById('piano-button').classList.add('active');
		} else {
			document.getElementById('piano-button').classList.remove('active');
		}
		this.draw();
	}
});
<commit_msg>make selection a clickable item rather than a collection<commit_after>// Main app class
enyo.kind({
	name: "TamTam.App",
	kind: "FittableRows",
	published: {activity: null},
	components: [
		{name: "content", kind: "Scroller", fit: true, classes: "maincontent", onresize: "resize",
		components: [
			{name: "collections", classes: "collections", components: [
			]},
			{name: "items", classes: "items", components: [
			]}
		]}
	],
	pianoMode: false,

	// Constructor
	create: function() {
		this.inherited(arguments);
		this.collection = 0;
		this.computeSize();
		var that = this;
		requirejs(["sugar-web/env"], function(env) {
			env.getEnvironment(function(err, environment) {
				that.userColor = environment.user.colorvalue;
				that.draw();
			});
		});
	},

	computeSize: function() {
		var toolbar = document.getElementById("main-toolbar");
		var canvas = document.getElementById("body");
		var canvas_height = canvas.offsetHeight;
		this.$.content.applyStyle("height", (canvas_height-toolbar.offsetHeight)+"px");
	},

	resize: function() {
		this.computeSize();
		this.draw();
	},

	// Draw screen
	draw: function() {
		// Remove collections
		var items = [];
		enyo.forEach(this.$.collections.getControls(), function(item) { items.push(item); });
		for (var i = 0 ; i < items.length ; i++) { items[i].destroy();	}

		// Remove items
		var items = [];
		enyo.forEach(this.$.items.getControls(), function(item) { items.push(item); });
		for (var i = 0 ; i < items.length ; i++) { items[i].destroy();	}
		if(this.pianoMode) {
			document.getElementById("body").style.backgroundColor = '#ffffff';
			this.$.collections.applyStyle("background-color", '#ffffff');

			if(currentPianoMode !== null) {
				this.$.items.createComponent(
					{ kind: "TamTam.Item", name: currentPianoMode},
					{ owner: this }
				).render();
			}

			this.$.items.createComponent(
				{ kind: "TamTam.Piano"},
				{ owner: this }
			).render();

		} else {
			// Display collections
			document.getElementById("body").style.backgroundColor = this.userColor.fill;
			this.$.collections.applyStyle("background-color", this.userColor.fill);
			var len = TamTam.collections.length;
			for(var i = 0 ; i < len ; i++ ) {
				this.$.collections.createComponent(
					{ kind: "TamTam.Collection", name: TamTam.collections[i].name, selection: (i == this.collection), ontap: "changeCollection" },
					{ owner: this }
				).render();
			}

			// Display items
			var collection = TamTam.collections[this.collection];
			var len = collection.content.length;
			for(var i = 0 ; i < len ; i++ ) {
				var item = this.$.items.createComponent(
					{ kind: "TamTam.Item", name: collection.content[i] },
					{ owner: this }
				);
				item.applyStyle("background-color", this.userColor.stroke);
				item.render();
			}
		}
	},

	// Handle event
	changeCollection: function(s, e) {
		// Stop sound
		sound.pause();

		// Select the collection
		var len = TamTam.collections.length;
		for(var i = 0 ; i < len ; i++) {
			if (TamTam.collections[i].name == s.name) {
				this.collection = i;
				this.draw();
				return;
			}
		}
	},

	changePianoMode: function(e) {
		console.log("changed");
		console.log(this.$)
		this.pianoMode = !this.pianoMode;
		if(this.pianoMode) {
			document.getElementById('piano-button').classList.add('active');
		} else {
			document.getElementById('piano-button').classList.remove('active');
		}
		this.draw();
	}
});
<|endoftext|>


<commit_before>import Ember from 'ember';

export default Ember.Mixin.create({
  mustUpdateInput: true,
  value: null,
  // add the observed properties
  minViewMode: undefined,
  format: undefined,
  language: undefined,
  startDate: undefined,
  endDate: undefined,

  setupBootstrapDatepicker: Ember.on('didInsertElement', function() {
    var self = this;

    this.$().
      datepicker({
        autoclose: this.get('autoclose'),
        calendarWeeks: this.get('calendarWeeks'),
        clearBtn: this.get('clearBtn'),
        container: this.get('widgetContainer'),
        daysOfWeekDisabled: this.get('daysOfWeekDisabled'),
        defaultViewDate: this.get('defaultViewDate'),
        disableTouchKeyboard: this.get('disableTouchKeyboard'),
        enableOnReadonly: this.get('enableOnReadonly'),
        endDate: this.get('endDate'),
        forceParse: this.get('forceParse'),
        format: this.get('format'),
        immediateUpdates: this.get('immediateUpdates'),
        keyboardNavigation: this.get('keyboardNavigation'),
        language: this.get('language') || undefined,
        maxViewMode: this.get('maxViewMode'),
        minViewMode: this.get('minViewMode'),
        multidate: this.get('multidate'),
        multidateSeparator: this.get('multidateSeparator'),
        orientation: this.get('orientation'),
        showOnFocus: this.get('showOnFocus'),
        startDate: this.get('startDate'),
        startView: this.get('startView'),
        todayBtn: this.get('todayBtn'),
        todayHighlight: this.get('todayHighlight'),
        toggleActive: this.get('toggleActive'),
        weekStart: this.get('weekStart'),
        datesDisabled: this.get('datesDisabled')
      }).
      on('changeDate', function(event) {
        Ember.run(function() {
          self._didChangeDate(event);
        });
      }).
      on('input', function(event) {
        if (!self.$().val()) {
          self._didChangeDate(event);
        }
      });

    this._updateDatepicker();
  }),

  teardownBootstrapDatepicker: Ember.on('willDestroyElement', function() {
    this.$().datepicker('remove');
  }),

  didChangeValue: Ember.observer('value', function() {
    this._updateDatepicker();
  }),

  _didChangeDate: function(event) {
    var value = null;

    if (event.date) {
      if (this.get('multidate')) {
        value = this.$().datepicker('getDates');
      } else {
        value = this.$().datepicker('getDate');
      }
    }

    this.set('mustUpdateInput', false);
    this.set('value', value);
    this.sendAction('changeDate', value);
  },

  _addObservers: Ember.on('didInsertElement', function() {
    this.addObserver('language', function() {
      this.$().datepicker('remove');
      this.setupBootstrapDatepicker();
    });

    this.addObserver('startDate', function() {
      this.$().datepicker('setStartDate', this.get('startDate'));
      this._updateDatepicker();
    });

    this.addObserver('endDate', function() {
      this.$().datepicker('setEndDate', this.get('endDate'));
      this._updateDatepicker();
    });

    this.addObserver('datesDisabled', function() {
      this.$().datepicker('setDatesDisabled', this.get('datesDisabled'));
      this._updateDatepicker();
    });

    this.addObserver('minViewMode', function() {
      this.$().datepicker('minViewMode', this.get('minViewMode'));
      this.$().data('datepicker')._process_options({minViewMode: this.get('minViewMode')});
      this._updateDatepicker();
    });

    this.addObserver('format', function() {
      this.$().datepicker('format', this.get('format'));
      this.$().data('datepicker')._process_options({format: this.get('format')});
      this._updateDatepicker();
    });
  }),

  _updateDatepicker: function() {
    var self = this,
        element = this.$(),
        value = this.get('value'),
        dates = [];

    if (!this.get('mustUpdateInput')) {
      this.set('mustUpdateInput', true);
      return;
    }

    switch (Ember.typeOf(value)) {
      case 'array':
        dates = value;
        break;
      case 'date':
        dates = [value];
        break;
      default:
        dates = [null];
    }
    dates = dates.map(function(date) {
      return (Ember.isNone(date)) ? null : self._getDateCloneWithNoTime(date);
    });

    element.datepicker
           .apply(element, Array.prototype.concat.call(['update'], dates));
  },

  // HACK: Have to reset time to 00:00:00 because of the bug in
  //       bootstrap-datepicker
  //       Issue: http://git.io/qH7Hlg
  _getDateCloneWithNoTime: function(date) {
    var clone = new Date(date.getTime());

    clone.setHours(0);
    clone.setMinutes(0);
    clone.setSeconds(0);
    clone.setMilliseconds(0);

    return clone;
  }
});
<commit_msg>Add function to apply new date value.<commit_after>import Ember from 'ember';

export default Ember.Mixin.create({
  mustUpdateInput: true,
  value: null,
  // add the observed properties
  minViewMode: undefined,
  format: undefined,
  language: undefined,
  startDate: undefined,
  endDate: undefined,

  setupBootstrapDatepicker: Ember.on('didInsertElement', function() {
    var self = this;

    this.$().
      datepicker({
        autoclose: this.get('autoclose'),
        calendarWeeks: this.get('calendarWeeks'),
        clearBtn: this.get('clearBtn'),
        container: this.get('widgetContainer'),
        daysOfWeekDisabled: this.get('daysOfWeekDisabled'),
        defaultViewDate: this.get('defaultViewDate'),
        disableTouchKeyboard: this.get('disableTouchKeyboard'),
        enableOnReadonly: this.get('enableOnReadonly'),
        endDate: this.get('endDate'),
        forceParse: this.get('forceParse'),
        format: this.get('format'),
        immediateUpdates: this.get('immediateUpdates'),
        keyboardNavigation: this.get('keyboardNavigation'),
        language: this.get('language') || undefined,
        maxViewMode: this.get('maxViewMode'),
        minViewMode: this.get('minViewMode'),
        multidate: this.get('multidate'),
        multidateSeparator: this.get('multidateSeparator'),
        orientation: this.get('orientation'),
        showOnFocus: this.get('showOnFocus'),
        startDate: this.get('startDate'),
        startView: this.get('startView'),
        todayBtn: this.get('todayBtn'),
        todayHighlight: this.get('todayHighlight'),
        toggleActive: this.get('toggleActive'),
        weekStart: this.get('weekStart'),
        datesDisabled: this.get('datesDisabled')
      }).
      on('changeDate', function(event) {
        Ember.run(function() {
          self._didChangeDate(event);
        });
      }).
      on('input', function() {
        if (!self.$().val()) {
          self._applyDateValue(null);
        }
      });

    this._updateDatepicker();
  }),

  teardownBootstrapDatepicker: Ember.on('willDestroyElement', function() {
    this.$().datepicker('remove');
  }),

  didChangeValue: Ember.observer('value', function() {
    this._updateDatepicker();
  }),

  _didChangeDate: function(event) {
    var value = null;

    if (event.date) {
      if (this.get('multidate')) {
        value = this.$().datepicker('getDates');
      } else {
        value = this.$().datepicker('getDate');
      }
    }

    this.set('mustUpdateInput', false);
    this._applyDateValue(value);
  },

  _applyDateValue: function(value) {
    this.set('value', value);
    this.sendAction('changeDate', value);
  },

  _addObservers: Ember.on('didInsertElement', function() {
    this.addObserver('language', function() {
      this.$().datepicker('remove');
      this.setupBootstrapDatepicker();
    });

    this.addObserver('startDate', function() {
      this.$().datepicker('setStartDate', this.get('startDate'));
      this._updateDatepicker();
    });

    this.addObserver('endDate', function() {
      this.$().datepicker('setEndDate', this.get('endDate'));
      this._updateDatepicker();
    });

    this.addObserver('datesDisabled', function() {
      this.$().datepicker('setDatesDisabled', this.get('datesDisabled'));
      this._updateDatepicker();
    });

    this.addObserver('minViewMode', function() {
      this.$().datepicker('minViewMode', this.get('minViewMode'));
      this.$().data('datepicker')._process_options({minViewMode: this.get('minViewMode')});
      this._updateDatepicker();
    });

    this.addObserver('format', function() {
      this.$().datepicker('format', this.get('format'));
      this.$().data('datepicker')._process_options({format: this.get('format')});
      this._updateDatepicker();
    });
  }),

  _updateDatepicker: function() {
    var self = this,
        element = this.$(),
        value = this.get('value'),
        dates = [];

    if (!this.get('mustUpdateInput')) {
      this.set('mustUpdateInput', true);
      return;
    }

    switch (Ember.typeOf(value)) {
      case 'array':
        dates = value;
        break;
      case 'date':
        dates = [value];
        break;
      default:
        dates = [null];
    }
    dates = dates.map(function(date) {
      return (Ember.isNone(date)) ? null : self._getDateCloneWithNoTime(date);
    });

    element.datepicker
           .apply(element, Array.prototype.concat.call(['update'], dates));
  },

  // HACK: Have to reset time to 00:00:00 because of the bug in
  //       bootstrap-datepicker
  //       Issue: http://git.io/qH7Hlg
  _getDateCloneWithNoTime: function(date) {
    var clone = new Date(date.getTime());

    clone.setHours(0);
    clone.setMinutes(0);
    clone.setSeconds(0);
    clone.setMilliseconds(0);

    return clone;
  }
});
<|endoftext|>


<commit_before>import Ember from 'ember';
import HashMap from 'perf-primitives/hash-map';
import layout from '../templates/components/liquid-destination';

const { inject, computed, A } = Ember;
const { gt } = computed;
const { service } = inject;

export default Ember.Component.extend({
  layout,
  classNames: ['liquid-destination'],
  classNameBindings: ['hasWormholes'],

  name: 'default',
  liquidWormholeService: service('liquidWormhole'),
  matchContext: {
    helperName: 'liquid-wormhole'
  },

  hasWormholes: gt('stacks.length', 0),

  init() {
    this._super(...arguments);

    this.stackMap = new HashMap();
    this.set('stacks', A());

    this.wormholeQueue = A();

    const name = this.get('name');

    this.get('liquidWormholeService').registerDestination(name, this);
  },

  willDestroyElement() {
    this._super(...arguments);

    const name = this.get('name');
    this.get('liquidWormholeService').unregisterDestination(name);
  },

  appendWormhole(wormhole) {
    // The order that wormholes are rendered in may be different from the order
    // that they appear in templates, because child components get rendered before
    // their parents. This logic inserts parent components *before* their children
    // so the ordering is correct.
    var appendIndex = this.wormholeQueue.get('length') - 1;

    for (; appendIndex >= 0; appendIndex--) {
      const lastWormholeElement = this.wormholeQueue.objectAt(appendIndex).element;

      if (!wormhole.element.contains(lastWormholeElement)) {
        break; // break when we find the first wormhole that isn't a parent
      }
    }

    this.wormholeQueue.insertAt(appendIndex + 1, wormhole);

    Ember.run.scheduleOnce('afterRender', this, this.flushWormholeQueue);
  },

  removeWormhole(wormhole) {
    const stackName = wormhole.get('stack');
    const stack = this.stackMap.get(stackName);
    const item = stack.find(item => item && item.wormhole === wormhole);

    const newNodes = item.get('nodes').clone();
    item.set('nodes', newNodes);
    item.set('_replaceNodes', true);

    Ember.run.next(() => stack.removeObject(item));
  },

  flushWormholeQueue() {
    this.wormholeQueue.forEach((wormhole) => {
      const stackName = wormhole.get('stack');
      const stack = this.stackMap.get(stackName) || this.createStack(wormhole);

      const nodes = wormhole.get('nodes');
      const value = wormhole.get('value');

      const item = Ember.Object.create({ nodes, wormhole, value });

      // Reset visibility in case we made them visible, see below
      nodes.css({ visibility: 'hidden' });

      stack.pushObject(item);
    });

    this.wormholeQueue.clear();
  },

  createStack(wormhole) {
    const stackName = wormhole.get('stack');

    const stack = A([ null ]);
    stack.set('name', stackName);

    this.stackMap.set(stackName, stack);
    this.stacks.pushObject(stack);

    return stack;
  },

  actions: {
    willTransition() {
      // Do nothing
    },

    afterChildInsertion() {
      // Do nothing
    },

    afterTransition([{ value, view }]) {
      // If wormholes were made w/o animations, they need to be made visible manually.
      this.$(view.element).find('.liquid-wormhole-element').css({ visibility: 'visible' });

      // Clean empty stacks
      if (value === null) {
        const stacks = this.get('stacks');
        const stackName = view.get('parentView.stackName');
        const stack = this.stackMap.get(stackName);

        stacks.removeObject(stack);
        this.stackMap.delete(stackName);
      }
    }
  }
});
<commit_msg>Don't try to do stuff after transition if the component is destroying or destroyed<commit_after>import Ember from 'ember';
import HashMap from 'perf-primitives/hash-map';
import layout from '../templates/components/liquid-destination';

const { inject, computed, A } = Ember;
const { gt } = computed;
const { service } = inject;

export default Ember.Component.extend({
  layout,
  classNames: ['liquid-destination'],
  classNameBindings: ['hasWormholes'],

  name: 'default',
  liquidWormholeService: service('liquidWormhole'),
  matchContext: {
    helperName: 'liquid-wormhole'
  },

  hasWormholes: gt('stacks.length', 0),

  init() {
    this._super(...arguments);

    this.stackMap = new HashMap();
    this.set('stacks', A());

    this.wormholeQueue = A();

    const name = this.get('name');

    this.get('liquidWormholeService').registerDestination(name, this);
  },

  willDestroyElement() {
    this._super(...arguments);

    const name = this.get('name');
    this.get('liquidWormholeService').unregisterDestination(name);
  },

  appendWormhole(wormhole) {
    // The order that wormholes are rendered in may be different from the order
    // that they appear in templates, because child components get rendered before
    // their parents. This logic inserts parent components *before* their children
    // so the ordering is correct.
    var appendIndex = this.wormholeQueue.get('length') - 1;

    for (; appendIndex >= 0; appendIndex--) {
      const lastWormholeElement = this.wormholeQueue.objectAt(appendIndex).element;

      if (!wormhole.element.contains(lastWormholeElement)) {
        break; // break when we find the first wormhole that isn't a parent
      }
    }

    this.wormholeQueue.insertAt(appendIndex + 1, wormhole);

    Ember.run.scheduleOnce('afterRender', this, this.flushWormholeQueue);
  },

  removeWormhole(wormhole) {
    const stackName = wormhole.get('stack');
    const stack = this.stackMap.get(stackName);
    const item = stack.find(item => item && item.wormhole === wormhole);

    const newNodes = item.get('nodes').clone();
    item.set('nodes', newNodes);
    item.set('_replaceNodes', true);

    Ember.run.next(() => stack.removeObject(item));
  },

  flushWormholeQueue() {
    this.wormholeQueue.forEach((wormhole) => {
      const stackName = wormhole.get('stack');
      const stack = this.stackMap.get(stackName) || this.createStack(wormhole);

      const nodes = wormhole.get('nodes');
      const value = wormhole.get('value');

      const item = Ember.Object.create({ nodes, wormhole, value });

      // Reset visibility in case we made them visible, see below
      nodes.css({ visibility: 'hidden' });

      stack.pushObject(item);
    });

    this.wormholeQueue.clear();
  },

  createStack(wormhole) {
    const stackName = wormhole.get('stack');

    const stack = A([ null ]);
    stack.set('name', stackName);

    this.stackMap.set(stackName, stack);
    this.stacks.pushObject(stack);

    return stack;
  },

  actions: {
    willTransition() {
      // Do nothing
    },

    afterChildInsertion() {
      // Do nothing
    },

    afterTransition([{ value, view }]) {
      if (this.isDestroying || this.isDestroyed) { return; }
      // If wormholes were made w/o animations, they need to be made visible manually.
      this.$(view.element).find('.liquid-wormhole-element').css({ visibility: 'visible' });

      // Clean empty stacks
      if (value === null) {
        const stacks = this.get('stacks');
        const stackName = view.get('parentView.stackName');
        const stack = this.stackMap.get(stackName);

        stacks.removeObject(stack);
        this.stackMap.delete(stackName);
      }
    }
  }
});
<|endoftext|>


<commit_before>/**
 * @module ember-paper
 */
import Ember from 'ember';
import PowerSelect from 'ember-power-select/components/power-select';

const { computed, inject } = Ember;

/**
 * @class PaperAutocomplete
 * @extends PowerSelectComponent
 */
export default PowerSelect.extend({
  util: inject.service(),
  constants: inject.service(),
  triggerComponent: 'paper-autocomplete-trigger', // paper-autocomplete-trigger paper-autocomplete-trigger-container
  contentComponent: 'paper-autocomplete-content',
  optionsComponent: 'paper-autocomplete-options',
  concatenatedDropdownClasses: ['md-autocomplete-suggestions-container md-virtual-repeat-container'],

  extra: computed('labelPath', 'label', function() {
    return { labelPath: this.get('labelPath'), label: this.get('label') };
  }),
  onchange: computed.alias('onChange'),

  actions: {
    onFocus(event) {
      this.send('activate');
      this.publicAPI.actions.open(event);
      let action = this.get('onfocus');
      if (action) {
        action(this.publicAPI, event);
      }
    },
    onBlur(event) {
      this.send('deactivate');
      let action = this.get('onblur');
      if (action) {
        action(this.publicAPI, event);
      }
    },
    onCreate(text) {
      if (this.get('onCreate')) {
        this.get('onCreate')(text);
      }
      this.publicAPI.actions.close();
    }
  }
});
<commit_msg>Add camel-case aliases for onFocus and onBlur in paper-autocomplete<commit_after>/**
 * @module ember-paper
 */
import Ember from 'ember';
import PowerSelect from 'ember-power-select/components/power-select';

const { computed, inject } = Ember;

/**
 * @class PaperAutocomplete
 * @extends PowerSelectComponent
 */
export default PowerSelect.extend({
  util: inject.service(),
  constants: inject.service(),
  triggerComponent: 'paper-autocomplete-trigger', // paper-autocomplete-trigger paper-autocomplete-trigger-container
  contentComponent: 'paper-autocomplete-content',
  optionsComponent: 'paper-autocomplete-options',
  concatenatedDropdownClasses: ['md-autocomplete-suggestions-container md-virtual-repeat-container'],

  extra: computed('labelPath', 'label', function() {
    return { labelPath: this.get('labelPath'), label: this.get('label') };
  }),
  onchange: computed.alias('onChange'),
  onfocus: computed.alias('onFocus'),
  onblur: computed.alias('onBlur'),

  actions: {
    onFocus(event) {
      this.send('activate');
      this.publicAPI.actions.open(event);
      let action = this.get('onfocus');
      if (action) {
        action(this.publicAPI, event);
      }
    },
    onBlur(event) {
      this.send('deactivate');
      let action = this.get('onblur');
      if (action) {
        action(this.publicAPI, event);
      }
    },
    onCreate(text) {
      if (this.get('onCreate')) {
        this.get('onCreate')(text);
      }
      this.publicAPI.actions.close();
    }
  }
});
<|endoftext|>


<commit_before>import Ember from 'ember';
import EmberTetherComponent from 'ember-tether/components/ember-tether';

const { $, computed, run } = Ember;

const defaultPosition = 'center';

let tooltipCounterId = 0;

function cleanNumber(stringOrNumber) {
  let cleanNumber;

  if (stringOrNumber && typeof stringOrNumber === 'string') {
    cleanNumber = parseInt(stringOrNumber, 10);

    /* Remove invalid parseInt results */

    if (isNaN(cleanNumber) || !isFinite(cleanNumber)) {
      cleanNumber = 0;
    }
  } else {
    cleanNumber = stringOrNumber;
  }

  return cleanNumber;
}

export default EmberTetherComponent.extend({

  /* Options */

  delay: 0,
  delayOnChange: true,
  duration: 0,
  effect: 'slide', // fade, slide, none
  event: 'hover', // hover, click, focus, none
  hideOn: null,
  role: 'tooltip',
  side: 'top',
  showOn: null,
  spacing: 10,
  tabindex: '0', // A positive integer (to enable) or -1 (to disable)
  tooltipIsVisible: false,
  keepInWindow: true,

  /*
  When this property changes it repositions the tooltip.

  This isn't actually used in the code anywhere - it just
  needs to be passed as an attribute so didUpdate is
  triggered.

  @property updateFor
  */

  updateFor: null,

  /* Actions */

  onTooltipDestroy: null,
  onTooltipHide: null,
  onTooltipRender: null,
  onTooltipShow: null,

  /* Properties */

  'aria-hidden': computed.not('tooltipIsVisible'),
  attributeBindings: ['aria-hidden', 'role', 'tabindex'],
  classNameBindings: ['effectClass'],
  classPrefix: 'ember-tooltip',
  classNames: ['ember-tooltip', 'tooltip'],
  /* The "tooltip" class is only included for backwards compatibility and
  will be removed in an upcoming major release. The component receives
  all of its styling and behavior from the "ember-tooltip" class. */

  _hideTimer: null,
  _showTimer: null,

  /* CPs */

  attachment: computed(function() {
    const side = this.get('side');

    let horizontalPosition, verticalPosition;

    switch(side) {
      case 'top':
        horizontalPosition = defaultPosition;
        verticalPosition = 'bottom';
        break;
      case 'right':
        horizontalPosition = 'left';
        verticalPosition = defaultPosition;
        break;
      case 'bottom':
        horizontalPosition = defaultPosition;
        verticalPosition = 'top';
        break;
      case 'left':
        horizontalPosition = 'right';
        verticalPosition = defaultPosition;
        break;
    }

    return `${verticalPosition} ${horizontalPosition}`;
  }),

  constraints: computed('keepInWindow', function() {
    let constraints;

    if (this.get('keepInWindow')) {
      constraints = [
        {
          to: 'window',
          attachment: 'together'
        }
      ];
    }

    return constraints;
  }),

  effectClass: computed(function() {
    return `ember-tooltip-${this.get('effect')}`;
  }),

  positionClass: computed(function() {
    const targetAttachment = this.get('targetAttachment');

    return `ember-tooltip-${targetAttachment.replace(' ', ' ember-tooltip-')}`;
  }),

  sideIsVertical: computed(function() {
    const side = this.get('side');

    return side === 'top' || side === 'bottom';
  }),

  target: computed(function() {
    const parentElement = this.$().parent();

    let parentElementId = parentElement.attr('id');

    if (!parentElementId) {
      parentElementId = `target-for-tooltip-${tooltipCounterId}`;

      tooltipCounterId++;

      parentElement.attr('id', parentElementId);
    }

    return `#${parentElementId}`;
  }),

  targetAttachment: computed(function() {
    const side = this.get('side');

    if (!this.get('sideIsVertical')) {
      return `center ${side}`;
    } else {
      return `${side} center`; // top and bottom
    }
  }),

  typeClass: computed(function() {
    const type = this.get('type');

    return type ? `ember-tooltip-${type}` : null;
  }),

  /* Private CPs */

  _hideOn: computed(function() {
    let hideOn = this.get('hideOn');

    if (!hideOn) {
      const event  = this.get('event');

      switch (event) {
        case 'hover': hideOn = 'mouseleave'; break;
        case 'focus': hideOn = 'blur'; break;
        case 'ready': hideOn = null; break;
        default: hideOn = event; break;
      }
    }

    return hideOn;
  }),

  _showOn: computed(function() {
    let showOn = this.get('showOn');

    if (!showOn) {
      const event  = this.get('event');

      switch (event) {
        case 'hover': showOn = 'mouseenter'; break;
        default: showOn = event; break;
      }
    }

    return showOn;
  }),

  /* Methods */

  hide() {

    if (this.get('isDestroying')) {
      return;
    }

    /* If the tooltip is about to be showed by
    a delay, stop is being shown. */

    run.cancel(this.get('_showTimer'));

    this.set('tooltipIsVisible', false);
    this.sendAction('onTooltipHide', this);
  },

  didInsertElement() {
    this._super(...arguments);

    const target = this.get('target');

    if (!target || target.indexOf('#') === -1) {
      Ember.assert('You must specify a target attribute in the format target="#element-id" for the tooltip component');
    }

    const event = this.get('event');
    const $target = $(this.get('target'));
    const _tether = this.get('_tether');
    const $_tether = $(_tether.element);

    this.sendAction('onTooltipRender', this);

    /* Setup event handling to hide and show the tooltip */

    if (event !== 'none') {
      const _hideOn = this.get('_hideOn');
      const _showOn = this.get('_showOn');

      /* If show and hide are the same (e.g. click), toggle
      the visibility */

      if (_showOn === _hideOn) {
        $target.on(_showOn, () => {
          this.toggle();
        });
      } else {

        /* Else, add the show and hide events individually */

        if (_showOn !== 'none') {
          $target.on(_showOn, () => {
            this.show();
          });
        }

        if (_hideOn !== 'none') {
          $target.on(_hideOn, () => {
            this.hide();
          });
        }
      }

      /* Hide and show the tooltip on focus and escape
      for acessibility */

      if (event !== 'focus') {

        /* If the event is click, we don't want the
        click to also trigger focusin */

        if (event !== 'click') {
          $target.focusin(() => {
            this.show();
          });
        }

        $target.focusout(() => {
          this.hide();
        });
      }

      $target.keydown((keyEvent) => {
        if (keyEvent.which === 27) {
          this.hide();
          keyEvent.preventDefault();

          return false;
        }
      });
    }

    $target.attr({
      'aria-describedby': `#${this.get('elementId')}`,
      tabindex: $target.attr('tabindex') || this.get('tabindex'),
    });

    /* When this component has rendered we need
    to check if Tether moved its position to keep the
    element in bounds */

    let renderedSide;

    ['top', 'right', 'bottom', 'left'].forEach(function(side) {
      if ($_tether.hasClass(`ember-tooltip-target-attached-${side}`)) {
        renderedSide = side;
      }
    });

    /* We then use the side the tooltip was *actually*
    rendered on to set the correct offset from
    the target element */

    const spacing = this.get('spacing');

    let offset;

    switch(renderedSide) {
      case 'top':
        offset = `${spacing}px 0`;
        break;
      case 'right':
        offset = `0 -${spacing}px`;
        break;
      case 'bottom':
        offset = `-${spacing}px 0`;
        break;
      case 'left':
        offset = `0 ${spacing}px`;
        break;
    }

    this.set('offset', offset);
  },

  /*
  Repositions the tooltip if new attributes or content are
  passed to the tooltip.

  @method didUpdate
  */

  didUpdate() {
    this._super(...arguments);

    run.later(() => {
      this.positionTether();
      this.sendAction('onTooltipRender', this);
    }, 1000);
  },

  /*
  We use an observer so the user can set tooltipIsVisible
  as a attribute.

  @method setTimer
  */

  setTimer: Ember.observer('tooltipIsVisible', function() {
    const tooltipIsVisible = this.get('tooltipIsVisible');

    if (tooltipIsVisible) {
      const duration = cleanNumber(this.get('duration'));

      run.cancel(this.get('_hideTimer'));

      if (duration) {

        /* Hide tooltip after specified duration */

        const hideTimer = run.later(this, this.hide, duration);

        /* Save timer ID for cancelling should an event
        hide the tooltop before the duration */

        this.set('_hideTimer', hideTimer);
      }
    }
  }),

  show() {

    if (this.get('isDestroying')) {
      return;
    }

    const _showTimer = this.get('_showTimer');

    let delay = cleanNumber(this.get('delay'));

    run.cancel(_showTimer);

    if (delay) {
      if (!this.get('delayOnChange')) {

        /* If the `delayOnChange` property is set to false, we
        don't want to delay opening this tooltip if there is
        already a tooltip visible in the DOM. Check that here
        and adjust the delay as needed. */

        let visibleTooltips = Ember.$('.ember-tooltip[aria-hidden="false"]').length;

        if (visibleTooltips) {
          delay = 0;
        }
      }

      const _showTimer = run.later(this, this.set, 'tooltipIsVisible', true, delay);

      this.set('_showTimer', _showTimer);
    } else {

      /* If there is no delay, show the tooltop immediately */

      this.set('tooltipIsVisible', true);
    }

    this.sendAction('onTooltipShow', this);
  },

  toggle() {

    /* We don't use toggleProperty because we centralize
    logic for showing and hiding in the show() and hide()
    methods. */

    if (this.get('tooltipIsVisible')) {
      this.hide();
    } else {
      this.show();
    }
  },

  willDestroy() {
    const $target = $(this.get('target'));

    this.set('effect', null);
    this.hide();

    $target.removeAttr('aria-describedby');
    $target.off();

    this._super(...arguments); // Removes tether

    this.sendAction('onTooltipDestroy', this);
  },

});
<commit_msg>removed .tooltip class<commit_after>import Ember from 'ember';
import EmberTetherComponent from 'ember-tether/components/ember-tether';

const { $, computed, run } = Ember;

const defaultPosition = 'center';

let tooltipCounterId = 0;

function cleanNumber(stringOrNumber) {
  let cleanNumber;

  if (stringOrNumber && typeof stringOrNumber === 'string') {
    cleanNumber = parseInt(stringOrNumber, 10);

    /* Remove invalid parseInt results */

    if (isNaN(cleanNumber) || !isFinite(cleanNumber)) {
      cleanNumber = 0;
    }
  } else {
    cleanNumber = stringOrNumber;
  }

  return cleanNumber;
}

export default EmberTetherComponent.extend({

  /* Options */

  delay: 0,
  delayOnChange: true,
  duration: 0,
  effect: 'slide', // fade, slide, none
  event: 'hover', // hover, click, focus, none
  hideOn: null,
  role: 'tooltip',
  side: 'top',
  showOn: null,
  spacing: 10,
  tabindex: '0', // A positive integer (to enable) or -1 (to disable)
  tooltipIsVisible: false,
  keepInWindow: true,

  /*
  When this property changes it repositions the tooltip.

  This isn't actually used in the code anywhere - it just
  needs to be passed as an attribute so didUpdate is
  triggered.

  @property updateFor
  */

  updateFor: null,

  /* Actions */

  onTooltipDestroy: null,
  onTooltipHide: null,
  onTooltipRender: null,
  onTooltipShow: null,

  /* Properties */

  'aria-hidden': computed.not('tooltipIsVisible'),
  attributeBindings: ['aria-hidden', 'role', 'tabindex'],
  classNameBindings: ['effectClass'],
  classPrefix: 'ember-tooltip',
  classNames: ['ember-tooltip'],

  _hideTimer: null,
  _showTimer: null,

  /* CPs */

  attachment: computed(function() {
    const side = this.get('side');

    let horizontalPosition, verticalPosition;

    switch(side) {
      case 'top':
        horizontalPosition = defaultPosition;
        verticalPosition = 'bottom';
        break;
      case 'right':
        horizontalPosition = 'left';
        verticalPosition = defaultPosition;
        break;
      case 'bottom':
        horizontalPosition = defaultPosition;
        verticalPosition = 'top';
        break;
      case 'left':
        horizontalPosition = 'right';
        verticalPosition = defaultPosition;
        break;
    }

    return `${verticalPosition} ${horizontalPosition}`;
  }),

  constraints: computed('keepInWindow', function() {
    let constraints;

    if (this.get('keepInWindow')) {
      constraints = [
        {
          to: 'window',
          attachment: 'together'
        }
      ];
    }

    return constraints;
  }),

  effectClass: computed(function() {
    return `ember-tooltip-${this.get('effect')}`;
  }),

  positionClass: computed(function() {
    const targetAttachment = this.get('targetAttachment');

    return `ember-tooltip-${targetAttachment.replace(' ', ' ember-tooltip-')}`;
  }),

  sideIsVertical: computed(function() {
    const side = this.get('side');

    return side === 'top' || side === 'bottom';
  }),

  target: computed(function() {
    const parentElement = this.$().parent();

    let parentElementId = parentElement.attr('id');

    if (!parentElementId) {
      parentElementId = `target-for-tooltip-${tooltipCounterId}`;

      tooltipCounterId++;

      parentElement.attr('id', parentElementId);
    }

    return `#${parentElementId}`;
  }),

  targetAttachment: computed(function() {
    const side = this.get('side');

    if (!this.get('sideIsVertical')) {
      return `center ${side}`;
    } else {
      return `${side} center`; // top and bottom
    }
  }),

  typeClass: computed(function() {
    const type = this.get('type');

    return type ? `ember-tooltip-${type}` : null;
  }),

  /* Private CPs */

  _hideOn: computed(function() {
    let hideOn = this.get('hideOn');

    if (!hideOn) {
      const event  = this.get('event');

      switch (event) {
        case 'hover': hideOn = 'mouseleave'; break;
        case 'focus': hideOn = 'blur'; break;
        case 'ready': hideOn = null; break;
        default: hideOn = event; break;
      }
    }

    return hideOn;
  }),

  _showOn: computed(function() {
    let showOn = this.get('showOn');

    if (!showOn) {
      const event  = this.get('event');

      switch (event) {
        case 'hover': showOn = 'mouseenter'; break;
        default: showOn = event; break;
      }
    }

    return showOn;
  }),

  /* Methods */

  hide() {

    if (this.get('isDestroying')) {
      return;
    }

    /* If the tooltip is about to be showed by
    a delay, stop is being shown. */

    run.cancel(this.get('_showTimer'));

    this.set('tooltipIsVisible', false);
    this.sendAction('onTooltipHide', this);
  },

  didInsertElement() {
    this._super(...arguments);

    const target = this.get('target');

    if (!target || target.indexOf('#') === -1) {
      Ember.assert('You must specify a target attribute in the format target="#element-id" for the tooltip component');
    }

    const event = this.get('event');
    const $target = $(this.get('target'));
    const _tether = this.get('_tether');
    const $_tether = $(_tether.element);

    this.sendAction('onTooltipRender', this);

    /* Setup event handling to hide and show the tooltip */

    if (event !== 'none') {
      const _hideOn = this.get('_hideOn');
      const _showOn = this.get('_showOn');

      /* If show and hide are the same (e.g. click), toggle
      the visibility */

      if (_showOn === _hideOn) {
        $target.on(_showOn, () => {
          this.toggle();
        });
      } else {

        /* Else, add the show and hide events individually */

        if (_showOn !== 'none') {
          $target.on(_showOn, () => {
            this.show();
          });
        }

        if (_hideOn !== 'none') {
          $target.on(_hideOn, () => {
            this.hide();
          });
        }
      }

      /* Hide and show the tooltip on focus and escape
      for acessibility */

      if (event !== 'focus') {

        /* If the event is click, we don't want the
        click to also trigger focusin */

        if (event !== 'click') {
          $target.focusin(() => {
            this.show();
          });
        }

        $target.focusout(() => {
          this.hide();
        });
      }

      $target.keydown((keyEvent) => {
        if (keyEvent.which === 27) {
          this.hide();
          keyEvent.preventDefault();

          return false;
        }
      });
    }

    $target.attr({
      'aria-describedby': `#${this.get('elementId')}`,
      tabindex: $target.attr('tabindex') || this.get('tabindex'),
    });

    /* When this component has rendered we need
    to check if Tether moved its position to keep the
    element in bounds */

    let renderedSide;

    ['top', 'right', 'bottom', 'left'].forEach(function(side) {
      if ($_tether.hasClass(`ember-tooltip-target-attached-${side}`)) {
        renderedSide = side;
      }
    });

    /* We then use the side the tooltip was *actually*
    rendered on to set the correct offset from
    the target element */

    const spacing = this.get('spacing');

    let offset;

    switch(renderedSide) {
      case 'top':
        offset = `${spacing}px 0`;
        break;
      case 'right':
        offset = `0 -${spacing}px`;
        break;
      case 'bottom':
        offset = `-${spacing}px 0`;
        break;
      case 'left':
        offset = `0 ${spacing}px`;
        break;
    }

    this.set('offset', offset);
  },

  /*
  Repositions the tooltip if new attributes or content are
  passed to the tooltip.

  @method didUpdate
  */

  didUpdate() {
    this._super(...arguments);

    run.later(() => {
      this.positionTether();
      this.sendAction('onTooltipRender', this);
    }, 1000);
  },

  /*
  We use an observer so the user can set tooltipIsVisible
  as a attribute.

  @method setTimer
  */

  setTimer: Ember.observer('tooltipIsVisible', function() {
    const tooltipIsVisible = this.get('tooltipIsVisible');

    if (tooltipIsVisible) {
      const duration = cleanNumber(this.get('duration'));

      run.cancel(this.get('_hideTimer'));

      if (duration) {

        /* Hide tooltip after specified duration */

        const hideTimer = run.later(this, this.hide, duration);

        /* Save timer ID for cancelling should an event
        hide the tooltop before the duration */

        this.set('_hideTimer', hideTimer);
      }
    }
  }),

  show() {

    if (this.get('isDestroying')) {
      return;
    }

    const _showTimer = this.get('_showTimer');

    let delay = cleanNumber(this.get('delay'));

    run.cancel(_showTimer);

    if (delay) {
      if (!this.get('delayOnChange')) {

        /* If the `delayOnChange` property is set to false, we
        don't want to delay opening this tooltip if there is
        already a tooltip visible in the DOM. Check that here
        and adjust the delay as needed. */

        let visibleTooltips = Ember.$('.ember-tooltip[aria-hidden="false"]').length;

        if (visibleTooltips) {
          delay = 0;
        }
      }

      const _showTimer = run.later(this, this.set, 'tooltipIsVisible', true, delay);

      this.set('_showTimer', _showTimer);
    } else {

      /* If there is no delay, show the tooltop immediately */

      this.set('tooltipIsVisible', true);
    }

    this.sendAction('onTooltipShow', this);
  },

  toggle() {

    /* We don't use toggleProperty because we centralize
    logic for showing and hiding in the show() and hide()
    methods. */

    if (this.get('tooltipIsVisible')) {
      this.hide();
    } else {
      this.show();
    }
  },

  willDestroy() {
    const $target = $(this.get('target'));

    this.set('effect', null);
    this.hide();

    $target.removeAttr('aria-describedby');
    $target.off();

    this._super(...arguments); // Removes tether

    this.sendAction('onTooltipDestroy', this);
  },

});
<|endoftext|>


<commit_before>import Ember from 'ember';

export default Ember.Mixin.create( {

    setupController: function( controller ){
        controller.set( 'formIsLocked', true );
    }

} );
<commit_msg>add resetController event to toggle-form-lock-route mixin<commit_after>import Ember from 'ember';

export default Ember.Mixin.create( {

    setupController: function( controller ){
        controller.set( 'formIsLocked', true );
    },

    resetController: function( controller ){
        controller.set( 'formIsLocked', true );
    }

} );
<|endoftext|>


<commit_before>import Ember from 'ember';
import NotificationMessage from '../objects/notification-message';
import configuration from '../configuration';

export default Ember.Service.extend({

  messages: Ember.A([]),

  _getPropertyOrDefault(options, propertyName){
    //first try to obtain property value from per-message definition
    let value = options[propertyName];

    //if not available, use global (default) settings
    if (Ember.isNone(value)){
      value = configuration.getDefaultSettingForProperty(options.type, propertyName);
    }

    return value;
  },

  addMessage(options){

    //first make sure, message has "some" type
     options.type = options.type || 'info';

    let timeout = this._getPropertyOrDefault(options, 'timeout');
    let sticky = this._getPropertyOrDefault(options, 'sticky');
    if (timeout < 0){
      sticky = true;
    }

    let messageObject = NotificationMessage.create({
           message: options.message,
           type: options.type,
           timeout: timeout,
           sticky,
           onClick: options.onClick,
           onClose: options.onClose,
           htmlContent: options.htmlContent
       });

    this.get('messages').addObject(messageObject);

    if (!this.get('message.sticky')){
      this.startMessageTimer(messageObject);
    }
  },

  removeMessageFromList(message){
     this.get('messages').removeObject(message);
  },

  markMessageForRemoval(message){
      message.set('removeMe', true);
      Ember.run.cancel(message.get('closeTimer'));
  },

  removeAll(){
    this.get('messages').forEach((msg)=>{this.markMessageForRemoval(msg);});
  },

  startMessageTimer(message){
    if (message.get('sticky')){
      return;
    }
    message.set('startTimeoutTime', Date.now());

    let timer = Ember.run.later(this, () => {
        this.markMessageForRemoval(message);
    }, message.get('timeout'));

    message.set('closeTimer', timer);
  },

  pauseMessageTimeout(message){
    if (message.get('sticky')){
      return;
    }

    Ember.run.cancel(message.get('closeTimer'));

    let remainingTimeout = message.get('timeout') - (Date.now() - message.get('startTimeoutTime'));
    message.set('timeout', remainingTimeout);
  }

});
<commit_msg>convinience methods for error/info/success messages<commit_after>import Ember from 'ember';
import NotificationMessage from '../objects/notification-message';
import configuration from '../configuration';

export default Ember.Service.extend({

  messages: Ember.A([]),

  _getPropertyOrDefault(options, propertyName){
    //first try to obtain property value from per-message definition
    let value = options[propertyName];

    //if not available, use global (default) settings
    if (Ember.isNone(value)){
      value = configuration.getDefaultSettingForProperty(options.type, propertyName);
    }

    return value;
  },

  addMessage(options){

    //first make sure, message has "some" type
     options.type = options.type || 'info';

    let timeout = this._getPropertyOrDefault(options, 'timeout');
    let sticky = this._getPropertyOrDefault(options, 'sticky');
    if (timeout < 0){
      sticky = true;
    }

    let messageObject = NotificationMessage.create({
           message: options.message,
           type: options.type,
           timeout: timeout,
           sticky,
           onClick: options.onClick,
           onClose: options.onClose,
           htmlContent: options.htmlContent
       });

    this.get('messages').addObject(messageObject);

    if (!this.get('message.sticky')){
      this.startMessageTimer(messageObject);
    }
  },

  addError(options){
    options.type = 'error';
    this.addMessage(options);
  },

  addInfo(options){
    options.type = 'info';
    this.addMessage(options);
  },

  addSuccess(options){
    options.type = 'success';
    this.addMessage(options);
  },

  removeMessageFromList(message){
     this.get('messages').removeObject(message);
  },

  markMessageForRemoval(message){
      message.set('removeMe', true);
      Ember.run.cancel(message.get('closeTimer'));
  },

  removeAll(){
    this.get('messages').forEach((msg)=>{this.markMessageForRemoval(msg);});
  },

  startMessageTimer(message){
    if (message.get('sticky')){
      return;
    }
    message.set('startTimeoutTime', Date.now());

    let timer = Ember.run.later(this, () => {
        this.markMessageForRemoval(message);
    }, message.get('timeout'));

    message.set('closeTimer', timer);
  },

  pauseMessageTimeout(message){
    if (message.get('sticky')){
      return;
    }

    Ember.run.cancel(message.get('closeTimer'));

    let remainingTimeout = message.get('timeout') - (Date.now() - message.get('startTimeoutTime'));
    message.set('timeout', remainingTimeout);
  }

});
<|endoftext|>


<commit_before>
import {defineConfig} from "vite";
import html from "@web/rollup-plugin-html";
import copy from "rollup-plugin-copy";
import resolve from "@rollup/plugin-node-resolve";
import minifyHTML from "rollup-plugin-minify-html-literals";
import summary from "rollup-plugin-summary";
import path from "path";
import del from "rollup-plugin-delete";
import {babel, getBabelOutputPlugin} from "@rollup/plugin-babel";
import {terser} from "rollup-plugin-terser";

const buildPath = path.resolve(__dirname, "build-vite");
const ivaPath = path.resolve(__dirname, "src/sites/iva");
const patternExt = /\.[0-9a-z]+$/i;
const patternConfig = /(config|settings|constants|tools)/gi;

export default defineConfig({
    mode: "development",
    root: "./",
    server: {
        open: "/src/sites/iva",
        port: 3000,
        watch: ["src", "styles"]
    },
    build: {
        polyfillModulePreload: true,
        rollupOptions: {
            input: [`${ivaPath}/iva-index.html`, "src/genome-browser/demo/genome-browser.html"],
            preserveEntrySignatures: "strict",
            plugins: [
                del({targets: "build-vite"}),
                html(),
                resolve(),
                minifyHTML(),
                babel({
                    exclude: "node_modules/**",
                    babelHelpers: "runtime",
                    presets: ["@babel/preset-env"],
                    plugins: [
                        "@babel/plugin-proposal-export-default-from",
                        "@babel/plugin-proposal-nullish-coalescing-operator",
                        "@babel/transform-runtime",
                        ["@babel/plugin-proposal-class-properties", {"loose": false}]
                    ]
                }),
                terser({
                    ecma: 2020,
                    module: true,
                    warnings: true
                }),
                summary(),
                copy({
                    targets: [
                        {src: `${ivaPath}/img`, dest: `${buildPath}`},
                        {src: `${ivaPath}/LICENSE`, dest: `${buildPath}`},
                        {src: `${ivaPath}/README.md`, dest: `${buildPath}`},
                        {src: `${ivaPath}/favicon.ico`, dest: `${buildPath}`},
                        {src: "./styles/fonts", dest: `${buildPath}/`},
                        {src: "./node_modules/bootstrap/dist/fonts", dest: `${buildPath}/`},
                        {src: "./node_modules/@fortawesome/fontawesome-free/webfonts", dest: `${buildPath}/`},
                    ]
                }),
            ],
            output: {
                dir: "build-vite",
                assetFileNames: assetInfo => {
                    if (assetInfo.name.match(patternConfig) !== null) {
                        return "conf/[name][extname]";
                    }
                    return "assets/[name]-[hash][extname]";
                }
            }
        },
    }
});
<commit_msg>:wrench:added build-signature rollup config<commit_after>
import {defineConfig} from "vite";
import html from "@web/rollup-plugin-html";
import copy from "rollup-plugin-copy";
import resolve from "@rollup/plugin-node-resolve";
import minifyHTML from "rollup-plugin-minify-html-literals";
import summary from "rollup-plugin-summary";
import path from "path";
import del from "rollup-plugin-delete";
import {babel} from "@rollup/plugin-babel";
import {terser} from "rollup-plugin-terser";
import {execSync} from "child_process";
import pkg from "./package.json";

const buildPath = path.resolve(__dirname, "build-vite");
const ivaPath = path.resolve(__dirname, "src/sites/iva");
const patternExt = /\.[0-9a-z]+$/i;
const patternConfig = /(config|settings|constants|tools)/gi;

const revision = () => {
    try {
        const jsorollaBranch = execSync("git rev-parse --abbrev-ref HEAD").toString();
        const jsorollaSha1 = execSync("git rev-parse HEAD").toString();
        return `~
        ~ Jsorolla Version: ${pkg.version} | Git: ${jsorollaBranch.trim()} - ${jsorollaSha1.trim()}
        ~ Build generated on: ${new Date()}`;
    } catch (error) {
        console.error(`
            Status: ${error.status}
            ${error.stderr.toString()}
        `);
    }
};

export default defineConfig({
    mode: "development",
    root: "./",
    server: {
        open: "/src/sites/iva",
        port: 3000,
        watch: ["src", "styles"]
    },
    build: {
        polyfillModulePreload: true,
        rollupOptions: {
            input: [`${ivaPath}/iva-index.html`, "src/genome-browser/demo/genome-browser.html"],
            preserveEntrySignatures: "strict",
            plugins: [
                del({targets: "build-vite"}),
                html({
                    transformHtml: [html => html.replace("[build-signature]", revision())],
                }),
                resolve(),
                minifyHTML(),
                babel({
                    exclude: "node_modules/**",
                    babelHelpers: "runtime",
                    presets: ["@babel/preset-env"],
                    plugins: [
                        "@babel/plugin-proposal-export-default-from",
                        "@babel/plugin-proposal-nullish-coalescing-operator",
                        "@babel/transform-runtime",
                        ["@babel/plugin-proposal-class-properties", {"loose": false}]
                    ]
                }),
                terser({
                    ecma: 2020,
                    module: true,
                    warnings: true
                }),
                summary(),
                copy({
                    targets: [
                        {src: `${ivaPath}/img`, dest: `${buildPath}`},
                        {src: `${ivaPath}/LICENSE`, dest: `${buildPath}`},
                        {src: `${ivaPath}/README.md`, dest: `${buildPath}`},
                        {src: `${ivaPath}/favicon.ico`, dest: `${buildPath}`},
                        {src: "./styles/fonts", dest: `${buildPath}/`},
                        {src: "./node_modules/bootstrap/dist/fonts", dest: `${buildPath}/`},
                        {src: "./node_modules/@fortawesome/fontawesome-free/webfonts", dest: `${buildPath}/`},
                    ]
                }),
            ],
            output: {
                dir: "build-vite",
                assetFileNames: assetInfo => {
                    if (assetInfo.name.match(patternConfig) !== null) {
                        return "conf/[name][extname]";
                    }
                    return "assets/[name]-[hash][extname]";
                }
            }
        },
    }
});
<|endoftext|>


<commit_before>
M.tool_assignmentupgrade = {
    init_upgrade_table: function(Y) {

        Y.use('node', function(Y) {
            checkboxes = Y.all('td.c0 input');
            checkboxes.each(function(node) {
                node.on('change', function(e) {
                    rowelement = e.currentTarget.get('parentNode').get('parentNode');
                    if (e.currentTarget.get('checked')) {
                        rowelement.setAttribute('class', 'selectedrow');
                    } else {
                        rowelement.setAttribute('class', 'unselectedrow');
                    }
                });

                rowelement = node.get('parentNode').get('parentNode');
                if (node.get('checked')) {
                    rowelement.setAttribute('class', 'selectedrow');
                } else {
                    rowelement.setAttribute('class', 'unselectedrow');
                }
            });
        });

        var selectall = Y.one('th.c0 input');
        selectall.on('change', function(e) {
            if (e.currentTarget.get('checked')) {
                checkboxes = Y.all('td.c0 input');
                checkboxes.each(function(node) {
                    rowelement = node.get('parentNode').get('parentNode');
                    node.set('checked', true);
                    rowelement.setAttribute('class', 'selectedrow');
                });
            } else {
                checkboxes = Y.all('td.c0 input');
                checkboxes.each(function(node) {
                    rowelement = node.get('parentNode').get('parentNode');
                    node.set('checked', false);
                    rowelement.setAttribute('class', 'unselectedrow');
                });
            }
        });

        var batchform = Y.one('.tool_assignmentupgrade_batchform form');
        batchform.on('submit', function(e) {
            checkboxes = Y.all('td.c0 input');
            var selectedassignments = [];
            checkboxes.each(function(node) {
                if (node.get('checked')) {
                    selectedassignments[selectedassignments.length] = node.get('value');
                }
            });

            operation = Y.one('#id_operation');
            assignmentsinput = Y.one('input.selectedassignments');
            assignmentsinput.set('value', selectedassignments.join(','));
            if (selectedassignments.length == 0) {
                alert(M.str.tool_assignmentupgrade.noassignmentsselected);
                e.preventDefault();
            }
        });

        var perpage = Y.one('#id_perpage');
        perpage.on('change', function(e) {
            window.onbeforeunload = null;
            Y.one('.tool_assignmentupgrade_paginationform form').submit();
        });

    }
}
<commit_msg>MDL-35119 tool_assignmentupgrade Changing onsubmit form for onclick button<commit_after>
M.tool_assignmentupgrade = {
    init_upgrade_table: function(Y) {

        Y.use('node', function(Y) {
            checkboxes = Y.all('td.c0 input');
            checkboxes.each(function(node) {
                node.on('change', function(e) {
                    rowelement = e.currentTarget.get('parentNode').get('parentNode');
                    if (e.currentTarget.get('checked')) {
                        rowelement.setAttribute('class', 'selectedrow');
                    } else {
                        rowelement.setAttribute('class', 'unselectedrow');
                    }
                });

                rowelement = node.get('parentNode').get('parentNode');
                if (node.get('checked')) {
                    rowelement.setAttribute('class', 'selectedrow');
                } else {
                    rowelement.setAttribute('class', 'unselectedrow');
                }
            });
        });

        var selectall = Y.one('th.c0 input');
        selectall.on('change', function(e) {
            if (e.currentTarget.get('checked')) {
                checkboxes = Y.all('td.c0 input');
                checkboxes.each(function(node) {
                    rowelement = node.get('parentNode').get('parentNode');
                    node.set('checked', true);
                    rowelement.setAttribute('class', 'selectedrow');
                });
            } else {
                checkboxes = Y.all('td.c0 input');
                checkboxes.each(function(node) {
                    rowelement = node.get('parentNode').get('parentNode');
                    node.set('checked', false);
                    rowelement.setAttribute('class', 'unselectedrow');
                });
            }
        });

        var upgradeselectedbutton = Y.one('#id_upgradeselected');
        upgradeselectedbutton.on('click', function(e) {
            checkboxes = Y.all('td.c0 input');
            var selectedassignments = [];
            checkboxes.each(function(node) {
                if (node.get('checked')) {
                    selectedassignments[selectedassignments.length] = node.get('value');
                }
            });

            operation = Y.one('#id_operation');
            assignmentsinput = Y.one('input.selectedassignments');
            assignmentsinput.set('value', selectedassignments.join(','));
            if (selectedassignments.length == 0) {
                alert(M.str.tool_assignmentupgrade.noassignmentsselected);
                e.preventDefault();
            }
        });

        var perpage = Y.one('#id_perpage');
        perpage.on('change', function(e) {
            window.onbeforeunload = null;
            Y.one('.tool_assignmentupgrade_paginationform form').submit();
        });

    }
}
<|endoftext|>