Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
21
gaia/tv_apps/browser/bower.json
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "browser",
|
||||
"version": "0.0.0",
|
||||
"homepage": "https://github.com/mozilla-b2g/gaia/tree/master/tv_apps/browser",
|
||||
"description": "Smart Screen Browser App",
|
||||
"main": "index.html",
|
||||
"license": "MPL",
|
||||
"private": true,
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"dependencies": {
|
||||
"evt": "fxos-components/evt#~0.4.0",
|
||||
"smart-button": "fxos-components/smart-button",
|
||||
"smart-icons": "smart-components/smart-icons#~0.0.3"
|
||||
}
|
||||
}
|
||||
28
gaia/tv_apps/browser/bower_components/evt/.bower.json
vendored
Executable file
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"name": "evt",
|
||||
"main": "index.js",
|
||||
"version": "0.4.0",
|
||||
"homepage": "https://github.com/wilsonpage/evt",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"package.json",
|
||||
"test",
|
||||
"tests",
|
||||
"README.md"
|
||||
],
|
||||
"_release": "0.4.0",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.4.0",
|
||||
"commit": "3593dd6b4dd19f683d00fd0eaf2581c11a128da6"
|
||||
},
|
||||
"_source": "git://github.com/gaia-components/evt.git",
|
||||
"_target": "~0.4.0",
|
||||
"_originalSource": "gaia-components/evt"
|
||||
}
|
||||
19
gaia/tv_apps/browser/bower_components/evt/bower.json
vendored
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "evt",
|
||||
"main": "index.js",
|
||||
"version": "0.4.0",
|
||||
"homepage": "https://github.com/wilsonpage/evt",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"package.json",
|
||||
"test",
|
||||
"tests",
|
||||
"README.md"
|
||||
]
|
||||
}
|
||||
154
gaia/tv_apps/browser/bower_components/evt/index.js
vendored
Executable file
|
|
@ -0,0 +1,154 @@
|
|||
|
||||
/**
|
||||
* Evt
|
||||
*
|
||||
* A super lightweight
|
||||
* event emitter library.
|
||||
*
|
||||
* @version 0.3.3
|
||||
* @author Wilson Page <wilson.page@me.com>
|
||||
*/
|
||||
|
||||
;(function() {
|
||||
|
||||
/**
|
||||
* Locals
|
||||
*/
|
||||
|
||||
var proto = Events.prototype;
|
||||
var slice = [].slice;
|
||||
|
||||
/**
|
||||
* Creates a new event emitter
|
||||
* instance, or if passed an
|
||||
* object, mixes the event logic
|
||||
* into it.
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @return {Object}
|
||||
*/
|
||||
function Events(obj) {
|
||||
if (!(this instanceof Events)) return new Events(obj);
|
||||
if (obj) return mixin(obj, proto);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a callback
|
||||
* with an event name.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Function} cb
|
||||
* @return {Event}
|
||||
*/
|
||||
proto.on = function(name, cb) {
|
||||
this._cbs = this._cbs || {};
|
||||
(this._cbs[name] || (this._cbs[name] = [])).push(cb);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Attach a callback that once
|
||||
* called, detaches itself.
|
||||
*
|
||||
* TODO: Implement `.off()` to work
|
||||
* with `once()` callbacks.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Function} cb
|
||||
* @public
|
||||
*/
|
||||
proto.once = function(name, cb) {
|
||||
this.on(name, one);
|
||||
function one() {
|
||||
cb.apply(this, arguments);
|
||||
this.off(name, one);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes a single callback,
|
||||
* or all callbacks associated
|
||||
* with the passed event name.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Function} cb
|
||||
* @return {Event}
|
||||
*/
|
||||
proto.off = function(name, cb) {
|
||||
this._cbs = this._cbs || {};
|
||||
|
||||
if (!name) { this._cbs = {}; return; }
|
||||
if (!cb) { return delete this._cbs[name]; }
|
||||
|
||||
var cbs = this._cbs[name] || [];
|
||||
var i;
|
||||
|
||||
while (cbs && ~(i = cbs.indexOf(cb))) { cbs.splice(i, 1); }
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Fires an event, triggering
|
||||
* all callbacks registered on this
|
||||
* event name.
|
||||
*
|
||||
* @param {String} name
|
||||
* @return {Event}
|
||||
*/
|
||||
proto.fire = proto.emit = function(options) {
|
||||
var cbs = this._cbs = this._cbs || {};
|
||||
var name = options.name || options;
|
||||
var batch = (cbs[name] || []).concat(cbs['*'] || []);
|
||||
var ctx = options.ctx || this;
|
||||
|
||||
if (batch.length) {
|
||||
this._fireArgs = arguments;
|
||||
var args = slice.call(arguments, 1);
|
||||
while (batch.length) {
|
||||
batch.shift().apply(ctx, args);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
proto.firer = function(name) {
|
||||
var self = this;
|
||||
return function() {
|
||||
var args = slice.call(arguments);
|
||||
args.unshift(name);
|
||||
self.fire.apply(self, args);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Util
|
||||
*/
|
||||
|
||||
/**
|
||||
* Mixes in the properties
|
||||
* of the second object into
|
||||
* the first.
|
||||
*
|
||||
* @param {Object} a
|
||||
* @param {Object} b
|
||||
* @return {Object}
|
||||
*/
|
||||
function mixin(a, b) {
|
||||
for (var key in b) a[key] = b[key];
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose 'Event' (UMD)
|
||||
*/
|
||||
|
||||
if (typeof exports === 'object') {
|
||||
module.exports = Events;
|
||||
} else if (typeof define === 'function' && define.amd) {
|
||||
define(function(){ return Events; });
|
||||
} else {
|
||||
window.evt = Events;
|
||||
}
|
||||
|
||||
})();
|
||||
26
gaia/tv_apps/browser/bower_components/smart-button/.bower.json
vendored
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "smart-button",
|
||||
"version": "0.0.2",
|
||||
"homepage": "https://github.com/gaia-components/smart-button",
|
||||
"main": "script.js",
|
||||
"license": "MPL",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests",
|
||||
"examples",
|
||||
"LICENSE",
|
||||
"README.md"
|
||||
],
|
||||
"_release": "0.0.2",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.0.2",
|
||||
"commit": "04fdae935e2f2ba99d1c4f3e156d17f12eb2d142"
|
||||
},
|
||||
"_source": "git://github.com/gaia-components/smart-button.git",
|
||||
"_target": "*",
|
||||
"_originalSource": "gaia-components/smart-button"
|
||||
}
|
||||
17
gaia/tv_apps/browser/bower_components/smart-button/bower.json
vendored
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "smart-button",
|
||||
"version": "0.0.2",
|
||||
"homepage": "https://github.com/gaia-components/smart-button",
|
||||
"main": "script.js",
|
||||
"license": "MPL",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests",
|
||||
"examples",
|
||||
"LICENSE",
|
||||
"README.md"
|
||||
]
|
||||
}
|
||||
62
gaia/tv_apps/browser/bower_components/smart-button/script.js
vendored
Executable file
|
|
@ -0,0 +1,62 @@
|
|||
'use strict';
|
||||
/* global KeyEvent */
|
||||
|
||||
window.SmartButton = (function(win) {
|
||||
// Extend from the HTMLButtonElement prototype
|
||||
var proto = Object.create(HTMLButtonElement.prototype);
|
||||
|
||||
proto.createdCallback = function() {
|
||||
this.addEventListener('mousedown', this);
|
||||
this.addEventListener('mouseup', this);
|
||||
this.addEventListener('touchstart', this);
|
||||
this.addEventListener('touchend', this);
|
||||
this.addEventListener('keydown', this);
|
||||
this.addEventListener('keyup', this);
|
||||
this.addEventListener('focus', this);
|
||||
this.addEventListener('blur', this);
|
||||
this.addEventListener('transitionend', this);
|
||||
this.tabIndex = 0;
|
||||
};
|
||||
|
||||
proto.handleEvent = function(evt) {
|
||||
switch(evt.type) {
|
||||
case 'mousedown':
|
||||
case 'touchstart':
|
||||
this.classList.add('pressed');
|
||||
break;
|
||||
case 'keydown':
|
||||
if (evt.keyCode === KeyEvent.DOM_VK_RETURN) {
|
||||
this.classList.add('pressed');
|
||||
}
|
||||
break;
|
||||
case 'mouseup':
|
||||
case 'touchend':
|
||||
this.classList.remove('pressed');
|
||||
this.classList.add('released');
|
||||
break;
|
||||
case 'keyup':
|
||||
if (evt.keyCode === KeyEvent.DOM_VK_RETURN) {
|
||||
this.classList.remove('pressed');
|
||||
this.classList.add('released');
|
||||
this.click();
|
||||
}
|
||||
break;
|
||||
case 'transitionend':
|
||||
if (this.classList.contains('released')) {
|
||||
this.classList.remove('released');
|
||||
}
|
||||
break;
|
||||
case 'focus':
|
||||
this.classList.add('focused');
|
||||
break;
|
||||
case 'blur':
|
||||
this.classList.remove('pressed');
|
||||
this.classList.remove('released');
|
||||
this.classList.remove('focused');
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
// Register and return the constructor
|
||||
return document.registerElement('smart-button', { prototype: proto });
|
||||
})(window);
|
||||
497
gaia/tv_apps/browser/bower_components/smart-button/style.css
vendored
Executable file
|
|
@ -0,0 +1,497 @@
|
|||
/**
|
||||
* Button state:
|
||||
* 1. normal
|
||||
* In this state, we don't add any class.
|
||||
* 2. focused (class name: focused)
|
||||
* The focused state may be triggered by keyboard or touch/mouse.
|
||||
* 3. pressed (class name: pressed)
|
||||
* This state is triggered by user pressed confirm button, mousedown,
|
||||
* and touchdown.
|
||||
* 4. released (class name: released)
|
||||
* This state is only for changing duration of transition. We enter this
|
||||
* state when user release the button. After transitionend, we goes back
|
||||
* to focused state.
|
||||
**/
|
||||
smart-button {
|
||||
font-family: "Fira Sans";
|
||||
display: inline-block;
|
||||
width: 8rem;
|
||||
height: 8rem;
|
||||
/* we need to set border to none to remove the button border */
|
||||
border: none;
|
||||
/* the radius is still make button as round even if we don't have border */
|
||||
border-radius: 50%;
|
||||
/* 50% is not a real circle because of rounding, we have to use a value larger
|
||||
than 50% */
|
||||
-moz-outline-radius: 60%;
|
||||
outline: transparent 0 solid;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 5.4rem auto;
|
||||
background-position: center center;
|
||||
font-style: italic;
|
||||
|
||||
transition-property: all;
|
||||
transition-timing-function: cubic-bezier(0.25, 0, 0, 1.0);
|
||||
transition-duration: 0.42s;
|
||||
}
|
||||
|
||||
smart-button.focused {
|
||||
outline: 0;
|
||||
background-color: #ffffff;
|
||||
transform: scale(1.2);
|
||||
transition-duration: 0.42s;
|
||||
}
|
||||
|
||||
smart-button.released {
|
||||
transition-duration: 0.16s;
|
||||
}
|
||||
|
||||
smart-button.toggled {
|
||||
background-color: #00caf2;
|
||||
}
|
||||
|
||||
smart-button.pressed {
|
||||
background-color: #00caf2;
|
||||
transform: scale(0.8);
|
||||
transition-duration: 0.06s;
|
||||
}
|
||||
|
||||
smart-button.disabled {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
smart-button[data-icon]:before {
|
||||
width: 5.4rem;
|
||||
left: 1.3rem;
|
||||
font-size: 5.4rem;
|
||||
line-height: 8rem;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
white-space: normal;
|
||||
top: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
smart-button[data-icon].focused:before {
|
||||
color: #2d2d2d;
|
||||
}
|
||||
|
||||
smart-button[data-icon].toggled:before {
|
||||
color: #00caf2;
|
||||
}
|
||||
|
||||
smart-button[data-icon].pressed:before {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
smart-button[data-icon].disabled:before {
|
||||
color: #ffffff;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Text Button
|
||||
**/
|
||||
smart-button[type="simple-text"] {
|
||||
color: #dddddd;
|
||||
background: none;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
|
||||
width: auto;
|
||||
height: 8rem;
|
||||
|
||||
line-height: 8rem;
|
||||
font-size: 2.4rem;
|
||||
-moz-user-select: none;
|
||||
padding-left: 2.6rem;
|
||||
padding-right: 2.6rem;
|
||||
}
|
||||
|
||||
smart-button[type="simple-text"].focused {
|
||||
color: #ffffff;
|
||||
background: none;
|
||||
}
|
||||
|
||||
smart-button[type="simple-text"].toggled {
|
||||
color: #00caf2;
|
||||
}
|
||||
|
||||
smart-button[type="simple-text"].pressed {
|
||||
color: #00caf2;
|
||||
background: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* End of Simple Text Button
|
||||
**/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* underlined text button
|
||||
*/
|
||||
smart-button[type="underlined-text"] {
|
||||
position: relative;
|
||||
color: white;
|
||||
font-size: 2.4rem;
|
||||
padding-left: 3.8rem;
|
||||
padding-right: 3.8rem;
|
||||
border-radius: 4rem;
|
||||
width: auto;
|
||||
line-height: 8rem;
|
||||
margin-right: 1.4rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
smart-button[type="underlined-text"]:after {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
content: ' ';
|
||||
border-bottom: 0.6rem #61acd7 solid;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
smart-button[type="underlined-text"].focused {
|
||||
transform: scale(1.2);
|
||||
color: #2d2d2d;
|
||||
}
|
||||
|
||||
smart-button[type="underlined-text"].pressed {
|
||||
transform: scale(1);
|
||||
color: white;
|
||||
background-color: #00caf2;
|
||||
}
|
||||
|
||||
/**
|
||||
* End of underlined text button
|
||||
*/
|
||||
|
||||
/**
|
||||
* App Icons
|
||||
**/
|
||||
smart-button[type="app-button"] {
|
||||
/* To use 33.4rem instead of to use 33.6rem is to work around the anti-alias
|
||||
pixel. So, the circle is filled by the background almost totally. */
|
||||
width: 33.4rem;
|
||||
height: 33.4rem;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
smart-button[type="app-button"].focused {
|
||||
transform: scale(1.4);
|
||||
/* To use outline will not change the size of button and make the whole button
|
||||
thrilling. */
|
||||
outline: 0.8rem solid #ffffff;
|
||||
}
|
||||
|
||||
smart-button[type="app-button"].pressed {
|
||||
/* While scaling, we may have a gap between outline and icon which may be
|
||||
anti-alias pixel. So, we use scale(1.22) to prevent such kind of case */
|
||||
transform: scale(1.22);
|
||||
/* To use outline will not change the size of button and make the whole button
|
||||
thrilling. */
|
||||
outline: 1.0rem solid #ffffff;
|
||||
}
|
||||
|
||||
smart-button[type="app-button"].fullsized {
|
||||
background-size: 33.6rem auto;
|
||||
}
|
||||
|
||||
smart-button[type="app-button"].fitted {
|
||||
background-size: 22rem auto;
|
||||
}
|
||||
|
||||
/** we use :after as label */
|
||||
smart-button[type="app-button"]:after {
|
||||
content: attr(label);
|
||||
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: auto;
|
||||
right: auto;
|
||||
|
||||
width: 33.6rem;
|
||||
height: 8rem;
|
||||
|
||||
padding-top: 1rem;
|
||||
|
||||
line-height: 3rem;
|
||||
text-align: center;
|
||||
|
||||
font-size: 2.8rem;
|
||||
font-style: italic;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
/**
|
||||
* text backgorund color
|
||||
**/
|
||||
smart-button[type="app-button"][app-type="deck"]:after {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
smart-button[type="app-button"][app-type="tv"]:after {
|
||||
background-color: #d90c83;
|
||||
}
|
||||
|
||||
smart-button[type="app-button"][app-type="app"]:after {
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
smart-button[type="app-button"][app-type="device"]:after {
|
||||
background-color: #4a82ea;
|
||||
}
|
||||
|
||||
smart-button[type="app-button"][app-type="folder"] {
|
||||
background-color: #595959;
|
||||
}
|
||||
|
||||
smart-button[type="app-button"]:before {
|
||||
left: 0;
|
||||
line-height: 30rem;
|
||||
font-size: 16rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
smart-button[type="app-button"][app-type="folder"]:before {
|
||||
color: #CCCCCC;
|
||||
}
|
||||
|
||||
/**
|
||||
* End of App Icons
|
||||
**/
|
||||
|
||||
/**
|
||||
* text and icon button
|
||||
*/
|
||||
smart-button[type="text-and-icon"] {
|
||||
position: relative;
|
||||
color: white;
|
||||
font-size: 2.4rem;
|
||||
padding-left: 4.6rem;
|
||||
padding-right: 4.6rem;
|
||||
border-radius: 4rem;
|
||||
width: auto;
|
||||
line-height: 8rem;
|
||||
margin-right: 1.4rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
smart-button[type="text-and-icon"][data-icon] {
|
||||
padding-left: 9.6rem;
|
||||
}
|
||||
|
||||
smart-button[type="text-and-icon"][data-icon]:before {
|
||||
left: 3.8rem;
|
||||
}
|
||||
|
||||
smart-button[type="text-and-icon"].focused {
|
||||
transform: scale(1.2);
|
||||
color: #2d2d2d;
|
||||
}
|
||||
|
||||
smart-button[type="text-and-icon"].pressed {
|
||||
transform: scale(1);
|
||||
color: white;
|
||||
background-color: #00caf2;
|
||||
}
|
||||
|
||||
/**
|
||||
* End of text and icon button
|
||||
*/
|
||||
|
||||
/**
|
||||
* banner button
|
||||
**/
|
||||
smart-button[type="banner-button"] {
|
||||
position: relative;
|
||||
|
||||
color: #ffffff;
|
||||
font-size: 2rem;
|
||||
|
||||
width: 36rem;
|
||||
height: 20rem;
|
||||
overflow: hidden;
|
||||
|
||||
border-radius: 0;
|
||||
border: 0 solid #ffffff;
|
||||
|
||||
background-color: #5f5f5f;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 120%;
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
transition-property: all;
|
||||
transition-timing-function: cubic-bezier(0.25, 0, 0.5, 1.0);
|
||||
transition-duration: 0.1s;
|
||||
}
|
||||
|
||||
smart-button[type="banner-button"][label]:before {
|
||||
content: attr(label);
|
||||
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
||||
height: 5rem;
|
||||
|
||||
line-height: 5rem;
|
||||
text-align: center;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
smart-button[type="banner-button"]:after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
transition-property: all;
|
||||
transition-timing-function: cubic-bezier(0.25, 0, 0, 1.0);
|
||||
transition-duration: 0.06s;
|
||||
background-color: rgba(255, 255, 255, 0);
|
||||
}
|
||||
|
||||
smart-button[type="banner-button"].focused {
|
||||
transform: none;
|
||||
border-width: 1.2rem;
|
||||
background-size: 100%;
|
||||
transition-duration: 0.24s;
|
||||
}
|
||||
|
||||
smart-button[type="banner-button"].pressed {
|
||||
transform: scale(0.945, 0.9);
|
||||
}
|
||||
|
||||
smart-button[type="banner-button"].pressed:after {
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
/**
|
||||
* banner button
|
||||
**/
|
||||
|
||||
/**
|
||||
* circle text button
|
||||
*/
|
||||
smart-button[type="circle-text"] {
|
||||
width: 21rem;
|
||||
height: 21rem;
|
||||
color: white;
|
||||
background-color: #5f6368;
|
||||
line-height: 21rem;
|
||||
padding: 2.5rem 2rem 1.5rem 2rem;
|
||||
text-align: center;
|
||||
font-size: 3.2rem;
|
||||
font-weight: bolder;
|
||||
overflow: hidden;
|
||||
transition-property: transform, color, background-color;
|
||||
}
|
||||
|
||||
smart-button[type="circle-text"].focused {
|
||||
transform: scale(1.2);
|
||||
color: #2d2d2d;
|
||||
background-color: white;
|
||||
transition-property: transform, color, background-color;
|
||||
}
|
||||
|
||||
smart-button[type="circle-text"].pressed {
|
||||
transform: scale(1);
|
||||
color: white;
|
||||
background-color: #00caf2;
|
||||
transition-property: transform, color, background-color;
|
||||
}
|
||||
|
||||
smart-button[type="circle-text"].primary {
|
||||
background-color: #00caf2;
|
||||
transition-property: transform, color, background-color;
|
||||
}
|
||||
|
||||
smart-button[type="circle-text"].primary.focused {
|
||||
color: #ffffff;
|
||||
background-color: #00caf2;
|
||||
transition-property: transform, color, background-color;
|
||||
}
|
||||
|
||||
smart-button[type="circle-text"].primary.pressed {
|
||||
background-color: #0097b5;
|
||||
transition-property: transform, color, background-color;
|
||||
}
|
||||
|
||||
smart-button[type="circle-text"].danger {
|
||||
background-color: #e63d2f;
|
||||
transition-property: transform, color, background-color;
|
||||
}
|
||||
|
||||
smart-button[type="circle-text"].danger.focused {
|
||||
color: #ffffff;
|
||||
background-color: #e63d2f;
|
||||
transition-property: transform, color, background-color;
|
||||
}
|
||||
|
||||
smart-button[type="circle-text"].danger.pressed {
|
||||
background-color: #ac2e23;
|
||||
transition-property: transform, color, background-color;
|
||||
}
|
||||
|
||||
/**
|
||||
* End of circle text button
|
||||
*/
|
||||
|
||||
/**
|
||||
* rounded-corner text button
|
||||
*/
|
||||
smart-button[type="rounded-corner-text"] {
|
||||
-moz-user-select: none;
|
||||
width: auto;
|
||||
height: 8rem;
|
||||
border-radius: 4rem;
|
||||
background-color: #5f6368;
|
||||
padding: 0 3.8rem;
|
||||
line-height: 8rem;
|
||||
color: white;
|
||||
text-align: center;
|
||||
font-size: 2.4rem;
|
||||
overflow: hidden;
|
||||
transition-property: transform, color, background-color;
|
||||
}
|
||||
|
||||
smart-button[type="rounded-corner-text"].focused,
|
||||
smart-button[type="rounded-corner-text"]:hover {
|
||||
transform: scale(1.2);
|
||||
color: #2d2d2d;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
smart-button[type="rounded-corner-text"].pressed {
|
||||
transform: scale(1);
|
||||
/*color: white;*/
|
||||
background-color: #00caf2;
|
||||
}
|
||||
|
||||
smart-button[type="rounded-corner-text"].primary {
|
||||
background-color: #00caf2;
|
||||
}
|
||||
|
||||
smart-button[type="rounded-corner-text"].primary:hover,
|
||||
smart-button[type="rounded-corner-text"].primary.focused {
|
||||
color: #ffffff;
|
||||
background-color: #00caf2;
|
||||
}
|
||||
|
||||
smart-button[type="rounded-corner-text"].primary.pressed {
|
||||
background-color: #0097b5;
|
||||
}
|
||||
|
||||
/**
|
||||
* End of rounded-corner text button
|
||||
*/
|
||||
30
gaia/tv_apps/browser/bower_components/smart-icons/.bower.json
vendored
Executable file
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"name": "smart-icons",
|
||||
"version": "0.0.3",
|
||||
"homepage": "https://github.com/smart-components/smart-icons",
|
||||
"description": "Icon font for smart-screen",
|
||||
"license": "MPL",
|
||||
"private": true,
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"templates",
|
||||
"images",
|
||||
"test",
|
||||
"tests",
|
||||
"index.html",
|
||||
"Gruntfile.js",
|
||||
"README.md",
|
||||
"package.json"
|
||||
],
|
||||
"_release": "0.0.3",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.0.3",
|
||||
"commit": "0c335ac23f484069b4fafa7b7e5afd9f3c08d66e"
|
||||
},
|
||||
"_source": "git://github.com/smart-components/smart-icons.git",
|
||||
"_target": "~0.0.3",
|
||||
"_originalSource": "smart-components/smart-icons"
|
||||
}
|
||||
21
gaia/tv_apps/browser/bower_components/smart-icons/bower.json
vendored
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "smart-icons",
|
||||
"version": "0.0.3",
|
||||
"homepage": "https://github.com/smart-components/smart-icons",
|
||||
"description": "Icon font for smart-screen",
|
||||
"license": "MPL",
|
||||
"private": true,
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"templates",
|
||||
"images",
|
||||
"test",
|
||||
"tests",
|
||||
"index.html",
|
||||
"Gruntfile.js",
|
||||
"README.md",
|
||||
"package.json"
|
||||
]
|
||||
}
|
||||
BIN
gaia/tv_apps/browser/bower_components/smart-icons/fonts/smart-icons.ttf
vendored
Executable file
25
gaia/tv_apps/browser/bower_components/smart-icons/smart-icons-embedded.css
vendored
Executable file
25
gaia/tv_apps/browser/bower_components/smart-icons/smart-icons.css
vendored
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
/* Generated by grunt-webfont */
|
||||
/* Based on https://github.com/endtwist/fontcustom/blob/master/lib/fontcustom/templates/fontcustom.css */
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: "smart-icons";
|
||||
src: url("fonts/smart-icons.ttf") format("truetype");
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
|
||||
[data-icon]:before,
|
||||
.ligature-icons {
|
||||
font-family: "smart-icons";
|
||||
content: attr(data-icon);
|
||||
display: inline-block;
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
text-decoration: inherit;
|
||||
text-transform: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-size: 30px;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
88
gaia/tv_apps/browser/build/build.js
Executable file
|
|
@ -0,0 +1,88 @@
|
|||
'use strict';
|
||||
|
||||
/* jshint node: true */
|
||||
|
||||
var utils = require('utils');
|
||||
var preprocessor = require('preprocessor');
|
||||
|
||||
var BrowserAppBuilder = function() {
|
||||
};
|
||||
|
||||
BrowserAppBuilder.prototype.setOptions = function(options) {
|
||||
this.stageDir = utils.getFile(options.STAGE_APP_DIR);
|
||||
this.appDir = utils.getFile(options.APP_DIR);
|
||||
this.distDirPath = options.GAIA_DISTRIBUTION_DIR;
|
||||
};
|
||||
|
||||
BrowserAppBuilder.prototype.initJSON = function() {
|
||||
var defaultJSONpath =
|
||||
utils.joinPath(this.appDir.path, 'build', 'default.json');
|
||||
var defaultJson = utils.getJSON(utils.getFile(defaultJSONpath));
|
||||
var file =
|
||||
utils.getFile(this.stageDir.path, 'js', 'init.json');
|
||||
utils.writeContent(file,
|
||||
utils.getDistributionFileContent('browser', defaultJson, this.distDirPath));
|
||||
};
|
||||
|
||||
BrowserAppBuilder.prototype.initTopsitesJSON = function() {
|
||||
var defaultJSONpath =
|
||||
utils.joinPath(this.appDir.path, 'build', 'topsites.json');
|
||||
var defaultJson = utils.getJSON(utils.getFile(defaultJSONpath));
|
||||
|
||||
defaultJson.topSites.forEach(function(site) {
|
||||
if (site.iconPath) {
|
||||
var file = utils.getFile(this.appDir.path, 'build', site.iconPath);
|
||||
var icon = utils.getFileAsDataURI(file);
|
||||
site.iconUri = icon;
|
||||
delete site.iconPath;
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
var file =
|
||||
utils.getFile(this.stageDir.path, 'js', 'inittopsites.json');
|
||||
utils.writeContent(file,
|
||||
utils.getDistributionFileContent('topsites', defaultJson,
|
||||
this.distDirPath));
|
||||
};
|
||||
|
||||
BrowserAppBuilder.prototype.enableFirefoxSync = function(options) {
|
||||
var fileList = {
|
||||
process: [
|
||||
['index.html'],
|
||||
['js', 'awesomescreen.js'],
|
||||
['js', 'bookmarkStore.js'],
|
||||
['js', 'historyStore.js'],
|
||||
['js', 'browser_dialog.js'],
|
||||
['js', 'index.js'],
|
||||
['js', 'settings.js'],
|
||||
['js', 'toolbar.js'],
|
||||
['style', 'settings.css'],
|
||||
['style', 'browser_dialog.css']
|
||||
],
|
||||
remove: [
|
||||
['js', 'sync', 'bookmarks.js'],
|
||||
['js', 'sync', 'db.js'],
|
||||
['js', 'sync', 'ds_helper.js'],
|
||||
['js', 'sync', 'history.js'],
|
||||
['js', 'sync', 'manager_bridge.js'],
|
||||
['js', 'sync', 'settings.js'],
|
||||
['js', 'sync', 'toolbar.js'],
|
||||
['test', 'unit', 'sync', 'manager_bridge_test.js'],
|
||||
['test', 'unit', 'sync', 'settings_test.js'],
|
||||
['test', 'unit', 'sync', 'toolbar_test.js']
|
||||
]
|
||||
};
|
||||
preprocessor.execute(options, 'FIREFOX_SYNC', fileList);
|
||||
};
|
||||
|
||||
BrowserAppBuilder.prototype.execute = function(options) {
|
||||
this.setOptions(options);
|
||||
this.initJSON();
|
||||
this.initTopsitesJSON();
|
||||
this.enableFirefoxSync(options);
|
||||
};
|
||||
|
||||
exports.execute = function(options) {
|
||||
utils.copyToStage(options);
|
||||
(new BrowserAppBuilder()).execute(options);
|
||||
};
|
||||
39
gaia/tv_apps/browser/build/default.json
Executable file
BIN
gaia/tv_apps/browser/build/firefox.png
Executable file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
gaia/tv_apps/browser/build/mozilla.png
Executable file
|
After Width: | Height: | Size: 407 B |
14
gaia/tv_apps/browser/build/topsites.json
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"topSites": [
|
||||
{
|
||||
"title": "Mozilla",
|
||||
"uri": "http://mozilla.org",
|
||||
"iconPath": "mozilla.png"
|
||||
},
|
||||
{
|
||||
"title": "Firefox OS",
|
||||
"uri": "http://mozilla.org/firefoxos",
|
||||
"iconPath": "firefox.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
58
gaia/tv_apps/browser/elements/fte.css
Executable file
|
|
@ -0,0 +1,58 @@
|
|||
.fte-container {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.75);
|
||||
text-align: center;
|
||||
z-index: 1000;
|
||||
color: #fff;
|
||||
opacity: 1;
|
||||
transition: opacity 0.5s linear;
|
||||
}
|
||||
|
||||
.fte-container.finish {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.fte-page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.fte-logo {
|
||||
margin: 7.5rem 0 1.5rem 0;
|
||||
}
|
||||
|
||||
.fte-greeting {
|
||||
margin: 1.5rem 0 8rem 0;
|
||||
line-height: 7rem;
|
||||
font-weight: lighter;
|
||||
font-style: italic;
|
||||
font-size: 7rem;
|
||||
}
|
||||
|
||||
.fte-description {
|
||||
width: 110rem;
|
||||
margin: 8rem auto 3.5rem auto;
|
||||
font-weight: lighter;
|
||||
font-style: italic;
|
||||
font-size: 3.8rem;
|
||||
}
|
||||
|
||||
.fte-button-container {
|
||||
position: absolute;
|
||||
bottom: 10.5rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fte-button-container > smart-button {
|
||||
width: 23.7rem;
|
||||
font-size: 2.4rem;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.fte-button-container > smart-button:first-child {
|
||||
margin-right: 1.8rem;
|
||||
}
|
||||
14
gaia/tv_apps/browser/elements/fte.html
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
<template>
|
||||
<div id="fte-container" class="fte-container">
|
||||
<div class="fte-page">
|
||||
<img class="fte-logo" src="../style/images/firefox_logo.png"></img>
|
||||
<h1 class="fte-greeting" data-l10n-id="fte-welcome"></h1>
|
||||
<p class="fte-description" data-l10n-id="fte-description"></p>
|
||||
<img class="fte-diagram" src="../style/images/account_image.png"></img>
|
||||
<div class="fte-button-container">
|
||||
<smart-button id="fte-skip" class="fte-button" type="rounded-corner-text" data-l10n-id="skip" data-behavior="skip"></smart-button>
|
||||
<smart-button id="fte-sign-in" class="fte-button fte-finish primary" type="rounded-corner-text" class="primary" data-l10n-id="login" data-behavior="finish"></smart-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
BIN
gaia/tv_apps/browser/img/key_active.png
Executable file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
gaia/tv_apps/browser/img/scroll_down.cur
Executable file
|
After Width: | Height: | Size: 17 KiB |
BIN
gaia/tv_apps/browser/img/scroll_left.cur
Executable file
|
After Width: | Height: | Size: 17 KiB |
BIN
gaia/tv_apps/browser/img/scroll_right.cur
Executable file
|
After Width: | Height: | Size: 17 KiB |
BIN
gaia/tv_apps/browser/img/scroll_up.cur
Executable file
|
After Width: | Height: | Size: 17 KiB |
828
gaia/tv_apps/browser/index.html
Executable file
|
|
@ -0,0 +1,828 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en-US" dir="ltr">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
|
||||
<meta charset="utf-8">
|
||||
<title>web browser</title>
|
||||
|
||||
<!-- building blocks -->
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/smart-button/style.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/smart-icons/smart-icons.css">
|
||||
|
||||
<!-- Specific style -->
|
||||
<link rel="stylesheet" type="text/css" href="style/components.css">
|
||||
<link rel="stylesheet" type="text/css" href="style/index.css">
|
||||
<link rel="stylesheet" type="text/css" href="style/awesomescreen.css">
|
||||
<link rel="stylesheet" type="text/css" href="style/authentication_dialog.css">
|
||||
<link rel="stylesheet" type="text/css" href="style/browser_dialog.css">
|
||||
<link rel="stylesheet" type="text/css" href="style/toolbar.css">
|
||||
<link rel="stylesheet" type="text/css" href="style/tooltip.css">
|
||||
<link rel="stylesheet" type="text/css" href="style/search_result.css">
|
||||
<link rel="stylesheet" type="text/css" href="style/settings.css">
|
||||
<link rel="stylesheet" type="text/css" href="style/smartList.css">
|
||||
|
||||
<!-- Resources -->
|
||||
<link rel="resource" type="image/png" href="shared/resources/branding/browser_336.png">
|
||||
|
||||
<!-- Localization -->
|
||||
<script defer="" src="/shared/js/l10n.js"></script>
|
||||
|
||||
<!-- L10n properties -->
|
||||
<meta name="defaultLanguage" content="en-US">
|
||||
<meta name="availableLanguages" content="en-US">
|
||||
<!--IFDEF_FIREFOX_SYNC
|
||||
<link rel="localization" href="shared/locales/firefox_sync/firefox_sync.{locale}.properties">
|
||||
ENDIF_FIREFOX_SYNC-->
|
||||
<link rel="localization" href="/locales/browser.{locale}.properties">
|
||||
|
||||
<!-- building blocks -->
|
||||
<script defer src="bower_components/evt/index.js"></script>
|
||||
<script defer src="bower_components/smart-button/script.js"></script>
|
||||
|
||||
<!-- Shared code -->
|
||||
<script defer src="shared/js/url_helper.js"></script>
|
||||
<script defer src="shared/js/utilities.js"></script>
|
||||
<script defer src="shared/js/smart-screen/connection_manager.js"></script>
|
||||
<script defer src="shared/js/lazy_loader.js"></script>
|
||||
<script defer src="shared/js/smart-screen/simple_key_navigation.js"></script>
|
||||
<script defer src="shared/js/smart-screen/f_t_e_wizard.js"></script>
|
||||
|
||||
<!-- Specific code -->
|
||||
<script defer src="js/resource_loader.js"></script>
|
||||
<script defer src="js/browser_db.js"></script>
|
||||
<!--IFDEF_FIREFOX_SYNC
|
||||
<script defer src="js/sync/db.js"></script>
|
||||
ENDIF_FIREFOX_SYNC-->
|
||||
<script defer src="js/index.js"></script>
|
||||
<script defer src="js/awesomescreen.js"></script>
|
||||
<script defer src="js/search_util.js"></script>
|
||||
<script defer src="js/authentication_dialog.js"></script>
|
||||
<script defer src="js/browser_dialog.js"></script>
|
||||
<script defer src="js/toolbar.js"></script>
|
||||
<script defer src="js/tooltip.js"></script>
|
||||
<script defer src="js/search_result.js"></script>
|
||||
<script defer src="js/settings.js"></script>
|
||||
<script defer src="js/connection_handler.js"></script>
|
||||
<script defer src="js/smartList.js"></script>
|
||||
<script defer src="js/bookmarkStore.js"></script>
|
||||
<script defer src="js/historyStore.js"></script>
|
||||
<script defer src="js/fte.js"></script>
|
||||
|
||||
<!-- IAC Handler (put here because it starts sending event immediately) -->
|
||||
<script defer src="shared/js/iac_handler.js"></script>
|
||||
|
||||
<!-- Lazy loaded code -->
|
||||
<!-- <script src="shared/js/settings_listener.js"><script> -->
|
||||
<!-- <script src="shared/js/sync/errors.js"></script> -->
|
||||
<!-- <script src="js/sync/manager_bridge.js"></script> -->
|
||||
<!-- <script src="js/sync/settings.js"></script> -->
|
||||
<!-- <script src="js/sync/toolbar.js"></script> -->
|
||||
<!-- <script src="js/sync/ds_helper.js"></script> -->
|
||||
<!-- <script src="js/sync/bookmarks.js"></script> -->
|
||||
<!-- <script src="js/sync/history.js"></script> -->
|
||||
|
||||
<!-- Lazy loaded Templates -->
|
||||
<!-- <link rel="import" href="elements/fte.html"> -->
|
||||
<!-- <link rel="stylesheet" type="text/css" href="elements/fte.css"> -->
|
||||
|
||||
</head>
|
||||
|
||||
<body class="page_screen start_page" role="application">
|
||||
<!-- mask for menu -->
|
||||
<div id="fade-base"></div>
|
||||
|
||||
<!-- side -->
|
||||
<div id="side-block" class="side-window">
|
||||
<!-- put widget here -->
|
||||
</div>
|
||||
|
||||
<!-- main -->
|
||||
<div id="main-block" data-mode="cursor" class="main-window">
|
||||
<!-- toolbar -->
|
||||
<ul id="toolbar-panel" data-pvt="false">
|
||||
<div id="private-bar"></div>
|
||||
<li id="sidebar-button-block" data-tips="WB_LT_TIPS_CHANGE_SCREEN" data-fade="false">
|
||||
<div id="sidebar-button" data-sidebar="true">
|
||||
<!-- XXX: Replace the SVG to icon font -->
|
||||
<svg id="sidebar-button-svg" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="3 3 47 47" x="0" y="0" preserveAspectRatio="xMidyMid slice">
|
||||
<g id="sidebar-close-svg" visibility="hidden">
|
||||
<g>
|
||||
<path class="sidebar-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231F20" d="M36.899,15.805H18.214c-1.968,0-3.716,2.093-3.716,4.061v14.997
|
||||
c0,1.968,1.747,3.332,3.716,3.332h18.686c1.968,0,3.502-1.364,3.502-3.332V19.866C40.401,17.898,38.867,15.805,36.899,15.805z
|
||||
M37.578,32.739c0,1.583-1.234,2.68-2.817,2.68H20.265c-1.583,0-2.989-1.097-2.989-2.68V21.849c0-1.583,1.406-3.267,2.989-3.267
|
||||
h14.497c1.583,0,2.817,1.684,2.817,3.267V32.739z"></path>
|
||||
<path class="sidebar-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231F20" d="M16.589,22.805h22.4v2.1h-22.4V22.805z"></path>
|
||||
</g>
|
||||
</g>
|
||||
<g id="sidebar-open-svg" visibility="hidden">
|
||||
<path class="sidebar-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231F20" d="M36.45,15.805H17.764c-1.968,0-3.716,2.093-3.716,4.061v14.997
|
||||
c0,1.968,1.747,3.332,3.716,3.332H36.45c1.968,0,3.502-1.364,3.502-3.332V19.866C39.952,17.898,38.418,15.805,36.45,15.805z
|
||||
M37.129,21.849v0.955H23.839v-4.222h10.472C35.895,18.583,37.129,20.266,37.129,21.849z M34.312,35.419H23.839V24.905h13.289
|
||||
v7.834C37.129,34.322,35.895,35.419,34.312,35.419z"></path>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li id="back-button-block" data-tips="WB_LT_TIPS_HISTORY_BACK">
|
||||
<div id="back-button">
|
||||
<!-- XXX: Replace the SVG to icon font -->
|
||||
<svg id="back-button-svg" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="3 3 47 47" x="0" y="0" preserveAspectRatio="xMidyMid meet">
|
||||
<path class="back-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M39.325,24.619H21.352l6.701-6.701
|
||||
c-0.38-1.648-0.861-3.185-1.428-4.584L15.46,24.5c-1.385,1.384-1.385,3.628,0,5.012l11.153,11.154
|
||||
c0.567-1.396,1.048-2.928,1.431-4.57L21.349,29.4h17.976C39.662,27.764,39.661,26.256,39.325,24.619z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</li>
|
||||
<li id="forward-button-block" class="disable" data-tips="WB_LT_TIPS_HISTORY_FORWARD">
|
||||
<div id="forward-button-border">
|
||||
<div id="forward-button">
|
||||
<!-- XXX: Replace the SVG to icon font -->
|
||||
<svg id="forward-button-svg" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="3 3 47 47" x="0" y="0" preserveAspectRatio="xMidyMid meet">
|
||||
<path class="forward-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M38.54,24.5L27.375,13.334
|
||||
c-0.567,1.399-1.048,2.936-1.429,4.584l6.702,6.701H14.675c-0.338,1.637-0.338,3.145,0,4.781h17.976l-6.695,6.695
|
||||
c0.383,1.643,0.863,3.174,1.431,4.57L38.54,29.512C39.925,28.128,39.925,25.883,38.54,24.5z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li id="space-block">
|
||||
<div></div>
|
||||
</li>
|
||||
<li id="addressbar-block">
|
||||
<form id="address-form">
|
||||
<input id="private-icon" value="" type="image">
|
||||
<input id="ssl-indicator" value="" type="image">
|
||||
<input id="url-input" dir="auto" type="text">
|
||||
<div class="input-line"></div>
|
||||
<div id="address-button" data-mode="load" data-tips="WB_LT_TIPS_RELOAD">
|
||||
<!-- XXX: Replace the SVG to icon font -->
|
||||
<svg id="address-button-svg" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="3 3 47 47" x="0" y="0" preserveAspectRatio="xMidyMid meet">
|
||||
<g id="address-reload-svg" visibility="hidden">
|
||||
<g>
|
||||
<g>
|
||||
<path class="address-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M39.701,24.33c-0.953-7.119-7.035-12.616-14.416-12.616
|
||||
c-8.041,0-14.56,6.52-14.56,14.561c0,8.042,6.519,14.56,14.56,14.56c4.022,0,7.663-1.63,10.298-4.266l-2.231-2.231
|
||||
c-2.064,2.065-4.916,3.343-8.067,3.343c-6.299,0-11.405-5.107-11.405-11.405c0-6.299,5.106-11.405,11.405-11.405
|
||||
c5.622,0,10.282,4.071,11.222,9.423c-1.445,0.126-2.765,0.437-3.866,0.883l4.343,4.343c0.539,0.539,1.413,0.539,1.951,0
|
||||
l4.339-4.338C42.251,24.763,41.03,24.472,39.701,24.33z"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="address-stop-svg" visibility="hidden">
|
||||
<g>
|
||||
<g>
|
||||
<polygon class="address-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" points="37.553,19.225 34.776,16.448 26.983,24.241
|
||||
19.207,16.465 16.43,19.242 24.206,27.018 16.448,34.776 19.225,37.553 26.983,29.795 34.758,37.57 37.536,34.793 29.76,27.018
|
||||
"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</form>
|
||||
</li>
|
||||
|
||||
<li id="searchbar-block">
|
||||
<form id="search-form">
|
||||
<input id="search-favicon" value="" type="image">
|
||||
<input id="search-input" data-tips="WB_LT_TIPS_SEARCH_BAR" dir="auto" type="text">
|
||||
<div class="input-line"></div>
|
||||
<div id="search-button">
|
||||
<!-- XXX: Replace the SVG to icon font -->
|
||||
<svg id="search-button-svg" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="3 3 47 47" x="0" y="0" preserveAspectRatio="xMidyMid meet">
|
||||
<path class="search-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M39.774,36.538l-5.462-5.461
|
||||
c1.128-1.731,1.789-3.793,1.789-6.012c0-6.096-4.943-11.036-11.037-11.036c-6.096,0-11.035,4.94-11.035,11.036
|
||||
c0,6.093,4.939,11.036,11.035,11.036c2.218,0,4.278-0.661,6.008-1.787l5.462,5.462c0.455,0.454,1.547,0.098,2.442-0.796
|
||||
C39.87,38.085,40.227,36.992,39.774,36.538z M25.065,32.271c-3.98,0-7.206-3.227-7.206-7.207c0-3.981,3.227-7.208,7.206-7.208
|
||||
c3.981,0,7.207,3.227,7.207,7.208C32.272,29.045,29.046,32.271,25.065,32.271z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div id="search-clear-button"></div>
|
||||
</form>
|
||||
<button id="search-close-button" data-l10n-id="LT_NETWORK_STATUS_BTN_CLOSE">close</button>
|
||||
</li>
|
||||
|
||||
<li id="iconbutton-block">
|
||||
<ul>
|
||||
<li id="bookmark-button-block" data-tips="WB_LT_TIPS_BOOKMARK_THIS_PAGE">
|
||||
<div id="bookmark-button" data-isbookmark="false">
|
||||
<!-- XXX: Replace the SVG to icon font -->
|
||||
<svg id="bookmark-button-svg" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="3 3 47 47" x="0" y="0" preserveAspectRatio="xMidyMid meet">
|
||||
<g id="bookmark-off-svg" visibility="hidden">
|
||||
<g>
|
||||
<g>
|
||||
<path class="bookmark-button-path" fill="#1D1D1B" d="M43.116,22.382l-11.238-1.477L27,10.673l-4.878,10.231l-11.238,1.477l8.224,7.801L17.04,41.327l9.96-5.41
|
||||
l9.96,5.41l-2.068-11.145L43.116,22.382z M27,32.824l-6.404,3.479l1.33-7.165l-5.287-5.016l7.225-0.949L27,16.594l3.136,6.579
|
||||
l7.226,0.949l-5.287,5.016l1.33,7.165L27,32.824z"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="bookmark-on-svg" visibility="hidden">
|
||||
<g>
|
||||
<g>
|
||||
<polygon class="bookmark-button-path" fill="#00caf2" points="43.116,22.382 31.878,20.904 27,10.673 22.122,20.904 10.884,22.382 19.107,30.183 17.04,41.327
|
||||
27,35.917 36.96,41.327 34.893,30.183 "></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</li>
|
||||
<li id="show-bookmarks-button-block" data-tips="WB_LT_TIPS_SHOW_YOUR_BOOKMARK">
|
||||
<div id="show-bookmarks-button">
|
||||
<!-- XXX: Replace the SVG to icon font -->
|
||||
<svg id="show-bookmarks-button-svg" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="3 3 47 47" x="0" y="0" preserveAspectRatio="xMidyMid meet">
|
||||
<path class="show-bookmarks-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M38.551,18.436h-4.794l-5.571-5.406l-5.581,5.406h-5.156
|
||||
c-1.205,0-2.181,0.977-2.181,2.181v18.172c0,1.204,0.976,2.181,2.181,2.181h21.102c1.204,0,2.181-0.977,2.181-2.181V20.617
|
||||
C40.731,19.413,39.755,18.436,38.551,18.436z M21.83,38.06h-4.363v-4.363h4.363V38.06z M21.833,31.521h-4.361v-4.361h4.361
|
||||
V31.521z M21.833,24.978h-4.361v-4.361h4.361V24.978z M23.991,27.159h14.56v4.361h-14.56V27.159z M38.552,38.06H23.999v-4.363
|
||||
h14.553V38.06z M38.542,24.968l-14.538,0.007v-4.356h14.548L38.542,24.968z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</li>
|
||||
<li id="home-button-block" data-tips="WB_LT_TIPS_HOMEPAGE">
|
||||
<div id="home-button">
|
||||
<!-- XXX: Replace the SVG to icon font -->
|
||||
<svg id="home-button-svg" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="3 3 47 47" x="0" y="0" preserveAspectRatio="xMidyMid meet">
|
||||
<path class="home-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M27.557,19.535l-9.028,8.469
|
||||
c-0.001,0.026-0.007,0.05-0.007,0.076v10.34c0,1.119,0.935,2.071,2.088,2.071h4.028c-0.188-0.238-0.305-0.534-0.305-0.86v-7.936
|
||||
c0-0.769,0.623-1.393,1.392-1.393h3.756c0.769,0,1.392,0.624,1.392,1.393v7.936c0,0.326-0.117,0.623-0.305,0.86h4.044
|
||||
c1.153,0,2.088-0.952,2.088-2.071v-10.34c0-0.014-0.004-0.027-0.004-0.041L27.557,19.535z M40.929,25.98L29.117,14.352
|
||||
c-0.815-0.791-2.137-0.791-2.953,0L14.352,25.98c-0.418,0.406-0.618,0.94-0.608,1.472c0.013,0,0.024-0.003,0.037-0.003h2.553
|
||||
l9.863-9.18l-0.035-0.032l0.651-0.541l0.895-0.833l1.373,1.243l-0.033,0.031l9.832,9.312h2.658
|
||||
C41.547,26.919,41.347,26.385,40.929,25.98z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</li>
|
||||
<li id="zoom-button-block" data-tips="WB_LT_TIPS_ZOOM_IN" data-colorbar="red">
|
||||
<div id="zoom-button">
|
||||
<!-- XXX: Replace the SVG to icon font -->
|
||||
<svg id="zoom-button-svg" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="3 3 47 47" x="0" y="0" preserveAspectRatio="xMidyMid meet">
|
||||
<path class="zoom-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M39.982,36.892l-6.505-6.505
|
||||
c1.148-1.698,1.818-3.746,1.818-5.95c0-5.876-4.764-10.64-10.64-10.64c-5.876,0-10.639,4.764-10.639,10.64
|
||||
c0,5.876,4.763,10.64,10.639,10.64c2.074,0,4.003-0.603,5.639-1.629l6.063,6.063c0.005,0.203,0.06,0.379,0.184,0.502
|
||||
c0.438,0.438,1.492,0.095,2.353-0.767c0.755-0.755,1.112-1.657,0.895-2.164L39.982,36.892z M24.656,32.544
|
||||
c-4.478,0-8.107-3.63-8.107-8.107c0-4.477,3.63-8.108,8.107-8.108c4.477,0,8.108,3.631,8.108,8.108
|
||||
C32.765,28.914,29.134,32.544,24.656,32.544z M25.766,19.229h-2.09v4.21h-4.212v2.089h4.212v4.192h2.09v-4.192h4.189V23.44
|
||||
h-4.189V19.229z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</li>
|
||||
<li id="tabs-button-block" data-tips="WB_LT_TIPS_TABS" data-tabs="tab01" data-colorbar="yellow">
|
||||
<div id="tabs-button">
|
||||
<!-- XXX: Replace the SVG to icon font -->
|
||||
<svg id="tabs-button-svg" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="3 3 47 47" x="0" y="0" preserveAspectRatio="xMidyMid meet">
|
||||
<g id="tabs-00-svg" visibility="hidden">
|
||||
<g>
|
||||
<g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M16.515,20.219c0-1.864,1.533-3.718,3.398-3.718h13.679
|
||||
c-0.176-1.671-1.596-2.786-3.341-2.786H16.746c-1.864,0-3.061,1.264-3.061,3.128v13.504c0,1.739,1.162,3.154,2.83,3.339V20.219z"></path>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231815" d="M29.456,24.899c-1.332,0-1.962,1.188-1.962,4.537
|
||||
c0,3.385,0.63,4.573,1.962,4.573c1.333,0,1.963-1.152,1.963-4.573C31.419,26.033,30.789,24.899,29.456,24.899z"></path>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231815" d="M36.813,18.595H22.328c-1.968,0-3.716,2.094-3.716,4.062v14.297
|
||||
c0,1.968,1.748,3.332,3.716,3.332h14.485c1.969,0,3.502-1.364,3.502-3.332V22.656C40.315,20.688,38.782,18.595,36.813,18.595z
|
||||
M29.456,35.757c-2.845,0-4.339-2.27-4.339-6.32c0-4.033,1.495-6.284,4.339-6.284c2.863,0,4.339,2.251,4.339,6.284
|
||||
C33.795,33.487,32.319,35.757,29.456,35.757z"></path>
|
||||
</g>
|
||||
</g>
|
||||
<g id="tabs-01-svg" visibility="hidden">
|
||||
<g>
|
||||
<g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M16.515,20.219c0-1.864,1.533-3.718,3.398-3.718h13.679
|
||||
c-0.176-1.671-1.596-2.786-3.341-2.786H16.746c-1.864,0-3.061,1.264-3.061,3.128v13.504c0,1.739,1.162,3.154,2.83,3.339V20.219z"></path>
|
||||
</g>
|
||||
</g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231815" d="M36.813,18.595H22.328c-1.968,0-3.716,2.094-3.716,4.062v14.297
|
||||
c0,1.968,1.748,3.332,3.716,3.332h14.485c1.969,0,3.502-1.364,3.502-3.332V22.656C40.315,20.688,38.782,18.595,36.813,18.595z
|
||||
M31.806,35.486h-2.269v-9.795l-2.701,1.639l-1.008-1.549l3.943-2.412h2.035V35.486z"></path>
|
||||
</g>
|
||||
<g id="tabs-02-svg" visibility="hidden">
|
||||
<g>
|
||||
<g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M16.515,20.219c0-1.864,1.533-3.718,3.398-3.718h13.679
|
||||
c-0.176-1.671-1.596-2.786-3.341-2.786H16.746c-1.864,0-3.061,1.264-3.061,3.128v13.504c0,1.739,1.162,3.154,2.83,3.339V20.219z"></path>
|
||||
</g>
|
||||
</g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231815" d="M36.813,18.595H22.328c-1.968,0-3.716,2.094-3.716,4.062v14.297
|
||||
c0,1.968,1.748,3.332,3.716,3.332h14.485c1.969,0,3.502-1.364,3.502-3.332V22.656C40.315,20.688,38.782,18.595,36.813,18.595z
|
||||
M33.057,35.486h-7.544v-1.692c4.141-4.214,5.149-5.348,5.149-7.059c0-1.116-0.702-1.765-1.747-1.765
|
||||
c-0.954,0-1.584,0.396-2.323,1.279l-1.422-1.117c0.972-1.26,2.25-1.98,3.925-1.98c2.503,0,3.943,1.513,3.943,3.403
|
||||
c0,2.053-1.17,3.547-4.916,7.112h5.186L33.057,35.486z"></path>
|
||||
</g>
|
||||
<g id="tabs-03-svg" visibility="hidden">
|
||||
<g>
|
||||
<g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M16.515,20.219c0-1.864,1.533-3.718,3.398-3.718h13.679
|
||||
c-0.176-1.671-1.596-2.786-3.341-2.786H16.746c-1.864,0-3.061,1.264-3.061,3.128v13.504c0,1.739,1.162,3.154,2.83,3.339V20.219z"></path>
|
||||
</g>
|
||||
</g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231815" d="M36.813,18.595H22.328c-1.968,0-3.716,2.094-3.716,4.062v14.297
|
||||
c0,1.968,1.748,3.332,3.716,3.332h14.485c1.969,0,3.502-1.364,3.502-3.332V22.656C40.315,20.688,38.782,18.595,36.813,18.595z
|
||||
M28.889,35.757c-1.656,0-2.989-0.612-3.925-1.747l1.314-1.242c0.738,0.828,1.531,1.188,2.485,1.188
|
||||
c1.296,0,2.143-0.774,2.143-2.035c0-1.44-0.81-1.944-2.179-1.944h-0.954l0.27-1.639h0.648c1.135,0,1.945-0.647,1.945-1.836
|
||||
c0-0.99-0.702-1.585-1.783-1.585c-0.936,0-1.674,0.343-2.431,1.062l-1.17-1.278c1.081-1.026,2.341-1.549,3.799-1.549
|
||||
c2.503,0,3.835,1.404,3.835,3.079c0,1.513-0.936,2.467-2.358,2.845c1.512,0.145,2.755,1.08,2.755,2.953
|
||||
C33.282,34.1,31.662,35.757,28.889,35.757z"></path>
|
||||
</g>
|
||||
<g id="tabs-04-svg" visibility="hidden">
|
||||
<g>
|
||||
<g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M16.515,20.219c0-1.864,1.533-3.718,3.398-3.718h13.679
|
||||
c-0.176-1.671-1.596-2.786-3.341-2.786H16.746c-1.864,0-3.062,1.264-3.062,3.128v13.504c0,1.739,1.162,3.154,2.83,3.339V20.219z"></path>
|
||||
</g>
|
||||
</g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231815" d="M36.813,18.595H22.328c-1.968,0-3.716,2.094-3.716,4.062v14.297
|
||||
c0,1.968,1.748,3.332,3.716,3.332h14.485c1.969,0,3.502-1.364,3.502-3.332V22.656C40.315,20.688,38.782,18.595,36.813,18.595z
|
||||
M33.967,32.714h-1.459v2.772h-2.25v-2.772h-5.149v-1.585l3.528-7.994l1.963,0.738l-3.097,7.076h2.772l0.234-3.043h1.998v3.043
|
||||
h1.459V32.714z"></path>
|
||||
</g>
|
||||
<g id="tabs-05-svg" visibility="hidden">
|
||||
<g>
|
||||
<g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M16.515,20.219c0-1.864,1.533-3.718,3.398-3.718h13.679
|
||||
c-0.176-1.671-1.596-2.786-3.341-2.786H16.746c-1.864,0-3.062,1.264-3.062,3.128v13.504c0,1.739,1.162,3.154,2.83,3.339V20.219z"></path>
|
||||
</g>
|
||||
</g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231815" d="M36.813,18.595H22.328c-1.968,0-3.716,2.094-3.716,4.062v14.297
|
||||
c0,1.968,1.748,3.332,3.716,3.332h14.485c1.969,0,3.502-1.364,3.502-3.332V22.656C40.315,20.688,38.782,18.595,36.813,18.595z
|
||||
M28.943,35.757c-1.692,0-2.881-0.685-3.817-1.711l1.332-1.242c0.648,0.756,1.423,1.17,2.431,1.17c1.351,0,2.197-0.864,2.197-2.431
|
||||
c0-1.674-0.828-2.25-1.944-2.25c-0.559,0-1.009,0.126-1.566,0.414h-1.639v-6.338h7.021l-0.27,1.71h-4.537v3.007
|
||||
c0.611-0.306,1.242-0.45,1.836-0.45c2.017,0,3.476,1.44,3.476,3.907C33.463,34.028,31.68,35.757,28.943,35.757z"></path>
|
||||
</g>
|
||||
<g id="tabs-06-svg" visibility="hidden">
|
||||
<g>
|
||||
<g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M16.515,20.219c0-1.864,1.533-3.718,3.397-3.718h13.679
|
||||
c-0.176-1.671-1.596-2.786-3.341-2.786H16.746c-1.864,0-3.061,1.264-3.061,3.128v13.504c0,1.739,1.162,3.154,2.83,3.339V20.219z"></path>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231815" d="M29.861,29.095c-0.828,0-1.584,0.485-2.143,1.242
|
||||
c0.036,2.593,0.595,3.709,1.98,3.709c1.225,0,1.818-1.062,1.818-2.646C31.518,29.671,30.888,29.095,29.861,29.095z"></path>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231815" d="M36.813,18.595H22.328c-1.968,0-3.716,2.094-3.716,4.062v14.297
|
||||
c0,1.968,1.748,3.332,3.716,3.332h14.485c1.969,0,3.502-1.364,3.502-3.332V22.656C40.315,20.688,38.782,18.595,36.813,18.595z
|
||||
M29.699,35.757c-3.097,0-4.375-2.396-4.375-5.87c0-4.051,1.891-6.734,4.97-6.734c1.062,0,1.944,0.307,2.646,0.774l-0.864,1.423
|
||||
c-0.522-0.307-1.099-0.486-1.746-0.486c-1.531,0-2.503,1.458-2.629,3.889c0.773-0.936,1.692-1.332,2.719-1.332
|
||||
c1.891,0,3.421,1.368,3.421,3.943C33.841,33.902,32.148,35.757,29.699,35.757z"></path>
|
||||
</g>
|
||||
</g>
|
||||
<g id="tabs-07-svg" visibility="hidden">
|
||||
<g>
|
||||
<g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M16.515,20.219c0-1.864,1.533-3.718,3.398-3.718h13.679
|
||||
c-0.176-1.671-1.596-2.786-3.341-2.786H16.746c-1.864,0-3.062,1.264-3.062,3.128v13.504c0,1.739,1.162,3.154,2.83,3.339V20.219z"></path>
|
||||
</g>
|
||||
</g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231815" d="M36.813,18.595H22.328c-1.968,0-3.716,2.094-3.716,4.062v14.297
|
||||
c0,1.968,1.748,3.332,3.716,3.332h14.485c1.969,0,3.502-1.364,3.502-3.332V22.656C40.315,20.688,38.782,18.595,36.813,18.595z
|
||||
M33.165,24.989l-4.483,10.731l-2.106-0.685l4.213-9.885h-5.113v-1.782h7.49V24.989z"></path>
|
||||
</g>
|
||||
<g id="tabs-08-svg" visibility="hidden">
|
||||
<g>
|
||||
<g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M16.515,20.219c0-1.864,1.533-3.718,3.398-3.718h13.679
|
||||
c-0.176-1.671-1.596-2.786-3.341-2.786H16.746c-1.864,0-3.061,1.264-3.061,3.128v13.504c0,1.739,1.162,3.154,2.83,3.339V20.219z"></path>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231815" d="M29.366,29.995l-0.558-0.198
|
||||
c-0.972,0.521-1.458,1.296-1.458,2.395c0,1.152,0.829,1.854,2.125,1.854c1.351,0,2.107-0.774,2.107-1.818
|
||||
C31.581,31.093,30.986,30.589,29.366,29.995z"></path>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231815" d="M29.564,28.284l0.342,0.126c0.954-0.594,1.296-1.188,1.296-2.053
|
||||
c0-0.954-0.594-1.584-1.729-1.584c-1.044,0-1.729,0.54-1.729,1.603C27.745,27.402,28.394,27.852,29.564,28.284z"></path>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231815" d="M36.813,18.595H22.328c-1.968,0-3.716,2.094-3.716,4.062v14.297
|
||||
c0,1.968,1.748,3.332,3.716,3.332h14.485c1.969,0,3.502-1.364,3.502-3.332V22.656C40.315,20.688,38.782,18.595,36.813,18.595z
|
||||
M29.42,35.757c-2.719,0-4.394-1.531-4.394-3.493c0-1.477,0.864-2.449,2.305-3.062c-1.296-0.702-1.818-1.674-1.818-2.862
|
||||
c0-1.98,1.801-3.188,3.961-3.188c2.143,0,3.961,1.081,3.961,3.098c0,1.116-0.63,2.034-1.999,2.736
|
||||
c1.656,0.738,2.485,1.801,2.485,3.241C33.921,34.208,32.175,35.757,29.42,35.757z"></path>
|
||||
</g>
|
||||
</g>
|
||||
<g id="tabs-09-svg" visibility="hidden">
|
||||
<g>
|
||||
<g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M16.515,20.219c0-1.864,1.533-3.718,3.398-3.718h13.679
|
||||
c-0.176-1.671-1.596-2.786-3.341-2.786H16.746c-1.864,0-3.061,1.264-3.061,3.128v13.504c0,1.739,1.162,3.154,2.83,3.339V20.219z"></path>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231815" d="M29.411,24.863c-1.17,0-1.908,0.811-1.908,2.358
|
||||
c0,1.656,0.756,2.305,1.729,2.305c0.828,0,1.53-0.45,2.07-1.242C31.337,25.781,30.761,24.863,29.411,24.863z"></path>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231815" d="M36.813,18.595H22.328c-1.968,0-3.716,2.094-3.716,4.062v14.297
|
||||
c0,1.968,1.748,3.332,3.716,3.332h14.485c1.969,0,3.502-1.364,3.502-3.332V22.656C40.315,20.688,38.782,18.595,36.813,18.595z
|
||||
M26.602,35.937l-0.486-1.639c3.025-0.792,4.753-1.963,5.078-4.357c-0.576,0.738-1.422,1.261-2.593,1.261
|
||||
c-1.873,0-3.403-1.494-3.403-3.943c0-2.539,1.873-4.105,4.213-4.105c2.809,0,4.25,1.909,4.25,4.699
|
||||
C33.66,32.84,31.463,34.784,26.602,35.937z"></path>
|
||||
</g>
|
||||
</g>
|
||||
<g id="tabs-10-svg" visibility="hidden">
|
||||
<g>
|
||||
<g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M16.515,20.219c0-1.864,1.533-3.718,3.398-3.718h13.679
|
||||
c-0.176-1.671-1.596-2.786-3.341-2.786H16.746c-1.864,0-3.061,1.264-3.061,3.128v13.504c0,1.739,1.162,3.154,2.83,3.339V20.219z"></path>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231815" d="M33.506,24.899c-1.332,0-1.962,1.188-1.962,4.537
|
||||
c0,3.385,0.63,4.573,1.962,4.573c1.333,0,1.963-1.152,1.963-4.573C35.469,26.033,34.838,24.899,33.506,24.899z"></path>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231815" d="M36.813,18.595H22.328c-1.968,0-3.716,2.094-3.716,4.062v14.297
|
||||
c0,1.968,1.748,3.332,3.716,3.332h14.485c1.969,0,3.502-1.364,3.502-3.332V22.656C40.315,20.688,38.782,18.595,36.813,18.595z
|
||||
M26.648,35.486h-2.269v-9.795l-2.701,1.639l-1.008-1.549l3.943-2.412h2.035V35.486z M33.506,35.757
|
||||
c-2.845,0-4.339-2.27-4.339-6.32c0-4.033,1.495-6.284,4.339-6.284c2.863,0,4.339,2.251,4.339,6.284
|
||||
C37.845,33.487,36.369,35.757,33.506,35.757z"></path>
|
||||
</g>
|
||||
</g>
|
||||
<g id="tabs-11-svg" visibility="hidden">
|
||||
<g>
|
||||
<g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M16.515,20.219c0-1.864,1.533-3.718,3.398-3.718h13.679
|
||||
c-0.176-1.671-1.596-2.786-3.341-2.786H16.746c-1.864,0-3.061,1.264-3.061,3.128v13.504c0,1.739,1.162,3.154,2.83,3.339V20.219z"></path>
|
||||
</g>
|
||||
</g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231815" d="M36.813,18.595H22.328c-1.968,0-3.716,2.094-3.716,4.062v14.297
|
||||
c0,1.968,1.748,3.332,3.716,3.332h14.485c1.969,0,3.502-1.364,3.502-3.332V22.656C40.315,20.688,38.782,18.595,36.813,18.595z
|
||||
M27.755,35.486h-2.269v-9.795l-2.701,1.639l-1.008-1.549l3.943-2.412h2.035V35.486z M35.855,35.486h-2.269v-9.795l-2.701,1.639
|
||||
l-1.008-1.549l3.943-2.412h2.035V35.486z"></path>
|
||||
</g>
|
||||
<g id="tabs-12-svg" visibility="hidden">
|
||||
<g>
|
||||
<g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M16.515,20.219c0-1.864,1.533-3.718,3.398-3.718h13.679
|
||||
c-0.176-1.671-1.596-2.786-3.341-2.786H16.746c-1.864,0-3.062,1.264-3.062,3.128v13.504c0,1.739,1.162,3.154,2.83,3.339V20.219z"></path>
|
||||
</g>
|
||||
</g>
|
||||
<path class="tabs-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#231815" d="M36.813,18.595H22.328c-1.968,0-3.716,2.094-3.716,4.062v14.297
|
||||
c0,1.968,1.748,3.332,3.716,3.332h14.485c1.969,0,3.502-1.364,3.502-3.332V22.656C40.315,20.688,38.782,18.595,36.813,18.595z
|
||||
M27.243,35.486h-2.27v-9.795l-2.7,1.639l-1.009-1.549l3.943-2.412h2.035V35.486z M37.107,35.486h-7.544v-1.692
|
||||
c4.141-4.214,5.149-5.348,5.149-7.059c0-1.116-0.702-1.765-1.747-1.765c-0.954,0-1.584,0.396-2.322,1.279l-1.423-1.117
|
||||
c0.973-1.26,2.251-1.98,3.926-1.98c2.502,0,3.942,1.513,3.942,3.403c0,2.053-1.17,3.547-4.915,7.112h5.186L37.107,35.486z"></path>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</li>
|
||||
<li id="new-tab-button-block" data-tips="WB_LT_TIPS_OPEN_A_NEW_TAB" data-colorbar="blue">
|
||||
<div id="new-tab-button">
|
||||
<!-- XXX: Replace the SVG to icon font -->
|
||||
<svg id="new-tab-button-svg" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="3 3 47 47" x="0" y="0" preserveAspectRatio="xMidyMid meet">
|
||||
<path class="new-tab-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M33.59,16.501c-0.176-1.671-1.595-2.786-3.341-2.786H16.746
|
||||
c-1.864,0-3.061,1.264-3.061,3.128v13.504c0,1.738,1.162,3.154,2.83,3.339V20.219c0-1.864,1.534-3.718,3.398-3.718H33.59z
|
||||
M36.814,18.595H22.328c-1.968,0-3.716,2.094-3.716,4.062v14.297c0,1.968,1.748,3.332,3.716,3.332h14.485
|
||||
c1.968,0,3.502-1.364,3.502-3.332V22.656C40.315,20.688,38.782,18.595,36.814,18.595z M35.394,30.061
|
||||
c0,0.499-0.405,1.127-0.904,1.127h-3.981v4.006c0,0.499-0.602,0.904-1.102,0.904h-0.524c-0.5,0-1.189-0.405-1.189-0.904v-4.006
|
||||
h-4c-0.5,0-0.904-0.628-0.904-1.127v-0.452c0-0.5,0.405-1.232,0.904-1.232h4v-3.982c0-0.5,0.689-0.904,1.189-0.904h0.524
|
||||
c0.5,0,1.102,0.404,1.102,0.904v3.982h3.981c0.5,0,0.904,0.732,0.904,1.232V30.061z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</li>
|
||||
<li id="menu-button-block" data-tips="WB_LT_TIPS_MENU">
|
||||
<div id="menu-button">
|
||||
<!-- XXX: Replace the SVG to icon font -->
|
||||
<svg id="menu-button-svg" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="3 3 47 47" x="0" y="0" preserveAspectRatio="xMidyMid meet">
|
||||
<path class="menu-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M36.783,16.15H17.217c-0.773,0-1.4,0.626-1.4,1.399v1.422
|
||||
c0,0.773,0.627,1.4,1.4,1.4h19.566c0.773,0,1.4-0.627,1.4-1.4V17.55C38.183,16.776,37.557,16.15,36.783,16.15z M36.783,24.594
|
||||
H17.217c-0.773,0-1.4,0.627-1.4,1.4v1.378c0,0.773,0.627,1.399,1.4,1.399h19.566c0.773,0,1.4-0.626,1.4-1.399v-1.378
|
||||
C38.183,25.221,37.557,24.594,36.783,24.594z M36.783,33.672H17.217c-0.773,0-1.4,0.627-1.4,1.4v1.378
|
||||
c0,0.773,0.627,1.399,1.4,1.399h19.566c0.773,0,1.4-0.626,1.4-1.399v-1.378C38.183,34.299,37.557,33.672,36.783,33.672z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<ul id="menu-block">
|
||||
<div>
|
||||
<li id="history-block"><a id="history-tab" href="#" data-l10n-id="LT_SE_HISTORY"></a></li>
|
||||
<li id="pocket-block"><a id="pocket-tab" href="#" data-l10n-id="pocket"></a></li>
|
||||
<li id="private-window-block"><a id="private-window-tab" href="#" data-l10n-id="WB_LT_TIPS_NEW_PRIVATE_WINDOW"></a></li>
|
||||
<!--IFDEF_FIREFOX_SYNC
|
||||
<li id="fxsync-block"><a id="fxsync-tab" href="#" data-l10n-id="fxsync-sign-in-to-sync"></a></li>
|
||||
ENDIF_FIREFOX_SYNC-->
|
||||
<li id="settings-block"><a id="settings-tab" href="#" data-l10n-id="LT_APPS_SETTINGS"></a></li>
|
||||
</div>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- bookmark animation -->
|
||||
<div id="bookmark-button-anime">
|
||||
<!-- XXX: Replace the SVG to icon font -->
|
||||
<svg id="bookmark-button-anime-svg" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 54 54" x="0" y="0" preserveAspectRatio="xMidyMid meet">
|
||||
<polygon class="bookmark-button-path" fill="#00CAF2" points="43.116,22.382 31.878,20.904 27,10.673 22.122,20.904 10.884,22.382 19.107,30.183 17.04,41.327
|
||||
27,35.917 36.96,41.327 34.893,30.183"></polygon>
|
||||
</svg>
|
||||
</div>
|
||||
<div id="show-bookmarks-button-anime">
|
||||
<!-- XXX: Replace the SVG to icon font -->
|
||||
<svg id="show-bookmarks-button-anime-svg" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 54 54" x="0" y="0" preserveAspectRatio="xMidyMid meet">
|
||||
<path class="show-bookmarks-button-path" fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M38.551,18.436h-4.794l-5.571-5.406l-5.581,5.406h-5.156
|
||||
c-1.205,0-2.181,0.977-2.181,2.181v18.172c0,1.204,0.976,2.181,2.181,2.181h21.102c1.204,0,2.181-0.977,2.181-2.181V20.617
|
||||
C40.731,19.413,39.755,18.436,38.551,18.436z M21.83,38.06h-4.363v-4.363h4.363V38.06z M21.833,31.521h-4.361v-4.361h4.361
|
||||
V31.521z M21.833,24.978h-4.361v-4.361h4.361V24.978z M23.991,27.159h14.56v4.361h-14.56V27.159z M38.552,38.06H23.999v-4.363
|
||||
h14.553V38.06z M38.542,24.968l-14.538,0.007v-4.356h14.548L38.542,24.968z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<!-- web -->
|
||||
<div id="web-block">
|
||||
<!--
|
||||
<iframe mozbrowser remote mozasyncpanzoom mozallowfullscreen id="browser_iframe" scrolling="yes"></iframe>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<!-- scroll up down -->
|
||||
<div id="scroll-u"></div>
|
||||
<div id="scroll-d"></div>
|
||||
|
||||
<div id="awesomescreen">
|
||||
<!-- awesomescreen tabview -->
|
||||
<section id="tab-view">
|
||||
<div id="tabview-panels">
|
||||
<ul id="tab-site-list" role="listbox">
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
<section id="top-sites">
|
||||
<div id="top-default-panels">
|
||||
<ul id="top-default-list">
|
||||
<li id="default-top-list-0" class="top-default-item"></li>
|
||||
<li id="default-top-list-1" class="top-default-item"></li>
|
||||
<li id="default-top-list-2" class="top-default-item"></li>
|
||||
<li id="default-top-list-3" class="top-default-item"></li>
|
||||
<li id="default-top-list-4" class="top-default-item"></li>
|
||||
<li id="default-top-list-5" class="top-default-item"></li>
|
||||
<li id="default-top-list-6" class="top-default-item"></li>
|
||||
<li id="default-top-list-7" class="top-default-item"></li>
|
||||
<li id="default-top-list-8" class="top-default-item"></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="top-panels">
|
||||
<ul id="top-site-list" role="listbox"></ul>
|
||||
</div>
|
||||
</section>
|
||||
<!-- awesomescreen bookamrk,history-->
|
||||
<section id="bookmark" tabindex="0"></section>
|
||||
<section id="history" tabindex="0"></section>
|
||||
<!-- private window -->
|
||||
<div id="private-browsing-block">
|
||||
<div id="private-browsing-panel">
|
||||
<!-- image logo -->
|
||||
<div id="private-browsing-img"></div>
|
||||
|
||||
<!-- title -->
|
||||
<h1 id="private-browsing-title" data-l10n-id="WB_LT_SETTINGS_PRIVATE_BROWSING"></h1>
|
||||
<!-- sum title -->
|
||||
<h2 id="private-browsing-subtitle" data-l10n-id="WB_LT_PRIVATE_BROWSING_1"></h2>
|
||||
|
||||
<!-- info -->
|
||||
<p class="private-browsing-text-block private-browsing-text" data-l10n-id="WB_LT_PRIVATE_BROWSING_2"></p>
|
||||
<p class="private-browsing-text-block private-browsing-text" data-l10n-id="WB_LT_PRIVATE_BROWSING_3"></p>
|
||||
|
||||
<!-- more info -->
|
||||
<div id="private-browsing-more-info">
|
||||
<p class="private-browsing-text" data-l10n-id="WB_LT_PRIVATE_BROWSING_4"></p>
|
||||
<a id="private-browsing-more-info-link" class="private-browsing-text" target="_blank" data-l10n-id="WB_LT_LEARN_MORE"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- awesomescreen alert dialog -->
|
||||
<div id="dialog-area">
|
||||
<div id="bmd-dialog">
|
||||
<div id="message-area">
|
||||
<div id="message-title" class="title-area"></div>
|
||||
<div id="bmtitle-area">
|
||||
<input id="input-area" value="" size="30" type="text" required pattern="\s*\S.*">
|
||||
<div class="input-line"></div>
|
||||
<div id="circle-img"></div>
|
||||
</div>
|
||||
<div id="check-area">
|
||||
<div id="cbox-area">
|
||||
<div id="check-box">
|
||||
<div id="check-box-background"></div>
|
||||
<img id="check-img" src="style/images/check-on.svg">
|
||||
</div>
|
||||
<div id="text-area" data-l10n-id="WB_LT_ALSO_PIN_TO_HOME">Also pin to home</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="button-area">
|
||||
<div id="bt-position">
|
||||
<button class="awesomescreen-primary-button none" id="ok-button" data-l10n-id="LT_WB_OK">OK</button>
|
||||
<button class="awesomescreen-default-button none" id="pinhome-button" data-l10n-id="LT_PIN_TO_HOME">Pin to HOME</button>
|
||||
<button class="awesomescreen-default-button none" id="clhistory-button" data-l10n-id="WB_LT_CLEAR_HISTORY">Clear History</button>
|
||||
<button class="awesomescreen-default-button none" id="remove-button" data-l10n-id="WB_LT_CLEAR_BROWSING_HISTORY">Clear All History</button>
|
||||
<button class="awesomescreen-default-button none" id="remove-bookmark-button" data-l10n-id="WB_LT_REMOVE">Remove</button>
|
||||
<button class="awesomescreen-default-button none" id="edit-button" data-l10n-id="LT_CL_EDIT">Edit</button>
|
||||
<button class="awesomescreen-default-button none" id="sethome-button" data-l10n-id="WB_LT_SET_AS_HOMEPAGE">Set as Homepage</button>
|
||||
<button class="awesomescreen-danger-button none" id="remove-topsite-button" data-l10n-id="WB_LT_REMOVE_FROM_TOP_SITES">Remove from Top Sites</button>
|
||||
<button class="awesomescreen-primary-button none" id="rename-confirm-button" data-l10n-id="LT_WB_OK">OK</button>
|
||||
<button class="awesomescreen-danger-button none" id="remove-confirm-button" data-l10n-id="WB_LT_REMOVE">Remove</button>
|
||||
<button class="awesomescreen-danger-button none" id="clear-button" data-l10n-id="WB_LT_CLEAR">Clear</button>
|
||||
<button class="awesomescreen-default-button none" id="cancel-button" data-l10n-id="LT_CANCEL">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="dialog-banner-message"></div>
|
||||
<div id="pointer-img"><img src="style/images/img_cursor_arrow2x.png" width="64" height="64"></div>
|
||||
|
||||
<!-- awesomescreen loading -->
|
||||
<div id="awesome-loading-icon">
|
||||
<div class="awesomecircle awesomecircle-1"></div>
|
||||
<div class="awesomecircle awesomecircle-2"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- authentication -->
|
||||
<section id="http-authentication-dialog" role="region" class="hidden skin-organic">
|
||||
<div id="http-authentication-dialog-wrap">
|
||||
<div id="http-authentication-header">
|
||||
<div id="http-authentication-key"></div>
|
||||
<div id="http-authentication-message"></div>
|
||||
</div>
|
||||
|
||||
<table id="http-authentication-body">
|
||||
<tbody><tr>
|
||||
<td><div class="http-authentication-title" data-l10n-id="LT_FILE_SHARING_DEVICE_USER">User</div></td>
|
||||
<td>
|
||||
<form class="http-authentication-input" id="http-authentication-username">
|
||||
<input class="http-authentication-input-area" id="http-authentication-username-area" dir="auto" type="text">
|
||||
<div class="input-line"></div>
|
||||
<div id="http-authentication-username-clear" class="special-pointer"></div>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div class="http-authentication-title" data-l10n-id="LT_FILE_SHARING_DEVICE_PASSWORD">Password</div></td>
|
||||
<td>
|
||||
<form class="http-authentication-input" id="http-authentication-password">
|
||||
<input class="http-authentication-input-area" id="http-authentication-password-area" type="password">
|
||||
<div class="input-line"></div>
|
||||
<div id="http-authentication-password-clear" class="special-pointer"></div>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
|
||||
<div id="http-authentication-button">
|
||||
<button class="http-authentication-button" id="http-authentication-ok">
|
||||
<span data-l10n-id="LT_WB_OK">OK</span>
|
||||
</button>
|
||||
<button class="http-authentication-button" id="http-authentication-cancel">
|
||||
<span data-l10n-id="LT_CANCEL">Cancel</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- dialog -->
|
||||
<div id="browser-dialog-base" class="hide">
|
||||
<div id="browser-dialog">
|
||||
<div id="browser-dialog-title">
|
||||
<p id="browser-dialog-title-text"></p>
|
||||
</div>
|
||||
<div id="browser-dialog-msg">
|
||||
<p id="browser-dialog-msg-text"></p>
|
||||
</div>
|
||||
<form id="browser-dialog-input">
|
||||
<input id="browser-dialog-input-area">
|
||||
<div class="input-line"></div>
|
||||
<div id="browser-dialog-input-clear"></div>
|
||||
</form>
|
||||
<div id="browser-dialog-margin"></div>
|
||||
<div id="browser-dialog-button">
|
||||
<button class="browser-dialog-button" id="browser-dialog-button2"></button>
|
||||
<button class="browser-dialog-button" id="browser-dialog-button1"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- settings -->
|
||||
<div role="region" id="settings-list" class="skin-organic">
|
||||
<div id="settings-list-area">
|
||||
<div id="settings-header">
|
||||
<p id="settings-header-title" data-l10n-id="WB_LT_BROWSER_SETTINGS">Browser Settings</p>
|
||||
</div>
|
||||
<div id="settings-list-item">
|
||||
<div id="settings-homepage">
|
||||
<p id="settings-homepage-title" data-l10n-id="WB_LT_HOMEPAGE">Homepage</p>
|
||||
<p id="settings-homepage-name"></p>
|
||||
</div>
|
||||
<div id="settings-search-engine">
|
||||
<p id="settings-search-engine-title" data-l10n-id="WB_LT_SETTINGS_SEARCH_ENGINE">Search Engine</p>
|
||||
<p id="settings-search-engine-name"></p>
|
||||
<p id="settings-search-engine-icon"></p>
|
||||
</div>
|
||||
<div id="settings-clear-history">
|
||||
<p id="settings-clear-history-title" data-l10n-id="WB_LT_CLEAR_BROWSING_HISTORY">Clear All History</p>
|
||||
</div>
|
||||
<div id="settings-clear-cookie">
|
||||
<p id="settings-clear-cookie-title" data-l10n-id="WB_LT_CLEAR_STORED_DATA">Clear Cookies and Stored Data</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--IFDEF_FIREFOX_SYNC
|
||||
<div id="fxsync-area">
|
||||
<div id="fxsync-header">
|
||||
<p data-l10n-id="fxsync">Firefox Sync</p>
|
||||
</div>
|
||||
<div id="fxsync-disabled">
|
||||
<smart-button id="fxsync-sign-in-button" type="rounded-corner-text" data-l10n-id="fxsync-sign-in"></smart-button>
|
||||
<p data-l10n-id="fxsync-sign-in-to-sync-description"></p>
|
||||
<p data-l10n-id="fxsync-sign-in-to-sync-description-plus"></p>
|
||||
</div>
|
||||
<div id="fxsync-enabled" hidden>
|
||||
<span id="fxsync-signed-in-as" data-l10n-id="fxsync-signed-in-as"></span>
|
||||
<smart-button id="fxsync-sync-now-button" type="rounded-corner-text" data-l10n-id="fxsync-sync-now"></smart-button>
|
||||
<smart-button id="fxsync-sign-out-button" type="rounded-corner-text" data-l10n-id="fxsync-sign-out"></smart-button>
|
||||
<ul class="settings-horizontal-list">
|
||||
<li class="settings-horizontal-list-item">
|
||||
<input type="checkbox" id="fxsync-collection-bookmarks" class="settings-list-checkbox"></input>
|
||||
<label for="fxsync-collection-bookmarks"></label>
|
||||
<span data-l10n-id="fxsync-collections-bookmarks"></span>
|
||||
</li>
|
||||
<li class="settings-horizontal-list-item">
|
||||
<input type="checkbox" id="fxsync-collection-history" class="settings-list-checkbox"></input>
|
||||
<label for="fxsync-collection-history"></label>
|
||||
<span data-l10n-id="fxsync-collections-history"></span>
|
||||
</li>
|
||||
</ul>
|
||||
<p class="fine-print"><a id="fxsync-tos" data-l10n-id="fxsync-tos"></a></p>
|
||||
<p class="fine-print"><a id="fxsync-privacy" data-l10n-id="fxsync-privacy"></a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
ENDIF_FIREFOX_SYNC-->
|
||||
|
||||
<div id="settings-dialog" class="hidden">
|
||||
<div id="settings-dialog-homepage" class="hidden">
|
||||
<div id="settings-dialog-homepage-header">
|
||||
<p id="settings-dialog-homepage-header-title" data-l10n-id="WB_LT_SET_AS_HOMEPAGE">Set as Homepage</p>
|
||||
</div>
|
||||
<form id="settings-dialog-homepage-input">
|
||||
<input id="settings-dialog-homepage-input-area" value="" type="url">
|
||||
<div class="input-line"></div>
|
||||
<div id="settings-dialog-homepage-clear"></div>
|
||||
</form>
|
||||
<button id="settings-dialog-homepage-default" data-l10n-id="WB_LT_RESTORE_TO_DEFAULT">Restore to default</button>
|
||||
<div id="settings-dialog-homepage-button">
|
||||
<button id="settings-dialog-homepage-cancel" data-l10n-id="LT_CANCEL">Cancel</button>
|
||||
<button id="settings-dialog-homepage-ok" data-l10n-id="LT_WB_OK">OK</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="settings-dialog-search" class="hidden">
|
||||
<div id="settings-dialog-search-header">
|
||||
<p id="settings-dialog-search-header-title" data-l10n-id="WB_LT_SETTINGS_SEARCH_ENGINE">Search Engine</p>
|
||||
</div>
|
||||
<div id="settings-dialog-search-select">
|
||||
<div id="settings-dialog-search-select-list"></div>
|
||||
</div>
|
||||
<div id="settings-dialog-search-button">
|
||||
<button id="settings-dialog-search-cancel" data-l10n-id="LT_CANCEL">Cancel</button>
|
||||
<button id="settings-dialog-search-ok" data-l10n-id="LT_WB_OK">OK</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="settings-banner-message"></div>
|
||||
</div>
|
||||
|
||||
<!-- loading -->
|
||||
<gaia-loading id="loading-icon">
|
||||
<div class="circle circle-1"></div>
|
||||
<div class="circle circle-2"></div>
|
||||
</gaia-loading>
|
||||
|
||||
<!-- zoom banner -->
|
||||
<div id="zoom-banner-message-block">
|
||||
<div id="zoom-banner-message"></div>
|
||||
</div>
|
||||
|
||||
<!-- pan cursor mode button -->
|
||||
<div id="mode-button-block" data-mode="cursor" data-tips="WB_LT_PRESS_COLOR_KEY">
|
||||
<div id="mode-button-panel">
|
||||
<button id="pan-cursor-button"></button>
|
||||
<h2 id="mode-button-title" data-l10n-id="WB_LT_CURSOR_MODE">Cursor Mode</h2>
|
||||
<div id="pan-cursor-button-block" data-colorbar=""></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="pan-cursor-banner-message" data-l10n-id="WB_LT_SWITCH_PAN_MODE">You have switched to Pan Mode</div>
|
||||
|
||||
<!-- search result -->
|
||||
<div id="search-result">
|
||||
<div id="search-result-list"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="block-r"></div>
|
||||
<div id="block-l"></div>
|
||||
<div id="block-d"></div>
|
||||
<!-- scroll left right -->
|
||||
<div id="scroll-l"></div>
|
||||
<div id="scroll-r"></div>
|
||||
|
||||
<!-- Tooltip -->
|
||||
<div id="tooltip-block"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
412
gaia/tv_apps/browser/js/authentication_dialog.js
Executable file
|
|
@ -0,0 +1,412 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
|
||||
'use strict';
|
||||
|
||||
/* exported AuthenticationDialog */
|
||||
|
||||
/**
|
||||
* Handles mozbrowserusernameandpasswordrequired event and show
|
||||
* authentication dialog.
|
||||
* @namespace AuthenticationDialog
|
||||
*/
|
||||
var AuthenticationDialog = {
|
||||
|
||||
_confirmed: {},
|
||||
focusElement: [],
|
||||
focusIndex: {x:0, y:0},
|
||||
|
||||
/** Get all DOM elements when inited. */
|
||||
getAllElements: function ad_getAllElements() {
|
||||
|
||||
var toCamelCase = function toCamelCase(str) {
|
||||
return str.replace(/\-(.)/g, function replacer(str, p1) {
|
||||
return p1.toUpperCase();
|
||||
});
|
||||
};
|
||||
|
||||
var elementIDs = [
|
||||
'http-authentication-dialog',
|
||||
'http-authentication-username', 'http-authentication-username-clear',
|
||||
'http-authentication-password', 'http-authentication-password-clear',
|
||||
'http-authentication-username-area', 'http-authentication-password-area',
|
||||
'http-authentication-message',
|
||||
'http-authentication-ok', 'http-authentication-cancel'];
|
||||
|
||||
// Loop and add element with camel style name to Modal Dialog attribute.
|
||||
elementIDs.forEach(function createElementRef(name) {
|
||||
this[toCamelCase(name)] = document.getElementById(name);
|
||||
}, this);
|
||||
},
|
||||
|
||||
currentEvents: {},
|
||||
|
||||
/** Initialization. Get elements and add listeners. */
|
||||
init: function ad_init(bindToWindow) {
|
||||
// Get all elements initially.
|
||||
this.getAllElements();
|
||||
|
||||
this.boundToWindow = bindToWindow || false;
|
||||
|
||||
this.httpAuthenticationUsername.addEventListener('submit',
|
||||
this.dialogInputSubmit.bind(this));
|
||||
this.httpAuthenticationPassword.addEventListener('submit',
|
||||
this.dialogInputSubmit.bind(this));
|
||||
|
||||
this.httpAuthenticationUsernameArea.addEventListener('blur',
|
||||
this.dialogInputAreaBlur.bind(this));
|
||||
this.httpAuthenticationPasswordArea.addEventListener('blur',
|
||||
this.dialogInputAreaBlur.bind(this));
|
||||
|
||||
this.httpAuthenticationUsernameArea.addEventListener('focus',
|
||||
this.dialogUsernameAreaFocus.bind(this));
|
||||
this.httpAuthenticationPasswordArea.addEventListener('focus',
|
||||
this.dialogPasswordAreaFocus.bind(this));
|
||||
|
||||
this.httpAuthenticationUsernameClear.addEventListener('mouseup',
|
||||
this.clearUsername.bind(this));
|
||||
this.httpAuthenticationUsernameClear.addEventListener('keyup',
|
||||
this.dialogButtonKeyup.bind(this));
|
||||
this.httpAuthenticationUsernameClear.tabIndex = 0;
|
||||
|
||||
this.httpAuthenticationPasswordClear.addEventListener('mouseup',
|
||||
this.clearPassword.bind(this));
|
||||
this.httpAuthenticationPasswordClear.addEventListener('keyup',
|
||||
this.dialogButtonKeyup.bind(this));
|
||||
this.httpAuthenticationPasswordClear.tabIndex = 0;
|
||||
|
||||
this.httpAuthenticationOk.addEventListener('mouseup', this);
|
||||
this.httpAuthenticationOk.addEventListener('keyup',
|
||||
this.dialogButtonKeyup.bind(this));
|
||||
this.httpAuthenticationOk.tabIndex = 0;
|
||||
|
||||
this.httpAuthenticationCancel.addEventListener('mouseup', this);
|
||||
this.httpAuthenticationCancel.addEventListener('keyup',
|
||||
this.dialogButtonKeyup.bind(this));
|
||||
this.httpAuthenticationCancel.tabIndex = 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Default event handler for mozbrowser event and click event.
|
||||
* @param {Event} evt
|
||||
* @param {String} origin Tab ID
|
||||
*/
|
||||
handleEvent: function ad_handleEvent(evt, origin) {
|
||||
switch (evt.type) {
|
||||
case 'mozbrowserusernameandpasswordrequired':
|
||||
evt.preventDefault();
|
||||
this.currentEvents[origin] = evt;
|
||||
|
||||
// Show authentication dialog only if
|
||||
// the frame is currently displayed.
|
||||
this.show(origin);
|
||||
break;
|
||||
|
||||
case 'mouseup':
|
||||
if (evt.currentTarget === this.httpAuthenticationCancel) {
|
||||
this.focusIndex.x = 2;
|
||||
this.focusIndex.y = 1;
|
||||
this.cancelHandler();
|
||||
} else {
|
||||
this.focusIndex.x = 2;
|
||||
this.focusIndex.y = 0;
|
||||
this.confirmHandler();
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Show dialog and set message.
|
||||
* @param {String} origin Tab ID
|
||||
*/
|
||||
show: function ad_show(origin) {
|
||||
this.currentOrigin = origin;
|
||||
var evt = this.currentEvents[origin];
|
||||
|
||||
this.httpAuthenticationDialog.classList.remove('hidden');
|
||||
|
||||
// XXX: We don't have a better way to detect login failed.
|
||||
if (this._confirmed[origin]) {
|
||||
//this.httpAuthenticationMessage.setAttribute('data-l10n-id',
|
||||
//'the-username-or-password-is-incorrect');
|
||||
//this.httpAuthenticationMessage.classList.add('error');
|
||||
} else {
|
||||
navigator.mozL10n.setAttributes(
|
||||
this.httpAuthenticationMessage,
|
||||
'WB_LT_AUTH_MESSAGE',
|
||||
{
|
||||
host: evt.detail.host,
|
||||
msg: evt.detail.realm
|
||||
}
|
||||
);
|
||||
/*
|
||||
navigator.mozL10n.setAttributes(this.httpAuthenticationMessage,
|
||||
'http-authentication-message',
|
||||
{ host: evt.detail.host });
|
||||
*/
|
||||
this.httpAuthenticationMessage.classList.remove('error');
|
||||
}
|
||||
|
||||
Browser.switchCursorMode(false);
|
||||
this.httpAuthenticationUsername.classList.remove('exfocus');
|
||||
this.httpAuthenticationPassword.classList.remove('exfocus');
|
||||
this.httpAuthenticationUsername.classList.remove('input');
|
||||
this.httpAuthenticationPassword.classList.remove('input');
|
||||
|
||||
this.httpAuthenticationUsernameArea.value = '';
|
||||
this.httpAuthenticationPasswordArea.value = '';
|
||||
this.httpAuthenticationUsernameArea.focus();
|
||||
|
||||
this.focusElement[0] = [];
|
||||
this.focusElement[0][0] = this.httpAuthenticationUsernameArea;
|
||||
this.focusElement[0][1] = this.httpAuthenticationUsernameClear;
|
||||
this.focusElement[1] = [];
|
||||
this.focusElement[1][0] = this.httpAuthenticationPasswordArea;
|
||||
this.focusElement[1][1] = this.httpAuthenticationPasswordClear;
|
||||
this.focusElement[2] = [];
|
||||
this.focusElement[2][0] = this.httpAuthenticationOk;
|
||||
this.focusElement[2][1] = this.httpAuthenticationCancel;
|
||||
this.focusIndex.x = 0;
|
||||
this.focusIndex.y = 0;
|
||||
},
|
||||
|
||||
/** Hide authentication dialog. */
|
||||
hide: function ad_hide() {
|
||||
var evt = this.currentEvents[this.currentOrigin];
|
||||
if (!evt) {
|
||||
return;
|
||||
}
|
||||
this.httpAuthenticationDialog.classList.add('hidden');
|
||||
this.currentOrigin = null;
|
||||
},
|
||||
|
||||
clearUsername: function ad_clearUsername() {
|
||||
this.focusIndex.x = 0;
|
||||
this.focusIndex.y = 1;
|
||||
this.httpAuthenticationUsernameArea.value = '';
|
||||
},
|
||||
|
||||
clearPassword: function ad_clearPassword() {
|
||||
this.focusIndex.x = 1;
|
||||
this.focusIndex.y = 1;
|
||||
this.httpAuthenticationPasswordArea.value = '';
|
||||
},
|
||||
|
||||
dialogButtonKeyup: function ad_dialogButtonKeyup(evt) {
|
||||
if( evt ) evt.preventDefault();
|
||||
switch( evt.keyCode ) {
|
||||
case KeyEvent.DOM_VK_RETURN :
|
||||
var elm = document.activeElement;
|
||||
elm.classList.remove('active');
|
||||
var dEvt = document.createEvent("MouseEvents");
|
||||
dEvt.initMouseEvent("mouseup", true, true, window, 0, 0, 0, 0, 0,
|
||||
false, false, false, false, 0, elm);
|
||||
elm.dispatchEvent( dEvt );
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
dialogInputSubmit: function ad_dialogInputSubmit(evt) {
|
||||
if( evt ) evt.preventDefault();
|
||||
this.dialogInputAreaBlur(evt);
|
||||
},
|
||||
|
||||
dialogInputAreaBlur: function ad_dialogInputBlur(evt) {
|
||||
if(Awesomescreen.pointerImg.style.display == 'none') {
|
||||
Browser.switchCursorMode(true);
|
||||
Browser.switchCursorMode(false);
|
||||
}
|
||||
if (evt.currentTarget === this.httpAuthenticationUsernameArea) {
|
||||
this.focusIndex.x = 0;
|
||||
this.focusIndex.y = 0;
|
||||
this.httpAuthenticationUsername.classList.remove('input');
|
||||
this.httpAuthenticationUsername.classList.add('exfocus');
|
||||
} else if(evt.currentTarget === this.httpAuthenticationPasswordArea) {
|
||||
this.focusIndex.x = 1;
|
||||
this.focusIndex.y = 0;
|
||||
this.httpAuthenticationPassword.classList.remove('input');
|
||||
this.httpAuthenticationPassword.classList.add('exfocus');
|
||||
}
|
||||
Awesomescreen.focusImgFunc(this.focusElement[this.focusIndex.x][this.focusIndex.y]);
|
||||
},
|
||||
|
||||
dialogUsernameAreaFocus: function ad_dialogUsernameAreaFocus(evt) {
|
||||
if( evt ) evt.preventDefault();
|
||||
this.httpAuthenticationUsername.classList.add('input');
|
||||
this.httpAuthenticationUsername.classList.remove('exfocus');
|
||||
},
|
||||
|
||||
dialogPasswordAreaFocus: function ad_dialogPasswordAreaFocus(evt) {
|
||||
if( evt ) evt.preventDefault();
|
||||
this.httpAuthenticationPassword.classList.add('input');
|
||||
this.httpAuthenticationPassword.classList.remove('exfocus');
|
||||
},
|
||||
|
||||
/**
|
||||
* When user clicks OK button on authentication dialog,
|
||||
* authenticate user.
|
||||
*/
|
||||
confirmHandler: function ad_confirmHandler() {
|
||||
var evt = this.currentEvents[this.currentOrigin];
|
||||
evt.detail.authenticate(this.httpAuthenticationUsernameArea.value,
|
||||
this.httpAuthenticationPasswordArea.value);
|
||||
this.httpAuthenticationUsername.classList.remove('exfocus');
|
||||
this.httpAuthenticationPassword.classList.remove('exfocus');
|
||||
this.httpAuthenticationDialog.classList.add('hidden');
|
||||
|
||||
// To remember we had ever logged in.
|
||||
this._confirmed[this.currentOrigin] = true;
|
||||
|
||||
delete this.currentEvents[this.currentOrigin];
|
||||
Browser.switchCursorMode(true);
|
||||
Awesomescreen.pointerImg.style.display = 'none';
|
||||
},
|
||||
|
||||
/**
|
||||
* When user clicks cancel button on authentication dialog or
|
||||
* when the user try to escape the dialog with the escape key,
|
||||
* cancel authentication.
|
||||
*/
|
||||
cancelHandler: function ad_cancelHandler() {
|
||||
var evt = this.currentEvents[this.currentOrigin];
|
||||
|
||||
evt.detail.cancel();
|
||||
|
||||
if (this._confirmed[this.currentOrigin]) {
|
||||
delete this._confirmed[this.currentOrigin];
|
||||
}
|
||||
|
||||
delete this.currentEvents[this.currentOrigin];
|
||||
this.httpAuthenticationUsername.classList.remove('exfocus');
|
||||
this.httpAuthenticationPassword.classList.remove('exfocus');
|
||||
this.httpAuthenticationDialog.classList.add('hidden');
|
||||
Browser.switchCursorMode(true);
|
||||
Awesomescreen.pointerImg.style.display = 'none';
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the specified tab currently has any event.
|
||||
* @param {String} origin Tab ID
|
||||
*/
|
||||
originHasEvent: function(origin) {
|
||||
return origin in this.currentEvents;
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear events of the specified tab ID.
|
||||
* @param {String} origin Tab ID
|
||||
*/
|
||||
clear: function ad_clear(origin) {
|
||||
if (this.currentEvents[origin]) {
|
||||
delete this.currentEvents[origin];
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Authentication dialog displays a confirmation.
|
||||
*/
|
||||
isDisplayed: function is_displayed() {
|
||||
return !this.httpAuthenticationDialog.classList.contains('hidden');
|
||||
},
|
||||
|
||||
moveFocus: function ad_moveFocus(xd, yd) {
|
||||
if(xd < 0 || yd < 0) {
|
||||
return;
|
||||
}
|
||||
if( (!this.focusElement[xd]) || (!this.focusElement[xd][yd]) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var opt = null;
|
||||
var flg = false;
|
||||
this.focusIndex.x = xd;
|
||||
this.focusIndex.y = yd;
|
||||
if(Awesomescreen.pointerImg.style.display == 'none') {
|
||||
Browser.switchCursorMode(true);
|
||||
Browser.switchCursorMode(false);
|
||||
flg = true;
|
||||
}
|
||||
document.activeElement.blur();
|
||||
if(this.focusElement[this.focusIndex.x][this.focusIndex.y].id == 'http-authentication-username-area') {
|
||||
this.httpAuthenticationPassword.classList.remove('exfocus');
|
||||
if( !this.httpAuthenticationUsername.classList.contains('exfocus') ) {
|
||||
this.httpAuthenticationUsername.classList.add('exfocus');
|
||||
}
|
||||
} else if(this.focusElement[this.focusIndex.x][this.focusIndex.y].id == 'http-authentication-username-clear') {
|
||||
this.focusElement[this.focusIndex.x][this.focusIndex.y].focus();
|
||||
this.httpAuthenticationPassword.classList.remove('exfocus');
|
||||
if( !this.httpAuthenticationUsername.classList.contains('exfocus') ) {
|
||||
this.httpAuthenticationUsername.classList.add('exfocus');
|
||||
}
|
||||
if( flg ) opt = Awesomescreen.DEFAULT_EXCLEAR;
|
||||
} else if(this.focusElement[this.focusIndex.x][this.focusIndex.y].id == 'http-authentication-password-area') {
|
||||
this.httpAuthenticationUsername.classList.remove('exfocus');
|
||||
if( !this.httpAuthenticationPassword.classList.contains('exfocus') ) {
|
||||
this.httpAuthenticationPassword.classList.add('exfocus');
|
||||
}
|
||||
} else if(this.focusElement[this.focusIndex.x][this.focusIndex.y].id == 'http-authentication-password-clear') {
|
||||
this.httpAuthenticationUsername.classList.remove('exfocus');
|
||||
this.focusElement[this.focusIndex.x][this.focusIndex.y].focus();
|
||||
if( !this.httpAuthenticationPassword.classList.contains('exfocus') ) {
|
||||
this.httpAuthenticationPassword.classList.add('exfocus');
|
||||
}
|
||||
if( flg ) opt = Awesomescreen.DEFAULT_EXCLEAR;
|
||||
} else {
|
||||
this.focusElement[this.focusIndex.x][this.focusIndex.y].focus();
|
||||
this.httpAuthenticationUsername.classList.remove('exfocus');
|
||||
this.httpAuthenticationPassword.classList.remove('exfocus');
|
||||
}
|
||||
Awesomescreen.focusImgFunc(this.focusElement[this.focusIndex.x][this.focusIndex.y], opt);
|
||||
},
|
||||
|
||||
handleKeyEvent: function ad_handleKeyEvent(evt) {
|
||||
if( !this.isDisplayed() ) return false;
|
||||
if( document.activeElement.nodeName == 'INPUT' ) {
|
||||
return true;
|
||||
}
|
||||
switch( evt.keyCode ) {
|
||||
case KeyEvent.DOM_VK_LEFT :
|
||||
evt.preventDefault();
|
||||
this.moveFocus(this.focusIndex.x, this.focusIndex.y-1);
|
||||
break;
|
||||
case KeyEvent.DOM_VK_RIGHT :
|
||||
evt.preventDefault();
|
||||
this.moveFocus(this.focusIndex.x, this.focusIndex.y+1);
|
||||
break;
|
||||
case KeyEvent.DOM_VK_UP :
|
||||
evt.preventDefault();
|
||||
if( this.focusIndex.x == 2 ) {
|
||||
this.moveFocus(this.focusIndex.x-1, 0);
|
||||
} else {
|
||||
this.moveFocus(this.focusIndex.x-1, this.focusIndex.y);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.DOM_VK_DOWN :
|
||||
evt.preventDefault();
|
||||
if( this.focusIndex.x == 1 ) {
|
||||
this.moveFocus(this.focusIndex.x+1, 0);
|
||||
} else {
|
||||
this.moveFocus(this.focusIndex.x+1, this.focusIndex.y);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.DOM_VK_RETURN :
|
||||
evt.preventDefault();
|
||||
if((this.focusIndex.x == 0 && this.focusIndex.y == 0) ||
|
||||
(this.focusIndex.x == 1 && this.focusIndex.y == 0)) {
|
||||
this.focusElement[this.focusIndex.x][this.focusIndex.y].focus();
|
||||
Awesomescreen.pointerImg.style.display = 'none';
|
||||
} else {
|
||||
document.activeElement.classList.remove('active');
|
||||
document.activeElement.classList.add('active');
|
||||
}
|
||||
break;
|
||||
case KeyEvent.DOM_VK_BACK_SPACE :
|
||||
this.cancelHandler();
|
||||
return true;
|
||||
default :
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
3216
gaia/tv_apps/browser/js/awesomescreen.js
Executable file
239
gaia/tv_apps/browser/js/bookmarkStore.js
Executable file
|
|
@ -0,0 +1,239 @@
|
|||
/* globals BrowserDB, SyncBrowserDB, SyncManagerBridge */
|
||||
'use strict';
|
||||
|
||||
(function(exports){
|
||||
|
||||
//IFDEF_FIREFOX_SYNC
|
||||
/**
|
||||
* The root folder id of synced bookmark data.
|
||||
* @type {String}
|
||||
*/
|
||||
const SYNC_BOOKMARK_ROOT_FOLDER_ID = 'places';
|
||||
/**
|
||||
* The mobile folder id of synced bookmark data.
|
||||
* @type {String}
|
||||
*/
|
||||
const SYNC_BOOKMARK_MOBILE_FOLDER_ID = 'mobile';
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
|
||||
// TODO: for the live time bookmark data loading task.
|
||||
var BookmarkStore = {
|
||||
isSynced: false,
|
||||
|
||||
cache: [],
|
||||
|
||||
currentFolder : null,
|
||||
|
||||
//IFDEF_FIREFOX_SYNC
|
||||
syncBookmarkRootFolderCache: {
|
||||
id: SYNC_BOOKMARK_ROOT_FOLDER_ID,
|
||||
title: '',
|
||||
type: 'folder',
|
||||
readOnly: true
|
||||
},
|
||||
|
||||
syncBookmarkMobileFolderCache: {
|
||||
id: SYNC_BOOKMARK_MOBILE_FOLDER_ID,
|
||||
title: '',
|
||||
type: 'folder',
|
||||
readOnly: true
|
||||
},
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
|
||||
init: function () {
|
||||
|
||||
//IFDEF_FIREFOX_SYNC
|
||||
var l10nPromises = [];
|
||||
l10nPromises
|
||||
.push(navigator.mozL10n.formatValue('fxsync-desktop-bookmarks'));
|
||||
l10nPromises
|
||||
.push(navigator.mozL10n.formatValue('fxsync-mobile-bookmarks'));
|
||||
Promise.all(l10nPromises).then(
|
||||
([l10nFxsyncDesktopBookmarks, l10nFxsyncMobileBookmarks]) => {
|
||||
this.syncBookmarkRootFolderCache.title = l10nFxsyncDesktopBookmarks;
|
||||
this.syncBookmarkMobileFolderCache.title = l10nFxsyncMobileBookmarks;
|
||||
}
|
||||
);
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
|
||||
},
|
||||
|
||||
reset: function(cb) {
|
||||
this.cache = [];
|
||||
this.currentFolder = null;
|
||||
|
||||
return new Promise(resolve => {
|
||||
|
||||
//IFNDEF_FIREFOX_SYNC
|
||||
resolve();
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
|
||||
//IFDEF_FIREFOX_SYNC
|
||||
SyncManagerBridge.getInfo().then(message => {
|
||||
if (message.state === 'enabled' || message.state === 'syncing') {
|
||||
this.isSynced = true;
|
||||
} else {
|
||||
this.isSynced = false;
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
getByRange: function(start, num, folderId, cb) {
|
||||
var self = this;
|
||||
function getCaches(){
|
||||
var length = (start + num) > self.cache.length ?
|
||||
(self.cache.length - start) : (start + num);
|
||||
var result = [];
|
||||
|
||||
for(var i = start; i < length; i++) {
|
||||
result.push(self.cache[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if(folderId !== this.currentFolder) {
|
||||
this.currentFolder = folderId;
|
||||
this.updateCache().then(() => {
|
||||
cb(getCaches());
|
||||
});
|
||||
} else {
|
||||
cb(getCaches());
|
||||
}
|
||||
},
|
||||
|
||||
getByIndex: function(index, folderId, cb) {
|
||||
var self = this;
|
||||
function getCache(){
|
||||
var result = null;
|
||||
if(index >= 0 && index < self.cache.length) {
|
||||
result = self.cache[index];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if(folderId !== this.currentFolder) {
|
||||
this.currentFolder = folderId;
|
||||
this.updateCache().then(() => {
|
||||
cb(getCache());
|
||||
});
|
||||
} else {
|
||||
cb(getCache());
|
||||
}
|
||||
},
|
||||
|
||||
//IFDEF_FIREFOX_SYNC
|
||||
_createRootFolderCache: function () {
|
||||
var self = this;
|
||||
// We query remote bookmarks by parentid with
|
||||
// SYNC_BOOKMARK_ROOT_FOLDER_ID for checking if the indexedDB has
|
||||
// remote bookmark data. If there is any remote data, we create a
|
||||
// folder item to show the synced bookmark.
|
||||
function getPlacesBookmarks() {
|
||||
return new Promise(resolve => {
|
||||
SyncBrowserDB.getBookmark({
|
||||
parentid: SYNC_BOOKMARK_ROOT_FOLDER_ID
|
||||
}, syncPlacesBookmarks => {
|
||||
if(syncPlacesBookmarks.length > 0) {
|
||||
self.cache.push(self.syncBookmarkRootFolderCache);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// If there is mobile folder and also has children in it,
|
||||
// create a folder item to show the synced mobile bookmark
|
||||
function getMobileBookmarks() {
|
||||
return new Promise(resolve => {
|
||||
SyncBrowserDB.getBookmark({
|
||||
parentid: SYNC_BOOKMARK_MOBILE_FOLDER_ID
|
||||
}, syncMobileBookmarks => {
|
||||
if(syncMobileBookmarks.length > 0) {
|
||||
self.cache.push(self.syncBookmarkMobileFolderCache);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// get bookmark data from origin indexdDB
|
||||
function getLocalBookmarks() {
|
||||
return new Promise(resolve => {
|
||||
BrowserDB.getBookmarks(localBookmarks => {
|
||||
if(localBookmarks.length > 0) {
|
||||
self.cache = self.cache.concat(localBookmarks);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return getPlacesBookmarks()
|
||||
.then(getMobileBookmarks)
|
||||
.then(getLocalBookmarks);
|
||||
},
|
||||
|
||||
_updateFolderCache: function () {
|
||||
return new Promise(resolve => {
|
||||
SyncBrowserDB.getBookmark({
|
||||
parentid: this.currentFolder
|
||||
}, syncBookmark => {
|
||||
var length = syncBookmark.length,
|
||||
bookmark = null;
|
||||
for(var i = 0; i < length; i++) {
|
||||
bookmark = syncBookmark[i];
|
||||
//hide mobile folder in sync bookmark folder
|
||||
if(this.currentFolder === SYNC_BOOKMARK_ROOT_FOLDER_ID &&
|
||||
bookmark.id === SYNC_BOOKMARK_MOBILE_FOLDER_ID) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// XXX: Now we only support two types: folder and bookmark.
|
||||
// And the data from firefox sync can't be modified.
|
||||
if(bookmark.type === 'folder' && bookmark.title) {
|
||||
bookmark.readOnly = true;
|
||||
this.cache.push(bookmark);
|
||||
} else if (bookmark.type === 'bookmark') {
|
||||
bookmark.uri = bookmark.bmkUri;
|
||||
bookmark.readOnly = true;
|
||||
this.cache.push(bookmark);
|
||||
}
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
|
||||
updateCache: function(){
|
||||
this.cache = [];
|
||||
return new Promise(resolve => {
|
||||
if(!this.isSynced) {
|
||||
// Get bookmark data from origin indexedDB
|
||||
BrowserDB.getBookmarks(bookmarks => {
|
||||
this.cache = bookmarks;
|
||||
resolve();
|
||||
});
|
||||
} else {
|
||||
//IFNDEF_FIREFOX_SYNC
|
||||
resolve();
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
|
||||
//IFDEF_FIREFOX_SYNC
|
||||
if(!this.currentFolder) {
|
||||
this._createRootFolderCache().then(resolve);
|
||||
} else {
|
||||
this._updateFolderCache().then(resolve);
|
||||
}
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
exports.BookmarkStore = BookmarkStore;
|
||||
})(window);
|
||||
2030
gaia/tv_apps/browser/js/browser_db.js
Executable file
607
gaia/tv_apps/browser/js/browser_dialog.js
Executable file
|
|
@ -0,0 +1,607 @@
|
|||
/* global Awesomescreen */
|
||||
/* global Browser */
|
||||
/* global BrowserDB */
|
||||
/* global KeyEvent */
|
||||
/* global Settings */
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* The dialog listen to mozbrowsershowmodalprompt event.
|
||||
* (alert/confirm/prompt)
|
||||
*
|
||||
* @namespace Dialog
|
||||
*/
|
||||
var BrowserDialog = {
|
||||
// Dialog Event
|
||||
dialogEvt: null,
|
||||
browserDialogInputArea: null,
|
||||
PORT_MIN: 0,
|
||||
PORT_MAX: 65535,
|
||||
focusElement: [],
|
||||
focusIndex: {x:0, y:0},
|
||||
defaultFocusIndex: {x:0, y:0},
|
||||
deferredActions: new Map(),
|
||||
|
||||
/** Get all elements when inited. */
|
||||
getAllElements: function dialog_getAllElements() {
|
||||
var toCamelCase = function toCamelCase(str) {
|
||||
return str.replace(/\-(.)/g, function replacer(str, p1) {
|
||||
return p1.toUpperCase();
|
||||
});
|
||||
};
|
||||
|
||||
var elementIDs = [
|
||||
'browser-dialog-base', 'browser-dialog',
|
||||
'browser-dialog-title', 'browser-dialog-msg',
|
||||
'browser-dialog-input',
|
||||
'browser-dialog-input-area',
|
||||
'browser-dialog-input-clear',
|
||||
'browser-dialog-button',
|
||||
'browser-dialog-button1', 'browser-dialog-button2',
|
||||
];
|
||||
|
||||
// Loop and add element with camel style name to Dialog attribute.
|
||||
elementIDs.forEach(function createElementRef(name) {
|
||||
this[toCamelCase(name)] = document.getElementById(name);
|
||||
}, this);
|
||||
},
|
||||
|
||||
/** Initialization. Get DOM elements and add listeners. */
|
||||
init: function dialog_init() {
|
||||
// Get all elements initially.
|
||||
this.getAllElements();
|
||||
|
||||
this.browserDialogBase.addEventListener('mouseup',
|
||||
this.dialogBaseClick.bind(this));
|
||||
|
||||
// Add event listener(dialog)
|
||||
this.browserDialogButton1.addEventListener('mouseup',
|
||||
this.dialogButton1.bind(this));
|
||||
this.browserDialogButton1.addEventListener('keyup',
|
||||
this.dialogButtonKeyup.bind(this));
|
||||
|
||||
this.browserDialogButton2.addEventListener('mouseup',
|
||||
this.dialogButton2.bind(this));
|
||||
this.browserDialogButton2.addEventListener('keyup',
|
||||
this.dialogButtonKeyup.bind(this));
|
||||
|
||||
this.browserDialogInput.addEventListener('submit',
|
||||
this.dialogInput.bind(this));
|
||||
this.browserDialogInputClear.addEventListener('mouseup',
|
||||
this.dialogInputClear.bind(this));
|
||||
this.browserDialogInputClear.addEventListener('keyup',
|
||||
this.dialogButtonKeyup.bind(this));
|
||||
|
||||
this.browserDialogInputArea.addEventListener('blur',
|
||||
this.dialogInputAreaBlur.bind(this));
|
||||
this.browserDialogInputArea.addEventListener('focus',
|
||||
this.dialogInputAreaFocus.bind(this));
|
||||
this.browserDialogInputArea.addEventListener('mousedown',
|
||||
this.dialogInputAreaClick.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* create Dialog
|
||||
*/
|
||||
createDialog: function dialog_createDialog(type, evt) {
|
||||
var opt;
|
||||
|
||||
this.cancelDialog();
|
||||
if( evt != null ) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
this.dialogEvt = evt;
|
||||
this.browserDialogBase.classList.remove('hide');
|
||||
this.browserDialogBase.dataset.type = type;
|
||||
|
||||
var promise;
|
||||
switch(type) {
|
||||
case 'del_cookie':
|
||||
opt = {
|
||||
title: null,
|
||||
msg: 'WB_LT_CONFIRM_DELETE_COOKIES',
|
||||
bt1: 'LT_CANCEL',
|
||||
bt2: 'WB_LT_CLEAR'
|
||||
};
|
||||
break;
|
||||
|
||||
case 'clear_history':
|
||||
opt = {
|
||||
title: null,
|
||||
msg: 'WB_LT_CLEAR_ALL_HISTORY',
|
||||
bt1: 'LT_CANCEL',
|
||||
bt2: 'WB_LT_CLEAR'
|
||||
};
|
||||
break;
|
||||
|
||||
case 'max_bookmark':
|
||||
opt = {
|
||||
title: null,
|
||||
msg: 'WB_LT_BOOKMARK_ERROR_1',
|
||||
bt1: 'LT_CANCEL',
|
||||
bt2: null
|
||||
};
|
||||
break;
|
||||
|
||||
case 'alert':
|
||||
opt = {
|
||||
title: null,
|
||||
msg: {raw: evt.detail.message},
|
||||
bt1: 'LT_WB_OK',
|
||||
bt2: null
|
||||
};
|
||||
break;
|
||||
|
||||
case 'prompt':
|
||||
opt = {
|
||||
title: null,
|
||||
msg: {raw: evt.detail.message},
|
||||
bt1: 'LT_CANCEL',
|
||||
bt2: 'LT_WB_OK'
|
||||
};
|
||||
break;
|
||||
|
||||
case 'confirm':
|
||||
opt = {
|
||||
title: null,
|
||||
msg: {raw: evt.detail.message},
|
||||
bt1: 'LT_CANCEL',
|
||||
bt2: 'LT_WB_OK'
|
||||
};
|
||||
break;
|
||||
|
||||
//IFDEF_FIREFOX_SYNC
|
||||
case 'signout_confirm':
|
||||
opt = {
|
||||
title: 'fxsync-confirm-sign-out-title',
|
||||
msg: 'fxsync-confirm-sign-out-message',
|
||||
bt1: 'LT_CANCEL',
|
||||
bt2: 'fxsync-sign-out'
|
||||
};
|
||||
var deferred = {};
|
||||
deferred.promise = new Promise(function(resolve, reject) {
|
||||
deferred.resolve = resolve;
|
||||
deferred.reject = reject;
|
||||
});
|
||||
promise = deferred.promise;
|
||||
this.deferredActions.set('signout_confirm', deferred);
|
||||
break;
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
Browser.switchCursorMode(false);
|
||||
|
||||
// title
|
||||
if (opt.title) {
|
||||
this.browserDialogTitle.setAttribute('data-l10n-id', opt.title);
|
||||
} else {
|
||||
this.browserDialogTitle.removeAttribute('data-l10n-id');
|
||||
this.browserDialogTitle.textContent = '';
|
||||
}
|
||||
|
||||
// msg
|
||||
if(opt.msg) {
|
||||
if (typeof opt.msg === 'string') {
|
||||
this.browserDialogMsg.setAttribute('data-l10n-id', opt.msg);
|
||||
} else if (opt.msg.hasOwnProperty('raw')) {
|
||||
this.browserDialogMsg.innerHTML = opt.msg.raw.replace(/\\n/g, '<br>');
|
||||
}
|
||||
} else {
|
||||
this.browserDialogMsg.removeAttribute('data-l10n-id');
|
||||
this.browserDialogMsg.textContent = '';
|
||||
}
|
||||
|
||||
var countIndex = 0;
|
||||
this.focusElement = [];
|
||||
this.focusElement[0] = [];
|
||||
this.focusElement[1] = [];
|
||||
this.defaultFocusIndex = {x:0, y:0};
|
||||
// button1
|
||||
if(opt.bt1) {
|
||||
this.browserDialogButton1.blur();
|
||||
this.browserDialogButton1.setAttribute('data-l10n-id', opt.bt1);
|
||||
this.browserDialogButton1.dataset.type = type;
|
||||
this.browserDialogButton1.classList.add('visible');
|
||||
}
|
||||
|
||||
// button2
|
||||
if(opt.bt2) {
|
||||
this.browserDialogButton2.blur();
|
||||
this.browserDialogButton2.setAttribute('data-l10n-id', opt.bt2);
|
||||
this.browserDialogButton2.dataset.type = type;
|
||||
this.browserDialogButton2.classList.add('visible');
|
||||
}
|
||||
|
||||
var width = Browser.SCREEN_WIDTH;
|
||||
if( Browser.sideBlock.dataset.sidebar == 'true' ) {
|
||||
width -= Browser.SIDE_WINDOW_WIDTH;
|
||||
}
|
||||
|
||||
if(type == 'prompt') {
|
||||
this.browserDialogInput.style.display = 'block';
|
||||
this.browserDialogInput.classList.remove('exfocus');
|
||||
this.browserDialogInput.classList.remove('input');
|
||||
this.browserDialogInputClear.tabIndex = 0;
|
||||
countIndex = 0;
|
||||
this.focusElement[1][countIndex++] = this.browserDialogInputArea;
|
||||
this.focusElement[1][countIndex++] = this.browserDialogInputClear;
|
||||
//this.browserDialogInput.insertBefore(this.browserDialogInputArea,
|
||||
// this.browserDialogInputClear);
|
||||
this.browserDialogInputArea.type = 'text';
|
||||
this.browserDialogInputArea.value = '';
|
||||
} else {
|
||||
this.browserDialogInput.style.display = 'none';
|
||||
}
|
||||
|
||||
// initialize position
|
||||
countIndex = 0;
|
||||
if(opt.bt1 && opt.bt2) {
|
||||
this.defaultFocusIndex.x = 0;
|
||||
this.defaultFocusIndex.y = 0;
|
||||
this.focusIndex.x = 0;
|
||||
|
||||
//IFDEF_FIREFOX_SYNC
|
||||
if(type === 'signout_confirm') {
|
||||
this.focusIndex.y = 0;
|
||||
this.focusElement[0][countIndex++] = this.browserDialogButton1;
|
||||
this.focusElement[0][countIndex++] = this.browserDialogButton2;
|
||||
} else {
|
||||
this.focusIndex.y = 1;
|
||||
this.focusElement[0][countIndex++] = this.browserDialogButton2;
|
||||
this.focusElement[0][countIndex++] = this.browserDialogButton1;
|
||||
}
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
|
||||
//IFNDEF_FIREFOX_SYNC
|
||||
this.focusIndex.y = 1;
|
||||
this.focusElement[0][countIndex++] = this.browserDialogButton2;
|
||||
this.focusElement[0][countIndex++] = this.browserDialogButton1;
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
} else if(opt.bt1) {
|
||||
this.defaultFocusIndex.x = 0;
|
||||
this.defaultFocusIndex.y = 0;
|
||||
this.focusIndex.x = 0;
|
||||
this.focusIndex.y = 0;
|
||||
this.focusElement[0][countIndex++] = this.browserDialogButton1;
|
||||
}
|
||||
Awesomescreen.focusImgFunc(
|
||||
this.focusElement[this.focusIndex.x][this.focusIndex.y]);
|
||||
this.focusElement[this.focusIndex.x][this.focusIndex.y].focus();
|
||||
return promise;
|
||||
},
|
||||
|
||||
isDisplayed: function dialog_isDisplayed() {
|
||||
return !this.browserDialogBase.classList.contains('hide');
|
||||
},
|
||||
|
||||
dialogBaseClick: function dialog_dialogBaseClick(evt) {
|
||||
if( evt ) {
|
||||
evt.stopPropagation();
|
||||
}
|
||||
},
|
||||
|
||||
dialogButtonKeyup: function dialog_dialogButton1Keyup(evt) {
|
||||
if( evt ) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
switch( evt.keyCode ) {
|
||||
case KeyEvent.DOM_VK_RETURN :
|
||||
var elm = document.activeElement;
|
||||
elm.classList.remove('active');
|
||||
var dEvt = document.createEvent('MouseEvents');
|
||||
dEvt.initMouseEvent('mouseup', true, true, window, 0, 0, 0, 0, 0,
|
||||
false, false, false, false, 0, elm);
|
||||
elm.dispatchEvent( dEvt );
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
completeDeferredAction: function(type, resolution) {
|
||||
if (!this.deferredActions.has(type)) {
|
||||
return;
|
||||
}
|
||||
this.deferredActions.get(type)[resolution]();
|
||||
this.deferredActions.delete(type);
|
||||
},
|
||||
|
||||
dialogButton1: function dialog_dialogButton1(evt) {
|
||||
if (evt) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
|
||||
var type = this.browserDialogButton1.dataset.type;
|
||||
|
||||
switch(type) {
|
||||
case 'del_cookie':
|
||||
case 'clear_history':
|
||||
case 'max_bookmark':
|
||||
case 'alert':
|
||||
case 'prompt':
|
||||
case 'confirm':
|
||||
case 'signout_confirm':
|
||||
this.dialogButton2End(evt.currentTarget);
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
this.completeDeferredAction(type, 'reject');
|
||||
},
|
||||
|
||||
dialogButton2End: function dialog_dialogButton2End(target) {
|
||||
// Animation end event
|
||||
var end_event = (function() {
|
||||
target.removeEventListener('transitionend', end_event, false);
|
||||
BrowserDialog.cancelDialog();
|
||||
});
|
||||
target.addEventListener('transitionend', end_event, false);
|
||||
},
|
||||
|
||||
dialogButton2: function dialog_dialogButton2(evt) {
|
||||
if (evt) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
|
||||
this.argEvt = evt.currentTarget;
|
||||
var type = this.browserDialogButton2.dataset.type;
|
||||
switch (type) {
|
||||
case 'del_cookie':
|
||||
var request = navigator.mozApps.getSelf();
|
||||
request.onsuccess = function() {
|
||||
var rtn = request.result.clearBrowserData();
|
||||
rtn.onsuccess = function() {
|
||||
//BrowserDialog.cancelDialog();
|
||||
BrowserDialog.dialogButton2End(BrowserDialog.argEvt);
|
||||
};
|
||||
rtn.onerror = function() {
|
||||
//BrowserDialog.cancelDialog();
|
||||
BrowserDialog.dialogButton2End(BrowserDialog.argEvt);
|
||||
Settings.clearCookieFailed();
|
||||
};
|
||||
};
|
||||
request.onerror = function() {
|
||||
//BrowserDialog.cancelDialog();
|
||||
BrowserDialog.dialogButton2End(BrowserDialog.argEvt);
|
||||
Settings.clearCookieFailed();
|
||||
};
|
||||
break;
|
||||
|
||||
case 'clear_history':
|
||||
//BrowserDB.clearHistory(this.cancelDialog.bind(this));
|
||||
BrowserDB.clearHistory(
|
||||
function(){
|
||||
BrowserDialog.dialogButton2End(BrowserDialog.argEvt);
|
||||
}.bind(this));
|
||||
Awesomescreen.selectTopSites();
|
||||
break;
|
||||
|
||||
case 'prompt':
|
||||
if (this.dialogEvt != null) {
|
||||
this.dialogEvt.detail.returnValue = this.browserDialogInputArea.value;
|
||||
if (this.dialogEvt.detail.unblock) {
|
||||
this.dialogEvt.detail.unblock();
|
||||
}
|
||||
this.dialogEvt = null;
|
||||
}
|
||||
//this.cancelDialog();
|
||||
this.dialogButton2End(this.argEvt);
|
||||
break;
|
||||
|
||||
case 'confirm':
|
||||
if (this.dialogEvt != null) {
|
||||
this.dialogEvt.detail.returnValue = true;
|
||||
if (this.dialogEvt.detail.unblock) {
|
||||
this.dialogEvt.detail.unblock();
|
||||
}
|
||||
this.dialogEvt = null;
|
||||
}
|
||||
//this.cancelDialog();
|
||||
this.dialogButton2End(this.argEvt);
|
||||
break;
|
||||
|
||||
case 'signout_confirm':
|
||||
BrowserDialog.dialogButton2End(BrowserDialog.argEvt);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
this.completeDeferredAction(type, 'resolve');
|
||||
},
|
||||
|
||||
dialogInput: function dialog_dialogInput(evt) {
|
||||
if( evt ) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
this.browserDialogInputArea.blur();
|
||||
},
|
||||
|
||||
dialogInputAreaFocus: function dialog_dialogInputAreaFocus(evt) {
|
||||
if( evt ) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
this.browserDialogInput.classList.add('input');
|
||||
this.browserDialogInput.classList.remove('exfocus');
|
||||
},
|
||||
|
||||
dialogInputClear: function dialog_dialogInputClear() {
|
||||
this.browserDialogInputArea.value = '';
|
||||
},
|
||||
|
||||
dialogInputAreaKeydown: function dialog_dialogInputKeydown(evt) {
|
||||
if( evt ) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
switch( evt.keyCode ) {
|
||||
case KeyEvent.DOM_VK_RETURN :
|
||||
this.moveFocus(this.focusIndex.x+1, 0);
|
||||
break;
|
||||
}
|
||||
},
|
||||
dialogInputAreaClick: function dialog_dialogInputAreaClick(evt) {
|
||||
Browser.switchCursorMode(true);
|
||||
Browser.switchCursorMode(false);
|
||||
|
||||
this.dialogInputAreaFocus();
|
||||
|
||||
this.focusIndex.x = 1;
|
||||
this.focusIndex.y = 0;
|
||||
this.focusElement[this.focusIndex.x][this.focusIndex.y].focus();
|
||||
Awesomescreen.pointerImg.style.display = 'none';
|
||||
},
|
||||
dialogInputAreaBlur: function dialog_dialogInputBlur() {
|
||||
if(Awesomescreen.pointerImg.style.display == 'none') {
|
||||
Browser.switchCursorMode(true);
|
||||
Browser.switchCursorMode(false);
|
||||
}
|
||||
BrowserDialog.browserDialogInput.classList.remove('input');
|
||||
BrowserDialog.browserDialogInput.classList.add('exfocus');
|
||||
var self = this;
|
||||
setTimeout( function() {
|
||||
self.focusIndex.x = 1;
|
||||
self.focusIndex.y = 0;
|
||||
Awesomescreen.focusImgFunc(self.browserDialogInputArea);
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
/**
|
||||
* cancel confirm dialog
|
||||
*/
|
||||
cancelDialog: function dialog_cancelDialog() {
|
||||
if( !BrowserDialog.isDisplayed() ) {
|
||||
return;
|
||||
}
|
||||
switch( BrowserDialog.browserDialogButton1.dataset.type ) {
|
||||
case 'alert':
|
||||
case 'prompt':
|
||||
if( BrowserDialog.dialogEvt != null ) {
|
||||
BrowserDialog.dialogEvt.detail.returnValue = null;
|
||||
if( BrowserDialog.dialogEvt.detail.unblock ) {
|
||||
BrowserDialog.dialogEvt.detail.unblock();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'confirm':
|
||||
if( BrowserDialog.dialogEvt != null ) {
|
||||
BrowserDialog.dialogEvt.detail.returnValue = false;
|
||||
if( BrowserDialog.dialogEvt.detail.unblock ) {
|
||||
BrowserDialog.dialogEvt.detail.unblock();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if( BrowserDialog.dialogEvt != null ) {
|
||||
BrowserDialog.dialogEvt = null;
|
||||
}
|
||||
// hide dialog
|
||||
if( BrowserDialog.browserDialogInputArea ) {
|
||||
BrowserDialog.browserDialogInput.classList.remove('exfocus');
|
||||
BrowserDialog.browserDialogInput.classList.remove('input');
|
||||
}
|
||||
BrowserDialog.browserDialogBase.classList.add('hide');
|
||||
BrowserDialog.browserDialogButton1.classList.remove('visible');
|
||||
BrowserDialog.browserDialogButton2.classList.remove('visible');
|
||||
Browser.switchCursorMode(true);
|
||||
Awesomescreen.pointerImg.style.display = 'none';
|
||||
},
|
||||
|
||||
moveFocus: function dialog_moveFocus(xd, yd) {
|
||||
if(!this.focusElement[xd]) {
|
||||
return;
|
||||
}
|
||||
if(( xd < 0 || yd < 0 ) || ( !this.focusElement[xd][yd] )) {
|
||||
if(( !this.browserDialogButton2.classList.contains('visible') ) &&
|
||||
( Awesomescreen.pointerImg.style.display !== 'block' )) {
|
||||
Browser.switchCursorMode(true);
|
||||
Browser.switchCursorMode(false);
|
||||
var x = this.defaultFocusIndex.x;
|
||||
var y = this.defaultFocusIndex.y;
|
||||
this.focusIndex.x = x;
|
||||
this.focusIndex.y = y;
|
||||
Awesomescreen.focusImgFunc(this.focusElement[x][y]);
|
||||
this.focusElement[x][y].focus();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this.focusIndex.x = xd;
|
||||
this.focusIndex.y = yd;
|
||||
var opt = null;
|
||||
var flg = false;
|
||||
if(Awesomescreen.pointerImg.style.display == 'none') {
|
||||
Browser.switchCursorMode(true);
|
||||
Browser.switchCursorMode(false);
|
||||
flg = true;
|
||||
}
|
||||
document.activeElement.blur();
|
||||
Awesomescreen.focusImgFunc(
|
||||
this.focusElement[this.focusIndex.x][this.focusIndex.y], opt);
|
||||
if(this.focusElement[this.focusIndex.x][this.focusIndex.y].nodeName ==
|
||||
'INPUT') {
|
||||
if( !this.browserDialogInput.classList.contains('exfocus') ) {
|
||||
this.browserDialogInput.classList.add('exfocus');
|
||||
}
|
||||
} else if(this.focusElement[this.focusIndex.x][this.focusIndex.y].id ==
|
||||
'browser-dialog-input-clear') {
|
||||
this.focusElement[this.focusIndex.x][this.focusIndex.y].focus();
|
||||
if( !this.browserDialogInput.classList.contains('exfocus') ) {
|
||||
this.browserDialogInput.classList.add('exfocus');
|
||||
}
|
||||
if( flg ) {
|
||||
opt = Awesomescreen.DEFAULT_EXCLEAR;
|
||||
}
|
||||
} else {
|
||||
this.focusElement[this.focusIndex.x][this.focusIndex.y].focus();
|
||||
this.browserDialogInput.classList.remove('exfocus');
|
||||
}
|
||||
},
|
||||
|
||||
handleKeyEvent: function dialog_handleKeyEvent(evt) {
|
||||
if( !BrowserDialog.isDisplayed() ) {
|
||||
return false;
|
||||
}
|
||||
if( document.activeElement.nodeName == 'INPUT' ) {
|
||||
return true;
|
||||
}
|
||||
switch( evt.keyCode ) {
|
||||
case KeyEvent.DOM_VK_LEFT :
|
||||
evt.preventDefault();
|
||||
this.moveFocus(this.focusIndex.x, this.focusIndex.y-1);
|
||||
break;
|
||||
case KeyEvent.DOM_VK_RIGHT :
|
||||
evt.preventDefault();
|
||||
this.moveFocus(this.focusIndex.x, this.focusIndex.y+1);
|
||||
break;
|
||||
case KeyEvent.DOM_VK_UP :
|
||||
evt.preventDefault();
|
||||
this.moveFocus(this.focusIndex.x+1, 0);
|
||||
break;
|
||||
case KeyEvent.DOM_VK_DOWN :
|
||||
evt.preventDefault();
|
||||
this.moveFocus(this.focusIndex.x-1, this.defaultFocusIndex.y);
|
||||
break;
|
||||
case KeyEvent.DOM_VK_RETURN :
|
||||
evt.preventDefault();
|
||||
if(this.focusIndex.x === 1 && this.focusIndex.y === 0) {
|
||||
this.focusElement[this.focusIndex.x][this.focusIndex.y].focus();
|
||||
Awesomescreen.pointerImg.style.display = 'none';
|
||||
} else {
|
||||
document.activeElement.classList.remove('active');
|
||||
document.activeElement.classList.add('active');
|
||||
}
|
||||
break;
|
||||
case KeyEvent.DOM_VK_BACK_SPACE :
|
||||
BrowserDialog.cancelDialog();
|
||||
return true;
|
||||
default :
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
77
gaia/tv_apps/browser/js/connection_handler.js
Executable file
|
|
@ -0,0 +1,77 @@
|
|||
/* global ConnectionManager, ConnectionHandler, Browser,
|
||||
UrlHelper, Awesomescreen */
|
||||
'use strict';
|
||||
(function(exports) {
|
||||
var ConnectionHandler = function() {};
|
||||
|
||||
ConnectionHandler.prototype = {
|
||||
_active: false,
|
||||
_messageQueue: [],
|
||||
|
||||
init: function() {
|
||||
this._connectionManager = new ConnectionManager();
|
||||
this._connectionManager.init(['iac-webpage-open']);
|
||||
this._connectionManager.on('view', this.preHandleMessage.bind(this));
|
||||
},
|
||||
|
||||
preHandleMessage: function(detail) {
|
||||
if (this._active) {
|
||||
this._digestMessage();
|
||||
this.openPage(detail.url);
|
||||
} else {
|
||||
this._messageQueue.push(detail);
|
||||
}
|
||||
},
|
||||
|
||||
_digestMessage: function() {
|
||||
if (this._messageQueue.length !== 0) {
|
||||
this._messageQueue.forEach(function(detail){
|
||||
this.openPage(detail.url);
|
||||
}.bind(this));
|
||||
this._messageQueue = [];
|
||||
}
|
||||
},
|
||||
|
||||
openPage: function(url) {
|
||||
url = Browser.getUrlFromInput(url);
|
||||
if (Browser.currentInfo && Browser.currentInfo.url &&
|
||||
UrlHelper.isURL(Browser.currentInfo.url)) {
|
||||
var ev = {
|
||||
detail: {
|
||||
url: url,
|
||||
frameElement: null
|
||||
}
|
||||
};
|
||||
Awesomescreen.openNewTab(ev);
|
||||
} else {
|
||||
Browser.navigate(url);
|
||||
}
|
||||
this.bringToFront();
|
||||
},
|
||||
|
||||
bringToFront: function() {
|
||||
if (document.visibilityState === 'hidden') {
|
||||
navigator.mozApps.getSelf().onsuccess = function(evt) {
|
||||
var app = evt.target.result;
|
||||
if (app) {
|
||||
app.launch();
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
activate: function() {
|
||||
this._active = true;
|
||||
this._digestMessage();
|
||||
},
|
||||
|
||||
pause: function() {
|
||||
this._active = false;
|
||||
},
|
||||
};
|
||||
|
||||
exports.ConnectionHandler = ConnectionHandler;
|
||||
}(window));
|
||||
|
||||
var connectionHandler = new ConnectionHandler();
|
||||
connectionHandler.init();
|
||||
76
gaia/tv_apps/browser/js/fte.js
Executable file
|
|
@ -0,0 +1,76 @@
|
|||
/* 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 Browser */
|
||||
/* global FTEWizard */
|
||||
/* global ResourceLoader */
|
||||
/* global SyncManagerBridge */
|
||||
|
||||
// XXX: If Firefox sign in is available outside of the browser app, we'll have
|
||||
// to remove or redesign FTE.
|
||||
|
||||
'use strict';
|
||||
|
||||
(function (exports) {
|
||||
|
||||
if (localStorage.getItem('browserFTE.fteskip')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var FTE = {
|
||||
|
||||
fteContainer: null,
|
||||
|
||||
fteWizard: null,
|
||||
|
||||
onuninit: function () {},
|
||||
|
||||
init(options) {
|
||||
this.onuninit = options.onuninit;
|
||||
|
||||
ResourceLoader.loadByName('fte')
|
||||
.then(node => {
|
||||
document.body.appendChild(node);
|
||||
|
||||
this.fteContainer = document.getElementById('fte-container');
|
||||
|
||||
this.fteWizard = new FTEWizard('browserFTE');
|
||||
this.fteWizard.init({
|
||||
container: this.fteContainer,
|
||||
propagateKeyEvent: true,
|
||||
onfinish: () => {
|
||||
SyncManagerBridge.enable();
|
||||
this.uninit();
|
||||
},
|
||||
onskip: () => {
|
||||
this.uninit();
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('visibilitychange', this);
|
||||
});
|
||||
},
|
||||
|
||||
handleEvent() {
|
||||
if (!document.hidden) {
|
||||
this.fteWizard.focus();
|
||||
}
|
||||
},
|
||||
|
||||
uninit() {
|
||||
document.body.removeChild(this.fteContainer);
|
||||
document.removeEventListener('visibilitychange', this);
|
||||
ResourceLoader.unloadByName('fte');
|
||||
this.onuninit();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
exports.FTE = FTE;
|
||||
exports.FTE.init({onuninit: () => {
|
||||
Browser.switchCursorMode(true);
|
||||
delete exports.FTE;
|
||||
}});
|
||||
|
||||
})(window);
|
||||
338
gaia/tv_apps/browser/js/historyStore.js
Executable file
|
|
@ -0,0 +1,338 @@
|
|||
/* globals BrowserDB, SyncBrowserDB, SyncManagerBridge */
|
||||
'use strict';
|
||||
|
||||
(function(exports){
|
||||
|
||||
const INITIAL_HISTORY_COUNT = 21;
|
||||
|
||||
const DAY_IN_MILLI_SECOND = 86400000;
|
||||
|
||||
// TODO: for the live time history data loading task.
|
||||
var HistoryStore = {
|
||||
isSynced: false,
|
||||
|
||||
cache: new Map(),
|
||||
|
||||
cacheIndexStartAt: 0,
|
||||
|
||||
cacheIndexEndAt: 0,
|
||||
|
||||
lastDataIndex: null,
|
||||
|
||||
currentFolder: null,
|
||||
|
||||
isHandlingCache: false,
|
||||
|
||||
cacheEventQueue: [],
|
||||
|
||||
reset: function (cb) {
|
||||
return new Promise(resolve => {
|
||||
this.cache.clear();
|
||||
this.cacheIndexStartAt = 0;
|
||||
this.cacheIndexEndAt = 0;
|
||||
this.lastDataIndex = null;
|
||||
this.currentFolder = null;
|
||||
this.isHandlingCache = false;
|
||||
this.cacheEventQueue = [];
|
||||
//IFNDEF_FIREFOX_SYNC
|
||||
resolve();
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
|
||||
//IFDEF_FIREFOX_SYNC
|
||||
SyncManagerBridge.getInfo().then(message => {
|
||||
if (message.state === 'enabled' || message.state === 'syncing') {
|
||||
this.isSynced = true;
|
||||
} else {
|
||||
this.isSynced = false;
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
getByRange: function (start, num, folderId, cb) {
|
||||
var self = this;
|
||||
function getCaches(){
|
||||
|
||||
var length = (start + num) > self.cache.size ?
|
||||
(self.cache.size - start) : (start + num);
|
||||
var result = [];
|
||||
|
||||
for(var i = start; i < length; i++) {
|
||||
result.push(self.cache.get(i));
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
if(folderId !== this.currentFolder) {
|
||||
this.currentFolder = folderId;
|
||||
this.fetchCache().then(() => {
|
||||
cb(getCaches());
|
||||
});
|
||||
} else {
|
||||
cb(getCaches());
|
||||
}
|
||||
},
|
||||
|
||||
//IFDEF_FIREFOX_SYNC
|
||||
traverseNextCache: function(cacheIndex) {
|
||||
return new Promise(resolve => {
|
||||
var traverse = () =>{
|
||||
var start = this.cache.get(this.cacheIndexStartAt).timestamp;
|
||||
SyncBrowserDB.getHistoryTimestamp(start, 'next', false,
|
||||
timestamp => {
|
||||
if(timestamp) {
|
||||
this.updateCacheByNextHistory(timestamp).then(() => {
|
||||
var history = this.cache.get(cacheIndex);
|
||||
if(!history) {
|
||||
traverse();
|
||||
} else {
|
||||
resolve(history);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
resolve(null);
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
traverse();
|
||||
});
|
||||
},
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
|
||||
//IFDEF_FIREFOX_SYNC
|
||||
traversePreviousCache: function(cacheIndex) {
|
||||
return new Promise(resolve => {
|
||||
var traverse = () => {
|
||||
var start = this.cache.get(this.cacheIndexEndAt).timestamp;
|
||||
SyncBrowserDB.getHistoryTimestamp(start, 'prev', false,
|
||||
timestamp => {
|
||||
if(timestamp) {
|
||||
this.updateCacheByPreviousHistory(timestamp).then(() => {
|
||||
var history = this.cache.get(cacheIndex);
|
||||
if(!history) {
|
||||
traverse();
|
||||
} else {
|
||||
resolve(history);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.lastDataIndex = this.cacheIndexEndAt;
|
||||
resolve(null);
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
traverse();
|
||||
});
|
||||
},
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
|
||||
getCache: function(cacheIndex) {
|
||||
return new Promise(resolve => {
|
||||
var history = null;
|
||||
|
||||
//IFNDEF_FIREFOX_SYNC
|
||||
if(this.cacheIndexStartAt <= cacheIndex <= this.cacheIndexEndAt) {
|
||||
resolve(null);
|
||||
} else {
|
||||
history = this.cache.get(cacheIndex);
|
||||
resolve(history);
|
||||
}
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
|
||||
//IFDEF_FIREFOX_SYNC
|
||||
if(cacheIndex < this.cacheIndexStartAt) {
|
||||
this.traverseNextCache(cacheIndex).then(history => {
|
||||
resolve(history);
|
||||
});
|
||||
} else if (cacheIndex > this.cacheIndexEndAt) {
|
||||
if(this.lastDataIndex && cacheIndex > this.lastDataIndex) {
|
||||
resolve(history);
|
||||
} else {
|
||||
this.traversePreviousCache(cacheIndex).then(history => {
|
||||
resolve(history);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
history = this.cache.get(cacheIndex);
|
||||
resolve(history);
|
||||
}
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
handleCacheEvent: function() {
|
||||
if(!this.isHandlingCache) {
|
||||
this.isHandlingCache = true;
|
||||
var handler = this.cacheEventQueue.shift();
|
||||
handler().then(() => {
|
||||
this.isHandlingCache = false;
|
||||
if(this.cacheEventQueue.length > 0) {
|
||||
this.handleCacheEvent();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
getByIndex: function (index, folderId, cb) {
|
||||
var handler = () => new Promise(resolve => {
|
||||
if(folderId !== this.currentFolder) {
|
||||
this.currentFolder = folderId;
|
||||
this.fetchCache().then(() => {
|
||||
this.getCache(index).then(history => {
|
||||
cb(history);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.getCache(index).then(history => {
|
||||
cb(history);
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.cacheEventQueue.push(handler);
|
||||
this.handleCacheEvent();
|
||||
},
|
||||
|
||||
fetchCache: function () {
|
||||
this.cache.clear();
|
||||
this.cacheIndexStartAt = 0;
|
||||
this.cacheIndexEndAt = -1;
|
||||
this.lastDataIndex = null;
|
||||
|
||||
return new Promise( resolve => {
|
||||
if(!this.isSynced) {
|
||||
// Get bookmark data from origin indexdDB
|
||||
BrowserDB.getHistory(localHistory => {
|
||||
localHistory.forEach(history => {
|
||||
this.cacheIndexEndAt++;
|
||||
this.cache.set(this.cacheIndexEndAt, history);
|
||||
});
|
||||
this.lastDataIndex = this.cacheIndexEndAt;
|
||||
resolve();
|
||||
});
|
||||
} else {
|
||||
//IFNDEF_FIREFOX_SYNC
|
||||
resolve();
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
|
||||
//IFDEF_FIREFOX_SYNC
|
||||
if(!this.currentFolder) {
|
||||
// XXX: Ideally we should use Promise.all for
|
||||
// SyncBrowserDB.getBookmark and BrowserDB.getBookmarks.
|
||||
// But now the implementation of these function are not
|
||||
// return Promise.
|
||||
SyncBrowserDB.getHistoryTimestamp(Date.now(), 'prev', true,
|
||||
timestamp => {
|
||||
// We query remote history by parentid for checking if
|
||||
// the indexedDB has remote history data. If there is
|
||||
// any remote data, we create a folder item to show the
|
||||
// synced history.
|
||||
if(timestamp) {
|
||||
this.cacheIndexEndAt++;
|
||||
this.cache.set(this.cacheIndexEndAt, {
|
||||
id: 'sync_history',
|
||||
title: 'Synced History',
|
||||
type: 'folder',
|
||||
readOnly: true
|
||||
});
|
||||
}
|
||||
|
||||
// get bookmark data from origin indexdDB
|
||||
BrowserDB.getHistory(localHistory => {
|
||||
localHistory.forEach(history => {
|
||||
this.cacheIndexEndAt++;
|
||||
this.cache.set(this.cacheIndexEndAt, history);
|
||||
});
|
||||
this.lastDataIndex = this.cacheIndexEndAt;
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
);
|
||||
} else {
|
||||
SyncBrowserDB.getHistory(INITIAL_HISTORY_COUNT, syncHistory => {
|
||||
syncHistory.forEach(history => {
|
||||
// XXX: the data from firefox sync can't be modified.
|
||||
history.readOnly = true;
|
||||
this.cacheIndexEndAt++;
|
||||
this.cache.set(this.cacheIndexEndAt, history);
|
||||
});
|
||||
|
||||
if(syncHistory.length < INITIAL_HISTORY_COUNT) {
|
||||
this.lastDataIndex = this.cacheIndexEndAt;
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
//IFDEF_FIREFOX_SYNC
|
||||
updateCacheByNextHistory: function (timestamp) {
|
||||
var promise = new Promise(resolve => {
|
||||
var start = timestamp,
|
||||
end = timestamp + DAY_IN_MILLI_SECOND;
|
||||
|
||||
SyncBrowserDB.getHistoryByTime(start, end, true, true, syncHistory => {
|
||||
this.cache.clear();
|
||||
this.cacheIndexEndAt = this.cacheIndexStartAt - 1;
|
||||
var length = syncHistory.length;
|
||||
while(length--) {
|
||||
this.cacheIndexStartAt--;
|
||||
this.cache.set(this.cacheIndexStartAt, syncHistory[length]);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
return promise;
|
||||
},
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
|
||||
//IFDEF_FIREFOX_SYNC
|
||||
updateCacheByPreviousHistory: function (timestamp) {
|
||||
var promise = new Promise(resolve => {
|
||||
var start = timestamp - DAY_IN_MILLI_SECOND,
|
||||
end = timestamp;
|
||||
|
||||
SyncBrowserDB.getHistoryByTime(start, end, true, true, syncHistory => {
|
||||
this.cache.clear();
|
||||
this.cacheIndexStartAt = this.cacheIndexEndAt + 1;
|
||||
syncHistory.forEach(history => {
|
||||
// XXX: the data from firefox sync can't be modified.
|
||||
history.readOnly = true;
|
||||
this.cacheIndexEndAt++;
|
||||
this.cache.set(this.cacheIndexEndAt, history);
|
||||
});
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
return promise;
|
||||
},
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
|
||||
removeCache: function (index) {
|
||||
if(this.cacheIndexStartAt <= index <= this.cacheIndexEndAt) {
|
||||
var value = null;
|
||||
for(var i = index; i<this.cacheIndexEndAt; i++) {
|
||||
value = this.cache.get(i+1);
|
||||
this.cache.set(i, value);
|
||||
}
|
||||
this.cache.delete(this.cacheIndexEndAt);
|
||||
this.cacheIndexEndAt--;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.HistoryStore = HistoryStore;
|
||||
})(window);
|
||||
1221
gaia/tv_apps/browser/js/index.js
Executable file
136
gaia/tv_apps/browser/js/resource_loader.js
Executable file
|
|
@ -0,0 +1,136 @@
|
|||
/* 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 files to be loaded should be enclosed by a <template> element.
|
||||
* <template>
|
||||
* put HTML content here
|
||||
* </template>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
(function (exports) {
|
||||
|
||||
/**
|
||||
* ResourceLoader is a stand-alone module which provides methods for lazy
|
||||
* loading HTML, CSS and javascript resources.
|
||||
*
|
||||
* TODO: Methods for lazy loading javascript files.
|
||||
*
|
||||
* @param {object} options [description]
|
||||
*/
|
||||
function ResourceLoader(options) {
|
||||
this.path = '';
|
||||
|
||||
this.init(options);
|
||||
}
|
||||
|
||||
ResourceLoader.prototype = {
|
||||
|
||||
constructor: ResourceLoader,
|
||||
|
||||
init(options) {
|
||||
options = options || {};
|
||||
|
||||
this.path = options.path || 'elements';
|
||||
},
|
||||
|
||||
/**
|
||||
* Load HTML and CSS by name.
|
||||
* @param {string} name [description]
|
||||
* @return {Promise} The returned Promise is resolved with a Node.
|
||||
*/
|
||||
loadByName(name) {
|
||||
var path = [this.path, name].join('/');
|
||||
this.loadCss(path);
|
||||
return this.loadHtml(path);
|
||||
},
|
||||
|
||||
/**
|
||||
* Load an HTML file from the specified path, the resulted DOM Node can be
|
||||
* directly appended or modified with DOM API.
|
||||
* @param {string} path The path of the HTML file, with or without
|
||||
* html extension.
|
||||
* @return {Promise} The returned Promise is resolved with a DOM Node.
|
||||
*/
|
||||
loadHtml(path) {
|
||||
if (!path.endsWith('.html')) {
|
||||
path = [path, 'html'].join('.');
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onload = function() {
|
||||
var template = xhr.responseXML.querySelector('template');
|
||||
var node = document.importNode(template.content, true);
|
||||
resolve(node);
|
||||
};
|
||||
xhr.open('GET', path);
|
||||
xhr.responseType = 'document';
|
||||
xhr.overrideMimeType('text/html');
|
||||
xhr.send();
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Load an CSS file from the specified path.
|
||||
* @param {string} path The path of the CSS file, with or without
|
||||
* css extension.
|
||||
* @return {Promise}
|
||||
*/
|
||||
loadCss(path) {
|
||||
if (!path.endsWith('.css')) {
|
||||
path = [path, 'css'].join('.');
|
||||
}
|
||||
|
||||
if (document.querySelector('link[rel=stylesheet][href="' + path + '"]')) {
|
||||
return;
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
var link = document.createElement('link');
|
||||
link.type = 'text/css';
|
||||
link.rel = 'stylesheet';
|
||||
link.href = path;
|
||||
link.addEventListener('load', () => {
|
||||
resolve();
|
||||
});
|
||||
document.head.appendChild(link);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Unload a loaded template. We don't cache HTML templates, so we only need
|
||||
* to remove the loaded link element from document.head.
|
||||
* @param {string} name The name of the template.
|
||||
*/
|
||||
unloadByName(name) {
|
||||
var path = [this.path, name].join('/');
|
||||
this.unloadCss(path);
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove a CSS link element from document.head.
|
||||
* @param {string} path The path of the CSS file, with or without
|
||||
* css extension.
|
||||
*/
|
||||
unloadCss(path) {
|
||||
if (!path.endsWith('.css')) {
|
||||
path = [path, 'css'].join('.');
|
||||
}
|
||||
|
||||
var link =
|
||||
document.querySelector('link[rel=stylesheet][href="' + path + '"]');
|
||||
|
||||
if (link) {
|
||||
document.head.removeChild(link);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
exports.ResourceLoader = new ResourceLoader();
|
||||
|
||||
})(window);
|
||||
242
gaia/tv_apps/browser/js/search_result.js
Executable file
|
|
@ -0,0 +1,242 @@
|
|||
/* global _, Browser, BrowserDB, MozActivity */
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Browser app search_result
|
||||
* @namespace SearchResult
|
||||
*/
|
||||
var SearchResult = {
|
||||
|
||||
listTemplate: null,
|
||||
searchResultTemplate: null,
|
||||
allResult: null,
|
||||
updateInProgress: false,
|
||||
pendingUpdateFilter: null,
|
||||
|
||||
/**
|
||||
* Intialise SearchResult.
|
||||
*/
|
||||
init: function result_init() {
|
||||
/* get Element */
|
||||
this.getAllElements();
|
||||
|
||||
/* Event Listener */
|
||||
window.addEventListener('click', this);
|
||||
|
||||
// Create template elements
|
||||
this.listTemplate = this.createList();
|
||||
this.searchResultTemplate = this.createSearchTemplate();
|
||||
},
|
||||
|
||||
/**
|
||||
* CamelCase (xxx-yyy -> xxxYyy)
|
||||
*/
|
||||
toCamelCase: function toCamelCase(str) {
|
||||
return str.replace(/-(.)/g, function replacer(str, p1) {
|
||||
return p1.toUpperCase();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Get All Elements (from id)
|
||||
*/
|
||||
getAllElements: function result_getAllElements() {
|
||||
var elementIDs = [
|
||||
'search-result', 'search-result-list',
|
||||
];
|
||||
|
||||
// Loop and add element with camel style name to Modal Dialog attribute.
|
||||
elementIDs.forEach(function createElementRef(name) {
|
||||
this[this.toCamelCase(name)] = document.getElementById(name);
|
||||
}, this);
|
||||
},
|
||||
|
||||
show: function result_show() {
|
||||
this.searchResult.classList.add('visible');
|
||||
this.handleSearchResultFormInput(null);
|
||||
},
|
||||
|
||||
hide: function result_hide() {
|
||||
var list = this.searchResultList.firstElementChild;
|
||||
if( list ) this.searchResultList.removeChild(list);
|
||||
this.searchResult.classList.remove('visible');
|
||||
Toolbar.setSearchBarStyle('false');
|
||||
},
|
||||
|
||||
isDisplayed: function result_isDisplayed() {
|
||||
return this.searchResult.classList.contains('visible');
|
||||
},
|
||||
|
||||
/**
|
||||
* Submit search form
|
||||
*/
|
||||
handleSearchResultFormInput: function result_handleSearchResultFormInput(ev) {
|
||||
if( ev ) ev.preventDefault();
|
||||
this.resultUpdate(Toolbar.searchInput.value);
|
||||
},
|
||||
|
||||
handleSearchResultFormSubmit: function result_handleSearchResultFormSubmit(ev) {
|
||||
if( ev ) ev.preventDefault();
|
||||
},
|
||||
|
||||
createList: function result_createList() {
|
||||
var list = document.createElement('ul');
|
||||
list.classList.add('result-box');
|
||||
return list;
|
||||
},
|
||||
|
||||
createSearchTemplate: function result_createSearchTemplate() {
|
||||
var template = document.createElement('li');
|
||||
template.classList.add('result-item');
|
||||
var link = document.createElement('div');
|
||||
link.classList.add('result-base');
|
||||
var title = document.createElement('div');
|
||||
title.classList.add('result-title');
|
||||
var url = document.createElement('div');
|
||||
url.classList.add('result-url');
|
||||
|
||||
link.appendChild(title);
|
||||
link.appendChild(url);
|
||||
template.appendChild(link);
|
||||
|
||||
return template;
|
||||
},
|
||||
|
||||
resultUpdate: function result_resultUpdate(filter) {
|
||||
// If an update is already in progress enqueue the following ones
|
||||
if (this.updateInProgress) {
|
||||
this.pendingUpdateFilter = filter;
|
||||
return;
|
||||
} else {
|
||||
this.updateInProgress = true;
|
||||
}
|
||||
|
||||
this.allResult = [];
|
||||
BrowserDB.getBookmarks((function(bookmarks) {
|
||||
this.resultFiltering(filter, bookmarks);
|
||||
BrowserDB.getHistory((function(history) {
|
||||
this.resultFiltering(filter, history);
|
||||
this.populateResults(filter);
|
||||
|
||||
this.updateInProgress = false;
|
||||
var pendingUpdateFilter = this.pendingUpdateFilter;
|
||||
if (pendingUpdateFilter !== null) {
|
||||
this.pendingUpdateFilter = null;
|
||||
this.resultUpdate(pendingUpdateFilter);
|
||||
}
|
||||
}).bind(this));
|
||||
}).bind(this));
|
||||
},
|
||||
|
||||
resultFiltering: function result_resultFiltering(filter, data) {
|
||||
if(( filter == '' ) || ( data == null )) return;
|
||||
|
||||
for( var i = 0 ; i < data.length ; i ++ ) {
|
||||
var current = data[i];
|
||||
var matched = false;
|
||||
if( filter ) {
|
||||
matched = this.matchesFilter(current.uri, filter) ||
|
||||
this.matchesFilter(current.title, filter);
|
||||
}
|
||||
if( matched || !filter ) {
|
||||
var j = 0;
|
||||
for( ; j < this.allResult.length ; j ++ ) {
|
||||
if( this.allResult[j].uri === current.uri ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( j == this.allResult.length ) {
|
||||
this.allResult.push(current);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the URI matches the regular expression filter.
|
||||
* @param {String} uri
|
||||
* @param {String} filter
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
matchesFilter: function result_matchesFilter(uri, filter) {
|
||||
if( !uri ) return false;
|
||||
return uri.match(new RegExp(filter, 'i')) !== null;
|
||||
},
|
||||
|
||||
populateResults: function result_populateResults(filter) {
|
||||
var list = this.createList();
|
||||
var engine = SearchUtil.getCurrentEngineName();
|
||||
if( engine ) {
|
||||
var result = this.searchResultTemplate.cloneNode(true);
|
||||
var title = result.childNodes[0].childNodes[0];
|
||||
// title.innerHTML = 'Search by ' + engine;
|
||||
navigator.mozL10n.setAttributes(title, 'WB_LT_TIPS_S_SEARCH', {
|
||||
value0:engine
|
||||
});
|
||||
var uri = result.childNodes[0].childNodes[1];
|
||||
uri.innerHTML = Browser.getSearchFromInput(filter);
|
||||
list.appendChild(result);
|
||||
result.addEventListener('mouseup',
|
||||
this.handleResultSelect.bind(this));
|
||||
}
|
||||
|
||||
for( var i = 0 ; i < this.allResult.length ; i ++ ) {
|
||||
var result = this.searchResultTemplate.cloneNode(true);
|
||||
var title = result.childNodes[0].childNodes[0];
|
||||
title.innerHTML = this.allResult[i].title;
|
||||
var uri = result.childNodes[0].childNodes[1];
|
||||
uri.innerHTML = this.allResult[i].uri;
|
||||
list.appendChild(result);
|
||||
result.addEventListener('mouseup',
|
||||
this.handleResultSelect.bind(this));
|
||||
}
|
||||
var oldList = this.searchResultList.firstElementChild;
|
||||
|
||||
if (oldList) {
|
||||
this.searchResultList.replaceChild(list, oldList);
|
||||
} else {
|
||||
this.searchResultList.appendChild(list);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* handle event
|
||||
*/
|
||||
handleEvent: function result_handleEvent(ev) {
|
||||
switch(ev.type) {
|
||||
case 'click':
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
handleResultSelect: function result_handleResultSelect(ev) {
|
||||
if( !ev ) return;
|
||||
ev.preventDefault();
|
||||
if(( ev.target.lastChild.lastChild.textContent != '' ) ||
|
||||
( ev.target.lastChild.lastChild.textContent != undefined )) {
|
||||
var url = ev.target.lastChild.lastChild.textContent;
|
||||
Browser.navigate(url);
|
||||
this.hide();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle Key Event.
|
||||
*/
|
||||
handleKeyEvent: function result_handleKeyEvent(ev) {
|
||||
// in the input area focus (= display keyboard)
|
||||
if(document.activeElement.nodeName == 'INPUT') {
|
||||
return;
|
||||
}
|
||||
switch( ev.keyCode ) {
|
||||
case KeyEvent.DOM_VK_BACK_SPACE :
|
||||
this.hide();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
283
gaia/tv_apps/browser/js/search_util.js
Executable file
|
|
@ -0,0 +1,283 @@
|
|||
'use strict';
|
||||
|
||||
var SearchUtil = {
|
||||
// country code
|
||||
COUNTRY: 'US',
|
||||
|
||||
/* search engine list of the search bar */
|
||||
ENGINE_LIST: {
|
||||
'CN': [
|
||||
{id: 2, name: 'Baidu'},
|
||||
{id: 1, name: 'Bing'}
|
||||
],
|
||||
// default
|
||||
'US': [
|
||||
{id: 1, name: 'Bing'},
|
||||
{id: 0, name: 'Google'}
|
||||
]
|
||||
},
|
||||
// search engine
|
||||
engineList: null,
|
||||
searchId: null,
|
||||
searchIdx: null,
|
||||
|
||||
DOMAIN_LIST: {
|
||||
'US':'com' , 'CA':'ca' , 'DE':'de' , 'IE':'ie' ,
|
||||
'NL':'nl' , 'HU':'hu' , 'PL':'pl' , 'CZ':'cz' ,
|
||||
'SK':'sk' , 'IT':'it' , 'GB':'co.uk' , 'SI':'si' ,
|
||||
'GR':'gr' , 'PT':'pt' , 'DK':'dk' , 'FI':'fi' ,
|
||||
'HR':'hr' , 'NO':'no' , 'RO':'ro' , 'RU':'ru' ,
|
||||
'BG':'bg' , 'LT':'lt' , 'YU':'rs' , 'SE':'se' ,
|
||||
'LV':'lv' , 'EE':'ee' , 'TR':'com.tr' , 'BR':'com.br' ,
|
||||
'ID':'co.id' , 'CN':'com.hk' , 'TW':'com.tw' , 'HK':'com.hk' ,
|
||||
'VN':'com.vn' , 'TH':'co.th' , 'SA':'com.sa' , 'FR':'fr' ,
|
||||
'ES':'es' , 'SG':'com.sg' , 'AU':'com.au' , 'NZ':'co.nz' ,
|
||||
'IN':'co.in' , 'MY':'com.my' , 'AE':'ae' , 'KW':'com.kw' ,
|
||||
'MX':'com.mx' , 'AT':'at' , 'BE':'be' , 'CH':'ch' ,
|
||||
'MT':'com.mt' , 'AD':':' , 'LU':'lu' , 'IS':'is' ,
|
||||
'UA':'com.ua' , 'KZ':'kz' , 'CIS':'by' , 'UK':'co.uk' ,
|
||||
'CL':'cl' , 'PE':'com.pe' , 'CO':'com.co' , 'AR':'com.ar' ,
|
||||
'PA':'com.pa' , 'JP':'co.jp' , 'MK':'mk' , 'MM':'com.mm'
|
||||
},
|
||||
// search domain
|
||||
domainList: null,
|
||||
|
||||
/* URL of each search engine */
|
||||
SEARCH_URL: {
|
||||
//Google :
|
||||
0 : [
|
||||
"http://www.google.DOMAIN/search?ie=UTF-8&oe=UTF-8&q=",
|
||||
"http://www.google.DOMAIN/search?ie=UTF-8&oe=UTF-8&tbm=isch&q=",
|
||||
"http://www.google.DOMAIN/search?ie=UTF-8&oe=UTF-8&tbm=vid&q=",
|
||||
"http://www.google.DOMAIN/search?ie=UTF-8&oe=UTF-8&tbm=nws&q=",
|
||||
"http://maps.google.com/maps?q=",
|
||||
"http://www.youtube.DOMAIN/results?search_query="
|
||||
],
|
||||
//bing :
|
||||
1 : [
|
||||
"http://www.bing.com/search?FORM=PANSSB&PC=PANS&q=",
|
||||
"http://www.bing.com/images/search?FORM=PANSSB&PC=PANS&q=",
|
||||
//"http://www.bing.com/videos/search?FORM=PANSSB&PC=PANS&q=",
|
||||
"http://www.bing.com/?scope=video&FORM=PANSSB&PC=PANS&q=",
|
||||
"http://www.bing.com/news/search?FORM=PANSSB&PC=PANS&q=",
|
||||
"http://www.bing.com/maps/?FORM=PANSSB&PC=PANS&q=",
|
||||
"http://www.bing.com/videos/search?FORM=PANSSB&PC=PANS&q="
|
||||
],
|
||||
//Baidu :
|
||||
2 : [
|
||||
"http://www.baidu.com/s?word=",
|
||||
"http://image.baidu.com/i?word=",
|
||||
"http://video.baidu.com/v?word=",
|
||||
"http://news.baidu.com/ns?word=",
|
||||
"http://map.baidu.com/m?word=",
|
||||
"http://video.baidu.com/v?word="
|
||||
]
|
||||
},
|
||||
searchUrl: null,
|
||||
|
||||
// keyword for auto category selection at voice search
|
||||
SEARCH_CAT: {
|
||||
//Google :
|
||||
0 :
|
||||
[
|
||||
[ [ "www.google.", "/search", "" ] ],
|
||||
[ [ "www.google.", "/search", "tbm=isch" ],
|
||||
[ "www.google.", "/imghp", "" ] ],
|
||||
[ [ "www.google.", "/search", "tbm=vid" ],
|
||||
[ "www.google.", "/videohp","" ] ],
|
||||
[ [ "www.google.", "/search", "tbm=nws" ],
|
||||
[ "news.google.", "/nwshp", "" ] ],
|
||||
[ [ "maps.google.", "", "" ],
|
||||
[ "www.google.", "/maps", "" ] ],
|
||||
[ [ "www.youtube.", "", "" ] ]
|
||||
],
|
||||
//Bing :
|
||||
1 :
|
||||
[
|
||||
[ [ "www.bing.com", "/search", "" ] ],
|
||||
[ [ "www.bing.com", "/images", "" ],
|
||||
[ "www.bing.com", "", "scope=images" ] ],
|
||||
[ [ "www.bing.com", "/videos", "" ],
|
||||
[ "www.bing.com", "", "scope=video" ] ],
|
||||
[ [ "www.bing.com", "/news", "" ],
|
||||
[ "www.bing.com", "", "scope=news" ] ],
|
||||
[ [ "www.bing.com", "/maps", "" ] ],
|
||||
[ [ "www.bing.com", "/videos", "" ],
|
||||
[ "www.bing.com", "", "scope=video" ] ]
|
||||
],
|
||||
//Baidu :
|
||||
2 :
|
||||
[
|
||||
[ [ "www.baidu.com", "", "" ] ],
|
||||
[ [ "image.baidu.com", "", "" ] ],
|
||||
[ [ "video.baidu.com", "", "" ] ],
|
||||
[ [ "news.baidu.com", "", "" ] ],
|
||||
[ [ "map.baidu.com", "", "" ] ],
|
||||
[ [ "video.baidu.com", "", "" ] ]
|
||||
]
|
||||
},
|
||||
|
||||
displaySearchEngineName: false,
|
||||
|
||||
/**
|
||||
* init SearchUtil
|
||||
*/
|
||||
init: function searchUtil_init(country, cb) {
|
||||
// set country code
|
||||
this.COUNTRY = country;
|
||||
|
||||
// search engine (default US)
|
||||
this.engineList = (country in this.ENGINE_LIST)?
|
||||
this.ENGINE_LIST[country]: this.ENGINE_LIST['US'];
|
||||
|
||||
// search domain (default US)
|
||||
this.domainList = (country in this.DOMAIN_LIST)?
|
||||
this.DOMAIN_LIST[country]: this.DOMAIN_LIST['US'];
|
||||
|
||||
// search URL (default US)
|
||||
this.searchUrl = this.SEARCH_URL;
|
||||
var index;
|
||||
for(index in this.searchUrl[0]){
|
||||
this.searchUrl[0][index] =
|
||||
this.searchUrl[0][index].replace(/DOMAIN/, this.domainList);
|
||||
}
|
||||
|
||||
// get all database
|
||||
this.getAllDatabase(cb);
|
||||
},
|
||||
|
||||
/**
|
||||
* get all database
|
||||
*/
|
||||
getAllDatabase: function searchUtil_getAllDatabase(cb){
|
||||
// DB get all
|
||||
this.getSearchEngineId((function(){
|
||||
this.initDatabase((function(){
|
||||
if(cb){
|
||||
cb();
|
||||
}
|
||||
}).bind(this))
|
||||
}).bind(this));
|
||||
},
|
||||
|
||||
// init database
|
||||
initDatabase: function search_initDatabase(cb){
|
||||
// default search engine url
|
||||
if(this.searchId != null){
|
||||
this.convSearchIdToIdx(this.searchId);
|
||||
}else{
|
||||
this.searchIdx = 0;
|
||||
this.displaySearchEngineName = true;
|
||||
}
|
||||
if(cb){
|
||||
cb();
|
||||
}
|
||||
},
|
||||
|
||||
// get search engine id
|
||||
getSearchEngineId: function searchUtil_getSearchEngineId(cb){
|
||||
BrowserDB.getSetting('SEARCH_ENGINE', (function(result) {
|
||||
Browser.debug("SEARCH_ENGINE = " + result);
|
||||
if(result != undefined){
|
||||
this.searchId = result;
|
||||
this.convSearchIdToIdx(result);
|
||||
}
|
||||
if(cb){
|
||||
cb(result);
|
||||
}
|
||||
}).bind(this));
|
||||
},
|
||||
|
||||
// set search engine id
|
||||
setSearchEngineId: function searchUtil_setSearchEngineId(id, cb){
|
||||
this.searchId = id;
|
||||
this.convSearchIdToIdx(id);
|
||||
BrowserDB.updateSetting(id, 'SEARCH_ENGINE', cb);
|
||||
},
|
||||
|
||||
// get search engine index
|
||||
getSearchEngineIdx: function searchUtil_getSearchEngineIdx(cb){
|
||||
if(this.searchId){
|
||||
this.convSearchIdToIdx(this.searchId);
|
||||
if(cb){
|
||||
cb();
|
||||
}
|
||||
}else{
|
||||
BrowserDB.getSetting('SEARCH_ENGINE', (function(result) {
|
||||
if(result != undefined){
|
||||
this.convSearchIdToIdx(result);
|
||||
}
|
||||
if(cb){
|
||||
cb();
|
||||
}
|
||||
}).bind(this));
|
||||
}
|
||||
},
|
||||
|
||||
// Convert the search_id (DB) to search index.
|
||||
convSearchIdToIdx: function searchUtil_convSearchIdToIdx(search_id) {
|
||||
var index = null;
|
||||
for(var i in this.engineList){
|
||||
if(search_id == this.engineList[i].id){
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(index == null){
|
||||
// terminated search service of Web. so select default.
|
||||
this.searchIdx = 0;
|
||||
this.searchId = this.engineList[0].id;
|
||||
BrowserDB.updateSetting(undefined, 'SEARCH_ENGINE');
|
||||
this.displaySearchEngineName = false;
|
||||
}else{
|
||||
this.searchIdx = index;
|
||||
this.displaySearchEngineName = true;
|
||||
}
|
||||
},
|
||||
|
||||
// Get Search Engine List.
|
||||
getEngineList: function searchUtil_getEngineList(){
|
||||
return this.engineList;
|
||||
},
|
||||
// Get Current Search Engine List.
|
||||
getCurrentEngineList: function searchUtil_getCurrentEngineList(){
|
||||
if(this.searchIdx != null && this.searchIdx < this.engineList.length) {
|
||||
return this.engineList[this.searchIdx];
|
||||
}else{
|
||||
return this.engineList[0];
|
||||
}
|
||||
},
|
||||
// Get Current Search Engine Name.
|
||||
getCurrentEngineName: function searchUtil_getCurrentEngineName(){
|
||||
if(this.searchIdx != null && this.searchIdx < this.engineList.length) {
|
||||
return this.engineList[this.searchIdx].name;
|
||||
}else{
|
||||
return this.engineList[0].name;
|
||||
}
|
||||
},
|
||||
// Get Search Id.
|
||||
getSearchId: function searchUtil_getSearchId(){
|
||||
return this.searchId;
|
||||
},
|
||||
// Get Search Index.
|
||||
getSearchIdx: function searchUtil_getSearchIdx(){
|
||||
return this.searchIdx;
|
||||
},
|
||||
// Get Search Url.
|
||||
getSearchUrl: function searchUtil_getSearchUrl(){
|
||||
return this.searchUrl;
|
||||
},
|
||||
// Get Current Search Url.
|
||||
getCurrentSearchUrl: function searchUtil_getCurrentSearchUrl(){
|
||||
if(this.searchId != null && (this.searchId in this.searchUrl)){
|
||||
return this.searchUrl[this.searchId];
|
||||
}else{
|
||||
return this.searchUrl[this.engineList[0].id];
|
||||
}
|
||||
},
|
||||
// Get Display Search Engine Name flag.
|
||||
getDispFlag: function searchUtil_getDispFlag(){
|
||||
return this.displaySearchEngineName;
|
||||
},
|
||||
};
|
||||
|
||||
719
gaia/tv_apps/browser/js/settings.js
Executable file
|
|
@ -0,0 +1,719 @@
|
|||
/* exported Settings */
|
||||
/* global Awesomescreen */
|
||||
/* global Browser */
|
||||
/* global BrowserDB */
|
||||
/* global BrowserDialog */
|
||||
/* global KeyEvent */
|
||||
/* global LazyLoader */
|
||||
/* global SearchUtil */
|
||||
/* global Toolbar */
|
||||
/* global UrlHelper */
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Browser app settings panel.
|
||||
* @namespace Settings
|
||||
*/
|
||||
var Settings = {
|
||||
DEFAULT_HOMEPAGE: 'http://www.mozilla.org',
|
||||
currentSearchEngine: null,
|
||||
selectSearchEngine: null,
|
||||
searchEngineList: null,
|
||||
focusList: null,
|
||||
focusPos: 0,
|
||||
|
||||
/** Get all DOM elements when inited. */
|
||||
getAllElements: function settings_getAllElements() {
|
||||
|
||||
var toCamelCase = function toCamelCase(str) {
|
||||
return str.replace(/\-(.)/g, function replacer(str, p1) {
|
||||
return p1.toUpperCase();
|
||||
});
|
||||
};
|
||||
|
||||
var elementIDs = [
|
||||
'settings-list', 'settings-list-area',
|
||||
'settings-homepage', 'settings-homepage-name',
|
||||
'settings-search-engine', 'settings-search-engine-name',
|
||||
'settings-clear-history',
|
||||
'settings-clear-cookie',
|
||||
|
||||
'settings-dialog',
|
||||
|
||||
'settings-dialog-homepage',
|
||||
'settings-dialog-homepage-input',
|
||||
'settings-dialog-homepage-input-area',
|
||||
'settings-dialog-homepage-clear',
|
||||
'settings-dialog-homepage-default',
|
||||
'settings-dialog-homepage-cancel',
|
||||
'settings-dialog-homepage-ok',
|
||||
|
||||
'settings-dialog-search',
|
||||
'settings-dialog-search-select',
|
||||
'settings-dialog-search-select-list',
|
||||
'settings-dialog-search-cancel',
|
||||
'settings-dialog-search-ok',
|
||||
|
||||
'settings-banner-message'
|
||||
];
|
||||
|
||||
// Loop and add element with camel style name to Modal Dialog attribute.
|
||||
elementIDs.forEach(function createElementRef(name) {
|
||||
this[toCamelCase(name)] = document.getElementById(name);
|
||||
}, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Intialise settings panel.
|
||||
*/
|
||||
init: function settings_init() {
|
||||
this.getAllElements();
|
||||
|
||||
this.getDefaultHomepage((function(result) {
|
||||
/* default homepage nothing... */
|
||||
Browser.debug('default homepage = ' + result);
|
||||
if(!result) {
|
||||
console.log('set default homepage...');
|
||||
this.setDefaultHomepage();
|
||||
this.setHomepage(this.DEFAULT_HOMEPAGE);
|
||||
}
|
||||
}).bind(this));
|
||||
|
||||
this.settingsList.addEventListener('mouseup',
|
||||
this.handleListClick.bind(this));
|
||||
this.settingsListArea.addEventListener('mouseup',
|
||||
this.handleListAreaClick.bind(this));
|
||||
this.settingsDialog.addEventListener('mouseup',
|
||||
this.handleListAreaClick.bind(this));
|
||||
|
||||
this.settingsHomepage.addEventListener('mouseup',
|
||||
this.handleHomepageClick.bind(this));
|
||||
this.settingsSearchEngine.addEventListener('mouseup',
|
||||
this.handleSearchEngineClick.bind(this));
|
||||
this.settingsClearHistory.addEventListener('mouseup',
|
||||
this.handleClearHistoryClick.bind(this));
|
||||
this.settingsClearCookie.addEventListener('mouseup',
|
||||
this.handleClearCookieClick.bind(this));
|
||||
|
||||
this.settingsDialogHomepageInput.addEventListener('submit',
|
||||
this.handleDialogHomepageInputSubmit.bind(this));
|
||||
this.settingsDialogHomepageClear.addEventListener('mouseup',
|
||||
this.handleDialogHomepageClear.bind(this));
|
||||
this.settingsDialogHomepageDefault.addEventListener('mouseup',
|
||||
this.handleDialogHomepageDefault.bind(this));
|
||||
this.settingsDialogHomepageCancel.addEventListener('mouseup',
|
||||
this.handleDialogHomepageCancel.bind(this));
|
||||
this.settingsDialogHomepageOk.addEventListener('mouseup',
|
||||
this.handleDialogHomepageOk.bind(this));
|
||||
|
||||
this.settingsDialogSearchCancel.addEventListener('mouseup',
|
||||
this.handleDialogSearchCancel.bind(this));
|
||||
this.settingsDialogSearchOk.addEventListener('mouseup',
|
||||
this.handleDialogSearchOk.bind(this));
|
||||
|
||||
this.settingsDialogHomepageInputArea.addEventListener('focus',
|
||||
this.handleDialogHomepageInputAreaFocus.bind(this));
|
||||
this.settingsDialogHomepageInputArea.addEventListener('mousedown',
|
||||
this.handleDialogHomepageInputAreaClick.bind(this));
|
||||
|
||||
this.settingsDialogHomepageInputArea.addEventListener('blur',
|
||||
this.handleDialogHomepageInputBlur.bind(this));
|
||||
this.settingsDialogHomepageClear.addEventListener('keyup',
|
||||
this.handleDialogHomepageClear.bind(this));
|
||||
this.settingsDialogHomepageDefault.addEventListener('keyup',
|
||||
this.handleDialogHomepageDefault.bind(this));
|
||||
this.settingsDialogHomepageCancel.addEventListener('keyup',
|
||||
this.handleDialogHomepageCancel.bind(this));
|
||||
this.settingsDialogHomepageOk.addEventListener('keyup',
|
||||
this.handleDialogHomepageOk.bind(this));
|
||||
|
||||
this.settingsDialogSearchCancel.addEventListener('keyup',
|
||||
this.handleDialogSearchCancel.bind(this));
|
||||
this.settingsDialogSearchOk.addEventListener('keyup',
|
||||
this.handleDialogSearchOk.bind(this));
|
||||
|
||||
//IFDEF_FIREFOX_SYNC
|
||||
LazyLoader.load('js/sync/settings.js');
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
},
|
||||
|
||||
getDefaultHomepage: function settings_getDefaultHomepage(cb) {
|
||||
BrowserDB.db.open((function() {
|
||||
BrowserDB.getSetting( 'default_homepage', cb );
|
||||
}).bind(this));
|
||||
},
|
||||
|
||||
setDefaultHomepage: function settings_setDefaultHomepage() {
|
||||
BrowserDB.db.open((function() {
|
||||
BrowserDB.updateSetting( this.DEFAULT_HOMEPAGE, 'default_homepage' );
|
||||
}).bind(this));
|
||||
},
|
||||
|
||||
getHomepage: function settings_getHomepage(cb) {
|
||||
BrowserDB.db.open((function() {
|
||||
BrowserDB.getSetting( 'settings_homepage', cb );
|
||||
}).bind(this));
|
||||
},
|
||||
|
||||
setHomepage: function settings_setHomepage(url) {
|
||||
BrowserDB.db.open((function() {
|
||||
BrowserDB.updateSetting( url, 'settings_homepage' );
|
||||
}).bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Show settings panel.
|
||||
*/
|
||||
show: function settings_show() {
|
||||
document.body.classList.add('settings-screen');
|
||||
this.getHomepage((function(result) {
|
||||
this.settingsHomepageName.textContent = result;
|
||||
}).bind(this));
|
||||
this.settingsSearchEngineName.textContent =
|
||||
SearchUtil.getCurrentEngineName();
|
||||
this.currentSearchEngine = this.settingsSearchEngineName.textContent;
|
||||
this.selectSearchEngine = this.currentSearchEngine;
|
||||
|
||||
// XXX: Get Firefox Account sign in status and display it
|
||||
},
|
||||
|
||||
/**
|
||||
* settings list displays a confirmation.
|
||||
*/
|
||||
isDisplayed: function settings_isDisplayed() {
|
||||
return document.body.classList.contains('settings-screen');
|
||||
},
|
||||
|
||||
/**
|
||||
* Hide settings panel.
|
||||
*/
|
||||
hide: function settings_hide() {
|
||||
// Browser.switchCursorMode( true );
|
||||
BrowserDialog.cancelDialog();
|
||||
this.hideDialogHomepage();
|
||||
this.hideDialogSearch();
|
||||
document.body.classList.remove('settings-screen');
|
||||
},
|
||||
|
||||
handleListClick: function settings_handleListClick(evt) {
|
||||
if( evt ) {
|
||||
evt.stopPropagation();
|
||||
}
|
||||
this.hide();
|
||||
},
|
||||
|
||||
handleListAreaClick: function settings_handleListAreaClick(evt) {
|
||||
if( evt ) {
|
||||
evt.stopPropagation();
|
||||
}
|
||||
},
|
||||
|
||||
focusChange: function settings_focusChange(pos) {
|
||||
var opt = null;
|
||||
var flg = false;
|
||||
if( Awesomescreen.pointerImg.style.display == 'none' ) {
|
||||
Browser.switchCursorMode(true);
|
||||
Browser.switchCursorMode(false);
|
||||
flg = true;
|
||||
}
|
||||
for( var i = 0 ; i < Settings.focusList.length ; i ++ ) {
|
||||
if( i == pos ) {
|
||||
if(Settings.focusList[i].nodeName == 'INPUT') {
|
||||
if( !Settings.settingsDialogHomepageInput
|
||||
.classList.contains('exfocus') ) {
|
||||
Settings.settingsDialogHomepageInput.classList.add('exfocus');
|
||||
}
|
||||
} else if(Settings.focusList[i].id == 'settings-dialog-homepage-clear'){
|
||||
Settings.focusList[i].focus();
|
||||
if( !Settings.settingsDialogHomepageInput
|
||||
.classList.contains('exfocus') ) {
|
||||
Settings.settingsDialogHomepageInput.classList.add('exfocus');
|
||||
}
|
||||
if( flg ) {
|
||||
opt = Awesomescreen.DEFAULT_EXCLEAR;
|
||||
}
|
||||
} else {
|
||||
Settings.focusList[i].focus();
|
||||
Settings.settingsDialogHomepageInput.classList.remove('exfocus');
|
||||
}
|
||||
Awesomescreen.focusImgFunc(Settings.focusList[i], opt);
|
||||
} else {
|
||||
Settings.focusList[i].blur();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle homepage click.
|
||||
*/
|
||||
handleHomepageClick: function settings_handleHomepageClick() {
|
||||
if( !this.isDialogHomepageDisplayed() ) {
|
||||
this.focusList = [];
|
||||
Browser.switchCursorMode(false);
|
||||
this.settingsDialog.classList.remove('hidden');
|
||||
this.settingsDialogHomepage.classList.remove('hidden');
|
||||
this.settingsDialogHomepageInput.classList.remove('input');
|
||||
this.settingsDialogHomepageInput.classList.remove('exfocus');
|
||||
this.settingsDialogHomepageInputArea.value =
|
||||
this.settingsHomepageName.textContent;
|
||||
this.settingsDialogHomepageInputArea.tabIndex = '0';
|
||||
this.settingsDialogHomepageClear.tabIndex = '0';
|
||||
|
||||
this.focusList.push(this.settingsDialogHomepageInputArea);
|
||||
this.focusList.push(this.settingsDialogHomepageClear);
|
||||
this.focusList.push(this.settingsDialogHomepageDefault);
|
||||
this.focusList.push(this.settingsDialogHomepageOk);
|
||||
this.focusList.push(this.settingsDialogHomepageCancel);
|
||||
this.focusPos = this.focusList.length - 1;
|
||||
this.focusChange(this.focusPos);
|
||||
}
|
||||
},
|
||||
|
||||
hideDialogHomepage: function settings_hideDialogHomepage() {
|
||||
if( this.isDialogHomepageDisplayed() ) {
|
||||
Awesomescreen.pointerImg.style.display = 'none';
|
||||
this.settingsDialogHomepageInput.classList.remove('input');
|
||||
this.settingsDialogHomepageInput.classList.remove('exfocus');
|
||||
this.settingsDialogHomepage.classList.add('hidden');
|
||||
this.settingsDialog.classList.add('hidden');
|
||||
Browser.switchCursorMode(true);
|
||||
}
|
||||
},
|
||||
|
||||
isDialogHomepageDisplayed: function settings_isDialogHomepageDisplayed() {
|
||||
return !this.settingsDialogHomepage.classList.contains('hidden');
|
||||
},
|
||||
|
||||
handleDialogHomepageInputSubmit:
|
||||
function settings_handleDialogHomepageInputSubmit(ev) {
|
||||
if (ev) {
|
||||
// Can be canceled
|
||||
ev.preventDefault();
|
||||
}
|
||||
|
||||
var hasScheme =
|
||||
UrlHelper.hasScheme(this.settingsDialogHomepageInputArea.value);
|
||||
// No scheme, prepend basic protocol and return
|
||||
if (!hasScheme) {
|
||||
this.settingsDialogHomepageInputArea.value =
|
||||
'http://' + this.settingsDialogHomepageInputArea.value;
|
||||
}
|
||||
|
||||
this.settingsDialogHomepageInputArea.blur();
|
||||
},
|
||||
|
||||
handleDialogHomepageInputAreaFocus:
|
||||
function settings_handleDialogHomepageInputAreaFocus(evt) {
|
||||
if( evt ) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
Settings.settingsDialogHomepageInput.classList.add('input');
|
||||
Settings.settingsDialogHomepageInput.classList.remove('exfocus');
|
||||
},
|
||||
|
||||
handleDialogHomepageInputAreaClick:
|
||||
function settings_handleDialogHomepageInputAreaClick(evt) {
|
||||
Browser.switchCursorMode(true);
|
||||
Browser.switchCursorMode(false);
|
||||
|
||||
Settings.settingsDialogHomepageInput.classList.add('input');
|
||||
Settings.settingsDialogHomepageInput.classList.remove('exfocus');
|
||||
|
||||
Settings.focusPos = 0;
|
||||
Settings.focusList[Settings.focusPos].focus();
|
||||
Awesomescreen.pointerImg.style.display = 'none';
|
||||
},
|
||||
|
||||
handleDialogHomepageInputBlur:
|
||||
function settings_handleDialogHomepageInputBlur(evt) {
|
||||
if( evt ) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
if( Awesomescreen.pointerImg.style.display == 'none' ) {
|
||||
Browser.switchCursorMode(true);
|
||||
Browser.switchCursorMode(false);
|
||||
}
|
||||
// Pointer image to the input area(fucusPos=0)
|
||||
Settings.focusPos = 0;
|
||||
Settings.settingsDialogHomepageInput.classList.remove('input');
|
||||
Settings.focusChange(Settings.focusPos);
|
||||
Awesomescreen.pointerImg.style.display = 'block';
|
||||
},
|
||||
|
||||
handleDialogHomepageClear:
|
||||
function settings_handleDialogHomepageClear(evt) {
|
||||
if( evt ) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
if(( evt.type == 'keyup' ) && ( evt.keyCode != KeyEvent.DOM_VK_RETURN )) {
|
||||
return;
|
||||
}
|
||||
if( evt.keyCode != KeyEvent.DOM_VK_RETURN ) {
|
||||
Awesomescreen.pointerImg.style.display = 'none';
|
||||
document.activeElement.blur();
|
||||
document.activeElement.classList.remove('exfocus');
|
||||
}
|
||||
document.activeElement.classList.remove('active');
|
||||
this.settingsDialogHomepageInputArea.value = '';
|
||||
},
|
||||
|
||||
handleDialogHomepageDefault:
|
||||
function settings_handleDialogHomepageDefault(evt) {
|
||||
if( evt ) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
if(( evt.type == 'keyup' ) && ( evt.keyCode != KeyEvent.DOM_VK_RETURN )) {
|
||||
return;
|
||||
}
|
||||
if( evt.keyCode != KeyEvent.DOM_VK_RETURN ) {
|
||||
Awesomescreen.pointerImg.style.display = 'none';
|
||||
document.activeElement.blur();
|
||||
document.activeElement.classList.remove('exfocus');
|
||||
}
|
||||
document.activeElement.classList.remove('active');
|
||||
this.getDefaultHomepage((function(result) {
|
||||
this.settingsDialogHomepageInputArea.value = result;
|
||||
}).bind(this));
|
||||
},
|
||||
|
||||
handleDialogHomepageCancel:
|
||||
function settings_handleDialogHomepageCancel(evt) {
|
||||
if( evt ) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
if(( evt.type == 'keyup' ) && ( evt.keyCode != KeyEvent.DOM_VK_RETURN )) {
|
||||
return;
|
||||
}
|
||||
// animation end event handler
|
||||
var end_event = (function() {
|
||||
Settings.settingsDialogHomepageCancel.removeEventListener('transitionend',
|
||||
end_event, false);
|
||||
Settings.hideDialogHomepage();
|
||||
});
|
||||
// end animantion event
|
||||
Settings.settingsDialogHomepageCancel.addEventListener('transitionend',
|
||||
end_event, false);
|
||||
document.activeElement.classList.remove('active');
|
||||
},
|
||||
|
||||
handleDialogHomepageOk: function settings_handleDialogHomepageOk(evt) {
|
||||
if( evt ) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
if(( evt.type == 'keyup' ) && ( evt.keyCode != KeyEvent.DOM_VK_RETURN )) {
|
||||
return;
|
||||
}
|
||||
// animation end event handler
|
||||
var end_event = (function() {
|
||||
Settings.settingsDialogHomepageOk.removeEventListener('transitionend',
|
||||
end_event, false);
|
||||
Settings.hideDialogHomepage();
|
||||
});
|
||||
// end animantion event
|
||||
Settings.settingsDialogHomepageOk.addEventListener('transitionend',
|
||||
end_event, false);
|
||||
document.activeElement.classList.remove('active');
|
||||
this.setHomepage(this.settingsDialogHomepageInputArea.value);
|
||||
this.settingsHomepageName.textContent =
|
||||
this.settingsDialogHomepageInputArea.value;
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle search engine click.
|
||||
*/
|
||||
handleSearchEngineClick: function settings_handleSearchEngineClick() {
|
||||
if( !this.isDialogSearchDisplayed() ) {
|
||||
this.focusList = [];
|
||||
Browser.switchCursorMode(false);
|
||||
this.settingsDialog.classList.remove('hidden');
|
||||
this.settingsDialogSearch.classList.remove('hidden');
|
||||
|
||||
this.selectSearchEngine = this.currentSearchEngine;
|
||||
this.searchEngineList = SearchUtil.getEngineList();
|
||||
for(var i in this.searchEngineList) {
|
||||
var title = document.createElement('div');
|
||||
title.classList.add('title');
|
||||
var name = document.createElement('p');
|
||||
name.classList.add('name');
|
||||
name.textContent = this.searchEngineList[i].name;
|
||||
title.appendChild(name);
|
||||
|
||||
var check = document.createElement('div');
|
||||
check.classList.add('check');
|
||||
var onoff = document.createElement('p');
|
||||
if( name.textContent == this.currentSearchEngine ) {
|
||||
name.dataset.display = 'selected';
|
||||
onoff.classList.add('on');
|
||||
} else {
|
||||
name.dataset.display = '';
|
||||
onoff.classList.add('off');
|
||||
}
|
||||
check.appendChild(onoff);
|
||||
|
||||
var item = document.createElement('div');
|
||||
item.classList.add('item');
|
||||
item.appendChild(title);
|
||||
item.appendChild(check);
|
||||
item.tabIndex = '0';
|
||||
this.settingsDialogSearchSelectList.appendChild(item);
|
||||
item.addEventListener('mouseup',
|
||||
this.handleDialogSearchSelected.bind(this));
|
||||
item.addEventListener('keyup',
|
||||
this.handleDialogSearchSelected.bind(this));
|
||||
this.focusList.push(item);
|
||||
}
|
||||
this.focusList.push(this.settingsDialogSearchOk);
|
||||
this.focusList.push(this.settingsDialogSearchCancel);
|
||||
this.focusPos = this.focusList.length - 1;
|
||||
this.focusChange(this.focusPos);
|
||||
}
|
||||
},
|
||||
|
||||
handleClearHistoryClick: function settings_handleClearHistoryClick() {
|
||||
BrowserDialog.createDialog('clear_history', null);
|
||||
},
|
||||
|
||||
handleClearCookieClick: function settings_handleClearCookieClick() {
|
||||
BrowserDialog.createDialog('del_cookie', null);
|
||||
},
|
||||
|
||||
clearCookieFailed: function settings_clearCookieFailed() {
|
||||
// this.settingsBannerMessage.innerHTML =
|
||||
// 'Failed to clear cookies and stored data';
|
||||
this.settingsBannerMessage.setAttribute('data-l10n-id', 'LT_FAILED_');
|
||||
this.showBannerMessage();
|
||||
},
|
||||
|
||||
showBannerMessage: function settings_showBannerMessage() {
|
||||
if( this.settingsBannerMessage.dataset.display != 'visible' ) {
|
||||
this.settingsBannerMessage.dataset.display = 'visible';
|
||||
}
|
||||
clearTimeout( this.showBannerMessageTimeoutID );
|
||||
this.showBannerMessageTimeoutID = setTimeout( function() {
|
||||
Settings.settingsBannerMessage.dataset.display = '';
|
||||
}, 3000);
|
||||
},
|
||||
|
||||
hideDialogSearch: function settings_hideDialogSearch() {
|
||||
if( this.isDialogSearchDisplayed() ) {
|
||||
Awesomescreen.pointerImg.style.display = 'none';
|
||||
var childs = this.settingsDialogSearchSelectList.childNodes;
|
||||
var len = childs.length;
|
||||
for(var i = 0 ; i < len ; i ++) {
|
||||
this.settingsDialogSearchSelectList.removeChild(childs[0]);
|
||||
}
|
||||
this.settingsDialogSearch.classList.add('hidden');
|
||||
this.settingsDialog.classList.add('hidden');
|
||||
Browser.switchCursorMode(true);
|
||||
}
|
||||
},
|
||||
|
||||
isDialogSearchDisplayed: function settings_isDialogSearchDisplayed() {
|
||||
return !this.settingsDialogSearch.classList.contains('hidden');
|
||||
},
|
||||
|
||||
handleDialogSearchSelected:
|
||||
function settings_handleDialogSearchSelected(ev) {
|
||||
if( ev ) {
|
||||
ev.preventDefault();
|
||||
}
|
||||
if(( ev.type == 'keyup' ) && ( ev.keyCode != KeyEvent.DOM_VK_RETURN )) {
|
||||
return;
|
||||
}
|
||||
this.selectSearchEngine = ev.currentTarget.textContent;
|
||||
var childs = this.settingsDialogSearchSelectList.childNodes;
|
||||
var len = childs.length;
|
||||
for(var i = 0 ; i < len ; i ++) {
|
||||
if(childs[i].textContent == this.selectSearchEngine) {
|
||||
childs[i].firstChild.firstChild.dataset.display = 'selected';
|
||||
childs[i].lastChild.lastChild.classList.remove('off');
|
||||
childs[i].lastChild.lastChild.classList.add('on');
|
||||
} else {
|
||||
childs[i].firstChild.firstChild.dataset.display = '';
|
||||
childs[i].lastChild.lastChild.classList.remove('on');
|
||||
childs[i].lastChild.lastChild.classList.add('off');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
handleDialogSearchCancel: function settings_handleDialogSearchCancel(ev) {
|
||||
if( ev ) {
|
||||
ev.preventDefault();
|
||||
}
|
||||
if(( ev.type == 'keyup' ) && ( ev.keyCode != KeyEvent.DOM_VK_RETURN )) {
|
||||
return;
|
||||
}
|
||||
// animation end event handler
|
||||
var end_event = (function() {
|
||||
Settings.settingsDialogSearchCancel.removeEventListener('transitionend',
|
||||
end_event, false);
|
||||
Settings.hideDialogSearch();
|
||||
});
|
||||
// end animantion event
|
||||
Settings.settingsDialogSearchCancel.addEventListener('transitionend',
|
||||
end_event, false);
|
||||
document.activeElement.classList.remove('active');
|
||||
},
|
||||
|
||||
handleDialogSearchOk: function settings_handleDialogSearchOk(ev) {
|
||||
if( ev ) {
|
||||
ev.preventDefault();
|
||||
}
|
||||
if(( ev.type == 'keyup' ) && ( ev.keyCode != KeyEvent.DOM_VK_RETURN )) {
|
||||
return;
|
||||
}
|
||||
// animation end event handler
|
||||
var end_event = (function() {
|
||||
Settings.settingsDialogSearchOk.removeEventListener('transitionend',
|
||||
end_event, false);
|
||||
Settings.hideDialogSearch();
|
||||
});
|
||||
|
||||
var setSearchEngine = function () {
|
||||
this.currentSearchEngine = this.selectSearchEngine;
|
||||
this.settingsSearchEngineName.textContent =
|
||||
this.currentSearchEngine;
|
||||
Toolbar.setSearchEngine();
|
||||
};
|
||||
|
||||
// end animantion event
|
||||
Settings.settingsDialogSearchOk.addEventListener('transitionend',
|
||||
end_event, false);
|
||||
if( this.currentSearchEngine != this.selectSearchEngine ) {
|
||||
for(var i in this.searchEngineList) {
|
||||
if( this.selectSearchEngine == this.searchEngineList[i].name ) {
|
||||
SearchUtil.setSearchEngineId(this.searchEngineList[i].id,
|
||||
setSearchEngine.bind(this));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
document.activeElement.classList.remove('active');
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle Key Event.
|
||||
*/
|
||||
handleKeyEvent: function settings_handleKeyEvent(ev) {
|
||||
if( !Settings.isDisplayed() ) {
|
||||
return false;
|
||||
}
|
||||
// in the input area focus (= display keyboard)
|
||||
if(document.activeElement.nodeName == 'INPUT') {
|
||||
return true;
|
||||
}
|
||||
switch( ev.keyCode ) {
|
||||
case KeyEvent.DOM_VK_LEFT :
|
||||
ev.preventDefault();
|
||||
if( Settings.isDialogHomepageDisplayed() ) {
|
||||
if(( Settings.focusPos == 1 ) || ( Settings.focusPos == 4 )) {
|
||||
Settings.focusPos --;
|
||||
Settings.focusChange(Settings.focusPos);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if( Settings.isDialogSearchDisplayed() ) {
|
||||
if( Settings.focusPos == Settings.focusList.length - 1 ) {
|
||||
Settings.focusPos --;
|
||||
Settings.focusChange(Settings.focusPos);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case KeyEvent.DOM_VK_RIGHT :
|
||||
ev.preventDefault();
|
||||
if( Settings.isDialogHomepageDisplayed() ) {
|
||||
if(( Settings.focusPos === 0 ) || ( Settings.focusPos === 3 )) {
|
||||
Settings.focusPos ++;
|
||||
Settings.focusChange(Settings.focusPos);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if( Settings.isDialogSearchDisplayed() ) {
|
||||
if( Settings.focusPos == Settings.focusList.length - 2 ) {
|
||||
Settings.focusPos ++;
|
||||
Settings.focusChange(Settings.focusPos);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case KeyEvent.DOM_VK_UP :
|
||||
ev.preventDefault();
|
||||
if( Settings.isDialogHomepageDisplayed() ) {
|
||||
if(( Settings.focusPos === 2 ) || ( Settings.focusPos === 4 )) {
|
||||
Settings.focusPos -= 2;
|
||||
Settings.focusChange(Settings.focusPos);
|
||||
} else if( Settings.focusPos === 3 ) {
|
||||
Settings.focusPos --;
|
||||
Settings.focusChange(Settings.focusPos);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if( Settings.isDialogSearchDisplayed() ) {
|
||||
if( Settings.focusPos > 0 ) {
|
||||
if( Settings.focusPos >= Settings.focusList.length - 1 ) {
|
||||
Settings.focusPos = Settings.focusList.length - 3;
|
||||
} else {
|
||||
Settings.focusPos --;
|
||||
}
|
||||
Settings.focusChange(Settings.focusPos);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case KeyEvent.DOM_VK_DOWN :
|
||||
ev.preventDefault();
|
||||
if( Settings.isDialogHomepageDisplayed() ) {
|
||||
if(( Settings.focusPos == 1 ) || ( Settings.focusPos === 2 )) {
|
||||
Settings.focusPos ++;
|
||||
Settings.focusChange(Settings.focusPos);
|
||||
} else if( Settings.focusPos === 0 ) {
|
||||
Settings.focusPos += 2;
|
||||
Settings.focusChange(Settings.focusPos);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if( Settings.isDialogSearchDisplayed() ) {
|
||||
if( Settings.focusPos < Settings.focusList.length - 2 ) {
|
||||
Settings.focusPos ++;
|
||||
Settings.focusChange(Settings.focusPos);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case KeyEvent.DOM_VK_RETURN :
|
||||
ev.preventDefault();
|
||||
if( Settings.focusPos === 0 ) {
|
||||
Settings.focusList[Settings.focusPos].focus();
|
||||
if( Settings.isDialogHomepageDisplayed() ) {
|
||||
Awesomescreen.pointerImg.style.display = 'none';
|
||||
}
|
||||
}else{
|
||||
document.activeElement.classList.remove('active');
|
||||
document.activeElement.classList.add('active');
|
||||
}
|
||||
break;
|
||||
|
||||
case KeyEvent.DOM_VK_BACK_SPACE :
|
||||
if( Settings.isDialogHomepageDisplayed() ) {
|
||||
Settings.hideDialogHomepage();
|
||||
return true;
|
||||
}
|
||||
if( Settings.isDialogSearchDisplayed() ) {
|
||||
Settings.hideDialogSearch();
|
||||
return true;
|
||||
}
|
||||
Settings.hide();
|
||||
return true;
|
||||
|
||||
default :
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
941
gaia/tv_apps/browser/js/smartList.js
Executable file
|
|
@ -0,0 +1,941 @@
|
|||
/* globals KeyEvent */
|
||||
|
||||
'use strict';
|
||||
|
||||
(function(exports){
|
||||
|
||||
/**
|
||||
* Max number of list item visible when scroll.
|
||||
* @type {Number}
|
||||
*/
|
||||
const MAX_VISIBLE_ITEM = 7;
|
||||
|
||||
/**
|
||||
* Initial list element query number when first render list view
|
||||
* @type {Number}
|
||||
*/
|
||||
const INIT_LIST_ELEMENT_QUERY_NUMBER = 14;
|
||||
|
||||
/**
|
||||
* Max number of list html element can be render.
|
||||
* @type {Number}
|
||||
*/
|
||||
const MAX_LIST_ELEMENT = 21;
|
||||
|
||||
/**
|
||||
* Height of list item element, unit is rem.
|
||||
* @type {Number}
|
||||
*/
|
||||
const LIST_ITEM_HEIGHT = 12;
|
||||
|
||||
/**
|
||||
* 1rem equals to 10px
|
||||
* @type {Number}
|
||||
*/
|
||||
const PER_REM = 10;
|
||||
|
||||
/**
|
||||
* SmartList constructor
|
||||
* @param {Node} el - Target HTML element of SmartList.
|
||||
* @param {String} l10nTitle - Smart list title string.
|
||||
*/
|
||||
function SmartList(el, l10nTitle){
|
||||
this.el = el;
|
||||
|
||||
this.listEl = null;
|
||||
|
||||
this.listPointerEl = null;
|
||||
|
||||
this.l10nTitle = l10nTitle;
|
||||
|
||||
/**
|
||||
* Number of list item rendered.
|
||||
* @type {Number}
|
||||
*/
|
||||
this.listItemRenderNum = 0;
|
||||
|
||||
/**
|
||||
* Index of focus element in list.
|
||||
* @type {Number}
|
||||
*/
|
||||
this.focusIndex = 0;
|
||||
|
||||
/**
|
||||
* Index of list item start at.
|
||||
* @type {Number}
|
||||
*/
|
||||
this.listIndexStartAt = 0;
|
||||
|
||||
/**
|
||||
* Index of list item end at.
|
||||
* @type {Number}
|
||||
*/
|
||||
this.listIndexEndAt = 0;
|
||||
|
||||
/**
|
||||
* Index of visible list item start at.
|
||||
* @type {Number}
|
||||
*/
|
||||
this.listVisibleStartAt = 0;
|
||||
|
||||
/**
|
||||
* Current navigation folder.
|
||||
* @type {String}
|
||||
*/
|
||||
this.navState = null;
|
||||
|
||||
/**
|
||||
* Save user browser history.
|
||||
* @type {Array}
|
||||
*/
|
||||
this.navHistory = [];
|
||||
|
||||
/**
|
||||
* list items which in dom tree and been initialized but render with data
|
||||
* @type {Array}
|
||||
*/
|
||||
this.initializedItems = [];
|
||||
|
||||
/**
|
||||
* List item element map
|
||||
* @type {Object}
|
||||
*/
|
||||
this.listItemMap = {};
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
SmartList.prototype = {
|
||||
constructor: SmartList,
|
||||
|
||||
/**
|
||||
* Create smart list dom tree architecture
|
||||
*/
|
||||
|
||||
/**
|
||||
* <div class="smart-list-container">
|
||||
* <h2 class="smart-list-title" data-l10n-id={this.l10nTitle}></h2>
|
||||
* <div class="smart-list-wrap">
|
||||
* <ul class="smart-list-view"></ul>
|
||||
* <div class="smart-list-mask"></div>
|
||||
* <div class="smart-list-pointer"></div>
|
||||
* </div>
|
||||
* </div>
|
||||
*/
|
||||
init: function() {
|
||||
var container = document.createElement('div'),
|
||||
title = document.createElement('h2'),
|
||||
listWrap = document.createElement('div'),
|
||||
listView = document.createElement('ul'),
|
||||
listMask = document.createElement('div'),
|
||||
listPointer = document.createElement('div');
|
||||
|
||||
container.classList.add('smart-list-container');
|
||||
title.classList.add('smart-list-title');
|
||||
title.setAttribute('data-l10n-id', this.l10nTitle);
|
||||
listWrap.classList.add('smart-list-wrap');
|
||||
listView.classList.add('smart-list-view');
|
||||
listMask.classList.add('smart-list-mask');
|
||||
listPointer.classList.add('smart-list-pointer');
|
||||
|
||||
container.appendChild(title);
|
||||
container.appendChild(listWrap);
|
||||
listWrap.appendChild(listView);
|
||||
listWrap.appendChild(listMask);
|
||||
listWrap.appendChild(listPointer);
|
||||
|
||||
this.el.classList.add('smart-list');
|
||||
this.el.addEventListener('keyup', this.handleListKeyUp.bind(this));
|
||||
this.el.appendChild(container);
|
||||
this.listEl = listView;
|
||||
this.listPointerEl = listPointer;
|
||||
},
|
||||
|
||||
/**
|
||||
* Open smart list.
|
||||
*/
|
||||
open: function() {
|
||||
this.reset();
|
||||
this.dispatchLoadDataByRange(0, INIT_LIST_ELEMENT_QUERY_NUMBER, null,
|
||||
(listData) => {
|
||||
this.el.classList.add('show');
|
||||
|
||||
if (listData.length > 0) {
|
||||
this.render(listData);
|
||||
var focusEl = this.listItemMap[0];
|
||||
this.pointerItem(focusEl);
|
||||
this.focusItem(focusEl);
|
||||
} else {
|
||||
this.focusItem(this.el);
|
||||
}
|
||||
|
||||
var event = new Event('open');
|
||||
this.el.dispatchEvent(event);
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Close smart list.
|
||||
*/
|
||||
close: function() {
|
||||
var event = new Event('close');
|
||||
this.navState = null;
|
||||
this.navHistory = [];
|
||||
this.el.classList.remove('show');
|
||||
this.el.dispatchEvent(event);
|
||||
if(this.isPointerDisplay()) {
|
||||
this.hideListPointer();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Reset smart list
|
||||
*/
|
||||
reset: function(){
|
||||
var key = 0;
|
||||
|
||||
this.listEl.style.transform = 'translateY(0rem)';
|
||||
|
||||
this.focusIndex = 0;
|
||||
this.listVisibleStartAt = 0;
|
||||
this.listIndexStartAt = 0;
|
||||
this.listIndexEndAt = 0;
|
||||
|
||||
for (key in this.listItemMap) {
|
||||
if (this.listItemMap.hasOwnProperty(key)) {
|
||||
this.resetItem(this.listItemMap[key]);
|
||||
this.initializedItems.push(this.listItemMap[key]);
|
||||
delete this.listItemMap[key];
|
||||
}
|
||||
}
|
||||
|
||||
this.hideListPointer();
|
||||
},
|
||||
|
||||
/**
|
||||
* Go back to previous folder. If there is no previous folder, close list.
|
||||
*/
|
||||
goBack: function() {
|
||||
if (!this.navState) {
|
||||
this.close();
|
||||
} else {
|
||||
this.navHistory.pop();
|
||||
this.navState = this.getCurNavHistory();
|
||||
var folderId = this.navState ? this.navState.folderId : null;
|
||||
this.reset();
|
||||
this.switchListView(folderId);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Render smart list
|
||||
* @param {Array} listData - Array of listData.
|
||||
*/
|
||||
render: function(listData){
|
||||
var itemEl = null,
|
||||
i = 0,
|
||||
length = listData.length;
|
||||
|
||||
for (; i < length; i++) {
|
||||
/*
|
||||
* if there are reseted list item, use these to render data,
|
||||
* else create new html element to render data
|
||||
*/
|
||||
if (this.initializedItems.length > 0) {
|
||||
itemEl = this.initializedItems.pop();
|
||||
this.updateItem(itemEl, listData[i]);
|
||||
} else {
|
||||
itemEl = this.createItem(listData[i]);
|
||||
this.listEl.appendChild(itemEl);
|
||||
this.listItemRenderNum++;
|
||||
}
|
||||
|
||||
itemEl.setAttribute('data-index', i);
|
||||
itemEl.style.transform =
|
||||
'translateY(' + (LIST_ITEM_HEIGHT * i) + 'rem)';
|
||||
this.listItemMap[i] = itemEl;
|
||||
}
|
||||
this.listIndexEndAt = length - 1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Is smart list opened.
|
||||
* @return {Boolean} - true when smart list opened.
|
||||
*/
|
||||
isDisplay: function() {
|
||||
return this.el.classList.contains('show');
|
||||
},
|
||||
|
||||
/**
|
||||
* Add new list item.
|
||||
* @param {Number} index - Index of new list item.
|
||||
* @param {Object} data - The list item data.
|
||||
*/
|
||||
addItem: function(index, data) {
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
var itemEl = null,
|
||||
transform = 0;
|
||||
if (index < this.listIndexStartAt) {
|
||||
// add item to the beginning of the list
|
||||
if (this.initializedItems.length > 0) {
|
||||
itemEl = this.initializedItems.pop();
|
||||
this.updateItem(itemEl, data);
|
||||
} else if (this.listItemRenderNum === MAX_LIST_ELEMENT){
|
||||
itemEl = this.listItemMap[this.listIndexEndAt];
|
||||
this.updateItem(itemEl, data);
|
||||
delete this.listItemMap[this.listIndexEndAt];
|
||||
this.listIndexEndAt--;
|
||||
} else {
|
||||
itemEl = this.createItem(data);
|
||||
this.listEl.appendChild(itemEl);
|
||||
this.listItemRenderNum++;
|
||||
}
|
||||
this.listItemMap[index] = itemEl;
|
||||
itemEl.setAttribute('data-index', index);
|
||||
transform = (index) * LIST_ITEM_HEIGHT;
|
||||
itemEl.style.transform =
|
||||
'translateY(' + transform + 'rem)';
|
||||
this.listIndexStartAt = index;
|
||||
} else if (index > this.listIndexEndAt) {
|
||||
// add item to the end of the list
|
||||
if (this.initializedItems.length > 0) {
|
||||
itemEl = this.initializedItems.pop();
|
||||
this.updateItem(itemEl, data);
|
||||
} else if (this.listItemRenderNum === MAX_LIST_ELEMENT){
|
||||
itemEl = this.listItemMap[this.listIndexStartAt];
|
||||
this.updateItem(itemEl, data);
|
||||
delete this.listItemMap[this.listIndexStartAt];
|
||||
this.listIndexStartAt++;
|
||||
} else {
|
||||
itemEl = this.createItem(data);
|
||||
this.listEl.appendChild(itemEl);
|
||||
this.listItemRenderNum++;
|
||||
}
|
||||
this.listItemMap[index] = itemEl;
|
||||
itemEl.setAttribute('data-index', index);
|
||||
transform = (index) * LIST_ITEM_HEIGHT;
|
||||
itemEl.style.transform =
|
||||
'translateY(' + transform + 'rem)';
|
||||
this.listIndexEndAt = index;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Create List Item.
|
||||
* @param {Object} data - list item data object
|
||||
*/
|
||||
|
||||
/**
|
||||
* <li class="list-item">
|
||||
* <div class="icon-box icon-box-left">
|
||||
* <div class="icon"></div>
|
||||
* </div>
|
||||
* <div class="text-box">
|
||||
* <span class="title"></span>
|
||||
* <span class="uri"></span>
|
||||
* </div>
|
||||
* <div class="icon-box icon-box-right">
|
||||
* <div class="icon" data-icon="arrow-right"></div>
|
||||
* </div>
|
||||
* </li>
|
||||
*/
|
||||
createItem: function(data) {
|
||||
var itemEl = document.createElement('li'),
|
||||
iconLeftEl = document.createElement('div'),
|
||||
iconImgLeftEl = document.createElement('div'),
|
||||
textEl = document.createElement('div'),
|
||||
titleEl = document.createElement('span'),
|
||||
uriEl = document.createElement('span'),
|
||||
iconRightEl = document.createElement('div'),
|
||||
iconImgRightEl = document.createElement('div');
|
||||
|
||||
itemEl.classList.add('list-item');
|
||||
itemEl.setAttribute('tabindex', '0');
|
||||
itemEl.setAttribute('data-type', data.type);
|
||||
iconLeftEl.classList.add('icon-box', 'icon-box-left');
|
||||
iconImgLeftEl.classList.add('icon');
|
||||
iconLeftEl.appendChild(iconImgLeftEl);
|
||||
|
||||
textEl.classList.add('text-box');
|
||||
titleEl.classList.add('title');
|
||||
uriEl.classList.add('uri');
|
||||
textEl.appendChild(titleEl);
|
||||
textEl.appendChild(uriEl);
|
||||
|
||||
iconRightEl.classList.add('icon-box', 'icon-box-right');
|
||||
iconImgRightEl.classList.add('icon');
|
||||
iconRightEl.appendChild(iconImgRightEl);
|
||||
|
||||
itemEl.appendChild(iconLeftEl);
|
||||
itemEl.appendChild(textEl);
|
||||
itemEl.appendChild(iconRightEl);
|
||||
|
||||
this.updateItemContent({
|
||||
item: itemEl,
|
||||
iconImgLeft: iconImgLeftEl,
|
||||
iconImgRight: iconImgRightEl,
|
||||
title: titleEl,
|
||||
uri: uriEl
|
||||
}, data);
|
||||
|
||||
// XXX: delegate these events later
|
||||
itemEl.
|
||||
addEventListener('keydown', this.handleItemKeyDown.bind(this));
|
||||
itemEl.
|
||||
addEventListener('keyup', this.handleItemKeyUp.bind(this));
|
||||
itemEl.
|
||||
addEventListener('mouseup', this.handleItemMouseUp.bind(this));
|
||||
itemEl.
|
||||
addEventListener('mouseover', this.handleItemMouseOver.bind(this));
|
||||
itemEl.
|
||||
addEventListener('mouseout', this.handleItemMouseOut.bind(this));
|
||||
|
||||
return itemEl;
|
||||
},
|
||||
|
||||
/**
|
||||
* Update list item element content.
|
||||
* @param {Node} el - HTML list item to update.
|
||||
* @param {Object} data - list item data object.
|
||||
*/
|
||||
updateItem: function(el, data) {
|
||||
var iconImgLeftEl = el.querySelector('.icon-box-left .icon'),
|
||||
titleEl = el.querySelector('.title'),
|
||||
uriEl = el.querySelector('.uri'),
|
||||
iconImgRightEl = el.querySelector('.icon-box-right .icon');
|
||||
|
||||
this.updateItemContent({
|
||||
item: el,
|
||||
iconImgLeft: iconImgLeftEl,
|
||||
iconImgRight: iconImgRightEl,
|
||||
title: titleEl,
|
||||
uri: uriEl
|
||||
}, data);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the content of the elements in an given item.
|
||||
* @param {Object} elems - all elements have to be updated.
|
||||
* @param {Object} data - list item data object.
|
||||
*/
|
||||
updateItemContent: function(elems, data) {
|
||||
var itemEl = elems.item,
|
||||
iconImgLeftEl = elems.iconImgLeft,
|
||||
iconImgRightEl = elems.iconImgRight,
|
||||
titleEl = elems.title,
|
||||
uriEl = elems.uri;
|
||||
|
||||
if (data.readOnly) {
|
||||
itemEl.setAttribute('readOnly', data.readOnly);
|
||||
} else {
|
||||
itemEl.setAttribute('readOnly', false);
|
||||
}
|
||||
|
||||
if (data.type) {
|
||||
itemEl.setAttribute('data-type', data.type);
|
||||
switch (data.type) {
|
||||
case 'folder':
|
||||
itemEl.setAttribute('data-folder', data.id);
|
||||
iconImgLeftEl.style.backgroundImage = '';
|
||||
iconImgLeftEl.setAttribute('data-icon', 'folder');
|
||||
titleEl.textContent = data.title;
|
||||
uriEl.textContent = '';
|
||||
iconImgRightEl.setAttribute('data-icon', 'arrow-right');
|
||||
break;
|
||||
case 'bookmark':
|
||||
itemEl.setAttribute('data-folder', '');
|
||||
if (data.iconUri) {
|
||||
iconImgLeftEl.style.backgroundImage = 'url(' + data.iconUri +')';
|
||||
iconImgLeftEl.setAttribute('data-icon', '');
|
||||
} else {
|
||||
iconImgLeftEl.style.backgroundImage = '';
|
||||
iconImgLeftEl.setAttribute('data-icon', 'default-fav');
|
||||
}
|
||||
titleEl.textContent = data.title ? data.title : data.uri;
|
||||
uriEl.textContent = data.uri;
|
||||
iconImgRightEl.setAttribute('data-icon', '');
|
||||
break;
|
||||
case 'button':
|
||||
itemEl.setAttribute('data-folder', '');
|
||||
iconImgLeftEl.style.backgroundImage = '';
|
||||
iconImgLeftEl.setAttribute('data-icon', 'arrow-left');
|
||||
titleEl.textContent = data.title;
|
||||
uriEl.textContent = '';
|
||||
iconImgRightEl.setAttribute('data-icon', '');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// The records without "type" will be recognized as history records.
|
||||
itemEl.setAttribute('data-type', 'bookmark');
|
||||
itemEl.setAttribute('data-folder', '');
|
||||
if (data.iconUri) {
|
||||
iconImgLeftEl.setAttribute('data-icon', '');
|
||||
iconImgLeftEl.style.backgroundImage = 'url(' + data.iconUri +')';
|
||||
} else {
|
||||
iconImgLeftEl.setAttribute('data-icon', 'default-fav');
|
||||
iconImgLeftEl.style.backgroundImage = '';
|
||||
}
|
||||
titleEl.textContent = data.title ? data.title : data.uri;
|
||||
uriEl.textContent = data.uri;
|
||||
iconImgRightEl.setAttribute('data-icon', '');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove the focus list item.
|
||||
*/
|
||||
removeFocusItem: function() {
|
||||
var targetEl = null,
|
||||
i = 0;
|
||||
|
||||
targetEl = this.listItemMap[this.focusIndex];
|
||||
if (targetEl) {
|
||||
this.resetItem(targetEl);
|
||||
this.initializedItems.push(targetEl);
|
||||
|
||||
//reindex and update transform of the element behind the focus index
|
||||
for (i = this.focusIndex; i < this.listIndexEndAt; i++) {
|
||||
this.listItemMap[i] = this.listItemMap[i+1];
|
||||
targetEl = this.listItemMap[i];
|
||||
targetEl.setAttribute('data-index', i);
|
||||
this.shiftElement(targetEl, (-1 * LIST_ITEM_HEIGHT));
|
||||
}
|
||||
|
||||
delete this.listItemMap[this.listIndexEndAt];
|
||||
this.listIndexEndAt--;
|
||||
|
||||
// if the removed item is the last item of index,
|
||||
// focus the new last element
|
||||
if (this.listItemMap[this.focusIndex]) {
|
||||
this.focusItem(this.listItemMap[this.focusIndex]);
|
||||
} else if (this.listIndexEndAt !== -1) {
|
||||
this.focusIndex = this.listIndexEndAt;
|
||||
this.focusItem(this.listItemMap[this.focusIndex]);
|
||||
}
|
||||
|
||||
var event = new Event('itemRemoved');
|
||||
this.el.dispatchEvent(event);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Focus list item.
|
||||
* @param {Node} el - HTML list item to focus.
|
||||
*/
|
||||
focusItem: function(el) {
|
||||
el.focus();
|
||||
},
|
||||
|
||||
pointerItem: function(el) {
|
||||
var pos = el.getBoundingClientRect(),
|
||||
transposX = (Math.ceil(pos.right) - 120 ) / PER_REM,
|
||||
transposY = (Math.ceil(pos.bottom) - 40 ) / PER_REM;
|
||||
|
||||
this.listPointerEl.style.transform =
|
||||
'translate(' + transposX + 'rem,' + transposY + 'rem)';
|
||||
this.showListPointer();
|
||||
},
|
||||
|
||||
/**
|
||||
* Focus the First visible list item.
|
||||
*/
|
||||
focusFirstVisibleItem: function() {
|
||||
var targetEl = null;
|
||||
|
||||
// if there is list item rendered and the current active element not in
|
||||
// smart list, focus the first visible list item.
|
||||
if (this.listIndexEndAt !== -1 &&
|
||||
Array.prototype.indexOf.call(
|
||||
this.listEl.children,
|
||||
document.activeElement) === -1) {
|
||||
this.focusIndex = this.listVisibleStartAt;
|
||||
targetEl = this.listItemMap[this.focusIndex];
|
||||
if (targetEl) {
|
||||
this.pointerItem(targetEl);
|
||||
this.focusItem(targetEl);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Reset list item.
|
||||
* @param {Node} el - HTML list item to focus.
|
||||
*/
|
||||
resetItem: function(el) {
|
||||
var iconImgEl = el.querySelector('.icon-box-left .icon'),
|
||||
titleEl = el.querySelector('.title'),
|
||||
uriEl = el.querySelector('.uri');
|
||||
|
||||
el.setAttribute('data-index', -1);
|
||||
el.setAttribute('data-type', '');
|
||||
el.setAttribute('data-folder', '');
|
||||
el.setAttribute('readOnly', false);
|
||||
el.style.transform = '';
|
||||
iconImgEl.style.backgroundImage = '';
|
||||
iconImgEl.setAttribute('data-icon', '');
|
||||
titleEl.textContent = '';
|
||||
uriEl.textContent = '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Preload the item out of visible view.
|
||||
* @param {Number} listIndex - preload list index.
|
||||
*/
|
||||
preloadItem: function(listIndex) {
|
||||
var dataIndex = 0;
|
||||
|
||||
if (this.navState) {
|
||||
if (listIndex === 0) {
|
||||
var data = this.generateBackButtonData(this.navState.folderTitle);
|
||||
this.addItem(0, data);
|
||||
} else {
|
||||
dataIndex = listIndex - 1;
|
||||
this.dispatchLoadDataByIndex(
|
||||
listIndex,
|
||||
dataIndex,
|
||||
this.navState.folderId
|
||||
);
|
||||
}
|
||||
} else {
|
||||
dataIndex = listIndex;
|
||||
this.dispatchLoadDataByIndex(
|
||||
listIndex,
|
||||
dataIndex,
|
||||
null
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Shift list item transform
|
||||
* @param {Node} el - list item element to transform
|
||||
* @param {Nunber} shift - shift transform, unit is rem
|
||||
*/
|
||||
shiftElement: function(el, shift) {
|
||||
var style = el.style.transform.split('('),
|
||||
transform = parseInt(style[1], 10);
|
||||
transform += shift;
|
||||
el.style.transform =
|
||||
'translateY(' + transform + 'rem) translateZ(0.01px)';
|
||||
},
|
||||
|
||||
/**
|
||||
* Get Focus list element's index
|
||||
*/
|
||||
getFocusItemIndex: function() {
|
||||
return this.focusIndex;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get Focus list element's uri content
|
||||
*/
|
||||
getFocusItemUri: function() {
|
||||
var targetEl = this.listItemMap[this.focusIndex];
|
||||
return targetEl ? targetEl.querySelector('.uri').textContent : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get Focus list element's title content
|
||||
*/
|
||||
getFocusItemTitle: function() {
|
||||
var targetEl = this.listItemMap[this.focusIndex];
|
||||
return targetEl ? targetEl.querySelector('.title').textContent : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Update focus list element's title content
|
||||
* @param {String} title - title to update
|
||||
*/
|
||||
updateFocusItemTitle: function(title) {
|
||||
var targetEl = this.listItemMap[this.focusIndex];
|
||||
|
||||
if (targetEl) {
|
||||
targetEl.querySelector('.title').textContent = title;
|
||||
this.focusItem(targetEl);
|
||||
var event = new Event('itemUpdated');
|
||||
this.el.dispatchEvent(event);
|
||||
}
|
||||
},
|
||||
|
||||
isPointerDisplay: function() {
|
||||
return this.listPointerEl.classList.contains('show');
|
||||
},
|
||||
|
||||
showListPointer: function() {
|
||||
this.listPointerEl.classList.add('show');
|
||||
},
|
||||
|
||||
hideListPointer: function() {
|
||||
this.listPointerEl.classList.remove('show');
|
||||
},
|
||||
|
||||
/**
|
||||
* Add folder id and folder title
|
||||
* @param {[type]} folderId [description]
|
||||
* @param {[type]} folderTitle [description]
|
||||
*/
|
||||
addNavHistory: function(folderId, folderTitle) {
|
||||
this.navHistory.push({
|
||||
folderId: folderId,
|
||||
folderTitle: folderTitle
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Get current user browse state.
|
||||
* @return {String} current user browse folder.
|
||||
*/
|
||||
getCurNavHistory: function() {
|
||||
var len = this.navHistory.length;
|
||||
if (len > 0) {
|
||||
return this.navHistory[len - 1];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Generate back button data.
|
||||
* @return {Object} - back button data
|
||||
*/
|
||||
generateBackButtonData: function(title) {
|
||||
return {
|
||||
type: 'button',
|
||||
title: 'Back to ' + title
|
||||
};
|
||||
},
|
||||
|
||||
switchListView: function(folderId) {
|
||||
this.dispatchLoadDataByRange(0, INIT_LIST_ELEMENT_QUERY_NUMBER, folderId,
|
||||
(listData) => {
|
||||
// if user is browser list data in a folder,
|
||||
// add back button data at the first place of listData
|
||||
if (this.navState) {
|
||||
listData.unshift(
|
||||
this.generateBackButtonData(this.navState.folderTitle)
|
||||
);
|
||||
}
|
||||
|
||||
if (listData.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.render(listData);
|
||||
|
||||
// focus the first item in list. if the first item is button and list
|
||||
// item length is bigger than 1, focus the second item
|
||||
this.focusIndex = 0;
|
||||
if (this.navState && this.listIndexEndAt > 0) {
|
||||
this.focusIndex = 1;
|
||||
}
|
||||
var focusEl = this.listItemMap[this.focusIndex];
|
||||
this.pointerItem(focusEl);
|
||||
this.focusItem(focusEl);
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Move focus to the previous element
|
||||
*/
|
||||
moveFocusIndexUp: function() {
|
||||
this.focusIndex -= 1;
|
||||
var preloadItemIndex = this.focusIndex - MAX_VISIBLE_ITEM;
|
||||
if (preloadItemIndex >= 0 && preloadItemIndex < this.listIndexStartAt) {
|
||||
this.preloadItem(preloadItemIndex);
|
||||
}
|
||||
|
||||
// if the new focus element is before this.listVisibleStartAt,
|
||||
// update list item's transform to shift down
|
||||
var targetEl = this.listItemMap[this.focusIndex];
|
||||
if (this.focusIndex < this.listVisibleStartAt) {
|
||||
this.listVisibleStartAt--;
|
||||
this.shiftElement(this.listEl, LIST_ITEM_HEIGHT);
|
||||
this.focusItem(targetEl);
|
||||
} else {
|
||||
this.pointerItem(targetEl);
|
||||
this.focusItem(targetEl);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Move focus to the next element
|
||||
*/
|
||||
moveFocusIndexDown: function() {
|
||||
this.focusIndex += 1;
|
||||
|
||||
// pre-load list item later then listIndexEndAt
|
||||
var preloadItemIndex = this.focusIndex + MAX_VISIBLE_ITEM;
|
||||
if (preloadItemIndex > this.listIndexEndAt) {
|
||||
this.preloadItem(preloadItemIndex);
|
||||
}
|
||||
|
||||
// if the new focus element is after this.listIndexEndAt,
|
||||
// update list item's transform to shift up
|
||||
var targetEl = this.listItemMap[this.focusIndex];
|
||||
if ((this.focusIndex - this.listVisibleStartAt) ===
|
||||
MAX_VISIBLE_ITEM ) {
|
||||
this.listVisibleStartAt++;
|
||||
this.shiftElement(this.listEl, (-1 * LIST_ITEM_HEIGHT));
|
||||
this.focusItem(targetEl);
|
||||
} else {
|
||||
this.pointerItem(targetEl);
|
||||
this.focusItem(targetEl);
|
||||
}
|
||||
},
|
||||
|
||||
handleListKeyUp: function(e) {
|
||||
switch(e.keyCode){
|
||||
case KeyEvent.DOM_VK_ESCAPE:
|
||||
case KeyEvent.DOM_VK_BACK_SPACE:
|
||||
this.goBack();
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
handleItemKeyDown: function(e) {
|
||||
switch(e.keyCode){
|
||||
case KeyEvent.DOM_VK_UP:
|
||||
if(this.focusIndex > this.listIndexStartAt) {
|
||||
this.moveFocusIndexUp();
|
||||
}
|
||||
break;
|
||||
case KeyEvent.DOM_VK_DOWN:
|
||||
if(this.focusIndex < this.listIndexEndAt) {
|
||||
this.moveFocusIndexDown();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
handleItemKeyUp: function(e) {
|
||||
switch(e.keyCode){
|
||||
case KeyEvent.DOM_VK_SUBMENU:
|
||||
this.handleKeySubmenu(e);
|
||||
break;
|
||||
case KeyEvent.DOM_VK_RETURN:
|
||||
this.handleKeyReturn(e);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
handleItemMouseUp: function(e) {
|
||||
switch(e.button){
|
||||
case 0 :
|
||||
// left click
|
||||
this.handleKeyReturn(e);
|
||||
break;
|
||||
case 2:
|
||||
//right click
|
||||
this.handleKeySubmenu(e);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
handleItemMouseOver: function(e) {
|
||||
var targetEl = e.currentTarget;
|
||||
if (targetEl) {
|
||||
var dataIndex = targetEl.getAttribute('data-index');
|
||||
var event = new CustomEvent('mouseOverItem', {detail: targetEl});
|
||||
targetEl.focus();
|
||||
this.focusIndex = parseInt(dataIndex, 10);
|
||||
this.el.dispatchEvent(event);
|
||||
}
|
||||
},
|
||||
|
||||
handleItemMouseOut: function(e) {
|
||||
var targetEl = e.currentTarget;
|
||||
if (targetEl) {
|
||||
this.hideListPointer();
|
||||
targetEl.blur();
|
||||
}
|
||||
},
|
||||
|
||||
handleKeyReturn: function(e) {
|
||||
var targetEl = e.currentTarget,
|
||||
type = targetEl.getAttribute('data-type'),
|
||||
folderId = null;
|
||||
|
||||
switch(type) {
|
||||
case 'folder':
|
||||
var folderTitle = targetEl.querySelector('.title').textContent;
|
||||
|
||||
folderId = targetEl.getAttribute('data-folder');
|
||||
this.addNavHistory(folderId, folderTitle);
|
||||
this.navState = this.getCurNavHistory();
|
||||
this.reset();
|
||||
this.switchListView(folderId);
|
||||
break;
|
||||
case 'bookmark':
|
||||
var uriEL = targetEl.querySelector('.uri');
|
||||
if (uriEL) {
|
||||
this.dispatchDisplayWebsite(uriEL.textContent);
|
||||
this.close();
|
||||
}
|
||||
break;
|
||||
case 'button':
|
||||
this.navHistory.pop();
|
||||
this.navState = this.getCurNavHistory();
|
||||
folderId = this.navState ? this.navState.folderId : null;
|
||||
this.reset();
|
||||
this.switchListView(folderId);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
handleKeySubmenu: function(e) {
|
||||
var targetEl = e.currentTarget;
|
||||
if (targetEl.getAttribute('data-type') === 'bookmark') {
|
||||
var event = new CustomEvent('showSubMenu', {
|
||||
detail: {
|
||||
readOnly: targetEl.getAttribute('readOnly')
|
||||
}
|
||||
});
|
||||
this.el.dispatchEvent(event);
|
||||
}
|
||||
},
|
||||
|
||||
dispatchDisplayWebsite: function(uri) {
|
||||
var event = new CustomEvent('displayWebsite', {detail: uri});
|
||||
this.el.dispatchEvent(event);
|
||||
},
|
||||
|
||||
dispatchLoadDataByRange: function(start, number, folderId, cb) {
|
||||
var eventDetail = {
|
||||
startAt: start,
|
||||
number: number,
|
||||
folderId: folderId,
|
||||
callback: cb
|
||||
};
|
||||
var event = new CustomEvent('loadDataByRange', {detail: eventDetail});
|
||||
this.el.dispatchEvent(event);
|
||||
},
|
||||
|
||||
dispatchLoadDataByIndex: function(listIndex, dataIndex, navState) {
|
||||
var event = new CustomEvent('loadDataByIndex', {
|
||||
detail: {
|
||||
listIndex: listIndex,
|
||||
dataIndex: dataIndex,
|
||||
folderId: navState
|
||||
}});
|
||||
this.el.dispatchEvent(event);
|
||||
}
|
||||
};
|
||||
|
||||
exports.SmartList = SmartList;
|
||||
})(window);
|
||||
107
gaia/tv_apps/browser/js/sync/bookmarks.js
Executable file
|
|
@ -0,0 +1,107 @@
|
|||
/* 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/. */
|
||||
|
||||
'use strict';
|
||||
|
||||
/* exported SyncBookmark */
|
||||
/* global SyncBrowserDB */
|
||||
/* global SyncDsHelper */
|
||||
|
||||
var SyncBookmark = (function () {
|
||||
var syncDataStore;
|
||||
|
||||
function updateWrapper(data) {
|
||||
return new Promise(resolve => {
|
||||
if (data.deleted) {
|
||||
SyncBrowserDB.removeBookmark(data.id, () => {
|
||||
resolve();
|
||||
});
|
||||
} else {
|
||||
SyncBrowserDB.updateRawBookmark(data, () => {
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleTask(task) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var data = [];
|
||||
if (task.data && task.data.fxsyncRecords) {
|
||||
for (var key in task.data.fxsyncRecords) {
|
||||
data.push(task.data.fxsyncRecords[key]);
|
||||
}
|
||||
}
|
||||
switch(task.operation) {
|
||||
case 'update':
|
||||
case 'add':
|
||||
Promise.all(data.map(updateWrapper)).then(resolve);
|
||||
break;
|
||||
case 'clear':
|
||||
// Ignore clear operation.
|
||||
resolve();
|
||||
break;
|
||||
case 'remove':
|
||||
getBookmarkByDsId(task.id, bookmark => {
|
||||
if (bookmark) {
|
||||
SyncBrowserDB.removeBookmark(bookmark.id, () => {
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'done':
|
||||
resolve();
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getBookmarkByDsId(dsid, callback) {
|
||||
SyncBrowserDB.getBookmark({bmkUri: dsid}, bookmark => {
|
||||
if (bookmark) {
|
||||
callback(bookmark);
|
||||
} else {
|
||||
var specialType =
|
||||
['query', 'microsummary', 'folder', 'livemark', 'separator'];
|
||||
var isSpecialType = specialType.some(value => {
|
||||
return dsid.indexOf(value + '|') === 0;
|
||||
});
|
||||
var tmp = dsid.split('|');
|
||||
if (isSpecialType && tmp.length === 2) {
|
||||
var fxsyncId = tmp[1];
|
||||
SyncBrowserDB.getBookmark(fxsyncId, callback);
|
||||
} else {
|
||||
console.warn('trying to delete a unknown type?', dsid);
|
||||
callback(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function start() {
|
||||
if (syncDataStore) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
syncDataStore = new SyncDsHelper('bookmarks_store');
|
||||
return syncDataStore.init().then(() => {
|
||||
return syncDataStore.start(handleTask);
|
||||
});
|
||||
}
|
||||
|
||||
function stop() {
|
||||
if (!syncDataStore) {
|
||||
return Promise.reject('Uninitialized DataStore');
|
||||
}
|
||||
return syncDataStore.stop().then(() => {
|
||||
syncDataStore = null;
|
||||
return SyncBrowserDB.clearBookmarks();
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
start: start,
|
||||
stop: stop
|
||||
};
|
||||
})();
|
||||
1958
gaia/tv_apps/browser/js/sync/db.js
Executable file
113
gaia/tv_apps/browser/js/sync/ds_helper.js
Executable file
|
|
@ -0,0 +1,113 @@
|
|||
/* 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/. */
|
||||
|
||||
'use strict';
|
||||
|
||||
/* exported SyncDsHelper */
|
||||
/* global localStorage */
|
||||
|
||||
var SyncDsHelper = function (dataStoreName) {
|
||||
if (typeof dataStoreName !== 'string') {
|
||||
throw new Event('Incorrect DataStore name.');
|
||||
}
|
||||
this.dataStoreName = dataStoreName;
|
||||
this.dataStoreRevId = dataStoreName + '::revId';
|
||||
};
|
||||
|
||||
SyncDsHelper.prototype = {
|
||||
store: null,
|
||||
dataChangeHandler: null,
|
||||
|
||||
init() {
|
||||
return this._ensureStore();
|
||||
},
|
||||
|
||||
_ensureStore() {
|
||||
if (this.store) {
|
||||
return Promise.resolve(this.store);
|
||||
}
|
||||
return navigator.getDataStores(this.dataStoreName).then(stores => {
|
||||
this.store = stores[0];
|
||||
return this.store;
|
||||
});
|
||||
},
|
||||
|
||||
setSyncedRevId(revId) {
|
||||
localStorage.setItem(this.dataStoreRevId, revId);
|
||||
},
|
||||
|
||||
getSyncedRevId() {
|
||||
return localStorage.getItem(this.dataStoreRevId);
|
||||
},
|
||||
|
||||
registerStoreChangeEvent(handler) {
|
||||
this._ensureStore().then(() => {
|
||||
if (!this.dataChangeHandler) {
|
||||
this.store.removeEventListener('change', this.dataChangeHandler);
|
||||
}
|
||||
this.dataChangeHandler = handler;
|
||||
this.store.addEventListener('change', this.dataChangeHandler);
|
||||
});
|
||||
},
|
||||
|
||||
unregisterStoreChangeEvent() {
|
||||
return this._ensureStore().then(() => {
|
||||
this.store.removeEventListener('change', this.dataChangeHandler);
|
||||
this.dataChangeHandler = null;
|
||||
});
|
||||
},
|
||||
|
||||
clear() {
|
||||
localStorage.removeItem(this.dataStoreRevId);
|
||||
return this._ensureStore().then(() => {
|
||||
return this.store.clear();
|
||||
});
|
||||
},
|
||||
|
||||
start(handleTask) {
|
||||
return this.init().then(() => {
|
||||
this.registerStoreChangeEvent(() => {
|
||||
this.dataStoreSync(handleTask);
|
||||
});
|
||||
return this.dataStoreSync(handleTask);
|
||||
});
|
||||
},
|
||||
|
||||
stop() {
|
||||
return this.unregisterStoreChangeEvent().then(this.clear.bind(this));
|
||||
},
|
||||
|
||||
dataStoreSync(handle) {
|
||||
return this._ensureStore().then(() => {
|
||||
var _revId = this.getSyncedRevId();
|
||||
return new Promise((resolve, reject) => {
|
||||
var runNextTask = (cursor) => {
|
||||
cursor.next().then(task => {
|
||||
manageTask(cursor, task);
|
||||
});
|
||||
};
|
||||
|
||||
var post = (cursor, task) => {
|
||||
if (task.operation === 'done') {
|
||||
this.setSyncedRevId(this.store.revisionId);
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
runNextTask(cursor);
|
||||
};
|
||||
|
||||
var manageTask = (cursor, task) => {
|
||||
if (handle) {
|
||||
handle(task).then(() => post(cursor, task));
|
||||
} else {
|
||||
post(cursor, task);
|
||||
}
|
||||
};
|
||||
|
||||
runNextTask(this.store.sync(_revId));
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
86
gaia/tv_apps/browser/js/sync/history.js
Executable file
|
|
@ -0,0 +1,86 @@
|
|||
/* 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/. */
|
||||
|
||||
'use strict';
|
||||
|
||||
/* exported SyncHistory */
|
||||
/* global SyncBrowserDB */
|
||||
/* global SyncDsHelper */
|
||||
|
||||
/*
|
||||
exampleHistroyInIndexedDB = {
|
||||
"uri": "http://example.com/",
|
||||
"title": "Hello World",
|
||||
"frecency": 1,
|
||||
"iconUri": "http://example.com/favicon.ico",
|
||||
"screenshot": {}
|
||||
}
|
||||
*/
|
||||
|
||||
var SyncHistory = (function () {
|
||||
var syncDataStore;
|
||||
|
||||
function handleTask(task) {
|
||||
return new Promise(resolve => {
|
||||
switch(task.operation) {
|
||||
case 'update':
|
||||
case 'add':
|
||||
var data = {};
|
||||
var syncedData = task.data;
|
||||
if (syncedData && syncedData.url &&
|
||||
Array.isArray(syncedData.visits) && syncedData.visits.length > 0) {
|
||||
data.uri = syncedData.url;
|
||||
data.title = syncedData.title;
|
||||
data.fxsyncId = syncedData.fxsyncId;
|
||||
data.timestamp = syncedData.visits[0];
|
||||
} else {
|
||||
console.warn('Invalid places record:', task);
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
SyncBrowserDB.updateRawHistory(data, () => {
|
||||
resolve();
|
||||
});
|
||||
break;
|
||||
case 'clear':
|
||||
// Ignore clear operation.
|
||||
resolve();
|
||||
break;
|
||||
case 'remove':
|
||||
SyncBrowserDB.removeHistory(task.id, () => {
|
||||
resolve();
|
||||
});
|
||||
break;
|
||||
case 'done':
|
||||
resolve();
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function start() {
|
||||
if (syncDataStore) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
syncDataStore = new SyncDsHelper('places');
|
||||
return syncDataStore.init().then(() => {
|
||||
return syncDataStore.start(handleTask);
|
||||
});
|
||||
}
|
||||
|
||||
function stop() {
|
||||
if (!syncDataStore) {
|
||||
return Promise.reject('Uninitialized DataStore');
|
||||
}
|
||||
return syncDataStore.stop().then(() => {
|
||||
syncDataStore = null;
|
||||
return SyncBrowserDB.clearHistoryDeep();
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
start: start,
|
||||
stop: stop
|
||||
};
|
||||
})();
|
||||
163
gaia/tv_apps/browser/js/sync/manager_bridge.js
Executable file
|
|
@ -0,0 +1,163 @@
|
|||
/* 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 module acts as a bridge between the browser UI and the Sync manager
|
||||
* that lives in the System application.
|
||||
*
|
||||
* It allows consumers to subscribe to updates done in the Sync state machine
|
||||
* so they can update the UI accordingly.
|
||||
*
|
||||
* The simple high level picture of Sync in the browser is:
|
||||
*
|
||||
* settings.js toolbar.js
|
||||
* | |
|
||||
* | |
|
||||
* \______ manager_bridge.js _______/
|
||||
* |
|
||||
* | IAC
|
||||
* |
|
||||
* smart_system/sync_manager.js
|
||||
*
|
||||
*/
|
||||
|
||||
/* global LazyLoader */
|
||||
/* global SyncBookmark */
|
||||
/* global SyncHistory */
|
||||
|
||||
'use strict';
|
||||
|
||||
(function(exports) {
|
||||
|
||||
const DEBUG = false;
|
||||
function debug() {
|
||||
if (DEBUG) {
|
||||
console.log('[SyncManagerBridge] ' + Array.slice(arguments).concat());
|
||||
}
|
||||
}
|
||||
|
||||
var SyncManagerBridge = {
|
||||
_port: null,
|
||||
_requests: new Map(),
|
||||
_listeners: new Map(),
|
||||
|
||||
addListener(listener) {
|
||||
debug('addListener', listener);
|
||||
if (!this._listeners.has(listener)) {
|
||||
this._listeners.set(listener);
|
||||
}
|
||||
},
|
||||
|
||||
removeListener(listener) {
|
||||
debug('removeListener', listener);
|
||||
if (!this._listeners.has(listener)) {
|
||||
return;
|
||||
}
|
||||
this._listeners.delete(listener);
|
||||
},
|
||||
|
||||
connect() {
|
||||
if (this._port) {
|
||||
return Promise.resolve(this._port);
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
navigator.mozApps.getSelf().onsuccess = event => {
|
||||
var app = event.target.result;
|
||||
app.connect('gaia-sync-management').then(ports => {
|
||||
if (!ports || !ports.length) {
|
||||
return reject();
|
||||
}
|
||||
this._port = ports[0];
|
||||
this._port.onmessage = this.onmessage.bind(this);
|
||||
resolve(this._port);
|
||||
}).catch(reject);
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
iacRequest(request) {
|
||||
debug('iacRequest', JSON.stringify(request));
|
||||
return new Promise(resolve => {
|
||||
this.connect().then(port => {
|
||||
if (request.id) {
|
||||
this._requests.set(request.id, resolve);
|
||||
}
|
||||
port.postMessage(request);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
onmessage(event) {
|
||||
var self = this;
|
||||
function notify() {
|
||||
if (self._listeners.size) {
|
||||
Array.from(self._listeners.keys()).forEach(listener => {
|
||||
listener(message);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var message = event.data;
|
||||
if (!message) {
|
||||
return;
|
||||
}
|
||||
|
||||
debug('message', JSON.stringify(message));
|
||||
|
||||
if (message.id && this._requests.has(message.id)) {
|
||||
this._requests.get(message.id)(message);
|
||||
this._requests.delete(message.id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.name !== 'onsyncchange') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.state == 'disabled' ||
|
||||
message.state == 'enabled') {
|
||||
LazyLoader.load([
|
||||
'js/sync/ds_helper.js',
|
||||
'js/sync/bookmarks.js',
|
||||
'js/sync/history.js'
|
||||
]).then(() => {
|
||||
var method = message.state == 'enabled' ? 'start'
|
||||
: 'stop';
|
||||
Promise.all([
|
||||
SyncBookmark[method](),
|
||||
SyncHistory[method]()
|
||||
]).catch(error => {
|
||||
console.warn(error);
|
||||
});
|
||||
|
||||
notify();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
notify();
|
||||
},
|
||||
|
||||
getInfo() {
|
||||
return this.iacRequest({
|
||||
name: 'getInfo',
|
||||
id: Date.now()
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
['enable',
|
||||
'disable',
|
||||
'sync'].forEach(requestName => {
|
||||
SyncManagerBridge[requestName] = () => {
|
||||
return SyncManagerBridge.iacRequest({
|
||||
name: requestName
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
exports.SyncManagerBridge = SyncManagerBridge;
|
||||
|
||||
}(window));
|
||||
507
gaia/tv_apps/browser/js/sync/settings.js
Executable file
|
|
@ -0,0 +1,507 @@
|
|||
/* 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 Awesomescreen */
|
||||
/* global Browser */
|
||||
/* global BrowserDialog */
|
||||
/* global ERROR_DIALOG_CLOSED_BY_USER */
|
||||
/* global ERROR_INVALID_SYNC_ACCOUNT */
|
||||
/* global ERROR_OFFLINE */
|
||||
/* global ERROR_SYNC_APP_KILLED */
|
||||
/* global ERROR_UNKNOWN */
|
||||
/* global LazyLoader */
|
||||
/* global Settings */
|
||||
/* global SettingsListener */
|
||||
/* global SyncManagerBridge */
|
||||
|
||||
'use strict';
|
||||
|
||||
(function(exports) {
|
||||
const DEBUG = false;
|
||||
function debug() {
|
||||
if (DEBUG) {
|
||||
console.log('[FirefoxSyncSettings] ' + Array.slice(arguments).concat());
|
||||
}
|
||||
}
|
||||
|
||||
// Screens
|
||||
const ENABLED = 'enabled';
|
||||
const DISABLED = 'disabled';
|
||||
|
||||
const BOOKMARKS_SETTING = 'sync.collections.bookmarks.enabled';
|
||||
const HISTORY_SETTING = 'sync.collections.history.enabled';
|
||||
|
||||
const ELEMENTS = [{
|
||||
screen: DISABLED,
|
||||
selector: '#fxsync-sign-in-button',
|
||||
event: 'mouseup',
|
||||
listener: 'enable'
|
||||
}, {
|
||||
screen: ENABLED,
|
||||
selector: '#fxsync-signed-in-as'
|
||||
}, {
|
||||
screen: ENABLED,
|
||||
selector: '#fxsync-sync-now-button',
|
||||
event: 'mouseup',
|
||||
listener: 'sync'
|
||||
}, {
|
||||
screen: ENABLED,
|
||||
selector: '#fxsync-sign-out-button',
|
||||
event: 'mouseup',
|
||||
listener: 'disable'
|
||||
}, {
|
||||
screen: ENABLED,
|
||||
selector: '#fxsync-collection-bookmarks',
|
||||
event: 'click',
|
||||
listener: 'onbookmarkschecked',
|
||||
init: 'onbookmarkschange'
|
||||
}, {
|
||||
screen: ENABLED,
|
||||
selector: '#fxsync-collection-history',
|
||||
event: 'click',
|
||||
listener: 'onhistorychecked',
|
||||
init: 'onhistorychange'
|
||||
}, {
|
||||
screen: ENABLED,
|
||||
selector: '#fxsync-tos',
|
||||
event: 'click',
|
||||
listener: 'openTos'
|
||||
}, {
|
||||
screen: ENABLED,
|
||||
selector: '#fxsync-privacy',
|
||||
event: 'click',
|
||||
listener: 'openPrivacy'
|
||||
}];
|
||||
|
||||
function getElementName(str) {
|
||||
str = str.toLowerCase().replace('#fxsync-', '');
|
||||
return str.replace(/-([a-z])/g, g => {
|
||||
return g[1].toUpperCase();
|
||||
});
|
||||
}
|
||||
|
||||
var FirefoxSyncSettings = {
|
||||
init() {
|
||||
this.area = document.querySelector('#fxsync-area');
|
||||
this.elements = {
|
||||
enabled: this.area.querySelector('#fxsync-enabled'),
|
||||
disabled: this.area.querySelector('#fxsync-disabled')
|
||||
};
|
||||
this.listeners = new Map();
|
||||
this.collections = new Map();
|
||||
this.screen = null;
|
||||
this.state = 'disabled';
|
||||
|
||||
this.showScreen(DISABLED);
|
||||
|
||||
LazyLoader.load('shared/js/settings_listener.js').then(() => {
|
||||
[{
|
||||
name: BOOKMARKS_SETTING,
|
||||
onchange: 'onbookmarkschange'
|
||||
}, {
|
||||
name: HISTORY_SETTING,
|
||||
onchange: 'onhistorychange'
|
||||
}].forEach(setting => {
|
||||
SettingsListener.observe(setting.name, true, enabled => {
|
||||
debug(setting.name + ' changed to ' + enabled);
|
||||
enabled ? this.collections.set(setting.name, enabled)
|
||||
: this.collections.delete(setting.name);
|
||||
this[setting.onchange]();
|
||||
this.maybeEnableSyncNow();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
SyncManagerBridge.addListener(this.onsyncchange.bind(this));
|
||||
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
debug('Visibility change', document.hidden);
|
||||
if (!document.hidden) {
|
||||
this.refresh();
|
||||
}
|
||||
});
|
||||
|
||||
this.refresh();
|
||||
},
|
||||
|
||||
refresh() {
|
||||
debug('Refreshing');
|
||||
SyncManagerBridge.getInfo().then(this.onsyncchange.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* This is where most part of the Sync settings logic lives.
|
||||
*
|
||||
* Here we handle Sync lifecycle events coming from the SyncManager
|
||||
* through the SyncMangerBridge. We react to these events by
|
||||
* changing the screen depending on the state.
|
||||
*
|
||||
* We show two possible different state:
|
||||
* 1. Logged out screen. We simply show the user what Sync is and
|
||||
* allow her to start using it or to keep walking.
|
||||
* 2. Logged in screen. We show to the user several different options:
|
||||
* + The user owning the Sync account. If the account belongs to a
|
||||
* verified user that previosly used Sync, we are fine, if not, we
|
||||
* show a warning asking the user to go to other Firefox client to
|
||||
* create a FxA and login into Sync.
|
||||
* + A button to disable sync. Clicking it will log the user out from
|
||||
* FxA and will clear the synchronized data.
|
||||
* + A button to start a sync on demand. Clicking it will disable the
|
||||
* button and the collections switches while the synchronization is
|
||||
* being performed. Once the sync is done successfully, we enable
|
||||
* all the options back and refresh the last sync time.
|
||||
* We disable this button if no collection is selected.
|
||||
* + Collections switches. Allow the user to select which collections
|
||||
* she wants to keep synchronized. If no collection is selected, the
|
||||
* synchronization will be disabled.
|
||||
* + ToS and Privacy links.
|
||||
*/
|
||||
|
||||
onsyncchange(message) {
|
||||
debug(JSON.stringify(message));
|
||||
if (!message || !message.state) {
|
||||
throw new Error('Missing sync state');
|
||||
}
|
||||
switch (message.state) {
|
||||
case 'disabled':
|
||||
// We want to show a dialog once Sync is disabled
|
||||
// but we only want to do that if it's disabled via user action
|
||||
// and the user has already logged in.
|
||||
// (and not because it is already disabled from a previous run).
|
||||
if (this.state === 'disabling' &&
|
||||
(this.previousState === 'enabled' ||
|
||||
this.previousState === 'syncing')) {
|
||||
navigator.mozL10n.formatValue('fxsync-disabled').then(result => {
|
||||
window.alert(result);
|
||||
});
|
||||
}
|
||||
this.showScreen(DISABLED);
|
||||
this.hideEnabling();
|
||||
break;
|
||||
case 'enabling':
|
||||
this.showEnabling();
|
||||
break;
|
||||
case 'enabled':
|
||||
// We want to show a dialog once Sync is enabled
|
||||
// but we only want to do that if its enabled via user action
|
||||
// (and not because it is already enabled from a previous run).
|
||||
if (this.state === 'enabling') {
|
||||
navigator.mozL10n.formatValue('fxsync-enabled').then(result => {
|
||||
window.alert(result);
|
||||
});
|
||||
}
|
||||
this.hideEnabling();
|
||||
this.showScreen(ENABLED);
|
||||
this.showUser(message.user);
|
||||
this.showSyncNow();
|
||||
break;
|
||||
case 'syncing':
|
||||
this.showScreen(ENABLED);
|
||||
// In case that the user opens the browser app while we are on a
|
||||
// syncing state the previous 'enabled' state is missed and so
|
||||
// we need to make sure that we show the user here as well.
|
||||
this.showUser(message.user);
|
||||
this.showSyncing();
|
||||
break;
|
||||
case 'errored':
|
||||
LazyLoader.load('shared/js/sync/errors.js', () => {
|
||||
const IGNORED_ERRORS = [
|
||||
ERROR_DIALOG_CLOSED_BY_USER,
|
||||
ERROR_SYNC_APP_KILLED
|
||||
];
|
||||
|
||||
if (IGNORED_ERRORS.indexOf(message.error) > -1) {
|
||||
Settings.hide.bind(Settings)();
|
||||
return;
|
||||
}
|
||||
|
||||
var errorIds = [ERROR_UNKNOWN, ERROR_UNKNOWN + '-explanation'];
|
||||
|
||||
const KNOWN_ERRORS = [
|
||||
ERROR_INVALID_SYNC_ACCOUNT,
|
||||
ERROR_OFFLINE
|
||||
];
|
||||
|
||||
if (KNOWN_ERRORS.indexOf(message.error) > -1) {
|
||||
errorIds[0] = message.error;
|
||||
errorIds[1] = message.error + '-explanation';
|
||||
}
|
||||
|
||||
var l10n = navigator.mozL10n;
|
||||
Promise.all(
|
||||
errorIds.map(l10n.formatValue.bind(l10n))
|
||||
).then(result => {
|
||||
window.alert(result[0] + '\n' + result[1], () => {
|
||||
this.showScreen(DISABLED);
|
||||
});
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
this.previousState = this.state;
|
||||
this.state = message.state;
|
||||
},
|
||||
|
||||
onbookmarkschange() {
|
||||
debug('onbookmarkschange');
|
||||
var needsCleanup;
|
||||
if (!this.elements.collectionBookmarks) {
|
||||
// We may observe a setting change once we already disabled Sync
|
||||
// because the Sync Manager is reverting user preference changes to
|
||||
// the default ones. In that case, we need to create the object
|
||||
// briefly, so we can update the DOM accordingly.
|
||||
this.elements.collectionBookmarks = this.area.querySelector(
|
||||
'#fxsync-collection-bookmarks'
|
||||
);
|
||||
needsCleanup = true;
|
||||
}
|
||||
|
||||
this.elements.collectionBookmarks.checked =
|
||||
this.collections.has(BOOKMARKS_SETTING);
|
||||
|
||||
if (needsCleanup) {
|
||||
this.elements.collectionBookmarks = null;
|
||||
}
|
||||
},
|
||||
|
||||
onbookmarkschecked() {
|
||||
debug('onbookmarkschecked');
|
||||
this.oncollectionchecked(this.elements.collectionBookmarks,
|
||||
BOOKMARKS_SETTING);
|
||||
},
|
||||
|
||||
onhistorychange() {
|
||||
debug('onhistorychange');
|
||||
var needsCleanup;
|
||||
if (!this.elements.collectionHistory) {
|
||||
// We may observe a setting change once we already disabled Sync
|
||||
// because the Sync Manager is reverting user preference changes to
|
||||
// the default ones. In that case, we need to create the object
|
||||
// briefly, so we can update the DOM accordingly.
|
||||
this.elements.collectionHistory = this.area.querySelector(
|
||||
'#fxsync-collection-history'
|
||||
);
|
||||
needsCleanup = true;
|
||||
}
|
||||
|
||||
this.elements.collectionHistory.checked =
|
||||
this.collections.has(HISTORY_SETTING);
|
||||
|
||||
if (needsCleanup) {
|
||||
this.elements.collectionHistory = null;
|
||||
}
|
||||
},
|
||||
|
||||
onhistorychecked() {
|
||||
debug('onhistorychecked');
|
||||
this.oncollectionchecked(this.elements.collectionHistory,
|
||||
HISTORY_SETTING);
|
||||
},
|
||||
|
||||
oncollectionchecked(element, setting) {
|
||||
if (!element || !setting) {
|
||||
return;
|
||||
}
|
||||
|
||||
var checked = element.checked;
|
||||
var settingObj = {};
|
||||
settingObj[setting] = checked;
|
||||
if (!checked) {
|
||||
this.collections.delete(setting);
|
||||
navigator.mozSettings.createLock().set(settingObj);
|
||||
return;
|
||||
}
|
||||
|
||||
// Yeah, mozId sucks...
|
||||
// We cannot call watch twice to change the id lifetime
|
||||
// callbacks. But we still need to do different stuff
|
||||
// within the onlogin callback depending on who calls
|
||||
// oncollectionchecked. So we need to save state.
|
||||
// Thank you mozId.
|
||||
this.setting = setting;
|
||||
this.settingObj = settingObj;
|
||||
|
||||
try {
|
||||
navigator.mozId.watch({
|
||||
wantIssuer: 'firefox-accounts',
|
||||
onlogin: () => {
|
||||
// This callback is fired every time a new account logs in,
|
||||
// but we only want to enable the history setting when this
|
||||
// callback is called because the refresh auth flow succeeded.
|
||||
// This can happen only if Sync is already enabled.
|
||||
if (this.state !== 'enabled') {
|
||||
return;
|
||||
}
|
||||
this.collections.set(this.setting, true);
|
||||
navigator.mozSettings.createLock().set(this.settingObj);
|
||||
},
|
||||
onlogout: () => {},
|
||||
onready: () => {},
|
||||
onerror: error => {
|
||||
element.checked = false;
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
} catch(e) {}
|
||||
|
||||
navigator.mozId.request({
|
||||
oncancel: () => {
|
||||
element.checked = false;
|
||||
},
|
||||
// We keep authenticated sessions of 5 minutes, if the user clicks on
|
||||
// the history collection switch after the 5 minutes are expired, we
|
||||
// will be asking her to re-enter her fxa password.
|
||||
refreshAuthentication: 5 * 60
|
||||
});
|
||||
},
|
||||
|
||||
addListener(element, event, listenerName) {
|
||||
if (!element || !event || !listenerName) {
|
||||
return;
|
||||
}
|
||||
// Because we bind this to the listener, we need to save
|
||||
// the reference so we can remove it afterwards.
|
||||
var listener = this[listenerName].bind(this);
|
||||
element.addEventListener(event, listener);
|
||||
return listener;
|
||||
},
|
||||
|
||||
removeListener(element, event, listener) {
|
||||
if (!element || !event || !listener) {
|
||||
return;
|
||||
}
|
||||
element.removeEventListener(event, listener);
|
||||
},
|
||||
|
||||
loadElements(screen) {
|
||||
ELEMENTS.forEach(element => {
|
||||
var name = getElementName(element.selector);
|
||||
if (!Array.isArray(element.screen)) {
|
||||
element.screen = [element.screen];
|
||||
}
|
||||
if (!this.elements[name]) {
|
||||
this.elements[name] = this.area.querySelector(element.selector);
|
||||
this.listeners.set(
|
||||
name,
|
||||
this.addListener(this.elements[name],
|
||||
element.event, element.listener)
|
||||
);
|
||||
if (element.init) {
|
||||
this[element.init]();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (element.init) {
|
||||
this[element.init]();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.listeners.has(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.elements[name].checked) {
|
||||
this.elements[name].checked = false;
|
||||
}
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
showScreen(screen) {
|
||||
if (this.screen == screen) {
|
||||
return;
|
||||
}
|
||||
this.screen = screen;
|
||||
|
||||
this.loadElements(screen);
|
||||
|
||||
this.elements.enabled.hidden = (screen != ENABLED);
|
||||
this.elements.disabled.hidden = (screen != DISABLED);
|
||||
},
|
||||
|
||||
showUser(user) {
|
||||
navigator.mozL10n.setAttributes(this.elements.signedInAs,
|
||||
'fxsync-signed-in-as', {
|
||||
email: user
|
||||
});
|
||||
},
|
||||
|
||||
maybeEnableSyncNow() {
|
||||
if (!this.elements.syncNowButton) {
|
||||
return;
|
||||
}
|
||||
(this.collections.size <= 0) ?
|
||||
this.elements.syncNowButton.classList.add('disabled') :
|
||||
this.elements.syncNowButton.classList.remove('disabled');
|
||||
},
|
||||
|
||||
disableSyncNowAndCollections(disabled) {
|
||||
['collectionBookmarks',
|
||||
'collectionHistory'].forEach(name => {
|
||||
if (!this.elements[name]) {
|
||||
return;
|
||||
}
|
||||
this.elements[name].disabled = disabled;
|
||||
});
|
||||
disabled ? this.elements.syncNowButton.classList.add('disabled')
|
||||
: this.elements.syncNowButton.classList.remove('disabled');
|
||||
},
|
||||
|
||||
showEnabling() {
|
||||
this.elements.signInButton.classList.add('disabled');
|
||||
this.elements.signInButton.dataset.l10nId = 'fxsync-signing';
|
||||
},
|
||||
|
||||
hideEnabling() {
|
||||
this.elements.signInButton.classList.remove('disabled');
|
||||
this.elements.signInButton.dataset.l10nId = 'fxsync-sign-in';
|
||||
},
|
||||
|
||||
showSyncNow() {
|
||||
this.elements.syncNowButton.dataset.l10nId = 'fxsync-sync-now';
|
||||
this.disableSyncNowAndCollections(false);
|
||||
this.maybeEnableSyncNow();
|
||||
},
|
||||
|
||||
showSyncing() {
|
||||
this.elements.syncNowButton.dataset.l10nId = 'fxsync-syncing';
|
||||
this.disableSyncNowAndCollections(true);
|
||||
},
|
||||
|
||||
enable() {
|
||||
SyncManagerBridge.enable();
|
||||
},
|
||||
|
||||
disable() {
|
||||
BrowserDialog.createDialog('signout_confirm').then(() => {
|
||||
SyncManagerBridge.disable();
|
||||
});
|
||||
},
|
||||
|
||||
sync() {
|
||||
SyncManagerBridge.sync();
|
||||
},
|
||||
|
||||
openTos() {
|
||||
this.showWebpage('https://accounts.firefox.com/legal/terms');
|
||||
},
|
||||
|
||||
openPrivacy() {
|
||||
this.showWebpage('https://accounts.firefox.com/legal/privacy');
|
||||
},
|
||||
|
||||
showWebpage(url) {
|
||||
Awesomescreen.createAddNewTab();
|
||||
Browser.navigate(url);
|
||||
Settings.hide();
|
||||
}
|
||||
};
|
||||
|
||||
exports.FirefoxSyncSettings = FirefoxSyncSettings;
|
||||
|
||||
LazyLoader.load('js/sync/manager_bridge.js', () => {
|
||||
FirefoxSyncSettings.init();
|
||||
});
|
||||
}(window));
|
||||
113
gaia/tv_apps/browser/js/sync/toolbar.js
Executable file
|
|
@ -0,0 +1,113 @@
|
|||
/* 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/. */
|
||||
|
||||
/* exports FirefoxSyncToolbar */
|
||||
|
||||
/* global LazyLoader */
|
||||
/* global Settings */
|
||||
/* global SyncManagerBridge */
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* This small module handles the logic of the Sync entry in the browser's
|
||||
* top right toolbar menu.
|
||||
*
|
||||
* We show two different variations of the UI depending on the state of Sync:
|
||||
*
|
||||
* - When Sync is disabled, we show a 'Sign in to Sync' entry. Clicking it
|
||||
* triggers the Firefox Accounts flow and signs the user into Sync if the
|
||||
* FxA flow is completed successfuly.
|
||||
* - When Sync is enabled, we show the 'Sign is as {{email}}' entry. Where
|
||||
* {{email}} is the email used by the user to login into FxA.
|
||||
*
|
||||
* We also handle a third Sync state. When an error is received through the
|
||||
* Sync Manager Bridge, we inform the user about them. The expected errors are:
|
||||
*
|
||||
* - ERROR_OFFLINE: The user is trying to log in Sync when the device is
|
||||
* offline.
|
||||
* - ERROR_INVALID_SYNC_ACCOUNT: The user is trying to log into Sync with a
|
||||
* Firefox Account that has never been used before with Sync. On the first
|
||||
* version we don't support the creation of new Sync accounts, so we ask the
|
||||
* user to first login in Firefox Desktop or Android and try login again
|
||||
* in the TV.
|
||||
* - ERROR_TRY_LATER: The server is probably down. We inform the user about it
|
||||
* and ask her to retry in a few minutes.
|
||||
* - ERROR_UNKNOWN: We don't know what the h* was wrong, but we can't log the
|
||||
* user in.
|
||||
*
|
||||
* Here we don't need to worry about keeping any kind of state or managing
|
||||
* any state transistion apart from the UI changes. The Sync State Machine
|
||||
* and Sync State Manager takes care of handling all that for us.
|
||||
*/
|
||||
|
||||
(function(exports) {
|
||||
const DEBUG = true;
|
||||
function debug() {
|
||||
if (DEBUG) {
|
||||
console.log('[FirefoxSyncToolbar] ' + Array.slice(arguments).concat());
|
||||
}
|
||||
}
|
||||
|
||||
var FirefoxSyncToolbar = {
|
||||
init() {
|
||||
SyncManagerBridge.addListener(this.onsyncchange.bind(this));
|
||||
|
||||
this.syncBlock = document.getElementById('fxsync-block');
|
||||
this.syncTab = this.syncBlock.querySelector('#fxsync-tab');
|
||||
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
if (!document.hidden) {
|
||||
this.refresh();
|
||||
}
|
||||
});
|
||||
|
||||
this.refresh();
|
||||
},
|
||||
|
||||
refresh() {
|
||||
SyncManagerBridge.getInfo().then(this.onsyncchange.bind(this));
|
||||
},
|
||||
|
||||
onsyncchange(message) {
|
||||
debug(JSON.stringify(message));
|
||||
if (!message || !message.state) {
|
||||
throw new Error('Missing sync state');
|
||||
}
|
||||
switch (message.state) {
|
||||
case 'disabled':
|
||||
if (this.showListener) {
|
||||
this.syncBlock.removeEventListener('mouseup', this.showListener);
|
||||
this.showListener = null;
|
||||
}
|
||||
this.syncBlock.addEventListener('mouseup', SyncManagerBridge.enable);
|
||||
this.syncTab.setAttribute('data-l10n-id', 'fxsync-sign-in-to-sync');
|
||||
this.syncTab.removeAttribute('data-l10n-args');
|
||||
break;
|
||||
case 'enabling':
|
||||
Settings.show();
|
||||
this.syncTab.setAttribute('data-l10n-id', 'fxsync-signing');
|
||||
break;
|
||||
case 'syncing':
|
||||
case 'enabled':
|
||||
this.showListener = Settings.show.bind(Settings);
|
||||
this.syncBlock.addEventListener('mouseup', this.showListener);
|
||||
this.syncBlock.removeEventListener('mouseup',
|
||||
SyncManagerBridge.enable);
|
||||
navigator.mozL10n.setAttributes(this.syncTab, 'fxsync-signed-in-as', {
|
||||
email: message.user
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Exported only for testing purposes
|
||||
exports.FirefoxSyncToolbar = FirefoxSyncToolbar;
|
||||
|
||||
LazyLoader.load('js/sync/manager_bridge.js', () => {
|
||||
FirefoxSyncToolbar.init();
|
||||
});
|
||||
|
||||
}(window));
|
||||
758
gaia/tv_apps/browser/js/toolbar.js
Executable file
|
|
@ -0,0 +1,758 @@
|
|||
/* global Awesomescreen */
|
||||
/* global Browser */
|
||||
/* global BrowserDB */
|
||||
/* global LazyLoader */
|
||||
/* global SearchResult */
|
||||
/* global SearchUtil */
|
||||
/* global Settings */
|
||||
/* global Tooltip*/
|
||||
/* global UrlHelper */
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Browser app toolbar
|
||||
* @namespace Toolbar
|
||||
*/
|
||||
var Toolbar = {
|
||||
|
||||
/* screen size */
|
||||
SCREEN_HEIGHT: 1080,
|
||||
SCREEN_WIDTH: 1920,
|
||||
|
||||
/* zoom */
|
||||
availableZoomScale: [
|
||||
{'scale': 1.25, 'disp': '100%'},
|
||||
{'scale': 1.625, 'disp': '130%'},
|
||||
{'scale': 2.0, 'disp': '160%'},
|
||||
],
|
||||
defaultZoomScale: 0,
|
||||
zoomScale: 0,
|
||||
availableZoomScaleYoutube: [
|
||||
{'scale': 1.55, 'disp': '100%'},
|
||||
{'scale': 1.775, 'disp': '130%'},
|
||||
{'scale': 2.0, 'disp': '160%'},
|
||||
],
|
||||
|
||||
urlButtonMode: null,
|
||||
GO: 0,
|
||||
REFRESH: 1,
|
||||
STOP: 2,
|
||||
SEARCH: 3,
|
||||
|
||||
initStart: true,
|
||||
|
||||
/**
|
||||
* Intialise toolbar.
|
||||
*/
|
||||
init: function toolbar_init() {
|
||||
/* get Element */
|
||||
this.getAllElements();
|
||||
|
||||
/* Event Listener */
|
||||
window.addEventListener('click', this);
|
||||
|
||||
this.sidebarButtonBlock.addEventListener('mouseup',
|
||||
this.showHideSidebar.bind(this));
|
||||
|
||||
this.backButtonBlock.addEventListener('mouseup',
|
||||
this.goBack.bind(this));
|
||||
|
||||
this.forwardButtonBlock.addEventListener('mouseup',
|
||||
this.goForward.bind(this));
|
||||
|
||||
this.addressForm.addEventListener('submit',
|
||||
this.handleUrlFormSubmit.bind(this));
|
||||
|
||||
this.urlInput.addEventListener('input',
|
||||
this.handleUrlInputKeypress.bind(this));
|
||||
|
||||
this.addressButton.addEventListener('mouseup',
|
||||
this.clickAddressButton.bind(this));
|
||||
|
||||
this.searchForm.addEventListener('submit',
|
||||
this.handleSearchFormSubmit.bind(this));
|
||||
|
||||
this.searchInput.addEventListener('focus',
|
||||
this.handleSearchInputFocus.bind(this));
|
||||
|
||||
// this.searchInput.addEventListener('keyup',
|
||||
// this.handleSearchInputKeypress.bind(this));
|
||||
|
||||
this.searchInput.addEventListener('input',
|
||||
this.handleSearchInputInput.bind(this));
|
||||
|
||||
this.searchButton.addEventListener('mouseup',
|
||||
this.clickSearchButton.bind(this));
|
||||
|
||||
this.searchClearButton.addEventListener('mouseup',
|
||||
this.clickSearchClearButton.bind(this));
|
||||
|
||||
this.searchCloseButton.addEventListener('mouseup',
|
||||
this.clickSearchCloseButton.bind(this));
|
||||
|
||||
this.bookmarkButtonBlock.addEventListener('mouseup',
|
||||
Browser.addBookmark.bind(Browser));
|
||||
this.bookmarkButtonAnime.addEventListener('animationend',
|
||||
Browser.bookmarkButtonAnimeEnd.bind(Browser));
|
||||
|
||||
this.showBookmarksButtonBlock.addEventListener('mouseup',
|
||||
Awesomescreen.selectBookmarksTab.bind(Awesomescreen));
|
||||
|
||||
this.homeButtonBlock.addEventListener('mouseup',
|
||||
this.clickHomeButtonBlock.bind(this));
|
||||
|
||||
this.zoomButtonBlock.addEventListener('mouseup',
|
||||
this.clickZoomButtonBlock.bind(this));
|
||||
|
||||
this.tabsButtonBlock.addEventListener('click',
|
||||
Awesomescreen.handleNewTab.bind(Awesomescreen));
|
||||
|
||||
this.newTabButtonBlock.addEventListener('click',
|
||||
Awesomescreen.createAddNewTab.bind(Awesomescreen));
|
||||
|
||||
this.menuButtonBlock.addEventListener('mouseup',
|
||||
this.clickMenuButtonBlock.bind(this));
|
||||
this.historyBlock.addEventListener('mouseup',
|
||||
Awesomescreen.selectHistoryTab.bind(Awesomescreen));
|
||||
this.pocketBlock.addEventListener('mouseup',
|
||||
this.clickPocketListBlock.bind(this));
|
||||
this.privateWindowBlock.addEventListener('mouseup',
|
||||
Browser.handlePrivateBrowsing.bind(Browser));
|
||||
this.settingsBlock.addEventListener('mouseup',
|
||||
Settings.show.bind(Settings));
|
||||
|
||||
this.modeButtonBlock.addEventListener('mouseover',
|
||||
this.selectedModeButtonBlock.bind(this));
|
||||
this.modeButtonBlock.addEventListener('mouseout',
|
||||
this.unselectedModeButtonBlock.bind(this));
|
||||
|
||||
this.toolbarPanel.dataset.search = 'false';
|
||||
|
||||
var colorBar = Browser.getColorBarData();
|
||||
this.panCursorButtonBlock.dataset.colorbar = colorBar[0].COLOR;
|
||||
this.zoomButtonBlock.dataset.colorbar = colorBar[1].COLOR;
|
||||
this.tabsButtonBlock.dataset.colorbar = colorBar[2].COLOR;
|
||||
this.newTabButtonBlock.dataset.colorbar = colorBar[3].COLOR;
|
||||
|
||||
// li = 73px * 3(list) + 20px(hover) + 10px(padding)
|
||||
this.menuBlock.style.height = 73 * 3 + 20 + 10 + 'px';
|
||||
Tooltip.init();
|
||||
|
||||
//IFDEF_FIREFOX_SYNC
|
||||
LazyLoader.load('js/sync/toolbar.js');
|
||||
//ENDIF_FIREFOX_SYNC
|
||||
},
|
||||
|
||||
/**
|
||||
* toolbar bookmark registered check.
|
||||
*/
|
||||
isBookmarks: function toolbar_isBookmarks() {
|
||||
if(Toolbar.bookmarkButton.dataset.isbookmark == 'true'){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Set search engine
|
||||
*/
|
||||
setSearchEngine: function toolbar_setSearchEngine() {
|
||||
var engineName = SearchUtil.getCurrentEngineName().toLowerCase();
|
||||
// favicon
|
||||
this.searchFavicon.dataset.engine = engineName;
|
||||
// placeholder
|
||||
engineName = engineName.charAt(0).toUpperCase() + engineName.slice(1);
|
||||
this.searchInput.placeholder = engineName;
|
||||
// tooltip
|
||||
navigator.mozL10n.formatValue('WB_LT_TIPS_SEARCH_BAR2', {
|
||||
engine: engineName
|
||||
}).then(val => {
|
||||
this.searchInput.dataset.tips = val;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* CamelCase (xxx-yyy -> xxxYyy)
|
||||
*/
|
||||
toCamelCase: function toCamelCase(str) {
|
||||
return str.replace(/-(.)/g, function replacer(str, p1) {
|
||||
return p1.toUpperCase();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Get All Elements (from id)
|
||||
*/
|
||||
getAllElements: function toolbar_getAllElements() {
|
||||
var elementIDs = [
|
||||
'toolbar-panel',
|
||||
'sidebar-button-block', 'sidebar-button',
|
||||
'back-button-block', 'back-button',
|
||||
'forward-button-block', 'forward-button-border', 'forward-button',
|
||||
'space-block',
|
||||
'addressbar-block', 'address-form', 'ssl-indicator', 'url-input',
|
||||
'address-button',
|
||||
'searchbar-block', 'search-form', 'search-favicon', 'search-input',
|
||||
'search-button', 'search-clear-button', 'search-close-button',
|
||||
'iconbutton-block',
|
||||
'bookmark-button-block', 'bookmark-button',
|
||||
'show-bookmarks-button-block', 'show-bookmarks-button',
|
||||
'home-button-block', 'home-button',
|
||||
'zoom-button-block', 'zoom-button',
|
||||
'tabs-button-block', 'tabs-button',
|
||||
'new-tab-button-block', 'new-tab-button',
|
||||
'menu-button-block', 'menu-button',
|
||||
'menu-block',
|
||||
'history-block', 'private-window-block',
|
||||
'settings-block',
|
||||
'history-tab', 'private-window-tab', 'settings-tab',
|
||||
'mode-button-block',
|
||||
'mode-button-title', 'pan-cursor-button', 'pan-cursor-button-block',
|
||||
'pan-cursor-banner-message',
|
||||
'zoom-banner-message-block', 'zoom-banner-message',
|
||||
'loading-icon',
|
||||
//'tooltip-block',
|
||||
'bookmark-button-anime', 'show-bookmarks-button-anime',
|
||||
'pocket-block', 'pocket-tab'
|
||||
];
|
||||
|
||||
// Loop and add element with camel style name to Modal Dialog attribute.
|
||||
elementIDs.forEach(function createElementRef(name) {
|
||||
this[this.toCamelCase(name)] = document.getElementById(name);
|
||||
}, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* handle event
|
||||
*/
|
||||
handleEvent: function toolbar_handleEvent(ev) {
|
||||
switch(ev.type) {
|
||||
case 'click':
|
||||
if(ev.target != this.menuButtonBlock) {
|
||||
this.toolbarPanel.dataset.menu = 'hide';
|
||||
}
|
||||
|
||||
// Settings in the display
|
||||
if(Settings.isDisplayed()) {
|
||||
switch(ev.target) {
|
||||
case this.backButtonBlock:
|
||||
case this.forwardButtonBlock:
|
||||
case this.addressForm:
|
||||
case this.urlInput:
|
||||
case this.addressButton:
|
||||
case this.searchForm:
|
||||
case this.searchInput:
|
||||
case this.searchButton:
|
||||
case this.bookmarkButtonBlock:
|
||||
case this.showBookmarksButtonBlock:
|
||||
case this.homeButtonBlock:
|
||||
case this.zoomButtonBlock:
|
||||
case this.tabsButtonBlock:
|
||||
case this.newTabButtonBlock:
|
||||
case this.menuButtonBlock:
|
||||
Settings.hide();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Specialized processing youtube (zoom)
|
||||
*/
|
||||
checkYoutube: function toolbar_checkYoutube() {
|
||||
if(!Browser.currentInfo || !Browser.currentInfo.url) {
|
||||
return false;
|
||||
}
|
||||
var end_pos1 =
|
||||
Browser.currentInfo.url.indexOf('https://www.youtube.com', 0);
|
||||
var end_pos2 = Browser.currentInfo.url.indexOf('http://www.youtube.com', 0);
|
||||
if(end_pos1 < 0 && end_pos2 < 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Full screen or Screen with submenu
|
||||
*/
|
||||
showHideSidebar: function toolbar_showHideSidebar() {
|
||||
this.sidebarButtonBlock.blur();
|
||||
// Hide Tooltip
|
||||
Tooltip.hide();
|
||||
|
||||
// Fade animation end event handler
|
||||
var fade_event = (function() {
|
||||
Browser.fadeBase.classList.toggle('fade');
|
||||
if(Browser.sideBlock.dataset.sidebar == 'true'){
|
||||
// Full screen
|
||||
Browser.sideBlock.dataset.sidebar = 'false';
|
||||
Browser.mainBlock.dataset.sidebar = 'false';
|
||||
// save screen mode
|
||||
BrowserDB.updateSetting('full', 'screen_mode');
|
||||
}else{
|
||||
// Disp side screen
|
||||
Browser.sideBlock.dataset.sidebar = 'true';
|
||||
Browser.mainBlock.dataset.sidebar = 'true';
|
||||
// save screen mode
|
||||
BrowserDB.updateSetting('side', 'screen_mode');
|
||||
}
|
||||
Browser.fadeBase.removeEventListener('transitionend', fade_event, false);
|
||||
// Specialized processing youtube (zoom)
|
||||
Browser.currentInfo.dom.zoom(Toolbar.getZoomScale());
|
||||
});
|
||||
// Add fade animantion event
|
||||
Browser.fadeBase.addEventListener('transitionend', fade_event, false);
|
||||
Browser.fadeBase.classList.toggle('fade');
|
||||
this.sidebarButtonBlock.dataset.fade='true';
|
||||
},
|
||||
|
||||
/**
|
||||
* Go back to the previous page
|
||||
*/
|
||||
goBack: function toolbar_goBack() {
|
||||
|
||||
if (Awesomescreen.isDisplayedTop()){
|
||||
Awesomescreen.topsiteReturnFunc();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Browser.currentInfo.dom.getCanGoBack){
|
||||
return;
|
||||
}
|
||||
|
||||
Browser.currentInfo.dom.getCanGoBack().onsuccess = (function(ev) {
|
||||
if(!ev.target.result){
|
||||
// dialog
|
||||
// XXX: refactor this and the same code in awesomescreen.js
|
||||
navigator.mozL10n.formatValue('LT_BROWSER_CONFIRM_EXIT2')
|
||||
.then(result => {
|
||||
if (window.confirm(result)) {
|
||||
window.close();
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
}).bind(this);
|
||||
|
||||
Browser.currentInfo.dom.goBack();
|
||||
},
|
||||
|
||||
/**
|
||||
* Go forward to the next page
|
||||
*/
|
||||
goForward: function toolbar_goForward() {
|
||||
Browser.currentInfo.dom.goForward();
|
||||
},
|
||||
|
||||
// Set url form input
|
||||
setUrlBar: function toolbar_setUrlBar(value) {
|
||||
this.urlInput.value = value;
|
||||
},
|
||||
// Get url form input
|
||||
getUrlFromInput: function toolbar_getUrlFromInput(input) {
|
||||
var hasScheme = UrlHelper.hasScheme(input);
|
||||
|
||||
// No scheme, prepend basic protocol and return
|
||||
if (!hasScheme) {
|
||||
return 'http://' + input;
|
||||
}
|
||||
|
||||
return input;
|
||||
},
|
||||
/**
|
||||
* Url form submit
|
||||
*/
|
||||
handleUrlFormSubmit: function toolbar_handleUrlFormSubmit(ev) {
|
||||
if (ev) {
|
||||
// Can be canceled
|
||||
ev.preventDefault();
|
||||
}
|
||||
|
||||
if (this.urlButtonMode === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var url = this.getUrlFromInput(this.urlInput.value);
|
||||
|
||||
if (url !== Browser.currentInfo.url) {
|
||||
this.setUrlBar(url);
|
||||
Browser.currentInfo.url = url;
|
||||
}
|
||||
|
||||
this.urlInput.blur();
|
||||
|
||||
Browser.navigate(url);
|
||||
},
|
||||
|
||||
/**
|
||||
* Input Url
|
||||
*/
|
||||
handleUrlInputKeypress: function toolbar_handleUrlInputKeypress(evt) {
|
||||
var input = this.urlInput.value;
|
||||
if (input === '') {
|
||||
this.setUrlButtonMode(null);
|
||||
this.addressButton.classList.add('disable');
|
||||
return;
|
||||
}
|
||||
|
||||
this.addressButton.classList.remove('disable');
|
||||
this.setUrlButtonMode(
|
||||
UrlHelper.isNotURL(input) ? this.SEARCH : this.GO
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Address Bookmark Current url
|
||||
*/
|
||||
clickAddressButton: function toolbar_clickAddressButton(ev) {
|
||||
//if(this.addressButton.classList.contains('disable')){
|
||||
//return;
|
||||
//}
|
||||
if(this.addressButton.dataset.mode == 'load') {
|
||||
if(Browser.currentInfo.url){
|
||||
Browser.currentInfo.dom.reload(false);
|
||||
}
|
||||
this.stopAddressIcon();
|
||||
} else {
|
||||
Browser.currentInfo.dom.stop();
|
||||
this.hiddenLoadingIcon();
|
||||
this.loadAddressIcon();
|
||||
}
|
||||
},
|
||||
|
||||
loadAddressIcon: function toolbar_loadAddressIcon() {
|
||||
this.addressButton.dataset.mode = 'load';
|
||||
this.addressButton.dataset.tips = 'WB_LT_TIPS_RELOAD';
|
||||
},
|
||||
|
||||
stopAddressIcon: function toolbar_stopAddressIcon() {
|
||||
this.addressButton.dataset.mode = 'stop';
|
||||
this.addressButton.dataset.tips = 'WB_LT_TIPS_STOP_LOADING';
|
||||
},
|
||||
|
||||
showLoadingIcon: function toolbar_showLoadingIcon() {
|
||||
if(Settings.isDisplayed()) {
|
||||
return;
|
||||
}
|
||||
if(!this.loadingIcon.classList.contains('visible')){
|
||||
this.loadingIcon.classList.add('visible');
|
||||
this.stopAddressIcon();
|
||||
}
|
||||
},
|
||||
|
||||
hiddenLoadingIcon: function toolbar_hiddenLoadingIcon() {
|
||||
if(Tooltip.isShow(this.addressButton)){
|
||||
Tooltip.hide();
|
||||
}
|
||||
this.loadingIcon.classList.remove('visible');
|
||||
this.loadAddressIcon();
|
||||
},
|
||||
|
||||
/**
|
||||
* Submit search form
|
||||
*/
|
||||
handleSearchFormSubmit: function toolbar_handleSearchFormSubmit(ev) {
|
||||
if (ev) {
|
||||
// Can be canceled
|
||||
ev.preventDefault();
|
||||
}
|
||||
|
||||
if( SearchResult.isDisplayed() ) {
|
||||
this.searchInput.blur();
|
||||
SearchResult.hide();
|
||||
}
|
||||
var url = Browser.getSearchFromInput(this.searchInput.value);
|
||||
Browser.navigate(url);
|
||||
},
|
||||
|
||||
/**
|
||||
* Click search button
|
||||
*/
|
||||
clickSearchButton: function toolbar_clickSearchButton(ev) {
|
||||
this.handleSearchFormSubmit(ev);
|
||||
},
|
||||
|
||||
clickSearchClearButton: function toolbar_clickSearchClearButton(ev) {
|
||||
if( ev ) {
|
||||
ev.preventDefault();
|
||||
}
|
||||
this.searchInput.value = '';
|
||||
SearchResult.resultUpdate(this.searchInput.value);
|
||||
},
|
||||
|
||||
clickSearchCloseButton: function toolbar_clickSearchCloseButton(ev) {
|
||||
if( ev ) {
|
||||
ev.preventDefault();
|
||||
}
|
||||
SearchResult.hide();
|
||||
},
|
||||
|
||||
/**
|
||||
* Input Search
|
||||
*/
|
||||
getSearchBarStyle: function toolbar_getSearchBarStyle() {
|
||||
return this.toolbarPanel.dataset.search;
|
||||
},
|
||||
|
||||
setSearchBarStyle: function toolbar_setSearchBarStyle(value) {
|
||||
this.toolbarPanel.dataset.search = value;
|
||||
},
|
||||
|
||||
handleSearchInputFocus: function toolbar_handleSearchInputFocus(evt) {
|
||||
this.handleSearchInputKeypress(evt);
|
||||
},
|
||||
|
||||
handleSearchInputInput: function toolbar_handleSearchInputInput(evt) {
|
||||
this.handleSearchInputKeypress(evt);
|
||||
},
|
||||
|
||||
handleSearchInputKeypress: function toolbar_handleSearchInputKeypress(evt) {
|
||||
if( this.getSearchBarStyle() == 'false' ) {
|
||||
if( evt ) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
if(Toolbar.searchInput.value) {
|
||||
Tooltip.hide();
|
||||
this.setSearchBarStyle('true');
|
||||
SearchResult.show();
|
||||
}
|
||||
} else {
|
||||
SearchResult.handleSearchResultFormInput(evt);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Click home button
|
||||
*/
|
||||
clickHomeButtonBlock: function toolbar_clickHomeButtonBlock(ev) {
|
||||
Settings.getHomepage((function(result) {
|
||||
if(result) {
|
||||
Browser.navigate(result);
|
||||
}
|
||||
}).bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Click zoom button
|
||||
*/
|
||||
clickZoomButtonBlock: function toolbar_clickZoomButtonBlock(ev) {
|
||||
if(ev){
|
||||
// stop event
|
||||
ev.stopPropagation();
|
||||
}
|
||||
clearTimeout(this.showZoomBannerTimeoutID);
|
||||
|
||||
this.zoomScale = Browser.currentInfo.zoom;
|
||||
this.zoomScale++;
|
||||
if(this.zoomScale >= this.availableZoomScale.length) {
|
||||
this.zoomScale = 0;
|
||||
}
|
||||
Browser.currentInfo.zoom = this.zoomScale;
|
||||
Browser.currentInfo.dom.zoom(this.getZoomScale());
|
||||
|
||||
this.zoomBannerMessage.innerHTML =
|
||||
this.availableZoomScale[this.zoomScale].disp;
|
||||
if(!this.zoomBannerMessageBlock.classList.contains('visible')){
|
||||
this.zoomBannerMessageBlock.classList.add('visible');
|
||||
}
|
||||
this.showZoomBannerTimeoutID = setTimeout(function(){
|
||||
Toolbar.zoomBannerMessageBlock.classList.remove('visible');
|
||||
}, 1500);
|
||||
},
|
||||
getZoomScale: function toolbar_getZoomScale() {
|
||||
if(this.checkYoutube() && Browser.sideBlock.dataset.sidebar == 'false'){
|
||||
return this.availableZoomScaleYoutube[this.zoomScale].scale;
|
||||
} else {
|
||||
return this.availableZoomScale[this.zoomScale].scale;
|
||||
}
|
||||
},
|
||||
setZoomScale: function toolbar_setZoomScale(scale) {
|
||||
this.zoomScale = scale;
|
||||
},
|
||||
getDefaultZoomScale: function toolbar_getDefaultZoomScale() {
|
||||
if(this.checkYoutube() && Browser.sideBlock.dataset.sidebar == 'false'){
|
||||
return this.availableZoomScaleYoutube[this.defaultZoomScale].scale;
|
||||
} else {
|
||||
return this.availableZoomScale[this.defaultZoomScale].scale;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Zoom out(for ars)
|
||||
*/
|
||||
zoomOut: function toolbar_zoomOut() {
|
||||
clearTimeout(this.showZoomBannerTimeoutID);
|
||||
|
||||
this.zoomScale = Browser.currentInfo.zoom;
|
||||
if(this.zoomScale === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.zoomScale--;
|
||||
Browser.currentInfo.zoom = this.zoomScale;
|
||||
Browser.currentInfo.dom.zoom(this.getZoomScale());
|
||||
|
||||
this.zoomBannerMessage.innerHTML =
|
||||
this.availableZoomScale[this.zoomScale].disp;
|
||||
if(!this.zoomBannerMessageBlock.classList.contains('visible')){
|
||||
this.zoomBannerMessageBlock.classList.add('visible');
|
||||
}
|
||||
this.showZoomBannerTimeoutID = setTimeout(function(){
|
||||
Toolbar.zoomBannerMessageBlock.classList.remove('visible');
|
||||
}, 1500);
|
||||
},
|
||||
|
||||
/**
|
||||
* Click menu button
|
||||
*/
|
||||
clickMenuButtonBlock: function toolbar_clickMenuButtonBlock(ev) {
|
||||
if(ev){
|
||||
// stop event
|
||||
ev.stopPropagation();
|
||||
}
|
||||
if(this.toolbarPanel.dataset.menu == 'show') {
|
||||
this.toolbarPanel.dataset.menu = 'hide';
|
||||
} else {
|
||||
this.toolbarPanel.dataset.menu = 'show';
|
||||
if(!this.menuBlock.style.minWidth) {
|
||||
var ar = [];
|
||||
// rate 1.25
|
||||
ar.push(432); // default 432(540 / 1.25)
|
||||
ar.push(this.historyTab.offsetWidth);
|
||||
ar.push(this.privateWindowTab.offsetWidth);
|
||||
|
||||
ar.push(this.settingsTab.offsetWidth);
|
||||
this.menuBlock.style.minWidth =
|
||||
(Math.max.apply(null, ar) * 1.25) + 'px';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Show mode button
|
||||
*/
|
||||
showModeButtonTimer: function toolbar_showModeButtonTimer() {
|
||||
this.showModeButtonTimeoutID = setTimeout(function(){
|
||||
Toolbar.modeButtonBlock.classList.remove('visible');
|
||||
}, 5000);
|
||||
},
|
||||
|
||||
/**
|
||||
* Show mode button
|
||||
*/
|
||||
showPanCursorButton: function toolbar_showPanCursorButton() {
|
||||
if(!this.modeButtonBlock.classList.contains('visible')){
|
||||
this.modeButtonBlock.classList.add('visible');
|
||||
this.showModeButtonTimer();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Selected mode button
|
||||
*/
|
||||
selectedModeButtonBlock: function toolbar_selectedModeButtonBlock() {
|
||||
clearTimeout(this.showModeButtonTimeoutID);
|
||||
},
|
||||
|
||||
/**
|
||||
* Unselected mode button
|
||||
*/
|
||||
unselectedModeButtonBlock: function toolbar_unselectedModeButtonBlock() {
|
||||
this.showModeButtonTimer();
|
||||
},
|
||||
|
||||
/**
|
||||
* Show pan cursor banner
|
||||
*/
|
||||
showPanCursorBanner: function toolbar_showPanCursorBanner() {
|
||||
if(!this.panCursorBannerMessage.classList.contains('visible')){
|
||||
this.panCursorBannerMessage.classList.add('visible');
|
||||
}
|
||||
clearTimeout(this.showPanCursorBannerTimeoutID);
|
||||
this.showPanCursorBannerTimeoutID = setTimeout(function(){
|
||||
Toolbar.panCursorBannerMessage.classList.remove('visible');
|
||||
}, 5000);
|
||||
},
|
||||
|
||||
/**
|
||||
* Click mode button
|
||||
*/
|
||||
clickModeButtonBlock: function toolbar_clickModeButtonBlock() {
|
||||
if(Browser.getCursorPanMode() == 'cursor') {
|
||||
Browser.setCursorPanMode('pan');
|
||||
this.modeButtonTitle.setAttribute('data-l10n-id', 'WB_LT_PAN_MODE');
|
||||
this.panCursorBannerMessage.setAttribute(
|
||||
'data-l10n-id', 'WB_LT_SWITCH_PAN_MODE');
|
||||
} else {
|
||||
this.clearDragMode();
|
||||
}
|
||||
|
||||
// Show mode button
|
||||
this.showPanCursorButton();
|
||||
// Show pan cursor banner
|
||||
this.showPanCursorBanner();
|
||||
},
|
||||
// clear drag mode
|
||||
clearDragMode: function toolbar_clearDragMode(){
|
||||
if(Browser.getCursorPanMode() == 'pan') {
|
||||
Browser.setCursorPanMode('cursor');
|
||||
this.modeButtonTitle.setAttribute('data-l10n-id', 'WB_LT_CURSOR_MODE');
|
||||
this.panCursorBannerMessage.setAttribute(
|
||||
'data-l10n-id', 'WB_LT_SWITCH_CURSOR_MODE');
|
||||
}
|
||||
},
|
||||
|
||||
setUrlButtonMode: function toolbar_setUrlButtonMode(mode) {
|
||||
this.urlButtonMode = mode;
|
||||
},
|
||||
|
||||
setPrivateBrowsing: function toolbar_setPrivateBrowsing(bool) {
|
||||
this.toolbarPanel.dataset.pvt = bool;
|
||||
},
|
||||
|
||||
isPrivateBrowsing: function toolbar_getPrivateBrowsing() {
|
||||
return (this.toolbarPanel.dataset.pvt == 'true');
|
||||
},
|
||||
|
||||
initStartBrowsing: function toolbar_initStartBrowsing() {
|
||||
if(this.initStart) {
|
||||
this.initStart = false;
|
||||
/* show pan cursor mode button */
|
||||
this.showPanCursorButton();
|
||||
}
|
||||
},
|
||||
|
||||
setToolbarMode: function toolbar_setToolbarMode(mode) {
|
||||
this.toolbarPanel.dataset.mode = mode;
|
||||
},
|
||||
getToolbarMode: function toolbar_getToolbarMode() {
|
||||
return this.toolbarPanel.dataset.mode;
|
||||
},
|
||||
|
||||
/**
|
||||
* Open Pocket List
|
||||
*/
|
||||
clickPocketListBlock: function toolbar_clickPocketListBlock() {
|
||||
var pocketHomePageUri = 'https://getpocket.com/fxostv';
|
||||
if (Browser.currentInfo.url &&
|
||||
UrlHelper.isURL(Browser.currentInfo.url)) {
|
||||
var ev = {
|
||||
detail: {
|
||||
url: pocketHomePageUri,
|
||||
frameElement: null
|
||||
}
|
||||
};
|
||||
Awesomescreen.openNewTab(ev);
|
||||
} else {
|
||||
Browser.navigate(pocketHomePageUri);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
190
gaia/tv_apps/browser/js/tooltip.js
Executable file
|
|
@ -0,0 +1,190 @@
|
|||
/* global _ */
|
||||
/* global Toolbar */
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Browser App Tooltip.
|
||||
* @namespace Tooltip
|
||||
*/
|
||||
var Tooltip = {
|
||||
tooltipBlock: null,
|
||||
showTimeoutID: null,
|
||||
hideTimeoutID: null,
|
||||
hideTimeoutData: 100,
|
||||
overObj: null,
|
||||
moveObj: null,
|
||||
showTarget: null,
|
||||
|
||||
/**
|
||||
* initialize
|
||||
*/
|
||||
init: function tooltip_init() {
|
||||
this.tooltipBlock = document.getElementById('tooltip-block');
|
||||
|
||||
var elements = [
|
||||
{target: Toolbar.sidebarButtonBlock},
|
||||
{target: Toolbar.backButtonBlock},
|
||||
{target: Toolbar.forwardButtonBlock},
|
||||
{target: Toolbar.addressButton},
|
||||
{target: Toolbar.searchInput},
|
||||
{target: Toolbar.bookmarkButtonBlock},
|
||||
{target: Toolbar.showBookmarksButtonBlock},
|
||||
{target: Toolbar.homeButtonBlock},
|
||||
{target: Toolbar.zoomButtonBlock},
|
||||
{target: Toolbar.tabsButtonBlock},
|
||||
{target: Toolbar.newTabButtonBlock},
|
||||
{target: Toolbar.menuButtonBlock},
|
||||
{target: Toolbar.modeButtonBlock},
|
||||
];
|
||||
|
||||
this.overObj = this.mouseoverEvent.bind(this);
|
||||
this.moveObj = this.mousemoveEvent.bind(this);
|
||||
// toolbar icon
|
||||
elements.forEach(function addEvent(elm) {
|
||||
var target = elm.target;
|
||||
// add event
|
||||
target.addEventListener('mouseover', this.overObj);
|
||||
target.addEventListener('mouseout', this.mouseoutEvent.bind(this));
|
||||
target.addEventListener('mousedown', this.clickEvent.bind(this));
|
||||
target.addEventListener('mouseup', this.clickEvent.bind(this));
|
||||
}, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* mousemove event
|
||||
*/
|
||||
mousemoveEvent: function tooltip_mousemoveEvent(ev) {
|
||||
if(this.isShow()) {
|
||||
// hide the tooltip in mouse movement at tooltip display.
|
||||
this.stopMousemoveEvent(ev.target);
|
||||
this.hideTimeoutID = setTimeout(function(){
|
||||
Tooltip.hide();
|
||||
}, this.hideTimeoutData);
|
||||
return;
|
||||
}
|
||||
if(this.showTimeoutID) {
|
||||
clearTimeout(this.showTimeoutID);
|
||||
}
|
||||
|
||||
var bounds = ev.currentTarget.getBoundingClientRect();
|
||||
var posY = Math.ceil(bounds.bottom);
|
||||
var top = Math.ceil(bounds.top);
|
||||
var tips = null;
|
||||
if(ev.target.dataset.tips != null && ev.target.dataset.tips != undefined) {
|
||||
if(ev.target == Toolbar.searchInput) {
|
||||
tips = {raw: ev.target.dataset.tips};
|
||||
} else {
|
||||
tips = ev.target.dataset.tips;
|
||||
}
|
||||
}
|
||||
this.showTimeoutID = setTimeout(function(){
|
||||
Tooltip.showTarget = ev.target;
|
||||
var disp = {
|
||||
top: top,
|
||||
text: tips,
|
||||
x: ev.pageX,
|
||||
//y: ev.pageY
|
||||
y: posY,
|
||||
};
|
||||
Tooltip.displaySetting(disp);
|
||||
}, 150);
|
||||
},
|
||||
startMousemoveEvent: function tooltip_startMousemoveEvent(target) {
|
||||
target.addEventListener('mousemove', this.moveObj);
|
||||
},
|
||||
stopMousemoveEvent: function tooltip_stopMousemoveEvent(target) {
|
||||
target.removeEventListener('mousemove', this.moveObj);
|
||||
},
|
||||
|
||||
/**
|
||||
* mouseover event
|
||||
*/
|
||||
mouseoverEvent: function tooltip_mouseoverEvent(ev) {
|
||||
this.startMousemoveEvent(ev.target);
|
||||
},
|
||||
|
||||
/**
|
||||
* mouseout event
|
||||
*/
|
||||
mouseoutEvent: function tooltip_mouseoutEvent(ev) {
|
||||
this.hide();
|
||||
},
|
||||
|
||||
/**
|
||||
* click event
|
||||
*/
|
||||
clickEvent: function tooltip_clickEvent(ev) {
|
||||
this.hide();
|
||||
},
|
||||
|
||||
/**
|
||||
* show tooltip
|
||||
*/
|
||||
isShow: function tooltip_isShow(target) {
|
||||
if(!target){
|
||||
return this.tooltipBlock.classList.contains('visible');
|
||||
} else {
|
||||
if(target == this.showTarget){
|
||||
return this.tooltipBlock.classList.contains('visible');
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* show tooltip
|
||||
*/
|
||||
show: function tooltip_show() {
|
||||
this.tooltipBlock.classList.add('visible');
|
||||
},
|
||||
|
||||
/**
|
||||
* hide tooltip
|
||||
*/
|
||||
hide: function tooltip_hide() {
|
||||
clearTimeout(this.showTimeoutID);
|
||||
clearTimeout(this.hideTimeoutID);
|
||||
this.tooltipBlock.classList.remove('visible');
|
||||
},
|
||||
|
||||
/**
|
||||
* display setting
|
||||
*/
|
||||
displaySetting: function tooltip_displaySetting(disp) {
|
||||
if(disp.text == null || disp.text == undefined) {
|
||||
return;
|
||||
}
|
||||
this.show();
|
||||
this.tooltipBlock.style.left = '0px';
|
||||
if (typeof disp.text === 'string') {
|
||||
this.tooltipBlock.setAttribute('data-l10n-id', disp.text);
|
||||
} else if (disp.text.hasOwnProperty('raw')) {
|
||||
this.tooltipBlock.innerHTML = disp.text.replace(/\\n/g, '<br>');
|
||||
}
|
||||
|
||||
// pos x adjustment
|
||||
// 25 = scrollbar margin
|
||||
var maxW = this.tooltipBlock.offsetWidth + disp.x + 25;
|
||||
var posX = disp.x;
|
||||
if(maxW >= Browser.SCREEN_WIDTH) {
|
||||
// 58 = margin
|
||||
posX = Browser.SCREEN_WIDTH - this.tooltipBlock.offsetWidth - 58;
|
||||
}
|
||||
|
||||
// pos y adjustment
|
||||
var bounds = this.tooltipBlock.getBoundingClientRect();
|
||||
var hg = Math.ceil(bounds.height);
|
||||
var posY = disp.y + 20;
|
||||
var maxH = posY + hg;
|
||||
if(maxH >= Browser.SCREEN_HEIGHT) {
|
||||
// hover item
|
||||
posY = disp.top - 20 - hg;
|
||||
}
|
||||
|
||||
this.tooltipBlock.style.top = (posY + 0) + 'px';
|
||||
this.tooltipBlock.style.left = (posX + 0) + 'px';
|
||||
},
|
||||
};
|
||||
|
||||
18
gaia/tv_apps/browser/jsdoc.json
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "tv-browser",
|
||||
"tags": {
|
||||
"dictionaries": ["jsdoc"]
|
||||
},
|
||||
"source": {
|
||||
"include": ["tv_apps/browser/js/**/*.js"]
|
||||
},
|
||||
"plugins": [
|
||||
"plugins/markdown",
|
||||
"plugins/summarize"
|
||||
],
|
||||
"opts": {
|
||||
"private": true,
|
||||
"recurse": true,
|
||||
"destination": "docs/tv-browser"
|
||||
}
|
||||
}
|
||||
226
gaia/tv_apps/browser/locales/browser.en-US.properties
Executable file
|
|
@ -0,0 +1,226 @@
|
|||
# modal-dialog buttons
|
||||
ok=OK
|
||||
cancel=Cancel
|
||||
done=Done
|
||||
|
||||
enter-search-or-address.placeholder=Search or enter address
|
||||
history=History
|
||||
new-tab=New tab
|
||||
open-in-new-tab=Open link in new tab
|
||||
edit=Edit
|
||||
|
||||
# History headings
|
||||
future=Future
|
||||
today=Today
|
||||
yesterday=Yesterday
|
||||
last-7-days=Last 7 days
|
||||
this-month=This month
|
||||
last-6-months=Last 6 months
|
||||
older-than-6-months=Older than 6 months
|
||||
|
||||
# Months
|
||||
month-0=January
|
||||
month-1=February
|
||||
month-2=March
|
||||
month-3=April
|
||||
month-4=May
|
||||
month-5=June
|
||||
month-6=July
|
||||
month-7=August
|
||||
month-8=September
|
||||
month-9=October
|
||||
month-10=November
|
||||
month-11=December
|
||||
|
||||
# Start Page
|
||||
browser={{browserBrandShortName}}
|
||||
start-browsing=Enter a search term or Web address to start browsing.
|
||||
|
||||
# LOCALIZATION NOTE: depending on your locale, you might want to use a more
|
||||
# compact translation for top-sites-tab than for top-sites-startPage.
|
||||
top-sites-startPage = Top sites
|
||||
top-sites-tab = Top sites
|
||||
|
||||
# Settings
|
||||
browser-settings=Settings
|
||||
privacy-and-security=Privacy & Security
|
||||
clear-browsing-history=Clear browsing history
|
||||
confirm-clear-browsing-history=Clear browsing history?
|
||||
clear-cookies-and-stored-data=Clear cookies and stored data
|
||||
confirm-clear-cookies-and-stored-data=Clear cookies and other data stored by sites on this device?
|
||||
search-engines=Search Engines
|
||||
default-search-engine=Default search engine
|
||||
|
||||
# Bookmarks
|
||||
bookmarks=Bookmarks
|
||||
bookmark=Bookmark
|
||||
unbookmark=Unbookmark
|
||||
edit-bookmark=Edit bookmark
|
||||
edit-bookmark-header=Edit bookmark
|
||||
page-title=Page title
|
||||
address=Address
|
||||
add-to-home-screen=Add to home screen
|
||||
|
||||
# HTTP Authentication dialog
|
||||
username=Username
|
||||
password=Password
|
||||
login=Sign in
|
||||
login-to-a-website=Sign in to website
|
||||
http-authentication-message=The website {{host}} requires you to sign in.
|
||||
the-username-or-password-is-incorrect=The username or password is incorrect.
|
||||
|
||||
# Crash screen
|
||||
this-is-embarrassing=Well, this is embarrassing.
|
||||
not-responding=We tried to display this Web page, but it’s not responding.
|
||||
close-tab=Close tab
|
||||
reload-tab=Reload
|
||||
|
||||
# Awesomescreen
|
||||
search-for=Search for
|
||||
|
||||
# Generic save link context menu
|
||||
save-link=Save linked file
|
||||
|
||||
# Image saving context menu
|
||||
save-image=Save Image
|
||||
|
||||
# Video saving context menu
|
||||
save-video=Save Video
|
||||
|
||||
# Audio saving context menu
|
||||
save-audio=Save Audio
|
||||
|
||||
# Toolbar
|
||||
pocket=Pocket
|
||||
|
||||
# FTE
|
||||
fte-welcome=Welcome to Firefox
|
||||
fte-description=To sign in with Firefox Account lets you access your bookmarks and more whenever you use Firefox. You can register a Firefox Account on your mobile or tablet.
|
||||
skip=Skip
|
||||
|
||||
# Firefox Sync
|
||||
fxsync-sign-in=Sign In
|
||||
fxsync-sign-out=Sign Out
|
||||
fxsync-confirm-sign-out-title=Are you sure?
|
||||
fxsync-confirm-sign-out-message=Your synced Firefox bookmarks and history will no longer be available on this TV until you sign in again.
|
||||
fxsync-signed-in-as={{email}}
|
||||
fxsync-sign-in-to-sync=Sign in to Sync
|
||||
fxsync-sign-in-to-sync-description=Sync your bookmarks and history from your Firefox Account.
|
||||
fxsync-sign-in-to-sync-description-plus=You can create a Firefox Account on your smartphone or computer at https://accounts.firefox.com
|
||||
fxsync-desktop-bookmarks=Desktop bookmarks
|
||||
fxsync-mobile-bookmarks=Mobile bookmarks
|
||||
fxsync-enabled=Success! Your Firefox Account is ready to go! In the future, you can access and manage your account from Settings.
|
||||
fxsync-disabled=You have signed out successfully.
|
||||
|
||||
# XXX: from partner
|
||||
LT_APPS_SETTINGS=Settings
|
||||
LT_AUX=AUX
|
||||
LT_AV1_COMPONENT1=AV1/COMPONENT1
|
||||
LT_AV2_COMPONENT2=AV2/COMPONENT2
|
||||
LT_AV_COMPONENT=AV/COMPONENT
|
||||
LT_BD=Blu-ray
|
||||
LT_BROWSER_CONFIRM_EXIT2=Do you want to exit Browser?
|
||||
LT_CABLE=CABLE
|
||||
LT_CAMERA=CAMERA
|
||||
LT_CANCEL=Cancel
|
||||
LT_CH_BS=[MP]ch BS
|
||||
LT_CH_CS1=[MP]ch CS1
|
||||
LT_CH_CS2=[MP]ch CS2
|
||||
LT_CH_DIGITAL=[MP]ch digital
|
||||
LT_CL_EDIT=Edit
|
||||
LT_COMPUTER=COMPUTER
|
||||
LT_DEFAULT=Default
|
||||
LT_DIGA=[JP] DIGA
|
||||
LT_DISK=DISK
|
||||
LT_DISPLAYPORT=DisplayPort
|
||||
LT_DVD=DVD
|
||||
LT_DVD1=DVD1
|
||||
LT_DVD2=DVD2
|
||||
LT_DVD_REC=DVD REC
|
||||
LT_DVR=DVR
|
||||
LT_FAILED_=Failed.
|
||||
LT_FILE_SHARING_DEVICE_PASSWORD=Password
|
||||
LT_FILE_SHARING_DEVICE_USER=User
|
||||
LT_GAME=GAME
|
||||
LT_HDD_RECORDER=[JP]HDD Recorder
|
||||
LT_HDMI=HDMI
|
||||
LT_HDMI1=HDMI1
|
||||
LT_HDMI2=HDMI2
|
||||
LT_HDMI3=HDMI3
|
||||
LT_HDMI4=HDMI4
|
||||
LT_HOME_THTR=HOME THTR
|
||||
LT_INPUT=Input
|
||||
LT_INP_SAT=SATELLITE
|
||||
LT_LABEL_NOT_USED=Not used
|
||||
LT_LD_NETWORK_ERROR=Network error occured.
|
||||
LT_MEDIA_CTR=MEDIA CTR
|
||||
LT_MEDIA_EXT=MEDIA EXT
|
||||
LT_MONITOR2=MONITOR
|
||||
LT_NETWORK=Network
|
||||
LT_NETWORK_STATUS_BTN_CLOSE=close
|
||||
LT_NET_BOOKMARK=Bookmark
|
||||
LT_OTHER2=OTHER
|
||||
LT_PC=PC
|
||||
LT_PIN_TO_HOME=Pin to HOME
|
||||
LT_PVR=PVR
|
||||
LT_RECEIVER=RECEIVER
|
||||
LT_SE_HISTORY=History
|
||||
LT_STB=STB
|
||||
LT_TERR=TERR
|
||||
LT_TITEL_NO_DISPLAY=no display
|
||||
LT_TZ_CLOCK_ERROR_NW=Please setup network connection.
|
||||
LT_USER_INPUT=Customize
|
||||
LT_VCR=VCR
|
||||
LT_WB_OK=OK
|
||||
LT_WCL_RESET_TO_DEF=Reset to Default
|
||||
LT_WCL_SELECT_PAGE=Select webpage
|
||||
WB_LT_ALSO_PIN_TO_HOME=Also pin to home
|
||||
WB_LT_AUTH_MESSAGE=The server {{ host }} requires a user name and password. <br /> Message from the server : {{ msg }}
|
||||
WB_LT_BOOKMARK_ERROR_1=Bookmarks limit reached. Cannot add anymore bookmarks.
|
||||
WB_LT_BOOKMARK_THIS_PAGE=Bookmark this page?
|
||||
WB_LT_BROWSER_SETTINGS=Browser Settings
|
||||
WB_LT_CLEAR=Clear
|
||||
WB_LT_CLEAR_ALL_HISTORY=Clear all history?
|
||||
WB_LT_CLEAR_BROWSING_HISTORY=Clear All History
|
||||
WB_LT_CLEAR_HISTORY=Clear History
|
||||
WB_LT_CLEAR_STORED_DATA=Clear Cookies and Stored Data
|
||||
WB_LT_CONFIRM_DELETE_COOKIES=Do you want to delete Cookies?
|
||||
WB_LT_CONNECTION_IS_UNTRUSTED=This Connection is Untrusted
|
||||
WB_LT_CURSOR_MODE=Cursor Mode
|
||||
WB_LT_HOMEPAGE=Homepage
|
||||
WB_LT_LEARN_MORE=Learn More
|
||||
WB_LT_PAGE_CANNOT_BE_DISPLAYED=The page cannot be displayed
|
||||
WB_LT_PAN_MODE=Pan Mode
|
||||
WB_LT_PRESS_COLOR_KEY=Press hardware shortcut color key to switch in between Cursor mode and Pan mode.
|
||||
WB_LT_PRIVATE_BROWSING_1=Firefox won't remember any history for this window.
|
||||
WB_LT_PRIVATE_BROWSING_2=In a Private Browsing window, Firefox won't keep any browser history, search history, download history, web form history, cookies, or temporary internet files. However, files you download and bookmarks you make will be kept.
|
||||
WB_LT_PRIVATE_BROWSING_3=To stop Private Browsing, you can close this window.
|
||||
WB_LT_PRIVATE_BROWSING_4=While this computer won't have a record of your browsing history, your internet service provider or employer can still track the pages you visit.
|
||||
WB_LT_REMOVE=Remove
|
||||
WB_LT_REMOVE_FROM_BOOKMARKS=Remove webpage from bookmarks?
|
||||
WB_LT_REMOVE_FROM_TOP_SITES=Remove from Top Sites
|
||||
WB_LT_REMOVE_HISTORY=Remove history?
|
||||
WB_LT_RENAME_BOOKMARK=Rename bookmark?
|
||||
WB_LT_RESTORE_TO_DEFAULT=Restore to default
|
||||
WB_LT_SETTINGS_PRIVATE_BROWSING=Private Browsing
|
||||
WB_LT_SETTINGS_SEARCH_ENGINE=Search Engine
|
||||
WB_LT_SET_AS_HOMEPAGE=Set as Homepage
|
||||
WB_LT_SET_HOMEPAGE={{value0}} is now set as your homepage
|
||||
WB_LT_SWITCH_CURSOR_MODE=You have switched to Cursor Mode
|
||||
WB_LT_SWITCH_PAN_MODE=You have switched to Pan Mode
|
||||
WB_LT_TIPS_BOOKMARK_THIS_PAGE=Bookmark this page
|
||||
WB_LT_TIPS_CHANGE_SCREEN=Change screen
|
||||
WB_LT_TIPS_HISTORY_BACK=Previous page
|
||||
WB_LT_TIPS_HISTORY_FORWARD=Next page
|
||||
WB_LT_TIPS_HOMEPAGE=Show homepage
|
||||
WB_LT_TIPS_MENU=Menu
|
||||
WB_LT_TIPS_NEW_PRIVATE_WINDOW=New private window
|
||||
WB_LT_TIPS_OPEN_A_NEW_TAB=Open a new tab
|
||||
WB_LT_TIPS_RELOAD=Reload
|
||||
WB_LT_TIPS_SEARCH_BAR2={{ engine }} Search the Web
|
||||
WB_LT_TIPS_SHOW_YOUR_BOOKMARK=Show your bookmarks
|
||||
WB_LT_TIPS_STOP_LOADING=Stop loading this page
|
||||
WB_LT_TIPS_S_SEARCH={{value0}} search
|
||||
WB_LT_TIPS_TABS=Show tabs
|
||||
WB_LT_TIPS_ZOOM_IN=Zoom in
|
||||
WB_LT_W_BOOKMARK_DELETE=Delete bookmark
|
||||
70
gaia/tv_apps/browser/manifest.webapp
Executable file
|
|
@ -0,0 +1,70 @@
|
|||
{
|
||||
"name": "Browser",
|
||||
"description": "Browser",
|
||||
"launch_path": "/index.html",
|
||||
"type": "certified",
|
||||
"role": "deck",
|
||||
"permissions": {
|
||||
"browser":{},
|
||||
"systemXHR":{},
|
||||
"desktop-notification" : {},
|
||||
"firefox-accounts": {},
|
||||
"moz-extremely-unstable-and-will-change-webcomponents":{},
|
||||
"settings": { "access": "readwrite" },
|
||||
"geolocation": {},
|
||||
"audio-capture": {},
|
||||
"video-capture": {}
|
||||
},
|
||||
"locales": {
|
||||
"ar": {
|
||||
"name": "المتصفح",
|
||||
"description": "متصفح الويب"
|
||||
},
|
||||
"en-US": {
|
||||
"name": "Browser",
|
||||
"description": "Web Browser"
|
||||
},
|
||||
"fr": {
|
||||
"name": "Navigateur",
|
||||
"description": "Navigateur Web"
|
||||
},
|
||||
"ja-JP": {
|
||||
"name": "ブラウザ",
|
||||
"description": "ブラウザ"
|
||||
},
|
||||
"zh-TW": {
|
||||
"name": "網路瀏覽器",
|
||||
"description": "網路瀏覽器"
|
||||
}
|
||||
},
|
||||
"default_locale": "en-US",
|
||||
"icons": {
|
||||
"336": "/shared/resources/branding/browser_336.png"
|
||||
},
|
||||
"activities": {
|
||||
"view": {
|
||||
"filters": {
|
||||
"type": "url",
|
||||
"url": {
|
||||
"required":true, "pattern":"https?:.{1,16384}", "patternFlags":"i"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"datastores-access": {
|
||||
"places": {
|
||||
"readonly": false,
|
||||
"description": "Read synced browsing history."
|
||||
},
|
||||
"bookmarks_store": {
|
||||
"readonly": false,
|
||||
"description": "Read synced browser bookmarks."
|
||||
}
|
||||
},
|
||||
"connections": {
|
||||
"webpage-open": {
|
||||
"description": "connection for opening webpage",
|
||||
"rules": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
225
gaia/tv_apps/browser/style/authentication_dialog.css
Executable file
|
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
* HTTP Authentication Dialog
|
||||
*/
|
||||
#http-authentication-dialog {
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
opacity: 1;
|
||||
background-color: rgba(0,0,0,0.9);
|
||||
z-index: 500;
|
||||
}
|
||||
#http-authentication-dialog.hidden {
|
||||
display: none;
|
||||
}
|
||||
#http-authentication-dialog-wrap {
|
||||
-moz-box-sizing: border-box;
|
||||
width: 1400px;
|
||||
margin: 50px auto;
|
||||
color: #f9f9f9;
|
||||
font-family: Fira Sans;
|
||||
font-size: 32px;
|
||||
text-align: center;
|
||||
}
|
||||
#http-authentication-header {
|
||||
-moz-box-sizing: border-box;
|
||||
width: 100%;
|
||||
padding: 30px;
|
||||
vertical-align: top;
|
||||
margin: 0px auto;
|
||||
text-align: left;
|
||||
display: inline-flex;
|
||||
}
|
||||
#http-authentication-key {
|
||||
-moz-box-sizing: border-box;
|
||||
float: left;
|
||||
width: 36px;
|
||||
height: 54px;
|
||||
margin-left: 30px;
|
||||
background-size: auto;
|
||||
background-position: 90%;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url('../img/key_active.png');
|
||||
}
|
||||
#http-authentication-message {
|
||||
-moz-box-sizing: border-box;
|
||||
margin: 0px 20px 0px 100px;
|
||||
text-align: left;
|
||||
overflow: hidden;
|
||||
font-family: Fira Sans;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#http-authentication-body {
|
||||
-moz-box-sizing: border-box;
|
||||
width: 100%;
|
||||
font-size: 32px;
|
||||
font-family: Fira Sans;
|
||||
text-align: left;
|
||||
color: white;
|
||||
}
|
||||
.http-authentication-title {
|
||||
text-align: right;
|
||||
height: 56px;
|
||||
width: 400px;
|
||||
}
|
||||
.http-authentication-input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
background-color: transparent;
|
||||
width: 700px;
|
||||
background-image: none;
|
||||
border-bottom: solid 2px #fff;
|
||||
-moz-transition: -moz-transform 0.16s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
border-bottom 0.16s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
.http-authentication-input-area {
|
||||
width: 600px;
|
||||
height: 100%;
|
||||
font-size: 38px;
|
||||
font-style: Italic;
|
||||
font-family: Fira Sans;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
background-image: none;
|
||||
}
|
||||
.http-authentication-input:hover,
|
||||
.http-authentication-input.exfocus {
|
||||
border-bottom: solid 3px #00caf2;
|
||||
transform: scale(1.2);
|
||||
outline:none;
|
||||
-moz-transition: -moz-transform 0.42s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
border-bottom 0.42s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
.http-authentication-input .input-line {
|
||||
width: 100%;
|
||||
}
|
||||
.http-authentication-input:hover .input-line,
|
||||
.http-authentication-input.exfocus .input-line {
|
||||
transform: scaleX(1);
|
||||
}
|
||||
.http-authentication-input.input {
|
||||
border-bottom: solid 3px #00caf2;
|
||||
transform: scale(1.0);
|
||||
-moz-transition: -moz-transform 0.42s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
border-bottom 0.42s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
.http-authentication-input.input .http-authentication-input-area {
|
||||
font-style: normal;
|
||||
-moz-transition: font-style 0.06s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
#http-authentication-username-clear,
|
||||
#http-authentication-password-clear {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
left: 40px;
|
||||
margin-left: -30px;
|
||||
display: inline-block;
|
||||
border-radius: 50%;
|
||||
border : 1px solid #5f6368;
|
||||
background: url("../style/images/ic_close.png") no-repeat center/contain #5f6368;
|
||||
position: relative;
|
||||
-moz-transition: -moz-transform 0.16s cubic-bezier(0.25, 0, 0, 1.0) ,
|
||||
background 0.16s cubic-bezier(0.25, 0, 0, 1.0) ,
|
||||
border 0.16s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
#http-authentication-username-clear:focus,
|
||||
#http-authentication-password-clear:focus,
|
||||
#http-authentication-username-clear:hover,
|
||||
#http-authentication-password-clear:hover {
|
||||
-moz-transition: -moz-transform 0.42s cubic-bezier(0.25, 0, 0, 1.0) ,
|
||||
background 0.42s cubic-bezier(0.25, 0, 0, 1.0) ,
|
||||
border 0.42s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
transform: scale(1.2);
|
||||
outline:none;
|
||||
border : 1px solid #fff;
|
||||
background: url("../style/images/ic_close_black.png") no-repeat center/contain #fff;
|
||||
|
||||
}
|
||||
#http-authentication-password-clear.active,
|
||||
#http-authentication-password-clear:active,
|
||||
#http-authentication-username-clear.active,
|
||||
#http-authentication-username-clear:active {
|
||||
-moz-transition: -moz-transform 0.06s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
-moz-transform: scale(1.0);
|
||||
border : 1px solid #00caf2;
|
||||
background: url("../style/images/ic_close.png") no-repeat center/contain #00caf2;
|
||||
}
|
||||
|
||||
#http-authentication-button {
|
||||
height: 100px;
|
||||
font-size: 32px;
|
||||
padding-top: 130px;
|
||||
}
|
||||
.http-authentication-button {
|
||||
-moz-box-sizing: border-box;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
width: 210px;
|
||||
height: 210px;
|
||||
top: 50%;
|
||||
color: white;
|
||||
font-family: Fira Sans;
|
||||
font-style: Italic;
|
||||
font-size: 24px;
|
||||
background-image: none;
|
||||
border: 0;
|
||||
border-radius: 50%;
|
||||
display: inline-table;
|
||||
-moz-transition: -moz-transform 0.16s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
background-color 0.16s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
color 0.16s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
#http-authentication-cancel {
|
||||
left: 22px;
|
||||
background-color: #5f6368;
|
||||
color: #ffffff;
|
||||
}
|
||||
#http-authentication-ok {
|
||||
right: 22px;
|
||||
background-color: #0097b6;
|
||||
color: #ffffff;
|
||||
}
|
||||
#http-authentication-cancel:focus,
|
||||
#http-authentication-cancel:hover {
|
||||
-moz-transition: -moz-transform 0.42s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
background-color 0.42s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
color 0.42s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
background-color: #ffffff;
|
||||
color: #2d2d2d;
|
||||
-moz-transform: scale(1.2);
|
||||
}
|
||||
#http-authentication-ok:focus,
|
||||
#http-authentication-ok:hover {
|
||||
-moz-transition: -moz-transform 0.42s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
-moz-transform: scale(1.2);
|
||||
}
|
||||
|
||||
#http-authentication-cancel.active,
|
||||
#http-authentication-cancel:active {
|
||||
-moz-transition: -moz-transform 0.06s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
background-color 0.06s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
color 0.06s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
background-color: #00caf2;
|
||||
color: #ffffff;
|
||||
-moz-transform: scale(1.0);
|
||||
}
|
||||
#http-authentication-ok.active,
|
||||
#http-authentication-ok:active {
|
||||
-moz-transition: -moz-transform 0.06s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
background-color 0.06s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
background-color: #00758c;
|
||||
color: #ffffff;
|
||||
-moz-transform: scale(1.0);
|
||||
}
|
||||
|
||||
1058
gaia/tv_apps/browser/style/awesomescreen.css
Executable file
267
gaia/tv_apps/browser/style/browser_dialog.css
Executable file
|
|
@ -0,0 +1,267 @@
|
|||
/* --------------- dialog --------------- */
|
||||
#browser-dialog-base {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: inherit;
|
||||
height: 1080px;
|
||||
z-index: 500;
|
||||
background-color: rgba(0,0,0,0.9);
|
||||
}
|
||||
|
||||
#browser-dialog-base.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#browser-dialog {
|
||||
-moz-box-sizing: border-box;
|
||||
position: relative;
|
||||
width: 700px;
|
||||
height: 640px;
|
||||
color: #f9f9f9;
|
||||
}
|
||||
#browser-dialog-title {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
min-height: 0px;
|
||||
text-align: center;
|
||||
font-size: 34px;
|
||||
font-family: Fira Sans;
|
||||
font-style: Italic; /* TODO : Light Italic */
|
||||
color: #f9f9f9;
|
||||
}
|
||||
#browser-dialog-msg {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
min-height: 38px;
|
||||
margin-bottom: 34px;
|
||||
text-align: center;
|
||||
font-size: 38px;
|
||||
font-family: Fira Sans;
|
||||
font-style: Italic; /* TODO : Light Italic */
|
||||
color: #f9f9f9;
|
||||
display: inline-block;
|
||||
}
|
||||
#browser-dialog-input {
|
||||
position: relative;
|
||||
height: 70px;
|
||||
width: 700px;
|
||||
text-align: center;
|
||||
display: table;
|
||||
vertical-align: middle;
|
||||
margin: 24px auto 20px;
|
||||
border-bottom: 2px solid #E7E7E7;
|
||||
-moz-transform: scale(1);
|
||||
-moz-transition: all 0.16s cubic-bezier(0.25, 0, 0, 1) 0s;
|
||||
}
|
||||
#browser-dialog-input:hover,
|
||||
#browser-dialog-input.exfocus {
|
||||
-moz-transform: scale(1.2);
|
||||
outline:none;
|
||||
-moz-transition: -moz-transform 0.42s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
border-bottom 0.42s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
#browser-dialog-input.input {
|
||||
border-bottom: solid 3px #00caf2;
|
||||
-moz-transform: scale(1.0);
|
||||
-moz-transition: -moz-transform 0.42s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
border-bottom 0.42s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
#browser-dialog-input.input #browser-dialog-input-area {
|
||||
font-style: normal;
|
||||
-moz-transition: font-style 0.06s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
#browser-dialog-input-area {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
width: 600px;
|
||||
height: 100%;
|
||||
background: none repeat scroll 0% 0% transparent;
|
||||
border: medium none;
|
||||
vertical-align: middle;
|
||||
margin: auto 50px;
|
||||
text-align: center;
|
||||
font-family: "Fira Sans";
|
||||
font-style: italic;
|
||||
font-size: 38px;
|
||||
color: #FFF;
|
||||
display: table-cell;
|
||||
}
|
||||
#browser-dialog-input .input-line {
|
||||
width: 100%;
|
||||
}
|
||||
#browser-dialog-input:hover .input-line,
|
||||
#browser-dialog-input.exfocus .input-line {
|
||||
transform: scaleX(1);
|
||||
}
|
||||
#browser-dialog-input-clear {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background: url('../style/images/ic_close.png') no-repeat scroll center center / contain #5F6368;
|
||||
border-radius: 50%;
|
||||
transition: -moz-transform 0.16s cubic-bezier(0.25, 0, 0, 1) 0s, background-color 0.16s cubic-bezier(0.25, 0, 0, 1) 0s, color 0.16s cubic-bezier(0.25, 0, 0, 1) 0s;
|
||||
pointer-events: auto;
|
||||
display: table-cell;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
margin: auto;
|
||||
right: calc(50px / 2 - 15px);
|
||||
}
|
||||
|
||||
#browser-dialog-input-clear:focus,
|
||||
#browser-dialog-input-clear:hover {
|
||||
-moz-transition : -moz-transform 0.42s cubic-bezier(0.25, 0, 0, 1.0) ,
|
||||
background 0.42s cubic-bezier(0.25, 0, 0, 1.0) ,
|
||||
border 0.42s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
-moz-transform: scale(1.2);
|
||||
outline:none;
|
||||
border : 1px solid #fff;
|
||||
background: url("../style/images/ic_close_black.png") no-repeat center/contain #fff;
|
||||
}
|
||||
#browser-dialog-input-clear.active,
|
||||
#browser-dialog-input-clear:active {
|
||||
-moz-transition : -moz-transform 0.06s cubic-bezier(0.25, 0, 0, 1.0) ,
|
||||
background 0.06s cubic-bezier(0.25, 0, 0, 1.0) ,
|
||||
border 0.06s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
-moz-transform: scale(1.0);
|
||||
border : 1px solid #00caf2;
|
||||
background: url("../style/images/ic_close.png") no-repeat center/contain #00caf2;
|
||||
}
|
||||
#browser-dialog-button {
|
||||
position: relative;
|
||||
display: table;
|
||||
height: 210px;
|
||||
margin: 130px auto;
|
||||
}
|
||||
.browser-dialog-button {
|
||||
position: relative;
|
||||
bottom: 0;
|
||||
height: 210px;
|
||||
width: 210px;
|
||||
margin-left: 22px;
|
||||
margin-right: 22px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
float: left;
|
||||
font-size: 24px;
|
||||
font-family: Fira Sans;
|
||||
font-style: Italic;
|
||||
border: 0;
|
||||
border-radius: 50%;
|
||||
color: #ffffff;
|
||||
background-image: none;
|
||||
-moz-transition: -moz-transform 0.16s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
-moz-transform: scale(1.0);
|
||||
}
|
||||
#browser-dialog-button1,
|
||||
#browser-dialog-button2 {
|
||||
display: none;
|
||||
}
|
||||
#browser-dialog-button1.visible,
|
||||
#browser-dialog-button2.visible {
|
||||
display: block;
|
||||
}
|
||||
#browser-dialog-button1 {
|
||||
background-color: #5f6368;
|
||||
}
|
||||
#browser-dialog-button2 {
|
||||
background-color: #0097b6;
|
||||
}
|
||||
#browser-dialog-button2[data-type="del_cookie"],
|
||||
#browser-dialog-button2[data-type="clear_history"] {
|
||||
background-color: #e63d2f;
|
||||
}
|
||||
.browser-dialog-button:focus,
|
||||
.browser-dialog-button:hover {
|
||||
-moz-transition: -moz-transform 0.42s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
-moz-transform: scale(1.2);
|
||||
}
|
||||
#browser-dialog-button1:focus,
|
||||
#browser-dialog-button1:hover {
|
||||
-moz-transition: background-color 0.42s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
color 0.42s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
-moz-transform 0.42s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
background-color: #ffffff;
|
||||
color: #2d2d2d;
|
||||
}
|
||||
#browser-dialog-button2:focus,
|
||||
#browser-dialog-button2:hover {
|
||||
}
|
||||
#browser-dialog-button1.active,
|
||||
#browser-dialog-button2.active,
|
||||
.browser-dialog-button:active {
|
||||
-moz-transition: -moz-transform 0.06s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
background-color: #00758c;
|
||||
-moz-transform: scale(1.0);
|
||||
}
|
||||
#browser-dialog-button1.active,
|
||||
#browser-dialog-button1:active {
|
||||
-moz-transition: background-color 0.06s cubic-bezier(0.25, 0, 0, 1.0) ,
|
||||
color 0.06s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
background-color: #00caf2;
|
||||
color: #ffffff;
|
||||
}
|
||||
#browser-dialog-button2.active,
|
||||
#browser-dialog-button2:active {
|
||||
-moz-transition: background-color 0.06s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
background-color: #00758c;
|
||||
}
|
||||
#browser-dialog-button2[data-type="del_cookie"].active,
|
||||
#browser-dialog-button2[data-type="del_cookie"]:active,
|
||||
#browser-dialog-button2[data-type="clear_history"]:active {
|
||||
-moz-transition: background-color 0.06s cubic-bezier(0.25, 0, 0, 1.0) ,
|
||||
color 0.06s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
background-color: #ac2e23;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
/*IFDEF_FIREFOX_SYNC*/
|
||||
#browser-dialog-base[data-type="signout_confirm"] #browser-dialog {
|
||||
width: 91rem;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#browser-dialog-base[data-type="signout_confirm"] #browser-dialog-title {
|
||||
position: absolute;
|
||||
top: 24.5rem;
|
||||
font-size: 3.8rem;
|
||||
font-weight: lighter;
|
||||
line-height: 3.8rem;
|
||||
}
|
||||
|
||||
#browser-dialog-base[data-type="signout_confirm"] #browser-dialog-msg {
|
||||
position: absolute;
|
||||
top: calc(24.5rem + 3.8rem + 6rem);
|
||||
font-size: 3.8rem;
|
||||
font-weight: lighter;
|
||||
line-height: 4.8rem;
|
||||
}
|
||||
|
||||
#browser-dialog-base[data-type="signout_confirm"] #browser-dialog-button {
|
||||
position: absolute;
|
||||
bottom: 24.5rem;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: center;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#browser-dialog-base[data-type="signout_confirm"] #browser-dialog-button1 {
|
||||
background-color: #5f6368;
|
||||
}
|
||||
|
||||
#browser-dialog-base[data-type="signout_confirm"] #browser-dialog-button1:hover,
|
||||
#browser-dialog-base[data-type="signout_confirm"] #browser-dialog-button1:focus {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#browser-dialog-base[data-type="signout_confirm"] #browser-dialog-button2{
|
||||
background-color: #e63d2f;
|
||||
}
|
||||
/*ENDIF_FIREFOX_SYNC*/
|
||||
43
gaia/tv_apps/browser/style/components.css
Executable file
|
|
@ -0,0 +1,43 @@
|
|||
/* checkbox */
|
||||
|
||||
.settings-horizontal-list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
input[type="checkbox"].settings-list-checkbox {
|
||||
display: none;
|
||||
}
|
||||
|
||||
input[type="checkbox"].settings-list-checkbox + label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
border: 0.4rem solid #5f6368;
|
||||
border-radius: 50%;
|
||||
margin-right: 2rem;
|
||||
line-height: 5rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
input[type="checkbox"].settings-list-checkbox:disabled + label,
|
||||
input[type="checkbox"].settings-list-checkbox:disabled ~ span {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
input[type="checkbox"].settings-list-checkbox:checked + label::after {
|
||||
font-family: "smart-icons";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 3rem;
|
||||
text-rendering: optimizelegibility;
|
||||
content: "check";
|
||||
color: #00caf2;
|
||||
}
|
||||
|
||||
input[type="checkbox"].settings-list-checkbox ~ span {
|
||||
line-height: normal;
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
BIN
gaia/tv_apps/browser/style/images/Google-search-favicon-70x70.png
Executable file
|
After Width: | Height: | Size: 7.1 KiB |
BIN
gaia/tv_apps/browser/style/images/account_image.png
Executable file
|
After Width: | Height: | Size: 48 KiB |
33
gaia/tv_apps/browser/style/images/add-tab.svg
Executable file
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="54px"
|
||||
height="54px" viewBox="0 0 54 54" enable-background="new 0 0 54 54" xml:space="preserve">
|
||||
<g id="Layer_40" display="none">
|
||||
<rect x="-274.333" y="-526" display="inline" fill="#464445" width="691.333" height="784"/>
|
||||
</g>
|
||||
<g id="Layer_6">
|
||||
</g>
|
||||
<g id="Dark">
|
||||
<g>
|
||||
<g>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M33.59,16.501c-0.176-1.671-1.595-2.786-3.341-2.786H16.746
|
||||
c-1.864,0-3.061,1.264-3.061,3.128v13.504c0,1.738,1.162,3.154,2.83,3.339V20.219c0-1.864,1.534-3.718,3.398-3.718H33.59z
|
||||
M36.814,18.595H22.328c-1.968,0-3.716,2.094-3.716,4.062v14.297c0,1.968,1.748,3.332,3.716,3.332h14.485
|
||||
c1.968,0,3.502-1.364,3.502-3.332V22.656C40.315,20.688,38.782,18.595,36.814,18.595z M35.394,30.061
|
||||
c0,0.499-0.405,1.127-0.904,1.127h-3.981v4.006c0,0.499-0.602,0.904-1.102,0.904h-0.524c-0.5,0-1.189-0.405-1.189-0.904v-4.006
|
||||
h-4c-0.5,0-0.904-0.628-0.904-1.127v-0.452c0-0.5,0.405-1.232,0.904-1.232h4v-3.982c0-0.5,0.689-0.904,1.189-0.904h0.524
|
||||
c0.5,0,1.102,0.404,1.102,0.904v3.982h3.981c0.5,0,0.904,0.732,0.904,1.232V30.061z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Layer_5" display="none">
|
||||
<path display="inline" opacity="0.3" fill-rule="evenodd" clip-rule="evenodd" fill="#E30613" d="M0,0v54h54V0H0z M47,47H7V7h40V47
|
||||
z"/>
|
||||
</g>
|
||||
<g id="name" display="none">
|
||||
<text transform="matrix(1 0 0 1 4.1891 51.1551)" display="inline" fill="#646363" font-family="'UniversLTStd-Cn'" font-size="8">add-tab</text>
|
||||
</g>
|
||||
<g id="Title" display="none">
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
BIN
gaia/tv_apps/browser/style/images/background_black.png
Executable file
|
After Width: | Height: | Size: 381 B |
BIN
gaia/tv_apps/browser/style/images/background_white.png
Executable file
|
After Width: | Height: | Size: 666 B |
25
gaia/tv_apps/browser/style/images/check-on.svg
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="54px"
|
||||
height="54px" viewBox="0 0 54 54" enable-background="new 0 0 54 54" xml:space="preserve">
|
||||
<g id="Layer_40" display="none">
|
||||
<rect x="-52.333" y="-600" display="inline" fill="#464445" width="691.333" height="784"/>
|
||||
</g>
|
||||
<g id="Layer_6">
|
||||
</g>
|
||||
<g id="Dark">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#00caf2" d="M25.019,38.429c-1.165,1.165-2.936,1.333-4.29,0.527l-6.786-9.133
|
||||
l2.462-2.891l5.262,7.151c0.009,0.01,0.015,0.021,0.024,0.03c0.447,0.446,1.158,0.458,1.623,0.042l0.005,0.005l16.739-19.613v6.009
|
||||
L25.019,38.429z"/>
|
||||
</g>
|
||||
<g id="Layer_5" display="none">
|
||||
<path display="inline" opacity="0.3" fill-rule="evenodd" clip-rule="evenodd" fill="#E30613" d="M0,0v54h54V0H0z M47,47H7V7h40V47
|
||||
z"/>
|
||||
</g>
|
||||
<g id="name" display="none">
|
||||
<text transform="matrix(1 0 0 1 4.3136 51.1551)" display="inline" fill="#646363" font-family="'UniversLTStd-Cn'" font-size="8">check</text>
|
||||
</g>
|
||||
<g id="Title" display="none">
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
25
gaia/tv_apps/browser/style/images/check.svg
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="54px"
|
||||
height="54px" viewBox="0 0 54 54" enable-background="new 0 0 54 54" xml:space="preserve">
|
||||
<g id="Layer_40" display="none">
|
||||
<rect x="-52.333" y="-600" display="inline" fill="#464445" width="691.333" height="784"/>
|
||||
</g>
|
||||
<g id="Layer_6">
|
||||
</g>
|
||||
<g id="Dark">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#1D1D1B" d="M25.019,38.429c-1.165,1.165-2.936,1.333-4.29,0.527l-6.786-9.133
|
||||
l2.462-2.891l5.262,7.151c0.009,0.01,0.015,0.021,0.024,0.03c0.447,0.446,1.158,0.458,1.623,0.042l0.005,0.005l16.739-19.613v6.009
|
||||
L25.019,38.429z"/>
|
||||
</g>
|
||||
<g id="Layer_5" display="none">
|
||||
<path display="inline" opacity="0.3" fill-rule="evenodd" clip-rule="evenodd" fill="#E30613" d="M0,0v54h54V0H0z M47,47H7V7h40V47
|
||||
z"/>
|
||||
</g>
|
||||
<g id="name" display="none">
|
||||
<text transform="matrix(1 0 0 1 4.3136 51.1551)" display="inline" fill="#646363" font-family="'UniversLTStd-Cn'" font-size="8">check</text>
|
||||
</g>
|
||||
<g id="Title" display="none">
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
61
gaia/tv_apps/browser/style/images/default-fav.svg
Executable file
|
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="54px"
|
||||
height="54px" viewBox="0 0 54 54" enable-background="new 0 0 54 54" xml:space="preserve">
|
||||
<g id="Layer_40" display="none">
|
||||
<rect x="-52.333" y="-526" display="inline" fill="#464445" width="691.333" height="784"/>
|
||||
</g>
|
||||
<g id="Layer_6">
|
||||
</g>
|
||||
<g id="Dark">
|
||||
<path fill="#1D1D1B" d="M37.209,30.338c0.622-1.237,1.562-4.018,0.758-6.292c0.006,0.022,0.011,0.044,0.017,0.066
|
||||
c-0.009-0.027-0.014-0.041-0.014-0.041s-0.151,0.455-0.363,1.158c-0.014-0.094-0.029-0.187-0.046-0.28
|
||||
c0.059-0.854,0.035-1.773-0.138-2.646c-0.273-1.381-1.34-2.58-1.904-2.967c0.028,0.021,0.057,0.046,0.087,0.073
|
||||
c-0.064-0.05-0.103-0.076-0.103-0.076s0.023,0.126,0.064,0.349c-0.612-0.962-1.544-1.415-1.544-1.415s0.029,0.161,0.075,0.498
|
||||
c-1.91-1.7-4.426-2.733-7.184-2.733c-2.806,0-5.363,1.069-7.285,2.823c0.106,0.127,0.216,0.274,0.33,0.445
|
||||
c0,0,0.731-0.131,1.622-0.046c1.55-1.095,3.397-1.684,5.333-1.684c2.477,0,4.806,0.965,6.558,2.718
|
||||
c0.092,0.092,0.18,0.185,0.268,0.28c-0.526-0.396-1.162-0.725-1.634-0.761c0.965,0.717,2.399,2.509,2.251,5.661
|
||||
c-0.247-0.519-0.544-0.927-0.866-1.211c0.346,3.164,0.043,3.844-0.167,4.685c-0.046-0.386-0.186-0.677-0.266-0.853
|
||||
c0,0-0.037,0.989-0.68,2.398c-0.487,1.067-0.989,1.397-1.212,1.36c-0.197-0.033-0.062-0.222-0.099-0.408
|
||||
c0,0-0.334,0.161-0.668,0.507c-0.316,0.327-0.6,0.69-0.748,0.587c0.111-0.093,0.192-0.247,0.278-0.389
|
||||
c-0.124,0.087-0.439,0.321-1.144,0.426c-0.288,0.043-1.515,0.266-3.147-0.55c0.238-0.027,0.593-0.111,0.865,0.049
|
||||
c-0.272-0.297-0.927-0.235-1.397-0.383c-0.409-0.129-0.944-0.704-1.251-0.994c1.255,0.307,2.589,0.086,3.361-0.442
|
||||
c0.779-0.533,1.24-0.922,1.654-0.829c0.414,0.092,0.689-0.323,0.368-0.691c-0.322-0.369-1.103-0.876-2.16-0.599
|
||||
c-0.745,0.195-1.669,1.019-3.078,0.185c-1.203-0.712-1.195-1.291-1.195-1.66c0-0.253,0.154-0.595,0.443-0.756
|
||||
c0.156,0.056,0.253,0.107,0.253,0.107s-0.072-0.111-0.118-0.165c0.011-0.003,0.022-0.006,0.033-0.009
|
||||
c0.127,0.043,0.414,0.149,0.559,0.222c0.196,0.099,0.263,0.199,0.263,0.199s0.046-0.029-0.002-0.13
|
||||
c-0.02-0.042-0.09-0.164-0.285-0.282c0.004,0,0.007,0,0.01-0.001c0.102,0.04,0.21,0.092,0.33,0.159
|
||||
c0.037-0.173,0.112-0.353,0.062-0.667c-0.035-0.221-0.031-0.278-0.087-0.359c-0.047-0.069,0.012-0.099,0.087-0.037
|
||||
c-0.018-0.055-0.043-0.109-0.072-0.164c0-0.001,0.001-0.002,0.001-0.003c0.004-0.017,0.014-0.036,0.029-0.058
|
||||
c0.23-0.319,1.665-1.072,1.779-1.157c0.141-0.104,0.284-0.257,0.391-0.435c0.146-0.091,0.25-0.466,0.277-0.749
|
||||
c0.011-0.113-0.235-0.247-0.365-0.272c-0.074-0.019-0.335-0.063-0.525-0.031c0.008,0.004,0.018,0.009,0.029,0.014
|
||||
c-0.266-0.017-0.625-0.024-1.11-0.02c-0.475,0.004-0.783-0.273-0.969-0.536c-0.037-0.056-0.07-0.11-0.1-0.158
|
||||
c-0.041-0.074-0.072-0.14-0.094-0.193c0.207-0.752,0.626-1.403,1.273-1.931c0.04-0.032-0.154,0.023-0.117-0.012
|
||||
c0.044-0.041,0.318-0.172,0.369-0.201c0.067-0.037-0.298-0.136-0.611-0.071c-0.312,0.065-0.374,0.102-0.535,0.185
|
||||
c0.065-0.068,0.277-0.175,0.226-0.164c-0.341,0.076-0.741,0.3-1.082,0.541c-0.003-0.031,0-0.055,0.006-0.105
|
||||
c-0.161,0.084-0.55,0.383-0.649,0.612c0-0.049,0-0.074-0.006-0.13c-0.111,0.102-0.217,0.221-0.313,0.354
|
||||
c-0.001,0.002-0.003,0.003-0.004,0.005c-1.013-0.252-1.874-0.191-2.593,0.04c-0.24-0.194-0.605-0.54-0.882-0.988
|
||||
c-0.026-0.041-0.029,0.092-0.052,0.049c-0.156-0.279-0.289-0.737-0.323-1.1c-0.003-0.036-0.006-0.072-0.007-0.106
|
||||
c0,0-0.133,0.078-0.276,0.316c-0.064,0.106-0.129,0.244-0.186,0.422c-0.032,0.102-0.056,0.162-0.079,0.218
|
||||
c-0.007,0.018,0.014-0.185,0.006-0.168c-0.035,0.072-0.135,0.185-0.167,0.315c-0.025,0.098-0.064,0.157-0.079,0.28
|
||||
c-0.001,0.002-0.002,0.004-0.003,0.006c-0.003-0.03-0.005-0.143-0.013-0.121c-0.083,0.218-0.16,0.468-0.221,0.751
|
||||
c-0.053,0.208-0.094,0.444-0.118,0.713c-0.027,0.308-0.031,0.658-0.003,1.057c-0.001,0.062-0.003,0.119-0.005,0.175
|
||||
c-0.273,0.376-0.439,0.7-0.508,0.859c-0.333,0.648-0.674,1.646-0.948,3.195c0,0,0.181-0.574,0.545-1.229
|
||||
c-0.001,0.008-0.003,0.017-0.004,0.025c-0.266,0.834-0.47,2.119-0.347,4.03c0.005-0.064,0.062-0.554,0.207-1.216
|
||||
c0.07,1.292,0.44,2.865,1.446,4.587c0.739,1.265,1.608,2.214,2.58,2.92c0.179,0.144,0.363,0.282,0.551,0.415
|
||||
c1.203,0.877,3.073,1.957,4.667,2.187c-0.557-0.161-0.903-0.482-0.903-0.482s1.895,0.608,3.277,0.556
|
||||
c-0.433-0.074-0.52-0.284-0.52-0.284s3.938,0.222,5.983-1.393c0.458-0.345,0.759-0.744,0.849-1.109
|
||||
c0.603-0.321,1.254-0.759,1.923-1.417c1.113-1.095,1.234-1.928,1.354-2.707c-0.004,0.024-0.01,0.049-0.015,0.073
|
||||
C37.366,30.815,37.332,30.54,37.209,30.338z"/>
|
||||
</g>
|
||||
<g id="Layer_5" display="none">
|
||||
<path display="inline" opacity="0.3" fill-rule="evenodd" clip-rule="evenodd" fill="#E30613" d="M0,0v54h54V0H0z M47,47H7V7h40V47
|
||||
z"/>
|
||||
</g>
|
||||
<g id="name" display="none">
|
||||
<text transform="matrix(1 0 0 1 4.3136 51.1551)" display="inline" fill="#646363" font-family="'UniversLTStd-Cn'" font-size="8">default-fav </text>
|
||||
</g>
|
||||
<g id="Title" display="none">
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.1 KiB |
BIN
gaia/tv_apps/browser/style/images/firefox_logo.png
Executable file
|
After Width: | Height: | Size: 41 KiB |
BIN
gaia/tv_apps/browser/style/images/ic_borwser_tips.png
Executable file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
gaia/tv_apps/browser/style/images/ic_close.png
Executable file
|
After Width: | Height: | Size: 658 B |
BIN
gaia/tv_apps/browser/style/images/ic_close_black.png
Executable file
|
After Width: | Height: | Size: 618 B |
BIN
gaia/tv_apps/browser/style/images/ic_cursormode.png
Executable file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
gaia/tv_apps/browser/style/images/ic_gray_globe.png
Executable file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
gaia/tv_apps/browser/style/images/ic_gray_padlock.png
Executable file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
gaia/tv_apps/browser/style/images/ic_panmode.png
Executable file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
gaia/tv_apps/browser/style/images/ic_unsecure.png
Executable file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
gaia/tv_apps/browser/style/images/img_borwser_privacy.png
Executable file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
gaia/tv_apps/browser/style/images/img_browser_private_logo.png
Executable file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
gaia/tv_apps/browser/style/images/img_cursor_arrow2x.png
Executable file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
gaia/tv_apps/browser/style/images/mozilla_screenshot.png
Executable file
|
After Width: | Height: | Size: 11 KiB |
BIN
gaia/tv_apps/browser/style/images/pocket_icon.png
Executable file
|
After Width: | Height: | Size: 489 B |
31
gaia/tv_apps/browser/style/images/reload-normal.svg
Executable file
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="54px"
|
||||
height="54px" viewBox="0 0 54 54" enable-background="new 0 0 54 54" xml:space="preserve">
|
||||
<g id="Layer_40" display="none">
|
||||
<rect x="-52.333" y="-452" display="inline" fill="#464445" width="691.333" height="784"/>
|
||||
</g>
|
||||
<g id="Layer_6">
|
||||
</g>
|
||||
<g id="Dark">
|
||||
<g>
|
||||
<g>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#5F6368" d="M39.701,24.33c-0.953-7.119-7.035-12.616-14.416-12.616
|
||||
c-8.041,0-14.56,6.52-14.56,14.561c0,8.042,6.519,14.56,14.56,14.56c4.022,0,7.663-1.63,10.298-4.266l-2.231-2.231
|
||||
c-2.064,2.065-4.916,3.343-8.067,3.343c-6.299,0-11.405-5.107-11.405-11.405c0-6.299,5.106-11.405,11.405-11.405
|
||||
c5.622,0,10.282,4.071,11.222,9.423c-1.445,0.126-2.765,0.437-3.866,0.883l4.343,4.343c0.539,0.539,1.413,0.539,1.951,0
|
||||
l4.339-4.338C42.251,24.763,41.03,24.472,39.701,24.33z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Layer_5" display="none">
|
||||
<path display="inline" opacity="0.3" fill-rule="evenodd" clip-rule="evenodd" fill="#E30613" d="M0,0v54h54V0H0z M47,47H7V7h40V47
|
||||
z"/>
|
||||
</g>
|
||||
<g id="name" display="none">
|
||||
<text transform="matrix(1 0 0 1 4.1891 50.4886)" display="inline" fill="#646363" font-family="'UniversLTStd-Cn'" font-size="8">reload</text>
|
||||
</g>
|
||||
<g id="Title" display="none">
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
176
gaia/tv_apps/browser/style/index.css
Executable file
|
|
@ -0,0 +1,176 @@
|
|||
html, body {
|
||||
width: 1920px;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
cursor: default;
|
||||
background-color : #e0e2e4;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
a {
|
||||
overflow: hidden;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.input-line {
|
||||
position: absolute;
|
||||
bottom: -2px;
|
||||
left: 0px;
|
||||
height: 3px;
|
||||
transition: transform 0.3s ease-in 0s;
|
||||
transform: scaleX(0);
|
||||
background-color: #00CAF2;
|
||||
}
|
||||
|
||||
/* --------------- layout --------------- */
|
||||
.side-window {
|
||||
width: 400px;
|
||||
height: 1080px;
|
||||
float: left;
|
||||
background-color: #282929;
|
||||
display: none;
|
||||
cursor: default;
|
||||
}
|
||||
#side-block[data-sidebar="true"] {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.main-window {
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 100%;
|
||||
float: left;
|
||||
cursor: default;
|
||||
display: block;
|
||||
}
|
||||
#main-block[data-sidebar="true"] {
|
||||
width: -moz-calc(1920px - 400px);
|
||||
}
|
||||
|
||||
/* --------------- block --------------- */
|
||||
|
||||
#web-block {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: -moz-calc(100% - 100px);
|
||||
cursor: default;
|
||||
top: 100px;
|
||||
}
|
||||
|
||||
/* --------------- other --------------- */
|
||||
input::-moz-focus-inner {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* --------------- browser --------------- */
|
||||
#web-block > iframe {
|
||||
-moz-box-sizing: border-box;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border: solid 0px;
|
||||
}
|
||||
|
||||
#block-l {
|
||||
position: absolute;
|
||||
left: 1px;
|
||||
width: 10px;
|
||||
height: 1080px;
|
||||
z-index: 200;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
#block-r {
|
||||
position: absolute;
|
||||
right: 1px;
|
||||
width: 10px;
|
||||
height: 1080px;
|
||||
z-index: 200;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
#block-d {
|
||||
position: absolute;
|
||||
bottom: 1px;
|
||||
width: 100%;
|
||||
height: 10px;
|
||||
z-index: 200;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* --------------- scroll --------------- */
|
||||
#scroll-u, #scroll-d {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
z-index: 190;
|
||||
}
|
||||
#scroll-u {
|
||||
top: 0px;
|
||||
}
|
||||
#scroll-d {
|
||||
bottom: 0px;
|
||||
}
|
||||
|
||||
#scroll-l, #scroll-r {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1080px;
|
||||
z-index: 190;
|
||||
}
|
||||
#scroll-l {
|
||||
left: 0px;
|
||||
}
|
||||
#scroll-r {
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
#scroll-u:not(.disable):hover {
|
||||
cursor: url('../img/scroll_up.cur'), auto;
|
||||
}
|
||||
#scroll-d:not(.disable):hover {
|
||||
cursor: url('../img/scroll_down.cur'), auto;
|
||||
}
|
||||
#scroll-l:not(.disable):hover {
|
||||
cursor: url('../img/scroll_left.cur'), auto;
|
||||
}
|
||||
#scroll-r:not(.disable):hover {
|
||||
cursor: url('../img/scroll_right.cur'), auto;
|
||||
}
|
||||
|
||||
/* --------------- fade --------------- */
|
||||
#fade-base {
|
||||
display: block;
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
opacity: 0;
|
||||
background-color: black;
|
||||
z-index: 1200;
|
||||
}
|
||||
#fade-base.fade {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
/* animation */
|
||||
#fade-base {
|
||||
-moz-transition-property: all;
|
||||
-moz-transition-duration: 1s;
|
||||
-moz-transition-timing-function: ease-out;
|
||||
-moz-transition-delay: 0s;
|
||||
|
||||
transition-property: all;
|
||||
transition-duration: 1s;
|
||||
transition-timing-function: ease-out;
|
||||
transition-delay: 0s;
|
||||
}
|
||||
|
||||
147
gaia/tv_apps/browser/style/search_result.css
Executable file
|
|
@ -0,0 +1,147 @@
|
|||
/* --------------- search-result --------------- */
|
||||
#search-result {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
background-color: #e0e2e4;
|
||||
z-index: 310;
|
||||
}
|
||||
|
||||
#search-result.visible {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#search-result-list {
|
||||
-moz-box-sizing: border-box;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
padding: 40px;
|
||||
font-family: Fira Sans;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.result-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margini: auto;
|
||||
}
|
||||
|
||||
.result-item {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
margin: auto;
|
||||
padding: 20px;
|
||||
border-bottom: solid 1px #b4b5b6;
|
||||
position: relative;
|
||||
-moz-transition: -moz-transform 0.6s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
font-size 0.6s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
height 0.6s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
border-bottom 0.6s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
.result-base {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.result-title {
|
||||
display: inline;
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
font-size: 32px;
|
||||
font-family: Fira Sans;
|
||||
color: #4d4d4d;
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
-moz-transition: height 0.6s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
font-size 0.6s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
|
||||
}
|
||||
|
||||
.result-url {
|
||||
display: inline;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
height: 31px; /* TODO: 24px */
|
||||
margin-top: 2px;
|
||||
font-size: 24px;
|
||||
font-family: Fira Sans;
|
||||
color: #9a9a9a;
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
-moz-transition: height 0.6s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
font-size 0.6s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
padding-left 0.16s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
.result-base,
|
||||
.result-title,
|
||||
.result-url {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.result-item:hover {
|
||||
height: 132px;
|
||||
border-bottom: solid 6px #b4b5b6;
|
||||
}
|
||||
|
||||
.result-item:hover > .result-base > .result-title {
|
||||
height: 50px;
|
||||
font-size: 38px;
|
||||
}
|
||||
|
||||
.result-item:hover > .result-base > .result-url {
|
||||
height: 36px;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.result-item:active {
|
||||
height: 132px;
|
||||
border-bottom: solid 6px #b4b5b6;
|
||||
-moz-transition: -moz-transform 0.16s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
height 0.16s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
border-bottom 0.16s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
.result-item:active > .result-base > .result-title {
|
||||
height: 50px;
|
||||
font-size: 38px;
|
||||
color: #00aac5;
|
||||
-moz-transition: height 0.16s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
font-size 0.16s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
color 0.16s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
.result-item:active > .result-base > .result-url {
|
||||
height: 36px;
|
||||
font-size: 28px;
|
||||
color: #00aac5;
|
||||
-moz-transition: height 0.16s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
font-size 0.16s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
color 0.16s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
753
gaia/tv_apps/browser/style/settings.css
Executable file
|
|
@ -0,0 +1,753 @@
|
|||
/* XXX: smart-button uses box-sizing: content-box, but it's overidden in toolbar.css */
|
||||
smart-button {
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
smart-button[type=simple-text] {
|
||||
background-color: #5f6368;
|
||||
border-radius: 4rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
smart-button[type=simple-text].disabled {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* --------------- settings-list --------------- */
|
||||
#settings-list {
|
||||
box-sizing: border-box;
|
||||
font-size: 32px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
/* top: 100px; */
|
||||
top: 0;
|
||||
width: 100%;
|
||||
/* height: 980px; */
|
||||
height: 1080px;
|
||||
background-color: #e0e2e4;
|
||||
color: #4d4d4d;
|
||||
z-index: 320;
|
||||
transition: 0.5s ease-in-out;
|
||||
transform: translateY(100%);
|
||||
}
|
||||
|
||||
.settings-screen #settings-list {
|
||||
transform: translateY(0%);
|
||||
}
|
||||
|
||||
/*IFDEF_FIREFOX_SYNC*/
|
||||
#fxsync-area {
|
||||
margin-top: 13rem
|
||||
}
|
||||
/*ENDIF_FIREFOX_SYNC*/
|
||||
|
||||
#settings-list-area {
|
||||
width: 120rem;
|
||||
margin: 50px auto 0 auto;
|
||||
}
|
||||
|
||||
/*IFDEF_FIREFOX_SYNC*/
|
||||
#fxsync-header,
|
||||
/*ENDIF_FIREFOX_SYNC*/
|
||||
#settings-header
|
||||
{
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 4.6rem;
|
||||
width: 100%;
|
||||
font-family: Fira Sans;
|
||||
font-size: 4.6rem;
|
||||
font-style: Italic; /* TODO: Regular? */
|
||||
color: #4d4d4d;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
p.fine-print {
|
||||
font-size: 2rem;
|
||||
line-height: 1.6rem;
|
||||
color: #00caf2;
|
||||
}
|
||||
|
||||
#settings-header {
|
||||
margin: 7rem 0;
|
||||
}
|
||||
|
||||
/*IFDEF_FIREFOX_SYNC*/
|
||||
#fxsync-header {
|
||||
margin-bottom: 5rem;
|
||||
}
|
||||
/*ENDIF_FIREFOX_SYNC*/
|
||||
|
||||
#settings-header-title {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#settings-list-item {
|
||||
top: 72px;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#settings-homepage,
|
||||
#settings-search-engine,
|
||||
#settings-clear-history,
|
||||
#settings-clear-cookie {
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
width: 100%;
|
||||
height: 72px;
|
||||
padding: 15px; /* TODO: 20px */
|
||||
font-family: Fira Sans;
|
||||
font-size: 32px;
|
||||
border-bottom: solid 1px #b4b5b6;
|
||||
transition: height 0.6s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
font-size 0.6s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
border-bottom 0.6s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
#settings-homepage:hover,
|
||||
#settings-search-engine:hover,
|
||||
#settings-clear-history:hover,
|
||||
#settings-clear-cookie:hover {
|
||||
height: 92px;
|
||||
font-size: 38px;
|
||||
border-bottom: solid 6px #b4b5b6;
|
||||
}
|
||||
|
||||
#settings-homepage:active,
|
||||
#settings-search-engine:active,
|
||||
#settings-clear-history:active,
|
||||
#settings-clear-cookie:active {
|
||||
height: 92px;
|
||||
font-size: 38px;
|
||||
border-bottom: solid 6px #b4b5b6;
|
||||
transition: height 0.16s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
font-size 0.16s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
border-bottom 0.16s cubic-bezier(0.25, 0, 0, 1.0);}
|
||||
|
||||
#settings-homepage-title,
|
||||
#settings-search-engine-title,
|
||||
#settings-clear-history-title,
|
||||
#settings-clear-cookie-title,
|
||||
#settings-homepage-name,
|
||||
#settings-search-engine-name {
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
margin: auto;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
transition: padding-left 0.42s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
color 0.42s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
#settings-homepage-title,
|
||||
#settings-search-engine-title {
|
||||
width: 54%;
|
||||
text-align: left;
|
||||
color: #4d4d4d;
|
||||
}
|
||||
|
||||
#settings-clear-history-title,
|
||||
#settings-clear-cookie-title {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
color: #4d4d4d;
|
||||
}
|
||||
|
||||
#settings-homepage-name,
|
||||
#settings-search-engine-name {
|
||||
padding-right: 5px;
|
||||
width: 45%;
|
||||
text-align: right;
|
||||
color: #8f8f8f;
|
||||
font-family: Fira Sans;
|
||||
font-style: Italic; /* TODO: Light Italic */
|
||||
}
|
||||
|
||||
#settings-search-engine-icon {
|
||||
position: absolute;
|
||||
bottom: 25%;
|
||||
right: 5px;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
margin: auto;
|
||||
border: 6px solid #8f8f8f;
|
||||
border-color: transparent #8f8f8f #8f8f8f transparent;
|
||||
}
|
||||
|
||||
#settings-homepage:active > #settings-homepage-title,
|
||||
#settings-search-engine:active > #settings-search-engine-title,
|
||||
#settings-clear-history:active > #settings-clear-history-title,
|
||||
#settings-clear-cookie:active > #settings-clear-cookie-title {
|
||||
padding-left: 10px;
|
||||
/*transition: padding-left 0.42s cubic-bezier(0.25, 0, 0, 1.0);*/
|
||||
}
|
||||
|
||||
#settings-homepage:active > #settings-homepage-title,
|
||||
#settings-homepage:active > #settings-homepage-name,
|
||||
#settings-search-engine:active > #settings-search-engine-title,
|
||||
#settings-search-engine:active > #settings-search-engine-name,
|
||||
#settings-clear-history:active > #settings-clear-history-title,
|
||||
#settings-clear-cookie:active > #settings-clear-cookie-title {
|
||||
color: #00aac5;
|
||||
/*transition: color 0.42s cubic-bezier(0.25, 0, 0, 1.0);*/
|
||||
}
|
||||
|
||||
#settings-search-engine:active > #settings-search-engine-icon {
|
||||
border: 6px solid #00aac5;
|
||||
border-color: transparent #00aac5 #00aac5 transparent;
|
||||
}
|
||||
|
||||
/* Firefox Sync */
|
||||
|
||||
/*IFDEF_FIREFOX_SYNC*/
|
||||
#fxsync-sign-in > smart-button {
|
||||
background-color: #4d4d4d;
|
||||
line-height: 4rem;
|
||||
height: 4rem;
|
||||
}
|
||||
|
||||
#fxsync-sign-in-to-sync-description,
|
||||
#fxsync-signed-in-as {
|
||||
color: #4d4d4d;
|
||||
font-style: italic;
|
||||
font-size: 2.8rem;
|
||||
font-weight: lighter;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#fxsync-disabled {
|
||||
margin-left: 4.5rem;
|
||||
}
|
||||
|
||||
#fxsync-disabled > p {
|
||||
font-size: 2.8rem;
|
||||
font-style: italic;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
#fxsync-enabled {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: -5.1rem;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#fxsync-enabled > p {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#fxsync-enabled[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#fxsync-enabled > smart-button {
|
||||
margin-left: 1.8rem;
|
||||
}
|
||||
|
||||
#fxsync-area.hidden,
|
||||
/*ENDIF_FIREFOX_SYNC*/
|
||||
#settings-dialog.hidden,
|
||||
#settings-dialog-homepage.hidden,
|
||||
#settings-dialog-search.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.settings-horizontal-list {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin-top: 2rem;
|
||||
margin-left: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.settings-horizontal-list-item {
|
||||
margin-right: 4rem;
|
||||
}
|
||||
|
||||
.settings-horizontal-list-item.disabled > span {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
#settings-dialog {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin: auto;
|
||||
background-color: rgba(0,0,0,0.9);
|
||||
font-size: 38px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Homepage setting dialog
|
||||
*/
|
||||
#settings-dialog-homepage {
|
||||
position: relative;
|
||||
top: 50%;
|
||||
width: 700px;
|
||||
height: 640px;
|
||||
margin: 0 auto;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
#settings-dialog-homepage-header {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 38px;
|
||||
margin: 0 auto 34px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#settings-dialog-homepage-header-title {
|
||||
display: inline;
|
||||
top: 0;
|
||||
left: 0;
|
||||
font-size: 38px;
|
||||
font-family: Fira Sans;
|
||||
font-style: Italic; /* TODO: Light Italic */
|
||||
color: #f9f9f9;
|
||||
}
|
||||
|
||||
#settings-dialog-homepage-input {
|
||||
position: relative;
|
||||
height: 70px;
|
||||
width: 700px;
|
||||
text-align: center;
|
||||
display: table;
|
||||
vertical-align: middle;
|
||||
margin: 24px auto 20px;
|
||||
border-bottom: 2px solid #E7E7E7;
|
||||
transform: scale(1);
|
||||
transition: all 0.16s cubic-bezier(0.25, 0, 0, 1) 0s;
|
||||
}
|
||||
|
||||
#settings-dialog-homepage-input:hover,
|
||||
#settings-dialog-homepage-input.exfocus {
|
||||
transform: scale(1.2);
|
||||
outline:none;
|
||||
}
|
||||
|
||||
#settings-dialog-homepage-input.input {
|
||||
transition: transform 0.06s cubic-bezier(0.25, 0, 0, 1.0) ,
|
||||
border-bottom 0.06s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
border-bottom: solid 3px #00caf2;
|
||||
transform: scale(1.0);
|
||||
outline:none;
|
||||
}
|
||||
|
||||
#settings-dialog-homepage-input.input #settings-dialog-homepage-input-area {
|
||||
font-style: normal;
|
||||
transition: font-style 0.06s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
#settings-dialog-homepage-input-area {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
width: 600px;
|
||||
height: 100%;
|
||||
background: none repeat scroll 0% 0% transparent;
|
||||
border: medium none;
|
||||
vertical-align: middle;
|
||||
margin: auto 50px;
|
||||
text-align: center;
|
||||
font-family: "Fira Sans";
|
||||
font-style: italic;
|
||||
font-size: 38px;
|
||||
color: #FFF;
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
#settings-dialog-homepage-input .input-line {
|
||||
width: 100%;
|
||||
bottom: 0px;
|
||||
}
|
||||
#settings-dialog-homepage-input:hover .input-line,
|
||||
#settings-dialog-homepage-input.exfocus .input-line {
|
||||
transform: scaleX(1);
|
||||
}
|
||||
|
||||
#settings-dialog-homepage-clear {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background: url('../style/images/ic_close.png') no-repeat scroll center center / contain #5F6368;
|
||||
border-radius: 50%;
|
||||
display: table-cell;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
margin: auto;
|
||||
right: calc(50px / 2 - 15px);
|
||||
transition: transform 0.16s cubic-bezier(0.25, 0, 0, 1) 0s,
|
||||
background-color 0.16s cubic-bezier(0.25, 0, 0, 1) 0s,
|
||||
color 0.16s cubic-bezier(0.25, 0, 0, 1) 0s;
|
||||
}
|
||||
|
||||
#settings-dialog-homepage-clear:focus,
|
||||
#settings-dialog-homepage-clear:hover {
|
||||
transition : transform 0.42s cubic-bezier(0.25, 0, 0, 1.0) ,
|
||||
background 0.42s cubic-bezier(0.25, 0, 0, 1.0) ,
|
||||
border 0.42s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
transform: scale(1.2);
|
||||
outline:none;
|
||||
border : 1px solid #fff;
|
||||
background: url("../style/images/ic_close_black.png") no-repeat center/contain #fff;
|
||||
|
||||
}
|
||||
|
||||
#settings-dialog-homepage-clear.active,
|
||||
#settings-dialog-homepage-clear:active {
|
||||
transition : transform 0.06s cubic-bezier(0.25, 0, 0, 1.0) ,
|
||||
background 0.06s cubic-bezier(0.25, 0, 0, 1.0) ,
|
||||
border 0.06s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
transform: scale(1.0);
|
||||
border : 1px solid #00caf2;
|
||||
background: url("../style/images/ic_close.png") no-repeat center/contain #00caf2;
|
||||
}
|
||||
|
||||
#settings-dialog-homepage-default {
|
||||
position: relative;
|
||||
top: 40px;
|
||||
left: 400px;
|
||||
height: 80px;
|
||||
min-width: 250px;
|
||||
margin-bottom: 40px;
|
||||
padding-left: 38px;
|
||||
padding-right: 38px;
|
||||
background-color: #000000;
|
||||
color: #ffffff;
|
||||
font-family: Fira Sans;
|
||||
font-size: 24px;
|
||||
border-radius: 40px;
|
||||
background-image: none;
|
||||
transition: transform 0.16s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
color 0.16s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
background-color 0.16s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
border: 1px solid #ffffff;
|
||||
}
|
||||
|
||||
#settings-dialog-homepage-default:focus,
|
||||
#settings-dialog-homepage-default:hover {
|
||||
transition: transform 0.42s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
color 0.42s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
background-color 0.42s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
border: none;
|
||||
color: #2d2d2d;
|
||||
background-color: #ffffff;
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
#settings-dialog-homepage-default.active,
|
||||
#settings-dialog-homepage-default:active {
|
||||
transition: transform 0.06s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
color 0.06s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
background-color 0.06s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
border: none;
|
||||
color: #ffffff;
|
||||
background-color: #00caf2;
|
||||
transform: scale(1.0);
|
||||
}
|
||||
|
||||
#settings-dialog-homepage-button {
|
||||
position: relative;
|
||||
margin: 130px auto;
|
||||
height: 210px;
|
||||
}
|
||||
|
||||
#settings-dialog-homepage-cancel,
|
||||
#settings-dialog-search-cancel {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 372px;
|
||||
height: 210px;
|
||||
width: 210px;
|
||||
font-family: Fira Sans;
|
||||
font-style: Italic;
|
||||
font-size: 24px;
|
||||
border: 0;
|
||||
border-radius: 50%;
|
||||
background-image: none;
|
||||
background-color: #5f6368;
|
||||
color: #ffffff;
|
||||
transition: transform 0.16s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
background-color 0.16s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
color 0.16s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
#settings-dialog-homepage-ok,
|
||||
#settings-dialog-search-ok {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 118px;
|
||||
height: 210px;
|
||||
width: 210px;
|
||||
font-family: Fira Sans;
|
||||
font-style: Italic;
|
||||
font-size: 24px;
|
||||
border: 0;
|
||||
border-radius: 50%;
|
||||
background-image: none;
|
||||
background-color: #0097b6;
|
||||
color: #ffffff;
|
||||
transition: transform 0.16s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
background-color 0.16s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
color 0.16s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Search Engine setting dialog
|
||||
*/
|
||||
#settings-dialog-search {
|
||||
position: absolute;
|
||||
width: 700px;
|
||||
height: 658px;
|
||||
top: calc(100% / 2 - 658px / 2); /* dialog centering */
|
||||
left: calc(100% / 2 - 700px / 2); /* dialog centering */
|
||||
}
|
||||
|
||||
#settings-dialog-search-header {
|
||||
position: absolute;
|
||||
top: -50px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 38px;
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#settings-dialog-search-header-title {
|
||||
display: inline;
|
||||
top: 0;
|
||||
left: 0;
|
||||
font-size: 44px;
|
||||
font-family: Fira Sans;
|
||||
font-style: Italic; /* TODO: Light Italic */
|
||||
color: #f9f9f9;
|
||||
}
|
||||
|
||||
#settings-dialog-search-select {
|
||||
position: absolute;
|
||||
top: 48px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
#settings-dialog-search-select-list {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
#settings-dialog-search-select-list > .item {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: inline-flex;
|
||||
outline: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#settings-dialog-search-select-list > .item > .title {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
#settings-dialog-search-select-list > .item > .title > .name {
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: inline;
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
line-height: 100%;
|
||||
margin-left: 94px;
|
||||
font-size: 44px;
|
||||
text-align: center;
|
||||
font-family: Fira Sans;
|
||||
font-style: Italic; /* TODO: Light Italic */
|
||||
color: #ffffff;
|
||||
transition: transform 0.6s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
color 0.6s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
#settings-dialog-search-select-list > .item > .check {
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 94px;
|
||||
margin: auto;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
#settings-dialog-search-select-list > .item > .check > .off {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
transition: transform 0.6s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
#settings-dialog-search-select-list > .item > .check > .on {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
background-image: url('../style/images/check-on.svg');
|
||||
background-position: contain;
|
||||
background-size: cover;
|
||||
transition: transform 0.6s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
#settings-dialog-search-button {
|
||||
position: absolute;
|
||||
margin: auto;
|
||||
top: 448px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 210px;
|
||||
}
|
||||
|
||||
#settings-dialog-search-cancel {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 372px;
|
||||
height: 210px;
|
||||
width: 210px;
|
||||
font-size: 24px;
|
||||
font-family: Fira Sans;
|
||||
font-style: Italic;
|
||||
border: 0;
|
||||
border-radius: 50%;
|
||||
background-image: none;
|
||||
background-color: #5f6368;
|
||||
color: #ffffff;
|
||||
transition: transform 0.42s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
background-color 0.42s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
color 0.42s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
#settings-dialog-search-ok {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 118px;
|
||||
height: 210px;
|
||||
width: 210px;
|
||||
font-size: 24px;
|
||||
font-family: Fira Sans;
|
||||
font-style: Italic;
|
||||
border: 0;
|
||||
border-radius: 50%;
|
||||
background-image: none;
|
||||
background-color: #0097b6;
|
||||
color: #ffffff;
|
||||
transition: transform 0.42s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
background-color 0.42s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
color 0.4s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
#settings-dialog-search-select-list > .item:focus > .title > .name,
|
||||
#settings-dialog-search-select-list > .item:hover > .title > .name,
|
||||
#settings-dialog-search-select-list > .item:focus > .check > .on,
|
||||
#settings-dialog-search-select-list > .item:hover > .check > .on {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
#settings-dialog-search-select-list > .item > .title > .name[data-display="selected"],
|
||||
#settings-dialog-search-select-list > .item > .title > .name[data-display="selected"] {
|
||||
color: #00caf2;
|
||||
}
|
||||
|
||||
#settings-dialog-homepage-cancel:focus,
|
||||
#settings-dialog-search-cancel:focus,
|
||||
#settings-dialog-homepage-cancel:hover,
|
||||
#settings-dialog-search-cancel:hover {
|
||||
transition: transform 0.42s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
background-color 0.42s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
color 0.42s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
background-color: #ffffff;
|
||||
color: #2d2d2d;
|
||||
transform: scale(1.2);
|
||||
}
|
||||
#settings-dialog-homepage-ok:focus,
|
||||
#settings-dialog-search-ok:focus,
|
||||
#settings-dialog-homepage-ok:hover,
|
||||
#settings-dialog-search-ok:hover {
|
||||
transition: transform 0.42s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
background-color 0.42s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
background-color: #0097b6;
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
#settings-dialog-homepage-cancel.active,
|
||||
#settings-dialog-search-cancel.active,
|
||||
#settings-dialog-homepage-cancel:active,
|
||||
#settings-dialog-search-cancel:active {
|
||||
transition: transform 0.06s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
background-color 0.06s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
color 0.06s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
background-color: #00caf2;
|
||||
color: #ffffff;
|
||||
transform: scale(1.0);
|
||||
}
|
||||
|
||||
#settings-dialog-homepage-ok.active,
|
||||
#settings-dialog-search-ok.active ,
|
||||
#settings-dialog-homepage-ok:active,
|
||||
#settings-dialog-search-ok:active {
|
||||
transition: transform 0.06s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
background-color 0.06s cubic-bezier(0.25, 0, 0, 1.0),
|
||||
color 0.06s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
background-color: #00758c;
|
||||
color: #ffffff;
|
||||
transform: scale(1.0);
|
||||
}
|
||||
|
||||
#settings-banner-message {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
bottom: 100px;
|
||||
width: auto;
|
||||
height: auto;
|
||||
padding-left: 44px;
|
||||
padding-right: 44px;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
max-width : 80%;
|
||||
margin: 0 auto;
|
||||
z-index: 325;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
background-color: #000000;
|
||||
display: none;
|
||||
font-family: Fira Sans;
|
||||
font-size: 1.4rem;
|
||||
font-style: Italic;
|
||||
color: #ffffff;
|
||||
text-align: center;
|
||||
word-wrap: break-word;
|
||||
border-radius: 55px;
|
||||
transition: opacity 0.7s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
#settings-banner-message[data-display="visible"] {
|
||||
display: table;
|
||||
}
|
||||
218
gaia/tv_apps/browser/style/smartList.css
Executable file
|
|
@ -0,0 +1,218 @@
|
|||
.smart-list {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index : 310;
|
||||
display : none;
|
||||
background-color: rgba(0, 0, 0, 0.75);
|
||||
}
|
||||
|
||||
.smart-list.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.smart-list-container {
|
||||
width: 149rem;
|
||||
margin: 0px auto;
|
||||
margin-top: 7rem;
|
||||
pointer-events : none;
|
||||
}
|
||||
|
||||
.smart-list-title {
|
||||
width: 132rem;
|
||||
height: 5rem;
|
||||
margin: 0 auto;
|
||||
font-family: Fira Sans;
|
||||
font-size: 4.2rem;
|
||||
font-style: italic;
|
||||
font-weight: normal;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.smart-list-wrap {
|
||||
position: relative;
|
||||
height: 90rem;
|
||||
margin-top: 6rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
.smart-list-view {
|
||||
position: relative;
|
||||
width: 132rem;
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
height: 12rem;
|
||||
border-bottom: 0.1rem solid rgba(255, 255, 255, 0.3);
|
||||
pointer-events: auto;
|
||||
transform: translateY(-12rem);
|
||||
}
|
||||
|
||||
.smart-list-view .list-item:focus {
|
||||
background-color: rgba(255,255,255,0.2);
|
||||
}
|
||||
|
||||
.smart-list-view .list-item .icon-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item .icon-box-left {
|
||||
width: 12rem;
|
||||
height: 100%;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item .text-box {
|
||||
display: inline-flex;
|
||||
width: 108rem;
|
||||
height: 100%;
|
||||
padding-top: 1.5rem;
|
||||
padding-bottom: 1.5rem;
|
||||
font-family: Fira Sans;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item .text-box .title {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
font-size: 4rem;
|
||||
color: #fff;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item .icon-box-right {
|
||||
width: 12rem;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item .icon-box-right .icon:before {
|
||||
font-size: 12rem;
|
||||
line-height: 12rem;
|
||||
color: #fff;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item[data-type="folder"] .icon-box-left {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item[data-type="folder"] .icon-box-left .icon {
|
||||
color: #57d1ef;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item[data-type="folder"] .icon-box-left .icon:before {
|
||||
font-size: 12rem;
|
||||
line-height: 12rem;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item[data-type="folder"] .text-box {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item[data-type="folder"] .uri {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item[data-type="bookmark"] .icon-box-left .icon {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #858585;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
background-size: 3rem 3rem;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item[data-type="bookmark"] .icon-box-left .icon:before {
|
||||
font-size: 8rem;
|
||||
line-height: 8rem;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item[data-type="bookmark"] .text-box {
|
||||
width: 120rem;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item[data-type="bookmark"] .title {
|
||||
height: 55%;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item[data-type="bookmark"] .uri {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: 45%;
|
||||
font-size: 3rem;
|
||||
color: #9A9A9A;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item[data-type="bookmark"] .icon-box-right {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item[data-type="button"] .icon-box-left {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item[data-type="button"] .icon-box-left .icon {
|
||||
color: #fff;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item[data-type="button"] .icon-box-left .icon:before {
|
||||
font-size: 12rem;
|
||||
line-height: 12rem;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item[data-type="button"] .text-box {
|
||||
width: 120rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item[data-type="button"] .uri {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.smart-list-view .list-item[data-type="button"] .icon-box-right {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.smart-list-mask {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 132rem;
|
||||
height: 6rem;
|
||||
margin: 0 auto;
|
||||
background: transparent linear-gradient(to bottom, transparent, rgb(64, 65, 65)) repeat scroll 0% 0%;
|
||||
}
|
||||
|
||||
.smart-list-pointer {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: none;
|
||||
width: 6.4rem;
|
||||
height: 6.4rem;
|
||||
z-index: 550;
|
||||
background: url('./images/img_cursor_arrow2x.png') no-repeat center;
|
||||
background-size: cover;
|
||||
transform: translate(0, 0);
|
||||
transition: transform 0.42s cubic-bezier(0.25, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
.smart-list-pointer.show {
|
||||
display: block;
|
||||
}
|
||||
1119
gaia/tv_apps/browser/style/toolbar.css
Executable file
41
gaia/tv_apps/browser/style/tooltip.css
Executable file
|
|
@ -0,0 +1,41 @@
|
|||
#tooltip-block {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
max-width: 80rem;
|
||||
height: auto;
|
||||
background-color: #000000;
|
||||
/*opacity: 0.7;*/
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
word-wrap: break-word;
|
||||
border-radius: 55px;
|
||||
/*word-break: break-all;*/
|
||||
z-index: 305;
|
||||
|
||||
padding-left: 44px;
|
||||
padding-right: 44px;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
font-family: Fira Sans;
|
||||
font-size: 2.8rem;
|
||||
font-style: Italic;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
#tooltip-block.visible {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#tooltip-block {
|
||||
-moz-transition-property: opacity;
|
||||
-moz-transition-duration: 0.3s;
|
||||
-moz-transition-timing-function: ease;
|
||||
-moz-transition-delay: 0s;
|
||||
|
||||
transition-property: opacity;
|
||||
transition-duration: 0.3s;
|
||||
transition-timing-function: ease;
|
||||
transition-delay: 0s;
|
||||
}
|
||||
|
||||
17
gaia/tv_apps/browser/test/unit/.jshintrc
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"extends": "../../../../.jshintrc",
|
||||
"predef": [
|
||||
"assert",
|
||||
"suite",
|
||||
"test",
|
||||
"setup",
|
||||
"teardown",
|
||||
"suiteSetup",
|
||||
"suiteTeardown",
|
||||
"require",
|
||||
"requireApp",
|
||||
"sinon",
|
||||
"mocha",
|
||||
"loadBodyHTML"
|
||||
]
|
||||
}
|
||||
834
gaia/tv_apps/browser/test/unit/browser_db_test.js
Executable file
|
|
@ -0,0 +1,834 @@
|
|||
'use strict';
|
||||
/* global BrowserDB, NumberHelper, MockNavigatorSettings */
|
||||
/* jshint latedef:false */
|
||||
|
||||
requireApp('browser/shared/test/unit/mocks/' +
|
||||
'mock_navigator_moz_set_message_handler.js');
|
||||
|
||||
// Stub of Browser object.
|
||||
var Browser = {
|
||||
_doNotCustomize: true,
|
||||
_hasSV: false,
|
||||
|
||||
getDefaultData: function getDefaultData(callback) {
|
||||
|
||||
var data = {
|
||||
'topSites': [
|
||||
{
|
||||
'title': 'Mozilla',
|
||||
'uri': 'http://mozilla.org'
|
||||
},
|
||||
{
|
||||
'title': 'Firefox OS',
|
||||
'uri': 'http://mozilla.org/firefoxos'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// Imitate real getConfigurationData function by creating JSON from our
|
||||
// object and parsing it before returning it.
|
||||
var json = JSON.stringify(data);
|
||||
|
||||
// Select the data from the object.
|
||||
var parsed = JSON.parse(json);
|
||||
|
||||
// Done, notify callback.
|
||||
callback(parsed);
|
||||
},
|
||||
|
||||
getConfigurationData: function browser_getDefaultData(variant, callback) {
|
||||
|
||||
// For all other tests in the suite, we do _not_ want any customizations.
|
||||
// We use this handy boolean to skip this step.
|
||||
if (this._doNotCustomize) {
|
||||
callback({});
|
||||
return;
|
||||
}
|
||||
|
||||
var mccCode = NumberHelper.zfill(variant.mcc, 3);
|
||||
var mncCode = NumberHelper.zfill(variant.mnc, 3);
|
||||
|
||||
// Customization test data.
|
||||
var dataNoSV = {
|
||||
'000000': {
|
||||
bookmarks: [
|
||||
{
|
||||
title: 'customize test 1',
|
||||
uri: 'http://customize.test.mozilla.org/1'
|
||||
},
|
||||
{
|
||||
title: 'customize test 2',
|
||||
uri: 'http://customize.test.mozilla.org/2'
|
||||
}
|
||||
],
|
||||
searchEngines: [
|
||||
{
|
||||
title: 'customize search test 1',
|
||||
uri: 'http://customize.test.mozilla.org/search/1',
|
||||
iconUri: DATA_URI
|
||||
}
|
||||
],
|
||||
settings: {
|
||||
defaultSearchEngine: 'http://customize.test.mozilla.org/search/1'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var dataSV = {
|
||||
'000000': {
|
||||
bookmarks: [
|
||||
{
|
||||
title: 'customize test 1',
|
||||
uri: 'http://customize.test.mozilla.org/1'
|
||||
},
|
||||
{
|
||||
title: 'customize test 2',
|
||||
uri: 'http://customize.test.mozilla.org/2'
|
||||
}
|
||||
],
|
||||
searchEngines: [
|
||||
{
|
||||
title: 'customize search test 1',
|
||||
uri: 'http://customize.test.mozilla.org/search/1',
|
||||
iconUri: DATA_URI
|
||||
}
|
||||
],
|
||||
settings: {
|
||||
defaultSearchEngine: 'http://customize.test.mozilla.org/search/1'
|
||||
}
|
||||
},
|
||||
'214007': {
|
||||
bookmarks: [
|
||||
{
|
||||
title: 'customize SV test 1',
|
||||
uri: 'http://customize.sv.test.mozilla.org/1'
|
||||
},
|
||||
{
|
||||
title: 'customize SV test 2',
|
||||
uri: 'http://customize.sv.test.mozilla.org/2'
|
||||
}
|
||||
],
|
||||
searchEngines: [
|
||||
{
|
||||
title: 'customize SV search test 1',
|
||||
uri: 'http://customize.sv.test.mozilla.org/search/1',
|
||||
iconUri: DATA_URI
|
||||
}
|
||||
],
|
||||
settings: {
|
||||
defaultSearchEngine: 'http://customize.sv.test.mozilla.org/search/1'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Imitate real getConfigurationData function by creating JSON from our
|
||||
// object and parsing it before returning it.
|
||||
var json =
|
||||
this._hasSV ? JSON.stringify(dataSV) : JSON.stringify(dataNoSV);
|
||||
|
||||
// Select the data from the object.
|
||||
var parsed = JSON.parse(json);
|
||||
|
||||
if (mccCode === '000' && mncCode === '000' && this._hasSV) {
|
||||
BrowserDB.waitFirstRunWithSim();
|
||||
return;
|
||||
}
|
||||
// Done, notify callback.
|
||||
callback(parsed[mccCode + mncCode]);
|
||||
|
||||
return;
|
||||
},
|
||||
|
||||
setSearchProvider: function browser_setSearchProvider(uri, title, iconUri) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
requireApp('browser/shared/test/unit/mocks/mock_navigator_moz_settings.js');
|
||||
|
||||
requireApp('browser/shared/js/utilities.js');
|
||||
requireApp('browser/js/browser_db.js');
|
||||
|
||||
/* jshint maxlen:false */
|
||||
const DATA_URI =
|
||||
'data:image/x-icon;base64,AAABAAIAEBAAAAEACABoBQAAJgAAABAQAAABACAAaAQAAI4FAAAoAAAAEAAAACAAAAABAAgAAAAAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAICNgB6Pg4AajoaAHo6FgBuRioAAhJqADJCdgBmVkIAbm5eAIJCEgCGRhYAikoSAIpKFgCGShoAllYaAJJWHgCeWhoAnl4eAJJaKgCSXi4AnmYmAJZiLgCmZiIApmomALJ2LgDKjjoA1po+ANqaOgC+ikoA0qJWANquVgDeslIA5q5OAO66UgDmvl4A6sp2AOrKfgAGJooAAiaeAAIymgACHqIAAi6iAAYupgACOqYADjqmAAIyqgAGMqoABjauAAIutgACPrIACj62AAJCqgAGSq4AGlKmAAJCsgACRrIAAkq2AApOtgACQroABkK+AApKvgAOUrIAAla6AAZSvgAKWr4AFlayABZetgAiTqoARnKCAEJqpgAGRsIACkrCAAZKygAKSs4AElbOABZaygAKUtIAClbWAApa0gAOXtYADl7aABZe2gAGZs4ACmbOAA5i1gAObtYADmraAA5q3gASYtoAGm7eAAZy1gAKctoADnLiABZ24gAacuIAEnriABJ65gAaeuIAEnrqABZ+6gAqcuIAcpKGACaGwgAGiuoAFobmABqC5gASguoAEobuABaK6gASjvIAIorqACKS7gA2nuYAHqLmABqi6gAWpvoAGq76ADKq4gA6uvIARqLSAEKu4gBOrvIAdqbuADLC7gAuxv4APtb+AGbCzgBWxuYAUsruAFrW9gDmyoYA7tKKAPbengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAJiYmJiYmAAAAAAAAAAAmJig3Nzc3NCYmAAAAAAAsMjJHTU1PT09ANSgAAAAyLDxXYWFhYV1XXVxAOgAAMjxha15aLTY+VGtpUzoAPDxVa2RZSDAnBAdndGg6OTw9a2tJSktRTCcLA3J1Wzk8VmthMTACDERGDgxFfXM5PGluMyknJwsRERAQCH58OTxtcGFxcXoqHBoZFwWBdzk8aXBrX2V7JyIhGxgJgHZBPGJwb2JkUlIGIyAVZoJDAABSa3BqaycnASQfFn95QwAAUmtSUmsqhIQlHhR4QgAAAFJSFBRSMIWFgx0UFAAAAABSAAAAFBQUFBQUAAAAAAD4HwAA4AcAAMADAACAAQAAgAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAACAAQAAgAMAAIAHAAC4HwAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFgAAAC0AAABSAQMlhQIGRLMDCVTHAwlVyAIGQbIBAyOKAAAAVQAAAC0AAAAWAAAAAAAAAAAAAAAAAAAAAAAAAEcBAyOKAR186AIym/kBQLD/AEay/wBGs/8CRbL/BESr+wUniPACBCaaAAAASgAAAAAAAAAAAAAAAAAAAAAAJV1eATKS6gM/s/8HRcL/ClPT/wtV1P8MWtP/DV7V/whb0v8HUr7/B0ms9wEkVnIAAAAAAAAAAAAAAAAAQ6o3ATqk6QdCvP8Pa9r/EXrn/xF45/8TeuL/EXvm/w9z4f8Oa93/DXDi/wty2P8DV7v3A0OPXQAAAAAAR7IKAT2yzwhBvP8QeOT/E4Dq/xZ34/8bb9z/DDin/xlQp/8OUbH/CWfP/xCH7/8Uh+b/B2TN/xBZuPElbMgYAUC0WgI3sPYNYdT/E4ft/xR96P8TYtn/CErD/wU2r/8CJp3/ejkV/zFBdv8nhsP/F6X6/weJ6v8IT7f/F1K4ggFAuK8JSL//E4ft/xOH7f8HSsr/CEvN/xBVzv8MXdn/FVvL/wImnf+GRxX/azka/x6i5/8Yrvj/BnLW/wBKtscBR7byD2zX/xOH7f8ReOH/ASy2/wIzqv96PA//ikoT/yNPqv9DaqX/h0sY/4pLFf9HcoD/Lcb//xmh6f8CTrb0AEez/hSH6P8SjvL/CDy1/wMfof8CJp3/Aiad/4FCEf+cWxr/n18e/5JXH/+VVBn/ZVZB/z/X//8wwO//AUiy/gU+r/cUiej/I5Dv/xR65f83nOX/N5zl/02s8v8CLaL/2ps7/8qPOv+wdS7/p2Yh/29GKv9Rye//Obvx/wVOtfoHM6jpF4fo/yOQ7/8Tgev/GXHi/yly4v93p+7/Aiad/+y4UP/kr0//1pg9/6RoJP9tb13/VMfm/zGq4/8IWLzSBiKczxl64f0jkO//IYrr/xp54/8Seuj/FF/a/xRf2v8CEmn/571e/9+yUP+fZCb/c5OH/1jW9f8ed8j/EWXAkQUUkZwXbtz/EoHr/yOQ7/8Yg+b/EoHr/wImnf8CJp3/AgM3/+vKdf/ar1X/l2Es/2TAz/9BruH/FVy38BZyxxgCB4dcFF/a/xKB6/8UX9r/FF/a/xKB6/8ELaX/8NSJ/+/Tiv/qy3//0qJU/5JdLP9FoNP/Flex9xNkwVYAAAAAAAAAABRf2v8UX9r/X0FThXZQRt0UX9r/BzOr//Tfnv/0357/5suG/7yJSf+hYyX/UkJZuQhPtzsAAAAAAAAAAAAAAAAUX9qsFF/aMwAAAACZZjM0Z0ZPmVtSaNeZZjPtmWYz7ZVhL82QWyuukForXQAAAAAAAAAAAAAAAAAAAADAAwAAwAMAAMADAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAIADAACQDwAA';
|
||||
/* jshint maxlen:80 */
|
||||
|
||||
var clearBrowserStores = function(done) {
|
||||
BrowserDB.db.open(function() {
|
||||
BrowserDB.db.clearPlaces(function() {
|
||||
BrowserDB.db.clearVisits(function() {
|
||||
BrowserDB.db.clearIcons(function() {
|
||||
BrowserDB.db.clearBookmarks(function() {
|
||||
BrowserDB.db.clearSearchEngines(function() {
|
||||
BrowserDB.db.clearSettings(function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
suite('BrowserDB', function() {
|
||||
var realMozSettings = null;
|
||||
|
||||
const MSG_NAME = 'first-run-with-sim';
|
||||
var message = { mcc: '214', mnc: '007' };
|
||||
|
||||
suiteSetup(function() {
|
||||
realMozSettings = navigator.mozSettings;
|
||||
navigator.mozSettings = MockNavigatorSettings;
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
navigator.mozSettings = realMozSettings;
|
||||
});
|
||||
|
||||
// XXX: Disable this test since TV doesn't have operator customizations.
|
||||
// Enable and modify this test once customization is implemented.
|
||||
// suite('BrowserDB.operatorVariantCustomization WITH SV configuration',
|
||||
// function() {
|
||||
// var realSetMessageHandler = null;
|
||||
|
||||
// suiteSetup(function() {
|
||||
// realSetMessageHandler = window.navigator.mozSetMessageHandler;
|
||||
// window.navigator.mozSetMessageHandler =
|
||||
// window.MockNavigatormozSetMessageHandler;
|
||||
// });
|
||||
|
||||
// suiteTeardown(function() {
|
||||
// window.navigator.mozSetMessageHandler = realSetMessageHandler;
|
||||
// });
|
||||
|
||||
// setup(function(done) {
|
||||
// this.sinon.useFakeTimers();
|
||||
// navigator.mozSetMessageHandler.mSetup();
|
||||
// navigator.mozSettings.createLock()
|
||||
// .set({'operatorResources.data.topsites': {
|
||||
// 'topSites': [
|
||||
// {
|
||||
// 'title': 'Topsite',
|
||||
// 'uri': 'http://customize.test.mozilla.org/topsite'
|
||||
// }
|
||||
// ]}});
|
||||
|
||||
// // For these series of tests, we *do* want customizations to run.
|
||||
// Browser._doNotCustomize = false;
|
||||
// Browser._hasSV = true;
|
||||
// // And we want to manually initialize the DB.
|
||||
// BrowserDB.init(function() {
|
||||
// var itemsToAdd = 3;
|
||||
// BrowserDB.populate(0, function() {
|
||||
// if (--itemsToAdd <= 0) {
|
||||
// done();
|
||||
// }
|
||||
// });
|
||||
// window.navigator.mozSetMessageHandler.mTrigger(MSG_NAME, message);
|
||||
// });
|
||||
// });
|
||||
|
||||
// teardown(function(done) {
|
||||
// Browser._doNotCustomize = true;
|
||||
// Browser._hasSV = false;
|
||||
// clearBrowserStores(done);
|
||||
// window.navigator.mozSetMessageHandler.mTeardown();
|
||||
// });
|
||||
|
||||
// test('Operator Variant Customization -- Bookmarks with SV configuration',
|
||||
// function(done) {
|
||||
// BrowserDB.db.getAllBookmarks(function(bookmarks) {
|
||||
// assert.equal(bookmarks.length, 2);
|
||||
|
||||
// // We can't yet guarantee order of bookmarks (bug 895807)
|
||||
// if (bookmarks[0].uri == 'http://customize.sv.test.mozilla.org/2') {
|
||||
// assert.equal(bookmarks[0].uri,
|
||||
// 'http://customize.sv.test.mozilla.org/2');
|
||||
// assert.equal(bookmarks[0].title, 'customize SV test 2');
|
||||
// assert.equal(bookmarks[1].uri,
|
||||
// 'http://customize.sv.test.mozilla.org/1');
|
||||
// assert.equal(bookmarks[1].title, 'customize SV test 1');
|
||||
// } else {
|
||||
// assert.equal(bookmarks[1].uri,
|
||||
// 'http://customize.sv.test.mozilla.org/2');
|
||||
// assert.equal(bookmarks[1].title, 'customize SV test 2');
|
||||
|
||||
// assert.equal(bookmarks[0].uri,
|
||||
// 'http://customize.sv.test.mozilla.org/1');
|
||||
// assert.equal(bookmarks[0].title, 'customize SV test 1');
|
||||
// }
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// XXX: Disable this test since TV doesn't have operator customizations.
|
||||
// Enable and modify this test once customization is implemented.
|
||||
// suite('BrowserDB.operatorVariantCustomization', function() {
|
||||
// setup(function(done) {
|
||||
// navigator.mozSettings.createLock()
|
||||
// .set({'operatorResources.data.topsites': {
|
||||
// 'topSites': [
|
||||
// {
|
||||
// 'title': 'Topsite',
|
||||
// 'uri': 'http://customize.test.mozilla.org/topsite'
|
||||
// }
|
||||
// ]}});
|
||||
|
||||
// // For these series of tests, we *do* want customizations to run.
|
||||
// Browser._doNotCustomize = false;
|
||||
// // And we want to manually initialize the DB.
|
||||
// BrowserDB.init(function() {
|
||||
// var itemsToAdd = 3;
|
||||
// BrowserDB.populate(0, function() {
|
||||
// if (--itemsToAdd <= 0) {
|
||||
// done();
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// teardown(function(done) {
|
||||
// Browser._doNotCustomize = true;
|
||||
// Browser._hasSV = false;
|
||||
// clearBrowserStores(done);
|
||||
// });
|
||||
|
||||
// test('Operator Variant Customization -- Bookmarks without SV configuration',
|
||||
// function(done) {
|
||||
|
||||
// BrowserDB.db.getAllBookmarks(function(bookmarks) {
|
||||
// assert.equal(bookmarks.length, 2);
|
||||
|
||||
// // We can't yet guarantee order of bookmarks (bug 895807)
|
||||
// if (bookmarks[0].uri == 'http://customize.test.mozilla.org/2') {
|
||||
// assert.equal(bookmarks[0].uri, 'http://customize.test.mozilla.org/2');
|
||||
// assert.equal(bookmarks[0].title, 'customize test 2');
|
||||
|
||||
// assert.equal(bookmarks[1].uri, 'http://customize.test.mozilla.org/1');
|
||||
// assert.equal(bookmarks[1].title, 'customize test 1');
|
||||
// } else {
|
||||
// assert.equal(bookmarks[1].uri, 'http://customize.test.mozilla.org/2');
|
||||
// assert.equal(bookmarks[1].title, 'customize test 2');
|
||||
|
||||
// assert.equal(bookmarks[0].uri, 'http://customize.test.mozilla.org/1');
|
||||
// assert.equal(bookmarks[0].title, 'customize test 1');
|
||||
// }
|
||||
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
|
||||
// test('Operator Variant Customization -- Search Engines', function(done) {
|
||||
// BrowserDB.getSearchEngine(
|
||||
// 'http://customize.test.mozilla.org/search/1',
|
||||
// function(searchEngine) {
|
||||
// assert.equal(searchEngine.uri,
|
||||
// 'http://customize.test.mozilla.org/search/1');
|
||||
// assert.equal(searchEngine.title,
|
||||
// 'customize search test 1');
|
||||
|
||||
// done();
|
||||
// }
|
||||
// );
|
||||
// });
|
||||
|
||||
// test('Operator Variant Customization -- Top sites', function(done) {
|
||||
// BrowserDB.getTopSites(20, null, function(places) {
|
||||
// assert.equal(places.length, 3);
|
||||
|
||||
// assert.equal(places[0].uri,
|
||||
// 'http://customize.test.mozilla.org/topsite');
|
||||
// assert.equal(places[0].title, 'Topsite');
|
||||
|
||||
// assert.equal(places[1].uri, 'http://mozilla.org');
|
||||
// assert.equal(places[1].title, 'Mozilla');
|
||||
|
||||
// assert.equal(places[2].uri, 'http://mozilla.org/firefoxos');
|
||||
// assert.equal(places[2].title, 'Firefox OS');
|
||||
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
suite('BrowserDB.db', function() {
|
||||
setup(function(done) {
|
||||
clearBrowserStores(done);
|
||||
});
|
||||
|
||||
teardown(function(done) {
|
||||
clearBrowserStores(done);
|
||||
});
|
||||
|
||||
test('createPlace', function(done) {
|
||||
BrowserDB.db.createPlace('http://mozilla.org/test1', function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('getPlace', function(done) {
|
||||
BrowserDB.db.createPlace('http://mozilla.org/test2', function() {
|
||||
BrowserDB.db.getPlace('http://mozilla.org/test2', function(place) {
|
||||
done(function() {
|
||||
assert.equal(place.title, 'http://mozilla.org/test2');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('getPlace - not found', function(done) {
|
||||
BrowserDB.db.getPlace('http://mozilla.org/doesnotexist',
|
||||
function(place) {
|
||||
done(function() {
|
||||
assert.equal(place, undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('saveBookmark', function(done) {
|
||||
var bookmark = {
|
||||
uri: 'http://mozilla.org/test1',
|
||||
title: 'Mozilla',
|
||||
timestamp: new Date().valueOf()
|
||||
};
|
||||
BrowserDB.db.saveBookmark(bookmark, function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: SHOULD FAIL
|
||||
test('saveBookmarkInvalidURI', function(done) {
|
||||
var bookmark = {
|
||||
uri: 'notAURI',
|
||||
title: 'Mozilla',
|
||||
timestamp: new Date().valueOf()
|
||||
};
|
||||
BrowserDB.db.saveBookmark(bookmark, function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: SHOULD FAIL
|
||||
test('saveBookmarkInvalidTitle', function(done) {
|
||||
var bookmark = {
|
||||
uri: 'http://mozilla.org/test1',
|
||||
title: '',
|
||||
timestamp: new Date().valueOf()
|
||||
};
|
||||
BrowserDB.db.saveBookmark(bookmark, function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('saveBookmarkNonHTTP(S)', function(done) {
|
||||
var bookmark = {
|
||||
uri: 'rtsp://mozilla.org/test1',
|
||||
title: '',
|
||||
timestamp: new Date().valueOf()
|
||||
};
|
||||
BrowserDB.db.saveBookmark(bookmark, function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('getBookmark', function(done) {
|
||||
var bookmark = {
|
||||
uri: 'http://mozilla.org/test2',
|
||||
title: 'Mozilla'
|
||||
};
|
||||
BrowserDB.db.saveBookmark(bookmark, function() {
|
||||
BrowserDB.db.getBookmark('http://mozilla.org/test2',
|
||||
function(bookmark) {
|
||||
done(function() {
|
||||
assert.equal(bookmark.title, 'Mozilla');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('getBookmark - not found', function(done) {
|
||||
BrowserDB.db.getBookmark('http://mozilla.org/doesnotexist',
|
||||
function(bookmark) {
|
||||
done(function() {
|
||||
assert.equal(bookmark, undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('deleteBookmark', function(done) {
|
||||
var bookmark = {
|
||||
uri: 'http://mozilla.org/test3',
|
||||
title: 'Mozilla'
|
||||
};
|
||||
BrowserDB.db.saveBookmark(bookmark, function() {
|
||||
BrowserDB.db.deleteBookmark('http://mozilla.org/test3',
|
||||
function() {
|
||||
BrowserDB.db.getBookmark('http://mozilla.org/test3',
|
||||
function(bookmark) {
|
||||
done(function(bookmark) {
|
||||
assert.equal(bookmark, undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// XXX: updatePlace has been changed to visitMaxCheck. Redesign this test
|
||||
// later.
|
||||
// test('updatePlace', function(done) {
|
||||
// var place = {
|
||||
// uri: 'http://mozilla.org/test3',
|
||||
// title: 'Mozilla'
|
||||
// };
|
||||
// BrowserDB.db.updatePlace(place, function() {
|
||||
// place.title = 'Mozilla3';
|
||||
// BrowserDB.db.updatePlace(place, function() {
|
||||
// BrowserDB.db.getPlace('http://mozilla.org/test3',
|
||||
// function(place) {
|
||||
// done(function() {
|
||||
// assert.equal(place.title, 'Mozilla3');
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
test('updatePlaceScreenshot', function(done) {
|
||||
var uri = 'http://mozilla.org/test4';
|
||||
BrowserDB.db.updatePlaceScreenshot(uri, DATA_URI, function() {
|
||||
BrowserDB.db.getPlace(uri, function(place) {
|
||||
done(function() {
|
||||
assert.equal(place.screenshot, DATA_URI);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// XXX: updatePlace has been changed to visitMaxCheck. Redesign this test
|
||||
// later.
|
||||
// test('getPlacesByFrecency', function(done) {
|
||||
// var place1 = {
|
||||
// uri: 'http://mozilla.org/test1',
|
||||
// frecency: 3
|
||||
// };
|
||||
// var place2 = {
|
||||
// uri: 'http://mozilla.org/test2',
|
||||
// frecency: 2
|
||||
// };
|
||||
// var place3 = {
|
||||
// uri: 'http://mozilla.org/test3',
|
||||
// frecency: 1
|
||||
// };
|
||||
// BrowserDB.db.updatePlace(place1, function() {
|
||||
// BrowserDB.db.updatePlace(place2, function() {
|
||||
// BrowserDB.db.updatePlace(place3, function() {
|
||||
// BrowserDB.db.getPlacesByFrecency(2, null, function(topSites) {
|
||||
// done(function() {
|
||||
// assert.equal(2, topSites.length);
|
||||
// assert.equal(topSites[0].uri, 'http://mozilla.org/test1');
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
test('saveIcon', function(done) {
|
||||
// Let's just use content-type text, a blob is a blob.
|
||||
var blob = new Blob(['hello', ' world'], {type: 'text/plain'});
|
||||
var iconEntry = {
|
||||
uri: 'http://mozilla.org/favicon.ico',
|
||||
data: blob,
|
||||
expiration: new Date().valueOf()
|
||||
};
|
||||
BrowserDB.db.saveIcon(iconEntry, function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
// XXX: Error: TypeError: callback is not a function
|
||||
// Fix this.
|
||||
// test('getIcon', function(done) {
|
||||
// // Let's just use content-type text, a blob is a blob.
|
||||
// var blob = new Blob(['hello', ' world'], {type: 'text/plain'});
|
||||
// var iconEntry = {
|
||||
// uri: 'http://mozilla.org/favicon.ico',
|
||||
// data: blob,
|
||||
// expiration: new Date().valueOf()
|
||||
// };
|
||||
// BrowserDB.db.saveIcon(iconEntry, function() {
|
||||
// BrowserDB.db.getIcon('http://mozilla.org/favicon.ico', function() {
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
test('saveIcon', function(done) {
|
||||
// Let's just use text, a blob is a blob.
|
||||
var blob = new Blob(['hello', ' world'], {type: 'text/plain'});
|
||||
var iconEntry = {
|
||||
uri: 'http://mozilla.org/favicon.ico',
|
||||
data: blob,
|
||||
expiration: new Date().valueOf()
|
||||
};
|
||||
BrowserDB.db.saveIcon(iconEntry, function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
// XXX: Test failed on Treeherder with reason unknown.
|
||||
// test('getAllBookmarks', function(done) {
|
||||
// BrowserDB.addBookmark('http://mozilla.org/test1', 'Mozilla', function() {
|
||||
// BrowserDB.addBookmark('http://mozilla.org/test2', 'Mozilla',
|
||||
// function() {
|
||||
// BrowserDB.db.getAllBookmarks(function(bookmarks) {
|
||||
// done(function() {
|
||||
// assert.equal(bookmarks.length, 2);
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// XXX: Test failed on Treeherder with reason unknown.
|
||||
// test('getAllBookmarkUris', function(done) {
|
||||
// BrowserDB.addBookmark('http://mozilla.org/test1', 'Mozilla', function() {
|
||||
// BrowserDB.addBookmark('http://mozilla.org/test2', 'Mozilla',
|
||||
// function() {
|
||||
// BrowserDB.db.getAllBookmarkUris(function(uris) {
|
||||
// done(function() {
|
||||
// assert.equal(uris.length, 2);
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// XXX: Error: expected null to equal 0
|
||||
// Fix this.
|
||||
// test('resetPlaceFrecency', function(done) {
|
||||
// BrowserDB.addPlace('http://mozilla.org/test8', function() {
|
||||
// BrowserDB.updateFrecency('http://mozilla.org/test8', function() {
|
||||
// BrowserDB.db.resetPlaceFrecency('http://mozilla.org/test8',
|
||||
// function() {
|
||||
// BrowserDB.db.getPlace('http://mozilla.org/test8', function(place) {
|
||||
// done(function() {
|
||||
// assert.equal(null, place.frecency);
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
test('saveSearchEngine', function(done) {
|
||||
var search_engine = {
|
||||
uri: 'http://google.com/',
|
||||
title: 'Google',
|
||||
iconUri: DATA_URI
|
||||
};
|
||||
BrowserDB.db.saveSearchEngine(search_engine, function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('getSearchEngine', function(done) {
|
||||
var search_engine = {
|
||||
uri: 'http://google.com/',
|
||||
title: 'Google',
|
||||
iconUri: DATA_URI
|
||||
};
|
||||
BrowserDB.db.saveSearchEngine(search_engine, function() {
|
||||
BrowserDB.db.getSearchEngine('http://google.com/',
|
||||
function(search_engine) {
|
||||
done(function() {
|
||||
assert.equal(search_engine.title, 'Google');
|
||||
assert.equal(search_engine.iconUri, DATA_URI);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('getAllSearchEngines', function(done) {
|
||||
var search_engine1 = {
|
||||
uri: 'http://google.com/search',
|
||||
title: 'Google',
|
||||
iconUri: DATA_URI
|
||||
};
|
||||
var search_engine2 = {
|
||||
uri: 'http://yahoo.com/search',
|
||||
title: 'Yahoo',
|
||||
iconUri: DATA_URI
|
||||
};
|
||||
BrowserDB.db.saveSearchEngine(search_engine1, function() {
|
||||
BrowserDB.db.saveSearchEngine(search_engine2, function() {
|
||||
BrowserDB.db.getAllSearchEngines(function(engines) {
|
||||
done(function() {
|
||||
assert.equal(engines.length, 2);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('BrowserDB', function() {
|
||||
setup(function(done) {
|
||||
clearBrowserStores(done);
|
||||
});
|
||||
|
||||
teardown(function(done) {
|
||||
clearBrowserStores(done);
|
||||
});
|
||||
|
||||
// XXX: Test failed on Treeherder with reason unknown.
|
||||
// test('addPlace', function(done) {
|
||||
// BrowserDB.addPlace('http://mozilla.org/test4', function() {
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
|
||||
// XXX: Error: timeout of 10000ms exceeded
|
||||
// Fix this.
|
||||
// test('setPageTitle', function(done) {
|
||||
// BrowserDB.addPlace('http://mozilla.org/test5', function() {
|
||||
// BrowserDB.setPageTitle('http://mozilla.org/test5',
|
||||
// 'Mozilla5', function() {
|
||||
// BrowserDB.db.getPlace('http://mozilla.org/test5',
|
||||
// function(place) {
|
||||
// done(function() {
|
||||
// assert.equal(place.title, 'Mozilla5');
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// XXX: Error: TypeError: callback is not a function
|
||||
// Fix this.
|
||||
// test('setAndLoadIconForPage', function(done) {
|
||||
// BrowserDB.setAndLoadIconForPage('http://mozilla.org/test6',
|
||||
// DATA_URI, function() {
|
||||
// BrowserDB.db.getIcon(DATA_URI, function(iconEntry) {
|
||||
// done(function() {
|
||||
// assert.equal(true, iconEntry.expiration > new Date().valueOf());
|
||||
// var twoDaysAway = new Date().valueOf() + 172800000;
|
||||
// assert.equal(true, iconEntry.expiration < twoDaysAway);
|
||||
// assert.equal(2550, iconEntry.data.size);
|
||||
// assert.equal('image/x-icon', iconEntry.data.type);
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// XXX: Error: timeout of 10000ms exceeded
|
||||
// Fix this.
|
||||
// test('addVisit', function(done) {
|
||||
// BrowserDB.addVisit('http://mozilla.org/test8', function() {
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
|
||||
// XXX: Error: timeout of 10000ms exceeded
|
||||
// Fix this.
|
||||
// test('addVisit - existing place', function(done) {
|
||||
// BrowserDB.addPlace('http://mozilla.org/test9', function() {
|
||||
// BrowserDB.addVisit('http://mozilla.org/test9', function() {
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// XXX: Test failed on Treeherder with reason unknown.
|
||||
// test('addBookmark', function(done) {
|
||||
// BrowserDB.addBookmark('http://mozilla.org/test7', 'Test 7', function() {
|
||||
// BrowserDB.getBookmark('http://mozilla.org/test7', function(bookmark) {
|
||||
// done(function() {
|
||||
// assert.equal(bookmark.title, 'Test 7');
|
||||
// assert.equal(true, bookmark.timestamp > 0);
|
||||
// var now = new Date().valueOf();
|
||||
// assert.equal(true, bookmark.timestamp <= now);
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// XXX: Test failed on Treeherder with reason unknown.
|
||||
// test('updateBookmark', function(done) {
|
||||
// BrowserDB.addBookmark('http://mozilla.org/test7', 'Test 7', function() {
|
||||
// BrowserDB.updateBookmark('http://mozilla.org/test7', 'Test 8',
|
||||
// function() {
|
||||
// BrowserDB.getBookmark('http://mozilla.org/test7', function(bookmark) {
|
||||
// done(function() {
|
||||
// assert.equal(bookmark.title, 'Test 8');
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// XXX: Test failed on Treeherder with reason unknown.
|
||||
// test('updateBookmark - not found', function(done) {
|
||||
// BrowserDB.updateBookmark('http://mozilla.org/test7', 'Test 7',
|
||||
// function() {
|
||||
// BrowserDB.getBookmark('http://mozilla.org/test7', function(bookmark) {
|
||||
// done(function() {
|
||||
// assert.equal(bookmark.title, 'Test 7');
|
||||
// assert.equal(true, bookmark.timestamp > 0);
|
||||
// var now = new Date().valueOf();
|
||||
// assert.equal(true, bookmark.timestamp <= now);
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// XXX: Test failed on Treeherder with reason unknown.
|
||||
// test('updateFrecency', function(done) {
|
||||
// BrowserDB.addPlace('http://mozilla.org/test8', function() {
|
||||
// BrowserDB.updateFrecency('http://mozilla.org/test8', function() {
|
||||
// BrowserDB.updateFrecency('http://mozilla.org/test8', function() {
|
||||
// BrowserDB.db.getPlace('http://mozilla.org/test8', function(place) {
|
||||
// done(function() {
|
||||
// assert.equal(2, place.frecency);
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
test('addSearchEngine', function(done) {
|
||||
var data = {
|
||||
uri: 'http://google.com/',
|
||||
title: 'Google',
|
||||
iconUri: DATA_URI
|
||||
};
|
||||
BrowserDB.addSearchEngine(data, function() {
|
||||
BrowserDB.getSearchEngine('http://google.com/',
|
||||
function(search_engine) {
|
||||
done(function() {
|
||||
assert.equal(search_engine.title, 'Google');
|
||||
assert.equal(search_engine.uri, 'http://google.com/');
|
||||
assert.equal(search_engine.iconUri, DATA_URI);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('updateSetting', function(done) {
|
||||
BrowserDB.updateSetting('test_value', 'test_key', function() {
|
||||
BrowserDB.getSetting('test_key', function(setting) {
|
||||
done(function() {
|
||||
assert.equal(setting, 'test_value');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
127
gaia/tv_apps/browser/test/unit/browser_dialog_test.js
Executable file
|
|
@ -0,0 +1,127 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/* global BrowserDialog */
|
||||
/* global expect */
|
||||
/* global MocksHelper */
|
||||
/* global MockL10n */
|
||||
|
||||
'use strict';
|
||||
|
||||
require('/shared/test/unit/load_body_html_helper.js');
|
||||
require('/shared/test/unit/mocks/mock_l10n.js');
|
||||
requireApp('browser/js/browser_dialog.js');
|
||||
requireApp('browser/test/unit/mocks/mock_browser.js');
|
||||
requireApp('browser/test/unit/mocks/mock_awesomescreen.js');
|
||||
|
||||
var mocksForBrowserDialog = new MocksHelper([
|
||||
'Awesomescreen',
|
||||
'Browser'
|
||||
]).init();
|
||||
|
||||
suite('Browser Dialog >', function() {
|
||||
var subject;
|
||||
var realL10n;
|
||||
|
||||
mocksForBrowserDialog.attachTestHelpers();
|
||||
|
||||
suiteSetup(function() {
|
||||
realL10n = navigator.mozL10n;
|
||||
navigator.mozL10n = MockL10n;
|
||||
|
||||
loadBodyHTML('fixtures/browser_dialog.html');
|
||||
|
||||
subject = BrowserDialog;
|
||||
subject.init();
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
navigator.mozL10n = realL10n;
|
||||
});
|
||||
|
||||
suite('Initial state', function() {
|
||||
test('should init DOM elements', function() {
|
||||
[
|
||||
'browserDialogBase',
|
||||
'browserDialog',
|
||||
'browserDialogTitle',
|
||||
'browserDialogMsg',
|
||||
'browserDialogInput',
|
||||
'browserDialogInputArea',
|
||||
'browserDialogInputClear',
|
||||
'browserDialogButton',
|
||||
'browserDialogButton1',
|
||||
'browserDialogButton2'].forEach(element => {
|
||||
expect(subject[element]).to.be.an('object');
|
||||
});
|
||||
});
|
||||
|
||||
test('should not have pending deferred actions', function() {
|
||||
expect(subject.deferredActions.size).to.equals(0);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Sign out dialog', function() {
|
||||
var promise;
|
||||
|
||||
setup(function() {
|
||||
this.sinon.stub(subject, 'cancelDialog');
|
||||
});
|
||||
|
||||
test('signout_confirm dialog should add a deferred action',
|
||||
function(done) {
|
||||
promise = subject.createDialog('signout_confirm');
|
||||
expect(subject.browserDialogTitle.getAttribute('data-l10n-id'))
|
||||
.to.equals('fxsync-confirm-sign-out-title');
|
||||
expect(subject.browserDialogMsg.getAttribute('data-l10n-id'))
|
||||
.to.equals('fxsync-confirm-sign-out-message');
|
||||
expect(subject.browserDialogButton1.getAttribute('data-l10n-id'))
|
||||
.to.equals('LT_CANCEL');
|
||||
expect(subject.browserDialogButton1.dataset.type)
|
||||
.to.equals('signout_confirm');
|
||||
expect(subject.browserDialogButton1.classList.contains('visible'))
|
||||
.to.equals(true);
|
||||
expect(subject.browserDialogButton2.getAttribute('data-l10n-id'))
|
||||
.to.equals('fxsync-sign-out');
|
||||
expect(subject.browserDialogButton2.dataset.type)
|
||||
.to.equals('signout_confirm');
|
||||
expect(subject.browserDialogButton2.classList.contains('visible'))
|
||||
.to.equals(true);
|
||||
expect(subject.deferredActions.size).to.equals(1);
|
||||
done();
|
||||
});
|
||||
|
||||
test('click on signout_confirm button 2 should resolve deferred action',
|
||||
function(done) {
|
||||
promise.then(() => {
|
||||
expect(subject.deferredActions.size).to.equals(0);
|
||||
done();
|
||||
});
|
||||
subject.dialogButton2({
|
||||
preventDefault() {},
|
||||
currentTarget: {
|
||||
addEventListener() {},
|
||||
removeEventListener() {}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('click on signout_confirm button 1 should reject deferred action',
|
||||
function(done) {
|
||||
subject.createDialog('signout_confirm').catch(() => {
|
||||
expect(subject.deferredActions.size).to.equals(0);
|
||||
done();
|
||||
});
|
||||
subject.dialogButton1({
|
||||
preventDefault() {},
|
||||
currentTarget: {
|
||||
addEventListener() {},
|
||||
removeEventListener() {}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
20
gaia/tv_apps/browser/test/unit/fixtures/browser_dialog.html
Executable file
|
|
@ -0,0 +1,20 @@
|
|||
<div id="browser-dialog-base">
|
||||
<div id="browser-dialog">
|
||||
<div id="browser-dialog-title">
|
||||
<p id="browser-dialog-title-text"></p>
|
||||
</div>
|
||||
<div id="browser-dialog-msg">
|
||||
<p id="browser-dialog-msg-text"></p>
|
||||
</div>
|
||||
<form id="browser-dialog-input">
|
||||
<input id="browser-dialog-input-area">
|
||||
<div class="input-line"></div>
|
||||
<div id="browser-dialog-input-clear"></div>
|
||||
</form>
|
||||
<div id="browser-dialog-margin"></div>
|
||||
<div id="browser-dialog-button">
|
||||
<button class="browser-dialog-button" id="browser-dialog-button2"></button>
|
||||
<button class="browser-dialog-button" id="browser-dialog-button1"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
16
gaia/tv_apps/browser/test/unit/mocks/mock_awesomescreen.js
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
'use strict';
|
||||
|
||||
(function(exports) {
|
||||
|
||||
var MockAwesomescreen = {
|
||||
focusImgFunc() {}
|
||||
};
|
||||
|
||||
exports.MockAwesomescreen = MockAwesomescreen;
|
||||
}(window));
|
||||
21
gaia/tv_apps/browser/test/unit/mocks/mock_browser.js
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
'use strict';
|
||||
|
||||
(function(exports) {
|
||||
|
||||
var MockBrowser = {
|
||||
sideBlock: {
|
||||
dataset: {
|
||||
sidebar: 'false'
|
||||
}
|
||||
},
|
||||
switchCursorMode() {}
|
||||
};
|
||||
|
||||
exports.MockBrowser = MockBrowser;
|
||||
}(window));
|
||||
16
gaia/tv_apps/browser/test/unit/mocks/mock_settings.js
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
'use strict';
|
||||
|
||||
(function(exports) {
|
||||
|
||||
var MockSettings = {
|
||||
show() {}
|
||||
};
|
||||
|
||||
exports.MockSettings = MockSettings;
|
||||
}(window));
|
||||
5
gaia/tv_apps/browser/test/unit/setup.js
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
'use strict';
|
||||
|
||||
/* global require */
|
||||
|
||||
require('/shared/test/unit/mocks/mocks_helper.js');
|
||||
482
gaia/tv_apps/browser/test/unit/sync/db_test.js
Executable file
|
|
@ -0,0 +1,482 @@
|
|||
'use strict';
|
||||
/* global SyncBrowserDB */
|
||||
/* exported Browser */
|
||||
/* jshint latedef:false */
|
||||
|
||||
requireApp('browser/shared/test/unit/mocks/' +
|
||||
'mock_navigator_moz_set_message_handler.js');
|
||||
|
||||
/* jshint maxlen:false */
|
||||
const DATA_URI =
|
||||
'data:image/x-icon;base64,AAABAAIAEBAAAAEACABoBQAAJgAAABAQAAABACAAaAQAAI4FAAAoAAAAEAAAACAAAAABAAgAAAAAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAICNgB6Pg4AajoaAHo6FgBuRioAAhJqADJCdgBmVkIAbm5eAIJCEgCGRhYAikoSAIpKFgCGShoAllYaAJJWHgCeWhoAnl4eAJJaKgCSXi4AnmYmAJZiLgCmZiIApmomALJ2LgDKjjoA1po+ANqaOgC+ikoA0qJWANquVgDeslIA5q5OAO66UgDmvl4A6sp2AOrKfgAGJooAAiaeAAIymgACHqIAAi6iAAYupgACOqYADjqmAAIyqgAGMqoABjauAAIutgACPrIACj62AAJCqgAGSq4AGlKmAAJCsgACRrIAAkq2AApOtgACQroABkK+AApKvgAOUrIAAla6AAZSvgAKWr4AFlayABZetgAiTqoARnKCAEJqpgAGRsIACkrCAAZKygAKSs4AElbOABZaygAKUtIAClbWAApa0gAOXtYADl7aABZe2gAGZs4ACmbOAA5i1gAObtYADmraAA5q3gASYtoAGm7eAAZy1gAKctoADnLiABZ24gAacuIAEnriABJ65gAaeuIAEnrqABZ+6gAqcuIAcpKGACaGwgAGiuoAFobmABqC5gASguoAEobuABaK6gASjvIAIorqACKS7gA2nuYAHqLmABqi6gAWpvoAGq76ADKq4gA6uvIARqLSAEKu4gBOrvIAdqbuADLC7gAuxv4APtb+AGbCzgBWxuYAUsruAFrW9gDmyoYA7tKKAPbengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAJiYmJiYmAAAAAAAAAAAmJig3Nzc3NCYmAAAAAAAsMjJHTU1PT09ANSgAAAAyLDxXYWFhYV1XXVxAOgAAMjxha15aLTY+VGtpUzoAPDxVa2RZSDAnBAdndGg6OTw9a2tJSktRTCcLA3J1Wzk8VmthMTACDERGDgxFfXM5PGluMyknJwsRERAQCH58OTxtcGFxcXoqHBoZFwWBdzk8aXBrX2V7JyIhGxgJgHZBPGJwb2JkUlIGIyAVZoJDAABSa3BqaycnASQfFn95QwAAUmtSUmsqhIQlHhR4QgAAAFJSFBRSMIWFgx0UFAAAAABSAAAAFBQUFBQUAAAAAAD4HwAA4AcAAMADAACAAQAAgAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAACAAQAAgAMAAIAHAAC4HwAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFgAAAC0AAABSAQMlhQIGRLMDCVTHAwlVyAIGQbIBAyOKAAAAVQAAAC0AAAAWAAAAAAAAAAAAAAAAAAAAAAAAAEcBAyOKAR186AIym/kBQLD/AEay/wBGs/8CRbL/BESr+wUniPACBCaaAAAASgAAAAAAAAAAAAAAAAAAAAAAJV1eATKS6gM/s/8HRcL/ClPT/wtV1P8MWtP/DV7V/whb0v8HUr7/B0ms9wEkVnIAAAAAAAAAAAAAAAAAQ6o3ATqk6QdCvP8Pa9r/EXrn/xF45/8TeuL/EXvm/w9z4f8Oa93/DXDi/wty2P8DV7v3A0OPXQAAAAAAR7IKAT2yzwhBvP8QeOT/E4Dq/xZ34/8bb9z/DDin/xlQp/8OUbH/CWfP/xCH7/8Uh+b/B2TN/xBZuPElbMgYAUC0WgI3sPYNYdT/E4ft/xR96P8TYtn/CErD/wU2r/8CJp3/ejkV/zFBdv8nhsP/F6X6/weJ6v8IT7f/F1K4ggFAuK8JSL//E4ft/xOH7f8HSsr/CEvN/xBVzv8MXdn/FVvL/wImnf+GRxX/azka/x6i5/8Yrvj/BnLW/wBKtscBR7byD2zX/xOH7f8ReOH/ASy2/wIzqv96PA//ikoT/yNPqv9DaqX/h0sY/4pLFf9HcoD/Lcb//xmh6f8CTrb0AEez/hSH6P8SjvL/CDy1/wMfof8CJp3/Aiad/4FCEf+cWxr/n18e/5JXH/+VVBn/ZVZB/z/X//8wwO//AUiy/gU+r/cUiej/I5Dv/xR65f83nOX/N5zl/02s8v8CLaL/2ps7/8qPOv+wdS7/p2Yh/29GKv9Rye//Obvx/wVOtfoHM6jpF4fo/yOQ7/8Tgev/GXHi/yly4v93p+7/Aiad/+y4UP/kr0//1pg9/6RoJP9tb13/VMfm/zGq4/8IWLzSBiKczxl64f0jkO//IYrr/xp54/8Seuj/FF/a/xRf2v8CEmn/571e/9+yUP+fZCb/c5OH/1jW9f8ed8j/EWXAkQUUkZwXbtz/EoHr/yOQ7/8Yg+b/EoHr/wImnf8CJp3/AgM3/+vKdf/ar1X/l2Es/2TAz/9BruH/FVy38BZyxxgCB4dcFF/a/xKB6/8UX9r/FF/a/xKB6/8ELaX/8NSJ/+/Tiv/qy3//0qJU/5JdLP9FoNP/Flex9xNkwVYAAAAAAAAAABRf2v8UX9r/X0FThXZQRt0UX9r/BzOr//Tfnv/0357/5suG/7yJSf+hYyX/UkJZuQhPtzsAAAAAAAAAAAAAAAAUX9qsFF/aMwAAAACZZjM0Z0ZPmVtSaNeZZjPtmWYz7ZVhL82QWyuukForXQAAAAAAAAAAAAAAAAAAAADAAwAAwAMAAMADAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAIADAACQDwAA';
|
||||
/* jshint maxlen:80 */
|
||||
const DEFAULT_FAVICON = 'style/images/default-fav.svg';
|
||||
|
||||
requireApp('browser/js/sync/db.js');
|
||||
|
||||
var clearBrowserStores = function(done) {
|
||||
SyncBrowserDB.db.open(function() {
|
||||
Promise.all([
|
||||
new Promise(SyncBrowserDB.db.clearPlaces),
|
||||
new Promise(SyncBrowserDB.db.clearVisits),
|
||||
new Promise(SyncBrowserDB.db.clearIcons),
|
||||
new Promise(SyncBrowserDB.db.clearBookmarks)
|
||||
]).then(() => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
var bookmarkGenerator = (amount, done, parentid) => {
|
||||
var list = [];
|
||||
function item(i) {
|
||||
return {
|
||||
id: 'FXSYNCID_00' + i,
|
||||
bmkUri: 'http://mozilla.org/test' + i,
|
||||
title: 'Mozilla',
|
||||
parentid: parentid ? parentid : 'FXS_P_ID_00' + i,
|
||||
timestamp: Date.now()
|
||||
};
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
|
||||
function wrapper() {
|
||||
if (i < amount) {
|
||||
var t = item(i);
|
||||
list.push(t);
|
||||
SyncBrowserDB.db.saveBookmark(t, wrapper);
|
||||
i++;
|
||||
} else {
|
||||
done(list);
|
||||
}
|
||||
}
|
||||
|
||||
wrapper();
|
||||
};
|
||||
|
||||
var historyGenerator = (amount, done, timeOffset) => {
|
||||
var list = [];
|
||||
function item(i) {
|
||||
return {
|
||||
fxsyncId: 'FXSYNCID_00' + i,
|
||||
uri: 'http://mozilla.org/test' + i,
|
||||
title: 'Mozilla',
|
||||
timestamp: timeOffset + i * 10
|
||||
};
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
|
||||
function wrapper() {
|
||||
if (i < amount) {
|
||||
var t = item(i);
|
||||
list.push(t);
|
||||
SyncBrowserDB.db.createRawHistory(t, wrapper);
|
||||
i++;
|
||||
} else {
|
||||
done(list);
|
||||
}
|
||||
}
|
||||
|
||||
wrapper();
|
||||
};
|
||||
|
||||
window.Awesomescreen = {
|
||||
DEFAULT_FAVICON: DEFAULT_FAVICON
|
||||
};
|
||||
|
||||
suite('SyncBrowserDB', function() {
|
||||
suite('SyncBrowserDB.db', function() {
|
||||
setup(function(done) {
|
||||
clearBrowserStores(done);
|
||||
});
|
||||
|
||||
teardown(function(done) {
|
||||
clearBrowserStores(done);
|
||||
});
|
||||
|
||||
test('createPlace & getPlace', function(done) {
|
||||
const URL = 'http://mozilla.org/test1';
|
||||
SyncBrowserDB.db.createPlace(URL, () => {
|
||||
SyncBrowserDB.db.getPlace(URL, place => {
|
||||
assert.equal(place.title, URL);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('createRawHistory & getHistory', function(done) {
|
||||
var example = {
|
||||
fxsyncId: 'FXSYNCID_001',
|
||||
uri: 'http://mozilla.org/test1',
|
||||
title: 'Mozilla',
|
||||
timestamp: Date.now()
|
||||
};
|
||||
SyncBrowserDB.db.createRawHistory(example, () => {
|
||||
SyncBrowserDB.db.getHistory(10, places => {
|
||||
assert.equal(places.length, 1);
|
||||
example.iconUri = DEFAULT_FAVICON;
|
||||
assert.deepEqual(places[0], example);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('getPlace - not found', function(done) {
|
||||
const NONEXIST_URL = 'http://mozilla.org/doesnotexist';
|
||||
SyncBrowserDB.db.getPlace(NONEXIST_URL, place => {
|
||||
assert.equal(place, undefined);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('saveBookmark && getBookmark', function(done) {
|
||||
var example = {
|
||||
id: 'FXSYNCID_001',
|
||||
bmkUri: 'http://mozilla.org/test1',
|
||||
title: 'Mozilla',
|
||||
parentid: 'FXS_P_ID_001',
|
||||
timestamp: Date.now()
|
||||
};
|
||||
SyncBrowserDB.db.saveBookmark(example, () => {
|
||||
SyncBrowserDB.db.getBookmark(example.id, bookmark => {
|
||||
assert.deepEqual(bookmark, example);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('saveBookmark && getBookmarkByUri', function(done) {
|
||||
var example = {
|
||||
id: 'FXSYNCID_002',
|
||||
bmkUri: 'http://mozilla.org/test2',
|
||||
title: 'Mozilla',
|
||||
parentid: 'FXS_P_ID_002',
|
||||
timestamp: Date.now()
|
||||
};
|
||||
SyncBrowserDB.db.saveBookmark(example, () => {
|
||||
SyncBrowserDB.db.getBookmarkByUri(example.bmkUri, bookmark => {
|
||||
assert.deepEqual(bookmark, example);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('getBookmarkByParentId', function(done) {
|
||||
var example = {
|
||||
id: 'FXSYNCID_001',
|
||||
bmkUri: 'http://mozilla.org/test1',
|
||||
title: 'Mozilla',
|
||||
parentid: 'FXS_P_ID_001',
|
||||
timestamp: Date.now()
|
||||
};
|
||||
SyncBrowserDB.db.saveBookmark(example, () => {
|
||||
SyncBrowserDB.db.getBookmarkByParentId(example.parentid, bookmark => {
|
||||
assert.equal(bookmark.length, 1);
|
||||
assert.deepEqual(bookmark[0], example);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('getBookmarkByUri - not found', function(done) {
|
||||
const NONEXIST_URL = 'http://mozilla.org/doesnotexist';
|
||||
SyncBrowserDB.db.getBookmarkByUri(NONEXIST_URL, bookmark => {
|
||||
assert.equal(bookmark, undefined);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('getAllBookmarks', function(done) {
|
||||
const RECORD_SIZE = 10;
|
||||
bookmarkGenerator(RECORD_SIZE, records => {
|
||||
SyncBrowserDB.db.getAllBookmarks(bookmarks => {
|
||||
assert.equal(bookmarks.length, RECORD_SIZE);
|
||||
// Sort by timestamp, so we did a reversing comparison here.
|
||||
for (var i = 0; i < RECORD_SIZE; i++) {
|
||||
assert.deepEqual(bookmarks[i], records[RECORD_SIZE -1 -i]);
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('getAllBookmarkUris', function(done) {
|
||||
const RECORD_SIZE = 10;
|
||||
bookmarkGenerator(RECORD_SIZE, records => {
|
||||
SyncBrowserDB.db.getAllBookmarkUris(bookmarkUris => {
|
||||
assert.equal(bookmarkUris.length, RECORD_SIZE);
|
||||
// Sort by timestamp, so we did a reversing comparison here.
|
||||
for (var i = 0; i < RECORD_SIZE; i++) {
|
||||
assert.deepEqual(bookmarkUris[i],
|
||||
records[RECORD_SIZE -1 -i].bmkUri);
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('deleteBookmark', function(done) {
|
||||
var example = {
|
||||
id: 'FXSYNCID_003',
|
||||
bmkUri: 'http://mozilla.org/test3',
|
||||
title: 'Mozilla',
|
||||
parentid: 'FXS_P_ID_003',
|
||||
timestamp: Date.now()
|
||||
};
|
||||
SyncBrowserDB.db.saveBookmark(example, () => {
|
||||
SyncBrowserDB.db.deleteBookmark('FXSYNCID_003', () => {
|
||||
SyncBrowserDB.db.getBookmark('FXSYNCID_003', bookmark => {
|
||||
assert.equal(bookmark, undefined);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('updatePlaceScreenshot', function(done) {
|
||||
var uri = 'http://mozilla.org/test4';
|
||||
SyncBrowserDB.db.updatePlaceScreenshot(uri, DATA_URI, () => {
|
||||
SyncBrowserDB.db.getPlace(uri, place => {
|
||||
assert.equal(place.screenshot, DATA_URI);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('saveIcon', function(done) {
|
||||
var blob = new Blob(['hello', ' world'], {type: 'text/plain'});
|
||||
var iconEntry = {
|
||||
uri: 'http://mozilla.org/favicon.ico',
|
||||
data: blob,
|
||||
expiration: Date.now()
|
||||
};
|
||||
SyncBrowserDB.db.saveIcon(iconEntry, () => {
|
||||
SyncBrowserDB.db.getIcon(iconEntry.uri, null, (e) => {
|
||||
assert.deepEqual(e, iconEntry);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('SyncBrowserDB', function() {
|
||||
setup(function(done) {
|
||||
clearBrowserStores(done);
|
||||
});
|
||||
|
||||
teardown(function(done) {
|
||||
clearBrowserStores(done);
|
||||
});
|
||||
|
||||
test('updateRawBookmark & getBookmark by id', function(done) {
|
||||
var example = {
|
||||
id: 'FXSYNCID_003',
|
||||
bmkUri: 'http://mozilla.org/test3',
|
||||
title: 'Mozilla',
|
||||
parentid: 'FXS_P_ID_003',
|
||||
timestamp: Date.now()
|
||||
};
|
||||
SyncBrowserDB.updateRawBookmark(example, () => {
|
||||
SyncBrowserDB.getBookmark(example.id, bookmark => {
|
||||
assert.deepEqual(example, bookmark);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('updateRawBookmark & getBookmark by {id}', function(done) {
|
||||
var example = {
|
||||
id: 'FXSYNCID_003',
|
||||
bmkUri: 'http://mozilla.org/test3',
|
||||
title: 'Mozilla',
|
||||
parentid: 'FXS_P_ID_003',
|
||||
timestamp: Date.now()
|
||||
};
|
||||
SyncBrowserDB.updateRawBookmark(example, () => {
|
||||
SyncBrowserDB.getBookmark({id: example.id}, bookmark => {
|
||||
assert.deepEqual(example, bookmark);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('updateRawBookmark & getBookmark by {bmkUri}', function(done) {
|
||||
var example = {
|
||||
id: 'FXSYNCID_003',
|
||||
bmkUri: 'http://mozilla.org/test3',
|
||||
title: 'Mozilla',
|
||||
parentid: 'FXS_P_ID_003',
|
||||
timestamp: Date.now()
|
||||
};
|
||||
SyncBrowserDB.updateRawBookmark(example, () => {
|
||||
SyncBrowserDB.getBookmark({bmkUri: example.bmkUri}, bookmark => {
|
||||
assert.deepEqual(example, bookmark);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('updateRawBookmark & getBookmark by {parentid}', function(done) {
|
||||
var example = {
|
||||
id: 'FXSYNCID_003',
|
||||
bmkUri: 'http://mozilla.org/test3',
|
||||
title: 'Mozilla',
|
||||
parentid: 'FXS_P_ID_003',
|
||||
timestamp: Date.now()
|
||||
};
|
||||
SyncBrowserDB.updateRawBookmark(example, () => {
|
||||
SyncBrowserDB.getBookmark({parentid: example.parentid}, bookmarks => {
|
||||
assert.equal(bookmarks.length, 1);
|
||||
assert.deepEqual(example, bookmarks[0]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('getBookmark by {parentid}, sorted by children array', function(done) {
|
||||
var example = {
|
||||
id: 'FXS_P_ID_001',
|
||||
type: 'folder',
|
||||
title: 'Mozilla',
|
||||
children: ['FXSYNCID_003', 'FXSYNCID_001',
|
||||
'FXSYNCID_000', 'FXSYNCID_002'],
|
||||
parentid: 'FXS_P_ID_000',
|
||||
timestamp: Date.now()
|
||||
};
|
||||
SyncBrowserDB.updateRawBookmark(example, () => {
|
||||
bookmarkGenerator(4, rawRecords => {
|
||||
SyncBrowserDB.getBookmark({parentid: example.id}, bookmarks => {
|
||||
assert.deepEqual(bookmarks[0], rawRecords[3]);
|
||||
assert.deepEqual(bookmarks[1], rawRecords[1]);
|
||||
assert.deepEqual(bookmarks[2], rawRecords[0]);
|
||||
assert.deepEqual(bookmarks[3], rawRecords[2]);
|
||||
done();
|
||||
});
|
||||
}, 'FXS_P_ID_001');
|
||||
});
|
||||
});
|
||||
|
||||
test('removeBookmark', function(done) {
|
||||
var example = {
|
||||
id: 'FXSYNCID_003',
|
||||
bmkUri: 'http://mozilla.org/test3',
|
||||
title: 'Mozilla',
|
||||
parentid: 'FXS_P_ID_003',
|
||||
timestamp: Date.now()
|
||||
};
|
||||
SyncBrowserDB.updateRawBookmark(example, () => {
|
||||
SyncBrowserDB.removeBookmark(example.id, () => {
|
||||
SyncBrowserDB.getBookmark(example.id, bookmark => {
|
||||
assert.equal(bookmark, undefined);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('clearBookmarks', function(done) {
|
||||
bookmarkGenerator(10, (rawRecords) => {
|
||||
SyncBrowserDB.clearBookmarks().then(() => {
|
||||
SyncBrowserDB.db.getAllBookmarks(bookmarks => {
|
||||
assert.isArray(bookmarks);
|
||||
assert.equal(bookmarks.length, 0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('updateRawHistory & removeHistory', function(done) {
|
||||
var example = {
|
||||
fxsyncId: 'FXSYNCID_003',
|
||||
uri: 'http://mozilla.org/test3',
|
||||
title: 'Mozilla',
|
||||
timestamp: Date.now()
|
||||
};
|
||||
SyncBrowserDB.updateRawHistory(example, () => {
|
||||
SyncBrowserDB.removeHistory(example.uri, bookmark => {
|
||||
assert.equal(bookmark, undefined);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('clearHistoryDeep', function(done) {
|
||||
historyGenerator(10, (rawRecords) => {
|
||||
SyncBrowserDB.clearHistoryDeep().then(() => {
|
||||
SyncBrowserDB.db.getHistory(10000, history => {
|
||||
assert.isArray(history);
|
||||
assert.equal(history.length, 0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
}, 10000);
|
||||
});
|
||||
|
||||
test('getHistoryByTime', function(done) {
|
||||
historyGenerator(10, (rawRecords) => {
|
||||
SyncBrowserDB.getHistoryByTime(10075, 10085, false, false, history => {
|
||||
assert.equal(history.length, 1);
|
||||
rawRecords[8].iconUri = DEFAULT_FAVICON;
|
||||
assert.deepEqual(history[0], rawRecords[8]);
|
||||
done();
|
||||
});
|
||||
}, 10000);
|
||||
});
|
||||
|
||||
test('getHistoryByTime with timestamp equal=true', function(done) {
|
||||
historyGenerator(10, (rawRecords) => {
|
||||
SyncBrowserDB.getHistoryByTime(10070, 10080, true, true, history => {
|
||||
assert.equal(history.length, 2);
|
||||
rawRecords[7].iconUri = DEFAULT_FAVICON;
|
||||
rawRecords[8].iconUri = DEFAULT_FAVICON;
|
||||
assert.deepEqual(history[0], rawRecords[8]);
|
||||
assert.deepEqual(history[1], rawRecords[7]);
|
||||
done();
|
||||
});
|
||||
}, 10000);
|
||||
});
|
||||
|
||||
test('getHistoryTimestamp with equal=true / dir=prev', function(done) {
|
||||
historyGenerator(10, (rawRecords) => {
|
||||
SyncBrowserDB.getHistoryTimestamp(10070, 'prev', true, ts => {
|
||||
assert.equal(ts, 10070);
|
||||
done();
|
||||
});
|
||||
}, 10000);
|
||||
});
|
||||
|
||||
test('getHistoryTimestamp with equal=false / dir=prev', function(done) {
|
||||
historyGenerator(10, (rawRecords) => {
|
||||
SyncBrowserDB.getHistoryTimestamp(10070, 'prev', false, ts => {
|
||||
assert.equal(ts, 10060);
|
||||
done();
|
||||
});
|
||||
}, 10000);
|
||||
});
|
||||
|
||||
test('getHistoryTimestamp with equal=true / dir=next', function(done) {
|
||||
historyGenerator(10, (rawRecords) => {
|
||||
SyncBrowserDB.getHistoryTimestamp(10075, 'next', true, ts => {
|
||||
assert.equal(ts, 10080);
|
||||
done();
|
||||
});
|
||||
}, 10000);
|
||||
});
|
||||
|
||||
test('getHistoryTimestamp with equal=false / dir=next', function(done) {
|
||||
historyGenerator(10, (rawRecords) => {
|
||||
SyncBrowserDB.getHistoryTimestamp(10075, 'next', false, ts => {
|
||||
assert.equal(ts, 10080);
|
||||
done();
|
||||
});
|
||||
}, 10000);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
27
gaia/tv_apps/browser/test/unit/sync/fixtures/settings.html
Executable file
|
|
@ -0,0 +1,27 @@
|
|||
<div id="fxsync-area">
|
||||
<div id="fxsync-header">
|
||||
<p data-l10n-id="fxsync-firefox-sync">Firefox Sync</p>
|
||||
</div>
|
||||
<div id="fxsync-disabled">
|
||||
<smart-button id="fxsync-sign-in-button" type="simple-text" data-l10n-id="fxsync-create-account-or-sign-in"></smart-button>
|
||||
<p id="fxsync-sign-in-description" data-l10n-id="fxsync-sign-in-to-sync-description"></p>
|
||||
</div>
|
||||
<div id="fxsync-enabled">
|
||||
<span id="fxsync-signed-in-as" data-l10n-id="fxsync-signed-in-as"></span>
|
||||
<smart-button id="fxsync-sync-now-button" type="simple-text" data-l10n-id="fxsync-sync-now"></smart-button>
|
||||
<smart-button id="fxsync-sign-out-button" type="simple-text" data-l10n-id="fxsync-sign-out"></smart-button>
|
||||
<ul class="settings-horizontal-list">
|
||||
<li class="settings-horizontal-list-item">
|
||||
<input type="checkbox" id="fxsync-collection-bookmarks" ></input>
|
||||
<label for="fxsync-collection-bookmarks"></label>
|
||||
<span data-l10n-id="fxsync-collection-bookmarks"></span>
|
||||
</li>
|
||||
<li class="settings-horizontal-list-item">
|
||||
<input type="checkbox" id="fxsync-collection-history" ></input>
|
||||
<label for="fxsync-collection-history"></label>
|
||||
<span data-l10n-id="fxsync-collection-history"></span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
1
gaia/tv_apps/browser/test/unit/sync/fixtures/toolbar.html
Executable file
|
|
@ -0,0 +1 @@
|
|||
<li id="fxsync-block"><a id="fxsync-tab" href="#" data-l10n-id="fxsync-sign-in-to-sync"></a></li>
|
||||
217
gaia/tv_apps/browser/test/unit/sync/manager_bridge_test.js
Executable file
|
|
@ -0,0 +1,217 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/* global SyncManagerBridge */
|
||||
|
||||
'use strict';
|
||||
|
||||
requireApp('browser/js/sync/manager_bridge.js');
|
||||
|
||||
suite('SyncManagerBridge >', () => {
|
||||
var subject;
|
||||
var realMozApps;
|
||||
var port;
|
||||
var app;
|
||||
var onmessageData;
|
||||
|
||||
suiteSetup(() => {
|
||||
subject = SyncManagerBridge;
|
||||
|
||||
realMozApps = navigator.mozApps;
|
||||
port = {
|
||||
postMessage: function() {},
|
||||
set onmessage(callback) {
|
||||
setTimeout(() => {
|
||||
callback({ data: onmessageData });
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
app = {
|
||||
connect: function() {
|
||||
return Promise.resolve([port]);
|
||||
}
|
||||
};
|
||||
|
||||
var onsuccess = {
|
||||
set onsuccess(callback) {
|
||||
setTimeout(() => {
|
||||
callback({ target: { result: app } });
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
navigator.mozApps = {
|
||||
getSelf: function() {
|
||||
return onsuccess;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
suiteTeardown(() => {
|
||||
subject = null;
|
||||
navigator.mozApps = realMozApps;
|
||||
});
|
||||
|
||||
suite('Initial state', () => {
|
||||
test('Integrity', () => {
|
||||
assert.ok(subject != null);
|
||||
assert.isNull(subject._port);
|
||||
assert.equal(subject._requests.size, 0);
|
||||
});
|
||||
});
|
||||
|
||||
['enable',
|
||||
'disable',
|
||||
'sync'].forEach(method => {
|
||||
suite(method, () => {
|
||||
var getSelfSpy;
|
||||
var connectSpy;
|
||||
var postMessageSpy;
|
||||
|
||||
setup(() => {
|
||||
getSelfSpy = this.sinon.spy(navigator.mozApps, 'getSelf');
|
||||
connectSpy = this.sinon.spy(app, 'connect');
|
||||
postMessageSpy = this.sinon.spy(port, 'postMessage');
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
getSelfSpy.restore();
|
||||
connectSpy.restore();
|
||||
postMessageSpy.restore();
|
||||
});
|
||||
|
||||
suiteTeardown(() => {
|
||||
subject._port = null;
|
||||
});
|
||||
|
||||
test(method + ' - no previous connection', done => {
|
||||
subject[method]();
|
||||
setTimeout(() => {
|
||||
this.sinon.assert.calledOnce(getSelfSpy);
|
||||
this.sinon.assert.calledOnce(connectSpy);
|
||||
this.sinon.assert.calledOnce(postMessageSpy);
|
||||
assert.equal(postMessageSpy.getCall(0).args[0].name, method);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test(method + ' - previous connection', done => {
|
||||
subject[method]();
|
||||
setTimeout(() => {
|
||||
this.sinon.assert.notCalled(getSelfSpy);
|
||||
this.sinon.assert.notCalled(connectSpy);
|
||||
this.sinon.assert.calledOnce(postMessageSpy);
|
||||
assert.equal(postMessageSpy.getCall(0).args[0].name, method);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('listeners', () => {
|
||||
suiteTeardown(() => {
|
||||
subject._listeners.clear();
|
||||
});
|
||||
|
||||
test('addListener', () => {
|
||||
assert.equal(subject._listeners.size, 0);
|
||||
this.listener = () => {};
|
||||
subject.addListener(this.listener);
|
||||
assert.equal(subject._listeners.size, 1);
|
||||
assert.ok(subject._listeners.has(this.listener));
|
||||
});
|
||||
|
||||
test('removeListener', () => {
|
||||
assert.equal(subject._listeners.size, 1);
|
||||
assert.ok(subject._listeners.has(this.listener));
|
||||
subject.removeListener(this.listener);
|
||||
assert.equal(subject._listeners.size, 0);
|
||||
});
|
||||
});
|
||||
|
||||
suite('getInfo', () => {
|
||||
var postMessageSpy;
|
||||
var dateNowStub;
|
||||
var now;
|
||||
var listenerCalled;
|
||||
|
||||
setup(() => {
|
||||
postMessageSpy = this.sinon.spy(port, 'postMessage');
|
||||
dateNowStub = this.sinon.stub(Date, 'now', () => {
|
||||
return now;
|
||||
});
|
||||
subject.addListener(() => {
|
||||
listenerCalled = true;
|
||||
});
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
postMessageSpy.restore();
|
||||
dateNowStub.restore();
|
||||
});
|
||||
|
||||
test('getInfo', done => {
|
||||
now = 'now';
|
||||
var expectedMessage = {
|
||||
data: {
|
||||
id: now,
|
||||
result: 'whatever'
|
||||
}
|
||||
};
|
||||
subject.getInfo().then(message => {
|
||||
assert.equal(message.id, expectedMessage.data.id);
|
||||
assert.equal(message.result, expectedMessage.data.result);
|
||||
assert.ok(!listenerCalled);
|
||||
done();
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.sinon.assert.calledOnce(postMessageSpy);
|
||||
assert.equal(postMessageSpy.getCall(0).args[0].name, 'getInfo');
|
||||
assert.equal(postMessageSpy.getCall(0).args[0].id, now);
|
||||
assert.ok(subject._requests.has(now));
|
||||
subject.onmessage(expectedMessage);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('onsyncchange', () => {
|
||||
var postMessageSpy;
|
||||
var observedMessage;
|
||||
var now;
|
||||
|
||||
setup(() => {
|
||||
postMessageSpy = this.sinon.spy(port, 'postMessage');
|
||||
var listener = (message) => {
|
||||
console.log('mes', JSON.stringify(message));
|
||||
observedMessage = message;
|
||||
};
|
||||
subject.addListener(listener);
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
postMessageSpy.restore();
|
||||
});
|
||||
|
||||
test('getInfo', done => {
|
||||
var expectedMessage = {
|
||||
data: {
|
||||
name: 'onsyncchange',
|
||||
result: 'whatever'
|
||||
}
|
||||
};
|
||||
|
||||
subject.onmessage(expectedMessage);
|
||||
setTimeout(() => {
|
||||
this.sinon.assert.notCalled(postMessageSpy);
|
||||
assert.ok(!(subject._requests.has(now)));
|
||||
assert.deepEqual(observedMessage, expectedMessage.data);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
36
gaia/tv_apps/browser/test/unit/sync/mocks/mock_manager_bridge.js
Executable file
|
|
@ -0,0 +1,36 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
'use strict';
|
||||
|
||||
(function(exports) {
|
||||
|
||||
var MockSyncManagerBridge = {
|
||||
_syncInfo: null,
|
||||
|
||||
addListener() {},
|
||||
|
||||
removeListener() {},
|
||||
|
||||
enable() {
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
disable() {
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
sync() {
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
getInfo() {
|
||||
return Promise.resolve(this._syncInfo);
|
||||
}
|
||||
};
|
||||
|
||||
exports.MockSyncManagerBridge = MockSyncManagerBridge;
|
||||
}(window));
|
||||
525
gaia/tv_apps/browser/test/unit/sync/settings_test.js
Executable file
|
|
@ -0,0 +1,525 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/* global ERROR_DIALOG_CLOSED_BY_USER */
|
||||
/* global ERROR_INVALID_SYNC_ACCOUNT */
|
||||
/* global ERROR_OFFLINE */
|
||||
/* global expect */
|
||||
/* global FirefoxSyncSettings */
|
||||
/* global MocksHelper */
|
||||
/* global MockL10n */
|
||||
/* global NavigatorSettings */
|
||||
/* global Settings */
|
||||
/* global SettingsListener */
|
||||
/* global SyncManagerBridge */
|
||||
|
||||
'use strict';
|
||||
|
||||
require('/shared/test/unit/load_body_html_helper.js');
|
||||
require('/shared/test/unit/mocks/mock_lazy_loader.js');
|
||||
require('/shared/test/unit/mocks/mock_l10n.js');
|
||||
require('/shared/test/unit/mocks/mock_navigator_moz_settings.js');
|
||||
require('/shared/test/unit/mocks/mock_settings_listener.js');
|
||||
require('/shared/js/sync/errors.js');
|
||||
requireApp('browser/test/unit/sync/mocks/mock_manager_bridge.js');
|
||||
requireApp('browser/js/settings.js');
|
||||
requireApp('browser/js/browser_dialog.js');
|
||||
|
||||
var mocksForSettings = new MocksHelper([
|
||||
'LazyLoader',
|
||||
'NavigatorSettings',
|
||||
'SettingsListener',
|
||||
'SyncManagerBridge'
|
||||
]).init();
|
||||
|
||||
suite('Sync settings >', function() {
|
||||
|
||||
const BOOKMARKS_SETTING = 'sync.collections.bookmarks.enabled';
|
||||
const HISTORY_SETTING = 'sync.collections.history.enabled';
|
||||
|
||||
var subject;
|
||||
var realL10n;
|
||||
var realMozSettings;
|
||||
|
||||
var observeStub;
|
||||
var addListenerStub;
|
||||
var addEventListenerStub;
|
||||
var getInfoSpy;
|
||||
var showScreenSpy;
|
||||
|
||||
var observers = {};
|
||||
var onsyncchange;
|
||||
var visibilityListener;
|
||||
|
||||
mocksForSettings.attachTestHelpers();
|
||||
|
||||
suiteSetup(function(done) {
|
||||
realL10n = navigator.mozL10n;
|
||||
navigator.mozL10n = MockL10n;
|
||||
realMozSettings = navigator.mozSettings;
|
||||
navigator.mozSettings = NavigatorSettings;
|
||||
|
||||
loadBodyHTML('sync/fixtures/settings.html');
|
||||
|
||||
getInfoSpy = sinon.spy(SyncManagerBridge, 'getInfo');
|
||||
observeStub = sinon.stub(SettingsListener, 'observe',
|
||||
(setting, unused, observer) => {
|
||||
observers[setting] = observer;
|
||||
});
|
||||
addListenerStub = sinon.stub(SyncManagerBridge, 'addListener',
|
||||
listener => {
|
||||
onsyncchange = listener;
|
||||
});
|
||||
addEventListenerStub = sinon.stub(document, 'addEventListener',
|
||||
(event, listener) => {
|
||||
visibilityListener = listener;
|
||||
});
|
||||
sinon.stub(Settings, 'hide');
|
||||
|
||||
require('/tv_apps/browser/js/sync/settings.js').then(() => {
|
||||
subject = FirefoxSyncSettings;
|
||||
showScreenSpy = sinon.spy(subject, 'showScreen');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
navigator.mozL10n = realL10n;
|
||||
navigator.mozSettings = realMozSettings;
|
||||
observeStub.restore();
|
||||
addListenerStub.restore();
|
||||
addEventListenerStub.restore();
|
||||
getInfoSpy.restore();
|
||||
showScreenSpy.restore();
|
||||
});
|
||||
|
||||
suite('Initial state', function() {
|
||||
test('Integrity', function() {
|
||||
expect(subject).to.be.an('object');
|
||||
});
|
||||
|
||||
test('Initialization', function() {
|
||||
expect(getInfoSpy.calledOnce).to.equal(true);
|
||||
expect(addListenerStub.calledOnce).to.equal(true);
|
||||
expect(addListenerStub.args[0][0]).to.be.a('function');
|
||||
expect(addEventListenerStub.calledOnce).to.equal(true);
|
||||
expect(onsyncchange).to.be.a('function');
|
||||
expect(visibilityListener).to.be.a('function');
|
||||
});
|
||||
|
||||
test('should observe settings', function() {
|
||||
expect(observeStub.calledTwice).to.be.equal(true);
|
||||
expect(observers[HISTORY_SETTING]).to.be.a('function');
|
||||
expect(observers[BOOKMARKS_SETTING]).to.be.a('function');
|
||||
});
|
||||
|
||||
test('DOM initial state', function() {
|
||||
expect(subject.area).to.be.an('object');
|
||||
expect(subject.elements.enabled).to.be.an('object');
|
||||
expect(subject.elements.disabled).to.be.an('object');
|
||||
expect(subject.listeners).to.be.an('object');
|
||||
expect(subject.listeners.size).to.be.equals(8);
|
||||
expect(subject.collections).to.be.an('object');
|
||||
expect(subject.collections.size).to.be.equals(0);
|
||||
expect(subject.screen).to.be.equals('disabled');
|
||||
expect(subject.state).to.be.equals('disabled');
|
||||
});
|
||||
});
|
||||
|
||||
suite('visibilitychange', function() {
|
||||
setup(function() {
|
||||
getInfoSpy.reset();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
getInfoSpy.reset();
|
||||
});
|
||||
|
||||
test('should refresh on visibity change', function() {
|
||||
expect(getInfoSpy.called).to.be.equal(false);
|
||||
visibilityListener();
|
||||
expect(getInfoSpy.called).to.be.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Disabled', function() {
|
||||
suiteSetup(function() {
|
||||
onsyncchange({
|
||||
state: 'disabled'
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
showScreenSpy.reset();
|
||||
});
|
||||
|
||||
test('should show disabled screen', function() {
|
||||
expect(showScreenSpy.calledOnce).to.be.equal(true);
|
||||
expect(showScreenSpy.args[0][0]).to.equal('disabled');
|
||||
expect(subject.elements.enabled.hidden).to.be.equal(true);
|
||||
expect(subject.elements.disabled.hidden).to.be.equal(false);
|
||||
});
|
||||
|
||||
test('should have signin button', function() {
|
||||
expect(subject.elements.signInButton).to.be.an('object');
|
||||
expect(subject.elements.signInButton.getAttribute('data-l10n-id'))
|
||||
.to.equals('fxsync-sign-in');
|
||||
expect(subject.elements.signInButton.classList.contains('disabled'))
|
||||
.to.equals(false);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Disabled from disabling', function() {
|
||||
var alertStub;
|
||||
var formatValueStub;
|
||||
suiteSetup(function() {
|
||||
formatValueStub = sinon.stub(navigator.mozL10n, 'formatValue', key => {
|
||||
return Promise.resolve(key);
|
||||
});
|
||||
|
||||
alertStub = sinon.stub(window, 'alert');
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
showScreenSpy.reset();
|
||||
formatValueStub.restore();
|
||||
alertStub.restore();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
alertStub.reset();
|
||||
});
|
||||
|
||||
['enabled', 'syncing'].forEach(previousState => {
|
||||
test('should show disabled dialog',
|
||||
function(done) {
|
||||
subject.previousState = previousState;
|
||||
subject.state = 'disabling';
|
||||
onsyncchange({
|
||||
state: 'disabled',
|
||||
user: 'pepito'
|
||||
});
|
||||
setTimeout(function() {
|
||||
expect(alertStub.calledOnce).to.equal(true);
|
||||
expect(alertStub.args[0][0]).to.equal('fxsync-disabled');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('Enabled', function() {
|
||||
suiteSetup(function() {
|
||||
onsyncchange({
|
||||
state: 'enabled',
|
||||
user: 'pepito'
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
showScreenSpy.reset();
|
||||
});
|
||||
|
||||
test('should show enabled screen', function() {
|
||||
expect(showScreenSpy.calledOnce).to.be.equal(true);
|
||||
expect(showScreenSpy.args[0][0]).to.equal('enabled');
|
||||
expect(subject.elements.enabled.hidden).to.be.equal(false);
|
||||
expect(subject.elements.disabled.hidden).to.be.equal(true);
|
||||
});
|
||||
|
||||
test('should show user', function() {
|
||||
expect(subject.elements.signedInAs).to.be.an('object');
|
||||
expect(subject.elements.signedInAs.getAttribute('data-l10n-id'))
|
||||
.to.equals('fxsync-signed-in-as');
|
||||
expect(subject.elements.signedInAs.getAttribute('data-l10n-args'))
|
||||
.to.equals('{"email":"pepito"}');
|
||||
});
|
||||
|
||||
test('should show sync now button', function() {
|
||||
expect(subject.elements.syncNowButton).to.be.an('object');
|
||||
expect(subject.elements.syncNowButton.getAttribute('data-l10n-id'))
|
||||
.to.equals('fxsync-sync-now');
|
||||
});
|
||||
|
||||
test('should show signout button', function() {
|
||||
expect(subject.elements.signOutButton).to.be.an('object');
|
||||
expect(subject.elements.signOutButton.getAttribute('data-l10n-id'))
|
||||
.to.equals('fxsync-sign-out');
|
||||
});
|
||||
|
||||
test('should show collection switches', function() {
|
||||
expect(subject.elements.collectionBookmarks).to.be.an('object');
|
||||
expect(subject.elements.collectionHistory).to.be.an('object');
|
||||
});
|
||||
});
|
||||
|
||||
suite('Enabled from enabling', function() {
|
||||
var alertStub;
|
||||
var formatValueStub;
|
||||
suiteSetup(function() {
|
||||
formatValueStub = sinon.stub(navigator.mozL10n, 'formatValue', key => {
|
||||
return Promise.resolve(key);
|
||||
});
|
||||
|
||||
alertStub = sinon.stub(window, 'alert');
|
||||
|
||||
subject.state = 'enabling';
|
||||
onsyncchange({
|
||||
state: 'enabled',
|
||||
user: 'pepito'
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
showScreenSpy.reset();
|
||||
formatValueStub.restore();
|
||||
alertStub.restore();
|
||||
});
|
||||
|
||||
test('should show enabled dialog', function() {
|
||||
expect(alertStub.calledOnce).to.equal(true);
|
||||
expect(alertStub.args[0][0]).to.equal('fxsync-enabled');
|
||||
});
|
||||
});
|
||||
|
||||
suite('Enabling', function() {
|
||||
suiteSetup(function() {
|
||||
onsyncchange({
|
||||
state: 'enabling'
|
||||
});
|
||||
});
|
||||
|
||||
test('should show signing in button', function() {
|
||||
expect(subject.elements.signInButton.dataset.l10nId)
|
||||
.to.equals('fxsync-signing');
|
||||
});
|
||||
|
||||
test('should disable signin button', function() {
|
||||
expect(subject.elements.signInButton.classList.contains('disabled'))
|
||||
.to.equals(true);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Syncing', function() {
|
||||
suiteSetup(function() {
|
||||
onsyncchange({
|
||||
state: 'syncing',
|
||||
user: 'pepito'
|
||||
});
|
||||
});
|
||||
|
||||
test('should show syncing button', function() {
|
||||
expect(subject.elements.syncNowButton.dataset.l10nId)
|
||||
.to.equals('fxsync-syncing');
|
||||
});
|
||||
|
||||
test('should show user', function() {
|
||||
expect(subject.elements.signedInAs).to.be.an('object');
|
||||
expect(subject.elements.signedInAs.getAttribute('data-l10n-id'))
|
||||
.to.equals('fxsync-signed-in-as');
|
||||
expect(subject.elements.signedInAs.getAttribute('data-l10n-args'))
|
||||
.to.equals('{"email":"pepito"}');
|
||||
});
|
||||
|
||||
test('should disable sync button and collection switches', function() {
|
||||
expect(subject.elements.syncNowButton.classList.contains('disabled'))
|
||||
.to.equals(true);
|
||||
expect(subject.elements.collectionBookmarks.disabled).to.equal(true);
|
||||
expect(subject.elements.collectionHistory.disabled).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Errored', function() {
|
||||
var alertStub;
|
||||
var formatValueStub;
|
||||
|
||||
suiteSetup(function() {
|
||||
alertStub = sinon.stub(window, 'alert');
|
||||
formatValueStub = sinon.stub(navigator.mozL10n, 'formatValue', key => {
|
||||
return Promise.resolve(key);
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
alertStub.restore();
|
||||
formatValueStub.restore();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
alertStub.reset();
|
||||
});
|
||||
|
||||
test('should ignore ERROR_DIALOG_CLOSED_BY_USER error', function() {
|
||||
onsyncchange({
|
||||
state: 'errored',
|
||||
error: ERROR_DIALOG_CLOSED_BY_USER
|
||||
});
|
||||
expect(alertStub.calledOnce).to.equal(false);
|
||||
});
|
||||
|
||||
test('should show ERROR_INVALID_SYNC_ACCOUNT error', function(done) {
|
||||
onsyncchange({
|
||||
state: 'errored',
|
||||
error: ERROR_INVALID_SYNC_ACCOUNT
|
||||
});
|
||||
setTimeout(() => {
|
||||
expect(alertStub.calledOnce).to.equal(true);
|
||||
expect(alertStub.args[0][0]).to.equal(ERROR_INVALID_SYNC_ACCOUNT +
|
||||
'\n' +
|
||||
ERROR_INVALID_SYNC_ACCOUNT +
|
||||
'-explanation');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('should show ERROR_OFFLINE error', function(done) {
|
||||
onsyncchange({
|
||||
state: 'errored',
|
||||
error: ERROR_OFFLINE
|
||||
});
|
||||
setTimeout(() => {
|
||||
expect(alertStub.calledOnce).to.equal(true);
|
||||
expect(alertStub.args[0][0]).to.equal(ERROR_OFFLINE +
|
||||
'\n' +
|
||||
ERROR_OFFLINE +
|
||||
'-explanation');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('Collections', function() {
|
||||
var realMozId;
|
||||
var mozIdError = null;
|
||||
|
||||
suiteSetup(function() {
|
||||
onsyncchange({
|
||||
state: 'enabled',
|
||||
user: 'pepito'
|
||||
});
|
||||
|
||||
realMozId = navigator.mozId;
|
||||
navigator.mozId = {
|
||||
watch(options) {
|
||||
this._onlogin = options.onlogin;
|
||||
this._onerror = options.onerror;
|
||||
},
|
||||
request() {
|
||||
mozIdError ? this._onerror() : this._onlogin();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
[{
|
||||
test: 'should check bookmarks on setting enabled',
|
||||
collection: 'collectionBookmarks',
|
||||
setting: BOOKMARKS_SETTING,
|
||||
enabled: true
|
||||
}, {
|
||||
test: 'should uncheck bookmarks on setting disabled',
|
||||
collection: 'collectionBookmarks',
|
||||
setting: BOOKMARKS_SETTING,
|
||||
enabled: false
|
||||
}, {
|
||||
test: 'should check history on setting enabled',
|
||||
collection: 'collectionHistory',
|
||||
setting: HISTORY_SETTING,
|
||||
enabled: true
|
||||
}, {
|
||||
test: 'should uncheck history on setting disabled',
|
||||
collection: 'collectionHistory',
|
||||
setting: HISTORY_SETTING,
|
||||
enabled: false
|
||||
}].forEach(config => {
|
||||
test(config.test, function() {
|
||||
expect(subject.elements[config.collection].checked)
|
||||
.to.be.equal(!config.enabled);
|
||||
observers[config.setting](config.enabled);
|
||||
expect(subject.elements[config.collection].checked)
|
||||
.to.be.equal(config.enabled);
|
||||
});
|
||||
});
|
||||
|
||||
[{
|
||||
test: 'bookmark checked',
|
||||
setting: BOOKMARKS_SETTING,
|
||||
checked: true,
|
||||
collection: 'collectionBookmarks',
|
||||
oncheckedFunction: 'onbookmarkschecked'
|
||||
}, {
|
||||
test: 'bookmark unchecked',
|
||||
setting: BOOKMARKS_SETTING,
|
||||
checked: false,
|
||||
collection: 'collectionBookmarks',
|
||||
oncheckedFunction: 'onbookmarkschecked'
|
||||
}, {
|
||||
test: 'history checked',
|
||||
setting: HISTORY_SETTING,
|
||||
checked: true,
|
||||
collection: 'collectionHistory',
|
||||
oncheckedFunction: 'onhistorychecked'
|
||||
}, {
|
||||
test: 'history unchecked',
|
||||
setting: HISTORY_SETTING,
|
||||
checked: false,
|
||||
collection: 'collectionHistory',
|
||||
oncheckedFunction: 'onhistorychecked'
|
||||
}].forEach(config => {
|
||||
test('should enable setting on ' + config.test, function() {
|
||||
expect(subject.collections.has(config.setting))
|
||||
.to.be.equal(!config.checked);
|
||||
subject.elements[config.collection].checked = config.checked;
|
||||
subject[config.oncheckedFunction]();
|
||||
expect(subject.collections.has(config.setting))
|
||||
.to.be.equal(config.checked);
|
||||
});
|
||||
});
|
||||
|
||||
test('should enable/disable Sync Now button on setting enabled/disabled',
|
||||
function() {
|
||||
[{
|
||||
setting: HISTORY_SETTING,
|
||||
enabled: true
|
||||
}, {
|
||||
setting: HISTORY_SETTING,
|
||||
enabled: false
|
||||
}, {
|
||||
setting: BOOKMARKS_SETTING,
|
||||
enabled: true
|
||||
}, {
|
||||
setting: BOOKMARKS_SETTING,
|
||||
enabled: false
|
||||
}].forEach(config => {
|
||||
observers[config.setting](config.enabled);
|
||||
expect(subject.elements.syncNowButton.classList.contains('disabled'))
|
||||
.to.equals(!config.enabled);
|
||||
});
|
||||
});
|
||||
|
||||
test(`should not enable collections checkboxes if refresh auth failed`,
|
||||
function() {
|
||||
[{
|
||||
setting: HISTORY_SETTING,
|
||||
element: 'collectionHistory',
|
||||
onchecked: 'onhistorychecked'
|
||||
}, {
|
||||
setting: BOOKMARKS_SETTING,
|
||||
element: 'collectionBookmarks',
|
||||
onchecked: 'onbookmarkschecked'
|
||||
}].forEach(config => {
|
||||
mozIdError = true;
|
||||
expect(subject.collections.has(config.setting))
|
||||
.to.be.equal(false);
|
||||
subject.elements[config.element].checked = true;
|
||||
subject[config.onchecked]();
|
||||
expect(subject.collections.has(config.setting))
|
||||
.to.be.equal(false);
|
||||
expect(subject.elements[config.element].checked)
|
||||
.to.be.equal(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||