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.
373
assets/webapps/music-oga.gaiamobile.org/shared/elements/gaia-header/dist/gaia-header.js
vendored
Normal file
|
|
@ -0,0 +1,373 @@
|
|||
;;(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.GaiaHeader=f()}})(function(){var define,module,exports;return(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){;(function(define){define(function(require,exports,module){'use strict';var debug=0?console.log.bind(console):function(){};var cache={};var MIN=16;var MAX=24;var BUFFER=3;module.exports=function(config){debug('font fit',config);var space=config.space-BUFFER;var min=config.min||MIN;var max=config.max||MAX;var text=trim(config.text);var fontSize=max;var textWidth;var font;do{font=config.font.replace(/\d+px/,fontSize+'px');textWidth=getTextWidth(text,font);}while(textWidth>space&&fontSize!==min&&fontSize--);return{textWidth:textWidth,fontSize:fontSize,overflowing:textWidth>space};};function getTextWidth(text,font){var ctx=getCanvasContext(font);var width=ctx.measureText(text).width;debug('got text width',width);return width;}
|
||||
function getCanvasContext(font){debug('get canvas context',font);var cached=cache[font];if(cached){return cached;}
|
||||
var canvas=document.createElement('canvas');canvas.setAttribute('moz-opaque','true');canvas.setAttribute('width','1px');canvas.setAttribute('height','1px');debug('created canvas',canvas);var ctx=canvas.getContext('2d',{willReadFrequently:true});ctx.font=font;return cache[font]=ctx;}
|
||||
function trim(text){return text.replace(/\s+/g,' ').trim();}});})(typeof define=='function'&&define.amd?define:(function(n,w){'use strict';return typeof module=='object'?function(c){c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){return w[n];},m.exports,m);w[n]=m.exports;};})('font-fit',this));},{}],2:[function(require,module,exports){;(function(define){'use strict';define(function(require,exports,module){var textContent=Object.getOwnPropertyDescriptor(Node.prototype,'textContent');var innerHTML=Object.getOwnPropertyDescriptor(Element.prototype,'innerHTML');var removeAttribute=Element.prototype.removeAttribute;var setAttribute=Element.prototype.setAttribute;var noop=function(){};exports.register=function(name,props){var baseProto=getBaseProto(props.extends);var template=props.template||baseProto.templateString;var extensible=props.extensible=props.hasOwnProperty('extensible')?props.extensible:true;delete props.extends;if(template){if(extensible&&props.template){props.templateString=props.template;}
|
||||
var output=processCss(template,name);props.template=document.createElement('template');props.template.innerHTML=output.template;props.lightCss=output.lightCss;props.globalCss=props.globalCss||'';props.globalCss+=output.globalCss;}
|
||||
injectGlobalCss(props.globalCss);delete props.globalCss;var descriptors=mixin(props.attrs||{},base.descriptors);props._attrs=props.attrs;delete props.attrs;var proto=createProto(baseProto,props);Object.defineProperties(proto,descriptors);try{return document.registerElement(name,{prototype:proto});}catch(e){if(e.name!=='NotSupportedError'){throw e;}}};var base={properties:{GaiaComponent:true,attributeChanged:noop,attached:noop,detached:noop,created:noop,createdCallback:function(){if(this.dirObserver){addDirObserver();}
|
||||
injectLightCss(this);this.created();},attributeChangedCallback:function(name,from,to){var prop=toCamelCase(name);if(this._attrs&&this._attrs[prop]){this[prop]=to;}
|
||||
this.attributeChanged(name,from,to);},attachedCallback:function(){if(this.dirObserver){this.setInnerDirAttributes=setInnerDirAttributes.bind(null,this);document.addEventListener('dirchanged',this.setInnerDirAttributes);}
|
||||
this.attached();},detachedCallback:function(){if(this.dirObserver){document.removeEventListener('dirchanged',this.setInnerDirAttributes);}
|
||||
this.detached();},setupShadowRoot:function(){if(!this.template){return;}
|
||||
var node=document.importNode(this.template.content,true);this.createShadowRoot().appendChild(node);if(this.dirObserver){setInnerDirAttributes(this);}
|
||||
return this.shadowRoot;},setAttr:function(name,value){var internal=this.shadowRoot.firstElementChild;setAttribute.call(internal,name,value);setAttribute.call(this,name,value);},removeAttr:function(name){var internal=this.shadowRoot.firstElementChild;removeAttribute.call(internal,name);removeAttribute.call(this,name);}},descriptors:{textContent:{set:function(value){textContent.set.call(this,value);if(this.lightStyle){this.appendChild(this.lightStyle);}},get:function(){return textContent.get();}},innerHTML:{set:function(value){innerHTML.set.call(this,value);if(this.lightStyle){this.appendChild(this.lightStyle);}},get:innerHTML.get}}};var defaultPrototype=createProto(HTMLElement.prototype,base.properties);function getBaseProto(proto){if(!proto){return defaultPrototype;}
|
||||
proto=proto.prototype||proto;return!proto.GaiaComponent?createProto(proto,base.properties):proto;}
|
||||
function createProto(proto,props){return mixin(Object.create(proto),props);}
|
||||
var hasShadowCSS=(function(){var div=document.createElement('div');try{div.querySelector(':host');div.querySelector('::content');return true;}
|
||||
catch(e){return false;}})();var regex={shadowCss:/(?:\:host|\:\:content)[^{]*\{[^}]*\}/g,':host':/(?:\:host)/g,':host()':/\:host\((.+)\)(?: \:\:content)?/g,':host-context':/\:host-context\((.+)\)([^{,]+)?/g,'::content':/(?:\:\:content)/g};function processCss(template,name){var globalCss='';var lightCss='';if(!hasShadowCSS){template=template.replace(regex.shadowCss,function(match){var hostContext=regex[':host-context'].exec(match);if(hostContext){globalCss+=match.replace(regex['::content'],'').replace(regex[':host-context'],'$1 '+name+'$2').replace(/ +/g,' ');}else{lightCss+=match.replace(regex[':host()'],name+'$1').replace(regex[':host'],name).replace(regex['::content'],name);}
|
||||
return'';});}
|
||||
return{template:template,lightCss:lightCss,globalCss:globalCss};}
|
||||
function injectGlobalCss(css){if(!css){return;}
|
||||
var style=document.createElement('style');style.innerHTML=css.trim();headReady().then(function(){document.head.appendChild(style);});}
|
||||
function headReady(){return new Promise(function(resolve){if(document.head){return resolve();}
|
||||
window.addEventListener('load',function fn(){window.removeEventListener('load',fn);resolve();});});}
|
||||
function injectLightCss(el){if(hasShadowCSS){return;}
|
||||
var stylesheet=el.querySelector('style');if(!stylesheet){stylesheet=document.createElement('style');stylesheet.setAttribute('scoped','');stylesheet.appendChild(document.createTextNode(el.lightCss));el.appendChild(stylesheet);}
|
||||
el.lightStyle=stylesheet;}
|
||||
function toCamelCase(string){return string.replace(/-(.)/g,function replacer(string,p1){return p1.toUpperCase();});}
|
||||
var dirObserver;function setInnerDirAttributes(component){var dir=component.dir||document.dir;Array.from(component.shadowRoot.children).forEach(element=>{if(element.nodeName!=='STYLE'){element.dir=dir;}});}
|
||||
function addDirObserver(){if(dirObserver){return;}
|
||||
dirObserver=new MutationObserver(onChanged);dirObserver.observe(document.documentElement,{attributeFilter:['dir'],attributes:true});function onChanged(mutations){document.dispatchEvent(new Event('dirchanged'));}}
|
||||
function mixin(target,source){for(var key in source){target[key]=source[key];}
|
||||
return target;}});})(typeof define=='function'&&define.amd?define:(function(n,w){'use strict';return typeof module=='object'?function(c){c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-component',this));},{}],3:[function(require,module,exports){(function(define){'use strict';define(function(require,exports,module){var base=window.GAIA_ICONS_BASE_URL||window.COMPONENTS_BASE_URL||'bower_components/';if(!document.documentElement){window.addEventListener('load',load);}else{load();}
|
||||
function load(){if(isLoaded()){return;}
|
||||
var link=document.createElement('link');link.rel='stylesheet';link.type='text/css';link.href=base+'gaia-icons/gaia-icons.css';document.head.appendChild(link);exports.loaded=true;}
|
||||
function isLoaded(){return exports.loaded||document.querySelector('link[href*=gaia-icons]')||document.documentElement.classList.contains('gaia-icons-loaded');}});})(typeof define=='function'&&define.amd?define:(function(n,w){'use strict';return typeof module=='object'?function(c){c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-icons',this));},{}],4:[function(require,module,exports){;(function(define){'use strict';define(function(require,exports,module){var component=require('gaia-component');var fontFit=require('font-fit');require('gaia-icons');var debug=0?console.log.bind(console):function(){};const KNOWN_ACTIONS={menu:'menu',back:'back',close:'close'};const TITLE_FONT='italic 300 24px FiraSans';const TITLE_PADDING=10;const MINIMUM_FONT_SIZE_CENTERED=20;const MINIMUM_FONT_SIZE_UNCENTERED=16;const MAXIMUM_FONT_SIZE=23;module.exports=component.register('gaia-header',{extensible:false,dirObserver:true,created:function(){debug('created');this.setupShadowRoot();this.els={actionButton:this.shadowRoot.querySelector('.action-button'),titles:this.getElementsByTagName('h1')};this.els.actionButton.addEventListener('click',e=>this.onActionButtonClick(e));this.observer=new MutationObserver(this.onMutation.bind(this));this.ignoreDir=this.hasAttribute('ignore-dir');this.titleEnd=this.getAttribute('title-end');this.titleStart=this.getAttribute('title-start');this.noFontFit=this.getAttribute('no-font-fit');this.notFlush=this.hasAttribute('not-flush');this.action=this.getAttribute('action');this.unresolved={};this.pending={};this._resizeThrottlingId=null;this.onResize=this.onResize.bind(this);},attached:function(){debug('attached');this.runFontFitSoon();this.observerStart();window.addEventListener('resize',this.onResize);},detached:function(){debug('detached');window.removeEventListener('resize',this.onResize);this.observerStop();this.clearPending();},clearPending:function(){for(var key in this.pending){this.pending[key].clear();delete this.pending[key];}
|
||||
window.cancelAnimationFrame(this._resizeThrottlingId);this._resizeThrottlingId=null;},runFontFit:function(){debug('run font-fit');if(this.noFontFit){return Promise.resolve();}
|
||||
var titles=this.els.titles;var space=this.getTitleSpace();var styles=[].map.call(titles,el=>this.getTitleStyle(el,space));return this.setTitleStylesSoon(styles);},runFontFitSoon:function(){debug('run font-fit soon');if(this.pending.runFontFitSoon){return;}
|
||||
this.pending.runFontFitSoon=this.nextTick(()=>{delete this.pending.runFontFitSoon;this.runFontFit();});},getTitleStyle:function(el,space){debug('get el style',el,space);var text=el.textContent;var styleId=space.start+text+space.end+'#'+space.value;if(!text||!text.trim()){return debug('exit: no text');}
|
||||
if(getStyleId(el)===styleId){return debug('exit: no change');}
|
||||
var marginStart=this.getTitleMarginStart();var textSpace=space.value-Math.abs(marginStart);var fontFitResult=this.fontFit(text,textSpace,{min:MINIMUM_FONT_SIZE_CENTERED});var overflowing=fontFitResult.overflowing;var padding={start:0,end:0};if(overflowing){debug('title overflowing');padding.start=!space.start?TITLE_PADDING:0;padding.end=!space.end?TITLE_PADDING:0;textSpace=space.value-padding.start-padding.end;fontFitResult=this.fontFit(text,textSpace);marginStart=0;}
|
||||
return{id:styleId,fontSize:fontFitResult.fontSize,marginStart:marginStart,overflowing:overflowing,padding:padding};},setTitleStylesSoon:function(styles){debug('set title styles soon',styles);var key='setStyleTitlesSoon';this._titleStyles=styles;if(this.unresolved[key]){return this.unresolved[key];}
|
||||
this.unresolved[key]=new Promise((resolve)=>{this.pending[key]=this.nextTick(()=>{var styles=this._titleStyles;var els=this.els.titles;[].forEach.call(els,(el,i)=>{if(!styles[i]){return debug('exit');}
|
||||
this.setTitleStyle(el,styles[i]);});delete this._titleStyles;delete this.unresolved[key];delete this.pending[key];resolve();});});},setTitleStyle:function(el,style){debug('set title style',style);this.observerStop();if(this.ignoreDir){el.style.marginLeft=style.marginStart+'px';el.style.paddingLeft=style.padding.start+'px';el.style.paddingRight=style.padding.end+'px';}else{el.style.marginInlineStart=style.marginStart+'px';el.style.paddingInlineStart=style.padding.start+'px';el.style.paddingInlineEnd=style.padding.end+'px';}
|
||||
el.style.fontSize=style.fontSize+'px';setStyleId(el,style.id);this.observerStart();},fontFit:function(text,space,opts={}){debug('font fit:',text,space,opts);var fontFitArgs={font:TITLE_FONT,min:opts.min||MINIMUM_FONT_SIZE_UNCENTERED,max:MAXIMUM_FONT_SIZE,text:text,space:space};return fontFit(fontFitArgs);},observerStart:function(){if(this.observing){return;}
|
||||
this.observer.observe(this,{childList:true,attributes:true,subtree:true});this.observing=true;debug('observer started');},observerStop:function(){if(!this.observing){return;}
|
||||
this.observer.disconnect();this.observing=false;debug('observer stopped');},onResize:function(e){debug('onResize',this._resizeThrottlingId);if(this._resizeThrottlingId!==null){return;}
|
||||
this._resizeThrottlingId=window.requestAnimationFrame(()=>{this._resizeThrottlingId=null;this.runFontFitSoon();});},onMutation:function(mutations){debug('on mutation',mutations);if(!this.pending.runFontFitSoon){this.runFontFit();}},getTitleSpace:function(){var start=this.titleStart;var end=this.titleEnd;var space=this.getWidth()-start-end;var result={value:space,start:start,end:end};debug('get title space',result);return result;},getWidth:function(){var value=this.notFlush?this.clientWidth:window.innerWidth;debug('get width',value);return value;},triggerAction:function(){if(this.action){this.els.actionButton.click();}},onActionButtonClick:function(){debug('action button click');var config={detail:{type:this.action}};var e=new CustomEvent('action',config);setTimeout(()=>this.dispatchEvent(e));},getTitleMarginStart:function(){var start=this.titleStart;var end=this.titleEnd;var marginStart=end-start;debug('get title margin start',marginStart);return marginStart;},getButtonsBeforeTitle:function(){var children=this.children;var l=children.length;var els=[];for(var i=0;i<l;i++){var el=children[i];if(el.tagName==='H1'){break;}
|
||||
if(!contributesToLayout(el)){continue;}
|
||||
els.push(el);}
|
||||
if(this.action){els.push(this.els.actionButton);}
|
||||
return els;},getButtonsAfterTitle:function(){var children=this.children;var els=[];for(var i=children.length-1;i>=0;i--){var el=children[i];if(el.tagName==='H1'){break;}
|
||||
if(!contributesToLayout(el)){continue;}
|
||||
els.push(el);}
|
||||
return els;},sumButtonWidths:function(buttons){var defaultWidth=50;var sum=buttons.reduce((prev,button)=>{var isStandardButton=button===this.els.actionButton;var width=isStandardButton?defaultWidth:button.clientWidth;return prev+width;},0);debug('sum button widths',buttons,sum);return sum;},attrs:{action:{get:function(){return this._action;},set:function(value){var action=KNOWN_ACTIONS[value];if(action===this._action){return;}
|
||||
this.setAttr('action',action);this._action=action;}},titleStart:{get:function(){debug('get title-start');if('_titleStart'in this){return this._titleStart;}
|
||||
var buttons=this.getButtonsBeforeTitle();var value=this.sumButtonWidths(buttons);debug('get title-start',buttons,value);return value;},set:function(value){debug('set title-start',value);value=parseInt(value,10);if(value===this._titleStart||isNaN(value)){return;}
|
||||
this.setAttr('title-start',value);this._titleStart=value;debug('set');}},titleEnd:{get:function(){debug('get title-end');if('_titleEnd'in this){return this._titleEnd;}
|
||||
var buttons=this.getButtonsAfterTitle();return this.sumButtonWidths(buttons);},set:function(value){debug('set title-end',value);value=parseInt(value,10);if(value===this._titleEnd||isNaN(value)){return;}
|
||||
this.setAttr('title-end',value);this._titleEnd=value;}},noFontFit:{get:function(){return this._noFontFit||false;},set:function(value){debug('set no-font-fit',value);value=!!(value||value==='');if(value===this.noFontFit){return;}
|
||||
this._noFontFit=value;if(value){this.setAttr('no-font-fit','');}
|
||||
else{this.removeAttr('no-font-fit');}}},ignoreDir:{get:function(){return this._ignoreDir||false;},set:function(value){debug('set ignore-dir',value);value=!!(value||value==='');if(value===this.ignoreDir){return;}
|
||||
this._ignoreDir=value;this.dirObserver=!value;if(value){this.setAttr('ignore-dir','');}
|
||||
else{this.removeAttr('ignore-dir');}}}},template:`<div class="inner">
|
||||
<button class="action-button">
|
||||
<content select="[l10n-action]"></content>
|
||||
</button>
|
||||
<content></content>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
||||
:host {
|
||||
display: block;
|
||||
-moz-user-select: none;
|
||||
|
||||
--gaia-header-button-color:
|
||||
var(--header-button-color,
|
||||
var(--header-color,
|
||||
var(--link-color,
|
||||
inherit)));
|
||||
}
|
||||
|
||||
/**
|
||||
* [hidden]
|
||||
*/
|
||||
|
||||
:host[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/** Reset
|
||||
---------------------------------------------------------*/
|
||||
|
||||
::-moz-focus-inner { border: 0; }
|
||||
|
||||
/** Inner
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.inner {
|
||||
display: flex;
|
||||
min-height: 50px;
|
||||
-moz-user-select: none;
|
||||
|
||||
background:
|
||||
var(--header-background,
|
||||
var(--background,
|
||||
#fff));
|
||||
}
|
||||
|
||||
/** Action Button
|
||||
---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* 1. Hidden by default
|
||||
*/
|
||||
|
||||
.action-button {
|
||||
position: relative;
|
||||
|
||||
display: none; /* 1 */
|
||||
width: 50px;
|
||||
font-size: 30px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
|
||||
align-items: center;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
transition: opacity 200ms 280ms;
|
||||
color:
|
||||
var(--header-action-button-color,
|
||||
var(--header-icon-color,
|
||||
var(--gaia-header-button-color)));
|
||||
}
|
||||
|
||||
/**
|
||||
* [action=back]
|
||||
* [action=menu]
|
||||
* [action=close]
|
||||
*
|
||||
* 1. For icon vertical-alignment
|
||||
*/
|
||||
|
||||
[action=back] .action-button,
|
||||
[action=menu] .action-button,
|
||||
[action=close] .action-button {
|
||||
display: flex; /* 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* :active
|
||||
*/
|
||||
|
||||
.action-button:active {
|
||||
transition: none;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
/** Action Button Icon
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.action-button:before {
|
||||
font-family: 'gaia-icons';
|
||||
font-style: normal;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
[action=close] .action-button:before { content: 'close' }
|
||||
[action=menu] .action-button:before { content: 'menu' }
|
||||
|
||||
[action=back]:-moz-dir(ltr) .action-button:before { content: 'left' }
|
||||
[action=back]:-moz-dir(rtl) .action-button:before { content: 'right' }
|
||||
|
||||
/** Action Button Icon
|
||||
---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* 1. To enable vertical alignment.
|
||||
*/
|
||||
|
||||
.action-button:before {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/** Action Button Text
|
||||
---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* To provide custom localized content for
|
||||
* the action-button, we allow the user
|
||||
* to provide an element with the class
|
||||
* .l10n-action. This node is then
|
||||
* pulled inside the real action-button.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* <gaia-header action="back">
|
||||
* <span l10n-action aria-label="Back">Localized text</span>
|
||||
* <h1>title</h1>
|
||||
* </gaia-header>
|
||||
*/
|
||||
|
||||
::content [l10n-action] {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
/** Title
|
||||
---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* 1. Vertically center text. We can't use flexbox
|
||||
* here as it breaks text-overflow ellipsis
|
||||
* without an inner div.
|
||||
*/
|
||||
|
||||
::content h1 {
|
||||
flex: 1;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
text-align: center;
|
||||
line-height: 50px; /* 1 */
|
||||
font-weight: 300;
|
||||
font-style: italic;
|
||||
font-size: 24px;
|
||||
|
||||
color:
|
||||
var(--header-title-color,
|
||||
var(--header-color,
|
||||
var(--title-color,
|
||||
var(--text-color,
|
||||
inherit))));
|
||||
}
|
||||
|
||||
/**
|
||||
* [ignore-dir]
|
||||
*
|
||||
* When the <gaia-header> component has an [ignore-dir] attribute, header
|
||||
* direction is forced to LTR but we still want the <h1> text to be reversed
|
||||
* so that strings like '1 selected' become 'selected 1'.
|
||||
*
|
||||
* When we're happy for <gaia-header> to be fully RTL responsive we won't need
|
||||
* these rules anymore, but this depends on all Gaia apps being ready.
|
||||
*
|
||||
* This should be safe to remove when bug 1179459 lands.
|
||||
*/
|
||||
|
||||
:host[ignore-dir] {
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
:host[ignore-dir]:-moz-dir(rtl) h1 {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
/** Buttons
|
||||
---------------------------------------------------------*/
|
||||
|
||||
::content a,
|
||||
::content button {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
width: auto;
|
||||
height: auto;
|
||||
min-width: 50px;
|
||||
margin: 0;
|
||||
padding: 0 10px;
|
||||
outline: 0;
|
||||
border: 0;
|
||||
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
background: none;
|
||||
border-radius: 0;
|
||||
font-style: italic;
|
||||
cursor: pointer;
|
||||
transition: opacity 200ms 280ms;
|
||||
color: var(--gaia-header-button-color);
|
||||
}
|
||||
|
||||
/**
|
||||
* :active
|
||||
*/
|
||||
|
||||
::content a:active,
|
||||
::content button:active {
|
||||
transition: none;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
/**
|
||||
* [hidden]
|
||||
*/
|
||||
|
||||
::content a[hidden],
|
||||
::content button[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* [disabled]
|
||||
*/
|
||||
|
||||
::content a[disabled],
|
||||
::content button[disabled] {
|
||||
pointer-events: none;
|
||||
color: var(--header-disabled-button-color);
|
||||
}
|
||||
|
||||
/** Icon Buttons
|
||||
---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Icons are a different color to text
|
||||
*/
|
||||
|
||||
::content .icon,
|
||||
::content [data-icon] {
|
||||
color:
|
||||
var(--header-icon-color,
|
||||
var(--gaia-header-button-color));
|
||||
}
|
||||
|
||||
/**
|
||||
* If users want their action button
|
||||
* to be in the component's light-dom
|
||||
* they can add an .action class
|
||||
* to make it look like the
|
||||
* shadow action button.
|
||||
*/
|
||||
|
||||
::content .action {
|
||||
color:
|
||||
var(--header-action-button-color,
|
||||
var(--header-icon-color,
|
||||
var(--gaia-header-button-color)));
|
||||
}
|
||||
|
||||
/**
|
||||
* [data-icon]:empty
|
||||
*
|
||||
* Icon buttons with no textContent,
|
||||
* should always be 50px.
|
||||
*
|
||||
* This is to prevent buttons being
|
||||
* larger than they should be before
|
||||
* icon-font has loaded.
|
||||
*/
|
||||
|
||||
::content [data-icon]:empty {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
</style>`,nextTick:nextTick});function contributesToLayout(el){return el.localName!=='style'&&!el.hasAttribute('l10n-action');}
|
||||
function setStyleId(el,id){el._styleId=id;}
|
||||
function getStyleId(el){return el._styleId;}
|
||||
function nextTick(fn){var cleared;Promise.resolve().then(()=>{if(!cleared){fn();}});return{clear:function(){cleared=true;}};}});})(typeof define=='function'&&define.amd?define:(function(n,w){'use strict';return typeof module=='object'?function(c){c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-header',this));},{"font-fit":1,"gaia-component":2,"gaia-icons":3}]},{},[4])(4)});
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/* Generated by grunt-webfont */
|
||||
/* Based on https://github.com/endtwist/fontcustom/blob/master/lib/fontcustom/templates/fontcustom.css */
|
||||
|
||||
@font-face {
|
||||
font-family: "gaia-icons";
|
||||
src: url("fonts/gaia-icons.ttf") format("truetype");
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
[data-icon]:before,
|
||||
.ligature-icons {
|
||||
font-family: "gaia-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;
|
||||
}
|
||||
|
||||
[data-icon]:not([data-l10n-id]):not([aria-label]):not([aria-hidden="true"]):before {
|
||||
/* Highlight cases where icons are not localized and still visible to screen
|
||||
reader */
|
||||
background: rgba(255, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
[data-icon]:not([data-l10n-id]):not([aria-label]):not([aria-hidden="true"]):after {
|
||||
background: #333;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
width: 20rem;
|
||||
border-radius: 0.5rem;
|
||||
padding: 0.5rem;
|
||||
content: "Icon is not localized and is still visible to screen reader. Please add data-l10n-id or aria-label for localization or use aria-hidden to hide the icon from screen reader.";
|
||||
z-index: 9999;
|
||||
}
|
||||
|
|
@ -0,0 +1,246 @@
|
|||
/*
|
||||
Gaia theme variables
|
||||
*/
|
||||
|
||||
|
||||
:root {
|
||||
|
||||
/** Grey Colors
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--color-alpha: #333333;
|
||||
--color-beta: #ffffff;
|
||||
--color-gamma: #4d4d4d;
|
||||
--color-delta: #5f5f5f;
|
||||
--color-epsilon: #858585;
|
||||
--color-zeta: #a6a6a6;
|
||||
--color-eta: #c7c7c7;
|
||||
--color-theta: #e7e7e7;
|
||||
--color-iota: #f4f4f4;
|
||||
|
||||
/** Brand Colors
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--color-darkblue: #00539f;
|
||||
--color-blue: #00caf2;
|
||||
--color-turquoise: #27c8c2;
|
||||
--color-darkorange: #e66000;
|
||||
--color-orange: #ff9500;
|
||||
--color-yellow: #ffcb00;
|
||||
--color-violet: #c40c84;
|
||||
|
||||
--color-warning: #fbbd3c;
|
||||
--color-destructive: #e2443a;
|
||||
--color-preffered: #00ba91;
|
||||
|
||||
/** Background
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--background: var(--color-beta);
|
||||
--background-plus: var(--color-theta);
|
||||
--background-minus: var(--color-zeta);
|
||||
|
||||
/** Borders
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--border-color: var(--color-theta);
|
||||
|
||||
/** Text Color
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--text-color: var(--color-gamma);
|
||||
--text-color-minus: var(--color-eta);
|
||||
--label-color: #000;
|
||||
|
||||
/** Button
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--button-background: var(--color-iota);
|
||||
|
||||
/** Links
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--link-color: var(--highlight-color);
|
||||
|
||||
/** Inputs
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--input-background: var(--color-beta);
|
||||
--input-color: var(--color-alpha);
|
||||
--input-clear-background: #909ca7;
|
||||
|
||||
/** Buttons
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--button-box-shadow:
|
||||
inset 0 -1px 0 #d8d8d8,
|
||||
inset 0 1px 0 #eeeeee;
|
||||
--button-box-shadow-active: var(--button-box-shadow);
|
||||
|
||||
/** Header
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--header-disabled-button-color: rgba(255,255,255,0.3);
|
||||
|
||||
/** Transitions
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--transition-duration: 0.2s;
|
||||
}
|
||||
|
||||
|
||||
.theme-productivity {
|
||||
|
||||
/** Brand Color
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--highlight-color: var(--color-orange);
|
||||
|
||||
/** Header
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--header-background: var(--highlight-color);
|
||||
--header-color: var(--color-beta);
|
||||
}
|
||||
|
||||
.theme-communications {
|
||||
|
||||
/** Brand Color
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--highlight-color: var(--color-turquoise);
|
||||
|
||||
/** Links
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--link-color: #177874;
|
||||
|
||||
/** Header
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--header-background: var(--highlight-color);
|
||||
--header-color: var(--color-beta);
|
||||
--header-icon-color: var(--color-beta);
|
||||
--header-button-color: var(--link-color);
|
||||
}
|
||||
|
||||
.theme-settings {
|
||||
|
||||
/** Background
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--background: var(--color-iota);
|
||||
--background-plus: var(--color-beta);
|
||||
--background-minus: var(--color-epsilon);
|
||||
--background-minus-minus: var(--color-zeta);
|
||||
|
||||
/** Highlight
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--highlight-color: var(--color-blue);
|
||||
|
||||
/** Borders
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--border-color: var(--color-theta);
|
||||
|
||||
/** Text Color
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--text-color: var(--color-gamma);
|
||||
|
||||
/** Titles
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--title-color: var(--background-minus);
|
||||
|
||||
/** Buttons
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--button-background: var(--background-plus);
|
||||
|
||||
/** Switch
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--switch-background: var(--background-minus-minus);
|
||||
|
||||
/** Checkbox
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--checkbox-border-color: var(--background-minus-minus);
|
||||
|
||||
/** Header
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--header-color: var(--title-color);
|
||||
--header-background: var(--background);
|
||||
--header-button-color: var(--highlight-color);
|
||||
--header-disabled-button-color: var(--color-theta);
|
||||
--header-action-button-color: var(--title-color);
|
||||
}
|
||||
|
||||
.theme-media {
|
||||
|
||||
/** Highlight Color
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--highlight-color: var(--color-blue);
|
||||
|
||||
/** Background
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--background: var(--color-alpha);
|
||||
--background-plus: var(--color-gamma);
|
||||
--background-minus: #2B2B2B;
|
||||
--background-minus-minus: #1a1a1a;
|
||||
|
||||
/** Text Color
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--text-color: var(--color-beta);
|
||||
--label-color: var(--color-beta);
|
||||
|
||||
/** Button
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--button-background: var(--background-plus);
|
||||
|
||||
/** Header
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--header-background: var(--background);
|
||||
--header-icon-color: var(--text-color);
|
||||
--header-button-color: var(--highlight-color);
|
||||
|
||||
/** Borders
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--border-color: var(--color-gamma);
|
||||
|
||||
/** Inputs
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--input-background: var(--background-plus);
|
||||
|
||||
/** Text Input
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--text-input-background: var(--background-minus);
|
||||
|
||||
/** Switch
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--switch-head-border-color: var(--background-minus-minus);
|
||||
--switch-background: var(--background-minus-minus);
|
||||
|
||||
/** Checkbox
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--checkbox-border-color: var(--background-minus-minus);
|
||||
|
||||
/** Buttons
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--button-box-shadow: none;
|
||||
--button-box-shadow-active: none;
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
;'use strict';window.GaiaSubheader=(function(win){var proto=Object.create(HTMLElement.prototype);var baseurl=window.GaiaSubheaderBaseurl||'/shared/elements/gaia_subheader/';proto.createdCallback=function(){ComponentUtils.style.call(this,baseurl);};return document.registerElement('gaia-subheader',{prototype:proto});})(window);
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
gaia-subheader[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gaia Subheader
|
||||
*
|
||||
* Dividing header usually found
|
||||
* heading and separating lists.
|
||||
*/
|
||||
|
||||
gaia-subheader {
|
||||
display: block;
|
||||
padding: 0.8rem 3rem;
|
||||
border-bottom: solid 0.1rem #e6e6e6;
|
||||
color: #424242;
|
||||
font-size: 1.5rem;
|
||||
line-height: 1.8rem;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
/**
|
||||
* [data-skin="organic"]
|
||||
*/
|
||||
|
||||
gaia-subheader[skin="organic"] {
|
||||
border: 0;
|
||||
background-color: #e7e7e7;
|
||||
color: #4d4d4d;
|
||||
}
|
||||
|
||||
/**
|
||||
* [data-skin="dark"]
|
||||
*/
|
||||
|
||||
gaia-subheader[skin="dark"] {
|
||||
border: 0;
|
||||
background-color: #2c353b;
|
||||
color: #fff;
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
;'use strict';(function(exports){var AccessibilityHelper={setAriaSelected:function ah_setAriaSelected(selectedTab,tabs){Array.prototype.forEach.call(tabs,function setAriaSelectedAttr(tab){tab.setAttribute('aria-selected',tab===selectedTab?'true':'false');});}};exports.AccessibilityHelper=AccessibilityHelper;})(window);
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
;;this.asyncStorage=(function(){'use strict';var DBNAME='asyncStorage';var DBVERSION=1;var STORENAME='keyvaluepairs';var db=null;function withDatabase(f){if(db){f();}else{var openreq=indexedDB.open(DBNAME,DBVERSION);openreq.onerror=function withStoreOnError(){console.error('asyncStorage: can\'t open database:',openreq.error.name);};openreq.onupgradeneeded=function withStoreOnUpgradeNeeded(){openreq.result.createObjectStore(STORENAME);};openreq.onsuccess=function withStoreOnSuccess(){db=openreq.result;f();};}}
|
||||
function withStore(type,callback,oncomplete){withDatabase(function(){var transaction=db.transaction(STORENAME,type);if(oncomplete){transaction.oncomplete=oncomplete;}
|
||||
callback(transaction.objectStore(STORENAME));});}
|
||||
function getItem(key,callback){var req;withStore('readonly',function getItemBody(store){req=store.get(key);req.onerror=function getItemOnError(){console.error('Error in asyncStorage.getItem(): ',req.error.name);};},function onComplete(){var value=req.result;if(value===undefined){value=null;}
|
||||
callback(value);});}
|
||||
function setItem(key,value,callback){withStore('readwrite',function setItemBody(store){var req=store.put(value,key);req.onerror=function setItemOnError(){console.error('Error in asyncStorage.setItem(): ',req.error.name);};},callback);}
|
||||
function removeItem(key,callback){withStore('readwrite',function removeItemBody(store){var req=store.delete(key);req.onerror=function removeItemOnError(){console.error('Error in asyncStorage.removeItem(): ',req.error.name);};},callback);}
|
||||
function clear(callback){withStore('readwrite',function clearBody(store){var req=store.clear();req.onerror=function clearOnError(){console.error('Error in asyncStorage.clear(): ',req.error.name);};},callback);}
|
||||
function length(callback){var req;withStore('readonly',function lengthBody(store){req=store.count();req.onerror=function lengthOnError(){console.error('Error in asyncStorage.length(): ',req.error.name);};},function onComplete(){callback(req.result);});}
|
||||
function key(n,callback){if(n<0){callback(null);return;}
|
||||
var req;withStore('readonly',function keyBody(store){var advanced=false;req=store.openCursor();req.onsuccess=function keyOnSuccess(){var cursor=req.result;if(!cursor){return;}
|
||||
if(n===0||advanced){return;}
|
||||
advanced=true;cursor.advance(n);};req.onerror=function keyOnError(){console.error('Error in asyncStorage.key(): ',req.error.name);};},function onComplete(){var cursor=req.result;callback(cursor?cursor.key:null);});}
|
||||
return{getItem:getItem,setItem:setItem,removeItem:removeItem,clear:clear,length:length,key:key};}());
|
||||
|
|
@ -0,0 +1,322 @@
|
|||
/* exported BluetoothHelper */
|
||||
|
||||
'use strict';
|
||||
|
||||
var BluetoothHelper = function() {
|
||||
var profiles = {
|
||||
'HFP': 0x111E,
|
||||
'A2DP': 0x110D
|
||||
};
|
||||
|
||||
var _bluetooth = window.navigator.mozBluetooth;
|
||||
var _isReady = false;
|
||||
var _callbacks = [];
|
||||
|
||||
var _adapter = null;
|
||||
var _oldAdapter = null; // The varaible is accessed for v1 only.
|
||||
var _v2 = true;
|
||||
|
||||
var _ready = function(callback) {
|
||||
if (!callback || !_bluetooth) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_isReady) {
|
||||
callback();
|
||||
} else {
|
||||
_callbacks.push(callback);
|
||||
}
|
||||
};
|
||||
|
||||
var _handleRequest = function(request, callback, errorcb) {
|
||||
request.onsuccess = function() {
|
||||
if (callback) {
|
||||
callback(request.result);
|
||||
}
|
||||
};
|
||||
|
||||
request.onerror = function() {
|
||||
console.log('Error handling bluetooth request');
|
||||
if (errorcb) {
|
||||
errorcb();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// run callbacks when adapter is ready
|
||||
var _processCallbacks = function() {
|
||||
if (_adapter) {
|
||||
_isReady = true;
|
||||
|
||||
_callbacks.forEach(function(callback) {
|
||||
callback();
|
||||
});
|
||||
// clean up the _callback queue
|
||||
_callbacks = [];
|
||||
} else {
|
||||
// We can do nothing without default adapter.
|
||||
console.log('BluetoothHelper(): connot get default adapter yet');
|
||||
}
|
||||
};
|
||||
|
||||
// API v2 get adapter via bluetooth
|
||||
var _fetchAdapterV2 = function() {
|
||||
// need time to get bluetooth adapter at first run
|
||||
_bluetooth.onattributechanged = function onManagerAttributeChanged(evt) {
|
||||
for (var i in evt.attrs) {
|
||||
switch (evt.attrs[i]) {
|
||||
case 'defaultAdapter':
|
||||
console.log('defaultAdapter changed. address:',
|
||||
_bluetooth.defaultAdapter.address);
|
||||
_adapter = _bluetooth.defaultAdapter;
|
||||
_processCallbacks();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_adapter = _bluetooth.defaultAdapter;
|
||||
if (_adapter) {
|
||||
_processCallbacks();
|
||||
}
|
||||
};
|
||||
|
||||
// API v1 get adapter via bluetooth
|
||||
var _fetchAdapter = function() {
|
||||
var req = _bluetooth.getDefaultAdapter();
|
||||
if (req) {
|
||||
req.onsuccess = function() {
|
||||
if (_adapter) {
|
||||
_oldAdapter = _adapter;
|
||||
}
|
||||
|
||||
_isReady = true;
|
||||
_adapter = req.result;
|
||||
|
||||
// Put the callback function of onpairedstatuschanged to the new adapter
|
||||
// because the new adapter won't remember those callback function which
|
||||
// is registered before. In other word, we get a new adpater after
|
||||
// turned on/off Bluetooth. The new adapter have no registered callback.
|
||||
if (_oldAdapter && _oldAdapter.onpairedstatuschanged) {
|
||||
_adapter.onpairedstatuschanged = _oldAdapter.onpairedstatuschanged;
|
||||
}
|
||||
|
||||
_callbacks.forEach(function(callback) {
|
||||
callback();
|
||||
});
|
||||
// clean up the _callback queue
|
||||
_callbacks = [];
|
||||
};
|
||||
|
||||
req.onerror = function() {
|
||||
// We can do nothing without default adapter.
|
||||
console.log('BluetoothHelper(): connot get default adapter!!!');
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
var _getAdapter = function() {
|
||||
if (_v2) {
|
||||
_fetchAdapterV2();
|
||||
} else {
|
||||
_fetchAdapter();
|
||||
}
|
||||
};
|
||||
|
||||
var _resetAdapter = function() {
|
||||
if (_adapter) {
|
||||
_oldAdapter = _adapter;
|
||||
}
|
||||
// clean up state and adapter
|
||||
_isReady = false;
|
||||
_adapter = null;
|
||||
};
|
||||
|
||||
// init
|
||||
if (_bluetooth) {
|
||||
// detect API version
|
||||
if (typeof(_bluetooth.onattributechanged) === 'undefined') {
|
||||
_v2 = false;
|
||||
}
|
||||
|
||||
if (_v2) {
|
||||
_bluetooth.onadapteradded = function onAdapterAdded(evt) {
|
||||
_getAdapter();
|
||||
};
|
||||
} else {
|
||||
_bluetooth.addEventListener('enabled', _getAdapter);
|
||||
_bluetooth.addEventListener('adapteradded', _getAdapter);
|
||||
_bluetooth.addEventListener('disabled', _resetAdapter);
|
||||
}
|
||||
_getAdapter();
|
||||
}
|
||||
|
||||
return {
|
||||
profiles: profiles,
|
||||
|
||||
answerWaitingCall: function() {
|
||||
_ready(function() {
|
||||
_adapter.answerWaitingCall();
|
||||
});
|
||||
},
|
||||
|
||||
ignoreWaitingCall: function() {
|
||||
_ready(function() {
|
||||
_adapter.ignoreWaitingCall();
|
||||
});
|
||||
},
|
||||
|
||||
toggleCalls: function() {
|
||||
_ready(function() {
|
||||
_adapter.toggleCalls();
|
||||
});
|
||||
},
|
||||
|
||||
getConnectedDevicesByProfile: function(profileID, cb) {
|
||||
_ready(function() {
|
||||
_handleRequest(_adapter.getConnectedDevices(profileID), cb);
|
||||
});
|
||||
},
|
||||
|
||||
connectSco: function(cb) {
|
||||
_ready(function() {
|
||||
_handleRequest(_adapter.connectSco(), cb);
|
||||
});
|
||||
},
|
||||
|
||||
disconnectSco: function(cb) {
|
||||
_ready(function() {
|
||||
_handleRequest(_adapter.disconnectSco(), cb);
|
||||
});
|
||||
},
|
||||
|
||||
getPairedDevices: function(cb) {
|
||||
_ready(function() {
|
||||
_handleRequest(_adapter.getPairedDevices(), cb);
|
||||
});
|
||||
},
|
||||
|
||||
getAddress: function(cb) {
|
||||
if (_v2) {
|
||||
console.log('getAddress function is deprecated');
|
||||
return;
|
||||
}
|
||||
|
||||
_ready(function() {
|
||||
var address = _adapter.address;
|
||||
cb(address);
|
||||
});
|
||||
},
|
||||
|
||||
setPairingConfirmation: function(address, confirmed) {
|
||||
if (_v2) {
|
||||
console.log('setPairingConfirmation API is deprecated');
|
||||
return;
|
||||
}
|
||||
|
||||
_ready(function() {
|
||||
_adapter.setPairingConfirmation(address, confirmed);
|
||||
});
|
||||
},
|
||||
|
||||
setPinCode: function(address, pincode) {
|
||||
if (_v2) {
|
||||
console.log('setPairingConfirmation API is deprecated');
|
||||
return;
|
||||
}
|
||||
|
||||
_ready(function() {
|
||||
_adapter.setPinCode(address, pincode);
|
||||
});
|
||||
},
|
||||
|
||||
setPasskey: function(address, key) {
|
||||
if (_v2) {
|
||||
console.log('setPairingConfirmation API is deprecated');
|
||||
return;
|
||||
}
|
||||
|
||||
_ready(function() {
|
||||
_adapter.setPasskey(address, key);
|
||||
});
|
||||
},
|
||||
|
||||
isScoConnected: function(cb, errorcb) {
|
||||
_ready(function() {
|
||||
_handleRequest(_adapter.isScoConnected(), cb, errorcb);
|
||||
});
|
||||
},
|
||||
|
||||
sendMediaMetaData: function(metadata, cb, errorcb) {
|
||||
_ready(function() {
|
||||
_handleRequest(_adapter.sendMediaMetaData(metadata), cb, errorcb);
|
||||
});
|
||||
},
|
||||
|
||||
sendMediaPlayStatus: function(metadata, cb, errorcb) {
|
||||
_ready(function() {
|
||||
_handleRequest(_adapter.sendMediaPlayStatus(metadata), cb, errorcb);
|
||||
});
|
||||
},
|
||||
|
||||
set onhfpstatuschanged(callback) {
|
||||
_ready(function() {
|
||||
_adapter.onhfpstatuschanged = callback;
|
||||
});
|
||||
},
|
||||
|
||||
set onscostatuschanged(callback) {
|
||||
_ready(function() {
|
||||
_adapter.onscostatuschanged = callback;
|
||||
});
|
||||
},
|
||||
|
||||
set ona2dpstatuschanged(callback) {
|
||||
_ready(function() {
|
||||
_adapter.ona2dpstatuschanged = callback;
|
||||
});
|
||||
},
|
||||
|
||||
set onrequestmediaplaystatus(callback) {
|
||||
_ready(function() {
|
||||
_adapter.onrequestmediaplaystatus = callback;
|
||||
});
|
||||
},
|
||||
|
||||
set onpairedstatuschanged(callback) {
|
||||
if (_v2) {
|
||||
console.log('onpairedstatuschanged API is deprecated');
|
||||
return;
|
||||
}
|
||||
|
||||
_ready(function() {
|
||||
_adapter.onpairedstatuschanged = callback;
|
||||
});
|
||||
},
|
||||
|
||||
v2: _v2, // expose API version for app reference
|
||||
|
||||
// bypass the enable/disable state if works in APIv1
|
||||
enable: function() {
|
||||
if (_v2) {
|
||||
_ready(function() {
|
||||
_adapter.enable();
|
||||
});
|
||||
} else {
|
||||
console.log('enable is not support in v1 API!');
|
||||
}
|
||||
},
|
||||
|
||||
disable: function() {
|
||||
if (_v2) {
|
||||
_ready(function() {
|
||||
_adapter.disable();
|
||||
});
|
||||
} else {
|
||||
console.log('disable is not support in v1 API!');
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
;(function(exports){'use strict';exports.ComponentUtils={style:function(baseUrl){if(window.VulpesCompat){window.VulpesCompat.componentStyle(this,baseUrl).catch(console.error);return;}var style=document.createElement('style');var url=baseUrl+'style.css';var self=this;style.setAttribute('scoped','');style.innerHTML='@import url('+url+');';this.appendChild(style);this.style.visibility='hidden';style.addEventListener('load',function(){if(self.shadowRoot){self.shadowRoot.appendChild(style.cloneNode(true));}
|
||||
self.style.visibility='';});}};}(window));
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
;'use strict';function getStorageIfAvailable(kind,size,success,error){var storage=navigator.getDeviceStorage(kind);storage.available().onsuccess=function(e){if(e.target.result!=='available'){if(error){error(e.target.result);}}
|
||||
else{storage.freeSpace().onsuccess=function(e){if(e.target.result<size){if(error){error(e.target.result);}}
|
||||
else{success(storage);}};}};}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
;'use strict';function getUnusedFilename(storage,name,callback){var getreq=storage.get(name);getreq.onerror=function(){callback(name);};getreq.onsuccess=function(){var version=0;var p=name.lastIndexOf('/');var dir=name.substring(0,p+1);var file=name.substring(p+1);p=file.lastIndexOf('.');if(p===-1){p=file.length;}
|
||||
var ext=file.substring(p);var base=file.substring(0,p);var parts=base.match(/^(.*)_(\d{1,2})$/);if(parts){base=parts[1];version=parseInt(parts[2]);}
|
||||
var newname=dir+base+'_'+(version+1)+ext;getUnusedFilename(storage,newname,callback);};}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
;;(function(exports){'use strict';var FontSizeUtils={_cachedContexts:{},_getCachedContext:function(fontSize,fontFamily,fontStyle){fontStyle=fontStyle||'italic';var cache=this._cachedContexts;var ctx=cache[fontSize]&&cache[fontSize][fontFamily]?cache[fontSize][fontFamily][fontStyle]:null;if(!ctx){var canvas=document.createElement('canvas');canvas.setAttribute('moz-opaque','true');canvas.setAttribute('width','1');canvas.setAttribute('height','1');ctx=canvas.getContext('2d',{willReadFrequently:true});ctx.font=fontStyle+' '+fontSize+'px '+fontFamily;if(!cache[fontSize]){cache[fontSize]={};}
|
||||
if(!cache[fontSize][fontFamily]){cache[fontSize][fontFamily]={};}
|
||||
cache[fontSize][fontFamily][fontStyle]=ctx;}
|
||||
return ctx;},resetCache:function(){this._cachedContexts={};},getFontWidth:function(string,fontSize,fontFamily,fontStyle){var ctx=this._getCachedContext(fontSize,fontFamily,fontStyle);return ctx.measureText(string).width;},getMaxFontSizeInfo:function(string,allowedSizes,fontFamily,maxWidth){var fontSize;var resultWidth;var i=allowedSizes.length-1;do{fontSize=allowedSizes[i];resultWidth=this.getFontWidth(string,fontSize,fontFamily);i--;}while(resultWidth>maxWidth&&i>=0);return{fontSize:fontSize,overflow:resultWidth>maxWidth,textWidth:resultWidth};},_overflowCountCache:-1,getOverflowCount:function(string,fontSize,fontFamily,maxWidth){var substring;var resultWidth;var overflowCount=-1;if(string.length>this._overflowCountCache){substring=string.substr(0,string.length-this._overflowCountCache);resultWidth=this.getFontWidth(substring,fontSize,fontFamily);if(resultWidth>maxWidth){overflowCount=this._overflowCountCache;}}
|
||||
do{overflowCount++;substring=string.substr(0,string.length-overflowCount);resultWidth=this.getFontWidth(substring,fontSize,fontFamily);}while(substring.length>0&&resultWidth>maxWidth);this._overflowCountCache=overflowCount;return overflowCount;},getContentWidth:function(style){var width=parseInt(style.width,10);if(style.boxSizing==='border-box'){width-=(parseInt(style.paddingRight,10)+
|
||||
parseInt(style.paddingLeft,10));}
|
||||
return width;},getStyleProperties:function(element){var style=window.getComputedStyle(element);var contentWidth=this.getContentWidth(style);if(isNaN(contentWidth)){contentWidth=0;}
|
||||
return{fontFamily:style.fontFamily,contentWidth:contentWidth,paddingRight:parseInt(style.paddingRight,10),paddingLeft:parseInt(style.paddingLeft,10),offsetLeft:element.offsetLeft};},getWindowWidth:function(){return window.innerWidth;}};exports.FontSizeUtils=FontSizeUtils;}(this));
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
;;(function(exports){'use strict';var ImageUtils=exports.ImageUtils={};const JPEG='image/jpeg';const PNG='image/png';const GIF='image/gif';const BMP='image/bmp';ImageUtils.JPEG=JPEG;ImageUtils.PNG=PNG;ImageUtils.GIF=GIF;ImageUtils.BMP=BMP;ImageUtils.getSizeAndType=function getSizeAndType(imageBlob){if(!(imageBlob instanceof Blob)){console.log('not blob');return Promise.reject(new TypeError('argument is not a Blob'));}
|
||||
return new Promise(function(resolve,reject){if(imageBlob.size<=16){reject('corrupt image file');return;}
|
||||
var bytesToRead=32*1024;if(imageBlob.type===PNG||imageBlob.type===GIF||imageBlob.type===BMP){bytesToRead=512;}
|
||||
findSizeAndType(imageBlob,bytesToRead,success,tryagain);function success(data){resolve(data);}
|
||||
function tryagain(data){if(data.type===JPEG){findSizeAndType(imageBlob,imageBlob.size,success,failure);}
|
||||
else{reject(data.error);}}
|
||||
function failure(data){reject(data.error);}});function findSizeAndType(imageBlob,amountToRead,success,failure){var slice=imageBlob.slice(0,Math.min(amountToRead,imageBlob.size));var reader=new FileReader();reader.readAsArrayBuffer(slice);reader.onloadend=function(){parseImageData(reader.result);};function parseImageData(buffer){var header=new Uint8Array(buffer,0,16);var view=new DataView(buffer);if(header[0]===0x89&&header[1]===0x50&&header[2]===0x4e&&header[3]===0x47&&header[4]===0x0d&&header[5]===0x0a&&header[6]===0x1A&&header[7]===0x0a&&header[12]===0x49&&header[13]===0x48&&header[14]===0x44&&header[15]===0x52)
|
||||
{try{success({type:PNG,width:view.getUint32(16,false),height:view.getUint32(20,false)});}
|
||||
catch(ex){failure({error:ex.toString()});}}
|
||||
else if(header[0]===0x47&&header[1]===0x49&&header[2]===0x46&&header[3]===0x38&&(header[4]===0x37||header[4]===0x39)&&header[5]===0x61)
|
||||
{try{success({type:GIF,width:view.getUint16(6,true),height:view.getUint16(8,true)});}
|
||||
catch(ex){failure({error:ex.toString()});}}
|
||||
else if(header[0]===0x42&&header[1]===0x4D&&view.getUint32(2,true)===imageBlob.size)
|
||||
{try{var width,height;if(view.getUint16(14,true)===12){width=view.getUint16(18,true);height=view.getUint16(20,true);}
|
||||
else{width=view.getUint32(18,true);height=view.getUint32(22,true);}
|
||||
success({type:BMP,width:width,height:height});}
|
||||
catch(ex){failure({error:ex.toString()});}}
|
||||
else if(header[0]===0xFF&&header[1]===0xD8){var value={type:JPEG};try{var offset=2;for(;;){if(view.getUint8(offset)!==0xFF){failure({error:'corrupt JPEG file'});}
|
||||
var segmentType=view.getUint8(offset+1);var segmentSize=view.getUint16(offset+2)+2;if((segmentType>=0xC0&&segmentType<=0xC3)||(segmentType>=0xC5&&segmentType<=0xC7)||(segmentType>=0xC9&&segmentType<=0xCB)||(segmentType>=0xCD&&segmentType<=0xCF))
|
||||
{value.height=view.getUint16(offset+5,false);value.width=view.getUint16(offset+7,false);success(value);break;}
|
||||
offset+=segmentSize;if(offset+9>view.byteLength){value.error='corrupt JPEG file';failure(value);break;}}}
|
||||
catch(ex){failure({error:ex.toString()});}}
|
||||
else{failure({error:'unknown image type'});}}}};ImageUtils.resizeAndCropToCover=function(inputImageBlob,outputWidth,outputHeight,outputType,encoderOptions)
|
||||
{if(!outputWidth||!isFinite(outputWidth)||outputWidth<=0||!outputHeight||!isFinite(outputHeight)||outputHeight<=0){return Promise.reject(new TypeError('invalid output dimensions'));}
|
||||
outputWidth=Math.round(outputWidth);outputHeight=Math.round(outputHeight);return ImageUtils.getSizeAndType(inputImageBlob).then(function resolve(data){var inputWidth=data.width;var inputHeight=data.height;if(inputWidth===outputWidth&&inputHeight===outputHeight){return inputImageBlob;}
|
||||
return resize(data);},function reject(error){return resize({});});function resize(data){var inputType=data.type;var inputWidth=data.width;var inputHeight=data.height;if(outputType&&outputType!==JPEG&&outputType!==PNG){console.warn('Ignoring unsupported outputType',outputType);outputType=undefined;}
|
||||
if(!outputType){if(inputType===JPEG||inputType===PNG){outputType=inputType;}
|
||||
else{outputType=PNG;}}
|
||||
var url=URL.createObjectURL(inputImageBlob);var mediaFragment;if(inputType===JPEG&&inputWidth>outputWidth&&inputHeight>outputHeight){var reduction=Math.max(outputWidth/inputWidth,outputHeight/inputHeight);mediaFragment=ImageUtils.Downsample.sizeNoMoreThan(reduction);}
|
||||
else{mediaFragment='';}
|
||||
return new Promise(function(resolve,reject){var offscreenImage=new Image();offscreenImage.src=url+mediaFragment;offscreenImage.onerror=function(e){cleanupImage();reject('failed to decode image');};offscreenImage.onload=function(){var actualWidth=offscreenImage.width;var actualHeight=offscreenImage.height;var widthScale=outputWidth/actualWidth;var heightScale=outputHeight/actualHeight;var scale=Math.max(widthScale,heightScale);var cropWidth=Math.round(outputWidth/scale);var cropHeight=Math.round(outputHeight/scale);var cropLeft=Math.floor((actualWidth-cropWidth)/2);var cropTop=Math.floor((actualHeight-cropHeight)/2);var canvas=document.createElement('canvas');canvas.width=outputWidth;canvas.height=outputHeight;var context=canvas.getContext('2d',{willReadFrequently:true});context.drawImage(offscreenImage,cropLeft,cropTop,cropWidth,cropHeight,0,0,outputWidth,outputHeight);cleanupImage();canvas.toBlob(function(blob){canvas.width=0;resolve(blob);},outputType,encoderOptions);};function cleanupImage(){offscreenImage.onerror=offscreenImage.onload='';offscreenImage.onload=offscreenImage.onerror=null;offscreenImage.removeAttribute('src');URL.revokeObjectURL(url);}});}};(function(exports){'use strict';function round(x){return Math.round(x*100)/100;}
|
||||
function MozSampleSize(n,scale){return Object.freeze({dimensionScale:round(scale),areaScale:round(scale*scale),toString:function(){return'#-moz-samplesize='+n;},scale:function(x){return Math.ceil(x*scale);}});}
|
||||
var NONE=Object.freeze({dimensionScale:1,areaScale:1,toString:function(){return'';},scale:function(x){return x;}});var fragments=[NONE,MozSampleSize(2,1/2),MozSampleSize(3,3/8),MozSampleSize(4,1/4),MozSampleSize(8,1/8)];function sizeAtLeast(scale){scale=round(scale);for(var i=0;i<fragments.length;i++){var f=fragments[i];if(f.dimensionScale<=scale){return f;}}
|
||||
return fragments[fragments.length-1];}
|
||||
function sizeNoMoreThan(scale){scale=round(scale);for(var i=fragments.length-1;i>=0;i--){var f=fragments[i];if(f.dimensionScale>=scale){return f;}}
|
||||
return NONE;}
|
||||
function areaAtLeast(scale){scale=round(scale);for(var i=0;i<fragments.length;i++){var f=fragments[i];if(f.areaScale<=scale){return f;}}
|
||||
return fragments[fragments.length-1];}
|
||||
function areaNoMoreThan(scale){scale=round(scale);for(var i=fragments.length-1;i>=0;i--){var f=fragments[i];if(f.areaScale>=scale){return f;}}
|
||||
return NONE;}
|
||||
exports.Downsample={sizeAtLeast:sizeAtLeast,sizeNoMoreThan:sizeNoMoreThan,areaAtLeast:areaAtLeast,areaNoMoreThan:areaNoMoreThan,NONE:NONE,MAX_SIZE_REDUCTION:1/fragments[fragments.length-1].dimensionScale,MAX_AREA_REDUCTION:1/fragments[fragments.length-1].areaScale};}(exports.ImageUtils));})(window);
|
||||
245
assets/webapps/music-oga.gaiamobile.org/shared/js/l10n.js
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
;;(function(window,undefined){'use strict';function L10nError(message,id,loc){this.name='L10nError';this.message=message;this.id=id;this.loc=loc;}
|
||||
L10nError.prototype=Object.create(Error.prototype);L10nError.prototype.constructor=L10nError;var io={_load:function(type,url,callback,sync){var xhr=new XMLHttpRequest();var needParse;if(xhr.overrideMimeType){xhr.overrideMimeType(type);}
|
||||
xhr.open('GET',url,!sync);if(type==='application/json'){if(sync){needParse=true;}else{xhr.responseType='json';}}
|
||||
xhr.addEventListener('load',function io_onload(e){if(e.target.status===200||e.target.status===0){var res=e.target.response||e.target.responseText;callback(null,needParse?JSON.parse(res):res);}else{callback(new L10nError('Not found: '+url));}});xhr.addEventListener('error',callback);xhr.addEventListener('timeout',callback);try{xhr.send(null);}catch(e){if(e.name==='NS_ERROR_FILE_NOT_FOUND'){callback(new L10nError('Not found: '+url));}else{throw e;}}},load:function(url,callback,sync){return io._load('text/plain',url,callback,sync);},loadJSON:function(url,callback,sync){return io._load('application/json',url,callback,sync);}};function EventEmitter(){}
|
||||
EventEmitter.prototype.emit=function ee_emit(){if(!this._listeners){return;}
|
||||
var args=Array.prototype.slice.call(arguments);var type=args.shift();if(!this._listeners[type]){return;}
|
||||
var typeListeners=this._listeners[type].slice();for(var i=0;i<typeListeners.length;i++){typeListeners[i].apply(this,args);}};EventEmitter.prototype.addEventListener=function ee_add(type,listener){if(!this._listeners){this._listeners={};}
|
||||
if(!(type in this._listeners)){this._listeners[type]=[];}
|
||||
this._listeners[type].push(listener);};EventEmitter.prototype.removeEventListener=function ee_rm(type,listener){if(!this._listeners){return;}
|
||||
var typeListeners=this._listeners[type];var pos=typeListeners.indexOf(listener);if(pos===-1){return;}
|
||||
typeListeners.splice(pos,1);};function getPluralRule(lang){var locales2rules={'af':3,'ak':4,'am':4,'ar':1,'asa':3,'az':0,'be':11,'bem':3,'bez':3,'bg':3,'bh':4,'bm':0,'bn':3,'bo':0,'br':20,'brx':3,'bs':11,'ca':3,'cgg':3,'chr':3,'cs':12,'cy':17,'da':3,'de':3,'dv':3,'dz':0,'ee':3,'el':3,'en':3,'eo':3,'es':3,'et':3,'eu':3,'fa':0,'ff':5,'fi':3,'fil':4,'fo':3,'fr':5,'fur':3,'fy':3,'ga':8,'gd':24,'gl':3,'gsw':3,'gu':3,'guw':4,'gv':23,'ha':3,'haw':3,'he':2,'hi':4,'hr':11,'hu':0,'id':0,'ig':0,'ii':0,'is':3,'it':3,'iu':7,'ja':0,'jmc':3,'jv':0,'ka':0,'kab':5,'kaj':3,'kcg':3,'kde':0,'kea':0,'kk':3,'kl':3,'km':0,'kn':0,'ko':0,'ksb':3,'ksh':21,'ku':3,'kw':7,'lag':18,'lb':3,'lg':3,'ln':4,'lo':0,'lt':10,'lv':6,'mas':3,'mg':4,'mk':16,'ml':3,'mn':3,'mo':9,'mr':3,'ms':0,'mt':15,'my':0,'nah':3,'naq':7,'nb':3,'nd':3,'ne':3,'nl':3,'nn':3,'no':3,'nr':3,'nso':4,'ny':3,'nyn':3,'om':3,'or':3,'pa':3,'pap':3,'pl':13,'ps':3,'pt':3,'rm':3,'ro':9,'rof':3,'ru':11,'rwk':3,'sah':0,'saq':3,'se':7,'seh':3,'ses':0,'sg':0,'sh':11,'shi':19,'sk':12,'sl':14,'sma':7,'smi':7,'smj':7,'smn':7,'sms':7,'sn':3,'so':3,'sq':3,'sr':11,'ss':3,'ssy':3,'st':3,'sv':3,'sw':3,'syr':3,'ta':3,'te':3,'teo':3,'th':0,'ti':4,'tig':3,'tk':3,'tl':4,'tn':3,'to':0,'tr':0,'ts':3,'tzm':22,'uk':11,'ur':3,'ve':3,'vi':0,'vun':3,'wa':4,'wae':3,'wo':0,'xh':3,'xog':3,'yo':0,'zh':0,'zu':3};function isIn(n,list){return list.indexOf(n)!==-1;}
|
||||
function isBetween(n,start,end){return typeof n===typeof start&&start<=n&&n<=end;}
|
||||
var pluralRules={'0':function(){return'other';},'1':function(n){if((isBetween((n%100),3,10))){return'few';}
|
||||
if(n===0){return'zero';}
|
||||
if((isBetween((n%100),11,99))){return'many';}
|
||||
if(n===2){return'two';}
|
||||
if(n===1){return'one';}
|
||||
return'other';},'2':function(n){if(n!==0&&(n%10)===0){return'many';}
|
||||
if(n===2){return'two';}
|
||||
if(n===1){return'one';}
|
||||
return'other';},'3':function(n){if(n===1){return'one';}
|
||||
return'other';},'4':function(n){if((isBetween(n,0,1))){return'one';}
|
||||
return'other';},'5':function(n){if((isBetween(n,0,2))&&n!==2){return'one';}
|
||||
return'other';},'6':function(n){if(n===0){return'zero';}
|
||||
if((n%10)===1&&(n%100)!==11){return'one';}
|
||||
return'other';},'7':function(n){if(n===2){return'two';}
|
||||
if(n===1){return'one';}
|
||||
return'other';},'8':function(n){if((isBetween(n,3,6))){return'few';}
|
||||
if((isBetween(n,7,10))){return'many';}
|
||||
if(n===2){return'two';}
|
||||
if(n===1){return'one';}
|
||||
return'other';},'9':function(n){if(n===0||n!==1&&(isBetween((n%100),1,19))){return'few';}
|
||||
if(n===1){return'one';}
|
||||
return'other';},'10':function(n){if((isBetween((n%10),2,9))&&!(isBetween((n%100),11,19))){return'few';}
|
||||
if((n%10)===1&&!(isBetween((n%100),11,19))){return'one';}
|
||||
return'other';},'11':function(n){if((isBetween((n%10),2,4))&&!(isBetween((n%100),12,14))){return'few';}
|
||||
if((n%10)===0||(isBetween((n%10),5,9))||(isBetween((n%100),11,14))){return'many';}
|
||||
if((n%10)===1&&(n%100)!==11){return'one';}
|
||||
return'other';},'12':function(n){if((isBetween(n,2,4))){return'few';}
|
||||
if(n===1){return'one';}
|
||||
return'other';},'13':function(n){if((isBetween((n%10),2,4))&&!(isBetween((n%100),12,14))){return'few';}
|
||||
if(n!==1&&(isBetween((n%10),0,1))||(isBetween((n%10),5,9))||(isBetween((n%100),12,14))){return'many';}
|
||||
if(n===1){return'one';}
|
||||
return'other';},'14':function(n){if((isBetween((n%100),3,4))){return'few';}
|
||||
if((n%100)===2){return'two';}
|
||||
if((n%100)===1){return'one';}
|
||||
return'other';},'15':function(n){if(n===0||(isBetween((n%100),2,10))){return'few';}
|
||||
if((isBetween((n%100),11,19))){return'many';}
|
||||
if(n===1){return'one';}
|
||||
return'other';},'16':function(n){if((n%10)===1&&n!==11){return'one';}
|
||||
return'other';},'17':function(n){if(n===3){return'few';}
|
||||
if(n===0){return'zero';}
|
||||
if(n===6){return'many';}
|
||||
if(n===2){return'two';}
|
||||
if(n===1){return'one';}
|
||||
return'other';},'18':function(n){if(n===0){return'zero';}
|
||||
if((isBetween(n,0,2))&&n!==0&&n!==2){return'one';}
|
||||
return'other';},'19':function(n){if((isBetween(n,2,10))){return'few';}
|
||||
if((isBetween(n,0,1))){return'one';}
|
||||
return'other';},'20':function(n){if((isBetween((n%10),3,4)||((n%10)===9))&&!(isBetween((n%100),10,19)||isBetween((n%100),70,79)||isBetween((n%100),90,99))){return'few';}
|
||||
if((n%1000000)===0&&n!==0){return'many';}
|
||||
if((n%10)===2&&!isIn((n%100),[12,72,92])){return'two';}
|
||||
if((n%10)===1&&!isIn((n%100),[11,71,91])){return'one';}
|
||||
return'other';},'21':function(n){if(n===0){return'zero';}
|
||||
if(n===1){return'one';}
|
||||
return'other';},'22':function(n){if((isBetween(n,0,1))||(isBetween(n,11,99))){return'one';}
|
||||
return'other';},'23':function(n){if((isBetween((n%10),1,2))||(n%20)===0){return'one';}
|
||||
return'other';},'24':function(n){if((isBetween(n,3,10)||isBetween(n,13,19))){return'few';}
|
||||
if(isIn(n,[2,12])){return'two';}
|
||||
if(isIn(n,[1,11])){return'one';}
|
||||
return'other';}};var index=locales2rules[lang.replace(/-.*$/,'')];if(!(index in pluralRules)){return function(){return'other';};}
|
||||
return pluralRules[index];}
|
||||
var MAX_PLACEABLES=100;var PropertiesParser={patterns:null,entryIds:null,init:function(){this.patterns={comment:/^\s*#|^\s*$/,entity:/^([^=\s]+)\s*=\s*(.*)$/,multiline:/[^\\]\\$/,index:/\{\[\s*(\w+)(?:\(([^\)]*)\))?\s*\]\}/i,unicode:/\\u([0-9a-fA-F]{1,4})/g,entries:/[^\r\n]+/g,controlChars:/\\([\\\n\r\t\b\f\{\}\"\'])/g,placeables:/\{\{\s*([^\s]*?)\s*\}\}/,};},parse:function(ctx,source){if(!this.patterns){this.init();}
|
||||
var ast=[];this.entryIds=Object.create(null);var entries=source.match(this.patterns.entries);if(!entries){return ast;}
|
||||
for(var i=0;i<entries.length;i++){var line=entries[i];if(this.patterns.comment.test(line)){continue;}
|
||||
while(this.patterns.multiline.test(line)&&i<entries.length){line=line.slice(0,-1)+entries[++i].trim();}
|
||||
var entityMatch=line.match(this.patterns.entity);if(entityMatch){try{this.parseEntity(entityMatch[1],entityMatch[2],ast);}catch(e){if(ctx){ctx._emitter.emit('parseerror',e);}else{throw e;}}}}
|
||||
return ast;},parseEntity:function(id,value,ast){var name,key;var pos=id.indexOf('[');if(pos!==-1){name=id.substr(0,pos);key=id.substring(pos+1,id.length-1);}else{name=id;key=null;}
|
||||
var nameElements=name.split('.');if(nameElements.length>2){throw new L10nError('Error in ID: "'+name+'".'+' Nested attributes are not supported.');}
|
||||
var attr;if(nameElements.length>1){name=nameElements[0];attr=nameElements[1];if(attr[0]==='$'){throw new L10nError('Attribute can\'t start with "$"',id);}}else{attr=null;}
|
||||
this.setEntityValue(name,attr,key,this.unescapeString(value),ast);},setEntityValue:function(id,attr,key,rawValue,ast){var pos,v;var value=rawValue.indexOf('{{')>-1?this.parseString(rawValue):rawValue;if(attr){pos=this.entryIds[id];if(pos===undefined){v={$i:id};if(key){v[attr]={};v[attr][key]=value;}else{v[attr]=value;}
|
||||
ast.push(v);this.entryIds[id]=ast.length-1;return;}
|
||||
if(key){if(typeof(ast[pos][attr])==='string'){ast[pos][attr]={$x:this.parseIndex(ast[pos][attr]),$v:{}};}
|
||||
ast[pos][attr].$v[key]=value;return;}
|
||||
ast[pos][attr]=value;return;}
|
||||
if(key){pos=this.entryIds[id];if(pos===undefined){v={};v[key]=value;ast.push({$i:id,$v:v});this.entryIds[id]=ast.length-1;return;}
|
||||
if(typeof(ast[pos].$v)==='string'){ast[pos].$x=this.parseIndex(ast[pos].$v);ast[pos].$v={};}
|
||||
ast[pos].$v[key]=value;return;}
|
||||
ast.push({$i:id,$v:value});this.entryIds[id]=ast.length-1;},parseString:function(str){var chunks=str.split(this.patterns.placeables);var complexStr=[];var len=chunks.length;var placeablesCount=(len-1)/2;if(placeablesCount>=MAX_PLACEABLES){throw new L10nError('Too many placeables ('+placeablesCount+', max allowed is '+MAX_PLACEABLES+')');}
|
||||
for(var i=0;i<chunks.length;i++){if(chunks[i].length===0){continue;}
|
||||
if(i%2===1){complexStr.push({t:'idOrVar',v:chunks[i]});}else{complexStr.push(chunks[i]);}}
|
||||
return complexStr;},unescapeString:function(str){if(str.lastIndexOf('\\')!==-1){str=str.replace(this.patterns.controlChars,'$1');}
|
||||
return str.replace(this.patterns.unicode,function(match,token){return unescape('%u'+'0000'.slice(token.length)+token);});},parseIndex:function(str){var match=str.match(this.patterns.index);if(!match){throw new L10nError('Malformed index');}
|
||||
if(match[2]){return[{t:'idOrVar',v:match[1]},match[2]];}else{return[{t:'idOrVar',v:match[1]}];}}};var KNOWN_MACROS=['plural'];var MAX_PLACEABLE_LENGTH=2500;var rePlaceables=/\{\{\s*(.+?)\s*\}\}/g;var nonLatin1=/[^\x01-\xFF]/;var FSI='\u2068';var PDI='\u2069';function createEntry(node,env){var keys=Object.keys(node);if(typeof node.$v==='string'&&keys.length===2){return node.$v;}
|
||||
var attrs;for(var i=0,key;key=keys[i];i++){if(key[0]==='$'){continue;}
|
||||
if(!attrs){attrs=Object.create(null);}
|
||||
attrs[key]=createAttribute(node[key],env,node.$i+'.'+key);}
|
||||
return{id:node.$i,value:node.$v!==undefined?node.$v:null,index:node.$x||null,attrs:attrs||null,env:env,dirty:false};}
|
||||
function createAttribute(node,env,id){if(typeof node==='string'){return node;}
|
||||
return{id:id,value:node.$v||(node!==undefined?node:null),index:node.$x||null,env:env,dirty:false};}
|
||||
function format(args,entity){if(typeof entity==='string'){return[{},entity];}
|
||||
if(entity.dirty){throw new L10nError('Cyclic reference detected: '+entity.id);}
|
||||
entity.dirty=true;var rv;try{rv=resolveValue({},args,entity.env,entity.value,entity.index);}finally{entity.dirty=false;}
|
||||
return rv;}
|
||||
function resolveIdentifier(args,env,id){if(KNOWN_MACROS.indexOf(id)>-1){return[{},env['__'+id]];}
|
||||
if(args&&args.hasOwnProperty(id)){if(typeof args[id]==='string'||(typeof args[id]==='number'&&!isNaN(args[id]))){return[{},args[id]];}else{throw new L10nError('Arg must be a string or a number: '+id);}}
|
||||
if(id in env&&id!=='__proto__'){return format(args,env[id]);}
|
||||
throw new L10nError('Unknown reference: '+id);}
|
||||
function subPlaceable(locals,args,env,id){var res;try{res=resolveIdentifier(args,env,id);}catch(err){return[{error:err},'{{ '+id+' }}'];}
|
||||
var value=res[1];if(typeof value==='number'){return res;}
|
||||
if(typeof value==='string'){if(value.length>=MAX_PLACEABLE_LENGTH){throw new L10nError('Too many characters in placeable ('+
|
||||
value.length+', max allowed is '+
|
||||
MAX_PLACEABLE_LENGTH+')');}
|
||||
if(locals.contextIsNonLatin1||value.match(nonLatin1)){res[1]=FSI+value+PDI;}
|
||||
return res;}
|
||||
return[{},'{{ '+id+' }}'];}
|
||||
function interpolate(locals,args,env,arr){return arr.reduce(function(prev,cur){if(typeof cur==='string'){return[prev[0],prev[1]+cur];}else if(cur.t==='idOrVar'){var placeable=subPlaceable(locals,args,env,cur.v);return[prev[0],prev[1]+placeable[1]];}},[locals,'']);}
|
||||
function resolveSelector(args,env,expr,index){var selectorName=index[0].v;var selector=resolveIdentifier(args,env,selectorName)[1];if(typeof selector!=='function'){return selector;}
|
||||
var argValue=index[1]?resolveIdentifier(args,env,index[1])[1]:undefined;if(selector===env.__plural){if(argValue===0&&'zero'in expr){return'zero';}
|
||||
if(argValue===1&&'one'in expr){return'one';}
|
||||
if(argValue===2&&'two'in expr){return'two';}}
|
||||
return selector(argValue);}
|
||||
function resolveValue(locals,args,env,expr,index){if(!expr){return[locals,expr];}
|
||||
if(typeof expr==='string'||typeof expr==='boolean'||typeof expr==='number'){return[locals,expr];}
|
||||
if(Array.isArray(expr)){locals.contextIsNonLatin1=expr.some(function($_){return typeof($_)==='string'&&$_.match(nonLatin1);});return interpolate(locals,args,env,expr);}
|
||||
if(index){var selector=resolveSelector(args,env,expr,index);if(expr.hasOwnProperty(selector)){return resolveValue(locals,args,env,expr[selector]);}}
|
||||
if('other'in expr){return resolveValue(locals,args,env,expr.other);}
|
||||
throw new L10nError('Unresolvable value');}
|
||||
var Resolver={createEntry:createEntry,format:format,rePlaceables:rePlaceables};function walkContent(node,fn){if(typeof node==='string'){return fn(node);}
|
||||
if(node.t==='idOrVar'){return node;}
|
||||
var rv=Array.isArray(node)?[]:{};var keys=Object.keys(node);for(var i=0,key;(key=keys[i]);i++){if(key==='$i'||key==='$x'){rv[key]=node[key];}else{rv[key]=walkContent(node[key],fn);}}
|
||||
return rv;}
|
||||
var reAlphas=/[a-zA-Z]/g;var reVowels=/[aeiouAEIOU]/g;var ACCENTED_MAP='\u0226\u0181\u0187\u1E12\u1E16\u0191\u0193\u0126\u012A'+'\u0134\u0136\u013F\u1E3E\u0220\u01FE\u01A4\u024A\u0158'+'\u015E\u0166\u016C\u1E7C\u1E86\u1E8A\u1E8E\u1E90'+'[\\]^_`'+'\u0227\u0180\u0188\u1E13\u1E17\u0192\u0260\u0127\u012B'+'\u0135\u0137\u0140\u1E3F\u019E\u01FF\u01A5\u024B\u0159'+'\u015F\u0167\u016D\u1E7D\u1E87\u1E8B\u1E8F\u1E91';var FLIPPED_MAP='\u2200\u0510\u2183p\u018E\u025F\u05E4HI\u017F'+'\u04FC\u02E5WNO\u0500\xD2\u1D1AS\u22A5\u2229\u0245'+'\uFF2DX\u028EZ'+'[\\]\u1D65_,'+'\u0250q\u0254p\u01DD\u025F\u0183\u0265\u0131\u027E'+'\u029E\u0285\u026Fuodb\u0279s\u0287n\u028C\u028Dx\u028Ez';function makeLonger(val){return val.replace(reVowels,function(match){return match+match.toLowerCase();});}
|
||||
function replaceChars(map,val){return val.replace(reAlphas,function(match){return map.charAt(match.charCodeAt(0)-65);});}
|
||||
var reWords=/[^\W0-9_]+/g;function makeRTL(val){return val.replace(reWords,function(match){return'\u202e'+match+'\u202c';});}
|
||||
var reExcluded=/(%[EO]?\w|\{\s*.+?\s*\}|&[#\w]+;|<\s*.+?\s*>)/;function mapContent(fn,val){if(!val){return val;}
|
||||
var parts=val.split(reExcluded);var modified=parts.map(function(part){if(reExcluded.test(part)){return part;}
|
||||
return fn(part);});return modified.join('');}
|
||||
function Pseudo(id,name,charMap,modFn){this.id=id;this.translate=mapContent.bind(null,function(val){return replaceChars(charMap,modFn(val));});this.name=this.translate(name);}
|
||||
var PSEUDO={'fr-x-psaccent':new Pseudo('fr-x-psaccent','Runtime Accented',ACCENTED_MAP,makeLonger),'ar-x-psbidi':new Pseudo('ar-x-psbidi','Runtime Bidi',FLIPPED_MAP,makeRTL)};function Locale(id,ctx){this.id=id;this.ctx=ctx;this.isReady=false;this.entries=Object.create(null);this.entries.__plural=getPluralRule(this.isPseudo()?this.ctx.defaultLocale:id);}
|
||||
Locale.prototype.isPseudo=function(){return this.ctx.qps.indexOf(this.id)!==-1;};var bindingsIO={extra:function(id,ver,path,type,callback,errback){if(type==='properties'){type='text';}
|
||||
navigator.mozApps.getLocalizationResource(id,ver,path,type).then(callback.bind(null,null),errback);},app:function(id,ver,path,type,callback,errback,sync){switch(type){case'properties':io.load(path,callback,sync);break;case'json':io.loadJSON(path,callback,sync);break;}},};Locale.prototype.build=function L_build(callback){var sync=!callback;var ctx=this.ctx;var self=this;var l10nLoads=ctx.resLinks.length;function onL10nLoaded(err){if(err){ctx._emitter.emit('fetcherror',err);}
|
||||
if(--l10nLoads<=0){self.isReady=true;if(callback){callback();}}}
|
||||
if(l10nLoads===0){onL10nLoaded();return;}
|
||||
function onJSONLoaded(err,json){if(!err&&json){self.addAST(json);}
|
||||
onL10nLoaded(err);}
|
||||
function onPropLoaded(err,source){if(!err&&source){var ast=PropertiesParser.parse(ctx,source);self.addAST(ast);}
|
||||
onL10nLoaded(err);}
|
||||
var idToFetch=this.isPseudo()?ctx.defaultLocale:this.id;var appVersion=null;var source='app';if(typeof(navigator)!=='undefined'){source=navigator.mozL10n._config.localeSources[this.id]||'app';appVersion=navigator.mozL10n._config.appVersion;}
|
||||
for(var i=0;i<ctx.resLinks.length;i++){var resLink=decodeURI(ctx.resLinks[i]);var path=resLink.replace('{locale}',idToFetch);var type=path.substr(path.lastIndexOf('.')+1);var cb;switch(type){case'json':cb=onJSONLoaded;break;case'properties':cb=onPropLoaded;break;}
|
||||
bindingsIO[source](this.id,appVersion,path,type,cb,onL10nLoaded,sync);}};function createPseudoEntry(node,entries){return Resolver.createEntry(walkContent(node,PSEUDO[this.id].translate),entries);}
|
||||
Locale.prototype.addAST=function(ast){var createEntry=this.isPseudo()?createPseudoEntry.bind(this):Resolver.createEntry;for(var i=0;i<ast.length;i++){this.entries[ast[i].$i]=createEntry(ast[i],this.entries);}};function Context(id){this.id=id;this.isReady=false;this.isLoading=false;this.defaultLocale='en-US';this.availableLocales=[];this.supportedLocales=[];this.qps=[];this.resLinks=[];this.locales={};this._emitter=new EventEmitter();this._ready=new Promise(this.once.bind(this));}
|
||||
function reportMissing(id,err){this._emitter.emit('notfounderror',err);return id;}
|
||||
function getWithFallback(id){var cur=0;var loc;var locale;while(loc=this.supportedLocales[cur]){locale=this.getLocale(loc);if(!locale.isReady){locale.build(null);}
|
||||
var entry=locale.entries[id];if(entry===undefined){cur++;reportMissing.call(this,id,new L10nError('"'+id+'"'+' not found in '+loc+' in '+this.id,id,loc));continue;}
|
||||
return entry;}
|
||||
throw new L10nError('"'+id+'"'+' missing from all supported locales in '+this.id,id);}
|
||||
function formatTuple(args,entity){try{return Resolver.format(args,entity);}catch(err){this._emitter.emit('resolveerror',err);var locals={error:err};return[locals,entity.id];}}
|
||||
function formatValue(args,entity){if(typeof entity==='string'){return entity;}
|
||||
return formatTuple.call(this,args,entity)[1];}
|
||||
function formatEntity(args,entity){var entityTuple=formatTuple.call(this,args,entity);var value=entityTuple[1];var formatted={value:value,attrs:null,};if(entity.attrs){formatted.attrs=Object.create(null);}
|
||||
for(var key in entity.attrs){var attrTuple=formatTuple.call(this,args,entity.attrs[key]);formatted.attrs[key]=attrTuple[1];}
|
||||
return formatted;}
|
||||
function formatAsync(fn,id,args){return this._ready.then(getWithFallback.bind(this,id)).then(fn.bind(this,args),reportMissing.bind(this,id));}
|
||||
Context.prototype.formatValue=function(id,args){return formatAsync.call(this,formatValue,id,args);};Context.prototype.formatEntity=function(id,args){return formatAsync.call(this,formatEntity,id,args);};function legacyGet(fn,id,args){if(!this.isReady){throw new L10nError('Context not ready');}
|
||||
var entry;try{entry=getWithFallback.call(this,id);}catch(err){if(err.loc){throw err;}
|
||||
reportMissing.call(this,id,err);return'';}
|
||||
return fn.call(this,args,entry);}
|
||||
Context.prototype.get=function(id,args){return legacyGet.call(this,formatValue,id,args);};Context.prototype.getEntity=function(id,args){return legacyGet.call(this,formatEntity,id,args);};Context.prototype.getLocale=function getLocale(code){var locales=this.locales;if(locales[code]){return locales[code];}
|
||||
return locales[code]=new Locale(code,this);};function negotiate(available,requested,defaultLocale){var supportedLocale;for(var i=0;i<requested.length;i++){var locale=requested[i];if(available.indexOf(locale)!==-1){supportedLocale=locale;break;}}
|
||||
if(!supportedLocale||supportedLocale===defaultLocale){return[defaultLocale];}
|
||||
return[supportedLocale,defaultLocale];}
|
||||
function freeze(supported){var locale=this.getLocale(supported[0]);if(locale.isReady){setReady.call(this,supported);}else{locale.build(setReady.bind(this,supported));}}
|
||||
function setReady(supported){this.supportedLocales=supported;this.isReady=true;this._emitter.emit('ready');}
|
||||
Context.prototype.registerLocales=function(defLocale,available){if(defLocale){this.defaultLocale=defLocale;}
|
||||
this.availableLocales=[this.defaultLocale];this.qps=Object.keys(PSEUDO);if(available){for(var i=0,loc;loc=available[i];i++){if(this.availableLocales.indexOf(loc)===-1){this.availableLocales.push(loc);var pos=this.qps.indexOf(loc);if(pos!==-1){this.qps.splice(pos,1);}}}}};Context.prototype.requestLocales=function requestLocales(){if(this.isLoading&&!this.isReady){throw new L10nError('Context not ready');}
|
||||
this.isLoading=true;var requested=Array.prototype.slice.call(arguments);if(requested.length===0){throw new L10nError('No locales requested');}
|
||||
var supported=negotiate(this.availableLocales.concat(this.qps),requested,this.defaultLocale);if(this.supportedLocales[0]!==supported[0]){freeze.call(this,supported);}};Context.prototype.addEventListener=function(type,listener){this._emitter.addEventListener(type,listener);};Context.prototype.removeEventListener=function(type,listener){this._emitter.removeEventListener(type,listener);};Context.prototype.ready=function(callback){if(this.isReady){setTimeout(callback);}
|
||||
this.addEventListener('ready',callback);};Context.prototype.once=function(callback){if(this.isReady){setTimeout(callback);return;}
|
||||
var callAndRemove=(function(){this.removeEventListener('ready',callAndRemove);callback();}).bind(this);this.addEventListener('ready',callAndRemove);};var allowed={elements:['a','em','strong','small','s','cite','q','dfn','abbr','data','time','code','var','samp','kbd','sub','sup','i','b','u','mark','ruby','rt','rp','bdi','bdo','span','br','wbr'],attributes:{global:['title','aria-label','aria-valuetext','aria-moz-hint'],a:['download'],area:['download','alt'],input:['alt','placeholder'],menuitem:['label'],menu:['label'],optgroup:['label'],option:['label'],track:['label'],img:['alt'],textarea:['placeholder'],th:['abbr']}};var rtlList=['ar','he','fa','ps','ar-x-psbidi','ur'];var nodeObserver=null;var pendingElements=null;var moConfig={attributes:true,characterData:false,childList:true,subtree:true,attributeFilter:['data-l10n-id','data-l10n-args']};navigator.mozL10n={ctx:null,get:function get(id,ctxdata){return navigator.mozL10n.ctx.get(id,ctxdata);},formatValue:function(id,ctxdata){return navigator.mozL10n.ctx.formatValue(id,ctxdata);},formatEntity:function(id,ctxdata){return navigator.mozL10n.ctx.formatEntity(id,ctxdata);},translateFragment:function(fragment){return translateFragment.call(navigator.mozL10n,fragment);},setAttributes:setL10nAttributes,getAttributes:getL10nAttributes,ready:function ready(callback){return navigator.mozL10n.ctx.ready(callback);},once:function once(callback){return navigator.mozL10n.ctx.once(callback);},get readyState(){return navigator.mozL10n.ctx.isReady?'complete':'loading';},language:{set code(lang){navigator.mozL10n.ctx.requestLocales(lang);},get code(){return navigator.mozL10n.ctx.supportedLocales[0];},get direction(){return getDirection(navigator.mozL10n.ctx.supportedLocales[0]);}},qps:PSEUDO,_config:{appVersion:null,localeSources:Object.create(null),isPretranslated:false,},_getInternalAPI:function(){return{Error:L10nError,Context:Context,Locale:Locale,Resolver:Resolver,getPluralRule:getPluralRule,rePlaceables:rePlaceables,translateDocument:translateDocument,onMetaInjected:onMetaInjected,PropertiesParser:PropertiesParser,walkContent:walkContent,buildLocaleList:buildLocaleList};}};function getDirection(lang){return(rtlList.indexOf(lang)>=0)?'rtl':'ltr';}
|
||||
var readyStates={loading:0,interactive:1,complete:2};function whenInteractive(callback){if(readyStates[document.readyState]>=readyStates.interactive){callback();return;}
|
||||
document.addEventListener('readystatechange',function l10n_onrsc(){if(readyStates[document.readyState]>=readyStates.interactive){document.removeEventListener('readystatechange',l10n_onrsc);callback();}});}
|
||||
function initObserver(){nodeObserver=new MutationObserver(onMutations.bind(navigator.mozL10n));nodeObserver.observe(document,moConfig);}
|
||||
function init(pretranslate){if(!pretranslate){initObserver();}
|
||||
initResources.call(navigator.mozL10n);}
|
||||
function initResources(){var meta={};var nodes=document.head.querySelectorAll('link[rel="localization"],'+'meta[name="availableLanguages"],'+'meta[name="defaultLanguage"],'+'meta[name="appVersion"],'+'script[type="application/l10n"]');for(var i=0,node;node=nodes[i];i++){var type=node.getAttribute('rel')||node.nodeName.toLowerCase();switch(type){case'localization':this.ctx.resLinks.push(node.getAttribute('href'));break;case'meta':onMetaInjected.call(this,node,meta);break;case'script':onScriptInjected.call(this,node);break;}}
|
||||
var additionalLanguagesPromise;if(navigator.mozApps&&navigator.mozApps.getAdditionalLanguages){additionalLanguagesPromise=navigator.mozApps.getAdditionalLanguages().catch(function(e){console.error('Error while loading getAdditionalLanguages',e);});document.addEventListener('additionallanguageschange',function(evt){registerLocales.call(this,meta,evt.detail);this.ctx.requestLocales.apply(this.ctx,navigator.languages||[navigator.language]);}.bind(this));}else{additionalLanguagesPromise=Promise.resolve();}
|
||||
additionalLanguagesPromise.then(function(extraLangs){registerLocales.call(this,meta,extraLangs);initLocale.call(this);}.bind(this));}
|
||||
function registerLocales(meta,extraLangs){var locales=buildLocaleList.call(this,meta,extraLangs);navigator.mozL10n._config.localeSources=locales[1];this.ctx.registerLocales(locales[0],Object.keys(locales[1]));}
|
||||
function getMatchingLangpack(appVersion,langpacks){for(var i=0,langpack;(langpack=langpacks[i]);i++){if(langpack.target===appVersion){return langpack;}}
|
||||
return null;}
|
||||
function buildLocaleList(meta,extraLangs){var loc,lp;var localeSources=Object.create(null);var defaultLocale=meta.defaultLanguage||this.ctx.defaultLocale;if(meta.availableLanguages){for(loc in meta.availableLanguages){localeSources[loc]='app';}}
|
||||
if(extraLangs){for(loc in extraLangs){lp=getMatchingLangpack(this._config.appVersion,extraLangs[loc]);if(!lp){continue;}
|
||||
if(!(loc in localeSources)||!meta.availableLanguages[loc]||parseInt(lp.revision)>meta.availableLanguages[loc]){localeSources[loc]='extra';}}}
|
||||
if(!(defaultLocale in localeSources)){localeSources[defaultLocale]='app';}
|
||||
return[defaultLocale,localeSources];}
|
||||
function splitAvailableLanguagesString(str){var langs={};str.split(',').forEach(function(lang){lang=lang.trim().split(':');langs[lang[0]]=parseInt(lang[1]);});return langs;}
|
||||
function onMetaInjected(node,meta){switch(node.getAttribute('name')){case'availableLanguages':meta.availableLanguages=splitAvailableLanguagesString(node.getAttribute('content'));break;case'defaultLanguage':meta.defaultLanguage=node.getAttribute('content');break;case'appVersion':navigator.mozL10n._config.appVersion=node.getAttribute('content');break;}}
|
||||
function onScriptInjected(node){var lang=node.getAttribute('lang');var locale=this.ctx.getLocale(lang);locale.addAST(JSON.parse(node.textContent));}
|
||||
function initLocale(){this.ctx.requestLocales.apply(this.ctx,navigator.languages||[navigator.language]);window.addEventListener('languagechange',function l10n_langchange(){this.ctx.requestLocales.apply(this.ctx,navigator.languages||[navigator.language]);}.bind(this));}
|
||||
function localizeMutations(mutations){var mutation;var targets=new Set();for(var i=0;i<mutations.length;i++){mutation=mutations[i];if(mutation.type==='childList'){var addedNode;for(var j=0;j<mutation.addedNodes.length;j++){addedNode=mutation.addedNodes[j];if(addedNode.nodeType!==Node.ELEMENT_NODE){continue;}
|
||||
targets.add(addedNode);}}
|
||||
if(mutation.type==='attributes'){targets.add(mutation.target);}}
|
||||
targets.forEach(function(target){if(target.childElementCount){translateFragment.call(this,target);}else if(target.hasAttribute('data-l10n-id')){translateElement.call(this,target);}},this);}
|
||||
function onMutations(mutations,self){self.disconnect();localizeMutations.call(this,mutations);self.observe(document,moConfig);}
|
||||
function onReady(){if(!navigator.mozL10n._config.isPretranslated){translateDocument.call(this);}
|
||||
navigator.mozL10n._config.isPretranslated=false;if(pendingElements){for(var i=0,element;element=pendingElements[i];i++){translateElement.call(this,element);}
|
||||
pendingElements=null;}
|
||||
if(!nodeObserver){initObserver();}
|
||||
fireLocalizedEvent.call(this);}
|
||||
function fireLocalizedEvent(){var event=new CustomEvent('localized',{'bubbles':false,'cancelable':false,'detail':{'language':this.ctx.supportedLocales[0]}});window.dispatchEvent(event);}
|
||||
var reOverlay=/<|&#?\w+;/;var reHtml=/[&<>]/g;var htmlEntities={'&':'&','<':'<','>':'>',};function translateDocument(){document.documentElement.lang=this.language.code;document.documentElement.dir=this.language.direction;translateFragment.call(this,document.documentElement);}
|
||||
function translateFragment(element){if(typeof element.hasAttribute==='function'&&element.hasAttribute('data-l10n-id')){translateElement.call(this,element);}
|
||||
var nodes=getTranslatableChildren(element);for(var i=0;i<nodes.length;i++){translateElement.call(this,nodes[i]);}}
|
||||
function setL10nAttributes(element,id,args){element.setAttribute('data-l10n-id',id);if(args){element.setAttribute('data-l10n-args',JSON.stringify(args));}}
|
||||
function getL10nAttributes(element){return{id:element.getAttribute('data-l10n-id'),args:JSON.parse(element.getAttribute('data-l10n-args'))};}
|
||||
function getTranslatableChildren(element){return element?element.querySelectorAll('*[data-l10n-id]'):[];}
|
||||
function camelCaseToDashed(string){if(string==='ariaValueText'){return'aria-valuetext';}
|
||||
return string.replace(/[A-Z]/g,function(match){return'-'+match.toLowerCase();}).replace(/^-/,'');}
|
||||
function escapeL10nArgs(match){return htmlEntities[match];}
|
||||
function translateElement(element){if(!this.ctx.isReady){if(!pendingElements){pendingElements=[];}
|
||||
pendingElements.push(element);return;}
|
||||
var l10nId=element.getAttribute('data-l10n-id');if(!l10nId){return false;}
|
||||
var l10nArgs=element.getAttribute('data-l10n-args');var entity=this.ctx.getEntity(l10nId,l10nArgs?JSON.parse(l10nArgs.replace(reHtml,escapeL10nArgs)):undefined);var value=entity.value;if(typeof value==='string'){if(!reOverlay.test(value)){element.textContent=value;}else{var translation=element.ownerDocument.createElement('template');translation.innerHTML=value;overlayElement(element,translation.content);}}
|
||||
for(var key in entity.attrs){var attrName=camelCaseToDashed(key);if(isAttrAllowed({name:attrName},element)){element.setAttribute(attrName,entity.attrs[key]);}}}
|
||||
function overlayElement(sourceElement,translationElement){var result=translationElement.ownerDocument.createDocumentFragment();var k,attr;var childElement;while((childElement=translationElement.childNodes[0])){translationElement.removeChild(childElement);if(childElement.nodeType===Node.TEXT_NODE){result.appendChild(childElement);continue;}
|
||||
var index=getIndexOfType(childElement);var sourceChild=getNthElementOfType(sourceElement,childElement,index);if(sourceChild){overlayElement(sourceChild,childElement);result.appendChild(sourceChild);continue;}
|
||||
if(isElementAllowed(childElement)){var sanitizedChild=childElement.ownerDocument.createElement(childElement.nodeName);overlayElement(sanitizedChild,childElement);result.appendChild(sanitizedChild);continue;}
|
||||
result.appendChild(document.createTextNode(childElement.textContent));}
|
||||
sourceElement.textContent='';sourceElement.appendChild(result);if(translationElement.attributes){for(k=0,attr;(attr=translationElement.attributes[k]);k++){if(isAttrAllowed(attr,sourceElement)){sourceElement.setAttribute(attr.name,attr.value);}}}}
|
||||
function isElementAllowed(element){return allowed.elements.indexOf(element.tagName.toLowerCase())!==-1;}
|
||||
function isAttrAllowed(attr,element){var attrName=attr.name.toLowerCase();var tagName=element.tagName.toLowerCase();if(allowed.attributes.global.indexOf(attrName)!==-1){return true;}
|
||||
if(!allowed.attributes[tagName]){return false;}
|
||||
if(allowed.attributes[tagName].indexOf(attrName)!==-1){return true;}
|
||||
if(tagName==='input'&&attrName==='value'){var type=element.type.toLowerCase();if(type==='submit'||type==='button'||type==='reset'){return true;}}
|
||||
return false;}
|
||||
function getNthElementOfType(context,element,index){var nthOfType=0;for(var i=0,child;child=context.children[i];i++){if(child.nodeType===Node.ELEMENT_NODE&&child.tagName===element.tagName){if(nthOfType===index){return child;}
|
||||
nthOfType++;}}
|
||||
return null;}
|
||||
function getIndexOfType(element){var index=0;var child;while((child=element.previousElementSibling)){if(child.tagName===element.tagName){index++;}}
|
||||
return index;}
|
||||
var DEBUG=false;navigator.mozL10n.ctx=new Context(window.document?document.URL:null);navigator.mozL10n.ctx.ready(onReady.bind(navigator.mozL10n));navigator.mozL10n.ctx.addEventListener('notfounderror',function reportMissingEntity(e){if(DEBUG||e.loc==='en-US'){console.warn(e.toString());}});if(DEBUG){navigator.mozL10n.ctx.addEventListener('fetcherror',console.error.bind(console));navigator.mozL10n.ctx.addEventListener('parseerror',console.error.bind(console));navigator.mozL10n.ctx.addEventListener('resolveerror',console.error.bind(console));}
|
||||
if(window.document){navigator.mozL10n._config.isPretranslated=document.documentElement.lang===navigator.language;var forcePretranslate=!navigator.mozL10n._config.isPretranslated;whenInteractive(init.bind(navigator.mozL10n,forcePretranslate));}
|
||||
document.l10n={setAttributes:navigator.mozL10n.setAttributes,getAttributes:navigator.mozL10n.getAttributes,formatValue:function(id,args){return navigator.mozL10n.formatValue(id,args);},translateFragment:function(frag){return Promise.resolve(navigator.mozL10n.translateFragment(frag));},ready:new Promise(function(resolve){navigator.mozL10n.once(resolve);}),formatValues:function(){var keys=arguments;var resp=keys.map(function(key){if(Array.isArray(key)){return navigator.mozL10n.formatValue(key[0],key[1]);}
|
||||
return navigator.mozL10n.formatValue(key);});return Promise.all(resp);},requestLanguages:function(langs){navigator.mozL10n.ctx.requestLocales.apply(navigator.mozL10n.ctx,langs);},pseudo:{'fr-x-psaccent':{getName:function(){return Promise.resolve(navigator.mozL10n.qps['fr-x-psaccent'].name);},processString:function(s){return Promise.resolve(navigator.mozL10n.qps['fr-x-psaccent'].translate(s));}},'ar-x-psbidi':{getName:function(){return Promise.resolve(navigator.mozL10n.qps['ar-x-psbidi'].name);},processString:function(s){return Promise.resolve(navigator.mozL10n.qps['ar-x-psbidi'].translate(s));}}},};navigator.mozL10n.ready(function(){document.documentElement.setAttribute('langs',navigator.mozL10n.ctx.supportedLocales.join(' '));});navigator.mozL10n.once(function(){window.addEventListener('localized',function(){document.dispatchEvent(new CustomEvent('DOMRetranslated',{bubbles:false,cancelable:false}));});});})(this);
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
;;'use strict';var LazyLoader=(function(){function LazyLoader(){this._loaded={};this._isLoading={};}
|
||||
LazyLoader.prototype={_js:function(file,callback){var script=document.createElement('script');script.src=file;script.async=false;script.addEventListener('load',callback);document.head.appendChild(script);this._isLoading[file]=script;},_css:function(file,callback){var style=document.createElement('link');style.type='text/css';style.rel='stylesheet';style.href=file;document.head.appendChild(style);callback();},_html:function(domNode,callback){if(domNode.getAttribute('is')){this.load(['/shared/js/html_imports.js'],function(){HtmlImports.populate(callback);}.bind(this));return;}
|
||||
for(var i=0;i<domNode.childNodes.length;i++){if(domNode.childNodes[i].nodeType==document.COMMENT_NODE){domNode.innerHTML=domNode.childNodes[i].nodeValue;break;}}
|
||||
window.dispatchEvent(new CustomEvent('lazyload',{detail:domNode}));callback();},getJSON:function(file,mozSystem){return new Promise(function(resolve,reject){var xhr;if(mozSystem){xhr=new XMLHttpRequest({mozSystem:true});}else{xhr=new XMLHttpRequest();}
|
||||
xhr.open('GET',file,true);xhr.responseType='json';xhr.onerror=function(error){reject(error);};xhr.onload=function(){if(xhr.response!==null){resolve(xhr.response);}else{reject(new Error('No valid JSON object was found ('+
|
||||
xhr.status+' '+xhr.statusText+')'));}};xhr.send();});},load:function(files,callback){var deferred={};deferred.promise=new Promise(resolve=>{deferred.resolve=resolve;});if(!Array.isArray(files)){files=[files];}
|
||||
var loadsRemaining=files.length,self=this;function perFileCallback(file){if(self._isLoading[file]){delete self._isLoading[file];}
|
||||
self._loaded[file]=true;if(--loadsRemaining===0){deferred.resolve();if(callback){callback();}}}
|
||||
for(var i=0;i<files.length;i++){var file=files[i];if(this._loaded[file.id||file]){perFileCallback(file);}else if(this._isLoading[file]){this._isLoading[file].addEventListener('load',perFileCallback.bind(null,file));}else{var method,idx;if(typeof file==='string'){method=file.match(/\.([^.]+)$/)[1];idx=file;}else{method='html';idx=file.id;}
|
||||
this['_'+method](file,perFileCallback.bind(null,idx));}}
|
||||
return deferred.promise;}};return new LazyLoader();}());
|
||||
|
|
@ -0,0 +1,379 @@
|
|||
/* globals BluetoothHelper */
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Media Remote Controls
|
||||
*
|
||||
* For media players, like music and video apps should support the capabilities
|
||||
* to receive and interact with the remote media commands from the connected
|
||||
* device/client, it might be a bluetooth device that supports A2DP and AVRCP,
|
||||
* or a remote client, such as the controls in Lock Screen/Utility tray, which
|
||||
* in the system app and uses the IAC.
|
||||
*
|
||||
* Since both AVRCP and IAC use system message to communication, this module
|
||||
* is designed for handling all the remote commands from system message. With
|
||||
* this module, players can just set the command listeners to the corresponding
|
||||
* commands, they might be the common media actions that a player should have,
|
||||
* so a player that uses this module doesn't need to write duplicate logic on
|
||||
* handling the same commands from the different requesters, and doesn't need
|
||||
* to care about where the requests are from.
|
||||
*
|
||||
* More, this module also handle the bluetooth states because to receive the
|
||||
* remote request or send the metadata and play status depends on the bluetooth
|
||||
* availability and the connection of A2DP, the player that uses the module
|
||||
* will automatically receive the requests or send the play information to the
|
||||
* remote client when the bluetooth states change.
|
||||
*
|
||||
*/
|
||||
|
||||
// Commands for AVRCP.
|
||||
var AVRCP = {
|
||||
PLAY_PRESS: 'media-play-button-press',
|
||||
PLAY_RELEASE: 'media-play-button-release',
|
||||
PAUSE_PRESS: 'media-pause-button-press',
|
||||
PAUSE_RELEASE: 'media-pause-button-release',
|
||||
PLAY_PAUSE_PRESS: 'media-play-pause-button-press',
|
||||
PLAY_PAUSE_RELEASE: 'media-play-pause-button-release',
|
||||
STOP_PRESS: 'media-stop-button-press',
|
||||
STOP_RELEASE: 'media-stop-button-release',
|
||||
NEXT_PRESS: 'media-next-track-button-press',
|
||||
NEXT_RELEASE: 'media-next-track-button-release',
|
||||
PREVIOUS_PRESS: 'media-previous-track-button-press',
|
||||
PREVIOUS_RELEASE: 'media-previous-track-button-release',
|
||||
FAST_FORWARD_PRESS: 'media-fast-forward-button-press',
|
||||
FAST_FORWARD_RELEASE: 'media-fast-forward-button-release',
|
||||
REWIND_PRESS: 'media-rewind-button-press',
|
||||
REWIND_RELEASE: 'media-rewind-button-release'
|
||||
};
|
||||
|
||||
// Commands for Inter-App Communication.
|
||||
var IAC = {
|
||||
PLAY_PRESS: 'play',
|
||||
PLAY_PAUSE_PRESS: 'playpause',
|
||||
PAUSE_PRESS: 'pause',
|
||||
STOP_PRESS: 'stop',
|
||||
NEXT_PRESS: 'nexttrack',
|
||||
PREVIOUS_PRESS: 'prevtrack',
|
||||
FAST_FORWARD_PRESS: 'fastforwardstart',
|
||||
FAST_FORWARD_RELEASE: 'fastforwardend',
|
||||
REWIND_PRESS: 'rewindstart',
|
||||
REWIND_RELEASE: 'rewindend',
|
||||
UPDATE_METADATA: 'updatemetadata',
|
||||
UPDATE_PLAYSTATUS: 'updateplaystatus'
|
||||
};
|
||||
|
||||
// Commands for the players to register, events will be fired to the listeners.
|
||||
var REMOTE_CONTROLS = {
|
||||
PLAY: 'play',
|
||||
PLAY_PAUSE: 'playpause',
|
||||
PAUSE: 'pause',
|
||||
STOP: 'stop',
|
||||
NEXT: 'next',
|
||||
PREVIOUS: 'previous',
|
||||
SEEK_PRESS: 'seekpress',
|
||||
SEEK_RELEASE: 'seekrelease',
|
||||
UPDATE_METADATA: 'updatemetadata',
|
||||
UPDATE_PLAYSTATUS: 'updateplaystatus'
|
||||
};
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
function MediaRemoteControls() {
|
||||
this._bluetoothHelper = null;
|
||||
this._commandListeners = {};
|
||||
this._isSCOConnected = false;
|
||||
|
||||
// Create the empty object for all command listeners.
|
||||
for (var command in REMOTE_CONTROLS) {
|
||||
this._commandListeners[REMOTE_CONTROLS[command]] = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the command listener so that it will be executed when the remote
|
||||
* commands fired.
|
||||
*
|
||||
* @param {String} command
|
||||
* @param {Object} listener
|
||||
*/
|
||||
MediaRemoteControls.prototype.addCommandListener = function(command, listener) {
|
||||
if (this._commandListeners[command]) {
|
||||
this._commandListeners[command].push(listener);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove the command listener.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Object} listener
|
||||
*/
|
||||
MediaRemoteControls.prototype.removeCommandListener = function(name, listener) {
|
||||
if (this._commandListeners[name]) {
|
||||
var index = -1;
|
||||
this._commandListeners[name].forEach(function(currListener, i) {
|
||||
if (currListener === listener) {
|
||||
index = i;
|
||||
}
|
||||
});
|
||||
|
||||
if (index !== -1) {
|
||||
this._commandListeners[name].splice(index, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup the bluetooth/system message, IAC and wired controls.
|
||||
*/
|
||||
MediaRemoteControls.prototype.start = function(callback) {
|
||||
this._setupBluetooth(callback);
|
||||
this._setupIAC();
|
||||
};
|
||||
|
||||
/*
|
||||
* Setup and configure the bluetooth/system message.
|
||||
*/
|
||||
MediaRemoteControls.prototype._setupBluetooth = function(callback) {
|
||||
var self = this;
|
||||
|
||||
// AVRCP commands use system message.
|
||||
navigator.mozSetMessageHandler(
|
||||
'media-button', this._commandHandler.bind(this)
|
||||
);
|
||||
|
||||
// bluetooth will be handled with BluetoothHelper
|
||||
// to send metadata and play status when those information are changed.
|
||||
this._bluetoothHelper = new BluetoothHelper();
|
||||
this._bluetoothHelper.onrequestmediaplaystatus = playstatusHandler;
|
||||
this._bluetoothHelper.ona2dpstatuschanged = a2dpConnectionHandler;
|
||||
this._bluetoothHelper.onscostatuschanged = scoConnectionHandler;
|
||||
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
|
||||
function playstatusHandler() {
|
||||
if (self._commandListeners.updateplaystatus.length > 0) {
|
||||
self._commandHandler(REMOTE_CONTROLS.UPDATE_PLAYSTATUS);
|
||||
}
|
||||
}
|
||||
|
||||
// A2DP is connected: update the status to the bluetooth device.
|
||||
// A2DP is disconnected: pause the player like the headphone is unplugged.
|
||||
function a2dpConnectionHandler(event) {
|
||||
var isConnected = event.status;
|
||||
if (isConnected && self._commandListeners.updatemetadata.length > 0) {
|
||||
self._commandHandler(REMOTE_CONTROLS.UPDATE_METADATA);
|
||||
}
|
||||
}
|
||||
|
||||
// Also expose the SCO status with the custom event because the SCO connection
|
||||
// could occupy the audio channel that the media apps using, besides sending
|
||||
// the play/pause commands, these additional status can help the media apps
|
||||
// to decide if they want more interaction with users while SCO is connected.
|
||||
function scoConnectionHandler(event) {
|
||||
self._isSCOConnected = event.status;
|
||||
if (self._isSCOConnected) {
|
||||
self._commandHandler(AVRCP.PAUSE_PRESS);
|
||||
}
|
||||
else {
|
||||
self._commandHandler(AVRCP.PLAY_PRESS);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Setup and configure the IAC.
|
||||
*/
|
||||
MediaRemoteControls.prototype._setupIAC = function() {
|
||||
var self = this;
|
||||
|
||||
this._queuedMessages = [];
|
||||
// Set up Inter-App Communications
|
||||
navigator.mozApps.getSelf().onsuccess = function() {
|
||||
var app = this.result;
|
||||
// If IAC doesn't exist, just bail out.
|
||||
if (!app.connect) {
|
||||
this._queuedMessages = null;
|
||||
return;
|
||||
}
|
||||
|
||||
app.connect('mediacomms').then(function(ports) {
|
||||
self._ports = ports;
|
||||
self._ports.forEach(function(port) {
|
||||
port.onmessage = function(event) {
|
||||
self._commandHandler(event.data.command);
|
||||
};
|
||||
|
||||
self._queuedMessages.forEach(function(message) {
|
||||
port.postMessage(message);
|
||||
});
|
||||
});
|
||||
self._queuedMessages = null;
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
// Synchronous connection-oriented(SCO) link is the type of radio link used
|
||||
// for voice data of bluetooth, it establishes when the user is in a call via
|
||||
// bluetooth hands-free headset. And since only voice will be routed to the
|
||||
// headset during a call, the media apps can use this api to know the SCO
|
||||
// status, so that the apps can adjust the ui or notify the user to get better
|
||||
// user experience, for more detail, please see:
|
||||
// http://en.wikipedia.org/wiki/Bluetooth_protocols
|
||||
MediaRemoteControls.prototype.getSCOStatus = function(callback) {
|
||||
this._bluetoothHelper.isScoConnected(callback, function onerror() {
|
||||
callback(false);
|
||||
});
|
||||
};
|
||||
|
||||
MediaRemoteControls.prototype._postMessage = function(name, value) {
|
||||
var message = {type: name, data: value};
|
||||
if (!this._ports) {
|
||||
if (this._queuedMessages) {
|
||||
this._queuedMessages.push(message);
|
||||
}
|
||||
} else {
|
||||
this._ports.forEach(function(port) {
|
||||
port.postMessage(message);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert the received messages to the REMOTE_CONTROLS commands, and create
|
||||
* custom event then pass the new event to the command listeners executer.
|
||||
*
|
||||
* @param {String} message
|
||||
*/
|
||||
MediaRemoteControls.prototype._commandHandler = function(message) {
|
||||
var type = 'remote';
|
||||
var option = {};
|
||||
|
||||
switch (message) {
|
||||
case AVRCP.PLAY_PRESS:
|
||||
case IAC.PLAY_PRESS:
|
||||
option.detail = {
|
||||
command: REMOTE_CONTROLS.PLAY,
|
||||
isSCOConnected: this._isSCOConnected
|
||||
};
|
||||
break;
|
||||
case AVRCP.PLAY_PAUSE_PRESS:
|
||||
case IAC.PLAY_PAUSE_PRESS:
|
||||
option.detail = {
|
||||
command: REMOTE_CONTROLS.PLAY_PAUSE,
|
||||
isSCOConnected: this._isSCOConnected
|
||||
};
|
||||
break;
|
||||
case AVRCP.PAUSE_PRESS:
|
||||
case IAC.PAUSE_PRESS:
|
||||
option.detail = {
|
||||
command: REMOTE_CONTROLS.PAUSE,
|
||||
isSCOConnected: this._isSCOConnected
|
||||
};
|
||||
break;
|
||||
case AVRCP.STOP_PRESS:
|
||||
case IAC.STOP_PRESS:
|
||||
option.detail = { command: REMOTE_CONTROLS.STOP };
|
||||
break;
|
||||
case AVRCP.NEXT_PRESS:
|
||||
case IAC.NEXT_PRESS:
|
||||
option.detail = { command: REMOTE_CONTROLS.NEXT };
|
||||
break;
|
||||
case AVRCP.PREVIOUS_PRESS:
|
||||
case IAC.PREVIOUS_PRESS:
|
||||
option.detail = { command: REMOTE_CONTROLS.PREVIOUS };
|
||||
break;
|
||||
case AVRCP.FAST_FORWARD_PRESS:
|
||||
case IAC.FAST_FORWARD_PRESS:
|
||||
option.detail = { command: REMOTE_CONTROLS.SEEK_PRESS, direction: 1 };
|
||||
break;
|
||||
case AVRCP.REWIND_PRESS:
|
||||
case IAC.REWIND_PRESS:
|
||||
option.detail = { command: REMOTE_CONTROLS.SEEK_PRESS, direction: -1 };
|
||||
break;
|
||||
case AVRCP.FAST_FORWARD_RELEASE:
|
||||
case IAC.FAST_FORWARD_RELEASE:
|
||||
case AVRCP.REWIND_RELEASE:
|
||||
case IAC.REWIND_RELEASE:
|
||||
option.detail = { command: REMOTE_CONTROLS.SEEK_RELEASE };
|
||||
break;
|
||||
case IAC.UPDATE_METADATA:
|
||||
case IAC.UPDATE_PLAYSTATUS:
|
||||
case REMOTE_CONTROLS.UPDATE_METADATA:
|
||||
case REMOTE_CONTROLS.UPDATE_PLAYSTATUS:
|
||||
option.detail = { command: message };
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
var event = new CustomEvent(type, option);
|
||||
this._executeCommandListeners(event);
|
||||
};
|
||||
|
||||
/**
|
||||
* Fire the event to the command listeners.
|
||||
*
|
||||
* @param {Object} event
|
||||
*/
|
||||
MediaRemoteControls.prototype._executeCommandListeners = function(event) {
|
||||
if (!event.detail) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._commandListeners[event.detail.command].forEach(function(listener) {
|
||||
listener(event);
|
||||
});
|
||||
};
|
||||
|
||||
MediaRemoteControls.prototype.notifyAppInfo = function(info) {
|
||||
// Send the app info via IAC.
|
||||
this._postMessage('appinfo', info);
|
||||
};
|
||||
|
||||
/**
|
||||
* Send the updated metadata to the remote requester/receiver.
|
||||
*
|
||||
* @param {Object} metadata
|
||||
*/
|
||||
MediaRemoteControls.prototype.notifyMetadataChanged = function(metadata) {
|
||||
// Send the new metadata via bluetooth.
|
||||
this._bluetoothHelper.sendMediaMetaData(metadata,
|
||||
function onsuccess() {
|
||||
// To do nothing here, expect onsuccess normally.
|
||||
},
|
||||
function onerror() {
|
||||
console.log('Sending Metadata error');
|
||||
});
|
||||
|
||||
// Now, send it via IAC.
|
||||
this._postMessage('nowplaying', metadata);
|
||||
};
|
||||
|
||||
/**
|
||||
* Send the updated play status to the remote requester/receiver.
|
||||
*
|
||||
* @param {Object} status
|
||||
*/
|
||||
MediaRemoteControls.prototype.notifyStatusChanged = function(status) {
|
||||
// Don't send the interrupted statuses to the remote client because
|
||||
// they are not the AVRCP statuses.
|
||||
if (status === 'mozinterruptbegin') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Send the new status via bluetooth.
|
||||
this._bluetoothHelper.sendMediaPlayStatus(status,
|
||||
function onsuccess() {
|
||||
// To do nothing here, expect onsuccess normally.
|
||||
},
|
||||
function onerror() {
|
||||
console.log('Sending Playstatus error');
|
||||
});
|
||||
|
||||
// Now, send it via IAC.
|
||||
this._postMessage('status', status);
|
||||
};
|
||||
148
assets/webapps/music-oga.gaiamobile.org/shared/js/mediadb.js
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
;'use strict';var MediaDB=(function(){function MediaDB(mediaType,metadataParser,options){this.mediaType=mediaType;this.metadataParser=metadataParser;if(!options){options={};}
|
||||
this.indexes=options.indexes||[];this.version=options.version||1;this.mimeTypes=options.mimeTypes;this.autoscan=(options.autoscan!==undefined)?options.autoscan:true;this.state=MediaDB.OPENING;this.scanning=false;this.initialScanComplete=false;this.parsingBigFiles=false;this.updateRecord=options.updateRecord;this.reparsedRecord=options.reparsedRecord;if(options.excludeFilter&&(options.excludeFilter instanceof RegExp)){this.clientExcludeFilter=options.excludeFilter;}
|
||||
this.batchHoldTime=options.batchHoldTime||100;this.batchSize=options.batchSize||0;this.dbname='MediaDB/'+this.mediaType+'/';var media=this;this.details={eventListeners:{},pendingInsertions:[],pendingDeletions:[],whenDoneProcessing:[],pendingCreateNotifications:[],pendingDeleteNotifications:[],pendingNotificationTimer:null,newestFileModTime:0};if(!this.metadataParser){this.metadataParser=function(file,callback){setTimeout(function(){callback({});},0);};}
|
||||
var dbVersion=(0xFFFF&this.version)<<16|(0xFFFF&MediaDB.VERSION);var openRequest=indexedDB.open(this.dbname,dbVersion);openRequest.onerror=function(e){console.error('MediaDB():',openRequest.error.name);};openRequest.onblocked=function(e){console.error('indexedDB.open() is blocked in MediaDB()');};openRequest.onupgradeneeded=function(e){var db=openRequest.result;var transaction=e.target.transaction;var oldVersion=e.oldVersion;var oldDbVersion=0xFFFF&oldVersion;var oldClientVersion=0xFFFF&(oldVersion>>16);if(oldClientVersion===0){oldDbVersion=2;oldClientVersion=oldVersion/oldDbVersion;}
|
||||
if(0===db.objectStoreNames.length){createObjectStores(db);}else{handleUpgrade(db,transaction,oldDbVersion,oldClientVersion);}};openRequest.onsuccess=function(e){media.db=openRequest.result;media.db.onerror=function(event){console.error('MediaDB: ',event.target.error&&event.target.error.name);};changeState(media,MediaDB.ENUMERABLE);var cursorRequest=media.db.transaction('files','readonly').objectStore('files').index('date').openCursor(null,'prev');cursorRequest.onerror=function(){console.error('MediaDB initialization error',cursorRequest.error);};cursorRequest.onsuccess=function(){var cursor=cursorRequest.result;if(cursor){media.details.newestFileModTime=cursor.value.date;}
|
||||
else{media.details.newestFileModTime=0;}
|
||||
initDeviceStorage();};};function createObjectStores(db){var filestore=db.createObjectStore('files',{keyPath:'name'});filestore.createIndex('date','date');media.indexes.forEach(function(indexName){if(indexName==='name'||indexName==='date'){return;}
|
||||
filestore.createIndex(indexName,indexName);});}
|
||||
function enumerateOldFiles(store,callback){var openCursorReq=store.openCursor();openCursorReq.onsuccess=function(){var cursor=openCursorReq.result;if(cursor){callback(cursor.value);cursor.continue();}};}
|
||||
function handleUpgrade(db,trans,oldDbVersion,oldClientVersion){media.state=MediaDB.UPGRADING;var evtDetail={'oldMediaDBVersion':oldDbVersion,'oldClientVersion':oldClientVersion,'newMediaDBVersion':MediaDB.VERSION,'newClientVersion':media.version};dispatchEvent(media,'upgrading',evtDetail);var store=trans.objectStore('files');if(media.version!=oldClientVersion){upgradeIndexesChanges(store);}
|
||||
var clientUpgradeNeeded=(media.version!=oldClientVersion)&&media.updateRecord;if((2!=oldDbVersion||3!=MediaDB.VERSION)&&!clientUpgradeNeeded){return;}
|
||||
enumerateOldFiles(store,function doUpgrade(dbfile){if(2==oldDbVersion&&3==MediaDB.VERSION){upgradeDBVer2to3(store,dbfile);}
|
||||
if(clientUpgradeNeeded){handleClientUpgrade(store,dbfile,oldClientVersion);}});}
|
||||
function upgradeIndexesChanges(store){var dbIndexes=store.indexNames;var clientIndexes=media.indexes;for(var i=0;i<dbIndexes.length;i++){if('name'===dbIndexes[i]||'date'===dbIndexes[i]){continue;}
|
||||
if(clientIndexes.indexOf(dbIndexes[i])<0){store.deleteIndex(dbIndexes[i]);}}
|
||||
for(i=0;i<clientIndexes.length;i++){if(!dbIndexes.contains(clientIndexes[i])){store.createIndex(clientIndexes[i],clientIndexes[i]);}}}
|
||||
function upgradeDBVer2to3(store,dbfile){if(dbfile.name[0]==='/'){return;}
|
||||
store.delete(dbfile.name);dbfile.name='/sdcard/'+dbfile.name;store.add(dbfile);}
|
||||
function handleClientUpgrade(store,dbfile,oldClientVersion){try{dbfile.metadata=media.updateRecord(dbfile,oldClientVersion,media.version);if(dbfile.needsReparse&&!media.reparsedRecord){console.warn('client app requested reparse, but no reparsedRecord was set');delete dbfile.needsReparse;}
|
||||
store.put(dbfile);}catch(ex){console.warn('client app updates record, '+dbfile.name+', failed: '+ex.message);}}
|
||||
function initDeviceStorage(){var details=media.details;details.storages=navigator.getDeviceStorages(mediaType);details.availability={};getStorageAvailability();function getStorageAvailability(){var next=0;getNextAvailability();function getNextAvailability(){if(next>=details.storages.length){setupHandlers();return;}
|
||||
var s=details.storages[next++];var name=s.storageName;var req=s.available();req.onsuccess=function(e){details.availability[name]=req.result;getNextAvailability();};req.onerror=function(e){details.availability[name]='unavailable';getNextAvailability();};}}
|
||||
function setupHandlers(){for(var i=0;i<details.storages.length;i++){details.storages[i].addEventListener('change',changeHandler);}
|
||||
details.dsEventListener=changeHandler;sendInitialEvent();}
|
||||
function sendInitialEvent(){var state=getState(details.availability);changeState(media,state);if(media.autoscan){scan(media);}}
|
||||
function getState(availability){var n=0;var a=0;var u=0;var s=0;for(var name in availability){n++;switch(availability[name]){case'available':a++;break;case'unavailable':u++;break;case'shared':s++;break;}}
|
||||
if(s>0){return MediaDB.UNMOUNTED;}
|
||||
if(u===n){return MediaDB.NOCARD;}
|
||||
return MediaDB.READY;}
|
||||
function changeHandler(e){switch(e.reason){case'modified':case'deleted':fileChangeHandler(e);return;case'available':case'unavailable':case'shared':volumeChangeHandler(e);return;default:return;}}
|
||||
function volumeChangeHandler(e){var storageName=e.target.storageName;if(details.availability[storageName]===e.reason){return;}
|
||||
var oldState=media.state;details.availability[storageName]=e.reason;var newState=getState(details.availability);if(newState!==oldState){changeState(media,newState);if(newState===MediaDB.READY){if(media.autoscan){scan(media);}}
|
||||
else{endscan(media);}}
|
||||
else if(newState===MediaDB.READY){if(e.reason==='available'){dispatchEvent(media,'ready');if(media.autoscan){scan(media);}}
|
||||
else if(e.reason==='unavailable'){dispatchEvent(media,'cardremoved');deleteAllFiles(storageName);}}}
|
||||
function fileChangeHandler(e){var filename=e.path;if(ignoreName(media,filename)){return;}
|
||||
if(e.reason==='modified'){insertRecord(media,filename);}else{deleteRecord(media,filename);}}
|
||||
function deleteAllFiles(storageName){var storagePrefix=storageName?'/'+storageName+'/':'';var store=media.db.transaction('files').objectStore('files');var cursorRequest=store.openCursor();cursorRequest.onsuccess=function(){var cursor=cursorRequest.result;if(cursor){if(cursor.value.name.startsWith(storagePrefix)){deleteRecord(media,cursor.value.name);}
|
||||
cursor.continue();}};}}}
|
||||
MediaDB.prototype={close:function close(){this.db.close();for(var i=0;i<this.details.storages.length;i++){var s=this.details.storages[i];s.removeEventListener('change',this.details.dsEventListener);}
|
||||
changeState(this,MediaDB.CLOSED);},addEventListener:function addEventListener(type,listener){if(!this.details.eventListeners.hasOwnProperty(type)){this.details.eventListeners[type]=[];}
|
||||
var listeners=this.details.eventListeners[type];if(listeners.indexOf(listener)!==-1){return;}
|
||||
listeners.push(listener);},removeEventListener:function removeEventListener(type,listener){if(!this.details.eventListeners.hasOwnProperty(type)){return;}
|
||||
var listeners=this.details.eventListeners[type];var position=listeners.indexOf(listener);if(position===-1){return;}
|
||||
listeners.splice(position,1);},getFileInfo:function getFile(filename,callback,errback){if(this.state===MediaDB.OPENING){throw Error('MediaDB is not ready. State: '+this.state);}
|
||||
var media=this;var read=media.db.transaction('files','readonly').objectStore('files').get(filename);read.onerror=function(){var msg='MediaDB.getFileInfo: unknown filename: '+filename;if(errback){errback(msg);}else{console.error(msg);}};read.onsuccess=function(){if(callback){callback(read.result);}};},getFile:function getFile(filename,callback,errback){if(this.state!==MediaDB.READY){throw Error('MediaDB is not ready. State: '+this.state);}
|
||||
var storage=navigator.getDeviceStorage(this.mediaType);var getRequest=storage.get(filename);getRequest.onsuccess=function(){callback(getRequest.result);};getRequest.onerror=function(){var errmsg=getRequest.error&&getRequest.error.name;if(errback){errback(errmsg);}else{console.error('MediaDB.getFile:',errmsg);}};},deleteFile:function deleteFile(filename){if(this.state!==MediaDB.READY){throw Error('MediaDB is not ready. State: '+this.state);}
|
||||
var storage=navigator.getDeviceStorage(this.mediaType);storage.delete(filename).onerror=function(e){console.error('MediaDB.deleteFile(): Failed to delete',filename,'from DeviceStorage:',e.target.error);};},addFile:function addFile(filename,file){if(this.state!==MediaDB.READY){throw Error('MediaDB is not ready. State: '+this.state);}
|
||||
var media=this;var storage=navigator.getDeviceStorage(media.mediaType);var deletereq=storage.delete(filename);deletereq.onsuccess=deletereq.onerror=save;function save(){var request=storage.addNamed(file,filename);request.onerror=function(){console.error('MediaDB: Failed to store',filename,'in DeviceStorage:',request.error);};}},updateMetadata:function(filename,metadata,callback){if(this.state===MediaDB.OPENING){throw Error('MediaDB is not ready. State: '+this.state);}
|
||||
var media=this;var read=media.db.transaction('files','readonly').objectStore('files').get(filename);read.onerror=function(){console.error('MediaDB.updateMetadata called with unknown filename');};read.onsuccess=function(){var fileinfo=read.result;Object.keys(metadata).forEach(function(key){fileinfo.metadata[key]=metadata[key];});var write=media.db.transaction('files','readwrite').objectStore('files').put(fileinfo);write.onerror=function(){console.error('MediaDB.updateMetadata: database write failed',write.error&&write.error.name);};if(callback){write.onsuccess=function(){callback();};}};},count:function(key,range,callback){if(this.state!==MediaDB.READY&&this.state!==MediaDB.ENUMERABLE){throw Error('MediaDB is not ready or enumerable. State: '+this.state);}
|
||||
if(arguments.length===1){callback=key;range=undefined;key=undefined;}
|
||||
else if(arguments.length===2){callback=range;range=key;key=undefined;}
|
||||
var store=this.db.transaction('files').objectStore('files');if(key&&key!=='name'){store=store.index(key);}
|
||||
var countRequest=store.count(range||null);countRequest.onerror=function(){console.error('MediaDB.count() failed with',countRequest.error);};countRequest.onsuccess=function(e){callback(e.target.result);};},enumerate:function enumerate(key,range,direction,callback){if(this.state!==MediaDB.READY&&this.state!==MediaDB.ENUMERABLE){throw Error('MediaDB is not ready or enumerable. State: '+this.state);}
|
||||
var handle={state:'enumerating'};if(arguments.length===1){callback=key;key=undefined;}
|
||||
else if(arguments.length===2){callback=range;range=undefined;}
|
||||
else if(arguments.length===3){callback=direction;direction=undefined;}
|
||||
var store=this.db.transaction('files').objectStore('files');if(key&&key!=='name'){store=store.index(key);}
|
||||
var cursorRequest=store.openCursor(range||null,direction||'next');cursorRequest.onerror=function(){console.error('MediaDB.enumerate() failed with',cursorRequest.error);handle.state='error';};cursorRequest.onsuccess=function(){if(handle.state==='cancelling'){handle.state='cancelled';return;}
|
||||
var cursor=cursorRequest.result;if(cursor){try{var fileinfo=cursor.value;if(!fileinfo.fail){callback(fileinfo);}}
|
||||
catch(e){console.warn('MediaDB.enumerate(): callback threw',e,e.stack);}
|
||||
cursor.continue();}
|
||||
else{handle.state='complete';callback(null);}};return handle;},advancedEnumerate:function(key,range,direction,index,callback){if(this.state!==MediaDB.READY){throw Error('MediaDB is not ready. State: '+this.state);}
|
||||
var handle={state:'enumerating'};var store=this.db.transaction('files').objectStore('files');if(key&&key!=='name'){store=store.index(key);}
|
||||
var cursorRequest=store.openCursor(range||null,direction||'next');var isTarget=false;cursorRequest.onerror=function(){console.error('MediaDB.enumerate() failed with',cursorRequest.error);handle.state='error';};cursorRequest.onsuccess=function(){if(handle.state==='cancelling'){handle.state='cancelled';return;}
|
||||
var cursor=cursorRequest.result;if(cursor){try{if(index===0){isTarget=true;}
|
||||
var fileinfo=cursor.value;if(!fileinfo.fail&&isTarget){callback(cursor.value);cursor.continue();}
|
||||
else{cursor.advance(index);isTarget=true;}}
|
||||
catch(e){console.warn('MediaDB.enumerate(): callback threw',e,e.stack);}}
|
||||
else{handle.state='complete';callback(null);}};return handle;},enumerateAll:function enumerateAll(key,range,direction,callback){var batch=[];if(arguments.length===1){callback=key;key=undefined;}
|
||||
else if(arguments.length===2){callback=range;range=undefined;}
|
||||
else if(arguments.length===3){callback=direction;direction=undefined;}
|
||||
return this.enumerate(key,range,direction,function(fileinfo){if(fileinfo!==null){batch.push(fileinfo);}else{callback(batch);}});},cancelEnumeration:function cancelEnumeration(handle){if(handle.state==='enumerating'){handle.state='cancelling';}},getAll:function getAll(callback){if(this.state!==MediaDB.READY&&this.state!==MediaDB.ENUMERABLE){throw Error('MediaDB is not ready or enumerable. State: '+this.state);}
|
||||
var store=this.db.transaction('files').objectStore('files');var request=store.mozGetAll();request.onerror=function(){console.error('MediaDB.getAll() failed with',request.error);};request.onsuccess=function(){var all=request.result;var good=all.filter(function(fileinfo){return!fileinfo.fail;});callback(good);};},scan:function(){scan(this);},freeSpace:function freeSpace(callback){if(this.state!==MediaDB.READY){throw Error('MediaDB is not ready. State: '+this.state);}
|
||||
var storage=navigator.getDeviceStorage(this.mediaType);var freereq=storage.freeSpace();freereq.onsuccess=function(){callback(freereq.result);};}};MediaDB.VERSION=3;MediaDB.OPENING='opening';MediaDB.UPGRADING='upgrading';MediaDB.ENUMERABLE='enumerable';MediaDB.READY='ready';MediaDB.NOCARD='nocard';MediaDB.UNMOUNTED='unmounted';MediaDB.CLOSED='closed';function ignore(media,file){if(ignoreName(media,file.name)){return true;}
|
||||
if(media.mimeTypes&&media.mimeTypes.indexOf(file.type)===-1){return true;}
|
||||
return false;}
|
||||
function ignoreName(media,filename){if(media.clientExcludeFilter&&media.clientExcludeFilter.test(filename)){return true;}else{return(filename[0]==='.'||filename.indexOf('/.')!==-1);}}
|
||||
function scan(media){media.scanning=true;dispatchEvent(media,'scanstart');quickScan(media.details.newestFileModTime);function quickScan(timestamp){var options;if(timestamp>0){media.details.firstscan=false;options={since:new Date(timestamp+1)};}
|
||||
else{media.details.firstscan=true;media.details.records=[];options={};}
|
||||
scanDS(media.details.storages,null,options).then(processFiles).catch(handleScanError);function processFiles(files){if(!media.scanning){return;}
|
||||
files=files.sort(function(a,b){return b.lastModifiedDate-a.lastModifiedDate;});for(var i=0;i<files.length;i++){insertRecord(media,files[i]);}
|
||||
whenDoneProcessing(media,function(){sendNotifications(media);if(media.details.firstscan){endscan(media);}
|
||||
else{fullScan();}});}
|
||||
function handleScanError(error){console.warn('Error while scanning',error);endscan(media);}}
|
||||
function fullScan(){if(media.state!==MediaDB.READY){endscan(media);return;}
|
||||
var dsfiles;scanDS(media.details.storages).then(function(files){dsfiles=files;getDBFiles();}).catch(function(error){console.warn('Error while scanning',error);endscan(media);});function getDBFiles(){var store=media.db.transaction('files').objectStore('files');var getAllRequest=store.mozGetAll();getAllRequest.onsuccess=function(){if(!media.scanning){return;}
|
||||
var dbfiles=getAllRequest.result;compareLists(dbfiles,dsfiles);};}
|
||||
function compareLists(dbfiles,dsfiles){dsfiles.sort(function(a,b){if(a.name<b.name){return-1;}else{return 1;}});var dsindex=0,dbindex=0;while(true){var dsfile;if(dsindex<dsfiles.length){dsfile=dsfiles[dsindex];}else{dsfile=null;}
|
||||
var dbfile;if(dbindex<dbfiles.length){dbfile=dbfiles[dbindex];}else{dbfile=null;}
|
||||
if(dsfile===null&&dbfile===null){break;}
|
||||
if(dbfile===null){insertRecord(media,dsfile);dsindex++;continue;}
|
||||
if(dsfile===null){deleteRecord(media,dbfile.name);dbindex++;continue;}
|
||||
if(dsfile.name===dbfile.name){var lastModified=dsfile.lastModifiedDate;var timeDifference=lastModified.getTime()-dbfile.date;var sameTime=(timeDifference===0||((Math.abs(timeDifference)<=12*60*60*1000)&&(timeDifference%10*60*1000===0)));var sameSize=dsfile.size===dbfile.size;if(!sameTime||!sameSize){deleteRecord(media,dbfile.name);insertRecord(media,dsfile);}else if(dbfile.needsReparse){deleteRecord(media,dbfile.name);insertRecord(media,dsfile,dbfile.metadata);}
|
||||
dsindex++;dbindex++;continue;}
|
||||
if(dsfile.name<dbfile.name){insertRecord(media,dsfile);dsindex++;continue;}
|
||||
if(dsfile.name>dbfile.name){deleteRecord(media,dbfile.name);dbindex++;continue;}
|
||||
console.error('Assertion failed');}
|
||||
insertRecord(media,null);}}
|
||||
function scanDS(storage,directory,options){if(Array.isArray(storage)){return Promise.all(storage.map((s)=>scanDS(s,directory,options))).then(function(arrays){return Array.prototype.concat.apply([],arrays);});}
|
||||
return new Promise(function(resolve,reject){var files=[];var cursor=storage.enumerate(directory||'',options||{});cursor.onerror=function(){if(cursor.error.name==='NotFoundError'){resolve(files);}
|
||||
else{reject(cursor.error);}};cursor.onsuccess=function(){var result=cursor.result;if(result){if(!ignore(media,result)){files.push(result);}
|
||||
cursor.continue();}
|
||||
else{resolve(files);}};});}}
|
||||
function endscan(media){if(media.scanning){media.initialScanComplete=true;media.scanning=false;media.parsingBigFiles=false;dispatchEvent(media,'scanend');}}
|
||||
function insertRecord(media,fileOrName,oldMetadata){var details=media.details;details.pendingInsertions.push([fileOrName,oldMetadata]);if(details.processingQueue){return;}
|
||||
processQueue(media);}
|
||||
function deleteRecord(media,filename){var details=media.details;details.pendingDeletions.push(filename);if(details.processingQueue){return;}
|
||||
processQueue(media);}
|
||||
function whenDoneProcessing(media,f){var details=media.details;if(details.processingQueue){details.whenDoneProcessing.push(f);}else{f();}}
|
||||
function processQueue(media){var details=media.details;details.processingQueue=true;next();function next(){if(details.pendingDeletions.length>0){deleteFiles();}
|
||||
else if(details.pendingInsertions.length>0){insertFile(...details.pendingInsertions.shift());}
|
||||
else{details.processingQueue=false;if(details.whenDoneProcessing.length>0){var functions=details.whenDoneProcessing;details.whenDoneProcessing=[];functions.forEach(function(f){f();});}}}
|
||||
function deleteFiles(){var transaction=media.db.transaction('files','readwrite');var store=transaction.objectStore('files');deleteNextFile();function deleteNextFile(){if(details.pendingDeletions.length===0){next();return;}
|
||||
var filename=details.pendingDeletions.shift();var request=store.delete(filename);request.onerror=function(){console.warn('MediaDB: Unknown file in deleteRecord:',filename,request.error);deleteNextFile();};request.onsuccess=function(){queueDeleteNotification(media,filename);deleteNextFile();};}}
|
||||
function insertFile(f,oldMetadata){if(f===null){sendNotifications(media);endscan(media);next();return;}
|
||||
if(typeof f==='string'){var storage=navigator.getDeviceStorage(media.mediaType);var getreq=storage.get(f);getreq.onerror=function(){console.warn('MediaDB: Unknown file in insertRecord:',f,getreq.error);next();};getreq.onsuccess=function(){if(media.mimeTypes&&ignore(media,getreq.result)){next();}else{parseMetadata(getreq.result,f,oldMetadata);}};}
|
||||
else{parseMetadata(f,f.name,oldMetadata);}}
|
||||
function parseMetadata(file,filename,oldMetadata){if(!file.lastModifiedDate){console.warn('MediaDB: parseMetadata: no lastModifiedDate for',filename,'using Date.now() until #793955 is fixed');}
|
||||
var fileinfo={name:filename,type:file.type,size:file.size,date:file.lastModifiedDate?file.lastModifiedDate.getTime():Date.now()};if(fileinfo.date>details.newestFileModTime){details.newestFileModTime=fileinfo.date;}
|
||||
media.metadataParser(file,gotMetadata,metadataError,parsingBigFile);function parsingBigFile(){media.parsingBigFiles=true;}
|
||||
function metadataError(e){console.warn('MediaDB: error parsing metadata for',filename,':',e);fileinfo.fail=true;storeRecord(fileinfo);}
|
||||
function gotMetadata(metadata){fileinfo.metadata=metadata;if(oldMetadata&&media.reparsedRecord){fileinfo.metadata=media.reparsedRecord(oldMetadata,metadata);}
|
||||
storeRecord(fileinfo);if(!media.scanning){media.parsingBigFiles=false;}}}
|
||||
function storeRecord(fileinfo){if(media.details.firstscan){media.details.records.push(fileinfo);if(!fileinfo.fail){queueCreateNotification(media,fileinfo);}
|
||||
next();}
|
||||
else{var transaction=media.db.transaction('files','readwrite');var store=transaction.objectStore('files');var request=store.add(fileinfo);request.onsuccess=function(){if(!fileinfo.fail){queueCreateNotification(media,fileinfo);}
|
||||
next();};request.onerror=function(event){if(request.error.name==='ConstraintError'){event.stopPropagation();event.preventDefault();var putrequest=store.put(fileinfo);putrequest.onsuccess=function(){queueDeleteNotification(media,fileinfo.name);if(!fileinfo.fail){queueCreateNotification(media,fileinfo);}
|
||||
next();};putrequest.onerror=function(){console.error('MediaDB: unexpected ConstraintError','in insertRecord for file:',fileinfo.name);next();};}
|
||||
else{console.error('MediaDB: unexpected error in insertRecord:',request.error,'for file:',fileinfo.name);next();}};}}}
|
||||
function queueCreateNotification(media,fileinfo){var creates=media.details.pendingCreateNotifications;creates.push(fileinfo);if(media.batchSize&&creates.length>=media.batchSize){sendNotifications(media);}else{resetNotificationTimer(media);}}
|
||||
function queueDeleteNotification(media,filename){var deletes=media.details.pendingDeleteNotifications;deletes.push(filename);if(media.batchSize&&deletes.length>=media.batchSize){sendNotifications(media);}else{resetNotificationTimer(media);}}
|
||||
function resetNotificationTimer(media){var details=media.details;if(details.pendingNotificationTimer){clearTimeout(details.pendingNotificationTimer);}
|
||||
details.pendingNotificationTimer=setTimeout(function(){sendNotifications(media);},media.scanning?media.batchHoldTime:100);}
|
||||
function sendNotifications(media){var details=media.details;if(details.pendingNotificationTimer){clearTimeout(details.pendingNotificationTimer);details.pendingNotificationTimer=null;}
|
||||
if(details.pendingDeleteNotifications.length>0){var deletions=details.pendingDeleteNotifications;details.pendingDeleteNotifications=[];dispatchEvent(media,'deleted',deletions);}
|
||||
if(details.pendingCreateNotifications.length>0){var creations=details.pendingCreateNotifications;details.pendingCreateNotifications=[];if(details.firstscan&&details.records.length>0){var transaction=media.db.transaction('files','readwrite');var store=transaction.objectStore('files');for(var i=0;i<details.records.length;i++){store.add(details.records[i]);}
|
||||
details.records.length=0;transaction.oncomplete=function(){dispatchEvent(media,'created',creations);};}
|
||||
else{dispatchEvent(media,'created',creations);}}}
|
||||
function dispatchEvent(media,type,detail){var handler=media['on'+type];var listeners=media.details.eventListeners[type];if(!handler&&(!listeners||listeners.length===0)){return;}
|
||||
var event={type:type,target:media,currentTarget:media,timestamp:Date.now(),detail:detail};if(typeof handler==='function'){try{handler.call(media,event);}
|
||||
catch(e){console.warn('MediaDB: ','on'+type,'event handler threw',e,e.stack);}}
|
||||
if(!listeners){return;}
|
||||
for(var i=0;i<listeners.length;i++){try{var listener=listeners[i];if(typeof listener==='function'){listener.call(media,event);}
|
||||
else{listener.handleEvent(event);}}
|
||||
catch(e){console.warn('MediaDB: ',type,'event listener threw',e,e.stack);}}}
|
||||
function changeState(media,state){if(media.state!==state){media.state=state;switch(state){case MediaDB.READY:case MediaDB.ENUMERABLE:dispatchEvent(media,state);break;default:dispatchEvent(media,'unavailable',state);break;}}}
|
||||
return MediaDB;}());
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
;'use strict';var MimeMapper={_typeToExtensionMap:{'image/jpeg':'jpg','image/png':'png','image/gif':'gif','image/bmp':'bmp','audio/mpeg':'mp3','audio/mp4':'m4a','audio/ogg':'ogg','audio/webm':'webm','audio/3gpp':'3gp','audio/amr':'amr','video/mp4':'mp4','video/mpeg':'mpg','video/ogg':'ogg','video/webm':'webm','video/3gpp':'3gp','video/3gpp2':'3g2','application/pdf':'pdf','application/vcard':'vcf','text/vcard':'vcf','text/x-vcard':'vcf'},_extensionToTypeMap:{'jpg':'image/jpeg','jpeg':'image/jpeg','jpe':'image/jpeg','png':'image/png','gif':'image/gif','bmp':'image/bmp','mp3':'audio/mpeg','m4a':'audio/mp4','m4b':'audio/mp4','m4p':'audio/mp4','m4r':'audio/mp4','aac':'audio/aac','opus':'audio/ogg','amr':'audio/amr','mp4':'video/mp4','mpeg':'video/mpeg','mpg':'video/mpeg','ogv':'video/ogg','ogx':'video/ogg','webm':'video/webm','3gp':'video/3gpp','3g2':'video/3gpp2','ogg':'video/ogg','pdf':'application/pdf','vcf':'text/vcard'},_parseExtension:function(filename){var array=filename.split('.');return array.length>1?array.pop():'';},isSupportedType:function(mimetype){return(mimetype in this._typeToExtensionMap);},isSupportedExtension:function(extension){return(extension in this._extensionToTypeMap);},isFilenameMatchesType:function(filename,mimetype){var extension=this._parseExtension(filename);var guessedType=this.guessTypeFromExtension(extension);return(guessedType==mimetype);},guessExtensionFromType:function(mimetype){return this._typeToExtensionMap[mimetype];},guessTypeFromExtension:function(extension){return this._extensionToTypeMap[extension];},guessTypeFromFileProperties:function(filename,mimetype){var extension=this._parseExtension(filename);var type=this.isSupportedType(mimetype)?mimetype:this.guessTypeFromExtension(extension);return type||'';},ensureFilenameMatchesType:function(filename,mimetype){if(!this.isFilenameMatchesType(filename,mimetype)){var guessedExt=this.guessExtensionFromType(mimetype);if(guessedExt){filename+='.'+guessedExt;}}
|
||||
return filename;}};
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
;'use strict';(function(exports){if(exports.ForwardLock){return;}
|
||||
const mimeSubtype='vnd.mozilla.oma.drm.fl';const SECRET_SETTINGS_ID='oma.drm.forward_lock.secret.key';var secret=null;function xor(buffer,key){var words=new Uint32Array(buffer,0,buffer.byteLength>>2);for(var i=0,n=words.length;i<n;i++){words[i]^=key;}}
|
||||
function lockBuffer(secret,content,type,metadata){var header='LOCKED 1 '+escape(type)+'\n';if(metadata){for(var p in metadata){header+=escape(p)+':'+escape(metadata[p])+'\n';}}
|
||||
header+='\0';var buffer=new Uint8Array(new Uint8Array(content)).buffer;xor(buffer,secret);return new Blob([header,buffer],{type:type.split('/')[0]+'/'+mimeSubtype});}
|
||||
function lockBlob(secret,blob,metadata,callback){var reader=new FileReader();reader.readAsArrayBuffer(blob);reader.onload=function(){callback(lockBuffer(secret,reader.result,blob.type,metadata));};}
|
||||
function unlockBlob(secret,blob,callback,errorCallback){if(!secret){return error('no secret supplied');}
|
||||
var reader=new FileReader();reader.readAsArrayBuffer(blob);reader.onload=function(){var buffer=reader.result;var bytes=new Uint8Array(buffer);var header='';var contentStart;for(var i=0;i<bytes.length;i++){if(bytes[i]===0){contentStart=i+1;break;}
|
||||
header+=String.fromCharCode(bytes[i]);}
|
||||
if(!header.startsWith('LOCKED')){return error('Bad magic number');}
|
||||
if(header.substring(6,9)!==' 1 '){return error('Unsupported version number');}
|
||||
if(!contentStart){return error('No content');}
|
||||
var eol=header.indexOf('\n');if(eol===-1){return error('malformed header');}
|
||||
var type=unescape(header.substring(9,eol).trim());var metadata={};var lines=header.substring(eol+1).split('\n');for(var j=0;j<lines.length;j++){var line=lines[j];if(!line){continue;}
|
||||
var[key,value]=line.split(':');if(!key||!value){return error('malformed metadata');}
|
||||
metadata[unescape(key)]=unescape(value);}
|
||||
var content=buffer.slice(contentStart);xor(content,secret);var blob=new Blob([content],{type:type});try{callback(blob,metadata);}
|
||||
catch(e){console.error('Exception in content callback',e);}};function error(msg){msg='LCKA.decrypt(): '+msg;if(errorCallback){try{errorCallback(msg);}
|
||||
catch(e){console.error('Exception in error callback',e);}}
|
||||
else{console.error(msg);}}}
|
||||
function getKey(callback){try{if(secret!==null){report(secret);return;}
|
||||
var lock=navigator.mozSettings.createLock();var getreq=lock.get(SECRET_SETTINGS_ID);getreq.onsuccess=function(){secret=getreq.result[SECRET_SETTINGS_ID]||null;report(secret);};getreq.onerror=function(){console.error('Error getting ForwardLock setting',getreq.error);report(null);};}
|
||||
catch(e){console.error('Exception in ForwardLock.getKey():',e);report(null);}
|
||||
function report(secret){if(callback){try{callback(secret);}
|
||||
catch(e){console.error('Exception in ForwardLock.getKey() callback',e);}}}}
|
||||
function getOrCreateKey(callback){getKey(function(key){if(key!==null){report(key);return;}
|
||||
secret=((Math.random()*0xFFFFFFFF)|0)+1;var setting={};setting[SECRET_SETTINGS_ID]=secret;var setreq=navigator.mozSettings.createLock().set(setting);setreq.onsuccess=function(){report(secret);};setreq.onerror=function(){console.error('Failed to set key in ForwardLock.getOrCreateKey()',setreq.error.name);secret=null;};});function report(secret){if(callback){try{callback(secret);}
|
||||
catch(e){console.error('Exception in ForwardLock.getOrCreateKey() callback');}}}}
|
||||
exports.ForwardLock={lockBuffer:lockBuffer,lockBlob:lockBlob,unlockBlob:unlockBlob,mimeSubtype:mimeSubtype,getKey:getKey,getOrCreateKey:getOrCreateKey};}(window));
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
;(function(root,factory){'use strict';if(typeof define==='function'&&define.amd){define(factory);}else if(typeof exports==='object'){module.exports=factory();}else{root.Sanitizer=factory();}}(this,function(){'use strict';var Sanitizer={_entity:/[&<>"'/]/g,_entities:{'&':'&','<':'<','>':'>','"':'"','\'':''','/':'/'},getEntity:function(s){return Sanitizer._entities[s];},escapeHTML:function(strings,...values){var result='';for(var i=0;i<strings.length;i++){result+=strings[i];if(i<values.length){result+=String(values[i]).replace(Sanitizer._entity,Sanitizer.getEntity);}}
|
||||
return result;},createSafeHTML:function(strings,...values){var escaped=Sanitizer.escapeHTML(strings,...values);return{__html:escaped,toString:function(){return'[object WrappedHTMLObject]';},info:'This is a wrapped HTML object. See https://developer.mozilla.or'+'g/en-US/Firefox_OS/Security/Security_Automation for more.'};},unwrapSafeHTML:function(...htmlObjects){var markupList=htmlObjects.map(function(obj){return obj.__html;});return markupList.join('');}};return Sanitizer;}));
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* text_normalizer.js: a basic string normalizer library that provides various
|
||||
* methods to normalize strings of characters
|
||||
*
|
||||
* The following methods are available:
|
||||
* toAscii(string): convert strings containing accented-form characters to
|
||||
* their ASCII equivalent
|
||||
*
|
||||
* escapeHTML(string, boolean): escape HTML tags
|
||||
* escapeRegExp(string): escape regular expressions
|
||||
*/
|
||||
var Normalizer = {
|
||||
/**
|
||||
* Initialize the ASCII normalizer
|
||||
*/
|
||||
initAsciiNormalizer: function normalizer_init() {
|
||||
// Map from lowercase ASCII to all known accented forms of the letter
|
||||
var equivalentChars = {
|
||||
'a': 'áăǎâäȧạȁàảȃāąåḁⱥãǽǣæ',
|
||||
'A': 'ÁĂǍÂÄȦẠȀÀẢȂĀĄÅḀȺÃǼǢÆ',
|
||||
'b': 'ḃḅɓḇƀƃ',
|
||||
'B': 'ḂḄƁḆɃƂ',
|
||||
'c': 'ćčçĉċƈȼ',
|
||||
'C': 'ĆČÇĈĊƇȻ',
|
||||
'd': 'ďḑḓḋḍɗḏđƌð',
|
||||
'D': 'ĎḐḒḊḌƊḎĐƋ',
|
||||
'e': 'éĕěȩêḙëėẹȅèẻȇēę',
|
||||
'E': 'ÉĔĚȨÊḘËĖẸȄÈẺȆĒĘ',
|
||||
'f': 'ḟƒ',
|
||||
'F': 'ḞƑ',
|
||||
'g': 'ǵğǧģĝġɠḡǥ',
|
||||
'G': 'ǴĞǦĢĜĠƓḠǤ',
|
||||
'h': 'ḫȟḩĥⱨḧḣḥħ',
|
||||
'H': 'ḪȞḨĤⱧḦḢḤĦ',
|
||||
'i': 'íĭǐîïịȉìỉȋīįɨĩḭı',
|
||||
'I': 'ÍĬǏÎÏỊȈÌỈȊĪĮƗĨḬ',
|
||||
'j': 'ĵɉ',
|
||||
'J': 'ĴɈ',
|
||||
'k': 'ḱǩķⱪꝃḳƙḵꝁ',
|
||||
'K': 'ḰǨĶⱩꝂḲƘḴꝀ',
|
||||
'l': 'ĺƚľļḽḷⱡꝉḻŀɫł',
|
||||
'L': 'ĹȽĽĻḼḶⱠꝈḺĿⱢŁ',
|
||||
'm': 'ḿṁṃɱ',
|
||||
'M': 'ḾṀṂⱮ',
|
||||
'n': 'ńňņṋṅṇǹɲṉƞñ',
|
||||
'N': 'ŃŇŅṊṄṆǸƝṈȠÑ',
|
||||
'o': 'óŏǒôöȯọőȍòỏơȏꝋꝍōǫøõœ',
|
||||
'O': 'ÓŎǑÔÖȮỌŐȌÒỎƠȎꝊꝌŌǪØÕŒ',
|
||||
'p': 'ṕṗꝓƥᵽꝑ',
|
||||
'P': 'ṔṖꝒƤⱣꝐ',
|
||||
'q': 'ꝗ',
|
||||
'Q': 'Ꝗ',
|
||||
'r': 'ŕřŗṙṛȑȓṟɍɽ',
|
||||
'R': 'ŔŘŖṘṚȐȒṞɌⱤ',
|
||||
's': 'śšşŝșṡṣß',
|
||||
'S': 'ŚŠŞŜȘṠṢ',
|
||||
't': 'ťţṱțⱦṫṭƭṯʈŧ',
|
||||
'T': 'ŤŢṰȚȾṪṬƬṮƮŦ',
|
||||
'u': 'úŭǔûṷüṳụűȕùủưȗūųůũṵ',
|
||||
'U': 'ÚŬǓÛṶÜṲỤŰȔÙỦƯȖŪŲŮŨṴ',
|
||||
'v': 'ṿʋṽ',
|
||||
'V': 'ṾƲṼ',
|
||||
'w': 'ẃŵẅẇẉẁⱳ',
|
||||
'W': 'ẂŴẄẆẈẀⱲ',
|
||||
'x': 'ẍẋ',
|
||||
'X': 'ẌẊ',
|
||||
'y': 'ýŷÿẏỵỳƴỷỿȳɏỹ',
|
||||
'Y': 'ÝŶŸẎỴỲƳỶỾȲɎỸ',
|
||||
'z': 'źžẑⱬżẓȥẕƶ',
|
||||
'Z': 'ŹŽẐⱫŻẒȤẔƵ'
|
||||
};
|
||||
// Create the reverse map (i.e. the accented chars to their ASCII
|
||||
// equivalent) and build the regexp string
|
||||
this._toAsciiForm = {};
|
||||
for (var letter in equivalentChars) {
|
||||
var accentedForms = equivalentChars[letter];
|
||||
for (var i = accentedForms.length - 1; i >= 0; i--) {
|
||||
this._toAsciiForm[accentedForms[i]] = letter;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Convert a string of characters to its ASCII equivalent
|
||||
* @param {string} str a string of characters.
|
||||
* @return {string} the normalized (ASCII) string in lower case.
|
||||
*/
|
||||
toAscii: function normalizer_toAscii(str) {
|
||||
if (!str || typeof str != 'string') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (!this._toAsciiForm) {
|
||||
Normalizer.initAsciiNormalizer();
|
||||
}
|
||||
|
||||
// Convert accented form to ASCII equivalent
|
||||
var result = '';
|
||||
for (var i = 0, len = str.length; i < len; i++) {
|
||||
result += this._toAsciiForm[str.charAt(i)] || str.charAt(i);
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* Escape HTML tags in a string of characters
|
||||
* @param {string} str a string of characters.
|
||||
* @param {boolean} escapeQuotes (optional) escape quotes.
|
||||
* @return {string} the HTML-escaped string.
|
||||
*/
|
||||
escapeHTML: function normalizer_escapeHTML(str, escapeQuotes) {
|
||||
if (Array.isArray(str)) {
|
||||
return Normalizer.escapeHTML(str.join(' '), escapeQuotes);
|
||||
}
|
||||
|
||||
if (!str || typeof str != 'string') {
|
||||
return '';
|
||||
}
|
||||
|
||||
var escaped = str.replace(/&/g, '&').replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
if (escapeQuotes) {
|
||||
return escaped.replace(/"/g, '"').replace(/'/g, ''');
|
||||
}
|
||||
return escaped;
|
||||
},
|
||||
|
||||
unescapeHTML: function normalizer_unescapeHTML(text) {
|
||||
return text.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, '\'');
|
||||
},
|
||||
|
||||
/**
|
||||
* Escape regular expressions in a string of characters
|
||||
* @param {string} str a string of characters.
|
||||
* @return {string} the regexp-escaped string.
|
||||
*/
|
||||
escapeRegExp: function normalizer_escapeRegExp(str) {
|
||||
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
|
||||
}
|
||||
};
|
||||
265
assets/webapps/music-oga.gaiamobile.org/shared/style/confirm.css
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
/* ----------------------------------
|
||||
* Confirm
|
||||
* ---------------------------------- */
|
||||
|
||||
/* Main dialog setup */
|
||||
form[role="dialog"][data-type="confirm"] {
|
||||
background: #2d2d2d;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding-bottom: 7rem;
|
||||
font-size: 0;
|
||||
/* Using font-size: 0; we avoid the unwanted visual space (about 3px)
|
||||
created by white-spaces and break lines in the code betewen inline-block elements */
|
||||
color: #fff;
|
||||
}
|
||||
html[dir="ltr"] form[role="dialog"][data-type="confirm"] { text-align: left; }
|
||||
html[dir="rtl"] form[role="dialog"][data-type="confirm"] { text-align: right; }
|
||||
|
||||
form[role="dialog"][data-type="confirm"]:before {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 0.1rem;
|
||||
height: 100%;
|
||||
margin-inline-start: -0.1rem;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] > section {
|
||||
font-weight: 300;
|
||||
font-size: 2.2rem;
|
||||
color: #FAFAFA;
|
||||
padding: 0 1.5rem;
|
||||
box-sizing: padding-box;
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
overflow-y: scroll;
|
||||
max-height: 100%;
|
||||
vertical-align: middle;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] h1 {
|
||||
font-weight: normal;
|
||||
font-size: 1.6rem;
|
||||
line-height: 1.5em;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
padding: 1rem 1.5rem 0;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
/* Menu & buttons setup */
|
||||
form[role="dialog"][data-type="confirm"] menu {
|
||||
white-space: nowrap;
|
||||
margin: 0;
|
||||
padding: 1.5rem;
|
||||
background: #4d4d4d;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] menu button::-moz-focus-inner {
|
||||
border: none;
|
||||
outline: none;
|
||||
margin-top: -0.2rem; /* To fix line-height bug (697451) */
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] menu button {
|
||||
font-family: sans-serif;
|
||||
font-style: italic;
|
||||
width: 100%;
|
||||
height: 4rem;
|
||||
margin: 0 0 1rem;
|
||||
padding: 0 0.2rem;
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
background: #d8d8d8;
|
||||
border: none;
|
||||
border-radius: 2rem;
|
||||
font-weight: normal;
|
||||
font-size: 1.6rem;
|
||||
line-height: 4rem;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
text-shadow: none;
|
||||
text-decoration: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Recommend */
|
||||
form[role="dialog"][data-type="confirm"] menu button.recommend {
|
||||
background-color: #00caf2;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Danger */
|
||||
form[role="dialog"][data-type="confirm"] menu button.danger {
|
||||
background-color: #e51e1e;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Pressed */
|
||||
form[role="dialog"][data-type="confirm"] menu button:active {
|
||||
background: #00aacc;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Disabled */
|
||||
form[role="dialog"][data-type="confirm"] > menu > button[disabled] {
|
||||
background-color: #565656;
|
||||
color: rgba(255,255,255,0.4);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] > menu > button[disabled].recommend {
|
||||
background-color: #006579;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] > menu > button[disabled].danger {
|
||||
background-color: #730f0f;
|
||||
}
|
||||
|
||||
button[disabled]::-moz-selection {
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] menu button {
|
||||
margin: 0;
|
||||
margin-inline-end: 1rem;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] menu button:last-child {
|
||||
margin-inline-end: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Specific component code
|
||||
**
|
||||
** 1. Text in confirm dialog should not be selectable.
|
||||
*/
|
||||
form[role="dialog"][data-type="confirm"] p:nth-child(2) {
|
||||
margin: 1rem 0 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] p {
|
||||
word-wrap: break-word;
|
||||
margin: 0;
|
||||
padding: 1rem 1.5rem;
|
||||
border-top: 0.1rem solid #686868;
|
||||
line-height: 3rem;
|
||||
-moz-user-select: none; /* 1 */
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] p > span {
|
||||
font-size: 1.5rem;
|
||||
display: block;
|
||||
line-height: 1.7rem;
|
||||
color: rgba(255,255,255,0.6);
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] p img {
|
||||
margin-inline-end: 2rem;
|
||||
}
|
||||
html[dir="ltr"] form[role="dialog"][data-type="confirm"] p img { float: left; }
|
||||
html[dir="rtl"] form[role="dialog"][data-type="confirm"] p img { float: right; }
|
||||
|
||||
form[role="dialog"][data-type="confirm"] p strong {
|
||||
display: block;
|
||||
margin-top: 0.2rem;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] p small {
|
||||
font-size: 1.4rem;
|
||||
font-weight: normal;
|
||||
color: #cbcbcb;
|
||||
display: block;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] dl {
|
||||
border-top: 0.1rem solid #686868;
|
||||
margin: 1rem 0 0;
|
||||
overflow: hidden;
|
||||
padding-top: 1rem;
|
||||
font-size: 1.6rem;
|
||||
line-height: 2.2rem;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] dl > dt {
|
||||
clear: both;
|
||||
width: 7rem;
|
||||
padding-inline-start: 1.5rem;
|
||||
font-weight: 500;
|
||||
text-align: left;
|
||||
}
|
||||
html[dir="ltr"] form[role="dialog"][data-type="confirm"] dl > dt { float: left; }
|
||||
html[dir="rtl"] form[role="dialog"][data-type="confirm"] dl > dt { float: right; text-align: right; }
|
||||
|
||||
form[role="dialog"][data-type="confirm"] dl > dd {
|
||||
padding-inline-end: 1.5rem;
|
||||
font-weight: 300;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: top;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] dl > dd > div {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] figure {
|
||||
margin: 1.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] figure img {
|
||||
padding-inline-end: 1.5rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] figure figcaption {
|
||||
font-size: 2.1rem;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] ul {
|
||||
margin: 0;
|
||||
padding: 2rem 1.5rem;
|
||||
border-top: 0.1rem solid #686868;
|
||||
list-style: none;
|
||||
font-size: 1.6rem;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] ul li {
|
||||
word-wrap: break-word;
|
||||
line-height: 2rem;
|
||||
padding-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] ul li:last-child {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] ul li ul {
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
|
@ -0,0 +1,65 @@
|
|||
<!DOCTYPE html>
|
||||
<html dir="ltr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Confirm</title>
|
||||
<meta name="description" content="Prompts user to take action">
|
||||
|
||||
<link rel="stylesheet" href="../confirm.css">
|
||||
|
||||
<!--
|
||||
- These <style> and <script> elements are only used for the example code;
|
||||
- they are not required for the real use case.
|
||||
-->
|
||||
<style type="text/css">
|
||||
html, body {
|
||||
font-family: sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 10px;
|
||||
background-color: #fff;
|
||||
}
|
||||
body {
|
||||
background: none;
|
||||
}
|
||||
#dir {
|
||||
position: relative;
|
||||
z-index: 999;
|
||||
display: block;
|
||||
direction: ltr;
|
||||
background-color: white;
|
||||
}
|
||||
#dir input {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
window.onload = function(){
|
||||
var input = document.querySelector('#dir input');
|
||||
input.checked = false;
|
||||
input.onchange = function() {
|
||||
document.documentElement.dir = this.checked ? 'rtl' : 'ltr';
|
||||
};
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body role="application">
|
||||
<label id="dir">
|
||||
<input type="checkbox"> RTL mode
|
||||
</label>
|
||||
|
||||
<form role="dialog" data-type="confirm">
|
||||
<section>
|
||||
<h1>Confirmation</h1>
|
||||
<p>Are you sure you want to delete this contact?</p>
|
||||
</section>
|
||||
<menu>
|
||||
<button>Cancel</button>
|
||||
<button class="danger">Delete</button>
|
||||
</menu>
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
<!DOCTYPE html>
|
||||
<html dir="ltr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Confirm</title>
|
||||
<meta name="description" content="Prompts user to take action">
|
||||
|
||||
<link rel="stylesheet" href="../confirm.css">
|
||||
|
||||
<!--
|
||||
- These <style> and <script> elements are only used for the example code;
|
||||
- they are not required for the real use case.
|
||||
-->
|
||||
<style type="text/css">
|
||||
html, body {
|
||||
font-family: sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 10px;
|
||||
background-color: #fff;
|
||||
}
|
||||
body {
|
||||
background: none;
|
||||
}
|
||||
#dir {
|
||||
position: relative;
|
||||
z-index: 999;
|
||||
display: block;
|
||||
direction: ltr;
|
||||
background-color: white;
|
||||
}
|
||||
#dir input {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
window.onload = function(){
|
||||
var input = document.querySelector('#dir input');
|
||||
input.checked = false;
|
||||
input.onchange = function() {
|
||||
document.documentElement.dir = this.checked ? 'rtl' : 'ltr';
|
||||
};
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body role="application">
|
||||
<label id="dir">
|
||||
<input type="checkbox"> RTL mode
|
||||
</label>
|
||||
|
||||
<form role="dialog" data-type="confirm">
|
||||
<section>
|
||||
<h1>Confirmation</h1>
|
||||
<p dir="auto">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
|
||||
</section>
|
||||
<menu>
|
||||
<button>Cancel</button>
|
||||
<button class="danger">Delete</button>
|
||||
</menu>
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
<!DOCTYPE html>
|
||||
<html dir="ltr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Confirm, w/o title</title>
|
||||
<meta name="description" content="Prompts user to take action">
|
||||
|
||||
<link rel="stylesheet" href="../confirm.css">
|
||||
|
||||
<!--
|
||||
- These <style> and <script> elements are only used for the example code;
|
||||
- they are not required for the real use case.
|
||||
-->
|
||||
<style type="text/css">
|
||||
html, body {
|
||||
font-family: sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 10px;
|
||||
background-color: #fff;
|
||||
}
|
||||
body {
|
||||
background: none;
|
||||
}
|
||||
#dir {
|
||||
position: relative;
|
||||
z-index: 999;
|
||||
display: block;
|
||||
direction: ltr;
|
||||
background-color: white;
|
||||
}
|
||||
#dir input {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
window.onload = function(){
|
||||
var input = document.querySelector('#dir input');
|
||||
input.checked = false;
|
||||
input.onchange = function() {
|
||||
document.documentElement.dir = this.checked ? 'rtl' : 'ltr';
|
||||
};
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body role="application">
|
||||
<label id="dir">
|
||||
<input type="checkbox"> RTL mode
|
||||
</label>
|
||||
|
||||
<form role="dialog" data-type="confirm">
|
||||
<section>
|
||||
<p dir="auto">Are you sure you want to delete this contact?</p>
|
||||
</section>
|
||||
<menu>
|
||||
<button>Cancel</button>
|
||||
<button class="danger">Delete</button>
|
||||
</menu>
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,575 @@
|
|||
/* ----------------------------------
|
||||
* Input areas
|
||||
* ---------------------------------- */
|
||||
|
||||
/**
|
||||
* BiDi notes:
|
||||
*
|
||||
* - as the <input>, <textarea> and [contentEditable] elements are filled by
|
||||
* the user, they need a `unicode-bidi: -moz-plaintext` attribute for their
|
||||
* content to be displayed properly (e.g. LTR content in an RTL document,
|
||||
* or vice-versa);
|
||||
*
|
||||
* - consequence: *-inline-start/end properties can still be used on such
|
||||
* elements content direction doesn't impact element's direction
|
||||
*
|
||||
* - however, the one-line inputs must still be aligned along with the
|
||||
* *document* direction: to the left in LTR, to the right in RTL
|
||||
* -- no matter what the *content* direction is.
|
||||
*/
|
||||
|
||||
html[dir="ltr"] input { text-align: left; }
|
||||
html[dir="rtl"] input { text-align: right; }
|
||||
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="email"],
|
||||
input[type="tel"],
|
||||
input[type="search"],
|
||||
input[type="url"],
|
||||
input[type="number"],
|
||||
textarea {
|
||||
font-family: sans-serif;
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 4rem;
|
||||
line-height: 4rem;
|
||||
resize: none;
|
||||
padding: 0 1.5rem;
|
||||
font-size: 1.6rem;
|
||||
border: 0.1rem solid #c7c7c7;
|
||||
border-radius: 0;
|
||||
box-shadow: none; /* override the box-shadow from the system (performance issue) */
|
||||
color: #333;
|
||||
background: #fff;
|
||||
margin: 0 0 1rem;
|
||||
unicode-bidi: -moz-plaintext;
|
||||
}
|
||||
|
||||
label:active {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
textarea {
|
||||
height: 10rem;
|
||||
max-height: 10rem;
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
||||
input::-moz-placeholder,
|
||||
textarea::-moz-placeholder {
|
||||
color: #a9a9a9;
|
||||
opacity: 1;
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
input[disabled],
|
||||
textarea[disabled] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.skin-dark input[type="text"],
|
||||
.skin-dark input[type="password"],
|
||||
.skin-dark input[type="email"],
|
||||
.skin-dark input[type="tel"],
|
||||
.skin-dark input[type="search"],
|
||||
.skin-dark input[type="url"],
|
||||
.skin-dark input[type="number"],
|
||||
.skin-dark textarea {
|
||||
color: #fff;
|
||||
background-color: transparent;
|
||||
border-color: #454545;
|
||||
}
|
||||
|
||||
form p {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
form p input + button[type="reset"],
|
||||
form p textarea + button[type="reset"] {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
padding: 0;
|
||||
border: none;
|
||||
font-size: 0;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
background: url(input_areas/images/clear.png) no-repeat 50% 50% / 2.4rem auto;
|
||||
}
|
||||
html[dir="ltr"] form p input + button[type="reset"],
|
||||
html[dir="ltr"] form p textarea + button[type="reset"] {
|
||||
right: -0.3rem;
|
||||
}
|
||||
html[dir="rtl"] form p input + button[type="reset"],
|
||||
html[dir="rtl"] form p textarea + button[type="reset"] {
|
||||
left: -0.3rem;
|
||||
}
|
||||
|
||||
.skin-dark p input + button[type="reset"],
|
||||
.skin-dark p textarea + button[type="reset"] {
|
||||
background-image: url(input_areas/images/clear_dark.png);
|
||||
}
|
||||
|
||||
/* To avoid colission with BB butons */
|
||||
li input + button[type="reset"]:after,
|
||||
li textarea + button[type="reset"]:after {
|
||||
background: none;
|
||||
}
|
||||
|
||||
textarea {
|
||||
padding: 1.2rem;
|
||||
}
|
||||
|
||||
html[dir="ltr"] form p input:focus { padding-right: 3rem; }
|
||||
html[dir="rtl"] form p input:focus { padding-left: 3rem; }
|
||||
|
||||
form p input:focus + button[type="reset"],
|
||||
form p textarea:focus + button[type="reset"] {
|
||||
opacity: 1;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
/* Fieldset */
|
||||
fieldset {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
margin: 1.5rem 0 0;
|
||||
padding: 0;
|
||||
font-size: 2rem;
|
||||
line-height: 1em;
|
||||
background: none;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
fieldset legend,
|
||||
input[type="date"],
|
||||
input[type="time"],
|
||||
input[type="datetime"],
|
||||
input[type="datetime-local"] {
|
||||
border: 0.1rem solid #c7c7c7;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
font-family: sans-serif;
|
||||
font-style: italic;
|
||||
font-size: 1.6rem;
|
||||
margin: 0 0 1.5rem;
|
||||
padding: 0 1.5rem;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
height: 4rem;
|
||||
color: #333;
|
||||
border-radius: 0;
|
||||
background-color: #fff;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
html[dir="ltr"] fieldset legend,
|
||||
html[dir="ltr"] input[type="date"],
|
||||
html[dir="ltr"] input[type="time"],
|
||||
html[dir="ltr"] input[type="datetime"],
|
||||
html[dir="ltr"] input[type="datetime-local"] {
|
||||
background-image: url(input_areas/images/dialog.svg);
|
||||
background-position: right 1rem bottom 1rem;
|
||||
}
|
||||
html[dir="rtl"] fieldset legend,
|
||||
html[dir="rtl"] input[type="date"],
|
||||
html[dir="rtl"] input[type="time"],
|
||||
html[dir="rtl"] input[type="datetime"],
|
||||
html[dir="rtl"] input[type="datetime-local"] {
|
||||
background-image: url(input_areas/images/dialog_rtl.svg);
|
||||
background-position: left 1rem bottom 1rem;
|
||||
}
|
||||
|
||||
fieldset legend {
|
||||
margin: 0 0 1rem;
|
||||
padding: 1rem 1.5rem 0;
|
||||
background-color: rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
fieldset[disabled] {
|
||||
opacity: 0.5;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.skin-dark fieldset legend,
|
||||
.skin-dark input[type="date"],
|
||||
.skin-dark input[type="time"],
|
||||
.skin-dark input[type="datetime"],
|
||||
.skin-dark input[type="datetime-local"] {
|
||||
color: #fff;
|
||||
background-color: transparent;
|
||||
border-color: #454545;
|
||||
}
|
||||
|
||||
fieldset[disabled] legend,
|
||||
input[type="date"][disabled],
|
||||
input[type="time"][disabled],
|
||||
input[type="datetime"][disabled],
|
||||
input[type="datetime-local"][disabled] {
|
||||
background-color: transparent;
|
||||
}
|
||||
html[dir="ltr"] fieldset[disabled] legend,
|
||||
html[dir="ltr"] input[type="date"][disabled],
|
||||
html[dir="ltr"] input[type="time"][disabled],
|
||||
html[dir="ltr"] input[type="datetime"][disabled],
|
||||
html[dir="ltr"] input[type="datetime-local"][disabled] {
|
||||
background-image: url(input_areas/images/dialog_disabled.svg);
|
||||
}
|
||||
html[dir="rtl"] fieldset[disabled] legend,
|
||||
html[dir="rtl"] input[type="date"][disabled],
|
||||
html[dir="rtl"] input[type="time"][disabled],
|
||||
html[dir="rtl"] input[type="datetime"][disabled],
|
||||
html[dir="rtl"] input[type="datetime-local"][disabled] {
|
||||
background-image: url(input_areas/images/dialog_disabled_rtl.svg);
|
||||
}
|
||||
|
||||
input[type="date"]:focus,
|
||||
input[type="time"]:focus,
|
||||
input[type="datetime"]:focus,
|
||||
input[type="datetime-local"]:focus {
|
||||
box-shadow: none;
|
||||
border-bottom-color: #c7c7c7;
|
||||
}
|
||||
|
||||
.skin-dark input[type="date"]:focus,
|
||||
.skin-dark input[type="time"]:focus,
|
||||
.skin-dark input[type="datetime"]:focus,
|
||||
.skin-dark input[type="datetime-local"]:focus {
|
||||
box-shadow: none;
|
||||
border-bottom-color: #454545;
|
||||
}
|
||||
|
||||
input[type="date"]:active,
|
||||
input[type="time"]:active,
|
||||
input[type="datetime"]:active,
|
||||
input[type="datetime-local"]:active {
|
||||
background-color: #b2f2ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.skin-dark input[type="date"]:active,
|
||||
.skin-dark input[type="time"]:active,
|
||||
.skin-dark input[type="datetime"]:active,
|
||||
.skin-dark input[type="datetime-local"]:active {
|
||||
background-color: #00aacc;
|
||||
background-image: url(input_areas/images/dialog_active.svg);
|
||||
}
|
||||
|
||||
/* fix for required inputs with wrong or empty value e.g. [type=email] */
|
||||
input:invalid,
|
||||
textarea:invalid,
|
||||
.skin-dark input:invalid,
|
||||
.skin-dark textarea:invalid {
|
||||
color: #b90000;
|
||||
}
|
||||
|
||||
input:focus,
|
||||
textarea:focus,
|
||||
.skin-dark input:focus,
|
||||
.skin-dark textarea:focus {
|
||||
box-shadow: inset 0 -0.1rem 0 #00caf2;
|
||||
border-bottom-color: #00caf2;
|
||||
}
|
||||
|
||||
input:invalid:focus,
|
||||
textarea:invalid:focus,
|
||||
.skin-dark input:invalid:focus,
|
||||
.skin-dark textarea:invalid:focus {
|
||||
box-shadow: inset 0 -0.1rem 0 #820000;
|
||||
border-bottom-color: #820000;
|
||||
}
|
||||
|
||||
input[type="range"]:focus,
|
||||
.skin-dark input[type="range"]:focus {
|
||||
box-shadow: none;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
/* Tidy (search/submit) */
|
||||
form[role="search"] {
|
||||
position: relative;
|
||||
height: 3.7rem;
|
||||
background: #f4f4f4;
|
||||
}
|
||||
|
||||
form[role="search"].skin-dark {
|
||||
background: #202020;
|
||||
}
|
||||
|
||||
form[role="search"] p {
|
||||
padding: 0 1.5rem;
|
||||
padding-inline-start: 3rem;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
form[role="search"] p input,
|
||||
form[role="search"] p textarea {
|
||||
height: 3.7rem;
|
||||
border: none;
|
||||
background: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
form[role="search"] p textarea {
|
||||
padding: 1rem 0 0;
|
||||
}
|
||||
|
||||
form[role="search"] p input::-moz-placeholder {
|
||||
background-image: url(input_areas/images/search.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 3rem;
|
||||
}
|
||||
html[dir="ltr"] form[role="search"] p input::-moz-placeholder {
|
||||
background-position: right -0.5rem center;
|
||||
}
|
||||
html[dir="rtl"] form[role="search"] p input::-moz-placeholder {
|
||||
background-position: left -0.5rem center;
|
||||
}
|
||||
|
||||
form[role="search"].skin-dark p input::-moz-placeholder {
|
||||
background-image: url(input_areas/images/search_dark.svg);
|
||||
}
|
||||
|
||||
form[role="search"] p input:focus::-moz-placeholder {
|
||||
background: none;
|
||||
}
|
||||
|
||||
form[role="search"] p input:invalid,
|
||||
form[role="search"] p textarea:invalid,
|
||||
form[role="search"] p input:focus,
|
||||
form[role="search"] p textarea:focus {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
form[role="search"].skin-dark p input,
|
||||
form[role="search"].skin-dark p textarea {
|
||||
color: #fff;
|
||||
background: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
form[role="search"] button[type="submit"] {
|
||||
min-width: 6rem;
|
||||
height: 3.7rem;
|
||||
padding: 0 1.5rem;
|
||||
border: none;
|
||||
color: #00aac5;
|
||||
font-weight: normal;
|
||||
font-size: 1.6rem;
|
||||
line-height: 3.7rem;
|
||||
width: auto;
|
||||
border-radius: 0;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
background-image: none;
|
||||
background-color: unset;
|
||||
font-style: italic;
|
||||
overflow: visible;
|
||||
}
|
||||
html[dir="ltr"] form[role="search"] button[type="submit"] { float: right; }
|
||||
html[dir="rtl"] form[role="search"] button[type="submit"] { float: left; }
|
||||
|
||||
form[role="search"] button[type="submit"]:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
offset-inline-start: -0.1rem;
|
||||
top: 0.7rem;
|
||||
bottom: 0.7rem;
|
||||
width: 0.1rem;
|
||||
background: #c7c7c7;
|
||||
}
|
||||
|
||||
form[role="search"] button[type="submit"].icon {
|
||||
font-size: 0;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: 3rem;
|
||||
}
|
||||
|
||||
form[role="search"] p input + button[type="reset"]{
|
||||
height: 3.7rem;
|
||||
offset-inline-end: 0.5rem;
|
||||
}
|
||||
|
||||
form[role="search"].skin-dark button[type="submit"]:after {
|
||||
background-color: #575757;
|
||||
}
|
||||
|
||||
form[role="search"] button[type="submit"] + p > textarea {
|
||||
height: 3.7rem;
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
||||
form[role="search"] button[type="submit"] + p button {
|
||||
height: 3.7rem;
|
||||
}
|
||||
|
||||
form[role="search"].full button[type="submit"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
form[role="search"] button.icon:active,
|
||||
form[role="search"] button[type="submit"]:active {
|
||||
background-color: #b2f2ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
form[role="search"].skin-dark button.icon:active,
|
||||
form[role="search"].skin-dark button[type="submit"]:active {
|
||||
background: #00aacc;
|
||||
}
|
||||
|
||||
form[role="search"] button[type="submit"][disabled] {
|
||||
color: #adadad;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
form button::-moz-focus-inner {
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* .bb-editable - e.g email & SMS recipients */
|
||||
.bb-editable [contenteditable] {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
max-width: calc(100% - 1.4rem);
|
||||
overflow: hidden;
|
||||
padding: 0 1.5rem;
|
||||
margin: 0 0 0.6rem;
|
||||
line-height: 2.8rem;
|
||||
border-radius: 1.4rem;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 1.6rem;
|
||||
font-style: italic;
|
||||
white-space: nowrap;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
html[dir="ltr"] .bb-editable [contenteditable].icon {
|
||||
padding-right: 3.7rem;
|
||||
}
|
||||
html[dir="rtl"] .bb-editable [contenteditable].icon {
|
||||
padding-left: 3.7rem;
|
||||
}
|
||||
|
||||
.bb-editable [contenteditable="false"].invalid {
|
||||
background-color: #fedcdc;
|
||||
padding: 0 1.5rem;
|
||||
}
|
||||
html[dir="ltr"] .bb-editable [contenteditable="false"].invalid { padding-left: 3.3rem; }
|
||||
html[dir="rtl"] .bb-editable [contenteditable="false"].invalid { padding-right: 3.3rem; }
|
||||
|
||||
.bb-editable [contenteditable="false"].invalid:before {
|
||||
content: "!";
|
||||
position: absolute;
|
||||
top: 0.6rem;
|
||||
display: block;
|
||||
width: 1.7rem;
|
||||
height: 1.6rem;
|
||||
padding: 0;
|
||||
border-radius: 50%;
|
||||
line-height: 1.6rem;
|
||||
font-size: 1.2rem;
|
||||
text-align: center;
|
||||
text-indent: -0.1rem;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
background-color: #b80404;
|
||||
}
|
||||
html[dir="ltr"] .bb-editable [contenteditable="false"].invalid:before { left: 0.8rem; }
|
||||
html[dir="rtl"] .bb-editable [contenteditable="false"].invalid:before { right: 0.8rem; }
|
||||
|
||||
.bb-editable [contenteditable="false"].invalid:hover:before,
|
||||
.bb-editable [contenteditable="false"].invalid:active:before {
|
||||
color: #b2f2ff;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.bb-editable [contenteditable]:hover,
|
||||
.bb-editable [contenteditable]:active,
|
||||
.bb-editable [contenteditable].invalid:hover,
|
||||
.bb-editable [contenteditable].invalid:active {
|
||||
color: #fff;
|
||||
background-color: #b2f2ff;
|
||||
}
|
||||
|
||||
.bb-editable [contenteditable].icon:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0.7rem;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 3rem;
|
||||
}
|
||||
html[dir="ltr"] .bb-editable [contenteditable].icon:after {
|
||||
right: 0;
|
||||
background-position: -0.7rem -3.8rem;
|
||||
}
|
||||
html[dir="rtl"] .bb-editable [contenteditable].icon:after {
|
||||
left: 0;
|
||||
background-position: 0.7rem -3.8rem;
|
||||
}
|
||||
|
||||
html[dir="ltr"] .bb-editable [contenteditable].icon:hover:after,
|
||||
html[dir="ltr"] .bb-editable [contenteditable].icon:active:after {
|
||||
background-position: -0.7rem -0.8rem;
|
||||
}
|
||||
html[dir="rtl"] .bb-editable [contenteditable].icon:hover:after,
|
||||
html[dir="rtl"] .bb-editable [contenteditable].icon:active:after {
|
||||
background-position: 0.7rem -0.8rem;
|
||||
}
|
||||
|
||||
html[dir="ltr"] .bb-editable [contenteditable].invalid.icon {
|
||||
padding-right: 3.7rem;
|
||||
}
|
||||
html[dir="rtl"] .bb-editable [contenteditable].invalid.icon {
|
||||
padding-left: 3.7rem;
|
||||
}
|
||||
|
||||
html[dir="ltr"] .bb-editable [contenteditable].invalid.icon:after {
|
||||
background-position: -0.7rem -6.8rem;
|
||||
}
|
||||
html[dir="rtl"] .bb-editable [contenteditable].invalid.icon:after {
|
||||
background-position: 0.7rem -6.8rem;
|
||||
}
|
||||
|
||||
html[dir="ltr"] .bb-editable [contenteditable].invalid.icon:hover:after,
|
||||
html[dir="ltr"] .bb-editable [contenteditable].invalid.icon:active:after {
|
||||
background-position: -0.7rem -0.8rem;
|
||||
}
|
||||
html[dir="rtl"] .bb-editable [contenteditable].invalid.icon:hover:after,
|
||||
html[dir="rtl"] .bb-editable [contenteditable].invalid.icon:active:after {
|
||||
background-position: 0.7rem -0.8rem;
|
||||
}
|
||||
|
||||
.bb-editable [contenteditable="true"],
|
||||
.bb-editable [contenteditable="true"]:hover,
|
||||
.skin-comms .bb-editable [contenteditable="true"]:hover {
|
||||
padding: 0 0.2rem;
|
||||
white-space: normal;
|
||||
font-size: 1.8rem;
|
||||
font-style: normal;
|
||||
color: #000;
|
||||
background: none repeat scroll 0 0 transparent;
|
||||
}
|
||||
|
||||
.skin-comms .bb-editable [contenteditable]:hover,
|
||||
.skin-comms .bb-editable [contenteditable]:active {
|
||||
color: #fff;
|
||||
background-color: #29bbb5;
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="9" viewBox="0 0 9 9"><path fill="#00AAC5" enable-background="new" d="M9 0L9 9 0 9"/></svg>
|
||||
|
After Width: | Height: | Size: 148 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="9" viewBox="0 0 9 9"><path fill="#B2F2FF" d="M9 0v9h-9"/></svg>
|
||||
|
After Width: | Height: | Size: 121 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="9" viewBox="0 0 9 9"><path opacity=".5" fill="#A9A9A9" d="M9 0L9 9 0 9"/></svg>
|
||||
|
After Width: | Height: | Size: 137 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="9" viewBox="0 0 9 9"><path opacity=".5" fill="#A9A9A9" enable-background="new" d="M0 0L0 9 9 9"/></svg>
|
||||
|
After Width: | Height: | Size: 161 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="9" viewBox="0 0 9 9"><path fill="#00AAC5" enable-background="new" d="M0 0L0 9 9 9"/></svg>
|
||||
|
After Width: | Height: | Size: 148 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30"><path fill-rule="evenodd" clip-rule="evenodd" fill="#424242" d="M23.385 21.494c.266.266.057.903-.465 1.426s-1.16.729-1.426.465l-4.041-4.039c-1.01.656-2.21 1.047-3.505 1.047-3.561 0-6.448-2.885-6.448-6.446 0-3.56 2.887-6.446 6.448-6.446 3.562 0 6.449 2.887 6.449 6.446 0 1.297-.393 2.499-1.051 3.509l4.041 4.039h-.002zm-9.437-12.459c-2.712 0-4.914 2.198-4.914 4.912s2.202 4.913 4.914 4.913c2.714 0 4.914-2.199 4.914-4.913-.001-2.714-2.2-4.912-4.914-4.912z"/></svg>
|
||||
|
After Width: | Height: | Size: 546 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30"><path fill-rule="evenodd" clip-rule="evenodd" fill="#8F9091" d="M23.385 21.494c.266.266.057.903-.465 1.426s-1.16.729-1.426.465l-4.041-4.039c-1.01.656-2.21 1.047-3.505 1.047-3.561 0-6.448-2.885-6.448-6.446 0-3.56 2.887-6.446 6.448-6.446 3.562 0 6.449 2.887 6.449 6.446 0 1.297-.393 2.499-1.051 3.509l4.041 4.039h-.002zm-9.437-12.459c-2.712 0-4.914 2.198-4.914 4.912s2.202 4.913 4.914 4.913c2.714 0 4.914-2.199 4.914-4.913-.001-2.714-2.2-4.912-4.914-4.912z"/></svg>
|
||||
|
After Width: | Height: | Size: 546 B |
|
|
@ -0,0 +1,236 @@
|
|||
<!DOCTYPE html>
|
||||
<html dir="ltr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Input areas</title>
|
||||
<link rel="stylesheet" href="../input_areas.css">
|
||||
<link rel="stylesheet" href="../../elements/gaia-icons/gaia-icons-embedded.css">
|
||||
<link rel="stylesheet" href="../../elements/gaia-icons/bidi-helper.css">
|
||||
|
||||
<!--
|
||||
- These <style> and <script> elements are only used for the example code,
|
||||
- they are not needed for the real use case.
|
||||
-->
|
||||
<style>
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 10px;
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
|
||||
label.bb-docs {
|
||||
font-family: sans-serif;
|
||||
font-size: 1.2rem;
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
|
||||
h2.bb-docs {
|
||||
font-family: sans-serif;
|
||||
padding: 0.4rem 3rem;
|
||||
margin: -0.1rem 0 0;
|
||||
border: solid 0.1rem #e8e8e8;
|
||||
color: #666;
|
||||
font-size: 1.8rem;
|
||||
font-weight: 300;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
form { margin: 1rem 1.5rem; }
|
||||
|
||||
form[role="search"] { margin: 1rem 0; }
|
||||
|
||||
div.skin-dark {
|
||||
background: #000;
|
||||
}
|
||||
|
||||
div.skin-dark.margins {
|
||||
margin: 1rem -1.5rem;
|
||||
padding: 1.5rem 1.5rem 0.5rem;
|
||||
}
|
||||
|
||||
/**
|
||||
* .bb-editable
|
||||
* Added properties for this example, don't add on app.
|
||||
*/
|
||||
.bb-editable {
|
||||
padding: 1.5rem 1rem 0.5rem;
|
||||
background: #bbb;
|
||||
}
|
||||
|
||||
/**
|
||||
* .icon-email:before
|
||||
* Define the background-image with custom icon for App.
|
||||
* Attention, the pseudo-element is required for compatibility with Building Blocks.
|
||||
*
|
||||
* Example:
|
||||
* .icon-mms:before { background-image: url(...); }
|
||||
*/
|
||||
.icon-email:after {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAABaCAYAAACv+ebYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAASRJREFUeNrsl8ENgjAUhqlhAEfxQDyzgXdOjoCT0ClYg54Nu+gGtcRiAlJ5fQ9CDP+XFJOW+hlo6/uTBADw76hfg9ba0n0cBd//VErp6FlO3FgZDevn9pO50u4iEXPkn/ul4hj54L4lxBT51/hS4odrVUA62b+UOCSvfP+q4rE8KF1DTF5w3JPLio9Gx1T/Yauzen/idGb8Jv13QgEAAAAAyNJi27bitJhlmeYUAhfXcoHYuKY5pU/uJ3OluaTm4sjN3JOiFnsxckN5PTFVJkVuqGsitrw9hRaL7ycvxFhxt7WuE3Lt+1ct6MfyXhq131PmVukkpX+n5RYRhn24IC0iLQIAAABIi2/uRSFOi+e6RlpEWkRaRFpEWkRaRFoEYG+8BBgAvaeWTjgXDaoAAAAASUVORK5CYII=);
|
||||
}
|
||||
|
||||
</style>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
document.getElementById('dir').checked = false;
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body role="application">
|
||||
<p dir="ltr">
|
||||
<label class="bb-docs">
|
||||
<input id="dir" type="checkbox" checked="false"
|
||||
onchange="document.documentElement.dir = this.checked ? 'rtl' : 'ltr'">
|
||||
RTL mode
|
||||
</label>
|
||||
</p>
|
||||
<h2 class="bb-docs">Default inputs</h2>
|
||||
<form>
|
||||
<p>
|
||||
<input dir="auto" type="text" placeholder="Placeholder">
|
||||
<button type="reset">Clear</button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<textarea placeholder="Placeholder in textarea"></textarea>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<input dir="auto" type="text" placeholder="Placeholder" value="Some written text" required>
|
||||
<button type="reset">Clear</button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<input dir="auto" type="text" placeholder="Disabled" disabled required>
|
||||
<button type="reset">Clear</button>
|
||||
</p>
|
||||
|
||||
<div class="skin-dark margins">
|
||||
<p>
|
||||
<input dir="auto" type="text" placeholder="Placeholder" value="Some written text">
|
||||
<button type="reset">Clear</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<h2 class="bb-docs">Required inputs</h2>
|
||||
<form>
|
||||
<p>
|
||||
<input dir="auto" type="text" placeholder="Placeholder" required>
|
||||
<button type="reset">Clear</button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<textarea placeholder="Placeholder in textarea" required></textarea>
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<h2 class="bb-docs">Date/time inputs</h2>
|
||||
<form>
|
||||
<p>
|
||||
<input dir="auto" disabled type="date" placeholder="YYYY-MM-DD">
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<input dir="auto" type="time" placeholder="hh:mm:ss">
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<h2 class="bb-docs">Fieldset</h2>
|
||||
<form>
|
||||
<fieldset>
|
||||
<legend class="action">Mobile</legend>
|
||||
<section>
|
||||
<p>
|
||||
<input dir="ltr" type="tel" placeholder="Phone number">
|
||||
<button type="reset">Clear</button>
|
||||
</p>
|
||||
<p>
|
||||
<input dir="auto" type="text" placeholder="Name" value="Jessy James">
|
||||
<button type="reset">Clear</button>
|
||||
</p>
|
||||
</section>
|
||||
</fieldset>
|
||||
|
||||
<fieldset disabled>
|
||||
<legend>Work</legend>
|
||||
<section>
|
||||
<p>
|
||||
<input dir="ltr" type="tel" placeholder="Email">
|
||||
<button type="reset">Clear</button>
|
||||
</p>
|
||||
</section>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
<h2 class="bb-docs">Forms: Input text</h2>
|
||||
<form role="search">
|
||||
<p>
|
||||
<input dir="auto" type="text" placeholder="Search…">
|
||||
<button type="reset">Clear</button>
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<form role="search">
|
||||
<button type="submit">Cancel</button>
|
||||
<p>
|
||||
<input dir="auto" type="text" placeholder="Search…" value="Some text here">
|
||||
<button type="reset">Clear</button>
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<div class="skin-dark">
|
||||
<h2 class="bb-docs">Skin dark</h2>
|
||||
<form role="search" class="skin-dark">
|
||||
<p>
|
||||
<input dir="auto" type="text" placeholder="Search…">
|
||||
<button type="reset">Clear</button>
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<form role="search" class="skin-dark">
|
||||
<button type="submit">Cancel</button>
|
||||
<p>
|
||||
<input dir="auto" type="text" placeholder="Search…" value="Some text here">
|
||||
<button type="reset">Clear</button>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<h2 class="bb-docs">Forms: Text area</h2>
|
||||
<form role="search" class="bottom">
|
||||
<!-- this button should be enabled after start typing in the input field-->
|
||||
<button type="submit" disabled>Send</button>
|
||||
<p>
|
||||
<textarea></textarea>
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<form role="search" class="bottom">
|
||||
<button type="submit">Send</button>
|
||||
<p>
|
||||
<textarea>Some text here</textarea>
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<form role="search" class="bottom">
|
||||
<button type="submit" class="icon" data-icon="send" aria-hidden="true">Send</button>
|
||||
<p>
|
||||
<textarea>Some text here</textarea>
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<h2 class="bb-docs">Content Editable</h2>
|
||||
<ul class="bb-editable">
|
||||
<li dir="auto" contenteditable="false">Travis Gray Travis Gray</li>
|
||||
<li dir="auto" contenteditable="false" class="invalid">Lucy B.</li>
|
||||
<li dir="auto" contenteditable="false" class="icon icon-email">Mary</li>
|
||||
<li dir="auto" contenteditable="false" class="invalid icon icon-email">Paul C.</li>
|
||||
<li dir="auto" contenteditable="true">John</li>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
/* ----------------------------------
|
||||
* Progress + activities
|
||||
* ---------------------------------- */
|
||||
|
||||
/* Spinner */
|
||||
progress:not([value]) {
|
||||
background: url(progress_activity/images/ui/default.png) no-repeat center center / 100% auto;
|
||||
animation: 0.9s rotate infinite steps(30);
|
||||
width: 2.9rem;
|
||||
height: 2.9rem;
|
||||
border: none;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
progress:not([value]).light {
|
||||
background-image: url(progress_activity/images/ui/light.png);
|
||||
}
|
||||
|
||||
progress:not([value])::-moz-progress-bar {
|
||||
background: none;
|
||||
}
|
||||
|
||||
/* Progress bar */
|
||||
progress[value] {
|
||||
width: 100%;
|
||||
background: #333;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
height: 0.4rem;
|
||||
display: block;
|
||||
}
|
||||
|
||||
progress[value]::-moz-progress-bar {
|
||||
background: #01c5ed;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
/* Progress bar */
|
||||
progress[value].pack-activity {
|
||||
background-size: 15rem;
|
||||
}
|
||||
html[dir="ltr"] progress[value].pack-activity {
|
||||
animation: 1.5s move-right steps(15) infinite;
|
||||
background-image: repeating-linear-gradient(135deg, #92F4FE, #92F4FE 5rem, #00CDF0 5rem, #00CDF0 10rem);
|
||||
}
|
||||
html[dir="rtl"] progress[value].pack-activity {
|
||||
animation: 1.5s move-left steps(15) infinite;
|
||||
background-image: repeating-linear-gradient(-135deg, #92F4FE, #92F4FE 5rem, #00CDF0 5rem, #00CDF0 10rem);
|
||||
}
|
||||
|
||||
/* Labels */
|
||||
p[role="status"] {
|
||||
padding: 0.5rem;
|
||||
font-weight: 300;
|
||||
font-size: 2.25rem;
|
||||
line-height: 1.4em;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
p[role="status"] progress:not([value]) {
|
||||
margin-inline-end: 0.5rem;
|
||||
}
|
||||
|
||||
p[role="status"] progress:not([value]) + span {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
p[role="status"] span {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
/* Progress steps */
|
||||
.bb-steps {
|
||||
position: relative;
|
||||
height: 0.3rem;
|
||||
}
|
||||
html[dir="ltr"] .bb-steps { transform: scaleX(1); }
|
||||
html[dir="rtl"] .bb-steps { transform: scaleX(-1); }
|
||||
|
||||
.bb-steps:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 0;
|
||||
left: 0;
|
||||
top: 0.1rem;
|
||||
right: 0;
|
||||
border-top: 0.1rem solid #b7b7b7;
|
||||
border-bottom: 0.1rem solid #fff;
|
||||
}
|
||||
|
||||
.bb-steps progress[value] {
|
||||
position: absolute;
|
||||
height: 0.3rem;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background: #858585;
|
||||
transition: transform 0.35s cubic-bezier(0, 1, 0.5, 1.1);
|
||||
}
|
||||
|
||||
.bb-steps progress[value]::-moz-progress-bar {
|
||||
background: none;
|
||||
}
|
||||
|
||||
/* Animations */
|
||||
@keyframes rotate {
|
||||
from { transform: rotate(1deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
@keyframes move-right {
|
||||
from { background-position: -15rem 0; }
|
||||
to { background-position: 0 0; }
|
||||
}
|
||||
|
||||
@keyframes move-left {
|
||||
from { background-position: 0 0; }
|
||||
to { background-position: -15rem 0; }
|
||||
}
|
||||
|
After Width: | Height: | Size: 99 B |
|
After Width: | Height: | Size: 789 B |
|
After Width: | Height: | Size: 502 B |
|
|
@ -0,0 +1,155 @@
|
|||
<!DOCTYPE html>
|
||||
<html dir="ltr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Progress & Activity Indicators</title>
|
||||
<meta name="description" content="Providing user with visual feedback that a process is active">
|
||||
|
||||
<link rel="stylesheet" href="../../style/headers.css">
|
||||
<link rel="stylesheet" href="../../style/confirm.css">
|
||||
<link rel="stylesheet" href="../progress_activity.css">
|
||||
|
||||
<!--
|
||||
- These <style> and <script> elements are only used for the example code,
|
||||
- they are not needed for the real use case.
|
||||
-->
|
||||
<style>
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 10px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
body { background: none; }
|
||||
|
||||
h2.bb-docs {
|
||||
font-size: 1.8rem;
|
||||
font-family: sans-serif;
|
||||
font-weight: 300;
|
||||
color: #666;
|
||||
margin: 10px 0;
|
||||
background-color: #f5f5f5;
|
||||
padding: 0.4rem;
|
||||
padding-inline-start: 3rem;
|
||||
border: solid 1px #e8e8e8;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] {
|
||||
position: relative;
|
||||
height: 30rem;
|
||||
}
|
||||
|
||||
form[role="dialog"][data-type="confirm"] > section {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.bb-steps progress[value] {
|
||||
width: 25%;
|
||||
transform: translateX(100%);
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
window.onload = function(){
|
||||
document.getElementById('dir').checked = false;
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body role="application">
|
||||
<p dir="ltr">
|
||||
<label class="bb-docs">
|
||||
<input id="dir" type="checkbox" checked="false"
|
||||
onchange="document.documentElement.dir = this.checked ? 'rtl' : 'ltr'">
|
||||
RTL mode
|
||||
</label>
|
||||
</p>
|
||||
<section role="region">
|
||||
<h2 class="bb-docs">Spinner</h2>
|
||||
<div style="text-align: center">
|
||||
<progress></progress>
|
||||
</div>
|
||||
|
||||
<h2 class="bb-docs">Activity bar</h2>
|
||||
<progress class="pack-activity" value="0" max="100"></progress>
|
||||
|
||||
<h2 class="bb-docs">Progress steps</h2>
|
||||
<p class="bb-steps">
|
||||
<progress value="2" max="4"></progress>
|
||||
</p>
|
||||
|
||||
<h2 class="bb-docs">Progress bar</h2>
|
||||
<progress value="80" max="100"></progress>
|
||||
|
||||
<h2 class="bb-docs">Progress + activity bar</h2>
|
||||
<progress class="pack-activity" value="80" max="100"></progress>
|
||||
</section>
|
||||
|
||||
<h2 class="bb-docs">Progress bar + Confirm BB</h2>
|
||||
<form role="dialog" data-type="confirm">
|
||||
<section>
|
||||
<h1>Name of the action</h1>
|
||||
<p style="text-align: center">
|
||||
<progress></progress>
|
||||
</p>
|
||||
</section>
|
||||
<menu>
|
||||
<button class="full">Cancel</button>
|
||||
</menu>
|
||||
</form>
|
||||
|
||||
<br/>
|
||||
|
||||
<form role="dialog" data-type="confirm">
|
||||
<section>
|
||||
<h1>Name of the action</h1>
|
||||
<p role="status">
|
||||
<span>80%</span>
|
||||
<progress value="80" max="100"></progress>
|
||||
</p>
|
||||
</section>
|
||||
<menu>
|
||||
<button class="full">Cancel</button>
|
||||
</menu>
|
||||
</form>
|
||||
|
||||
<br/>
|
||||
|
||||
<form role="dialog" data-type="confirm">
|
||||
<section>
|
||||
<h1>Name of the action</h1>
|
||||
<p role="status">
|
||||
<progress class="pack-activity" value="0" max="100"></progress>
|
||||
</p>
|
||||
</section>
|
||||
<menu>
|
||||
<button class="full">Cancel</button>
|
||||
</menu>
|
||||
</form>
|
||||
|
||||
|
||||
<h2 class="bb-docs">Progress bar in Headers</h2>
|
||||
<section role="region">
|
||||
<header>
|
||||
<a href="#"><span class="icon icon-back">back</span></a>
|
||||
<h1>Song title</h1>
|
||||
</header>
|
||||
<progress value="80" max="100"></progress>
|
||||
<header>
|
||||
<h2>Subheader text</h2>
|
||||
</header>
|
||||
</section>
|
||||
|
||||
<section role="region">
|
||||
<header>
|
||||
<a href="#"><span class="icon icon-back">back</span></a>
|
||||
<h1>Song title</h1>
|
||||
</header>
|
||||
<progress class="pack-activity" value="0" max="100"></progress>
|
||||
<header>
|
||||
<h2>Subheader text</h2>
|
||||
</header>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/* ----------------------------------
|
||||
* Status
|
||||
* ---------------------------------- */
|
||||
|
||||
html[dir="ltr"] section[role="status"] [dir] { text-align: left; }
|
||||
html[dir="rtl"] section[role="status"] [dir] { text-align: right; }
|
||||
|
||||
section[role="status"] {
|
||||
background-color: #4d4d4d;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
color: #fff;
|
||||
}
|
||||
html[dir="ltr"] section[role="status"] { background-position: left top; }
|
||||
html[dir="rtl"] section[role="status"] { background-position: right top; }
|
||||
|
||||
section[role="status"] p {
|
||||
font-size: 1.8rem;
|
||||
font-weight: normal;
|
||||
line-height: 2.2rem;
|
||||
margin: 1rem 3rem;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
section[role="status"] p strong {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE html>
|
||||
<html dir="ltr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Status</title>
|
||||
<meta name="description" content="Most common used after Multi-Select edit, to confirm user action, and optional provide 'Undo' input">
|
||||
|
||||
<link rel="stylesheet" href="../status.css">
|
||||
|
||||
<!--
|
||||
This <style>, <script> and <link> are only used for the example code,
|
||||
they are not needed for the real use case
|
||||
-->
|
||||
<style>
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 10px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
body {
|
||||
background: none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
window.onload = function(){
|
||||
document.getElementById('dir').checked = false;
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body role="application">
|
||||
<p dir="ltr">
|
||||
<label>
|
||||
<input id="dir" type="checkbox"
|
||||
onchange="document.documentElement.dir = this.checked ? 'rtl' : 'ltr'">
|
||||
RTL mode
|
||||
</label>
|
||||
</p>
|
||||
|
||||
<section role="status">
|
||||
<p>The Alarm is set for <strong>7 hours</strong> and <strong>14 minutes</strong> from now</p>
|
||||
</section>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
282
assets/webapps/music-oga.gaiamobile.org/shared/style/tabs.css
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
/* ----------------------------------
|
||||
* Tabs
|
||||
* ---------------------------------- */
|
||||
|
||||
.bb-tablist:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: 4.5rem;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
border-top: 0.1rem solid #e7e7e7;
|
||||
}
|
||||
|
||||
.bb-tablist {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.bb-tablist > li {
|
||||
-moz-box-sizing: content-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 4.5rem;
|
||||
background-color: #ffffff;
|
||||
list-style: none;
|
||||
pointer-events: all;
|
||||
flex: 1 1 0;
|
||||
}
|
||||
|
||||
.bb-tablist > li > a,
|
||||
.bb-tablist > li > button {
|
||||
position: relative;
|
||||
-moz-box-sizing: content-box;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: #5f5f5f;
|
||||
font-size: 1.6rem;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
line-height: 4.5rem;
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
background-size: 3rem auto;
|
||||
background-repeat: no-repeat;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.bb-tablist > li > button {
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.bb-tablist > li > button::-moz-focus-inner {
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.bb-tablist > li > .icon {
|
||||
font-size: 0;
|
||||
background-position: 50% 0;
|
||||
}
|
||||
|
||||
.bb-tablist > li > a[data-icon] {
|
||||
line-height: 0;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.bb-tablist > li > a[data-icon]:before {
|
||||
line-height: 4.5rem;
|
||||
}
|
||||
|
||||
.bb-tablist > li > a:active,
|
||||
.bb-tablist > li > button:active {
|
||||
border-radius: 0;
|
||||
background-color: #b2f2ff;
|
||||
}
|
||||
|
||||
/* ----------------------------------
|
||||
* Skin: dark
|
||||
* ---------------------------------- */
|
||||
.bb-tablist.skin-dark:before {
|
||||
border-color: rgba(189,189,189, 0.1);
|
||||
}
|
||||
|
||||
.bb-tablist.skin-dark > li:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 4.5rem;
|
||||
background-color: #000000;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.bb-tablist.skin-dark > li {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.bb-tablist.skin-dark > li > a,
|
||||
.bb-tablist.skin-dark > li > button {
|
||||
color: #ffffff;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.bb-tablist.skin-dark > li > a:active,
|
||||
.bb-tablist.skin-dark > li > button:active {
|
||||
background-color: rgb(0,170,204);
|
||||
}
|
||||
|
||||
/* Selected state */
|
||||
.bb-tablist > li > a:after,
|
||||
.bb-tablist > li > button:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.bb-tablist > li > a[aria-selected="true"],
|
||||
.bb-tablist > li > button[aria-selected="true"] {
|
||||
color: #00aacc;
|
||||
font-weight: 500;
|
||||
background-position: 50% 100%;
|
||||
}
|
||||
|
||||
.bb-tablist > li > a[aria-selected="true"]:after,
|
||||
.bb-tablist > li > button[aria-selected="true"]:after {
|
||||
display: inline-block;
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top:0;
|
||||
height: calc(100% - 0.3rem);
|
||||
border-bottom: 0.3rem solid #00aacc;
|
||||
}
|
||||
|
||||
.bb-tablist > li > a[aria-selected="true"]:active,
|
||||
.bb-tablist > li > button[aria-selected="true"]:active {
|
||||
color: #5f5f5f;
|
||||
background-position: 50% 0;
|
||||
}
|
||||
|
||||
.bb-tablist.skin-dark > li > a[aria-selected="true"]:active,
|
||||
.bb-tablist.skin-dark > li > button[aria-selected="true"]:active {
|
||||
background-color: #00aacc;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
|
||||
/* Disabled state */
|
||||
.bb-tablist > li[aria-disabled="true"] > a,
|
||||
.bb-tablist > li[aria-disabled="true"] > button,
|
||||
.bb-tablist > li[disabled] > a,
|
||||
.bb-tablist > li[disabled] > button,
|
||||
.bb-tablist > li > a[aria-disabled="true"],
|
||||
.bb-tablist > li > button[aria-disabled="true"],
|
||||
.bb-tablist > li > a[disabled],
|
||||
.bb-tablist > li > button[disabled] {
|
||||
color: #333333;
|
||||
opacity: 0.25;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.bb-tablist.skin-dark > li[aria-disabled="true"] > a,
|
||||
.bb-tablist.skin-dark > li[aria-disabled="true"] > button,
|
||||
.bb-tablist.skin-dark > li[disabled] > a,
|
||||
.bb-tablist.skin-dark > li[disabled] > button,
|
||||
.bb-tablist.skin-dark > li > a[aria-disabled="true"],
|
||||
.bb-tablist.skin-dark > li > button[aria-disabled="true"],
|
||||
.bb-tablist.skin-dark > li > a[disabled],
|
||||
.bb-tablist.skin-dark > li > button[disabled] {
|
||||
opacity: 0.35;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.bb-tablist .bb-tabpanel {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 4.5rem;
|
||||
left: 0;
|
||||
visibility: hidden;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.bb-tablist [aria-selected="true"] ~.bb-tabpanel {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* ----------------------------------
|
||||
* Filters
|
||||
* ---------------------------------- */
|
||||
|
||||
.bb-tablist[data-type="filter"] {
|
||||
display: flex;
|
||||
position: relative;
|
||||
height: 4rem;
|
||||
background: #fff;
|
||||
border-bottom: 0.1rem solid #e7e7e7;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.bb-tablist[data-type="filter"]:before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.bb-tablist[data-type="filter"] > li {
|
||||
background: none;
|
||||
position: relative;
|
||||
color: #737272;
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.bb-tablist[data-type="filter"] > li:first-child {
|
||||
border-inline-start: none;
|
||||
}
|
||||
|
||||
.bb-tablist[data-type="filter"] > li > a,
|
||||
.bb-tablist[data-type="filter"] > li > button {
|
||||
height: 4rem;
|
||||
border: none;
|
||||
box-sizing: border-box;
|
||||
width: auto;
|
||||
position: static;
|
||||
display: inline-block;
|
||||
padding: 0 0.5rem;
|
||||
color: #575757;
|
||||
line-height: 4rem;
|
||||
font-style: italic;
|
||||
text-decoration: none;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.bb-tablist[data-type="filter"] > li > a:before,
|
||||
.bb-tablist[data-type="filter"] > li > button:before {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.bb-tablist[data-type="filter"] > li:before,
|
||||
.bb-tablist[data-type="filter"] > li > a[aria-selected="true"]:after,
|
||||
.bb-tablist[data-type="filter"] > li > button[aria-selected="true"]:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Selected state */
|
||||
.bb-tablist[data-type="filter"] > li:active {
|
||||
color: #ffffff;
|
||||
background-color: #b2f2ff;
|
||||
}
|
||||
|
||||
.bb-tablist[data-type="filter"] > li > a[aria-selected="true"],
|
||||
.bb-tablist[data-type="filter"] > li > button[aria-selected="true"] {
|
||||
color: #000000;
|
||||
color: #0AC;
|
||||
border-bottom: 0.3rem solid #0AC;
|
||||
}
|
||||
|
||||
.bb-tablist[data-type="filter"] > li > a[aria-selected="true"]:after,
|
||||
.bb-tablist[data-type="filter"] > li > button[aria-selected="true"]:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.bb-tablist[data-type="filter"] > li > a:active {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Filters</title>
|
||||
<meta name="description" content="Filters can be used to enable the user to view a single set of data in a different lens">
|
||||
|
||||
<link rel="stylesheet" href="../tabs.css">
|
||||
|
||||
<!--
|
||||
This <style> and <link> is only used for the example code, is no needed for the real case use
|
||||
-->
|
||||
<style>
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 10px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
body {
|
||||
background: none;
|
||||
}
|
||||
|
||||
h2.bb-docs {
|
||||
font-size: 1.8rem;
|
||||
font-family: sans-serif;
|
||||
font-weight: 300;
|
||||
color: #666;
|
||||
margin: -1px 0 0;
|
||||
background-color: #f5f5f5;
|
||||
padding: 0.4rem 0.4rem 0.4rem 3rem;
|
||||
border: solid 1px #e8e8e8;
|
||||
}
|
||||
|
||||
body[role="application"] ul.bb-tablist[data-type="filter"] {
|
||||
margin: 10px 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body role="application">
|
||||
<section role="region">
|
||||
|
||||
<h2 class="bb-docs">Default position - Default Filters</h2>
|
||||
<ul role="tablist" class="bb-tablist" data-type="filter">
|
||||
<li id="filter1-1" role="presentation"><a href="#filter1-1" role="tab">Action 01</a></li>
|
||||
<li id="filter1-2" role="presentation"><a href="#filter1-2" role="tab">Action 02</a></li>
|
||||
</ul>
|
||||
|
||||
<ul role="tablist" class="bb-tablist" data-type="filter" >
|
||||
<li id="filter2-1" role="presentation"><a href="#filter2-1" role="tab">Action 01</a></li>
|
||||
<li id="filter2-2" role="presentation"><a href="#filter2-2" role="tab">Action 02</a></li>
|
||||
<li id="filter2-3" role="presentation"><a href="#filter2-3" role="tab">Action 02</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 88 B |
|
|
@ -0,0 +1,68 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Tabs</title>
|
||||
<meta name="description" content="Allows multiple instances to be contained within a single window. Tabs are used as a navigational widget for switching between sets of views. ">
|
||||
|
||||
<link rel="stylesheet" href="../tabs.css">
|
||||
<link rel="stylesheet" href="../../elements/gaia-icons/gaia-icons-embedded.css">
|
||||
<!--
|
||||
This <style> and <link> is only used for the example code, is no needed for the real case use
|
||||
-->
|
||||
<style>
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 10px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
body {
|
||||
background: none;
|
||||
}
|
||||
|
||||
h2.bb-docs {
|
||||
font-size: 1.8rem;
|
||||
font-family: sans-serif;
|
||||
font-weight: 300;
|
||||
color: #666;
|
||||
margin: -1px 0 0;
|
||||
background-color: #f5f5f5;
|
||||
padding: 0.4rem 0.4rem 0.4rem 3rem;
|
||||
border: solid 1px #e8e8e8;
|
||||
}
|
||||
|
||||
.bb-tabpanel {
|
||||
padding: 2rem;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body role="application">
|
||||
|
||||
<section role="region">
|
||||
<!-- if your tabs are at the top, remove class="bottom" -->
|
||||
<ul role="tablist" class="bb-tablist">
|
||||
<li id="panel1" role="presentation">
|
||||
<a id="tab1" href="#panel1" data-icon="recent-calls" aria-label="recent calls" role="tab" aria-controls="tabpanel1">comms</a>
|
||||
<div id="tabpanel1" class="bb-tabpanel" role="tabpanel" aria-labelledby="tab1">Tab Panel 1</div>
|
||||
</li>
|
||||
<li id="panel2" role="presentation">
|
||||
<a id="tab2" href="#panel2" data-icon="user" aria-label="contacts" role="tab" aria-controls="tabpanel2">contacts</a>
|
||||
<div id="tabpanel2" class="bb-tabpanel" role="tabpanel" aria-labelledby="tab2">Tab Panel 2</div>
|
||||
</li>
|
||||
<li id="panel3" role="presentation" aria-disabled="true">
|
||||
<a id="tab3" href="#panel3" data-icon="dialpad" aria-label="dialer" role="tab" aria-controls="tabpanel3">dialer</a>
|
||||
<div id="tabpanel3" class="bb-tabpanel" role="tabpanel" aria-labelledby="tab3">Tab Panel 3</div>
|
||||
</li>
|
||||
<li id="panel4" role="presentation">
|
||||
<a id="tab4" href="#panel4" role="tab" aria-controls="tabpanel4">Tab name</a>
|
||||
<div id="tabpanel4" class="bb-tabpanel" role="tabpanel" aria-labelledby="tab4">Tab Panel 4</div>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Tabs</title>
|
||||
<meta name="description" content="Allows multiple instances to be contained within a single window. Tabs are used as a navigational widget for switching between sets of views. ">
|
||||
|
||||
<link rel="stylesheet" href="../tabs.css">
|
||||
|
||||
<!--
|
||||
This <style> and <link> is only used for the example code, is no needed for the real case use
|
||||
-->
|
||||
<style>
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 10px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
body {
|
||||
background: none;
|
||||
}
|
||||
|
||||
h2.bb-docs {
|
||||
font-size: 1.8rem;
|
||||
font-family: sans-serif;
|
||||
font-weight: 300;
|
||||
color: #666;
|
||||
margin: -1px 0 0;
|
||||
background-color: #f5f5f5;
|
||||
padding: 0.4rem 0.4rem 0.4rem 3rem;
|
||||
border: solid 1px #e8e8e8;
|
||||
}
|
||||
|
||||
.bb-tabpanel {
|
||||
padding: 2rem;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
/* icons */
|
||||
#panel1 a {
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMCIgaGVpZ2h0PSI5MCIgdmlld0JveD0iMCAwIDMwIDkwIj48cGF0aCBmaWxsPSIjMDBDQUYyIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IiBkPSJNMjkuODYzIDY4LjU2OWgtNS41Nzd2Mi43MmMtLjMyLjA2Ni0uNjY1LS4wMDgtLjkxMi0uMjU5bC0zLjA0NC0zLjA5NGMtLjM5NC0uNC0uMzk0LTEuMDQ4IDAtMS40NDhsMy4wNDQtMy4wOTNjLjI0OS0uMjUzLjU5NC0uMzI2LjkxMi0uMjYxdjIuNzM0aDUuNTc4Yy4xODEuODkuMTgxIDEuODEyLS4wMDEgMi43MDF6bS0xMS44MDktNS43MzJjLS4yNDguMjUzLS41OTEuMzI2LS45MTIuMjYxdi0yLjcyaC01LjU3N2MtLjE4MS0uODktLjE4MS0xLjgxLS4wMDEtMi42OTloNS41Nzd2LTIuNzM1Yy4zMjEtLjA2Ni42NjYuMDA4LjkxMi4yNjFsMy4wNDQgMy4wOTRjLjM5NS40LjM5NSAxLjA0OCAwIDEuNDQ2bC0zLjA0MyAzLjA5MnptLTEuNTIxIDEwLjY4bC4wMjIuMDIyYy42MTMtLjM0MyAxLjIxNy0uNzU2IDEuODE3LTEuMTk5bDUuNzI5IDUuMTU0Yy0xLjIwOCAxLjA2MS0yLjUyIDEuOTMtMy44OTkgMi41ODYtMy42NjUtLjY4OC04LjM2My0zLjQ1OS0xMi41NzktNy43NDUtNC4yMTctNC4yODItNi45NDItOS4wNTMtNy42MjMtMTIuNzc1LjY0NS0xLjQwNCAxLjUwMy0yLjczNyAyLjU0OC0zLjk2OGw1LjA3NiA1LjgyNmMtLjQzNS42MDktLjg0MSAxLjIyMy0xLjE3OSAxLjg0NWwuMDIyLjAyM2MtLjU5NCAxLjMyNi43ODEgNC4yMSAzLjM1MiA2LjgyMyAyLjU3MiAyLjYxMyA1LjQxMSA0LjAxMSA2LjcxNCAzLjQwOHoiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMjkuODYzIDIzLjU2OGgtNS41Nzd2Mi43MmMtLjMyLjA2Ni0uNjY1LS4wMDgtLjkxMi0uMjU5bC0zLjA0NC0zLjA5NGMtLjM5NC0uNC0uMzk0LTEuMDQ4IDAtMS40NDhsMy4wNDQtMy4wOTNjLjI0OS0uMjUzLjU5NC0uMzI4LjkxMi0uMjYxdjIuNzM0aDUuNTc4Yy4xODEuODkxLjE4MSAxLjgxMi0uMDAxIDIuNzAxem0tMTEuODA5LTUuNzMxYy0uMjQ4LjI1My0uNTkxLjMyOC0uOTEyLjI2MXYtMi43MTloLTUuNTc3Yy0uMTgxLS44OS0uMTgxLTEuODEtLjAwMS0yLjcwMWg1LjU3N3YtMi43MzZjLjMyMS0uMDY2LjY2Ni4wMDguOTEyLjI2MWwzLjA0NCAzLjA5NGMuMzk1LjQuMzk1IDEuMDQ4IDAgMS40NDZsLTMuMDQzIDMuMDk0em0tMS41MjEgMTAuNjhsLjAyMi4wMjJjLjYxMy0uMzQzIDEuMjE3LS43NTYgMS44MTctMS4xOTdsNS43MjkgNS4xNTRjLTEuMjA4IDEuMDYxLTIuNTIgMS45MjktMy44OTkgMi41ODYtMy42NjUtLjY4OC04LjM2My0zLjQ1OC0xMi41NzktNy43NDUtNC4yMTctNC4yODQtNi45NDItOS4wNTMtNy42MjMtMTIuNzc3LjY0NS0xLjQwNCAxLjUwMy0yLjczNyAyLjU0OC0zLjk2OGw1LjA3NiA1LjgyNmMtLjQzNS42MDktLjg0MSAxLjIyMy0xLjE3OSAxLjg0NGwuMDIyLjAyM2MtLjU5NCAxLjMyNi43ODEgNC4yMSAzLjM1MiA2LjgyM3M1LjQxMSA0LjAxMSA2LjcxNCAzLjQwOXoiLz48L3N2Zz4=);
|
||||
}
|
||||
|
||||
#panel2 a {
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMCIgaGVpZ2h0PSI5MCIgdmlld0JveD0iMCAwIDMwIDkwIj48cGF0aCBmaWxsPSIjMDBDQUYyIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IiBkPSJNMjQuMjU5IDcyLjk1OGMwIDIuNTg0LS41MSA0Ljk5MS0xLjM3OCA3LjA0MmgtMTUuNzYyYy0uODY4LTIuMDUyLTEuMzc4LTQuNDU3LTEuMzc4LTcuMDQyaC4wMDV2LS4wMDFjMC0yLjU3NyAyLjEzMS00LjggNS4yMTctNS44NTZsNC4wMzggNC4wNzIgNC4wMzctNC4wNzJjMy4wODUgMS4wNTggNS4yMTcgMy4yNzkgNS4yMTcgNS44NTZ2LjAwMmwuMDA0LS4wMDF6bS05LjI1OS03LjMwNWMtMi45MTcgMC01LjI4NC0yLjM4NC01LjI4NC01LjMyNnMyLjM2Ny01LjMyNyA1LjI4NC01LjMyN2MyLjkxNiAwIDUuMjgzIDIuMzg1IDUuMjgzIDUuMzI3cy0yLjM2NyA1LjMyNi01LjI4MyA1LjMyNnoiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMjQuMjU5IDI3Ljk1OGMwIDIuNTg0LS41MSA0Ljk5MS0xLjM3OCA3LjA0MmgtMTUuNzYyYy0uODY4LTIuMDUyLTEuMzc4LTQuNDU4LTEuMzc4LTcuMDQyaC4wMDV2LS4wMDFjMC0yLjU3NyAyLjEzMS00LjggNS4yMTctNS44NTZsNC4wMzggNC4wNzIgNC4wMzctNC4wNzJjMy4wODUgMS4wNTggNS4yMTcgMy4yNzkgNS4yMTcgNS44NTZ2LjAwMmwuMDA0LS4wMDF6bS05LjI1OS03LjMwNWMtMi45MTcgMC01LjI4NC0yLjM4NC01LjI4NC01LjMyNiAwLTIuOTQzIDIuMzY3LTUuMzI3IDUuMjg0LTUuMzI3IDIuOTE2IDAgNS4yODMgMi4zODUgNS4yODMgNS4zMjcgMCAyLjk0MS0yLjM2NyA1LjMyNi01LjI4MyA1LjMyNnoiLz48L3N2Zz4=);
|
||||
}
|
||||
|
||||
#panel3 a {
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMCIgaGVpZ2h0PSI5MCIgdmlld0JveD0iMCAwIDMwIDkwIj48cGF0aCBmaWxsPSIjMDBDQUYyIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IiBkPSJNOS4zNTkgNjEuMDE1bC0uMDIzLjAxOWMtLjEwMy40MjMtLjQ5Ljc0Ni0uOTc3Ljc0NmwtLjAwMS4wMDFoLTIuNDg3bC0uMDAyLS4wMDFjLS40ODYgMC0uODczLS4zMjMtLjk3Ni0uNzQ2bC0uMDIzLS4wMTljLS4xODgtLjkxNS0uMzE4LTEuOTQ3LS4zNy0zLjA2aDUuMjI4Yy0uMDUyIDEuMTEzLS4xOCAyLjE0NS0uMzY5IDMuMDZ6bTcuODg2IDBsLS4wMjIuMDE5Yy0uMTAzLjQyMy0uNDkuNzQ2LS45NzcuNzQ2bC0uMDAxLjAwMWgtMi40ODhsLS4wMDEtLjAwMWMtLjQ4NiAwLS44NzMtLjMyMy0uOTc2LS43NDZsLS4wMjMtLjAxOWMtLjE5LS45MTUtLjMxOC0xLjk0Ny0uMzY5LTMuMDZoNS4yMjhjLS4wNTMgMS4xMTMtLjE4MyAyLjE0NS0uMzcxIDMuMDZ6bTcuODg2IDBsLS4wMjIuMDE5Yy0uMTAzLjQyMy0uNDkuNzQ2LS45NzcuNzQ2bC0uMDAxLjAwMWgtMi40ODh2LS4wMDFjLS40ODcgMC0uODc0LS4zMjMtLjk3OS0uNzQ2bC0uMDItLjAxOWMtLjE5LS45MTUtLjMxOC0xLjk0Ny0uMzY5LTMuMDZoNS4yMjVjLS4wNTIgMS4xMTMtLjE4MSAyLjE0NS0uMzY5IDMuMDZ6bS0xNS43NzIgNy42MzJsLS4wMjMuMDE5Yy0uMTAzLjQyMy0uNDkuNzQ3LS45NzcuNzQ3aC0yLjQ5Yy0uNDg2IDAtLjg3My0uMzI1LS45NzYtLjc0N2wtLjAyMy0uMDE5Yy0uMTktLjkxNC0uMzE4LTEuOTQ3LS4zNy0zLjA2aDUuMjI4Yy0uMDUyIDEuMTEzLS4xOCAyLjE0Ny0uMzY5IDMuMDZ6bTcuODg2IDBsLS4wMjIuMDE5Yy0uMTAzLjQyMy0uNDkuNzQ3LS45NzcuNzQ3aC0yLjQ4OWMtLjQ4NiAwLS44NzMtLjMyNS0uOTc2LS43NDdsLS4wMjMtLjAxOWMtLjE5LS45MTQtLjMxOC0xLjk0OS0uMzY5LTMuMDZoNS4yMjhjLS4wNTQgMS4xMTMtLjE4NCAyLjE0Ny0uMzcyIDMuMDZ6bTcuODg2IDBsLS4wMjIuMDE5Yy0uMTAzLjQyMy0uNDkuNzQ3LS45NzcuNzQ3aC0yLjQ4OWMtLjQ4NyAwLS44NzQtLjMyNS0uOTc5LS43NDdsLS4wMi0uMDE5Yy0uMTktLjkxNC0uMzE4LTEuOTQ5LS4zNjktMy4wNmg1LjIyNWMtLjA1MiAxLjExMy0uMTgxIDIuMTQ3LS4zNjkgMy4wNnptLTE1Ljc3MiA3LjYzNGwtLjAyMy4wMTdjLS4xMDQuNDI1LS40OS43NDctLjk3OS43NDdoLTIuNDg5Yy0uNDg2IDAtLjg3My0uMzIzLS45NzYtLjc0N2wtLjAyMy0uMDE4Yy0uMTg4LS45MTUtLjMxOC0xLjk1LS4zNjktMy4wNmg1LjIyOGMtLjA1MiAxLjExMS0uMTggMi4xNDYtLjM2OSAzLjA2MXptNy44ODYgMGwtLjAyMi4wMTdjLS4xMDQuNDI1LS40OTEuNzQ3LS45NzkuNzQ3aC0yLjQ4OWMtLjQ4NiAwLS44NzMtLjMyMy0uOTc2LS43NDdsLS4wMjMtLjAxOGMtLjE5LS45MTUtLjMxOC0xLjk1LS4zNjktMy4wNmg1LjIyOGMtLjA1MiAxLjExMS0uMTgyIDIuMTQ2LS4zNyAzLjA2MXptNy44ODYgMGwtLjAyMi4wMTdjLS4xMDQuNDI1LS40OS43NDctLjk3OS43NDdoLTIuNDg5Yy0uNDg3IDAtLjg3NC0uMzIzLS45NzktLjc0N2wtLjAyLS4wMThjLS4xOS0uOTE1LS4zMTgtMS45NS0uMzY5LTMuMDZoNS4yMjdjLS4wNTIgMS4xMTEtLjE4MSAyLjE0Ni0uMzY5IDMuMDYxeiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik05LjM1OSAxNi4wMTVsLS4wMjMuMDE5Yy0uMTAzLjQyMy0uNDkuNzQ2LS45NzcuNzQ2bC0uMDAxLjAwMWgtMi40ODdsLS4wMDItLjAwMWMtLjQ4NiAwLS44NzMtLjMyMy0uOTc2LS43NDZsLS4wMjMtLjAxOWMtLjE4OC0uOTE0LS4zMTgtMS45NDctLjM3LTMuMDZoNS4yMjhjLS4wNTIgMS4xMTMtLjE4IDIuMTQ1LS4zNjkgMy4wNnptNy44ODYgMGwtLjAyMi4wMTljLS4xMDMuNDIzLS40OS43NDYtLjk3Ny43NDZsLS4wMDEuMDAxaC0yLjQ4OGwtLjAwMS0uMDAxYy0uNDg2IDAtLjg3My0uMzIzLS45NzYtLjc0NmwtLjAyMy0uMDE5Yy0uMTktLjkxNC0uMzE4LTEuOTQ3LS4zNjktMy4wNmg1LjIyOGMtLjA1MyAxLjExMy0uMTgzIDIuMTQ1LS4zNzEgMy4wNnptNy44ODYgMGwtLjAyMi4wMTljLS4xMDMuNDIzLS40OS43NDYtLjk3Ny43NDZsLS4wMDEuMDAxaC0yLjQ4OHYtLjAwMWMtLjQ4NyAwLS44NzQtLjMyMy0uOTc5LS43NDZsLS4wMi0uMDE5Yy0uMTktLjkxNC0uMzE4LTEuOTQ3LS4zNjktMy4wNmg1LjIyNWMtLjA1MiAxLjExMy0uMTgxIDIuMTQ1LS4zNjkgMy4wNnptLTE1Ljc3MiA3LjYzMmwtLjAyMy4wMTljLS4xMDMuNDIzLS40OS43NDctLjk3Ny43NDdoLTIuNDljLS40ODYgMC0uODczLS4zMjUtLjk3Ni0uNzQ3bC0uMDIzLS4wMTljLS4xOS0uOTE0LS4zMTgtMS45NDctLjM3LTMuMDZoNS4yMjhjLS4wNTIgMS4xMTMtLjE4IDIuMTQ3LS4zNjkgMy4wNnptNy44ODYgMGwtLjAyMi4wMTljLS4xMDMuNDIzLS40OS43NDctLjk3Ny43NDdoLTIuNDg5Yy0uNDg2IDAtLjg3My0uMzI1LS45NzYtLjc0N2wtLjAyMy0uMDE5Yy0uMTktLjkxNS0uMzE4LTEuOTQ5LS4zNjktMy4wNjFoNS4yMjhjLS4wNTQgMS4xMTQtLjE4NCAyLjE0OC0uMzcyIDMuMDYxem03Ljg4NiAwbC0uMDIyLjAxOWMtLjEwMy40MjMtLjQ5Ljc0Ny0uOTc3Ljc0N2gtMi40ODljLS40ODcgMC0uODc0LS4zMjUtLjk3OS0uNzQ3bC0uMDItLjAxOWMtLjE5LS45MTUtLjMxOC0xLjk0OS0uMzY5LTMuMDYxaDUuMjI1Yy0uMDUyIDEuMTE0LS4xODEgMi4xNDgtLjM2OSAzLjA2MXptLTE1Ljc3MiA3LjYzNGwtLjAyMy4wMTdjLS4xMDQuNDI1LS40OS43NDctLjk3OS43NDdoLTIuNDg5Yy0uNDg2IDAtLjg3My0uMzIzLS45NzYtLjc0N2wtLjAyMy0uMDE3Yy0uMTg4LS45MTUtLjMxOC0xLjk1LS4zNjktMy4wNmg1LjIyOGMtLjA1MiAxLjExLS4xOCAyLjE0NS0uMzY5IDMuMDZ6bTcuODg2IDBsLS4wMjIuMDE3Yy0uMTA0LjQyNS0uNDkxLjc0Ny0uOTc5Ljc0N2gtMi40ODljLS40ODYgMC0uODczLS4zMjMtLjk3Ni0uNzQ3bC0uMDIzLS4wMTdjLS4xOS0uOTE1LS4zMTgtMS45NS0uMzY5LTMuMDZoNS4yMjhjLS4wNTIgMS4xMS0uMTgyIDIuMTQ1LS4zNyAzLjA2em03Ljg4NiAwbC0uMDIyLjAxN2MtLjEwNC40MjUtLjQ5Ljc0Ny0uOTc5Ljc0N2gtMi40ODljLS40ODcgMC0uODc0LS4zMjMtLjk3OS0uNzQ3bC0uMDItLjAxN2MtLjE5LS45MTUtLjMxOC0xLjk1LS4zNjktMy4wNmg1LjIyN2MtLjA1MiAxLjExLS4xODEgMi4xNDUtLjM2OSAzLjA2eiIvPjwvc3ZnPg==);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body role="application">
|
||||
|
||||
<section role="region">
|
||||
<!-- if your tabs are at the top, remove class="bottom" -->
|
||||
<ul role="tablist" class="bb-tablist skin-dark">
|
||||
<li id="panel1" role="presentation">
|
||||
<a id="tab1" href="#panel1" class="icon" role="tab" aria-controls="tabpanel1">comms</a>
|
||||
<div id="tabpanel1" class="bb-tabpanel" role="tabpanel" aria-labelledby="tab1">Tab Panel 1</div>
|
||||
</li>
|
||||
<li id="panel2" role="presentation">
|
||||
<a id="tab2" href="#panel2" class="icon" role="tab" aria-controls="tabpanel2">contacts</a>
|
||||
<div id="tabpanel2" class="bb-tabpanel" role="tabpanel" aria-labelledby="tab2">Tab Panel 2</div>
|
||||
</li>
|
||||
<li id="panel3" role="presentation" aria-disabled="true">
|
||||
<a id="tab3" class="icon" role="tab" aria-controls="tabpanel3">dialer</a>
|
||||
<div id="tabpanel3" class="bb-tabpanel" role="tabpanel" aria-labelledby="tab3">Tab Panel 3</div>
|
||||
</li>
|
||||
<li id="panel4" role="presentation">
|
||||
<a id="tab4" href="#panel4" role="tab" aria-controls="tabpanel4">Tab name</a>
|
||||
<div id="tabpanel4" class="bb-tabpanel" role="tabpanel" aria-labelledby="tab4">Tab Panel 4</div>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
</body>
|
||||
</html>
|
||||