<commit_before>/*global app, client*/
"use strict";

var async = require('async');
var BaseCollection = require('./baseCollection');
var MUC = require('./muc');

module.exports = BaseCollection.extend({
    type: 'mucs',
    model: MUC,
    comparator: function (model1, model2) {
        var name1 = model1.displayName.toLowerCase();
        var name2 = model2.displayName.toLowerCase();
        if (name1 === name2) {
            return 0;
        }
        if (name1 < name2) {
            return -1;
        }
        return 1;
    },
    initialize: function (model, options) {
        this.bind('change', this.sort, this);
    },
    loadBookmarks: function () {
        var self = this;
        app.whenConnected(function () {
            client.getBookmarks(function (err, res) {
                if (err) return;

                var mucs = res.privateStorage.bookmarks.conferences;
                mucs.forEach(function (muc) {
                    self.add(muc);
                    if (muc.autoJoin) {
                        self.get(muc.jid).join();
                    }
                });
            });
        });
    },
    init: function () {
        var self = this;
        app.whenConnected(function () {

            function _fetch(init) {
                self.fetch(function() {
                    self.update();
                    if (init) self.trigger('loaded');
                    setTimeout(_fetch, 30000);
                });
            }
            _fetch(true);

        });
    },
    fetch: function(cb) {
        var self = this;
        while(app.mucInfos.length > 0) {
            app.mucInfos.pop();
        }

        if (SERVER_CONFIG.muc) {
            if (client.sessionStarted) {

                var rooms = [];
                client.getDiscoItems(SERVER_CONFIG.muc, '', function (err, res) {
                    if (err) return;

                    rooms = res.discoItems.items;
                    if (rooms === undefined)
                        rooms = [];
                    var roomNum = 0;

                    rooms.forEach (function (room) {
                      client.getDiscoInfo(room.jid, '', function (err, res) {

                        roomNum++;
                        if (err) return;

                        var features = res.discoInfo.features;

                        var persistent = features.indexOf("muc_persistent") > -1;
                        var membersOnly = features.indexOf("muc_membersonly") > -1;

                        var mucInfo = {
                          id: room.jid.full,
                          name: room.name,
                          jid: room.jid,
                          nick: me.nick,
                          autoJoin: persistent,
                          persistent: persistent
                        };

                        if(membersOnly)
                        {
							async.parallel([
								function(callback) {
			                        client.getRoomMembers(mucInfo.jid, { items: [ { affiliation: 'member' } ] }, function (err, res) {
									    var members = res.mucAdmin.items.map(function (item) {
									        return item.jid.bare;
									    });
									    var amMember = members.indexOf(client.jid.bare) > -1;
									    callback(null, amMember);
									})
		                    	},
		                    	function(callback) {
			                        client.getRoomMembers(mucInfo.jid, { items: [ { affiliation: 'admin' } ] }, function (err, res) {
									    var members = res.mucAdmin.items.map(function (item) {
									        return item.jid.bare;
									    });
									    var amMember = members.indexOf(client.jid.bare) > -1;
									    callback(null, amMember);
									})
		                    	},
		                    	function(callback) {
			                        client.getRoomMembers(mucInfo.jid, { items: [ { affiliation: 'owner' } ] }, function (err, res) {
									    var members = res.mucAdmin.items.map(function (item) {
									        return item.jid.bare;
									    });
									    var amMember = members.indexOf(client.jid.bare) > -1;
									    callback(null, amMember);
									})
		                    	}
							],
							function(err, results){
								if(results.indexOf('true') > -1)
								{
                        			app.mucInfos.push(mucInfo);
								}
							});
						}
						else
						{
                        	app.mucInfos.push(mucInfo);
						}

                      }).then(function() {
                        if (cb && roomNum == rooms.length) cb();
                      });
                    });
                }).then(function() {
                    if (cb && !rooms.length) cb();
                });

            } else {
                app.whenConnected(function () {
                    self.fetch(cb);
                });
            }
            return;
        }

        if (cb) cb();

    },
    update: function () {
        if (SERVER_CONFIG.muc) {
            var toRemove = [];
            for ( var i = 0; i < this.models.length; i++) {
                toRemove.push(this.models[i]);
            }

            for (var i = 0; i < app.mucInfos.length; i++) {

                var mucInfo = app.mucInfos[i];
                var muc = this.get(mucInfo.jid);
                if (muc) {
                    muc.name = mucInfo.name;
                    muc.autoJoin =  mucInfo.autoJoin;
                    muc.persistent = mucInfo.persistent;

                    var index = toRemove.indexOf(muc);
                    if (index > -1) {
                        toRemove.splice(index, 1);
                    }
                }
                else {
                    this.add(mucInfo);
                    muc = this.get(mucInfo.jid);
                }

                if (muc.autoJoin && !muc.joined) {
                    muc.join();
                }

            }

            this.remove(toRemove);

            while(app.mucInfos.length > 0) {
                app.mucInfos.pop();
            }
        }
    },
    save: function (cb) {
        var self = this;
        app.whenConnected(function () {
            var models = [];
            self.models.forEach(function (model) {
                models.push({
                    name: model.name,
                    jid: model.jid,
                    nick: model.nick,
                    autoJoin: model.autoJoin
                });
            });
            client.setBookmarks({conferences: models}, cb);
        });
    }
});
<commit_msg>Attempting to log errors<commit_after>/*global app, client*/
"use strict";

var async = require('async');
var BaseCollection = require('./baseCollection');
var MUC = require('./muc');

