Bug 972020 - Loop basic UI. r=Standard8

--HG--
rename : browser/components/loop/content/libs/backbone-min.js => browser/components/loop/content/shared/libs/backbone-1.1.2.js
rename : browser/components/loop/content/libs/lodash.min.js => browser/components/loop/content/shared/libs/lodash-2.4.1.js
This commit is contained in:
Nicolas Perriault 2014-05-29 21:13:41 +01:00
Родитель 0a91369aaa
Коммит 0990db56f0
24 изменённых файлов: 6944 добавлений и 22 удалений

Просмотреть файл

@ -0,0 +1,65 @@
/* 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*/
var loop = loop || {};
loop.Client = (function($) {
"use strict";
/**
* Loop server client.
*
* @param {Object} settings Settings object.
*/
function Client(settings) {
settings = settings || {};
if (!settings.hasOwnProperty("baseApiUrl")) {
throw new Error("missing required baseApiUrl");
}
this.settings = settings;
}
Client.prototype = {
/**
* Requests a call URL to the Loop server.
*
* @param {Function} cb Callback(err, callUrl)
*/
requestCallUrl: function(simplepushUrl, cb) {
var endpoint = this.settings.baseApiUrl + "/call-url/",
reqData = {simplepushUrl: simplepushUrl};
function validate(callUrlData) {
if (typeof callUrlData !== "object" ||
!callUrlData.hasOwnProperty("call_url")) {
var message = "Invalid call url data received";
console.error(message, callUrlData);
throw new Error(message);
}
return callUrlData.call_url;
}
var req = $.post(endpoint, reqData, function(callUrlData) {
try {
cb(null, validate(callUrlData));
} catch (err) {
cb(err);
}
}, "json");
req.fail(function(xhr, type, err) {
var error = "Unknown error.";
if (xhr && xhr.responseJSON && xhr.responseJSON.error) {
error = xhr.responseJSON.error;
}
var message = "HTTP error " + xhr.status + ": " + err + "; " + error;
console.error(message);
cb(new Error(message));
});
}
};
return Client;
})(jQuery);

Просмотреть файл

@ -0,0 +1,70 @@
/* 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/. */
Components.utils.import("resource://gre/modules/Services.jsm");
const Ci = Components.interfaces;
/**
* Data accessor for chrome resources. This is used to provide an
* interface for l10n.js to use.
*
* XXX currently this file accesses chrome direct, and hence is a big
* simplification on what it could be. When we implement
* bug 976109 we'll likely need to do a proxy to the chrome space.
*/
var FirefoxCom = (function FirefoxComClosure() {
return {
/**
* Handles requests for data synchronously.
*/
requestSync: function(action, data) {
if (action === 'getLocale')
return this.getLocale();
if (action === 'getStrings')
return this.getStrings(data);
console.error('[fxcom] Action' + action + ' is unknown');
return null;
},
getLocale: function() {
try {
return Services.prefs.getCharPref('general.useragent.locale');
} catch (x) {
return 'en-US';
}
},
getStrings: function(data) {
try {
return JSON.stringify(this.localizedStrings[data] || null);
} catch (e) {
console.error('[fxcom] Unable to retrive localized strings: ' + e);
}
},
get localizedStrings() {
var stringBundle =
Services.strings.createBundle('chrome://browser/locale/loop/loop.properties');
var map = {};
var enumerator = stringBundle.getSimpleEnumeration();
while (enumerator.hasMoreElements()) {
var string = enumerator.getNext().QueryInterface(Ci.nsIPropertyElement);
var key = string.key, property = 'textContent';
var i = key.lastIndexOf('.');
if (i >= 0) {
property = key.substring(i + 1);
key = key.substring(0, i);
}
if (!(key in map))
map[key] = {};
map[key][property] = string.value;
}
delete this.localizedStrings;
return this.localizedStrings = map;
}
};
})();

Просмотреть файл

