Bug 1033841: Ported Loop panel views to React. r=Standard8
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* jshint esnext:true */
|
||||
/* global loop:true, hawk, deriveHawkCredentials */
|
||||
|
||||
var loop = loop || {};
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* jshint esnext:true */
|
||||
/* global loop:true */
|
||||
|
||||
var loop = loop || {};
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* jshint esnext:true */
|
||||
/* global loop:true */
|
||||
|
||||
var loop = loop || {};
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
/** @jsx React.DOM */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* global loop:true */
|
||||
/*jshint newcap:false*/
|
||||
/*global loop:true, React */
|
||||
|
||||
var loop = loop || {};
|
||||
loop.panel = (function(_, mozL10n) {
|
||||
@@ -21,162 +24,188 @@ loop.panel = (function(_, mozL10n) {
|
||||
/**
|
||||
* Do not disturb panel subview.
|
||||
*/
|
||||
var DoNotDisturbView = sharedViews.BaseView.extend({
|
||||
template: _.template([
|
||||
'<label>',
|
||||
' <input type="checkbox" <%- checked %>>',
|
||||
' <span data-l10n-id="do_not_disturb"></span>',
|
||||
'</label>',
|
||||
].join('')),
|
||||
|
||||
events: {
|
||||
"click input[type=checkbox]": "toggle"
|
||||
var DoNotDisturb = React.createClass({displayName: 'DoNotDisturb',
|
||||
getInitialState: function() {
|
||||
return {doNotDisturb: navigator.mozLoop.doNotDisturb};
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggles mozLoop activation status.
|
||||
*/
|
||||
toggle: function() {
|
||||
handleCheckboxChange: function() {
|
||||
// Note: side effect!
|
||||
navigator.mozLoop.doNotDisturb = !navigator.mozLoop.doNotDisturb;
|
||||
this.render();
|
||||
this.setState({doNotDisturb: navigator.mozLoop.doNotDisturb});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.$el.html(this.template({
|
||||
checked: navigator.mozLoop.doNotDisturb ? "checked" : ""
|
||||
}));
|
||||
return this;
|
||||
// XXX https://github.com/facebook/react/issues/310 for === htmlFor
|
||||
return (
|
||||
React.DOM.p( {className:"dnd"},
|
||||
React.DOM.input( {type:"checkbox", checked:this.state.doNotDisturb,
|
||||
id:"dnd-component", onChange:this.handleCheckboxChange} ),
|
||||
React.DOM.label( {htmlFor:"dnd-component"}, __("do_not_disturb"))
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var ToSView = sharedViews.BaseView.extend({
|
||||
template: _.template([
|
||||
'<p data-l10n-id="legal_text_and_links"',
|
||||
' data-l10n-args=\'',
|
||||
' {"terms_of_use_url": "https://accounts.firefox.com/legal/terms",',
|
||||
' "privacy_notice_url": "www.mozilla.org/privacy/"',
|
||||
' }\'></p>'
|
||||
].join('')),
|
||||
var ToSView = React.createClass({displayName: 'ToSView',
|
||||
getInitialState: function() {
|
||||
return {seenToS: navigator.mozLoop.getLoopCharPref('seenToS')};
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (navigator.mozLoop.getLoopCharPref('seenToS') === null) {
|
||||
this.$el.html(this.template());
|
||||
var tosHTML = __("legal_text_and_links", {
|
||||
"terms_of_use_url": "https://accounts.firefox.com/legal/terms",
|
||||
"privacy_notice_url": "www.mozilla.org/privacy/"
|
||||
});
|
||||
|
||||
if (!this.state.seenToS) {
|
||||
navigator.mozLoop.setLoopCharPref('seenToS', 'seen');
|
||||
return React.DOM.p( {className:"tos",
|
||||
dangerouslySetInnerHTML:{__html: tosHTML}});
|
||||
} else {
|
||||
return React.DOM.div(null );
|
||||
}
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
var PanelLayout = React.createClass({displayName: 'PanelLayout',
|
||||
propTypes: {
|
||||
summary: React.PropTypes.string.isRequired
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
React.DOM.div( {className:"share generate-url"},
|
||||
React.DOM.div( {className:"description"},
|
||||
React.DOM.p(null, this.props.summary)
|
||||
),
|
||||
React.DOM.div( {className:"action"},
|
||||
this.props.children
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var CallUrlResult = React.createClass({displayName: 'CallUrlResult',
|
||||
propTypes: {
|
||||
callUrl: React.PropTypes.string.isRequired,
|
||||
retry: React.PropTypes.func.isRequired
|
||||
},
|
||||
|
||||
handleButtonClick: function() {
|
||||
this.props.retry();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
// XXX setting elem value from a state (in the callUrl input)
|
||||
// makes it immutable ie read only but that is fine in our case.
|
||||
// readOnly attr will suppress a warning regarding this issue
|
||||
// from the react lib.
|
||||
return (
|
||||
PanelLayout( {summary:__("share_link_url")},
|
||||
React.DOM.div( {className:"invite"},
|
||||
React.DOM.input( {type:"url", value:this.props.callUrl, readOnly:"true"} ),
|
||||
React.DOM.button( {onClick:this.handleButtonClick,
|
||||
className:"btn btn-success"}, __("new_url"))
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var CallUrlForm = React.createClass({displayName: 'CallUrlForm',
|
||||
propTypes: {
|
||||
client: React.PropTypes.object.isRequired,
|
||||
notifier: React.PropTypes.object.isRequired
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
pending: false,
|
||||
disabled: true,
|
||||
callUrl: false
|
||||
};
|
||||
},
|
||||
|
||||
retry: function() {
|
||||
this.setState(this.getInitialState());
|
||||
},
|
||||
|
||||
handleTextChange: function(event) {
|
||||
this.setState({disabled: !event.currentTarget.value});
|
||||
},
|
||||
|
||||
handleFormSubmit: function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
this.setState({pending: true});
|
||||
|
||||
this.props.client.requestCallUrl(
|
||||
this.refs.caller.getDOMNode().value, this._onCallUrlReceived);
|
||||
},
|
||||
|
||||
_onCallUrlReceived: function(err, callUrlData) {
|
||||
var callUrl = false;
|
||||
|
||||
this.props.notifier.clear();
|
||||
|
||||
if (err) {
|
||||
this.props.notifier.errorL10n("unable_retrieve_url");
|
||||
} else {
|
||||
callUrl = callUrlData.callUrl || callUrlData.call_url;
|
||||
}
|
||||
|
||||
this.setState({pending: false, callUrl: callUrl});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
// If we have a call url, render result
|
||||
if (this.state.callUrl) {
|
||||
return (
|
||||
CallUrlResult( {callUrl:this.state.callUrl, retry:this.retry})
|
||||
);
|
||||
}
|
||||
|
||||
// If we don't display the form
|
||||
var cx = React.addons.classSet;
|
||||
return (
|
||||
PanelLayout( {summary:__("get_link_to_share")},
|
||||
React.DOM.form( {className:"invite", onSubmit:this.handleFormSubmit},
|
||||
|
||||
React.DOM.input( {type:"text", name:"caller", ref:"caller", required:"required",
|
||||
className:cx({'pending': this.state.pending}),
|
||||
onChange:this.handleTextChange,
|
||||
placeholder:__("call_identifier_textinput_placeholder")} ),
|
||||
|
||||
React.DOM.button( {type:"submit", className:"get-url btn btn-success",
|
||||
disabled:this.state.disabled},
|
||||
__("get_a_call_url")
|
||||
)
|
||||
),
|
||||
ToSView(null )
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Panel view.
|
||||
*/
|
||||
var PanelView = sharedViews.BaseView.extend({
|
||||
template: _.template([
|
||||
'<div class="description">',
|
||||
' <p data-l10n-id="get_link_to_share"></p>',
|
||||
'</div>',
|
||||
'<div class="action">',
|
||||
' <form class="invite">',
|
||||
' <input type="text" name="caller" data-l10n-id="caller" required>',
|
||||
' <button type="submit" class="get-url btn btn-success"',
|
||||
' data-l10n-id="get_a_call_url"></button>',
|
||||
' </form>',
|
||||
' <p class="tos"></p>',
|
||||
' <p class="result hide">',
|
||||
' <input id="call-url" type="url" readonly>',
|
||||
' <a class="go-back btn btn-info" href="" data-l10n-id="new_url"></a>',
|
||||
' </p>',
|
||||
' <p class="dnd"></p>',
|
||||
'</div>',
|
||||
].join("")),
|
||||
|
||||
className: "share generate-url",
|
||||
|
||||
/**
|
||||
* Do not disturb view.
|
||||
* @type {DoNotDisturbView|undefined}
|
||||
*/
|
||||
dndView: undefined,
|
||||
|
||||
events: {
|
||||
"keyup input[name=caller]": "changeButtonState",
|
||||
"submit form.invite": "getCallUrl",
|
||||
"click a.go-back": "goBack"
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
options = options || {};
|
||||
if (!options.notifier) {
|
||||
throw new Error("missing required notifier");
|
||||
}
|
||||
this.notifier = options.notifier;
|
||||
this.client = new loop.Client();
|
||||
},
|
||||
|
||||
getNickname: function() {
|
||||
return this.$("input[name=caller]").val();
|
||||
},
|
||||
|
||||
getCallUrl: function(event) {
|
||||
this.notifier.clear();
|
||||
event.preventDefault();
|
||||
var callback = function(err, callUrlData) {
|
||||
this.clearPending();
|
||||
if (err) {
|
||||
this.notifier.errorL10n("unable_retrieve_url");
|
||||
this.render();
|
||||
return;
|
||||
}
|
||||
this.onCallUrlReceived(callUrlData);
|
||||
}.bind(this);
|
||||
|
||||
this.setPending();
|
||||
this.client.requestCallUrl(this.getNickname(), callback);
|
||||
},
|
||||
|
||||
goBack: function(event) {
|
||||
event.preventDefault();
|
||||
this.$(".action .result").hide();
|
||||
this.$(".action .invite").show();
|
||||
this.$(".description p").text(__("get_link_to_share"));
|
||||
this.changeButtonState();
|
||||
},
|
||||
|
||||
onCallUrlReceived: function(callUrlData) {
|
||||
this.notifier.clear();
|
||||
this.$(".action .invite").hide();
|
||||
this.$(".action .invite input").val("");
|
||||
this.$(".action .result input").val(callUrlData.callUrl);
|
||||
this.$(".action .result").show();
|
||||
this.$(".description p").text(__("share_link_url"));
|
||||
},
|
||||
|
||||
setPending: function() {
|
||||
this.$("[name=caller]").addClass("pending");
|
||||
this.$(".get-url").addClass("disabled").attr("disabled", "disabled");
|
||||
},
|
||||
|
||||
clearPending: function() {
|
||||
this.$("[name=caller]").removeClass("pending");
|
||||
this.changeButtonState();
|
||||
},
|
||||
|
||||
changeButtonState: function() {
|
||||
var enabled = !!this.$("input[name=caller]").val();
|
||||
if (enabled) {
|
||||
this.$(".get-url").removeClass("disabled")
|
||||
.removeAttr("disabled", "disabled");
|
||||
} else {
|
||||
this.$(".get-url").addClass("disabled").attr("disabled", "disabled");
|
||||
}
|
||||
var PanelView = React.createClass({displayName: 'PanelView',
|
||||
propTypes: {
|
||||
notifier: React.PropTypes.object.isRequired,
|
||||
client: React.PropTypes.object.isRequired
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.$el.html(this.template());
|
||||
// Do not Disturb sub view
|
||||
this.dndView = new DoNotDisturbView({el: this.$(".dnd")}).render();
|
||||
this.tosView = new ToSView({el: this.$(".tos")}).render();
|
||||
return this;
|
||||
return (
|
||||
React.DOM.div(null,
|
||||
CallUrlForm( {client:this.props.client,
|
||||
notifier:this.props.notifier} ),
|
||||
DoNotDisturb(null )
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -230,10 +259,12 @@ loop.panel = (function(_, mozL10n) {
|
||||
* Resets this router to its initial state.
|
||||
*/
|
||||
reset: function() {
|
||||
// purge pending notifications
|
||||
this._notifier.clear();
|
||||
// reset home view
|
||||
this.loadView(new PanelView({notifier: this._notifier}));
|
||||
var client = new loop.Client({
|
||||
baseServerUrl: navigator.mozLoop.serverUrl
|
||||
});
|
||||
this.loadReactComponent(PanelView( {client:client,
|
||||
notifier:this._notifier} ));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -259,8 +290,9 @@ loop.panel = (function(_, mozL10n) {
|
||||
|
||||
return {
|
||||
init: init,
|
||||
DoNotDisturb: DoNotDisturb,
|
||||
CallUrlForm: CallUrlForm,
|
||||
PanelView: PanelView,
|
||||
DoNotDisturbView: DoNotDisturbView,
|
||||
PanelRouter: PanelRouter,
|
||||
ToSView: ToSView
|
||||
};
|
||||
|
||||
299
browser/components/loop/content/js/src/panel.jsx
Normal file
299
browser/components/loop/content/js/src/panel.jsx
Normal file
@@ -0,0 +1,299 @@
|
||||
/** @jsx React.DOM */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*jshint newcap:false*/
|
||||
/*global loop:true, React */
|
||||
|
||||
var loop = loop || {};
|
||||
loop.panel = (function(_, mozL10n) {
|
||||
"use strict";
|
||||
|
||||
var sharedViews = loop.shared.views,
|
||||
// aliasing translation function as __ for concision
|
||||
__ = mozL10n.get;
|
||||
|
||||
/**
|
||||
* Panel router.
|
||||
* @type {loop.desktopRouter.DesktopRouter}
|
||||
*/
|
||||
var router;
|
||||
|
||||
/**
|
||||
* Do not disturb panel subview.
|
||||
*/
|
||||
var DoNotDisturb = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {doNotDisturb: navigator.mozLoop.doNotDisturb};
|
||||
},
|
||||
|
||||
handleCheckboxChange: function() {
|
||||
// Note: side effect!
|
||||
navigator.mozLoop.doNotDisturb = !navigator.mozLoop.doNotDisturb;
|
||||
this.setState({doNotDisturb: navigator.mozLoop.doNotDisturb});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
// XXX https://github.com/facebook/react/issues/310 for === htmlFor
|
||||
return (
|
||||
<p className="dnd">
|
||||
<input type="checkbox" checked={this.state.doNotDisturb}
|
||||
id="dnd-component" onChange={this.handleCheckboxChange} />
|
||||
<label htmlFor="dnd-component">{__("do_not_disturb")}</label>
|
||||
</p>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var ToSView = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {seenToS: navigator.mozLoop.getLoopCharPref('seenToS')};
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var tosHTML = __("legal_text_and_links", {
|
||||
"terms_of_use_url": "https://accounts.firefox.com/legal/terms",
|
||||
"privacy_notice_url": "www.mozilla.org/privacy/"
|
||||
});
|
||||
|
||||
if (!this.state.seenToS) {
|
||||
navigator.mozLoop.setLoopCharPref('seenToS', 'seen');
|
||||
return <p className="tos"
|
||||
dangerouslySetInnerHTML={{__html: tosHTML}}></p>;
|
||||
} else {
|
||||
return <div />;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var PanelLayout = React.createClass({
|
||||
propTypes: {
|
||||
summary: React.PropTypes.string.isRequired
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<div className="share generate-url">
|
||||
<div className="description">
|
||||
<p>{this.props.summary}</p>
|
||||
</div>
|
||||
<div className="action">
|
||||
{this.props.children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var CallUrlResult = React.createClass({
|
||||
propTypes: {
|
||||
callUrl: React.PropTypes.string.isRequired,
|
||||
retry: React.PropTypes.func.isRequired
|
||||
},
|
||||
|
||||
handleButtonClick: function() {
|
||||
this.props.retry();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
// XXX setting elem value from a state (in the callUrl input)
|
||||
// makes it immutable ie read only but that is fine in our case.
|
||||
// readOnly attr will suppress a warning regarding this issue
|
||||
// from the react lib.
|
||||
return (
|
||||
<PanelLayout summary={__("share_link_url")}>
|
||||
<div className="invite">
|
||||
<input type="url" value={this.props.callUrl} readOnly="true" />
|
||||
<button onClick={this.handleButtonClick}
|
||||
className="btn btn-success">{__("new_url")}</button>
|
||||
</div>
|
||||
</PanelLayout>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var CallUrlForm = React.createClass({
|
||||
propTypes: {
|
||||
client: React.PropTypes.object.isRequired,
|
||||
notifier: React.PropTypes.object.isRequired
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
pending: false,
|
||||
disabled: true,
|
||||
callUrl: false
|
||||
};
|
||||
},
|
||||
|
||||
retry: function() {
|
||||
this.setState(this.getInitialState());
|
||||
},
|
||||
|
||||
handleTextChange: function(event) {
|
||||
this.setState({disabled: !event.currentTarget.value});
|
||||
},
|
||||
|
||||
handleFormSubmit: function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
this.setState({pending: true});
|
||||
|
||||
this.props.client.requestCallUrl(
|
||||
this.refs.caller.getDOMNode().value, this._onCallUrlReceived);
|
||||
},
|
||||
|
||||
_onCallUrlReceived: function(err, callUrlData) {
|
||||
var callUrl = false;
|
||||
|
||||
this.props.notifier.clear();
|
||||
|
||||
if (err) {
|
||||
this.props.notifier.errorL10n("unable_retrieve_url");
|
||||
} else {
|
||||
callUrl = callUrlData.callUrl || callUrlData.call_url;
|
||||
}
|
||||
|
||||
this.setState({pending: false, callUrl: callUrl});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
// If we have a call url, render result
|
||||
if (this.state.callUrl) {
|
||||
return (
|
||||
<CallUrlResult callUrl={this.state.callUrl} retry={this.retry}/>
|
||||
);
|
||||
}
|
||||
|
||||
// If we don't display the form
|
||||
var cx = React.addons.classSet;
|
||||
return (
|
||||
<PanelLayout summary={__("get_link_to_share")}>
|
||||
<form className="invite" onSubmit={this.handleFormSubmit}>
|
||||
|
||||
<input type="text" name="caller" ref="caller" required="required"
|
||||
className={cx({'pending': this.state.pending})}
|
||||
onChange={this.handleTextChange}
|
||||
placeholder={__("call_identifier_textinput_placeholder")} />
|
||||
|
||||
<button type="submit" className="get-url btn btn-success"
|
||||
disabled={this.state.disabled}>
|
||||
{__("get_a_call_url")}
|
||||
</button>
|
||||
</form>
|
||||
<ToSView />
|
||||
</PanelLayout>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Panel view.
|
||||
*/
|
||||
var PanelView = React.createClass({
|
||||
propTypes: {
|
||||
notifier: React.PropTypes.object.isRequired,
|
||||
client: React.PropTypes.object.isRequired
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<div>
|
||||
<CallUrlForm client={this.props.client}
|
||||
notifier={this.props.notifier} />
|
||||
<DoNotDisturb />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var PanelRouter = loop.desktopRouter.DesktopRouter.extend({
|
||||
/**
|
||||
* DOM document object.
|
||||
* @type {HTMLDocument}
|
||||
*/
|
||||
document: undefined,
|
||||
|
||||
routes: {
|
||||
"": "home"
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
options = options || {};
|
||||
if (!options.document) {
|
||||
throw new Error("missing required document");
|
||||
}
|
||||
this.document = options.document;
|
||||
|
||||
this._registerVisibilityChangeEvent();
|
||||
|
||||
this.on("panel:open panel:closed", this.reset, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Register the DOM visibility API event for the whole document, and trigger
|
||||
* appropriate events accordingly:
|
||||
*
|
||||
* - `panel:opened` when the panel is open
|
||||
* - `panel:closed` when the panel is closed
|
||||
*
|
||||
* @link http://www.w3.org/TR/page-visibility/
|
||||
*/
|
||||
_registerVisibilityChangeEvent: function() {
|
||||
this.document.addEventListener("visibilitychange", function(event) {
|
||||
this.trigger(event.currentTarget.hidden ? "panel:closed"
|
||||
: "panel:open");
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Default entry point.
|
||||
*/
|
||||
home: function() {
|
||||
this.reset();
|
||||
},
|
||||
|
||||
/**
|
||||
* Resets this router to its initial state.
|
||||
*/
|
||||
reset: function() {
|
||||
this._notifier.clear();
|
||||
var client = new loop.Client({
|
||||
baseServerUrl: navigator.mozLoop.serverUrl
|
||||
});
|
||||
this.loadReactComponent(<PanelView client={client}
|
||||
notifier={this._notifier} />);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Panel initialisation.
|
||||
*/
|
||||
function init() {
|
||||
// Do the initial L10n setup, we do this before anything
|
||||
// else to ensure the L10n environment is setup correctly.
|
||||
mozL10n.initialize(navigator.mozLoop);
|
||||
|
||||
router = new PanelRouter({
|
||||
document: document,
|
||||
notifier: new sharedViews.NotificationListView({el: "#messages"})
|
||||
});
|
||||
Backbone.history.start();
|
||||
|
||||
// Notify the window that we've finished initalization and initial layout
|
||||
var evtObject = document.createEvent('Event');
|
||||
evtObject.initEvent('loopPanelInitialized', true, false);
|
||||
window.dispatchEvent(evtObject);
|
||||
}
|
||||
|
||||
return {
|
||||
init: init,
|
||||
DoNotDisturb: DoNotDisturb,
|
||||
CallUrlForm: CallUrlForm,
|
||||
PanelView: PanelView,
|
||||
PanelRouter: PanelRouter,
|
||||
ToSView: ToSView
|
||||
};
|
||||
})(_, document.mozL10n);
|
||||
Reference in New Issue
Block a user