module.exports = BaseCollection.extend({
    type: 'mucs',
    model: MUC,
    comparator: function (model1, model2) {
        var name1 = model1.displayName.toLowerCase();
        var name2 = model2.displayName.toLowerCase();
        if (name1 === name2) {
            return 0;
        }
        if (name1 < name2) {
            return -1;
        }
        return 1;
    },
    initialize: function (model, options) {
        this.bind('change', this.sort, this);
    },
    loadBookmarks: function () {
        var self = this;
        app.whenConnected(function () {
            client.getBookmarks(function (err, res) {
                if (err) return;

                var mucs = res.privateStorage.bookmarks.conferences;
                mucs.forEach(function (muc) {
                    self.add(muc);
                    if (muc.autoJoin) {
                        self.get(muc.jid).join();
                    }
                });
            });
        });
    },
    init: function () {
        var self = this;
        app.whenConnected(function () {

            function _fetch(init) {
                self.fetch(function() {
                    self.update();
                    if (init) self.trigger('loaded');
                    setTimeout(_fetch, 30000);
                });
            }
            _fetch(true);

        });
    },
    fetch: function(cb) {
        var self = this;
        while(app.mucInfos.length > 0) {
            app.mucInfos.pop();
        }

        if (SERVER_CONFIG.muc) {
            if (client.sessionStarted) {

                var rooms = [];
                client.getDiscoItems(SERVER_CONFIG.muc, '', function (err, res) {
                    if (err) return;

                    rooms = res.discoItems.items;
                    if (rooms === undefined)
                        rooms = [];
                    var roomNum = 0;

                    rooms.forEach (function (room) {
                      client.getDiscoInfo(room.jid, '', function (err, res) {

                        roomNum++;
                        if (err) return;

                        var features = res.discoInfo.features;

                        var persistent = features.indexOf("muc_persistent") > -1;
                        var membersOnly = features.indexOf("muc_membersonly") > -1;

                        var mucInfo = {
                          id: room.jid.full,
                          name: room.name,
                          jid: room.jid,
                          nick: me.nick,
                          autoJoin: persistent,
                          persistent: persistent
                        };

                        if(membersOnly)
                        {
							async.parallel([
								function(callback) {
			                        client.getRoomMembers(mucInfo.jid, { items: [ { affiliation: 'member' } ] }, function (err, res) {
			                        	if(err) {
			                        		console.log(err);
			                        		callback(null, false);
			                        	}
									    var members = res.mucAdmin.items.map(function (item) {
									        return item.jid.bare;
									    });
									    var amMember = members.indexOf(client.jid.bare) > -1;
									    callback(null, amMember);
									})
		                    	},
		                    	function(callback) {
			                        client.getRoomMembers(mucInfo.jid, { items: [ { affiliation: 'admin' } ] }, function (err, res) {
			                        	if(err) {
			                        		console.log(err);
			                        		callback(null, false);
			                        	}
									    var members = res.mucAdmin.items.map(function (item) {
									        return item.jid.bare;
									    });
									    var amMember = members.indexOf(client.jid.bare) > -1;
									    callback(null, amMember);
									})
		                    	},
		                    	function(callback) {
			                        client.getRoomMembers(mucInfo.jid, { items: [ { affiliation: 'owner' } ] }, function (err, res) {
			                        	if(err) {
			                        		console.log(err);
			                        		callback(null, false);
			                        	}
									    var members = res.mucAdmin.items.map(function (item) {
									        return item.jid.bare;
									    });
									    var amMember = members.indexOf(client.jid.bare) > -1;
									    callback(null, amMember);
									})
		                    	}
							],
							function(err, results){
								if(results.indexOf('true') > -1)
								{
                        			app.mucInfos.push(mucInfo);
								}
							});
						}
						else
						{
                        	app.mucInfos.push(mucInfo);
						}

                      }).then(function() {
                        if (cb && roomNum == rooms.length) cb();
                      });
                    });
                }).then(function() {
                    if (cb && !rooms.length) cb();
                });

            } else {
                app.whenConnected(function () {
                    self.fetch(cb);
                });
            }
            return;
        }

        if (cb) cb();

    },
    update: function () {
        if (SERVER_CONFIG.muc) {
            var toRemove = [];
            for ( var i = 0; i < this.models.length; i++) {
                toRemove.push(this.models[i]);
            }

            for (var i = 0; i < app.mucInfos.length; i++) {

                var mucInfo = app.mucInfos[i];
                var muc = this.get(mucInfo.jid);
                if (muc) {
                    muc.name = mucInfo.name;
                    muc.autoJoin =  mucInfo.autoJoin;
                    muc.persistent = mucInfo.persistent;

                    var index = toRemove.indexOf(muc);
                    if (index > -1) {
                        toRemove.splice(index, 1);
                    }
                }
                else {
                    this.add(mucInfo);
                    muc = this.get(mucInfo.jid);
                }

                if (muc.autoJoin && !muc.joined) {
                    muc.join();
                }

            }

            this.remove(toRemove);

            while(app.mucInfos.length > 0) {
                app.mucInfos.pop();
            }
        }
    },
    save: function (cb) {
        var self = this;
        app.whenConnected(function () {
            var models = [];
            self.models.forEach(function (model) {
                models.push({
                    name: model.name,
                    jid: model.jid,
                    nick: model.nick,
                    autoJoin: model.autoJoin
                });
            });
            client.setBookmarks({conferences: models}, cb);
        });
    }
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright The Closure Library Authors.
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @fileoverview Shims between goog.iter.Iterator and ES6 iterator.
 */

goog.module('goog.iter.es6');
goog.module.declareLegacyNamespace();

const GoogIterable = goog.require('goog.iter.Iterable');
const GoogIterator = goog.require('goog.iter.Iterator');
const StopIteration = goog.require('goog.iter.StopIteration');

/**
 * Common interface extending both `goog.iter.Iterable` and ES6 `Iterable`,
 * and providing `toGoog()` and `toEs6()` methods to get either kind
 * of iterator.  `ShimIterable.of()` is the primary entry point for
 * this library.  If it is given an iterable that is *not* also an
 * iterator, then it will inherit any reusability from its argument
 * (i.e. `ShimIterable.of(mySet)` will be reusable, since mySet makes
 * a fresh Iterator every time, whereas `ShimIterable.of(myIterator)`
 * will be one-shot).
 *
 * `ShimGoogIterator` and `ShimEs6Iterator` extend `ShimIterable` and
 * also implement one or the other iterator API.  Since they extend
 * `ShimIterable`, it is easy to convert back and forth between the two
 * APIs.  Any such conversion will expose a view to the same underlying
 * iterator, so elements pulled via one API will not be available from
 * the other.
 *
 * @interface
 * @extends {Iterable<VALUE>}
 * @template VALUE
 */
class ShimIterable {
  /** @return {!GoogIterator<VALUE>} */
  __iterator__() {}

  /** @return {!ShimGoogIterator<VALUE>} */
  toGoog() {}

  /** @return {!ShimEs6Iterator<VALUE>} */
  toEs6() {}

  /**
   * @param {!Iterable<VALUE>|!Iterator<VALUE>|
   *         !GoogIterator<VALUE>|!GoogIterable} iter
   * @return {!ShimIterable}
   * @template VALUE
   */
  static of(iter) {
    if (iter instanceof ShimIterableImpl || iter instanceof ShimGoogIterator ||
        iter instanceof ShimEs6Iterator) {
      return iter;
    } else if (typeof iter.nextValueOrThrow == 'function') {
      return new ShimIterableImpl(
          () => wrapGoog(/** @type {!Iterator|!GoogIterator} */ (iter)));
    } else if (typeof iter[Symbol.iterator] == 'function') {
      return new ShimIterableImpl(() => iter[Symbol.iterator]());
    } else if (typeof iter.__iterator__ == 'function') {
      return new ShimIterableImpl(
          () => wrapGoog(
              /** @type {{__iterator__:function(this:?, boolean=)}} */ (iter)
                  .__iterator__()));
    }
    throw new Error('Not an iterator or iterable.');
  }
}

/**
 * @param {!GoogIterator<VALUE>|!Iterator<VALUE>} iter
 * @return {!Iterator<VALUE>}
 * @template VALUE
 */
const wrapGoog = (iter) => {
  if (!(iter instanceof GoogIterator)) return iter;
  let done = false;
  return /** @type {?} */ ({
    next() {
      let value;
      while (!done) {
        try {
          value = /** @type {!GoogIterator<VALUE>} */ (iter).nextValueOrThrow();
          break;
        } catch (err) {
          if (err !== StopIteration) throw err;
          done = true;
        }
      }
      return {value, done};
    },
  });
};

/**
 * Concrete (private) implementation of a non-iterator iterable.  This is
 * separate from the iterator versions since it supports iterables that
 * are not "one-shot".
 * @implements {ShimIterable<VALUE>}
 * @template VALUE
 */
class ShimIterableImpl {
  /** @param {function(): !Iterator<VALUE>} func */
  constructor(func) {
    /** @const @private */
    this.func_ = func;
  }

  /** @override */
  __iterator__() {
    return new ShimGoogIterator(this.func_());
  }

  /** @override */
  toGoog() {
    return new ShimGoogIterator(this.func_());
  }

  /** @override */
  [Symbol.iterator]() {
    return new ShimEs6Iterator(this.func_());
  }

  /** @override */
  toEs6() {
    return new ShimEs6Iterator(this.func_());
  }
}

/**
 * Concrete `goog.iter.Iterator` subclass that also implements `ShimIterable`.
 * @extends {GoogIterator<VALUE>}
 * @implements {ShimIterable<VALUE>}
 * @template VALUE
 */
class ShimGoogIterator extends GoogIterator {
  /** @param {!Iterator<VALUE>} iter */
  constructor(iter) {
    super();
    this.iter_ = iter;
  }

  /** @override */
  nextValueOrThrow() {
    const result = this.iter_.next();
    if (result.done) throw StopIteration;
    return result.value;
  }
  /**
   * @override @see {!goog.iter.Iterator}
   * @return {!IIterableResult<VALUE>}
   */
  next() {
    return this.iter_.next();
  }

  /** @override */
  toGoog() {
    return this;
  }

  /** @override */
  [Symbol.iterator]() {
    return new ShimEs6Iterator(this.iter_);
  }

  /** @override */
  toEs6() {
    return new ShimEs6Iterator(this.iter_);
  }
}

/**
 * Concrete ES6 `Iterator` that also implements `ShimIterable`.
 * @implements {IteratorIterable<VALUE>}
 * @extends {ShimIterableImpl<VALUE>}
 * @template VALUE
 */
class ShimEs6Iterator extends ShimIterableImpl {
  /** @param {!Iterator<VALUE>} iter */
  constructor(iter) {
    super(() => iter);
    /** @const @private */
    this.iter_ = iter;
  }

  /** @override */
  next() {
    return this.iter_.next();
  }
}

exports = {
  ShimIterable,
  ShimEs6Iterator,
  ShimGoogIterator,
};
<commit_msg>Migrate goog.iter.Iterator #nextValueOrThrow usages to #next calls. RELNOTES: n/a<commit_after>/**
 * @license
 * Copyright The Closure Library Authors.
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @fileoverview Shims between goog.iter.Iterator and ES6 iterator.
 */

goog.module('goog.iter.es6');
goog.module.declareLegacyNamespace();

const GoogIterable = goog.require('goog.iter.Iterable');
const GoogIterator = goog.require('goog.iter.Iterator');
const StopIteration = goog.require('goog.iter.StopIteration');

/**
 * Common interface extending both `goog.iter.Iterable` and ES6 `Iterable`,
 * and providing `toGoog()` and `toEs6()` methods to get either kind
 * of iterator.  `ShimIterable.of()` is the primary entry point for
 * this library.  If it is given an iterable that is *not* also an
 * iterator, then it will inherit any reusability from its argument
 * (i.e. `ShimIterable.of(mySet)` will be reusable, since mySet makes
 * a fresh Iterator every time, whereas `ShimIterable.of(myIterator)`
 * will be one-shot).
 *
 * `ShimGoogIterator` and `ShimEs6Iterator` extend `ShimIterable` and
 * also implement one or the other iterator API.  Since they extend
 * `ShimIterable`, it is easy to convert back and forth between the two
 * APIs.  Any such conversion will expose a view to the same underlying
 * iterator, so elements pulled via one API will not be available from
 * the other.
 *
 * @interface
 * @extends {Iterable<VALUE>}
 * @template VALUE
 */
class ShimIterable {
  /** @return {!GoogIterator<VALUE>} */
  __iterator__() {}

  /** @return {!ShimGoogIterator<VALUE>} */
  toGoog() {}

  /** @return {!ShimEs6Iterator<VALUE>} */
  toEs6() {}

  /**
   * @param {!Iterable<VALUE>|!Iterator<VALUE>|
   *         !GoogIterator<VALUE>|!GoogIterable} iter
   * @return {!ShimIterable}
   * @template VALUE
   */
  static of(iter) {
    if (iter instanceof ShimIterableImpl || iter instanceof ShimGoogIterator ||
        iter instanceof ShimEs6Iterator) {
      return iter;
    } else if (typeof iter.next == 'function') {
      return new ShimIterableImpl(
          () => /** @type {!Iterator|!GoogIterator} */ (iter));
    } else if (typeof iter[Symbol.iterator] == 'function') {
      return new ShimIterableImpl(() => iter[Symbol.iterator]());
    } else if (typeof iter.__iterator__ == 'function') {
      return new ShimIterableImpl(
          () => /** @type {{__iterator__:function(this:?, boolean=)}} */ (iter)
                    .__iterator__());
    }
    throw new Error('Not an iterator or iterable.');
  }
}

/**
 * Concrete (private) implementation of a non-iterator iterable.  This is
 * separate from the iterator versions since it supports iterables that
 * are not "one-shot".
 * @implements {ShimIterable<VALUE>}
 * @template VALUE
 */
class ShimIterableImpl {
  /** @param {function(): !Iterator<VALUE>} func */
  constructor(func) {
    /** @const @private */
    this.func_ = func;
  }

  /** @override */
  __iterator__() {
    return new ShimGoogIterator(this.func_());
  }

  /** @override */
  toGoog() {
    return new ShimGoogIterator(this.func_());
  }

  /** @override */
  [Symbol.iterator]() {
    return new ShimEs6Iterator(this.func_());
  }

  /** @override */
  toEs6() {
    return new ShimEs6Iterator(this.func_());
  }
}

/**
 * Concrete `goog.iter.Iterator` subclass that also implements `ShimIterable`.
 * @extends {GoogIterator<VALUE>}
 * @implements {ShimIterable<VALUE>}
 * @template VALUE
 */
class ShimGoogIterator extends GoogIterator {
  /** @param {!Iterator<VALUE>} iter */
  constructor(iter) {
    super();
    this.iter_ = iter;
  }

  /** @override */
  nextValueOrThrow() {
    const result = this.iter_.next();
    if (result.done) throw StopIteration;
    return result.value;
  }
  /**
   * @override @see {!goog.iter.Iterator}
   * @return {!IIterableResult<VALUE>}
   */
  next() {
    return this.iter_.next();
  }

  /** @override */
  toGoog() {
    return this;
  }

  /** @override */
  [Symbol.iterator]() {
    return new ShimEs6Iterator(this.iter_);
  }

  /** @override */
  toEs6() {
    return new ShimEs6Iterator(this.iter_);
  }
}

/**
 * Concrete ES6 `Iterator` that also implements `ShimIterable`.
 * @implements {IteratorIterable<VALUE>}
 * @extends {ShimIterableImpl<VALUE>}
 * @template VALUE
 */
class ShimEs6Iterator extends ShimIterableImpl {
  /** @param {!Iterator<VALUE>} iter */
  constructor(iter) {
    super(() => iter);
    /** @const @private */
    this.iter_ = iter;
  }

  /** @override */
  next() {
    return this.iter_.next();
  }
}

exports = {
  ShimIterable,
  ShimEs6Iterator,
  ShimGoogIterator,
};
<|endoftext|>


<commit_before><commit_msg>Removed defunct function<commit_after><|endoftext|>


<commit_before>var blacklist = require('blacklist');
var classNames = require('classnames');
var ErrorView = require('./ErrorView');
var React = require('react/addons');
var Transition = React.addons.CSSTransitionGroup;

function createViewsFromChildren (children) {
	var views = {};
	React.Children.forEach(children, function (view) {
		views[view.props.name] = view;
	});
	return views;
}

var ViewContainer = React.createClass({
	statics: {
		shouldFillVerticalSpace: true
	},
	propTypes: {
		children: React.PropTypes.node
	},
	render () {
		var props = blacklist(this.props, 'children');
		return
{this.props.children}
;
	}
});

var ViewManager = React.createClass({
	statics: {
		shouldFillVerticalSpace: true
	},
	contextTypes: {
		app: React.PropTypes.object.isRequired
	},
	propTypes: {
		name: React.PropTypes.string,
		children: React.PropTypes.node,
		className: React.PropTypes.string,
		defaultView: React.PropTypes.string,
		onViewChange: React.PropTypes.func
	},
	getDefaultProps () {
		return {
			name: '__default'
		};
	},
	getInitialState () {
		return {
			views: createViewsFromChildren(this.props.children),
			currentView: this.props.defaultView,
			options: {}
		};
	},
	componentDidMount () {
		this.context.app.viewManagers[this.props.name] = this;
	},
	componentWillUnmount () {
		delete this.context.app.viewManagers[this.props.name];
	},
	componentWillReceiveProps (nextProps) {
		this.setState({
			views: createViewsFromChildren(this.props.children)
		});
		if (nextProps.name !== this.props.name) {
			this.context.app.viewManagers[nextProps.name] = this;
			delete this.context.app.viewManagers[this.props.name];
		}
		if (nextProps.currentView && nextProps.currentView !== this.state.currentView) {
			this.transitionTo(nextProps.currentView, { viewProps: nextProps.viewProps });
		}
	},
	transitionTo (viewKey, options) {
		if (typeof options === 'string') {
			options = { transition: options };
		}
		if (!options) options = {};
		this.activeTransitionOptions = options;
		this.context.app.viewManagerInTransition = this;
		this.props.onViewChange && this.props.onViewChange(viewKey);
		this.setState({
			currentView: viewKey,
			options: options
		}, () => {
			delete this.activeTransitionOptions;
			delete this.context.app.viewManagerInTransition;
		});
	},
	renderViewContainer () {
		var viewKey = this.state.currentView;
		if (!viewKey) {
			return (
				<ErrorView>
					ViewManager: {this.props.name}
					Error: There is no current View.
				</ErrorView>
			);
		}
		var view = this.state.views[viewKey];
		if (!view || !view.props.component) {
			return (
				<ErrorView>
					ViewManager: {this.props.name}
					Error: The Current View ({viewKey}) is invalid.
				</ErrorView>
			);
		}
		var options = this.state.options || {};
		var viewClassName = classNames('View View--' + viewKey, view.props.className);
		var ViewComponent = view.props.component;
		var viewProps = blacklist(view.props, 'component', 'className');
		Object.assign(viewProps, options.viewProps);
		var viewElement = <ViewComponent {...viewProps} />;

		if (this.__lastRenderedView !== viewKey) {
			// console.log('initialising view ' + viewKey + ' with options', options);
			if (viewElement.type.navigationBar && viewElement.type.getNavigation) {
				var app = this.context.app;
				var transition = options.transition;
				if (app.viewManagerInTransition) {
					transition = app.viewManagerInTransition.activeTransitionOptions.transition;
				}
				setTimeout(() => {
					app.navigationBars[viewElement.type.navigationBar].updateWithTransition(viewElement.type.getNavigation(viewProps, app), transition);
				}, 0);
			}
			this.__lastRenderedView = viewKey;
		}

		return (
			<ViewContainer className={viewClassName} key={viewKey}>
				{viewElement}
			</ViewContainer>
		);
	},
	render () {
		var className = classNames('ViewManager', this.props.className);
		var viewContainer = this.renderViewContainer(this.state.currentView, { viewProps: this.state.currentViewProps });

		var transitionName = 'view-transition-instant';
		if (this.state.options.transition) {
			// console.log('applying view transition: ' + this.state.options.transition + ' to view ' + this.state.currentView);
			transitionName = 'view-transition-' + this.state.options.transition;
		}
		return (
			<Transition transitionName={transitionName} transitionEnter={true} transitionLeave={true} className={className} component="div">
				{viewContainer}
			</Transition>
		);
	}
});

export default ViewManager;
<commit_msg>improve view manager error message<commit_after>var blacklist = require('blacklist');
var classNames = require('classnames');
var ErrorView = require('./ErrorView');
var React = require('react/addons');
var Transition = React.addons.CSSTransitionGroup;

function createViewsFromChildren (children) {
	var views = {};
	React.Children.forEach(children, function (view) {
		views[view.props.name] = view;
	});
	return views;
}

var ViewContainer = React.createClass({
	statics: {
		shouldFillVerticalSpace: true
	},
	propTypes: {
		children: React.PropTypes.node
	},
	render () {
		var props = blacklist(this.props, 'children');
		return
{this.props.children}
;
	}
});

var ViewManager = React.createClass({
	statics: {
		shouldFillVerticalSpace: true
	},
	contextTypes: {
		app: React.PropTypes.object.isRequired
	},
	propTypes: {
		name: React.PropTypes.string,
		children: React.PropTypes.node,
		className: React.PropTypes.string,
		defaultView: React.PropTypes.string,
		onViewChange: React.PropTypes.func
	},
	getDefaultProps () {
		return {
			name: '__default'
		};
	},
	getInitialState () {
		return {
			views: createViewsFromChildren(this.props.children),
			currentView: this.props.defaultView,
			options: {}
		};
	},
	componentDidMount () {
		this.context.app.viewManagers[this.props.name] = this;
	},
	componentWillUnmount () {
		delete this.context.app.viewManagers[this.props.name];
	},
	componentWillReceiveProps (nextProps) {
		this.setState({
			views: createViewsFromChildren(this.props.children)
		});
		if (nextProps.name !== this.props.name) {
			this.context.app.viewManagers[nextProps.name] = this;
			delete this.context.app.viewManagers[this.props.name];
		}
		if (nextProps.currentView && nextProps.currentView !== this.state.currentView) {
			this.transitionTo(nextProps.currentView, { viewProps: nextProps.viewProps });
		}
	},
	transitionTo (viewKey, options) {
		if (typeof options === 'string') {
			options = { transition: options };
		}
		if (!options) options = {};
		this.activeTransitionOptions = options;
		this.context.app.viewManagerInTransition = this;
		this.props.onViewChange && this.props.onViewChange(viewKey);
		this.setState({
			currentView: viewKey,
			options: options
		}, () => {
			delete this.activeTransitionOptions;
			delete this.context.app.viewManagerInTransition;
		});
	},
	renderViewContainer () {
		var viewKey = this.state.currentView;
		if (!viewKey) {
			return (
				<ErrorView>
					ViewManager: {this.props.name}
					Error: There is no current View.
				</ErrorView>
			);
		}
		var view = this.state.views[viewKey];
		if (!view || !view.props.component) {
			return (
				<ErrorView>
					ViewManager: "{this.props.name}"
					The View "{viewKey}" is invalid.
				</ErrorView>
			);
		}
		var options = this.state.options || {};
		var viewClassName = classNames('View View--' + viewKey, view.props.className);
		var ViewComponent = view.props.component;
		var viewProps = blacklist(view.props, 'component', 'className');
		Object.assign(viewProps, options.viewProps);
		var viewElement = <ViewComponent {...viewProps} />;

		if (this.__lastRenderedView !== viewKey) {
			// console.log('initialising view ' + viewKey + ' with options', options);
			if (viewElement.type.navigationBar && viewElement.type.getNavigation) {
				var app = this.context.app;
				var transition = options.transition;
				if (app.viewManagerInTransition) {
					transition = app.viewManagerInTransition.activeTransitionOptions.transition;
				}
				setTimeout(() => {
					app.navigationBars[viewElement.type.navigationBar].updateWithTransition(viewElement.type.getNavigation(viewProps, app), transition);
				}, 0);
			}
			this.__lastRenderedView = viewKey;
		}

		return (
			<ViewContainer className={viewClassName} key={viewKey}>
				{viewElement}
			</ViewContainer>
		);
	},
	render () {
		var className = classNames('ViewManager', this.props.className);
		var viewContainer = this.renderViewContainer(this.state.currentView, { viewProps: this.state.currentViewProps });

		var transitionName = 'view-transition-instant';
		if (this.state.options.transition) {
			// console.log('applying view transition: ' + this.state.options.transition + ' to view ' + this.state.currentView);
			transitionName = 'view-transition-' + this.state.options.transition;
		}
		return (
			<Transition transitionName={transitionName} transitionEnter={true} transitionLeave={true} className={className} component="div">
				{viewContainer}
			</Transition>
		);
	}
});

export default ViewManager;
<|endoftext|>


<commit_before>//----------------------------------------------------------------------------
//  Copyright (C) 2008-2011  The IPython Development Team
//
//  Distributed under the terms of the BSD License.  The full license is in
//  the file COPYING, distributed as part of this software.
//----------------------------------------------------------------------------
//============================================================================
// Tooltip
//============================================================================
//
// you can set the autocall time by setting `IPython.tooltip.time_before_tooltip` in ms
//
// you can configure the differents action of pressing tab several times in a row by
// setting/appending different fonction in the array
// IPython.tooltip.tabs_functions
//
// eg :
// IPython.tooltip.tabs_functions[4] = function (){console.log('this is the action of the 4th tab pressing')}
//
var IPython = (function (IPython) {
    "use strict";

    var utils = IPython.utils;

    // tooltip constructor
    var Tooltip = function () {
            var that = this;
            this.time_before_tooltip = 1200;

            // handle to html
            this.tooltip = $('#tooltip');
            this._hidden = true;

            // variable for consecutive call
            this._old_cell = null;
            this._old_request = null;
            this._consecutive_counter = 0;

            // 'sticky ?'
            this._sticky = false;

            // display tooltip if the docstring is empty?
            this._hide_if_no_docstring = false;

            // contain the button in the upper right corner
            this.buttons = $('<div/>').addClass('tooltipbuttons');

            // will contain the docstring
            this.text = $('<div/>').addClass('tooltiptext').addClass('smalltooltip');

            // build the buttons menu on the upper right
            // expand the tooltip to see more
            var expandlink = $('<a/>').attr('href', "#").addClass("ui-corner-all") //rounded corner
            .attr('role', "button").attr('id', 'expanbutton').attr('title', 'Grow the tooltip vertically (press tab 2 times)').click(function () {
                that.expand()
            }).append(
            $('<span/>').text('Expand').addClass('ui-icon').addClass('ui-icon-plus'));

            // open in pager
            var morelink = $('<a/>').attr('href', "#").attr('role', "button").addClass('ui-button').attr('title', 'show the current docstring in pager (press tab 4 times)');
            var morespan = $('<span/>').text('Open in Pager').addClass('ui-icon').addClass('ui-icon-arrowstop-l-n');
            morelink.append(morespan);
            morelink.click(function () {
                that.showInPager(that._old_cell);
            });

            // close the tooltip
            var closelink = $('<a/>').attr('href', "#").attr('role', "button").addClass('ui-button');
            var closespan = $('<span/>').text('Close').addClass('ui-icon').addClass('ui-icon-close');
            closelink.append(closespan);
            closelink.click(function () {
                that.remove_and_cancel_tooltip(true);
            });

            this._clocklink = $('<a/>').attr('href', "#");
            this._clocklink.attr('role', "button");
            this._clocklink.addClass('ui-button');
            this._clocklink.attr('title', 'Tootip is not dismissed while typing for 10 seconds');
            var clockspan = $('<span/>').text('Close');
            clockspan.addClass('ui-icon');
            clockspan.addClass('ui-icon-clock');
            this._clocklink.append(clockspan);
            this._clocklink.click(function () {
                that.cancel_stick();
            });

            //construct the tooltip
            // add in the reverse order you want them to appear
            this.buttons.append(closelink);
            this.buttons.append(expandlink);
            this.buttons.append(morelink);
            this.buttons.append(this._clocklink);
            this._clocklink.hide();

            // we need a phony element to make the small arrow
            // of the tooltip in css
            // we will move the arrow later
            this.arrow = $('<div/>').addClass('pretooltiparrow');
            this.tooltip.append(this.buttons);
            this.tooltip.append(this.arrow);
            this.tooltip.append(this.text);

            // function that will be called if you press tab 1, 2, 3... times in a row
            this.tabs_functions = [function (cell, text) {
                that._request_tooltip(cell, text);
            }, function () {
                that.expand();
            }, function () {
                that.stick();
            }, function (cell) {
                that.cancel_stick();
                that.showInPager(cell);
            }];
            // call after all the tabs function above have bee call to clean their effects
            // if necessary
            this.reset_tabs_function = function (cell, text) {
                this._old_cell = (cell) ? cell : null;
                this._old_request = (text) ? text : null;
                this._consecutive_counter = 0;
            }
        };

    Tooltip.prototype.showInPager = function (cell) {
        // reexecute last call in pager by appending ? to show back in pager
        var that = this;
        var empty = function () {};
        cell.kernel.execute(
        that.name + '?', {
            'execute_reply': empty,
            'output': empty,
            'clear_output': empty,
            'cell': cell
        }, {
            'silent': false,
            'store_history': true
        });
        this.remove_and_cancel_tooltip();
    }

    // grow the tooltip verticaly
    Tooltip.prototype.expand = function () {
        this.text.removeClass('smalltooltip');
        this.text.addClass('bigtooltip');
        $('#expanbutton').hide('slow');
    }

    // deal with all the logic of hiding the tooltip
    // and reset it's status
    Tooltip.prototype._hide = function () {
        this.tooltip.fadeOut('fast');
        $('#expanbutton').show('slow');
        this.text.removeClass('bigtooltip');
        this.text.addClass('smalltooltip');
        // keep scroll top to be sure to always see the first line
        this.text.scrollTop(0);
        this._hidden = true;
        this.code_mirror = null;
    }

    // return true on successfully removing a visible tooltip; otherwise return
    // false.
    Tooltip.prototype.remove_and_cancel_tooltip = function (force) {
        // note that we don't handle closing directly inside the calltip
        // as in the completer, because it is not focusable, so won't
        // get the event.
        this.cancel_pending();
        if (!this._hidden) {
          if (force || !this._sticky) {
              this.cancel_stick();
              this._hide();
          }
          this.reset_tabs_function();
          return true;
        } else {
          return false;
        }
    }

    // cancel autocall done after '(' for example.
    Tooltip.prototype.cancel_pending = function () {
        if (this._tooltip_timeout != null) {
            clearTimeout(this._tooltip_timeout);
            this._tooltip_timeout = null;
        }
    }

    // will trigger tooltip after timeout
    Tooltip.prototype.pending = function (cell, hide_if_no_docstring) {
        var that = this;
        this._tooltip_timeout = setTimeout(function () {
            that.request(cell, hide_if_no_docstring)
        }, that.time_before_tooltip);
    }

    // easy access for julia monkey patching.
    Tooltip.last_token_re = /[a-z_][0-9a-z._]+$/gi;

    Tooltip.prototype.extract_oir_token = function(line){
        // use internally just to make the request to the kernel
        // Feel free to shorten this logic if you are better
        // than me in regEx
        // basicaly you shoul be able to get xxx.xxx.xxx from
        // something(range(10), kwarg=smth) ; xxx.xxx.xxx( firstarg, rand(234,23), kwarg1=2,
        // remove everything between matchin bracket (need to iterate)
        var matchBracket = /\([^\(\)]+\)/g;
        var endBracket = /\([^\(]*$/g;
        var oldline = line;

        line = line.replace(matchBracket, "");
        while (oldline != line) {
            oldline = line;
            line = line.replace(matchBracket, "");
        }
        // remove everything after last open bracket
        line = line.replace(endBracket, "");
        return Tooltip.last_token_re.exec(line)
    }

    Tooltip.prototype._request_tooltip = function (cell, line) {
        var callbacks = {
            'object_info_reply': $.proxy(this._show, this)
        }
        var oir_token = this.extract_oir_token(line);
        var msg_id = cell.session.kernel.object_info_request(oir_token, callbacks);
    }

    // make an imediate completion request
    Tooltip.prototype.request = function (cell, hide_if_no_docstring) {
        // request(codecell)
        // Deal with extracting the text from the cell and counting
        // call in a row
        this.cancel_pending();
        var editor = cell.code_mirror;
        var cursor = editor.getCursor();
        var text = editor.getRange({
            line: cursor.line,
            ch: 0
        }, cursor).trim();

        this._hide_if_no_docstring = hide_if_no_docstring;

        if(editor.somethingSelected()){
            text = editor.getSelection();
        }

        // need a permanent handel to code_mirror for future auto recall
        this.code_mirror = editor;

        // now we treat the different number of keypress
        // first if same cell, same text, increment counter by 1
        if (this._old_cell == cell && this._old_request == text && this._hidden == false) {
            this._consecutive_counter++;
        } else {
            // else reset
            this.cancel_stick();
            this.reset_tabs_function (cell, text);
        }

        // don't do anything if line beggin with '(' or is empty
        if (text === "" || text === "(") {
            return;
        }

        this.tabs_functions[this._consecutive_counter](cell, text);

        // then if we are at the end of list function, reset
        if (this._consecutive_counter == this.tabs_functions.length) this.reset_tabs_function (cell, text);

        return;
    }

    // cancel the option of having the tooltip to stick
    Tooltip.prototype.cancel_stick = function () {
        clearTimeout(this._stick_timeout);
        this._stick_timeout = null;
        this._clocklink.hide('slow');
        this._sticky = false;
    }

    // put the tooltip in a sicky state for 10 seconds
    // it won't be removed by remove_and_cancell() unless you called with
    // the first parameter set to true.
    // remove_and_cancell_tooltip(true)
    Tooltip.prototype.stick = function (time) {
        time = (time != undefined) ? time : 10;
        var that = this;
        this._sticky = true;
        this._clocklink.show('slow');
        this._stick_timeout = setTimeout(function () {
            that._sticky = false;
            that._clocklink.hide('slow');
        }, time * 1000);
    }

    // should be called with the kernel reply to actually show the tooltip
    Tooltip.prototype._show = function (reply) {
        // move the bubble if it is not hidden
        // otherwise fade it
        this.name = reply.name;

        // do some math to have the tooltip arrow on more or less on left or right
        // width of the editor
        var w = $(this.code_mirror.getScrollerElement()).width();
        // ofset of the editor
        var o = $(this.code_mirror.getScrollerElement()).offset();

        // whatever anchor/head order but arrow at mid x selection
        var anchor = this.code_mirror.cursorCoords(false);
        var head  = this.code_mirror.cursorCoords(true);
        var xinit = (head.left+anchor.left)/2;
        var xinter = o.left + (xinit - o.left) / w * (w - 450);
        var posarrowleft = xinit - xinter;

        if (this._hidden == false) {
            this.tooltip.animate({
                'left': xinter - 30 + 'px',
                'top': (head.bottom + 10) + 'px'
            });
        } else {
            this.tooltip.css({
                'left': xinter - 30 + 'px'
            });
            this.tooltip.css({
                'top': (head.bottom + 10) + 'px'
            });
        }
        this.arrow.animate({
            'left': posarrowleft + 'px'
        });

        // build docstring
        var defstring = reply.call_def;
        if (defstring == null) {
            defstring = reply.init_definition;
        }
        if (defstring == null) {
            defstring = reply.definition;
        }

        var docstring = reply.call_docstring;
        if (docstring == null) {
            docstring = reply.init_docstring;
        }
        if (docstring == null) {
            docstring = reply.docstring;
        }

        if (docstring == null) {
            // For reals this time, no docstring
            if (this._hide_if_no_docstring) {
                return;
            } else {
                docstring = "<empty docstring>";
            }
        }

        this.tooltip.fadeIn('fast');
        this._hidden = false;
        this.text.children().remove();

        var pre = $('<pre/>').html(utils.fixConsole(docstring));
        if (defstring) {
            var defstring_html = $('<pre/>').html(utils.fixConsole(defstring));
            this.text.append(defstring_html);
        }
        this.text.append(pre);
        // keep scroll top to be sure to always see the first line
        this.text.scrollTop(0);
    }

    IPython.Tooltip = Tooltip;

    return IPython;

}(IPython));
<commit_msg>add missing cell.session in tooltip.js<commit_after>//----------------------------------------------------------------------------
//  Copyright (C) 2008-2011  The IPython Development Team
//
//  Distributed under the terms of the BSD License.  The full license is in
//  the file COPYING, distributed as part of this software.
//----------------------------------------------------------------------------
//============================================================================
// Tooltip
//============================================================================
//
// you can set the autocall time by setting `IPython.tooltip.time_before_tooltip` in ms
//
// you can configure the differents action of pressing tab several times in a row by
// setting/appending different fonction in the array
// IPython.tooltip.tabs_functions
//
// eg :
// IPython.tooltip.tabs_functions[4] = function (){console.log('this is the action of the 4th tab pressing')}
//
var IPython = (function (IPython) {
    "use strict";

    var utils = IPython.utils;

    // tooltip constructor
    var Tooltip = function () {
            var that = this;
            this.time_before_tooltip = 1200;

            // handle to html
            this.tooltip = $('#tooltip');
            this._hidden = true;

            // variable for consecutive call
            this._old_cell = null;
            this._old_request = null;
            this._consecutive_counter = 0;

            // 'sticky ?'
            this._sticky = false;

            // display tooltip if the docstring is empty?
            this._hide_if_no_docstring = false;

            // contain the button in the upper right corner
            this.buttons = $('<div/>').addClass('tooltipbuttons');

            // will contain the docstring
            this.text = $('<div/>').addClass('tooltiptext').addClass('smalltooltip');

            // build the buttons menu on the upper right
            // expand the tooltip to see more
            var expandlink = $('<a/>').attr('href', "#").addClass("ui-corner-all") //rounded corner
            .attr('role', "button").attr('id', 'expanbutton').attr('title', 'Grow the tooltip vertically (press tab 2 times)').click(function () {
                that.expand()
            }).append(
            $('<span/>').text('Expand').addClass('ui-icon').addClass('ui-icon-plus'));

            // open in pager
            var morelink = $('<a/>').attr('href', "#").attr('role', "button").addClass('ui-button').attr('title', 'show the current docstring in pager (press tab 4 times)');
            var morespan = $('<span/>').text('Open in Pager').addClass('ui-icon').addClass('ui-icon-arrowstop-l-n');
            morelink.append(morespan);
            morelink.click(function () {
                that.showInPager(that._old_cell);
            });

            // close the tooltip
            var closelink = $('<a/>').attr('href', "#").attr('role', "button").addClass('ui-button');
            var closespan = $('<span/>').text('Close').addClass('ui-icon').addClass('ui-icon-close');
            closelink.append(closespan);
            closelink.click(function () {
                that.remove_and_cancel_tooltip(true);
            });

            this._clocklink = $('<a/>').attr('href', "#");
            this._clocklink.attr('role', "button");
            this._clocklink.addClass('ui-button');
            this._clocklink.attr('title', 'Tootip is not dismissed while typing for 10 seconds');
            var clockspan = $('<span/>').text('Close');
            clockspan.addClass('ui-icon');
            clockspan.addClass('ui-icon-clock');
            this._clocklink.append(clockspan);
            this._clocklink.click(function () {
                that.cancel_stick();
            });

            //construct the tooltip
            // add in the reverse order you want them to appear
            this.buttons.append(closelink);
            this.buttons.append(expandlink);
            this.buttons.append(morelink);
            this.buttons.append(this._clocklink);
            this._clocklink.hide();

            // we need a phony element to make the small arrow
            // of the tooltip in css
            // we will move the arrow later
            this.arrow = $('<div/>').addClass('pretooltiparrow');
            this.tooltip.append(this.buttons);
            this.tooltip.append(this.arrow);
            this.tooltip.append(this.text);

            // function that will be called if you press tab 1, 2, 3... times in a row
            this.tabs_functions = [function (cell, text) {
                that._request_tooltip(cell, text);
            }, function () {
                that.expand();
            }, function () {
                that.stick();
            }, function (cell) {
                that.cancel_stick();
                that.showInPager(cell);
            }];
            // call after all the tabs function above have bee call to clean their effects
            // if necessary
            this.reset_tabs_function = function (cell, text) {
                this._old_cell = (cell) ? cell : null;
                this._old_request = (text) ? text : null;
                this._consecutive_counter = 0;
            }
        };

    Tooltip.prototype.showInPager = function (cell) {
        // reexecute last call in pager by appending ? to show back in pager
        var that = this;
        var empty = function () {};
        cell.session.kernel.execute(
        that.name + '?', {
            'execute_reply': empty,
            'output': empty,
            'clear_output': empty,
            'cell': cell
        }, {
            'silent': false,
            'store_history': true
        });
        this.remove_and_cancel_tooltip();
    }

    // grow the tooltip verticaly
    Tooltip.prototype.expand = function () {
        this.text.removeClass('smalltooltip');
        this.text.addClass('bigtooltip');
        $('#expanbutton').hide('slow');
    }

    // deal with all the logic of hiding the tooltip
    // and reset it's status
    Tooltip.prototype._hide = function () {
        this.tooltip.fadeOut('fast');
        $('#expanbutton').show('slow');
        this.text.removeClass('bigtooltip');
        this.text.addClass('smalltooltip');
        // keep scroll top to be sure to always see the first line
        this.text.scrollTop(0);
        this._hidden = true;
        this.code_mirror = null;
    }

    // return true on successfully removing a visible tooltip; otherwise return
    // false.
    Tooltip.prototype.remove_and_cancel_tooltip = function (force) {
        // note that we don't handle closing directly inside the calltip
        // as in the completer, because it is not focusable, so won't
        // get the event.
        this.cancel_pending();
        if (!this._hidden) {
          if (force || !this._sticky) {
              this.cancel_stick();
              this._hide();
          }
          this.reset_tabs_function();
          return true;
        } else {
          return false;
        }
    }

    // cancel autocall done after '(' for example.
    Tooltip.prototype.cancel_pending = function () {
        if (this._tooltip_timeout != null) {
            clearTimeout(this._tooltip_timeout);
            this._tooltip_timeout = null;
        }
    }

    // will trigger tooltip after timeout
    Tooltip.prototype.pending = function (cell, hide_if_no_docstring) {
        var that = this;
        this._tooltip_timeout = setTimeout(function () {
            that.request(cell, hide_if_no_docstring)
        }, that.time_before_tooltip);
    }

    // easy access for julia monkey patching.
    Tooltip.last_token_re = /[a-z_][0-9a-z._]+$/gi;

    Tooltip.prototype.extract_oir_token = function(line){
        // use internally just to make the request to the kernel
        // Feel free to shorten this logic if you are better
        // than me in regEx
        // basicaly you shoul be able to get xxx.xxx.xxx from
        // something(range(10), kwarg=smth) ; xxx.xxx.xxx( firstarg, rand(234,23), kwarg1=2,
        // remove everything between matchin bracket (need to iterate)
        var matchBracket = /\([^\(\)]+\)/g;
        var endBracket = /\([^\(]*$/g;
        var oldline = line;

        line = line.replace(matchBracket, "");
        while (oldline != line) {
            oldline = line;
            line = line.replace(matchBracket, "");
        }
        // remove everything after last open bracket
        line = line.replace(endBracket, "");
        return Tooltip.last_token_re.exec(line)
    }

    Tooltip.prototype._request_tooltip = function (cell, line) {
        var callbacks = {
            'object_info_reply': $.proxy(this._show, this)
        }
        var oir_token = this.extract_oir_token(line);
        var msg_id = cell.session.kernel.object_info_request(oir_token, callbacks);
    }

    // make an imediate completion request
    Tooltip.prototype.request = function (cell, hide_if_no_docstring) {
        // request(codecell)
        // Deal with extracting the text from the cell and counting
        // call in a row
        this.cancel_pending();
        var editor = cell.code_mirror;
        var cursor = editor.getCursor();
        var text = editor.getRange({
            line: cursor.line,
            ch: 0
        }, cursor).trim();

        this._hide_if_no_docstring = hide_if_no_docstring;

        if(editor.somethingSelected()){
            text = editor.getSelection();
        }

        // need a permanent handel to code_mirror for future auto recall
        this.code_mirror = editor;

        // now we treat the different number of keypress
        // first if same cell, same text, increment counter by 1
        if (this._old_cell == cell && this._old_request == text && this._hidden == false) {
            this._consecutive_counter++;
        } else {
            // else reset
            this.cancel_stick();
            this.reset_tabs_function (cell, text);
        }

        // don't do anything if line beggin with '(' or is empty
        if (text === "" || text === "(") {
            return;
        }

        this.tabs_functions[this._consecutive_counter](cell, text);

        // then if we are at the end of list function, reset
        if (this._consecutive_counter == this.tabs_functions.length) this.reset_tabs_function (cell, text);

        return;
    }

    // cancel the option of having the tooltip to stick
    Tooltip.prototype.cancel_stick = function () {
        clearTimeout(this._stick_timeout);
        this._stick_timeout = null;
        this._clocklink.hide('slow');
        this._sticky = false;
    }

    // put the tooltip in a sicky state for 10 seconds
    // it won't be removed by remove_and_cancell() unless you called with
    // the first parameter set to true.
    // remove_and_cancell_tooltip(true)
    Tooltip.prototype.stick = function (time) {
        time = (time != undefined) ? time : 10;
        var that = this;
        this._sticky = true;
        this._clocklink.show('slow');
        this._stick_timeout = setTimeout(function () {
            that._sticky = false;
            that._clocklink.hide('slow');
        }, time * 1000);
    }

    // should be called with the kernel reply to actually show the tooltip
    Tooltip.prototype._show = function (reply) {
        // move the bubble if it is not hidden
        // otherwise fade it
        this.name = reply.name;

        // do some math to have the tooltip arrow on more or less on left or right
        // width of the editor
        var w = $(this.code_mirror.getScrollerElement()).width();
        // ofset of the editor
        var o = $(this.code_mirror.getScrollerElement()).offset();

        // whatever anchor/head order but arrow at mid x selection
        var anchor = this.code_mirror.cursorCoords(false);
        var head  = this.code_mirror.cursorCoords(true);
        var xinit = (head.left+anchor.left)/2;
        var xinter = o.left + (xinit - o.left) / w * (w - 450);
        var posarrowleft = xinit - xinter;

        if (this._hidden == false) {
            this.tooltip.animate({
                'left': xinter - 30 + 'px',
                'top': (head.bottom + 10) + 'px'
            });
        } else {
            this.tooltip.css({
                'left': xinter - 30 + 'px'
            });
            this.tooltip.css({
                'top': (head.bottom + 10) + 'px'
            });
        }
        this.arrow.animate({
            'left': posarrowleft + 'px'
        });

        // build docstring
        var defstring = reply.call_def;
        if (defstring == null) {
            defstring = reply.init_definition;
        }
        if (defstring == null) {
            defstring = reply.definition;
        }

        var docstring = reply.call_docstring;
        if (docstring == null) {
            docstring = reply.init_docstring;
        }
        if (docstring == null) {
            docstring = reply.docstring;
        }

        if (docstring == null) {
            // For reals this time, no docstring
            if (this._hide_if_no_docstring) {
                return;
            } else {
                docstring = "<empty docstring>";
            }
        }

        this.tooltip.fadeIn('fast');
        this._hidden = false;
        this.text.children().remove();

        var pre = $('<pre/>').html(utils.fixConsole(docstring));
        if (defstring) {
            var defstring_html = $('<pre/>').html(utils.fixConsole(defstring));
            this.text.append(defstring_html);
        }
        this.text.append(pre);
        // keep scroll top to be sure to always see the first line
        this.text.scrollTop(0);
    }

    IPython.Tooltip = Tooltip;

    return IPython;

}(IPython));
<|endoftext|>


<commit_before>//===============================================================
//==========================  UI ================================
//===============================================================

//===============================================================
//========================= UTILITY =============================
//===============================================================

function toggle_active_menu(element){
  $(".active").toggleClass('active');
  $(element).toggleClass('active');
}

function load_partial(page, container_id, on_complete) {
  $.get(page, function (data){
    $(container_id).html(data).ready(on_complete());
  });
}

function increment_inpunt_value (){
  $(".tagsinput-add").on("click", function(event) {
    var button = $(this);
    var input = button.parent().find('input');
    var old_value = input.val();

    if (old_value == "") {
      old_value = 0;
    };
    //Incremento il valore e salvo
    input.val(++old_value);
  });
}

function decrement_input_value (){
  $(".tagsinput-remove").on("click", function(event) {
    var button = $(this);
    var input = button.parent().find('input');
    var old_value = input.val();

    if (old_value == "") {
      old_value = 0;
    };
    if (--old_value >= 0) {
      //Incremento il valore e salvo
      input.val(old_value);
    };
  });
}

//===============================================================
//======================= NEW SESSION ===========================
//===============================================================
$('#new-session').click(function () {
  new_session();
});

$("#welcome-avanti").click(function() {
  new_session();
});

function new_session (){
  $("#welcome").hide();
  $(".categoria").show();
  $("#logo").addClass('logo-deactive');
  $("#new-session").addClass('new-session-active');
  load_form_famiglia();
  edit_mode = true;
}

//===============================================================
//====================== form FAMIGLIA ==========================
//===============================================================

$("#menu-famiglia-button").click(function() {
  load_form_famiglia();
});

function load_form_famiglia() {
  toggle_active_menu("#menu-famiglia-button");
  load_partial("partials/famiglia.html", "#form-container", function(){
    form_famiglia();
  });
}

function form_famiglia(){
  //Collego i bottoni +,-
  increment_inpunt_value();
  decrement_input_value();

  //Carico i dati dell'utente se sono in edit mode
  if (edit_mode) {
    load_famiglia_data();
  };

  $("#famiglia-avanti").click(function() {
    var data = {};
    $.each($('#famiglia-caller').serializeArray(), function (i, el){
      data[el.name] = el.value;
    });
    user_new_data.famiglia = data;
    //Carica il prossimo from
    load_form_abitazione();
  });
}

function load_famiglia_data() {
  var famiglia = user_new_data.famiglia;
  //Controllo che i dati siano effettivamente presenti
  if (!$.isEmptyObject(famiglia)) {
    //Se non ho dati vuol dire che sono in fase di aggiunta
    $("input[name=adulti]").val(famiglia.adulti);
    $("input[name=bambini]").val(famiglia.bambini);
  };
}

//===============================================================
//====================== form ABITAZIONE ========================
//===============================================================
var comune = "";
var zona = "";
var categoria = "";
var costo_min = 0;
var costo_max = 0;
var costo = 0;

$("#menu-abitazione-button").click(function() {
  load_form_abitazione("#menu-abitazione-button");
});

function load_form_abitazione (){
  toggle_active_menu("#menu-abitazione-button");
  load_partial("partials/abitazione.html", "#form-container", function (){
    form_abitazione();
  });
}

function form_abitazione (){
  // selettori belli bellissimi
  $("select").selectpicker({style: 'btn-hg btn-primary', menuStyle: 'dropdown-inverse'});
  $('.switch')['bootstrapSwitch']();

  if (edit_mode) {
    load_abitazione_data();
  };

  //Imposto evento per il cabio di valore nel capo input
  $("input[name=grandezza]").change(function() {
    //Controllo che il valore passato sia un numero
    if (!isNaN($("input[name=grandezza]").val())) {
      set_input_costi();
    };
  });

  //Carico i dati del dropdown dei comuni
  get_comuni(function (data){
    //Chiamata alla api asincrona
    $.each(data, function(i, el) {
      $("select[name=comune]").append("<option>"+el+"</option>");
    });
  });

  //Aggiungo ascoltatore per quando l'utente seleziona un valore
  // per il capo comune
  $("select[name=comune]").change(function (){
    comune = $("select[name=comune]").val();
    // prendo il valore dei costi medi di tutte le zone
    get_zone(comune, function (data){
      $.each(data, function(i, el) {
        $("select[name=zona_abitativa]").append("<option value="+el.code+">"+el.zona+"</option>");
      });
    });
    //Carico i costi di quel comune
    get_costi_med_comuni($("select[name=comune]").val(), function (data){
      //Aggiorno i valori nelle varabili globali poi aggiorno i campi
      update_values_costi(data);
      set_input_costi();
    });
    //Re-imposto il valore di default per i from sottostanti
    $("select[name=zona_abitativa]").prop('selectedIndex',0);
    $("select[name=categoria_edilizia]").prop('selectedIndex',0);
  });

  //Dopo aver caricato le zone carico le categorie edilizie ed aggiorno
  $("select[name=zona_abitativa]").change(function (){
    zona = $("select[name=zona_abitativa]").val();
    get_categoria_edilizia(comune, zona, function (data) {
        $.each(data, function(i, el) {
          $("select[name=categoria_edilizia]").append("<option value="+el.code+">"+el.tipologia+"</option>")
        });
    });
    //Reset dei capi sottostanti
    $("select[name=categoria_edilizia]").prop('selectedIndex',0);
  });

  //Ecento al cambiamento della categoria edilizia
  $("select[name=categoria_edilizia]").change(function() {
    categoria = $("select[name=categoria_edilizia]").val();
    //Aggiorno i costi con i nuovi dati
    get_costi_totali(comune, zona, categoria, function (data){
      update_values_costi(data);
      set_input_costi();
    });
  });

  //Bottone avanti, salvo i dati inseriti dall'utente
  $("#abitazione-avanti").click(function() {
    var data = {};
    $.each($('#abitazione-caller').serializeArray(), function (i, el){
      data[el.name] = el.value;
    });
    user_new_data.abitazione = data;
    //Carica il prossimo from
    load_form_trasporti();
  });
}

function update_values_costi (data){
  costo_min = data.cost_min;
  costo_max = data.cost_max;
  costo = data.cost_med;
}

function set_input_costi (){
  var grandezza = $("input[name=grandezza]").val();
  //Imposto i valori moltiplicando per la grandezza
  $("input[name=costo_min]").val((grandezza*costo_min).toFixed(2));
  $("input[name=costo_max]").val((grandezza*costo_max).toFixed(2));
  $("input[name=costo]").val((grandezza*costo).toFixed(2));
}

function load_abitazione_data(){
  var abitazione;
  if(!$.isEmptyObject(user_new_data.abitazione)){
    abitazione = user_new_data.abitazione;
    //Carico i dati utente, se vi è contenuta l'indicazione del comune
    //Carico il form completo altrimenti carico quello parziale
    if (!$.isEmptyObject(abitazione.comune)) {
      //Carico tutti i dati e genero il form completo
    }else{
      //Carico solo il costo inserito dall'utente
    };
  };
}

//===============================================================
//======================= form TRASPORTI ========================
//===============================================================
$("#menu-trasporti-button").click(function() {
  load_form_trasporti();
});

function load_form_trasporti(){
  toggle_active_menu("#menu-trasporti-button");
  load_partial("partials/trasporti.html", "#form-container", function(){
    from_trasporti();
  });
}

function from_trasporti(){

}

//===============================================================
//===================== form SPOSTAMENTI ========================
//===============================================================
$("#menu-spostamenti-button").click(function (){
  load_form_spostamenti();
});

function load_form_spostamenti (){
  toggle_active_menu("#menu-spostamenti-button");
  load_partial("partials/spostamenti.html", "#form-container", function(){
    form_spostamenti();
  });
}

function form_spostamenti (){

}

<commit_msg>Aggiunto caricamento dati dopo aver salvato<commit_after>//===============================================================
//==========================  UI ================================
//===============================================================

//===============================================================
//========================= UTILITY =============================
//===============================================================

function toggle_active_menu(element){
  $(".active").toggleClass('active');
  $(element).toggleClass('active');
}

function load_partial(page, container_id, on_complete) {
  $.get(page, function (data){
    $(container_id).html(data).ready(on_complete());
  });
}

function increment_inpunt_value (){
  $(".tagsinput-add").on("click", function(event) {
    var button = $(this);
    var input = button.parent().find('input');
    var old_value = input.val();

    if (old_value == "") {
      old_value = 0;
    };
    //Incremento il valore e salvo
    input.val(++old_value);
  });
}

function decrement_input_value (){
  $(".tagsinput-remove").on("click", function(event) {
    var button = $(this);
    var input = button.parent().find('input');
    var old_value = input.val();

    if (old_value == "") {
      old_value = 0;
    };
    if (--old_value >= 0) {
      //Incremento il valore e salvo
      input.val(old_value);
    };
  });
}

//===============================================================
//======================= NEW SESSION ===========================
//===============================================================
$('#new-session').click(function () {
  new_session();
});

$("#welcome-avanti").click(function() {
  new_session();
});

function new_session (){
  $("#welcome").hide();
  $(".categoria").show();
  $("#logo").addClass('logo-deactive');
  $("#new-session").addClass('new-session-active');
  load_form_famiglia();
  edit_mode = true;
}

//===============================================================
//====================== form FAMIGLIA ==========================
//===============================================================

$("#menu-famiglia-button").click(function() {
  load_form_famiglia();
});

function load_form_famiglia() {
  toggle_active_menu("#menu-famiglia-button");
  load_partial("partials/famiglia.html", "#form-container", function(){
    form_famiglia();
  });
}

function form_famiglia(){
  //Collego i bottoni +,-
  increment_inpunt_value();
  decrement_input_value();

  //Carico i dati dell'utente se sono in edit mode
  if (edit_mode) {
    load_famiglia_data();
  };

  $("#famiglia-avanti").click(function() {
    var data = {};
    $.each($('#famiglia-caller').serializeArray(), function (i, el){
      data[el.name] = el.value;
    });
    user_new_data.famiglia = data;
    //Carica il prossimo from
    load_form_abitazione();
  });
}

function load_famiglia_data() {
  var famiglia = user_new_data.famiglia;
  //Controllo che i dati siano effettivamente presenti
  if (!$.isEmptyObject(famiglia)) {
    //Se non ho dati vuol dire che sono in fase di aggiunta
    $("input[name=adulti]").val(famiglia.adulti);
    $("input[name=bambini]").val(famiglia.bambini);
  };
}

//===============================================================
//====================== form ABITAZIONE ========================
//===============================================================
var comune = "";
var zona = "";
var categoria = "";
var costo_min = 0;
var costo_max = 0;
var costo = 0;

$("#menu-abitazione-button").click(function() {
  load_form_abitazione("#menu-abitazione-button");
});

function load_form_abitazione (){
  toggle_active_menu("#menu-abitazione-button");
  load_partial("partials/abitazione.html", "#form-container", function (){
    form_abitazione();
  });
}

function form_abitazione (){
  // selettori belli bellissimi
  $("select").selectpicker({style: 'btn-hg btn-primary', menuStyle: 'dropdown-inverse'});
  $('.switch')['bootstrapSwitch']();

  if (edit_mode) {
    load_abitazione_data();
  };

  //Imposto evento per il cabio di valore nel capo input
  $("input[name=grandezza]").change(function() {
    //Controllo che il valore passato sia un numero
    if (!isNaN($("input[name=grandezza]").val())) {
      set_input_costi();
    };
  });

  //Carico i dati del dropdown dei comuni
  get_comuni(function (data){
    //Chiamata alla api asincrona
    $.each(data, function(i, el) {
      $("select[name=comune]").append("<option>"+el+"</option>");
    });
  });

  //Aggiungo ascoltatore per quando l'utente seleziona un valore
  // per il capo comune
  $("select[name=comune]").change(function (){
    comune = $("select[name=comune]").val();
    // prendo il valore dei costi medi di tutte le zone
    get_zone(comune, function (data){
      $.each(data, function(i, el) {
        $("select[name=zona_abitativa]").append("<option value="+el.code+">"+el.zona+"</option>");
      });
    });
    //Carico i costi di quel comune
    get_costi_med_comuni($("select[name=comune]").val(), function (data){
      //Aggiorno i valori nelle varabili globali poi aggiorno i campi
      update_values_costi(data);
    });
    //Re-imposto il valore di default per i from sottostanti
    $("select[name=zona_abitativa]").prop('selectedIndex',0);
    $("select[name=categoria_edilizia]").prop('selectedIndex',0);
  });

  //Dopo aver caricato le zone carico le categorie edilizie ed aggiorno
  $("select[name=zona_abitativa]").change(function (){
    zona = $("select[name=zona_abitativa]").val();
    get_categoria_edilizia(comune, zona, function (data) {
        $.each(data, function(i, el) {
          $("select[name=categoria_edilizia]").append("<option value="+el.code+">"+el.tipologia+"</option>");
        });
    });
    //Reset dei capi sottostanti
    $("select[name=categoria_edilizia]").prop('selectedIndex',0);
  });

  //Ecento al cambiamento della categoria edilizia
  $("select[name=categoria_edilizia]").change(function() {
    categoria = $("select[name=categoria_edilizia]").val();
    //Aggiorno i costi con i nuovi dati
    get_costi_totali(comune, zona, categoria, function (data){
      update_values_costi(data);
    });
  });

  //Bottone avanti, salvo i dati inseriti dall'utente
  $("#abitazione-avanti").click(function() {
    var data = {};
    $.each($('#abitazione-caller').serializeArray(), function (i, el){
      data[el.name] = el.value;
    });
    user_new_data.abitazione = data;
    //Carica il prossimo from
    load_form_trasporti();
  });
}

function update_values_costi (data){
  costo_min = data.cost_min;
  costo_max = data.cost_max;
  costo = data.cost_med;
  set_input_costi();
}

function set_input_costi (){
  var grandezza = $("input[name=grandezza]").val();
  //Imposto i valori moltiplicando per la grandezza
  $("input[name=costo_min]").val((grandezza*costo_min).toFixed(2));
  $("input[name=costo_max]").val((grandezza*costo_max).toFixed(2));
  $("input[name=costo]").val((grandezza*costo).toFixed(2));
}

function load_abitazione_data(){
  var abitazione;
  if(!$.isEmptyObject(user_new_data.abitazione)){
    abitazione = user_new_data.abitazione;
    //Carico i dati utente, se vi è contenuta l'indicazione del comune
    //Carico il form completo altrimenti carico quello parziale
    if (!$.isEmptyObject(abitazione.comune)) {
      //Carico tutti i dati e genero il form completo
      comune = abitazione.comune;
      zona = abitazione.zona_abitativa;
      categoria = abitazione.categoria_edilizia;
      //Imposto la grandezza
      $("input[name=grandezza]").val(abitazione.grandezza);
      //Ricarico i dati presi dal server
      //Comune
      get_comuni(function (data){
      $.each(data, function(i, el) {
          $("select[name=comune]").append("<option>"+el+"</option>");
          $("select[name=comune]").val(comune);
        });
      });
      //Zona
      get_zone(comune, function (data){
        $.each(data, function(i, el) {
          $("select[name=zona_abitativa]").append("<option value="+el.code+">"+el.zona+"</option>");
        });
        $("select[name=zona_abitativa]").val(zona);
      });
      //Categoria edilizia
      get_categoria_edilizia(comune, zona, function (data) {
        $.each(data, function(i, el) {
          $("select[name=categoria_edilizia]").append("<option value="+el.code+">"+el.tipologia+"</option>");
        });
        $("select[name=categoria_edilizia]").val(categoria);
      });
      //Imposto i valori nei capi di testo
      console.log(abitazione);
      set_input_costi();
    }else{
      //Carico solo il costo inserito dall'utente
    };
  };
}

//===============================================================
//======================= form TRASPORTI ========================
//===============================================================
$("#menu-trasporti-button").click(function() {
  load_form_trasporti();
});

function load_form_trasporti(){
  toggle_active_menu("#menu-trasporti-button");
  load_partial("partials/trasporti.html", "#form-container", function(){
    from_trasporti();
  });
}

function from_trasporti(){

}

//===============================================================
//===================== form SPOSTAMENTI ========================
//===============================================================
$("#menu-spostamenti-button").click(function (){
  load_form_spostamenti();
});

function load_form_spostamenti (){
  toggle_active_menu("#menu-spostamenti-button");
  load_partial("partials/spostamenti.html", "#form-container", function(){
    form_spostamenti();
  });
}

function form_spostamenti (){

}

<|endoftext|>


<commit_before>export { Base } from "./Operation/Operation_Base.js";
export { Root } from "./Operation/Operation_Base.js";
export { RootPool } from "./Operation/Operation_Base.js";

export { TwinArray } from "./Operation/Operation_TwinArray.js";
export { TwinArrayPool } from "./Operation/Operation_TwinArray.js";

export { AddTwoTensors } from "./Operation/Operation_AddTwoTensors.js";
export { MultiplyTwoTensors } from "./Operation/Operation_MultiplyTwoTensors.js";
export { ConcatShuffleSplit } from "./Operation/Operation_ConcatShuffleSplit.js";
export { ConcatAlongAxisId2 } from "./Operation/Operation_ConcatAlongAxisId2.js";

export { Depthwise } from "./Operation/Operation_Depthwise.js";
export { Depthwise_SameWhenPassThrough } from "./Operation/Operation_Depthwise_SameWhenPassThrough.js";
export { Depthwise_ConstantWhenPassThrough } from "./Operation/Operation_Depthwise_ConstantWhenPassThrough.js";

export { Pointwise } from "./Operation/Operation_Pointwise.js";
export { Pointwise_SameWhenPassThrough } from "./Operation/Operation_Pointwise_SameWhenPassThrough.js";

//!!! (2022/06/07 Remarked) seems no longer needed.
// export { Pointwise_SameWhenPassThrough_PrefixSqueezeExcitation }
//   from "./Operation/Operation_Pointwise_SameWhenPassThrough_PrefixSqueezeExcitation.js";

export { Pointwise_ConstantWhenPassThrough } from "./Operation/Operation_Pointwise_ConstantWhenPassThrough.js";

//!!! (2022/06/07 Remarked) seems part of Block.Base.
//export { SqueezeExcitation } from "./Operation/Operation_SqueezeExcitation.js";

<commit_msg>Update Operation.js<commit_after>export { Base } from "./Operation/Operation_Base.js";
export { Root } from "./Operation/Operation_Base.js";
export { RootPool } from "./Operation/Operation_Base.js";

export { TwinArray } from "./Operation/Operation_TwinArray.js";
export { TwinArrayPool } from "./Operation/Operation_TwinArray.js";

export { AddTwoTensors } from "./Operation/Operation_AddTwoTensors.js";
export { AddTwoTensorsPool } from "./Operation/Operation_AddTwoTensors.js";

export { MultiplyTwoTensors } from "./Operation/Operation_MultiplyTwoTensors.js";
export { MultiplyTwoTensorsPool } from "./Operation/Operation_MultiplyTwoTensors.js";

export { ConcatShuffleSplit } from "./Operation/Operation_ConcatShuffleSplit.js";
export { ConcatShuffleSplitPool } from "./Operation/Operation_ConcatShuffleSplit.js";

export { ConcatAlongAxisId2 } from "./Operation/Operation_ConcatAlongAxisId2.js";
export { ConcatAlongAxisId2Pool } from "./Operation/Operation_ConcatAlongAxisId2.js";

export { Depthwise } from "./Operation/Operation_Depthwise.js";
export { DepthwisePool } from "./Operation/Operation_Depthwise.js";
export { Depthwise_SameWhenPassThrough } from "./Operation/Operation_Depthwise_SameWhenPassThrough.js";
export { Depthwise_SameWhenPassThroughPool } from "./Operation/Operation_Depthwise_SameWhenPassThrough.js";
export { Depthwise_ConstantWhenPassThrough } from "./Operation/Operation_Depthwise_ConstantWhenPassThrough.js";
export { Depthwise_ConstantWhenPassThroughPool } from "./Operation/Operation_Depthwise_ConstantWhenPassThrough.js";

export { Pointwise } from "./Operation/Operation_Pointwise.js";
export { PointwisePool } from "./Operation/Operation_Pointwise.js";
export { Pointwise_SameWhenPassThrough } from "./Operation/Operation_Pointwise_SameWhenPassThrough.js";
export { Pointwise_SameWhenPassThroughPool } from "./Operation/Operation_Pointwise_SameWhenPassThrough.js";
export { Pointwise_ConstantWhenPassThrough } from "./Operation/Operation_Pointwise_ConstantWhenPassThrough.js";
export { Pointwise_ConstantWhenPassThroughPool } from "./Operation/Operation_Pointwise_ConstantWhenPassThrough.js";

<|endoftext|>


<commit_before>var FObject = require('../fobject');

/**
 * Base class for asset handling.
 *
 * You should override:
 * - validateAsset (static)
 *
 * You may want to override:
 * - createNode
 * - Fire.FObject._serialize
 * - Fire.FObject._deserialize
 *
 * @class Asset
 * @extends Object
 * @constructor
 */
module.exports = Fire.Class({
    name: 'Fire.Asset', extends: FObject,

    constructor: function () {
        /**
         * @property _uuid
         * @type {string}
         * @private
         */
        Object.defineProperty(this, '_uuid', {
            value: '',
            writable: true,
            enumerable: false   // avoid uuid being assigned to empty string during destroy,
        });

        ///**
        // * @property dirty
        // * @type boolean
        // * @private
        // */
        //this.dirty = false;
    },

    properties: {
        /**
         * Returns the url of this asset's first raw file, if none of rawFile exists,
         * it will returns the url of this serialized asset.
         * @property url
         * @type {string}
         * @readOnly
         */
        url: {
            get: function () {
                if (this._rawFiles) {
                    if (Fire.AssetLibrary) {
                        var url = Fire.AssetLibrary.getUrl(this._uuid);
                        var ext = this._rawFiles[0];
                        return ext ? url + '.' + ext : url;
                    }
                    else {
                        Fire.error('asset.url is not usable in core process');
                    }
                }
                return '';
            },
            visible: false
        },

        /**
         * Returns the url of this asset's raw files, if none of rawFile exists,
         * it will returns an empty array.
         * @property urls
         * @type {string[]}
         * @readOnly
         */
        urls: {
            get: function () {
                if (this._rawFiles) {
                    if (Fire.AssetLibrary) {
                        var url = Fire.AssetLibrary.getUrl(this._uuid);
                        return this._rawFiles.map(function (ext) {
                            return ext ? url + '.' + ext : url;
                        });
                    }
                    else {
                        Fire.error('asset.urls is not usable in core process');
                    }
                }
                return [];
            },
            visible: false
        },

        /**
         * 在 lite 版的 Fireball 里，raw asset 并不仅仅是在 properties 里声明了 rawType 才有，
         * 而是每个 asset 都能指定自己的 raw file url。但 AssetLibrary 并不会帮你加载这个 url，除非你声明了 rawType。
         * @property _rawFiles
         * @type {string[]}
         * @default null
         * @private
         */
        _rawFiles: null
    },

    statics: {
        /**
         * Checks if this type asset can be created from given asset file. (Without actually creating the asset).
         * @method validateAsset
         * @param {string} fsPath - file system path of the asset file in asset database
         * @return {boolean}
         */
        validateAsset: function (fsPath) {
            return true;
        },

        /**
         * 这个方法给 AssetDB 专用，或许能让 AssetDB 不耦合 Editor.serialize()。
         * @method serialize
         * @return {string}
         * @private
         */
        serialize: function () {
            return Editor.serialize(this);
        },

        /**
         * 这个方法给 AssetDB 专用，或许能让 AssetDB 不耦合 Fire.deserialize()。
         * @method deserialize
         * @param {string} data
         * @return {Asset}
         * @private
         */
        deserialize: function (data) {
            return Fire.deserialize(data);
        },

        urlToUuid: function (url) {
            if (Fire.AssetLibrary) {
                var uuid = Fire.AssetLibrary.getUuid(url);
                return uuid;
            }
            else {
                Fire.error('Asset.urlToUuid is not usable in core process');
            }
            return '';
        }
    },

    /**
     * Create a new node using this asset in the scene.
     * If this type of asset dont have corresponding type of node, this method should be null.
     * @createNode createNode
     * @param {function} callback
     * @param {string} callback.error - null or the error info
     * @param {object} callback.node - the created node or null
     */
    createNode: null,

    /**
     * Set raw extname for this asset.
     * @method _setRawFiles
     * @param {string[]} rawFiles
     * @private
     */
    _setRawFiles: function (rawFiles) {
        rawFiles = rawFiles.map(function (item) {
            if (item.charAt(0) === '.') {
                item = item.slice(1);
            }
            return item;
        });
        this._rawFiles = rawFiles;
    }
});

<commit_msg>minor tweak<commit_after>var FObject = require('../fobject');

/**
 * Base class for asset handling.
 *
 * You should override:
 * - validateAsset (static)
 *
 * You may want to override:
 * - createNode
 * - Fire.FObject._serialize
 * - Fire.FObject._deserialize
 *
 * @class Asset
 * @extends Object
 * @constructor
 */
module.exports = Fire.Class({
    name: 'Fire.Asset', extends: FObject,

    constructor: function () {
        /**
         * @property _uuid
         * @type {string}
         * @private
         */
        Object.defineProperty(this, '_uuid', {
            value: '',
            writable: true,
            enumerable: false   // avoid uuid being assigned to empty string during destroy,
        });

        ///**
        // * @property dirty
        // * @type boolean
        // * @private
        // */
        //this.dirty = false;
    },

    properties: {
        /**
         * Returns the url of this asset's first raw file, if none of rawFile exists,
         * it will returns the url of this serialized asset.
         * @property url
         * @type {string}
         * @readOnly
         */
        url: {
            get: function () {
                if (this._rawFiles) {
                    if (Fire.AssetLibrary) {
                        var url = Fire.AssetLibrary.getUrl(this._uuid);
                        var ext = this._rawFiles[0];
                        return ext ? url + '.' + ext : url;
                    }
                    else {
                        Fire.error('asset.url is not usable in core process');
                    }
                }
                return '';
            },
            visible: false
        },

        /**
         * Returns the url of this asset's raw files, if none of rawFile exists,
         * it will returns an empty array.
         * @property urls
         * @type {string[]}
         * @readOnly
         */
        urls: {
            get: function () {
                if (this._rawFiles) {
                    if (Fire.AssetLibrary) {
                        var url = Fire.AssetLibrary.getUrl(this._uuid);
                        return this._rawFiles.map(function (ext) {
                            return ext ? url + '.' + ext : url;
                        });
                    }
                    else {
                        Fire.error('asset.urls is not usable in core process');
                    }
                }
                return [];
            },
            visible: false
        },

        /**
         * 在 lite 版的 Fireball 里，raw asset 并不仅仅是在 properties 里声明了 rawType 才有，
         * 而是每个 asset 都能指定自己的 raw file url。但 AssetLibrary 并不会帮你加载这个 url，除非你声明了 rawType。
         * @property _rawFiles
         * @type {string[]}
         * @default null
         * @private
         */
        _rawFiles: null
    },

    statics: {
        /**
         * Checks if this type asset can be created from given asset file. (Without actually creating the asset).
         * @method validateAsset
         * @param {string} fsPath - file system path of the asset file in asset database
         * @return {boolean}
         */
        validateAsset: function (fsPath) {
            return true;
        },

        /**
         * 这个方法给 AssetDB 专用，或许能让 AssetDB 不耦合 Fire.deserialize()。
         * @method deserialize
         * @param {string} data
         * @return {Asset}
         * @static
         * @private
         */
        deserialize: function (data) {
            return Fire.deserialize(data);
        },

        urlToUuid: function (url) {
            if (Fire.AssetLibrary) {
                var uuid = Fire.AssetLibrary.getUuid(url);
                return uuid;
            }
            else {
                Fire.error('Asset.urlToUuid is not usable in core process');
            }
            return '';
        }
    },

    /**
     * 这个方法为了让 AssetDB 不耦合 Editor.serialize()。
     * @method serialize
     * @return {string}
     * @private
     */
    serialize: function () {
        return Editor.serialize(this);
    },

    /**
     * Create a new node using this asset in the scene.
     * If this type of asset dont have corresponding type of node, this method should be null.
     * @createNode createNode
     * @param {function} callback
     * @param {string} callback.error - null or the error info
     * @param {object} callback.node - the created node or null
     */
    createNode: null,

    /**
     * Set raw extname for this asset.
     * @method _setRawFiles
     * @param {string[]} rawFiles
     * @private
     */
    _setRawFiles: function (rawFiles) {
        rawFiles = rawFiles.map(function (item) {
            if (item.charAt(0) === '.') {
                item = item.slice(1);
            }
            return item;
        });
        this._rawFiles = rawFiles.length > 0 ? rawFiles : null;
    }
});

<|endoftext|>


<commit_before>import 'babel-polyfill';
import React from 'react';

import config from 'config';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { Router, browserHistory } from 'react-router';
import { ReduxAsyncConnect } from 'redux-async-connect';
import { langToLocale, getLanguage } from 'core/i18n/utils';
import I18nProvider from 'core/i18n/Provider';
import Jed from 'jed';

import log from 'core/logger';

export default function makeClient(routes, createStore) {
  const initialStateContainer = document.getElementById('redux-store-state');
  let initialState;

  const html = document.querySelector('html');
  const lang = getLanguage(html.getAttribute('lang'));
  const locale = langToLocale(lang);
  const appName = config.get('appName');
  function renderApp(jedData) {
    const i18n = new Jed(jedData);

    if (initialStateContainer) {
      try {
        initialState = JSON.parse(initialStateContainer.textContent);
      } catch (error) {
        log.error('Could not load initial redux data');
      }
    }
    const store = createStore(initialState);

    function reduxAsyncConnectRender(props) {
      return <ReduxAsyncConnect {...props} />;
    }

    render(
      <I18nProvider i18n={i18n}>
        <Provider store={store} key="provider">
          <Router render={reduxAsyncConnectRender} children={routes} history={browserHistory} />
        </Provider>
      </I18nProvider>,
      document.getElementById('react-view')
    );
  }

  try {
    if (locale !== langToLocale(config.get('defaultLang'))) {
      // eslint-disable-next-line global-require, max-len
      require(`bundle?name=[name]-i18n-[folder]!json!../../locale/${locale}/${appName}.json`)(renderApp);
    }
  } catch (e) {
    log.info(dedent`Locale not found or required for locale: "${locale}".
      Falling back to default lang: "${config.get('defaultLang')}"`);
    renderApp({});
  }
}
<commit_msg>Always run renderApp if locale matches default<commit_after>import 'babel-polyfill';
import React from 'react';

import config from 'config';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { Router, browserHistory } from 'react-router';
import { ReduxAsyncConnect } from 'redux-async-connect';
import { langToLocale, getLanguage } from 'core/i18n/utils';
import I18nProvider from 'core/i18n/Provider';
import Jed from 'jed';

import log from 'core/logger';

export default function makeClient(routes, createStore) {
  const initialStateContainer = document.getElementById('redux-store-state');
  let initialState;

  const html = document.querySelector('html');
  const lang = getLanguage(html.getAttribute('lang'));
  const locale = langToLocale(lang);
  const appName = config.get('appName');

  function renderApp(jedData) {
    const i18n = new Jed(jedData);

    if (initialStateContainer) {
      try {
        initialState = JSON.parse(initialStateContainer.textContent);
      } catch (error) {
        log.error('Could not load initial redux data');
      }
    }
    const store = createStore(initialState);

    function reduxAsyncConnectRender(props) {
      return <ReduxAsyncConnect {...props} />;
    }

    render(
      <I18nProvider i18n={i18n}>
        <Provider store={store} key="provider">
          <Router render={reduxAsyncConnectRender} children={routes} history={browserHistory} />
        </Provider>
      </I18nProvider>,
      document.getElementById('react-view')
    );
  }

  try {
    if (locale !== langToLocale(config.get('defaultLang'))) {
      // eslint-disable-next-line max-len, global-require
      require(`bundle?name=[name]-i18n-[folder]!json!../../locale/${locale}/${appName}.json`)(renderApp);
    } else {
      renderApp({});
    }
  } catch (e) {
    log.info(dedent`Locale not found or required for locale: "${locale}".
      Falling back to default lang: "${config.get('defaultLang')}"`);
    renderApp({});
  }
}
<|endoftext|>