@ -0,0 +1,146 @@
/* 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*/
var loop = loop || {};
loop.panel = (function(_, __) {
"use strict";
// XXX: baseApiUrl should be configurable (browser pref)
var baseApiUrl = "http://localhost:5000",
panelView;
/**
* Panel initialisation.
*/
function init() {
panelView = new PanelView();
panelView.render();
}
/**
* Notification model.
*/
var NotificationModel = Backbone.Model.extend({
defaults: {
level: "info",
message: ""
}
});
/**
* Notification collection
*/
var NotificationCollection = Backbone.Collection.extend({
model: NotificationModel
});
/**
* Notification view.
*/
var NotificationView = Backbone.View.extend({
template: _.template([
'<div class="alert alert-<%- level %>">',
' <button class="close"></button>',
' <p class="message"><%- message %></p>',
'</div>'
].join("")),
events: {
"click .close": "dismiss"
},
dismiss: function() {
this.$el.addClass("fade-out");
setTimeout(function() {
this.collection.remove(this.model);
this.remove();
}.bind(this), 500);
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
/**
* Notification list view.
*/
var NotificationListView = Backbone.View.extend({
initialize: function() {
this.listenTo(this.collection, "reset add remove", this.render);
},
render: function() {
this.$el.html(this.collection.map(function(notification) {
return new NotificationView({
model: notification,
collection: this.collection
}).render().$el;
}.bind(this)));
return this;
}
});
/**
* Panel view.
*/
var PanelView = Backbone.View.extend({
el: "#default-view",
events: {
"click a.get-url": "getCallUrl"
},
initialize: function() {
this.client = new loop.Client({
baseApiUrl: baseApiUrl
});
this.notificationCollection = new NotificationCollection();
this.notificationListView = new NotificationListView({
el: this.$(".messages"),
collection: this.notificationCollection
});
this.notificationListView.render();
},
notify: function(message, level) {
this.notificationCollection.add({
level: level || "info",
message: message
});
},
getCallUrl: function(event) {
event.preventDefault();
var simplepushUrl = "http://fake.url/"; // XXX: send a real simplepush url
this.client.requestCallUrl(simplepushUrl, function(err, callUrl) {
if (err) {
this.notify(__("unable_retrieve_url"), "error");
return;
}
this.onCallUrlReceived(callUrl);
}.bind(this));
},
onCallUrlReceived: function(callUrl) {
this.notificationCollection.reset();
this.$(".action .invite").hide();
this.$(".action .result input").val(callUrl);
this.$(".action .result").show();
this.$(".description p").text(__("share_link_url"));
}
});
return {
init: init,
NotificationModel: NotificationModel,
NotificationCollection: NotificationCollection,
NotificationView: NotificationView,
NotificationListView: NotificationListView,
PanelView: PanelView
};
})(_, document.mozL10n.get);

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -4,20 +4,44 @@
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<html>
<head>
<meta charset="utf-8">
<title>Loop Panel</title>
<link rel="stylesheet" type="text/css" href="shared/css/common.css">
<link rel="stylesheet" type="text/css" href="shared/css/panel.css">
</head>
<body onload="loop.panel.init();">
<!-- XXX (n1k0): i10n tbd later as these are temporary texts. -->
<div id="default-view" class="share generate-url">
<div class="description">
<p data-l10n-id="get_link_to_share">
Get a link to share with a friend to Video Chat.
</p>
</div>
<div class="action">
<div class="messages"></div>
<p class="invite">
<a class="get-url btn btn-success" href=""
data-l10n-id="get_a_call_url">Get a call url</a>
</p>
<p class="result hide">
<input id="call-url" type="url" readonly>
<a class="get-url btn btn-info" href="" data-l10n-id="renew">Renew</a>
</p>
</div>
</div>
<!-- XXX (adam): Should we import our own version of Webl10n?
What we have here is a copy of the version from pdf.js
(which I can't seem to reference directly, so we've copied
it here). At the very least, if we're using the same
library as pdf.js, we should be referring to the same
file. -->
<script type="text/javascript" src="js/fxcom.js"></script>
<script type="text/javascript" src="libs/l10n.js"></script>
<script type="text/javascript" src="libs/zepto.min.js"></script>
<script type="text/javascript" src="libs/lodash.min.js"></script>
<script type="text/javascript" src="libs/backbone-min.js"></script>
</head>
<body>
<!-- Intentionally not localisable as this is a temporary page -->
<p>Soon you'll be able to get a url to share with your friends and chat with them</p>
<script type="text/javascript" src="shared/libs/jquery-2.1.0.js"></script>
<script type="text/javascript" src="shared/libs/lodash-2.4.1.js"></script>
<script type="text/javascript" src="shared/libs/backbone-1.1.2.js"></script>
<script type="text/javascript" src="js/client.js"></script>
<script type="text/javascript" src="js/panel.js"></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,12 @@
Loop Shared Web Assets
======================
This directory contains web assets shared across the Loop client webapp and the
Loop Firefox Component.
Warning
-------
Any modification in these files will have possible side effects on both the
Firefox component and the webapp. The `css/readme.html` file uses all the shared
styles, you should use it as a way of checking for visual regressions.

Просмотреть файл

@ -0,0 +1,138 @@
/* 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/. */
/* Generic rules */
/**
* "Fixes" the Box Model.
* @see http://www.paulirish.com/2012/box-sizing-border-box-ftw/
*/
*, *:before, *:after {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
font-family: "Helvetica Neue", Helvetica, Arial, sans;
font-size: 14px;
background: #f2f2f2;
}
button {
font-size: .9em; /* for some reason, text is larger within <button> */
}
img {
border: none;
}
/* Helpers */
/**
* Clearfix impl. for modern browsers
* 1. The space content is one way to avoid an Opera bug when the
* contenteditable attribute is included anywhere else in the document.
* Otherwise it causes space to appear at the top and bottom of elements
* that are clearfixed.
* 2. The use of `table` rather than `block` is only necessary if using
* `:before` to contain the top-margins of child elements.
*/
.cf:before,
.cf:after {
content: " "; /* 1 */
display: table; /* 2 */
}
.cf:after {
clear: both;
}
.hide {
display: none;
}
.tc {
text-align: center;
}
/* Buttons */
.btn {
display: inline-block;
background: #aaa;
border: none;
color: #fff;
text-decoration: none;
padding: .25em .5em .3em;
border-radius: .2em;
}
.btn-info {
background: #428BCA;
}
.btn-success {
background: #5cb85c;
}
.btn-warning {
background: #f0ad4e;
}
.btn-error {
background: #d9534f;
}
/* Alerts */
.alert {
background: #eee;
padding: .2em 1em;
margin-bottom: 1em;
}
.alert p.message {
padding: 0;
margin: 0;
}
.alert.alert-error {
background: #f99;
border: 1px solid #f77;
}
.alert .close {
position: relative;
top: 0;
right: -.8em;
}
/* Misc */
.close {
float: right;
font-size: 20px;
font-weight: bold;
line-height: 1em;
color: #000;
opacity: .2;
}
.close:before {
/* \2716 is unicode representation of the close button icon */
content: '\2716';
}
button.close {
background: none;
border: none;
padding: none;
cursor: pointer;
}
/* Transitions */
.fade-out {
transition: opacity 0.5s ease-in;
opacity: 0;
}

Просмотреть файл

@ -0,0 +1,43 @@
/* 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/. */
/* Conversation window styles */
.conversation .controls {
background: #f2f2f2;
padding: .5em;
}
.conversation .media video {
background: #eee;
}
/* Nested video elements */
.conversation .media.nested {
position: relative;
}
.conversation .media.nested .remote {
width: 100%;
}
.conversation .media.nested .local {
position: absolute;
bottom: .8em;
right: .8em;
width: 30%;
max-width: 140px;
}
/* Side by side video elements */
.conversation .media.side-by-side .remote {
width: 50%;
float: left;
}
.conversation .media.side-by-side .local {
width: 50%;
}

Просмотреть файл

@ -0,0 +1,60 @@
/* 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/. */
/* Panel styles */
.spacer {
margin-bottom: 1em;
}
.share {
background: #f2f2f2;
}
.share .description {
background: #f7f7f7 url("../img/icon_32.png") no-repeat 1em 1.5em;
border-bottom: 1px solid #c3c3c3;
padding: 1em 1em 0 4em;
}
.share .description .field {
padding-bottom: 1em;
border-bottom: 1px dotted #ddd;
}
.share .description select {
float: right;
}
.share .description .preview video {
background: #ccc;
float: right;
width: 180px;
}
.share .action {
clear: right;
padding: 1em;
border-top: 1px solid #fafafa;
}
.share .action p {
margin: 0 0 1em 0;
}
.share .action input {
font-size: .9em;
width: 60%;
padding: .4em;
}
/* Specific cases */
.share.generate-url .action {
text-align: center;
}
.share .action .messages p {
margin: 0;
}

Просмотреть файл

@ -0,0 +1,173 @@
<!DOCTYPE html>
<!-- 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/. -->
<!-- This file is intended to help frontend developers to easily identify what
are the available styles for the Loop UI components. -->
<html>
<head>
<meta charset="utf-8">
<title>Loop UI shared CSS information/demo</title>
<link type="text/css" rel="stylesheet" href="common.css">
<link type="text/css" rel="stylesheet" href="panel.css">
<link type="text/css" rel="stylesheet" href="conversation.css">
<style>
body {
width: 600px;
margin: 1em auto;
background: #fff;
font-family: Helvetica, Arial, sans;
}
</style>
</head>
<body>
<h1>Loop UI toolkit</h1>
<h2>Logo icons</h2>
<p>
<img src="../img/icon_32.png"> 32x32 transparent PNG
<img src="../img/icon_64.png"> 64x64 transparent PNG
</p>
<p><em><strong>Note:</strong> these are temporary.</em></p>
<h2>Share panel</h2>
<h3>Simple</h3>
<div class="share">
<form class="description">
<p>This is a simple message.</p>
</form>
<div class="action">
<p><input type="url" value="http://loop.im/plop75"></p>
<p>Your name will appear as <a href="">Unnamed</a>.</p>
</div>
</div>
<h3>Featuring options</h3>
<div class="share">
<form class="description">
<p class="field">
<label>Share this link with a friend to
<select>
<option>browse together</option>
<option selected="selected">video chat</option>
<option>audio chat</option>
<option>text chat</option>
</select>
</label>
</p>
<p class="field">
<label>
Use webcam <select><option>Foo</option></select>
</label>
</p>
<p class="field">
<label>Use whatever
<select><option>Long foo is long indeed</option></select>
</label>
</p>
<p class="preview cf">
Preview <video></video>
</p>
</form>
<div class="action">
<p><input type="url" value="http://loop.im/plop75"></p>
<p>Your name will appear as <a href="">Unnamed</a>.</p>
</div>
</div>
<h2>Conversation window</h2>
<p><em>The conversation component adapts automatically to its container to
occupy all the available space.</em></p>
<h3>Large</h3>
<div class="conversation">
<div class="media nested">
<video class="remote"></video>
<video class="local"></video>
</div>
</div>
<h3>Large with controls</h3>
<div class="conversation">
<nav class="controls">
<button class="btn">Start</button>
<button class="btn">Stop</button>
</nav>
<div class="media nested">
<video class="remote"></video>
<video class="local"></video>
</div>
</div>
<h3>Small (think chat window)</h3>
<div style="width: 204px">
<div class="conversation">
<div class="media nested">
<video class="remote"></video>
<video class="local"></video>
</div>
</div>
</div>
<h3>Side by side</h3>
<div class="conversation">
<div class="media side-by-side">
<video class="remote"></video>
<video class="local"></video>
</div>
</div>
<h2>Buttons</h2>
<h3>Using <code>&lt;a&gt;</code></h3>
<p>
<a href="" class="btn">default</a>
<a href="" class="btn btn-info">info</a>
<a href="" class="btn btn-success">success</a>
<a href="" class="btn btn-warning">warning</a>
<a href="" class="btn btn-error">error</a>
</p>
<h3>Inline</h3>
<p>Click <a href="" class="btn btn-info">here</a>.</p>
<h3>Using <code>&lt;button&gt;</code></h3>
<p>
<button class="btn">default</button>
<button class="btn btn-info">info</button>
<button class="btn btn-success">success</button>
<button class="btn btn-warning">warning</button>
<button class="btn btn-error">error</button>
</p>
<h2>Alerts</h2>
<div class="alert alert-error">
<button class="close"
onclick="var el=this.parentNode;el.classList.add('fade-out');setTimeout(el.remove.bind(el), 500);"></button>
<p class="message">Oops! Something went really wrong.</p>
</div>
<script>
window.onload = function() {
[].forEach.call(document.querySelectorAll("video"), function(video) {
video.setAttribute("src", "http://v2v.cc/~j/theora_testsuite/320x240.ogg");
});
}
</script>
</body>
</html>

Двоичные данные
browser/components/loop/content/shared/img/icon_32.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.3 KiB

Двоичные данные
browser/components/loop/content/shared/img/icon_64.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.0 KiB

4
browser/components/loop/content/shared/libs/jquery-2.1.0.js поставляемый Normal file

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -3,4 +3,17 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
browser.jar:
content/browser/loop/panel.html (content/panel.html)
content/browser/loop/panel.html (content/panel.html)
content/browser/loop/shared/css/common.css (content/shared/css/common.css)
content/browser/loop/shared/css/panel.css (content/shared/css/panel.css)
content/browser/loop/shared/css/conversation.css (content/shared/css/conversation.css)
content/browser/loop/shared/img/icon_32.png (content/shared/img/icon_32.png)
content/browser/loop/shared/img/icon_64.png (content/shared/img/icon_64.png)
content/browser/loop/shared/libs/lodash-2.4.1.js (content/shared/libs/lodash-2.4.1.js)
content/browser/loop/shared/libs/jquery-2.1.0.js (content/shared/libs/jquery-2.1.0.js)
content/browser/loop/shared/libs/backbone-1.1.2.js (content/shared/libs/backbone-1.1.2.js)
content/browser/loop/libs/l10n.js (content/libs/l10n.js)
content/browser/loop/js/fxcom.js (content/js/fxcom.js)
content/browser/loop/js/client.js (content/js/client.js)
content/browser/loop/js/panel.js (content/js/panel.js)

Просмотреть файл

@ -0,0 +1,69 @@
/* 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, sinon */
var expect = chai.expect;
describe("loop.Client", function() {
"use strict";
var sandbox, fakeXHR, requests = [];
beforeEach(function() {
sandbox = sinon.sandbox.create();
fakeXHR = sandbox.useFakeXMLHttpRequest();
requests = [];
// https://github.com/cjohansen/Sinon.JS/issues/393
fakeXHR.xhr.onCreate = function (xhr) {
requests.push(xhr);
};
});
afterEach(function() {
sandbox.restore();
});
describe("loop.Client", function() {
describe("#constructor", function() {
it("should require a baseApiUrl setting", function() {
expect(function() {
new loop.Client();
}).to.Throw(Error, /required/);
});
});
describe("#requestCallUrl", function() {
var client;
beforeEach(function() {
client = new loop.Client({baseApiUrl: "http://fake.api"});
});
it("should request for a call url", function() {
var callback = sinon.spy();
client.requestCallUrl("fakeSimplepushUrl", callback);
expect(requests).to.have.length.of(1);
requests[0].respond(200, {"Content-Type": "application/json"},
'{"call_url": "fakeCallUrl"}');
sinon.assert.calledWithExactly(callback, null, "fakeCallUrl");
});
it("should send an error when the request fails", function() {
var callback = sinon.spy();
client.requestCallUrl("fakeSimplepushUrl", callback);
expect(requests).to.have.length.of(1);
requests[0].respond(400, {"Content-Type": "application/json"},
'{"error": "my error"}');
sinon.assert.calledWithMatch(callback, sinon.match(function(err) {
return /HTTP error 400: Bad Request; my error/.test(err.message);
}));
});
});
});
});

Просмотреть файл

@ -1,4 +1,7 @@
<!DOCTYPE html>
<!-- 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/. -->
<html>
<head>
<meta charset="utf-8">
@ -11,18 +14,46 @@
</div>
<div id="messages"></div>
<div id="fixtures"></div>
<!-- libs -->
<script>
// Components won't load in unprivileged space, faking this one.
var FirefoxCom = {
requestSync: function(action) {
if (action === 'getLocale')
return "en-US";
if (action === 'getStrings')
return '{}';
},
getLocale: function() {
return "en-US";
},
getStrings: function() {
return [];
},
};
</script>
<script src="../../content/libs/l10n.js"></script>
<script type="text/javascript" src="../../content/shared/libs/jquery-2.1.0.js"></script>
<script type="text/javascript" src="../../content/shared/libs/lodash-2.4.1.js"></script>
<script type="text/javascript" src="../../content/shared/libs/backbone-1.1.2.js"></script>
<!-- test dependencies -->
<script src="../vendor/mocha-1.17.1.js"></script>
<script src="../vendor/chai-1.9.0.js"></script>
<script src="../../content/libs/zepto.min.js"></script>
<script src="../vendor/sinon-1.9.0.js"></script>
<script>
chai.Assertion.includeStack = true;
mocha.setup('bdd');
</script>
<script src="sample_test.js"></script>
<!-- App scripts -->
<script src="../../content/js/client.js"></script>
<script src="../../content/js/panel.js"></script>
<!-- Test scripts -->
<script src="panel_test.js"></script>
<script src="client_test.js"></script>
<script>
mocha.run(function () {
$("#mocha").append("<p id='complete'>complete</p>");
$("#mocha").append("<p>Complete.</p>");
});
</script>
</body>

Просмотреть файл

@ -0,0 +1,128 @@
/* 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, sinon */
var expect = chai.expect;
describe("loop.panel", function() {
"use strict";
var sandbox, fakeXHR, requests = [];
beforeEach(function() {
sandbox = sinon.sandbox.create();
fakeXHR = sandbox.useFakeXMLHttpRequest();
requests = [];
// https://github.com/cjohansen/Sinon.JS/issues/393
fakeXHR.xhr.onCreate = function (xhr) {
requests.push(xhr);
};
});
afterEach(function() {
$("#fixtures").empty();
sandbox.restore();
});
describe("loop.panel.NotificationView", function() {
describe("#render", function() {
it("should render template with model attribute values", function() {
var view = new loop.panel.NotificationView({
el: $("#fixtures"),
model: new loop.panel.NotificationModel({
level: "error",
message: "plop"
})
});
view.render();
expect(view.$(".message").text()).eql("plop");
});
});
});
describe("loop.panel.NotificationListView", function() {
describe("Collection events", function() {
var coll, testNotif, view;
beforeEach(function() {
sandbox.stub(loop.panel.NotificationListView.prototype, "render");
testNotif = new loop.panel.NotificationModel({
level: "error",
message: "plop"
});
coll = new loop.panel.NotificationCollection();
view = new loop.panel.NotificationListView({collection: coll});
});
it("should render on notification added to the collection", function() {
coll.add(testNotif);
sinon.assert.calledOnce(view.render);
});
it("should render on notification removed from the collection",
function() {
coll.add(testNotif);
coll.remove(testNotif);
sinon.assert.calledTwice(view.render);
});
it("should render on collection reset",
function() {
coll.reset();
sinon.assert.calledOnce(view.render);
});
});
});
describe("loop.panel.PanelView", function() {
beforeEach(function() {
$("#fixtures").append([
'<div id="default-view" class="share generate-url">',
' <div class="description">',
' <p>Get a link to share with a friend to Video Chat.</p>',
' </div>',
' <div class="action">',
' <div class="messages"></div>',
' <p class="invite">',
' <a class="get-url" href="">Get a call url</a>',
' </p>',
' <p class="result hide">',
' <input id="call-url" type="url" readonly>',
' <a class="get-url" href="">Renew</a>',
' </p>',
' </div>',
'</div>'
].join(""));
});
describe("#getCallurl", function() {
it("should request a call url to the server", function() {
var requestCallUrl = sandbox.stub(loop.Client.prototype,
"requestCallUrl");
var view = new loop.panel.PanelView();
view.getCallUrl({preventDefault: sandbox.spy()});
sinon.assert.calledOnce(requestCallUrl);
});
});
describe("#onCallUrlReceived", function() {
it("should update the text field with the call url", function() {
var view = new loop.panel.PanelView();
view.render();
view.onCallUrlReceived("http://call.me/");
expect(view.$("input").val()).eql("http://call.me/");
});
});
});
});

Просмотреть файл

@ -1,9 +0,0 @@
var expect = chai.expect;
describe("test", function() {
"use strict";
it("is true", function() {
expect(true).eql(true);
});
});

4794
browser/components/loop/test/vendor/sinon-1.9.0.js поставляемый Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,5 @@
get_link_to_share=Get a link to share with a friend to Video Chat.
get_a_call_url=Get a call url
renew=Renew
unable_retrieve_url=Sorry, we were unable to retrieve a call url.
share_link_url=Share the link below with your friend to start your call!

Просмотреть файл

@ -64,6 +64,7 @@
locale/browser/devtools/font-inspector.dtd (%chrome/browser/devtools/font-inspector.dtd)
locale/browser/devtools/app-manager.dtd (%chrome/browser/devtools/app-manager.dtd)
locale/browser/devtools/app-manager.properties (%chrome/browser/devtools/app-manager.properties)
locale/browser/loop/loop.properties (%chrome/browser/loop/loop.properties)
locale/browser/newTab.dtd (%chrome/browser/newTab.dtd)
locale/browser/newTab.properties (%chrome/browser/newTab.properties)
locale/browser/pageInfo.dtd (%chrome/browser/pageInfo.dtd)