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.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,565 @@
;(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={'&':'&amp;','<':'&lt;','>':'&gt;',};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);;'use strict';(function(exports){var appMgr=navigator.mozApps.mgmt;var apps=null;window.performance.mark('homescreenStart@system.gaiamobile.org');appMgr.getAll().onsuccess=function onsuccess(event){apps=event.target.result;window.dispatchEvent(new CustomEvent('navigator-mozapps-ready'));};function ApplicationSource(store){this.store=store;this.entries=[];this.entriesByManifestUrl={};this.svPreviouslyInstalledApps=[];var pendingInstallRequests=[];function addSVEventListener(){window.addEventListener('singlevariant-ready',function svFileReady(ev){window.removeEventListener('singlevariant-ready',svFileReady);for(var i=0;i<pendingInstallRequests;i++){pendingInstallRequests[i]();}});}
addSVEventListener();var self=this;function addIcons(){window.removeEventListener('navigator-mozapps-ready',addIcons);for(var i=0,iLen=apps.length;i<iLen;i++){self.makeIcons(apps[i]);}
apps=null;}
apps?addIcons():window.addEventListener('navigator-mozapps-ready',addIcons);function install(application){var manifest=application.manifest||application.updateManifest;if(manifest.role&&app.HIDDEN_ROLES.indexOf(manifest.role)!==-1){return;}
this.addIconToGrid(application);var svApp=configurator.getSingleVariantApp(application.manifestURL);var lastElem=app.grid.getIndexLastIcon();if(configurator.isSimPresentOnFirstBoot&&svApp&&svApp.location<lastElem&&!this.isPreviouslyInstalled(application.manifestURL)){app.grid.popDivider();app.grid.removeNonVisualElements();lastElem=app.grid.getIndexLastIcon();app.grid.moveTo(lastElem,svApp.location);_moveAhead(svApp.location+1);this.addPreviouslyInstalledSvApp(application.manifestURL);app.itemStore.savePrevInstalledSvApp(this.svPreviouslyInstalledApps);}
app.grid.render();app.itemStore.deferredSave(app.grid.getItems());}
function _moveAhead(startPos){var elems=app.grid.getItems();for(var i=startPos,iLen=elems.length;i<iLen;i++){var item=elems[i];if(item instanceof GaiaGrid.Mozapp){var svApp=configurator.getSingleVariantApp(elems[i].identifier);if(svApp&&i>svApp.location){app.grid.moveTo(i,i-1);}}}}
appMgr.oninstall=function oninstall(event){if(configurator.isSingleVariantReady){install.bind(this)(event.application);}else{pendingInstallRequests.push(install.bind(this,event.application));}}.bind(this);appMgr.onuninstall=function onuninstall(event){var application=event.application;var manifest=application.updateManifest||application.manifest;this.removeIconFromGrid(application.manifestURL);app.itemStore.deferredSave(app.grid.getItems());if(app.HIDDEN_ROLES.indexOf(manifest.role)!==-1){return;}}.bind(this);}
ApplicationSource.prototype={synchronize:function(){var storeItems=this.store._allItems;var toAdd=[];var appIconsByManifestUrl={};for(var i=0,iLen=storeItems.length;i<iLen;i++){var item=storeItems[i];if(!(item instanceof GaiaGrid.Mozapp)){continue;}
appIconsByManifestUrl[item.detail.manifestURL]=item;}
for(i=0,iLen=this.entries.length;i<iLen;i++){var entry=this.entries[i];var manifest=entry.app.updateManifest||entry.app.manifest;if(!appIconsByManifestUrl[entry.detail.manifestURL]&&!manifest.entry_points){toAdd.push(entry);}else{delete appIconsByManifestUrl[entry.detail.manifestURL];}}
for(i in appIconsByManifestUrl){this.removeIconFromGrid(i);}
toAdd.forEach(function _toAdd(newApp){this.addIconToGrid(newApp.app);},this);app.itemStore.deferredSave(app.grid.getItems());},addIconToGrid:function(application){this.makeIcons(application);var appObject=this.mapToApp({manifestURL:application.manifestURL});app.grid.appendItemToExpandedGroup(appObject);app.grid.render();},removeIconFromGrid:function(manifestURL){var icons=app.grid.getIcons();var appObject=icons[manifestURL];if(appObject){appObject.removeFromGrid();}},populate:function(success){success(this.entries);},makeIcons:function(eachApp){var manifest=eachApp.manifest||eachApp.updateManifest;if(app.HIDDEN_ROLES.indexOf(manifest.role)!==-1){return;}
function eachIcon(icon){if(!icon.icon){return;}
icon.setPosition(this.store.getNextPosition());this.entries.push(icon);}
this.entriesByManifestUrl[eachApp.manifestURL]=eachApp;if(manifest.entry_points){for(var i in manifest.entry_points){eachIcon.call(this,new GaiaGrid.Mozapp(eachApp,i));}}else{eachIcon.call(this,new GaiaGrid.Mozapp(eachApp));}},mapToApp:function(entry){var app=this.entriesByManifestUrl[entry.manifestURL];app=app||{manifestURL:entry.manifestURL,manifest:{name:'',icons:[]}};return new GaiaGrid.Mozapp(app,entry.entryPoint,{decoratedIconBlob:entry.decoratedIconBlob});},addPreviouslyInstalledSvApp:function(manifest){this.svPreviouslyInstalledApps.push({manifestURL:manifest});},isPreviouslyInstalled:function(manifest){for(var i=0,elemNum=this.svPreviouslyInstalledApps.length;i<elemNum;i++){if(this.svPreviouslyInstalledApps[i].manifestURL===manifest){return true;}}
return false;}};exports.ApplicationSource=ApplicationSource;}(window));;'use strict';(function(exports){function AppManager(){var grid=document.querySelector('gaia-grid');var self=this;navigator.mozApps.getSelf().onsuccess=function(evt){self.app=evt.target.result;window.dispatchEvent(new CustomEvent('appmanager-ready'));};grid.addEventListener('removeitem',this);}
AppManager.prototype={dialogVisible:false,get self(){return this.app;},handleItemRemoval:function(item){function errorLogger(err){console.error('Error while trying to remove',item.name,err);}
switch(item.detail.type){case'bookmark':BookmarksDatabase.remove(item.identifier).catch(errorLogger);break;default:console.error('Cannot handle remove for item type ',item.detail.type);}},handleEvent:function(e){var nameObj={name:e.detail&&e.detail.name};switch(e.type){case'removeitem':if(this.dialogVisible){return;}
this.dialogVisible=true;if(e.detail.detail.type=='app'){var request=navigator.mozApps.mgmt.uninstall(e.detail.app);request.onsuccess=()=>{e.detail.removeFromGrid();this.dialogVisible=false;};request.onerror=()=>{console.error('Error while trying to remove',e.detail.name,request.error);this.dialogVisible=false;};break;}
var dialog=new ConfirmDialogHelper({type:'remove',title:{id:'delete-title',args:nameObj},body:{id:'delete-body',args:nameObj},cancel:{title:'cancel',cb:()=>{this.dialogVisible=false;}},confirm:{title:'delete',type:'danger',cb:()=>{e.detail.removeFromGrid();this.handleItemRemoval(e.detail);this.dialogVisible=false;}}});dialog.show(document.body);break;}}};exports.appManager=new AppManager();}(window));;'use strict';(function(exports){const APPEARANCE={OPAQUE:'opaque',SEMI_TRANSPARENT:'semi-transparent'};function StatusBar(){this.threshold=document.getElementById('search').clientHeight;if(!appManager.app){window.addEventListener('appmanager-ready',function onReady(){window.removeEventListener('appmanager-ready',onReady);this.onAppReady();}.bind(this));}else{this.onAppReady();}}
StatusBar.prototype={handleEvent:function(e){switch(e.type){case'editmode-start':window.removeEventListener('context-menu-open',this);window.removeEventListener('context-menu-close',this);window.removeEventListener('gaia-confirm-open',this);window.removeEventListener('gaia-confirm-close',this);case'context-menu-open':case'gaia-confirm-open':window.removeEventListener('scroll',this);this.setAppearance(APPEARANCE.OPAQUE);break;case'editmode-end':window.addEventListener('context-menu-open',this);window.addEventListener('context-menu-close',this);window.addEventListener('gaia-confirm-open',this);window.addEventListener('gaia-confirm-close',this);case'context-menu-close':case'gaia-confirm-close':window.addEventListener('scroll',this);case'scroll':this.setAppearance(this.calculateAppearance());break;case'visibilitychange':if(document.hidden){break;}
this.appearance=null;this.setAppearance(this.calculateAppearance());break;}},onAppReady:function(){var grid=app.grid;window.addEventListener('scroll',this);grid.addEventListener('editmode-start',this);grid.addEventListener('editmode-end',this);window.addEventListener('context-menu-close',this);window.addEventListener('context-menu-open',this);window.addEventListener('gaia-confirm-open',this);window.addEventListener('gaia-confirm-close',this);window.addEventListener('visibilitychange',this);this.setAppearance(APPEARANCE.SEMI_TRANSPARENT);},calculateAppearance:function(){return window.scrollY>this.threshold?APPEARANCE.OPAQUE:APPEARANCE.SEMI_TRANSPARENT;},setAppearance:function(value){if(this.appearance===value){return;}
this.appearance=value;var meta=document.head.querySelector('meta[name="theme-color"]');if(value==APPEARANCE.OPAQUE){meta.content='black';}else{meta.content='transparent';}}};exports.statusBar=new StatusBar();}(window));;'use strict';(function(exports){var datastore;var DATASTORE_NAME='vertical_preferences_store';var readyState;var listeners=Object.create(null);function init(){return new Promise(function doInit(resolve,reject){if(readyState==='initialized'){resolve();return;}
if(readyState==='initializing'){document.addEventListener('vps-initialized',function oninitalized(){document.removeEventListener('vps-initialized',oninitalized);resolve();});return;}
readyState='initializing';if(!navigator.getDataStores){console.error('Preferences store: DataStore API is not working');reject({name:'NO_DATASTORE'});readyState='failed';return;}
navigator.getDataStores(DATASTORE_NAME).then(function(ds){if(ds.length<1){console.error('Preferences store: Cannot get access to the Store');reject({name:'NO_ACCESS_TO_DATASTORE'});readyState='failed';return;}
datastore=ds[0];datastore.addEventListener('change',onchangeHandler);readyState='initialized';document.dispatchEvent(new CustomEvent('vps-initialized'));resolve();},reject);});}
function onchangeHandler(event){var operation=event.operation;var callbacks=listeners[operation];callbacks&&callbacks.forEach(function iterCallback(callback){datastore.get(event.id).then(function got(result){callback.method.call(callback.context||this,{type:operation,target:{name:event.id,value:result}});});});}
function addEventListener(type,callback){var context;if(!(type in listeners)){listeners[type]=[];}
var cb=callback;if(typeof cb==='object'){context=cb;cb=cb.handleEvent;}
if(cb){listeners[type].push({method:cb,context:context});init();}}
function removeEventListener(type,callback){if(!(type in listeners)){return false;}
var callbacks=listeners[type];var length=callbacks.length;for(var i=0;i<length;i++){var thisCallback=callback;if(typeof thisCallback==='object'){thisCallback=callback.handleEvent;}
if(callbacks[i]&&callbacks[i].method===thisCallback){callbacks.splice(i,1);return true;}}
return false;}
function get(id){return new Promise(function doGet(resolve,reject){init().then(function onInitialized(){datastore.get(id).then(resolve,reject);},reject);});}
function put(id,value){return new Promise(function doAdd(resolve,reject){init().then(function onInitialized(){datastore.put(value,id).then(function success(){resolve();},reject);},reject);});}
exports.verticalPreferences={get:get,put:put,addEventListener:addEventListener,removeEventListener:removeEventListener};}(window));;'use strict';(function(exports){var datastore;var DATASTORE_NAME='bookmarks_store';var readyState;var listeners=Object.create(null);function init(){return new Promise(function doInit(resolve,reject){if(readyState==='initialized'){resolve();return;}
if(readyState==='initializing'){document.addEventListener('ds-initialized',function oninitalized(){document.removeEventListener('ds-initialized',oninitalized);resolve();});return;}
readyState='initializing';if(!navigator.getDataStores){console.error('Bookmark store: DataStore API is not working');reject({name:'NO_DATASTORE'});readyState='failed';return;}
navigator.getDataStores(DATASTORE_NAME).then(function(ds){if(ds.length<1){console.error('Bookmark store: Cannot get access to the Store');reject({name:'NO_ACCESS_TO_DATASTORE'});readyState='failed';return;}
datastore=ds[0];datastore.addEventListener('change',onchangeHandler);readyState='initialized';document.dispatchEvent(new CustomEvent('ds-initialized'));resolve();},reject);});}
function doGetAll(resolve,reject){var result=Object.create(null);var cursor=datastore.sync();function cursorResolve(task){switch(task.operation){case'update':case'add':result[task.data.id]=task.data;break;case'remove':delete result[task.data.id];break;case'clear':result=Object.create(null);break;case'done':resolve(result);return;}
cursor.next().then(cursorResolve,reject);}
cursor.next().then(cursorResolve,reject);}
function get(id){return new Promise(function doGet(resolve,reject){init().then(function onInitialized(){datastore.get(id).then(resolve,reject);},reject);});}
function getAll(){return new Promise(function doGet(resolve,reject){init().then(doGetAll.bind(null,resolve,reject),reject);});}
function onchangeHandler(event){var operation=event.operation;var callbacks=listeners[operation];callbacks&&callbacks.forEach(function iterCallback(callback){datastore.get(event.id).then(function got(result){callback.method.call(callback.context||this,{type:operation,target:result||event});});});}
function addEventListener(type,callback){var context;if(!(type in listeners)){listeners[type]=[];}
var cb=callback;if(typeof cb==='object'){context=cb;cb=cb.handleEvent;}
if(cb){listeners[type].push({method:cb,context:context});init();}}
function removeEventListener(type,callback){if(!(type in listeners)){return false;}
var callbacks=listeners[type];var length=callbacks.length;for(var i=0;i<length;i++){var thisCallback=callback;if(typeof thisCallback==='object'){thisCallback=callback.handleEvent;}
if(callbacks[i]&&callbacks[i].method===thisCallback){callbacks.splice(i,1);return true;}}
return false;}
function add(data){return new Promise(function doAdd(resolve,reject){init().then(function onInitialized(){var id=data.url;Object.defineProperty(data,'id',{enumerable:true,configurable:false,writable:false,value:id});datastore.add(data,id).then(function add_success(){resolve(true);},function add_error(){datastore.put(data,id).then(function put_success(){resolve();},reject);});},reject);});}
function getRevisionId(){return new Promise(function doGet(resolve,reject){init().then(function onInitialized(){resolve(datastore.revisionId);},reject);});}
function put(data){return new Promise(function doAdd(resolve,reject){init().then(function onInitialized(){datastore.put(data,data.id).then(function success(){resolve();},reject);},reject);});}
function remove(id){return new Promise(function doRemove(resolve,reject){init().then(function onInitialized(){datastore.remove(id).then(resolve,reject);},reject);});}
function clear(){return new Promise(function doClear(resolve,reject){init().then(function onInitialized(){datastore.clear().then(resolve,reject);},reject);});}
exports.BookmarksDatabase={get:get,getAll:getAll,getRevisionId:getRevisionId,addEventListener:addEventListener,removeEventListener:removeEventListener,add:add,put:put,remove:remove,clear:clear};}(window));;'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();}());;'use strict';var rscheme=/^(?:[a-z\u00a1-\uffff0-9-+]+)(?::(?:\/\/)?)/i;var UrlHelper={a:null,getUrlFromInput:function urlHelper_getUrlFromInput(input){this.a=this.a||document.createElement('a');this.a.href=input;return this.a.href;},_getScheme:function(input){return(rscheme.exec(input)||[])[0];},hasScheme:function(input){return!!this._getScheme(input);},isURL:function urlHelper_isURL(input){return!UrlHelper.isNotURL(input);},isNotURL:function urlHelper_isNotURL(input){var case1Reg=/^(\?)|(\?.+\s)/;var case2Reg=/[\?\.\s\:]/;var case3Reg=/^(data|view-source)\:/;var str=input.trim();if(case1Reg.test(str)||!case2Reg.test(str)||this._getScheme(str)===str){return true;}
if(case3Reg.test(str)){return false;}
if(!this.hasScheme(str)){str='http://'+str;}
if(!this.urlValidate){this.urlValidate=document.createElement('input');this.urlValidate.setAttribute('type','url');}
this.urlValidate.setAttribute('value',str);return!this.urlValidate.validity.valid;},resolveUrl:function urlHelper_resolveURL(url,baseUrl){if(!url){return null;}
try{return new URL(url,baseUrl).href;}catch(e){return null;}},getHostname:function urlHelper_getHostname(url){try{return new URL(url).hostname;}catch(e){return null;}}};;'use strict';(function WebManifestHelper(exports){var getManifest=function(url){return new Promise(function(resolve,reject){var xhr=new XMLHttpRequest({mozSystem:true});xhr.open('get',url,true);xhr.responseType='json';xhr.setRequestHeader('Accept','application/manifest+json');xhr.onload=function(){var status=xhr.status;var webManifest;if(status==200){if(!xhr.response){reject(new Error('Empty JSON response to '+url+', '+'possibly syntax error'));}
webManifest=processRawManifest(xhr.response||{},url);resolve(webManifest);}else{reject(status);}};xhr.onerror=function(e){console.error('Unable to get web manifest');reject(e.target.status);};xhr.send();});};var processRawManifest=function(webManifest,manifestURL){if(!manifestURL){throw new Error('WebManifestHelper.processRawManifest:'+' no manifestURL given');}
if('icons'in webManifest){webManifest.icons=processIcons(webManifest,manifestURL||'');}
return webManifest;};const onlyDecimals=/^\d+$/,anyRegEx=new RegExp('any','i');var processIcons=function(manifest,baseURL){const obj={objectName:'manifest',object:manifest,property:'icons',expectedType:'array'},icons=[];var value=extractValue(obj);if(Array.isArray(value)){var processableIcons=value.filter(icon=>icon&&Object.prototype.hasOwnProperty.call(icon,'src')&&icon.src!=='');for(var potentialIcon of processableIcons){var src=processSrcMember(potentialIcon,baseURL);if(src!==undefined){var icon={src:src,type:processTypeMember(potentialIcon),sizes:processSizesMember(potentialIcon),density:processDensityMember(potentialIcon)};icons.push(icon);}}}
return icons;function processTypeMember(icon){const obj={objectName:'icon',object:icon,property:'type',expectedType:'string'};var value=extractValue(obj),isParsable=(typeof value==='string'&&value.length>0);return(value===''||!isParsable)?undefined:value;}
function processDensityMember(icon){const hasDensity=Object.prototype.hasOwnProperty.call(icon,'density'),rawValue=(hasDensity)?icon.density:undefined,value=parseFloat(rawValue),result=(Number.isNaN(value)||value===+Infinity||value<=0)?1.0:value;return result;}
function processSrcMember(icon,baseURL){const obj={objectName:'icon',object:icon,property:'src',expectedType:'string'},value=extractValue(obj);var url;if(typeof value==='string'&&value.trim()!==''){try{url=new URL(value,baseURL).href;}catch(e){}}
return url;}
function processSizesMember(icon){const sizes=[],obj={objectName:'icon',object:icon,property:'sizes',expectedType:'string'};var value=extractValue(obj);value=(value)?value.trim():value;if(value){var validSizes=value.split(/\s+/).filter(isValidSizeValue);validSizes.forEach((size)=>sizes.push(size));}
return sizes;function isValidSizeValue(size){if(anyRegEx.test(size)){return true;}
size=size.toLowerCase();if(!size.contains('x')||size.indexOf('x')!==size.lastIndexOf('x')){return false;}
const width=size.substring(0,size.indexOf('x'));const height=size.substring(size.indexOf('x')+1,size.length);const isValid=!(height.startsWith('0')||width.startsWith('0')||!onlyDecimals.test(width+height));return isValid;}}};function extractValue(obj){var value=obj.object[obj.property];const type=(Array.isArray(value))?'array':typeof value;if(type!==obj.expectedType){if(type!=='undefined'){var msg='Expected the '+obj.objectName+'s '+obj.property+' member to be a '+obj.expectedType;console.warn(msg);}
value=undefined;}
return value;}
exports.WebManifestHelper={getManifest:getManifest,processRawManifest:processRawManifest};})(window);;'use strict';(function IconsHelper(exports){const ICON_CACHE_PERIOD=24*60*60*1000;const FETCH_XHR_TIMEOUT=10000;const DEBUG=false;var dataStore=null;function getDefaultIconSize(){var dpr=window.devicePixelRatio;return(dpr&&dpr>1)?142:84;}
function sizeIsNearer(size1,size2,targetSize){var delta1=Math.abs(targetSize-size1);var delta2=Math.abs(targetSize-size2);return(delta1<=delta2);}
function getIcon(uri,iconTargetSize,placeObj={},siteObj={}){var iconUrl=null;iconTargetSize=iconTargetSize*window.devicePixelRatio;if(siteObj.webManifestUrl&&siteObj.webManifest){iconUrl=getBestIconFromWebManifest(siteObj.webManifest,iconTargetSize);if(DEBUG&&iconUrl){console.log('Icon from Web Manifest');}}
if(!iconUrl&&siteObj.manifest&&siteObj.manifest.icons){iconUrl=getBestIconFromWebManifest({icons:_convertToWebManifestIcons(siteObj.manifest,siteObj.origin||siteObj.manifest.origin)},iconTargetSize);if(DEBUG&&iconUrl){console.log('Icon from Firefox App Manifest');}}
if(!iconUrl&&placeObj&&placeObj.icons){iconUrl=getBestIconFromMetaTags(placeObj.icons,iconTargetSize);if(DEBUG&&iconUrl){console.log('Icon from Meta tags');}}
if(!iconUrl){var a=document.createElement('a');a.href=uri;iconUrl=a.origin+'/favicon.ico';if(iconTargetSize){iconUrl+='#-moz-resolution='+iconTargetSize+','+iconTargetSize;}
DEBUG&&console.log('Icon from favicon.ico');}
return new Promise(resolve=>{resolve(iconUrl);});}
function getIconBlob(uri,iconTargetSize,placeObj={},siteObj={}){return new Promise((resolve,reject)=>{getIcon(uri,iconTargetSize,placeObj,siteObj).then(iconUrl=>{getStore().then(iconStore=>{iconStore.get(iconUrl).then(iconObj=>{if(!iconObj||!iconObj.timestamp||Date.now()-iconObj.timestamp>=ICON_CACHE_PERIOD){return fetchIconBlob(iconUrl).then(iconBlob=>{var img=document.createElement('img');var icon=new Icon(img,uri);icon.renderBlob(iconBlob,{size:iconTargetSize,onLoad:function(blob){var iconObj={blob:blob,originalUrl:iconUrl.toString(),timestamp:Date.now()};resolve(iconObj);iconStore.add(iconObj,iconUrl);},onerror:function(e){reject(`Failed to fetch icon ${iconUrl}`);}});}).catch(err=>{reject(`Failed to fetch icon ${iconUrl}: ${err}`);});}
return resolve(iconObj);}).catch(err=>{reject(`Failed to get icon from dataStore: ${err}`);});}).catch(err=>{reject(`Error opening the dataStore: ${err}`);});});});}
function setElementIcon(icon,targetSize){return getIconBlob(icon.bookmark.url,targetSize,icon.bookmark,icon.bookmark).then(iconObj=>{if(iconObj.blob){icon.icon=iconObj.blob;return Promise.resolve();}else if(icon.bookmark.icon){return fetchIconBlob(icon.bookmark.icon).then(iconBlob=>{icon.icon=iconBlob;return Promise.resolve();},Promise.reject.bind(Promise));}
return Promise.reject('No icon data found');},Promise.reject.bind(Promise));}
function getBestIconFromWebManifest(webManifest,iconSize){var icons=webManifest.icons;if(!icons){return null;}
var maxSize=10000;var bestSize=maxSize;var iconURL=null;iconSize=iconSize||getDefaultIconSize();icons.forEach((potentialIcon)=>{if(!iconURL){iconURL=potentialIcon.src;}
var sizes=Array.from(potentialIcon.sizes);var nearestSize=getNearestSize(sizes,iconSize,bestSize);if(nearestSize!==bestSize&&sizeIsNearer(nearestSize,bestSize,iconSize)){iconURL=potentialIcon.src;bestSize=nearestSize;}});return iconURL?iconURL:null;}
function _convertToWebManifestIcons(manifest,origin){return Object.keys(manifest.icons).map(function(size){var url=manifest.icons[size];var sizes=[size+'x'+size];url=url.indexOf('http')>-1?url:origin+url;return{src:new URL(url),sizes:sizes};});}
function getBestIconFromMetaTags(icons,iconSize){if(!icons){return null;}
iconSize=iconSize||getDefaultIconSize();var iconURL=null;var bestSize=10000;Object.keys(icons).forEach((uri)=>{var potentialIcon=icons[uri];if(!iconURL){iconURL=uri;}
var sizes=Array.from(potentialIcon.sizes);var nearestSize=getNearestSize(sizes,iconSize,bestSize);if(nearestSize!==bestSize&&sizeIsNearer(nearestSize,bestSize,iconSize)){iconURL=uri;bestSize=nearestSize;}
if(potentialIcon.rel==='apple-touch-icon'||potentialIcon.rel==='apple-touch-icon-precomposed'){var moreInfoUrl='https://developer.mozilla.org/en-US/'+'Apps/Build/Icon_implementation_for_apps#General_icons_for_web_apps';console.warn('Warning: The apple-touch icons are being used '+'as a fallback only. They will be deprecated in '+'the future. See '+moreInfoUrl);}});return iconURL||null;}
function getNearestSize(sizes,iconSize,bestSize){var bogusSize=10000;if(!bestSize){bestSize=bogusSize;}
var nearestSize=sizes.reduce(function(nearestSize,sizeString,idx){var size=widthFromSizeString(sizeString);if(isNaN(size)){return nearestSize;}
if(sizeIsNearer(size,nearestSize,iconSize)){return size;}else{return nearestSize;}},bestSize);return nearestSize===bogusSize?-1:nearestSize;}
function widthFromSizeString(size){size=size||'';var xIndex=size.indexOf('x');if(!xIndex){return NaN;}
return parseInt(size.substr(0,xIndex));}
function getStore(){return new Promise(resolve=>{if(dataStore){return resolve(dataStore);}
navigator.getDataStores('icons').then(stores=>{dataStore=stores[0];return resolve(dataStore);});});}
function clear(){return getStore().then(iconStore=>{iconStore.clear();});}
function fetchIcon(iconUrl){return new Promise((resolve,reject)=>{fetchIconBlob(iconUrl).then((iconBlob)=>{var img=document.createElement('img');img.src=URL.createObjectURL(iconBlob);img.onload=()=>{var iconSize=Math.max(img.naturalWidth,img.naturalHeight);resolve({blob:iconBlob,url:iconUrl,size:iconSize,timestamp:Date.now()});};img.onerror=()=>{reject(new Error(`Error while loading image.`));};}).catch((e)=>{reject(new Error(`Error while loading image: ${e}`));});});}
function fetchIconBlob(iconUrl){return new Promise((resolve,reject)=>{var xhr=new XMLHttpRequest({mozAnon:true,mozSystem:true});xhr.open('GET',iconUrl,true);xhr.responseType='blob';xhr.timeout=FETCH_XHR_TIMEOUT;xhr.send();xhr.onload=()=>{if(xhr.readyState===XMLHttpRequest.DONE&&xhr.status===200){var iconBlob=xhr.response;resolve(iconBlob);return;}
reject(new Error(`Got HTTP status ${xhr.status} trying to load ${iconUrl}.`));};xhr.onerror=xhr.ontimeout=()=>{reject(new Error(`Error while getting ${iconUrl}.`));};});}
exports.IconsHelper={getIcon:getIcon,getIconBlob:getIconBlob,setElementIcon:setElementIcon,getBestIconFromWebManifest:getBestIconFromWebManifest,getBestIconFromMetaTags:getBestIconFromMetaTags,fetchIcon:fetchIcon,fetchIconBlob:fetchIconBlob,get defaultIconSize(){return getDefaultIconSize();},clear:clear,getNearestSize:getNearestSize,};})(window);;'use strict';(function(exports){var eventTypesToListenFor=['added','updated','removed'];function BookmarkSource(store){this.store=store;this.entries=[];eventTypesToListenFor.forEach(function iterateTypes(type){BookmarksDatabase.addEventListener(type,this);},this);}
BookmarkSource.prototype={synchronize:function(){var allAppBookmarks={};var toAdd=[];var icons=app.grid.getIcons();for(var i in icons){var icon=icons[i];if(icon.detail.type!=='bookmark'){continue;}
allAppBookmarks[icon.detail.url]=icon;}
for(var j=0,jLen=this.entries.length;j<jLen;j++){var entry=this.entries[j];if(!allAppBookmarks[entry.detail.url]){toAdd.push(entry);}else{delete allAppBookmarks[entry.detail.url];}}
for(i in allAppBookmarks){this.removeIconFromGrid(allAppBookmarks[i].detail.url);}
for(i=0;i<toAdd.length;i++){this.addIconToGrid(toAdd[i].detail);}
app.itemStore.deferredSave(app.grid.getItems());},populate:function(success){var self=this;BookmarksDatabase.getAll().then(function(systemBookmarks){Object.keys(systemBookmarks).forEach(function(id){self.entries.push(new GaiaGrid.Bookmark(systemBookmarks[id]));});success(self.entries);},success);},handleEvent:function(e){switch(e.type){case'added':case'updated':this.addIconToGrid(e.target);app.itemStore.deferredSave(app.grid.getItems());break;case'removed':var id=e.target.id;this.removeIconFromGrid(id);break;}},addIconToGrid:function(detail){var icons=app.grid.getIcons();var existing=icons[detail.id];if(existing){existing.update(detail);app.grid.render();return;}
var bookmark=new GaiaGrid.Bookmark(detail);bookmark.setPosition(this.store.getNextPosition());this.entries.push(bookmark);app.grid.appendItemToExpandedGroup(bookmark);app.grid.render();},removeIconFromGrid:function(url){var icons=app.grid.getIcons();var appObject=icons[url];if(appObject){appObject.removeFromGrid();}}};exports.BookmarkSource=BookmarkSource;}(window));;'use strict';(function(exports){const DB_VERSION=1;const DB_NAME='verticalhome';const DB_ITEM_STORE='items';const DB_SV_APP_STORE_NAME='svAppsInstalled';const DATASTORE_NAME='verticalhome_items_migration';const PREFS_STORE='vertical_preferences_store';var db;var datastore;function sort(entries,order){if(!order||!order.length){return entries;}
var newEntries=[];function isEqual(lookFor,compareWith){if(!compareWith.detail||!lookFor){return false;}
if(compareWith instanceof GaiaGrid.Mozapp){if(!lookFor.manifestURL||!compareWith.detail.manifestURL){return false;}
if(compareWith.detail.entryPoint){return lookFor.manifestURL===compareWith.detail.manifestURL&&lookFor.entry_point===compareWith.detail.entryPoint;}else{return lookFor.manifestURL===compareWith.detail.manifestURL;}}else if(compareWith instanceof GaiaGrid.Bookmark){if(!lookFor.id||!compareWith.detail.id){return false;}
return lookFor.id===compareWith.detail.id;}}
for(var i=0,iLen=order.length;i<iLen;i++){for(var j=0,jLen=order[i].length;j<jLen;j++){var ind=entries.findIndex(isEqual.bind(null,order[i][j]));if(ind>=0){newEntries.push(entries.splice(ind,1)[0]);}}
if(i<iLen-1){newEntries.push(new GaiaGrid.Divider());}}
if(entries.length>0){if(configurator.isSimPresentOnFirstBoot){sortUnclassifiedApps(newEntries,entries);}else{newEntries.push(new GaiaGrid.Divider());newEntries=newEntries.concat(entries);}}
for(i=0,iLen=newEntries.length;i<iLen;i++){if(newEntries[i].detail){newEntries[i].detail.index=i;}}
return newEntries;}
function sortUnclassifiedApps(dstEntries,orgEntries){function compareApps(appA,appB){var svAppA=null;var svAppB=null;if(appA){svAppA=configurator.getSingleVariantApp(appA.detail.manifestURL);}
if(appB){svAppB=configurator.getSingleVariantApp(appB.detail.manifestURL);}
var locA=svAppA&&svAppA.location!==undefined&&svAppA.location||Number.MAX_VALUE;var locB=svAppB&&svAppB.location!==undefined&&svAppB.location||Number.MAX_VALUE;var relPos=locA-locB;return relPos?(relPos>0?1:-1):0;}
orgEntries.sort(compareApps);if(!configurator.getSingleVariantApp(orgEntries[0].detail.manifestURL)){dstEntries.push(new GaiaGrid.Divider());dstEntries=dstEntries.concat(orgEntries);}else{var sepAdded=false;for(var i=0,iLen=orgEntries.length;i<iLen;i++){var app=orgEntries[i];var svApp=configurator.getSingleVariantApp(app.detail.manifestURL);if(!svApp){if(!sepAdded){dstEntries.push(new GaiaGrid.Divider());sepAdded=true;}
dstEntries.push(app);}else{if(svApp.location!==undefined){dstEntries.splice(svApp.location,0,app);}else{dstEntries.push(app);}}}}}
function loadTable(table,indexName,iterator,aNext){newTxn(table,'readonly',function(txn,store){var index=store.index(indexName);index.openCursor().onsuccess=function onsuccess(event){var cursor=event.target.result;if(!cursor){return;}
iterator(cursor.value);cursor.continue();};},aNext);}
function newTxn(storeName,txnType,withTxnAndStore,successCb){var txn=db.transaction([storeName],txnType);var store=txn.objectStore(storeName);txn.oncomplete=function(event){if(successCb){successCb(event);}};txn.onerror=function(event){console.warn('Error during transaction.');};withTxnAndStore(txn,store);}
function ItemStore(onsuccess){var self=this;this.applicationSource=new ApplicationSource(this);this.bookmarkSource=new BookmarkSource(this);this.sources=[this.applicationSource,this.bookmarkSource];this.ready=false;var isEmpty=false;self.gridOrder=null;var request=window.indexedDB.open(DB_NAME,DB_VERSION);request.onupgradeneeded=function _onupgradeneeded(event){var db=event.target.result;var oldVersion=event.oldVersion||0;switch(oldVersion){case 0:var objectStore=db.createObjectStore(DB_ITEM_STORE,{keyPath:'index'});objectStore.createIndex('index','index',{unique:true});isEmpty=true;var objectSV=db.createObjectStore(DB_SV_APP_STORE_NAME,{keyPath:'manifestURL'});objectSV.createIndex('indexSV','indexSV',{unique:true});}};request.onsuccess=function _onsuccess(){onsuccess&&onsuccess(isEmpty);db=request.result;var cb=self.fetch.bind(self,self.synchronize.bind(self));if(isEmpty){window.addEventListener('configuration-ready',function onReady(){window.removeEventListener('configuration-ready',onReady);self.gridOrder=configurator.getGrid();self.populate(cb);});}else{self.initSources(cb);}
navigator.mozSetMessageHandler('connection',self.handleIAC.bind(self));};window.addEventListener('gaiagrid-cached-icons-rendered',this);}
ItemStore.prototype={_renderedOnce:false,_deferredSaveArgs:[],_allItems:[],nextPosition:0,all:function(success){if(!this.ready){window.addEventListener('databaseready',this.all.bind(this,success));return;}
success(this._allItems);},saveTable:function(table,objArr,column,checkPersist,aNext){newTxn(table,'readwrite',function(txn,store){store.clear();for(var i=0,iLen=objArr.length;i<iLen;i++){if(!checkPersist||(checkPersist&&objArr[i].persistToDB)){store.put(column?objArr[i][column]:objArr[i]);}}
if(typeof aNext==='function'){aNext();}});},saveMigrationData:function(objArr,column,checkPersist){return datastore.clear().then(()=>{var chain=[];objArr.forEach((object)=>{if(!checkPersist||object.persistToDB){var data=column?object[column]:object;chain.push(datastore.put(data,data.index+1));}});return Promise.all(chain);});},saveItem:function(object,callback){if(object.index==null){console.error('Attempting to save object without `index`');return;}
newTxn(DB_ITEM_STORE,'readwrite',function(txn,store){store.put(object);},callback);},deferredSave:function(){var args=Array.slice(arguments);if(this._renderedOnce){return this.save.apply(this,args);}
this._deferredSaveArgs=args;},save:function(entries,aNext){entries=sort(entries,this.gridOrder);this.gridOrder=null;this.saveTable(DB_ITEM_STORE,entries,'detail',true,aNext);},savePrevInstalledSvApp:function(svApps,aNext){this.saveTable(DB_SV_APP_STORE_NAME,svApps,null,false,aNext);},fetch:function(callback){var cached={};var collected=[];function iterator(value){collected.push(value);}
function iteratorSV(value){this.applicationSource.addPreviouslyInstalledSvApp(value.manifestURL);}
loadTable(DB_SV_APP_STORE_NAME,'indexSV',iteratorSV.bind(this));loadTable(DB_ITEM_STORE,'index',iterator,finish.bind(this));function addIfUnique(item){if(!cached[item.identifier]){cached[item.identifier]=true;this._allItems.push(item);}}
function finish(){for(var i=0,iLen=collected.length;i<iLen;i++){var thisItem=collected[i];if(thisItem.type==='app'){var itemObj=this.applicationSource.mapToApp(thisItem);addIfUnique.call(this,itemObj);}else if(thisItem.type==='divider'){var divider=new GaiaGrid.Divider(thisItem);this._allItems.push(divider);}else if(thisItem.type==='bookmark'){var bookmark=new GaiaGrid.Bookmark(thisItem);addIfUnique.call(this,bookmark);}}
this.notifyReady();if(callback&&typeof callback==='function'){callback();}}},synchronize:function(){this.sources.forEach(function eachSource(source){source.synchronize();});},initSources:function(callback){var pending=this.sources.length;var allEntries=[];var self=this;var current=0;function handleSource(){var source=self.sources[current];current++;source.populate(next);}
handleSource();function next(entries){allEntries=allEntries.concat(entries);if(!(--pending)){callback(allEntries);}else{handleSource();}}},populate:function(callback){this.initSources(function(entries){this.deferredSave(entries,callback);}.bind(this));},notifyReady:function(){this.ready=true;dispatchEvent(new CustomEvent('databaseready'));},getNextPosition:function(){var nextPosition=this.nextPosition;this.nextPosition++;return nextPosition;},handleIAC:function(connectionRequest){if(connectionRequest.keyword!=='verticalhome-migrate'){return;}
var port=connectionRequest.port;port.onmessage=(event)=>{if(event.data.action!=='migrate'){console.error('Unhandled migration action requested:',event.data.action);return;}
this.migrate(event.data.manifestURL);};port.start();},migrate:function(manifestURL){this.migratingTo=manifestURL;console.info('verticalhome migrating to '+this.migratingTo);if(this.migrating){return;}
this.migrating=true;(datastore?Promise.resolve():navigator.getDataStores(DATASTORE_NAME).then(stores=>{datastore=stores[0];return Promise.resolve();},(e)=>{return Promise.reject(e);})).then(()=>{this.all(entries=>{this.saveMigrationData(entries,'detail',true).then(()=>{this.migrating=false;window.navigator.mozSettings.createLock().set({'homescreen.manifestURL':this.migratingTo});navigator.getDataStores(PREFS_STORE).then(stores=>{if(stores.length<1){console.error('Error opening verticalhome prefs datastore');return;}
stores[0].put('migrated',true).then(()=>{window.close();},e=>{console.error('Error storing migration pref',e);window.close();});});});});},e=>{console.error('Error retrieving datastore',e);});},handleEvent:function(e){switch(e.type){case'gaiagrid-cached-icons-rendered':this._renderedOnce=true;window.removeEventListener('gaiagrid-cached-icons-rendered',this);if(this._deferredSaveArgs.length){this.save.apply(this,this._deferredSaveArgs);}
break;}}};exports.ItemStore=ItemStore;}(window));;'use strict';(function(exports){const maxIconsPerRow=4;const iconScaleFactorMaxIconsPerRow=5;const minIconsPerRow=3;const iconScaleFactorMinIconsPerRow=3.8;const distanceBetweenIconsWithMinIconsPerRow=36;const distanceBetweenIconsWithMaxIconsPerRow=38;const eachTextRowHeight=20;var constraintSize;function GridLayout(gridView){this.gridView=gridView;if(window.verticalPreferences){verticalPreferences.get('grid.cols').then(value=>{this.cols=value;this.onReady();},this.onReady);verticalPreferences.addEventListener('updated',this);}else{this.onReady();}}
GridLayout.prototype={minIconsPerRow:minIconsPerRow,maxIconsPerRow:maxIconsPerRow,_cols:minIconsPerRow,_offsetY:0,_percent:1,_dividerLineHeight:0,get percent(){return this._percent;},get cols(){return this._cols;},set cols(value){if(!value||value===this._cols){return;}
if(window.verticalPreferences){verticalPreferences.put('grid.cols',value);}
this._offsetY=0;this._percent=value==minIconsPerRow?1:minIconsPerRow/maxIconsPerRow;this._cols=value;},get constraintSize(){if(!constraintSize){this.calculateSize();}
return constraintSize;},get gridItemHeight(){var height=this.gridIconSize+
(this._cols===minIconsPerRow?distanceBetweenIconsWithMinIconsPerRow:distanceBetweenIconsWithMaxIconsPerRow);var defaultTextRows=2;var definedRows=parseInt(this.gridView.element.getAttribute('text-rows'),10);if(definedRows>defaultTextRows){height+=(definedRows-defaultTextRows)*eachTextRowHeight;}
return height;},get gridItemWidth(){return this.constraintSize/this._cols;},get gridMaxIconSize(){var baseSize=(this.constraintSize/iconScaleFactorMinIconsPerRow);return baseSize*devicePixelRatio;},get gridIconSize(){var numCols=this._cols;var size=this.constraintSize/numCols;if(numCols===minIconsPerRow){size=this.constraintSize/iconScaleFactorMinIconsPerRow;}else if(numCols===maxIconsPerRow){size=this.constraintSize/iconScaleFactorMaxIconsPerRow;}
return Math.floor(size);},get offsetY(){return this._offsetY;},set offsetY(value){this._offsetY=value;},stepYAxis:function(value){this._offsetY+=value;},handleEvent:function(e){switch(e.type){case'updated':var prop=e.target;if(prop.name==='grid.cols'){this.cols=parseInt(prop.value,10);this.gridView.render();}
break;}},calculateSize:function(){constraintSize=Math.min(window.screen.width,window.screen.height);},onReady:function(){window.dispatchEvent(new CustomEvent('gaiagrid-layout-ready'));}};exports.GridLayout=GridLayout;}(window));;'use strict';(function(exports){const SHADOW_BLUR=1;const SHADOW_OFFSET_Y=1;const SHADOW_OFFSET_X=1;const SHADOW_COLOR='rgba(0, 0, 0, 0.2)';const DEFAULT_BACKGROUND_COLOR='rgb(228, 234, 238)';const UNSCALED_CANVAS_PADDING=2;const CANVAS_PADDING=UNSCALED_CANVAS_PADDING*devicePixelRatio;function IconRenderer(icon){this._icon=icon;}
IconRenderer.TYPE={CLIP:'clip',FAVICON:'favicon',STANDARD:'standard',};IconRenderer.prototype={unscaledCanvasPadding:UNSCALED_CANVAS_PADDING*2,get _maxSize(){return this._icon.grid.layout.gridMaxIconSize;},_createCanvas:function(){const CANVAS_PADDING_BOTTOM=1*devicePixelRatio;var canvas=document.createElement('canvas');canvas.width=this._maxSize+(CANVAS_PADDING*2);canvas.height=this._maxSize+CANVAS_PADDING+CANVAS_PADDING_BOTTOM;return canvas;},_createClipCanvas:function(){var canvas=document.createElement('canvas');canvas.width=this._maxSize+(CANVAS_PADDING*2);canvas.height=this._maxSize+(CANVAS_PADDING*2);return canvas;},_decorateShadowCanvas:function(canvas){var ctx=canvas.getContext('2d',{willReadFrequently:true});ctx.shadowColor=SHADOW_COLOR;ctx.shadowBlur=SHADOW_BLUR;ctx.shadowOffsetY=SHADOW_OFFSET_Y;ctx.shadowOffsetX=SHADOW_OFFSET_X;return ctx;},clip:function(img){return new Promise((resolve)=>{var shadowCanvas=this._createCanvas();var shadowCtx=this._decorateShadowCanvas(shadowCanvas);var clipCanvas=this._createClipCanvas();var clipCtx=clipCanvas.getContext('2d',{willReadFrequently:true});clipCtx.beginPath();clipCtx.arc(clipCanvas.width/2,clipCanvas.height/2,clipCanvas.height/2,0,2*Math.PI);clipCtx.clip();clipCtx.drawImage(img,0,0,clipCanvas.width,clipCanvas.height);shadowCtx.drawImage(clipCanvas,CANVAS_PADDING,CANVAS_PADDING,this._maxSize,this._maxSize);shadowCanvas.toBlob(resolve);});},favicon:function(img){if(img.width>this._icon.grid.layout.gridIconSize/2){return this.clip(img);}
return new Promise((resolve)=>{var shadowCanvas=this._createCanvas();var shadowCtx=this._decorateShadowCanvas(shadowCanvas);var iconWidth;var iconHeight;shadowCtx.beginPath();shadowCtx.arc(shadowCanvas.width/2,shadowCanvas.height/2,shadowCanvas.height/2-CANVAS_PADDING,0,2*Math.PI,false);shadowCtx.fillStyle=DEFAULT_BACKGROUND_COLOR;shadowCtx.fill();iconWidth=iconHeight=this._maxSize*0.55;shadowCtx.shadowBlur=0;shadowCtx.shadowOffsetY=0;shadowCtx.mozImageSmoothingEnabled=false;shadowCtx.drawImage(img,(shadowCanvas.width-iconWidth)/2,(shadowCanvas.height-iconHeight)/2,iconWidth,iconHeight);shadowCanvas.toBlob(resolve);});},standard:function(img){return new Promise((resolve)=>{var shadowCanvas=this._createCanvas();var shadowCtx=this._decorateShadowCanvas(shadowCanvas);shadowCtx.drawImage(img,CANVAS_PADDING,CANVAS_PADDING,this._maxSize,this._maxSize);shadowCanvas.toBlob(resolve);});}};exports.GridIconRenderer=IconRenderer;}(window));;'use strict';(function(exports){const APP_LAUNCH_TIMEOUT=3000;function GridView(config){this.config=config;this.clickIcon=this.clickIcon.bind(this);this.onVisibilityChange=this.onVisibilityChange.bind(this);if(config.features.zoom){this.zoom=new GridZoom(this);}
this.layout=new GridLayout(this);if(config.element.hasAttribute('cols')){this.layout.cols=parseInt(config.element.getAttribute('cols'),10);}
this.start();}
GridView.prototype={icons:{},items:[],get element(){return this.config.element;},set cols(value){this.layout.cols=value;},_launchingApp:false,add:function(item,insertTo,expandGroup){if(!item){return;}
if(item.identifier){if(this.icons[item.identifier]){console.log('Error, duplicate identifier: ',item.identifier,new Error().stack);return;}
this.icons[item.identifier]=item;}else if(item.detail.type!=='divider'&&item.detail.type!=='placeholder'){console.log('Error, could not load identifier for object: ',JSON.stringify(item.detail));return;}
if(!isNaN(parseFloat(insertTo))&&isFinite(insertTo)){this.items.splice(insertTo,0,item);}else{insertTo=this.items.length;this.items.push(item);}
if(expandGroup){for(var i=insertTo+1,iLen=this.items.length;i<iLen;i++){var divider=this.items[i];if(divider.detail.type==='divider'){if(divider.detail.collapsed){divider.expand();}
break;}}}},getNearestItemIndex:function(x,y,isRow){var foundIndex=null;var leastDistance=null;var itemMiddleOffset=this.layout.gridItemWidth/2;for(var i=0,iLen=this.items.length;i<iLen;i++){var item=this.items[i];if(!item.isDraggable()){continue;}
if(this.config.features.disableSections&&item.detail.type==='divider'){continue;}
if(item.detail.type!=='divider'&&item.element.classList.contains('collapsed')){continue;}
var middleX=item.x+itemMiddleOffset;var middleY=item.y+item.pixelHeight/2;var xDistance=(isRow||item.detail.type==='divider')?0:x-middleX;var yDistance=y-middleY;var distance=Math.sqrt(xDistance*xDistance+
yDistance*yDistance);if(leastDistance===null||distance<leastDistance){leastDistance=distance;foundIndex=i;}}
return foundIndex;},start:function(){this.element.addEventListener('click',this.clickIcon);window.addEventListener('visibilitychange',this.onVisibilityChange);},stop:function(){this.element.removeEventListener('click',this.clickIcon);window.removeEventListener('visibilitychange',this.onVisibilityChange);},findItemFromElement:function(element,excludeCollapsedIcons){while(element&&element.parentNode!==this.element){element=element.parentNode;}
if(!element){return null;}
var i,iLen=this.items.length;var identifier=element.dataset.identifier;var icon=this.icons[identifier];if(!icon){for(i=0;i<iLen;i++){if(this.items[i].element===element){icon=this.items[i];break;}}}
if(icon&&excludeCollapsedIcons){if(icon.detail.type!=='divider'&&icon.detail.type!=='placeholder'&&icon.element.classList.contains('collapsed')){for(i=icon.detail.index+1;i<iLen;i++){if(this.items[i].detail.type==='divider'){return this.items[i];}}
console.warn('Collapsed icon found with no group');icon=null;}}
return icon;},onVisibilityChange:function(){this._launchingApp=false;},clickIcon:function(e){e.preventDefault();var inEditMode=this.dragdrop&&this.dragdrop.inEditMode;var action='launch';if(e.target.classList.contains('remove')){action='remove';}
var icon=this.findItemFromElement(e.target);if(!icon){return;}
if(action==='launch'){if(inEditMode&&e.target.classList.contains('icon')){if(!icon.isEditable()){return;}
action='edit';}else{if(!icon[action]){return;}
icon.element.classList.add('launching');var returnTimeout=500;setTimeout(function stateReturn(){if(icon.element){icon.element.classList.remove('launching');}},returnTimeout);}}
if((icon.detail.type==='app'||icon.detail.type==='bookmark')&&this._launchingApp){return;}
if((icon.detail.type==='app'&&icon.appState==='ready')||icon.detail.type==='bookmark'){this._launchingApp=true;if(this._launchingTimeout){window.clearTimeout(this._launchingTimeout);this._launchingTimeout=null;}
this._launchingTimeout=window.setTimeout(function(){this._launchingTimeout=null;this._launchingApp=false;}.bind(this),APP_LAUNCH_TIMEOUT);}
icon[action](e.target);},cleanItems:function(skipDivider){var appCount=0;var toRemove=[];this.items.forEach(function(item,idx){if(item instanceof GaiaGrid.Divider){if(appCount===0){toRemove.push(idx);}
appCount=0;}else{appCount++;}},this);toRemove.reverse();toRemove.forEach(function(idx){var removed=this.items.splice(idx,1)[0];removed.remove();},this);if(skipDivider){return;}
var lastItem=this.items[this.items.length-1];if(!lastItem||!(lastItem instanceof GaiaGrid.Divider)){this.items.push(new GaiaGrid.Divider());}},removeAllPlaceholders:function(){var toSplice=[];var previousItem;this.items.forEach(function(item,idx){if(item instanceof GaiaGrid.Placeholder){if((!previousItem||(previousItem&&previousItem instanceof GaiaGrid.Divider))&&this.dragdrop&&this.dragdrop.inDragAction){return;}
toSplice.push(idx);}
previousItem=item;},this);toSplice.reverse().forEach(function(idx){this.items.splice(idx,1)[0].remove();},this);},clear:function(){for(var i=0,iLen=this.items.length;i<iLen;i++){var item=this.items[i];if(item.element){this.element.removeChild(item.element);item.element=null;item.lastX=null;item.lastY=null;item.lastScale=null;}}
this.items=[];this.icons={};},createPlaceholders:function(coordinates,idx,count){var isRTL=(document.documentElement.dir==='rtl');for(var i=0;i<count;i++){var item=new GaiaGrid.Placeholder();this.items.splice(idx+i,0,item);item.setPosition(idx+i);var xPosition=(coordinates[0]+i)*this.layout.gridItemWidth;if(isRTL){xPosition=(this.layout.constraintSize-this.layout.gridItemWidth)-
xPosition;}
item.setCoordinates(xPosition,this.layout.offsetY);item.render();}},render:function(options){var self=this;options=options||{};this.removeAllPlaceholders();this.cleanItems(options.skipDivider);var oldHeight=this.layout.offsetY;this.layout.offsetY=0;var x=0;var y=0;function step(item){var pixelHeight=item.pixelHeight;self.layout.stepYAxis(pixelHeight);x=0;y++;}
var pendingCachedIcons=0;var onCachedIconRendered=()=>{if(--pendingCachedIcons<=0){this.element.removeEventListener('cached-icon-rendered',onCachedIconRendered);this.element.dispatchEvent(new CustomEvent('cached-icons-rendered'));}};this.element.addEventListener('cached-icon-rendered',onCachedIconRendered);var nextDivider=null;var oddDivider=true;var isRTL=(document.documentElement.dir==='rtl');for(var idx=0;idx<this.items.length;idx++){var item=this.items[idx];if(options.rerender&&item.element){this.element.removeChild(item.element);item.element=null;}
if(item.detail.type==='divider'){nextDivider=null;}else{if(!nextDivider){for(var i=idx+1;i<this.items.length;i++){if(this.items[i].detail.type==='divider'){nextDivider=this.items[i];oddDivider=!oddDivider;break;}}
if(nextDivider&&!nextDivider.detail.collapsed){this.layout.offsetY+=nextDivider.headerHeight;}}
if(nextDivider&&nextDivider.detail.collapsed){item.setPosition(idx);continue;}}
if(x>0&&item.gridWidth>1&&x+item.gridWidth>=this.layout.cols){var remaining=this.layout.cols-x;this.createPlaceholders([x,y],idx,remaining);idx+=remaining;item=this.items[idx];var lastItemInRow=this.items[idx-1];step(lastItemInRow);}
item.setPosition(idx);if(!options.skipItems){item.hasCachedIcon&&++pendingCachedIcons;var xPosition=x*this.layout.gridItemWidth;if(isRTL){xPosition=(this.layout.constraintSize-this.layout.gridItemWidth)-
xPosition;}
item.setCoordinates(xPosition,this.layout.offsetY);if(!item.active){item.render();}
if(item.detail.type==='divider'){if(oddDivider){item.element.classList.add('odd');}else{item.element.classList.remove('odd');}}}
x+=item.gridWidth;if((x>=this.layout.cols)&&(idx<this.items.length-1)){step(item);}}
if(this.layout.offsetY!=oldHeight){if(this.dragdrop&&this.dragdrop.inDragAction){this.layout.offsetY=oldHeight;}else{this.element.dispatchEvent(new CustomEvent('gaiagrid-resize',{detail:this.layout.offsetY}));}}
this.element.setAttribute('cols',this.layout.cols);pendingCachedIcons===0&&onCachedIconRendered();this.loadDragDrop();},loadDragDrop:function(){if(!this.dragdrop&&this.config.features.dragdrop){LazyLoader.load('shared/elements/gaia_grid/js/grid_dragdrop.js',()=>{if(this.dragdrop){return;}
this.dragdrop=new GridDragDrop(this);});}}};exports.GridView=GridView;}(window));;window.GaiaGrid=(function(win){'use strict';var proto=Object.create(HTMLElement.prototype);var baseurl=window.GaiaGridBaseurl||'/shared/elements/gaia_grid/';proto.createdCallback=function(){var shadow=this.createShadowRoot();this._template=template.content.cloneNode(true);this._styleHack();this._grid=new GridView({element:this,features:{dragdrop:this.getAttribute('dragdrop')!==null,zoom:this.getAttribute('zoom')!==null,disableSections:this.getAttribute('disable-sections')!==null}});shadow.appendChild(this._template);};proto.add=function(){this._grid.add.apply(this._grid,arguments);};proto.clear=function(){this._grid.clear.apply(this._grid,arguments);};proto.render=function(){this._grid.layout.calculateSize();this._grid.render.apply(this._grid,arguments);};proto.start=function(){this._grid.start.apply(this._grid,arguments);};proto.stop=function(){this._grid.stop.apply(this._grid,arguments);};proto.getIcons=function(){return this._grid.icons;};proto.getItems=function(){return this._grid.items;};proto.getIcon=function(identifier){return this._grid.icons[identifier];};proto.removeIconByIdentifier=function(identifier){delete this._grid.icons[identifier];};proto.removeItemByIndex=function(itemIndex){this._grid.items.splice(itemIndex,1);};proto.popDivider=function(){var items=this._grid.items;if(items.length&&items[items.length-1].detail.type==='divider'){return items.pop();}
return null;};proto.appendItem=function(item){var items=this._grid.items;var lastIndex=items.length-1;if(items[lastIndex].detail.type==='divider'){this.add(item,lastIndex);}else{this.add(item);}};proto.appendItemToExpandedGroup=function(item){var items=this._grid.items;var lastIndex=items.length-1;if(items[lastIndex].detail.type==='divider'&&items[lastIndex].detail.collapsed){items[lastIndex].expand();}
this.appendItem(item);};proto.setEditHeaderElement=function(element){if(this._grid.dragdrop){this._grid.dragdrop.editHeaderElement=element;}};Object.defineProperty(proto,'maxIconSize',{get:function(){return this._grid.layout.gridMaxIconSize;}});proto.getIndexLastIcon=function(){var items=this._grid.items;for(var i=this._grid.items.length-1;i>=0;i--){if(items[i]instanceof GaiaGrid.Mozapp){return i;}}};proto.removeNonVisualElements=function(){var nonVisualElements=[GaiaGrid.Placeholder];function isNonVisual(elem){var retVal=false;for(var i=0,iLen=nonVisualElements.length;i<iLen&&!retVal;i++){retVal=elem instanceof nonVisualElements[i];}
return retVal;}
var i=0;var iLen=this._grid.items.length;while(i<iLen){this._grid.items[i].detail.index=i;if(isNonVisual(this._grid.items[i])){this._grid.items.splice(i,1);iLen-=1;}else{i+=1;}}};proto.moveTo=function(orig,dst){this._grid.items.splice(dst,0,this._grid.items.splice(orig,1)[0]);};proto._styleHack=function(){var style=this._template.querySelector('style');this.appendChild(style.cloneNode(true));};var stylesheet=baseurl+'style.css';var template=document.createElement('template');template.innerHTML=`<style scoped>
@import url(${stylesheet});</style>
<content></content>`;return document.registerElement('gaia-grid',{prototype:proto});})(window);;'use strict';(function(exports){const ICON_BLOB_DECORATED_EVENT='iconblobdecorated';const ICON_BLOB_ERROR_EVENT='gaiagrid-iconbloberror';const FETCH_XHR_TIMEOUT=10000;function fetchBlob(uri){return new Promise(function(accept,reject){var xhr=new XMLHttpRequest({mozAnon:true,mozSystem:true});xhr.open('GET',uri,true);xhr.responseType='blob';xhr.timeout=FETCH_XHR_TIMEOUT;xhr.send();xhr.onload=function(){var status=xhr.status;if(status!==0&&status!==200){reject(new Error('Got HTTP status '+status+' trying to load '+uri));return;}
accept(xhr.response);};xhr.onerror=xhr.ontimeout=function(){reject(new Error('Error while HTTP GET: ',uri));};});}
function GridItem(){this.detail={};}
GridItem.prototype={x:0,y:0,pixelHeight:0,gridWidth:1,scale:1,persistToDB:true,lastX:null,lastY:null,lastScale:null,get hasCachedIcon(){return this.detail&&this.detail.decoratedIconBlob;},renderer:GridIconRenderer.TYPE.STANDARD,iconState:'none',get defaultIcon(){return'/shared/elements/gaia_grid/images/default_icon.png';},get grid(){return document.getElementsByTagName('gaia-grid')[0]._grid;},isRemovable:function(){return false;},isEditable:function(){return false;},isDraggable:function(){return true;},isIconFromOrigin:function(){return this.icon.startsWith('http')||this.icon.startsWith('app:');},setPosition:function(position){this.detail.index=position;},setCoordinates:function(x,y){this.x=x;this.y=y;},requestAttention:function(){var rect={x:this.x,y:this.y,width:this.gridWidth*this.grid.layout.gridItemWidth,height:this.pixelHeight};this.grid.element.dispatchEvent(new CustomEvent('gaiagrid-attention',{detail:rect}));},closestIconSizeFromList:function(choices){if(!choices){return 0;}
var sizes=Object.keys(choices);if(!sizes.length){return 0;}
var maxSize=this.grid.layout.gridMaxIconSize;var filter=(a)=>a>=maxSize?a:0;var bestSize=Math.min(...sizes.map(filter));bestSize=bestSize||Math.max(...sizes);return bestSize||0;},closestIconFromList:function(choices){var icon;if(Array.isArray(choices)){var manifest={'icons':choices};var maxSize=this.grid.layout.gridMaxIconSize;icon=window.IconsHelper.getBestIconFromWebManifest(manifest,maxSize);return icon?(new URL(icon,this.app.manifestURL)).href:null;}
var accurateSize=this.closestIconSizeFromList(choices);if(accurateSize===0){return this.defaultIcon;}
icon=choices[accurateSize];if(!UrlHelper.hasScheme(icon)){icon=this.app.origin+icon;}
return icon;},renderIconFromSrc:function(url){var background=new Image();background.src=url;background.onload=this._decorateIcon.bind(this,background);},renderIconFromBlob:function(blob){var background=new Image();background.src=URL.createObjectURL(blob);background.onload=()=>{this._decorateIcon(background);URL.revokeObjectURL(background.src);};background.onerror=()=>{URL.revokeObjectURL(background.src);if(this.hasCachedIcon){this._stampElementWithIcon('blobcache');this._displayDecoratedIcon(this.detail.decoratedIconBlob,true);return;}
this.renderIconFromSrc(this.defaultIcon);this._stampElementWithIcon(this.defaultIcon);};},_decorateIcon:function(img){var strategy=this.detail.renderer||this.renderer;this.rendererInstance=new GridIconRenderer(this);this.rendererInstance[strategy](img).then(this._displayDecoratedIcon.bind(this));},_displayDecoratedIcon:function(blob,isCachedIcon){if(!this.element){return;}
var style=this.element.style;if(!style.backgroundSize){style.height=this.grid.layout.gridItemHeight+'px';var backgroundHeight=((this.grid.layout.gridIconSize*(1/this.grid.layout.percent))+
GridIconRenderer.prototype.unscaledCanvasPadding);if(this.grid.layout.gridItemHeight>backgroundHeight){style.backgroundSize=backgroundHeight+'px';}else{style.backgroundSize=style.height;}}
if(isCachedIcon){var url=URL.createObjectURL(blob);style.backgroundImage='url('+url+')';this.element.dataset.backgroundImage=url;var img=new Image();img.onload=img.onerror=()=>{this.grid.element.dispatchEvent(new CustomEvent('cached-icon-rendered'));};img.src=url;return;}
this._compareBlobs(blob,this.detail.decoratedIconBlob).then((equal)=>{if(equal){return;}
style.backgroundImage='url('+URL.createObjectURL(blob)+')';this.detail.decoratedIconBlob=blob;this.grid.element.dispatchEvent(new CustomEvent(ICON_BLOB_DECORATED_EVENT,{detail:this}));var bgImg=this.element.dataset.backgroundImage;bgImg&&URL.revokeObjectURL(bgImg);});},_compareBlobs:function(blob1,blob2){return new Promise(function(resolve){if(!blob1||!blob2||blob1.type!==blob2.type||blob1.size!==blob2.size){resolve(false);return;}
var startBytes=127;var bytesHash=16;var reader=new FileReader();reader.onloadend=function(){var result1=reader.result;reader=new FileReader();reader.onloadend=reader.onerror=function(){resolve(result1===reader.result);};reader.readAsDataURL(blob2.slice(startBytes,startBytes+bytesHash));};reader.onerror=function(){resolve(false);};reader.readAsDataURL(blob1.slice(startBytes,startBytes+bytesHash));});},fetchIconBlob:function(){return fetchBlob(this.icon);},_stampElementWithIcon:function(uri){if(!this.element||uri.startsWith('data:')){return;}
if(uri.length>255){uri=uri.slice(0,255);}
this.element.dataset.testIcon=uri;},renderIcon:function(renderCachedIcon){var icon=this.icon;this.iconState='pending';if(!icon){return;}
if(renderCachedIcon&&this.hasCachedIcon){this._displayDecoratedIcon(this.detail.decoratedIconBlob,true);var resolveIcon=()=>{this.grid.element.removeEventListener('cached-icons-rendered',resolveIcon);this.doRenderIcon(icon);};this.grid.element.addEventListener('cached-icons-rendered',resolveIcon);}else{this.doRenderIcon(icon);}},doRenderIcon:function(icon){if(!this.isIconFromOrigin()){this._stampElementWithIcon(icon);this.renderIconFromSrc(icon);this.iconState='success';return Promise.resolve();}
var eventTarget=this.grid.element;var blobNotFound=()=>{this.iconState='error';if(!this.hasCachedIcon){this.renderIconFromSrc(this.defaultIcon);this._stampElementWithIcon(this.defaultIcon);}else{this._stampElementWithIcon('blobcache');}
eventTarget.dispatchEvent(new CustomEvent(ICON_BLOB_ERROR_EVENT,{detail:this}));};return this.fetchIconBlob().then((blob)=>{if(!blob){return blobNotFound();}
this.renderIconFromBlob(blob);this.iconState='success';this._stampElementWithIcon(icon);}).catch((err)=>{blobNotFound();});},removeFromGrid:function(){var idx=this.grid.items.indexOf(this);if(idx===-1){console.error('Attempting to remove self before item has been added!');return;}
this.grid.items.splice(idx,1);delete this.grid.icons[this.identifier];if(this.element){this.element.parentNode.removeChild(this.element);}
this.grid.render({from:idx-1});},remove:function(){this.grid.element.dispatchEvent(new CustomEvent('removeitem',{detail:this}));},render:function(){var scale=this.grid.layout.percent*this.scale;if(!this.element){var tile=document.createElement('div');tile.className='icon';tile.dataset.identifier=this.identifier;tile.dataset.isDraggable=this.isDraggable();tile.setAttribute('role','link');tile.setAttribute('tabindex',0);tile.style.width=(this.grid.layout.constraintSize/3)+'px';var nameContainerEl=document.createElement('p');nameContainerEl.style.marginTop=((this.grid.layout.gridIconSize*(1/this.grid.layout.percent))+
(GridIconRenderer.prototype.unscaledCanvasPadding/2))+'px';tile.appendChild(nameContainerEl);var nameEl=document.createElement('span');nameEl.className='title';nameEl.setAttribute('dir','auto');nameContainerEl.appendChild(nameEl);if(this.isRemovable()){var removeEl=document.createElement('span');removeEl.className='remove';tile.appendChild(removeEl);}
this.element=tile;this.updateTitle();this.renderIcon(true);this.grid.element.appendChild(tile);}
this.transform(this.x,this.y,scale);},transform:function(x,y,scale,element){scale=scale||1;if(!element){if(x===this.lastX&&y===this.lastY&&scale===this.lastScale){return;}
element=this.element;this.lastX=x;this.lastY=y;this.lastScale=scale;}
element.style.transform='translate('+x+'px,'+y+'px) scale('+scale+')';},setActive:function(active){if(active){this.element.classList.add('active');this.active=true;}else{this.element.classList.remove('active');this.active=false;}},updateTitle:function(){if(!this.element){return;}
var nameEl=this.element.querySelector('.title');if(this.asyncName){this.asyncName().then(function(name){nameEl.textContent=name;});}else{nameEl.textContent=this.name;}},updateFromDatastore:function(record){var iconChanged=record.icon!==this.icon;var nameChanged=record.name!==this.name;var type=this.detail.type;var lastIcon=this.icon;record.type=type;this.detail=record;if(nameChanged){this.updateTitle();}
if(iconChanged&&record.icon){this.renderIcon();}else if(!record.icon){this.detail.icon=lastIcon;}}};exports.GaiaGrid.GridItem=GridItem;}(window));;'use strict';(function(exports){const TYPE='bookmark';function Bookmark(record,features){this.detail=record;this.features=features||{};this.detail.type=TYPE;}
Bookmark.prototype={__proto__:GaiaGrid.GridItem.prototype,renderer:GridIconRenderer.TYPE.FAVICON,get pixelHeight(){return this.grid.layout.gridItemHeight;},gridWidth:1,get name(){return this.detail.name;},get icon(){return this.detail.icon||this.defaultIcon;},get identifier(){return this.detail.id;},update:GaiaGrid.GridItem.prototype.updateFromDatastore,isEditable:function(){return this.features&&this.features.isEditable!==false;},isRemovable:function(){return this.features&&this.features.isRemovable!==false;},isDraggable:function(){return this.features&&this.features.isDraggable!==false;},render:function(){GaiaGrid.GridItem.prototype.render.call(this);this.element.classList.add('bookmark');if(this.isEditable()){this.element.classList.add('editable');}},launch:function(){var features={name:this.name,icon:this.icon,remote:true};var url=this.detail.url;if(this.features.search){features.searchName=this.name;features.searchUrl=url;}
window.open(url,'_samescope',Object.keys(features).map(function eachFeature(key){return encodeURIComponent(key)+'='+
encodeURIComponent(features[key]);}).join(','));},edit:function(){new MozActivity({name:'save-bookmark',data:{type:'url',url:this.detail.id}});}};exports.GaiaGrid.Bookmark=Bookmark;}(window));;'use strict';(function(exports){function Divider(){this.detail={type:'divider',index:0};}
Divider.prototype={__proto__:GaiaGrid.GridItem.prototype,x:0,y:0,headerHeight:0,get pixelHeight(){return(this.grid.layout.cols>3)?50:60;},gridWidth:4,scale:1,render:function(){if(!this.element){var divider=this.element=document.createElement('section');divider.className='divider';var span=document.createElement('span');span.className='spacer';divider.appendChild(span);this.grid.element.appendChild(divider);}
this.element.style.transform='translate(0 ,'+this.y+'px)';},remove:function(){if(this.element){this.element.parentNode.removeChild(this.element);}},isDraggable:function(){return false;}};exports.GaiaGrid.Divider=Divider;}(window));;'use strict';(function(exports){const IDENTIFIER_SEP='-';var MOZAPP_EVENTS=['downloadsuccess','downloaderror','downloadavailable','downloadapplied','progress'];var APP_LOADING='loading';var APP_ERROR='error';var APP_UNRECOVERABLE='unrecoverable';var APP_PAUSED='paused';var APP_READY='ready';function localizeString(str){var userLang=document.documentElement.lang;if(navigator.mozL10n&&navigator.mozL10n.ctx.qps.indexOf(userLang)!==-1){return navigator.mozL10n.qps[userLang].translate(str);}
return str;}
function Mozapp(app,entryPoint,details){this.app=app;this.entryPoint=entryPoint;this.detail={type:'app',manifestURL:app.manifestURL,entryPoint:entryPoint,index:0,decoratedIconBlob:details&&details.decoratedIconBlob};MOZAPP_EVENTS.forEach(function(type){this.app['on'+type]=this.handleEvent.bind(this);},this);this.setAppState(this._determineState(app));}
Mozapp.HIDDEN_ROLES=['system','input','homescreen','search','addon','langpack'];Mozapp.prototype={__proto__:GaiaGrid.GridItem.prototype,_isHiddenRole:function(){var manifest=this.app.manifest;if(!manifest||!manifest.role){return null;}
return Mozapp.HIDDEN_ROLES.indexOf(manifest.role)!==-1;},_determineState:function(app){if(app.installState==='pending'&&!app.downloadAvailable&&!app.readyToApplyDownload){return APP_UNRECOVERABLE;}
if(app.downloading){return APP_LOADING;}
if(app.downloadError&&app.downloadError.name){if(app.downloadError.name==='DOWNLOAD_CANCELED'){return APP_PAUSED;}
return APP_ERROR;}
if(app.installState==='pending'){return APP_PAUSED;}
return APP_READY;},handleEvent:function(event){switch(event.type){case'progress':case'downloaderror':case'downloadsuccess':this.setAppState(this._determineState(this.app));break;case'downloadapplied':if(this._isHiddenRole()){console.warn('Removing hidden app from the grid',this.name);return this.removeFromGrid();}
delete this._accurateIcon;delete this._accurateIconSize;this.setAppState(this._determineState(this.app));this.renderIcon();window.dispatchEvent(new CustomEvent('downloadapplied',{detail:{id:this.app.manifestURL}}));break;}},fetchIconBlob:function(){if(!this._accurateIconSize){this._accurateIconSize=this.closestIconSizeFromList(this.descriptor.icons);}
var result=this._accurateIconSize?navigator.mozApps.mgmt.getIcon(this.app,this._accurateIconSize,this.entryPoint||''):GaiaGrid.GridItem.prototype.fetchIconBlob.call(this);return result;},get pixelHeight(){return this.grid.layout.gridItemHeight;},gridWidth:1,get name(){var userLang=document.documentElement.lang;if(navigator.mozL10n&&userLang in navigator.mozL10n.qps){return navigator.mozL10n.qps[userLang].translate(this.descriptor.short_name||this.descriptor.name);}
var locales=this.descriptor.locales;var localized=locales&&locales[userLang]&&(locales[userLang].short_name||locales[userLang].name);return localized||this.descriptor.short_name||this.descriptor.name;},asyncName:function(){var userLang=document.documentElement.lang;var ep=this.entryPoint||undefined;if(!this.app.getLocalizedValue){return new Promise((resolve,reject)=>{reject();});}
return this.app.getLocalizedValue('short_name',userLang,ep).then(shortName=>localizeString(shortName),this.app.getLocalizedValue.bind(this.app,'name',userLang,ep)).then(name=>localizeString(name),()=>this.name);},get icon(){var icon=this._accurateIcon;if(!icon){icon=this._accurateIcon=this.closestIconFromList(this.descriptor.icons);}
return icon;},get descriptor(){var manifest=this.app.manifest||this.app.updateManifest;if(this.entryPoint&&manifest.entry_points&&manifest.entry_points[this.entryPoint]){return manifest.entry_points[this.entryPoint];}
return manifest;},identifierSeparator:IDENTIFIER_SEP,get identifier(){var identifier=[this.app.manifestURL];if(this.entryPoint){identifier.push(this.entryPoint);}
return identifier.join(IDENTIFIER_SEP);},isRemovable:function(){return this.app.removable;},unrecoverableError:function(){navigator.mozApps.mgmt.uninstall(this.app);},cancel:function(){var dialog=new ConfirmDialogHelper({type:'pause',title:{id:'gaia-grid-stop-download-title',args:{name:this.name}},body:'gaia-grid-stop-download-body',cancel:{title:'gaia-grid-cancel'},confirm:{title:'gaia-grid-stop-download-action',type:'danger',cb:()=>this.app.cancelDownload()}});dialog.show(document.body);},resume:function(){var dialog=new ConfirmDialogHelper({type:'resume',title:'gaia-grid-resume-download-title',body:{id:'gaia-grid-resume-download-body',args:{name:this.name}},cancel:{title:'gaia-grid-cancel'},confirm:{title:'gaia-grid-resume-download-action',cb:()=>{this.setAppState(APP_LOADING);this.app.download();}}});dialog.show(document.body);},setAppState:function(state){this.appState=state;if(this.element){this.element.dataset.appState=state;}},render:function(){var needsStateSet=!this.element;GaiaGrid.GridItem.prototype.render.apply(this,arguments);if(needsStateSet){this.setAppState(this.appState);}},launch:function(){var app=this.app;switch(this._determineState(app)){case APP_UNRECOVERABLE:return this.unrecoverableError();case APP_ERROR:case APP_PAUSED:return this.resume();case APP_LOADING:return this.cancel();}
window.performance.mark('appLaunch@'+app.origin);if(this.entryPoint){return app.launch(this.entryPoint);}
return app.launch();}};exports.GaiaGrid.Mozapp=Mozapp;}(window));;'use strict';(function(exports){const COLLAPSE_RATIO=0.33;const COLLAPSED_GROUP_SIZE=6;const COLLAPSED_GROUP_MARGIN_LEFT=23;const COLLAPSED_GROUP_MARGIN_RIGHT=53;const TOGGLE_TIMEOUT=250;function Group(detail){this.detail=detail||{};this.detail.type='divider';this.detail.index=0;this.pendingCollapse=this.detail.collapsed=!!this.detail.collapsed;}
Group.prototype={__proto__:GaiaGrid.GridItem.prototype,gridWidth:4,get headerHeight(){return this.detail.collapsed?20:30;},pendingCollapse:false,pendingCollapseTimeout:null,backgroundHeight:0,lastBackgroundHeight:null,separatorHeight:0,collapseRatio:COLLAPSE_RATIO,get pixelHeight(){return this.detail.collapsed?this.backgroundHeight:this.separatorHeight;},get size(){var size=0;for(var i=this.detail.index-1,items=this.grid.items;i>=0&&items[i].detail.type!=='divider';i--){size++;}
return size;},_createElement:function(){var group=this.element=document.createElement('section');group.className='divider group newly-created';var span=document.createElement('span');span.className='background';group.appendChild(span);this.backgroundSpanElement=span;span=document.createElement('span');span.className='shadow';group.appendChild(span);this.shadowSpanElement=span;span=document.createElement('span');span.className='header';group.appendChild(span);this.headerSpanElement=span;span=document.createElement('span');span.className='gripper';this.headerSpanElement.appendChild(span);var button=document.createElement('button');button.className='toggle';button.dataset.l10nId='gaia-grid-toggle-expanded';this.headerSpanElement.appendChild(button);this.toggleElement=button;span=document.createElement('span');span.className='separator';group.appendChild(span);this.dividerSpanElement=span;this.dividerSpanElement.appendChild(document.createElement('span'));this.grid.element.appendChild(group);this.separatorHeight=this.dividerSpanElement.clientHeight;this.lastBackgroundHeight=null;},_renderChildren:function(nApps){var isRTL=(document.documentElement.dir==='rtl');if(!this.detail.collapsed){this.element.classList.remove('collapsed');return;}
this.element.classList.add('collapsed');var y=this.y;var index=this.detail.index;var width=Math.round((this.grid.layout.constraintSize-
COLLAPSED_GROUP_MARGIN_LEFT-COLLAPSED_GROUP_MARGIN_RIGHT)/COLLAPSED_GROUP_SIZE);var x=isRTL?(this.grid.layout.constraintSize-COLLAPSED_GROUP_MARGIN_RIGHT):COLLAPSED_GROUP_MARGIN_LEFT;y+=this.headerHeight;var maxGridItemWidth=this.grid.layout.constraintSize/this.grid.layout.minIconsPerRow;this.collapseRatio=(maxGridItemWidth/this.grid.layout.gridItemWidth)*COLLAPSE_RATIO;for(var i=index-nApps;i<index;i++){var item=this.grid.items[i];if(this.detail.collapsed){item.scale=this.collapseRatio;var itemVisible=(i-(index-nApps))<COLLAPSED_GROUP_SIZE;if(!itemVisible){item.setCoordinates(isRTL?x+width:x-width,y);}else{item.setCoordinates(x,y);x+=isRTL?-width:width;}
item.render();item.element.classList.add('collapsed');if(!itemVisible){item.element.classList.add('hidden');}}}},getRealYPosition:function(nApps){if(this.detail.collapsed){return this.y;}
return this.grid.items[this.detail.index-nApps].y-
this.headerHeight;},render:function(){var createdElements=false;if(!this.element){createdElements=true;this._createElement();}
var nApps=this.size;this._renderChildren(nApps);var y=this.getRealYPosition(nApps);if(y!==this.lastY){this.headerSpanElement.style.transform='translate(0px, '+y+'px)';}
if(this.toggleElement){var toggleLabel=this.detail.collapsed?'collapsed':'expanded';this.toggleElement.dataset.l10nId='gaia-grid-toggle-'+toggleLabel;}
if(this.detail.collapsed){this.backgroundHeight=Math.round(this.collapseRatio*this.grid.layout.gridIconSize*1.5);}else{var height=Math.ceil(nApps/this.grid.layout.cols);this.backgroundHeight=(height||1)*this.grid.layout.gridItemHeight;}
this.backgroundHeight+=this.headerHeight;if(y!=this.lastY||this.backgroundHeight!==this.lastBackgroundHeight){this.backgroundSpanElement.style.transform='translate(0px, '+y+'px) scale(1, '+this.backgroundHeight+')';this.shadowSpanElement.style.transform='translateY('+y+'px)';this.shadowSpanElement.style.height=this.backgroundHeight+'px';this.dividerSpanElement.style.transform='translate(0px, '+(y+this.backgroundHeight)+'px)';}
this.lastBackgroundHeight=this.backgroundHeight;this.lastY=y;this.backgroundHeight+=this.separatorHeight;if(createdElements){this.element.clientTop;this.element.classList.remove('newly-created');}},forEachItem:function(callback){var nApps=this.size;var index=this.detail.index;for(var i=index-nApps;i<index;i++){callback(this.grid.items[i]);}},setActive:function(active){GaiaGrid.GridItem.prototype.setActive.call(this,active);this.collapse();var callback=active?function(item){item.element.classList.add('active');}:function(item){item.element.classList.remove('active');};this.forEachItem(callback);},_rerenderOnToggle:function(){if(this.pendingCollapseTimeout){clearTimeout(this.pendingCollapseTimeout);this.pendingCollapseTimeout=null;}
if(this.toggleElement){this.toggleElement.classList.add('toggling');setTimeout(()=>{this.toggleElement.classList.remove('toggling');},TOGGLE_TIMEOUT);}
this.pendingCollapseTimeout=setTimeout(()=>{this.detail.collapsed=this.pendingCollapse;this.pendingCollapseTimeout=null;if(!this.detail.collapsed){this.forEachItem(function(item){item.scale=1;if(item.element){item.element.classList.remove('collapsed');item.element.classList.remove('hidden');}});}
if(this.active){this.render();}
this.grid.render();var dragging=this.grid.dragdrop&&this.grid.dragdrop.inDragAction;if(dragging){this.grid.dragdrop.updateIconPosition();}else{window.dispatchEvent(new CustomEvent('gaiagrid-saveitems'));this.requestAttention();}},20);},collapse:function(){if(this.detail.collapsed){return;}
this.pendingCollapse=true;this._rerenderOnToggle();},expand:function(){if(!this.detail.collapsed){return;}
this.pendingCollapse=false;this._rerenderOnToggle();},launch:function(target){if(target!==this.toggleElement){return;}
if(this.detail.collapsed){this.expand();}else{this.collapse();}},remove:function(){if(this.element){this.element.parentNode.removeChild(this.element);}},isDraggable:function(){return true;},requestAttention:function(){var rect={x:0,y:this.getRealYPosition(this.size),width:this.gridWidth*this.grid.layout.gridItemWidth,height:this.backgroundHeight};this.grid.element.dispatchEvent(new CustomEvent('gaiagrid-attention',{detail:rect}));}};exports.GaiaGrid.Divider=Group;}(window));;'use strict';(function(exports){function Placeholder(){this.detail={type:'placeholder',index:0};}
Placeholder.prototype={__proto__:GaiaGrid.GridItem.prototype,get pixelHeight(){return this.grid.layout.gridItemHeight;},createsGroupOnDrop:false,gridWidth:1,persistToDB:false,get name(){return'';},render:function(){if(!this.element){var tile=document.createElement('div');tile.className='icon placeholder';tile.style.height=this.pixelHeight+'px';this.element=tile;this.grid.element.appendChild(tile);}
this.transform(this.x,this.y,this.grid.layout.percent);},remove:function(){if(this.element){this.element.parentNode.removeChild(this.element);}}};exports.GaiaGrid.Placeholder=Placeholder;}(window));;window.COMPONENTS_BASE_URL='/shared/elements/';;'use strict';(function(exports){const HIDDEN_ROLES=['system','input','homescreen','theme','addon','langpack'];const EDIT_MODE_TRANSITION_STYLE='transform 0.25s ease 0s, height 0s ease 0.5s';function App(){window.performance.mark('navigationLoaded');this.grid=document.getElementById('icons');this.grid.addEventListener('iconblobdecorated',this);this.grid.addEventListener('gaiagrid-iconbloberror',this);this.grid.addEventListener('gaiagrid-attention',this);this.grid.addEventListener('gaiagrid-resize',this);this.grid.addEventListener('cached-icons-rendered',this);this.grid.addEventListener('edititem',this);this.grid.addEventListener('editmode-start',this);this.grid.addEventListener('editmode-end',this);window.addEventListener('hashchange',this);window.addEventListener('gaiagrid-saveitems',this);window.addEventListener('online',this.retryFailedIcons.bind(this));var editModeDone=document.getElementById('exit-edit-mode');editModeDone.addEventListener('click',this.exitEditMode);window.addEventListener('gaiagrid-dragdrop-begin',this);window.addEventListener('gaiagrid-dragdrop-finish',this);window.addEventListener('context-menu-open',this);window.addEventListener('context-menu-close',this);window.addEventListener('gaia-confirm-open',this);window.addEventListener('gaia-confirm-close',this);this.layoutReady=false;window.addEventListener('gaiagrid-layout-ready',this);this._iconsToRetry=[];document.addEventListener('visibilitychange',this);window.performance.mark('navigationInteractive');}
App.prototype={HIDDEN_ROLES:HIDDEN_ROLES,EDIT_MODE_TRANSITION_STYLE:EDIT_MODE_TRANSITION_STYLE,retryFailedIcons:function(){if(!this._iconsToRetry.length){return;}
var icons=this.grid.getIcons();var iconId;while((iconId=this._iconsToRetry.shift())){var icon=icons[iconId];if(!icon){continue;}
icon.renderIcon();}},init:function(){this.itemStore=new ItemStore((firstTime)=>{if(!firstTime){return;}
LazyLoader.load(['shared/js/icc_helper.js','shared/js/version_helper.js','js/configurator.js'],function onLoad(){exports.configurator=new Configurator();});});this.itemStore.all(function _all(results){results.forEach(function _eachResult(result){this.grid.add(result);},this);if(this.layoutReady){this.renderGrid();}else{window.addEventListener('gaiagrid-layout-ready',function onReady(){window.removeEventListener('gaiagrid-layout-ready',onReady);this.renderGrid();}.bind(this));}
window.performance.mark('visuallyLoaded');window.performance.mark('contentInteractive');window.addEventListener('localized',this.onLocalized.bind(this));LazyLoader.load(['shared/elements/gaia-header/dist/gaia-header.js','js/contextmenu_handler.js','/shared/js/homescreens/confirm_dialog_helper.js'],function(){window.performance.mark('fullyLoaded');});}.bind(this));},renderGrid:function(){this.grid.setEditHeaderElement(document.getElementById('edit-header'));this.grid.render();},start:function(){this.grid.start();},stop:function(){this.grid.stop();},onLocalized:function(){var items=this.grid.getItems();items.forEach(function eachItem(item){if(!item.name){return;}
item.updateTitle();});this.renderGrid();},exitEditMode:function(e){e.preventDefault();window.dispatchEvent(new CustomEvent('hashchange'));},handleEvent:function(e){switch(e.type){case'cached-icons-rendered':window.dispatchEvent(new CustomEvent('gaiagrid-cached-icons-rendered'));break;case'iconblobdecorated':var item=e.detail;this.itemStore.saveItem(item.detail,()=>{item.element.classList.add('test-icon-cached');});break;case'edititem':var icon=e.detail;if(icon.detail.type!='divider'){return;}
LazyLoader.load('js/edit_group.js',()=>{groupEditor.edit(icon);});break;case'gaiagrid-iconbloberror':this._iconsToRetry.push(e.detail.identifier);break;case'gaiagrid-attention':var offsetTop=this.grid.offsetTop;var scrollTop=window.scrollY;var gridHeight=document.body.clientHeight;if(this.grid._grid.dragdrop.inEditMode){gridHeight-=offsetTop;}else{scrollTop-=offsetTop;}
var rect=e.detail;if(scrollTop+gridHeight<rect.y+rect.height){scrollTop=(rect.y+rect.height)-gridHeight;}
if(scrollTop>rect.y){scrollTop=rect.y;}
if(!this.grid._grid.dragdrop.inEditMode){scrollTop+=offsetTop;}
if(scrollTop!==window.scrollY){document.body.style.overflow='';requestAnimationFrame(()=>{requestAnimationFrame(()=>{window.scrollTo({left:0,top:scrollTop,behavior:'smooth'});});});}
break;case'gaiagrid-resize':var height=e.detail;var oldHeight=this.grid.clientHeight;if(this.gridResizeTimeout!==null){clearTimeout(this.gridResizeTimeout);this.gridResizeTimeout=null;}
if(height<oldHeight){var viewHeight=document.body.clientHeight;var scrollBottom=window.scrollY+viewHeight;var padding=window.getComputedStyle?parseInt(window.getComputedStyle(this.grid).paddingBottom):0;var maxScrollBottom=height+this.grid.offsetTop+padding;if(scrollBottom>=maxScrollBottom){requestAnimationFrame(()=>{requestAnimationFrame(()=>{window.scrollTo({left:0,top:maxScrollBottom-viewHeight,behavior:'smooth'});});});}}
if(height===oldHeight){break;}
this.grid.style.height=height+'px';break;case'gaiagrid-saveitems':this.itemStore.save(this.grid.getItems());break;case'context-menu-open':case'gaia-confirm-open':document.body.classList.add('fixed-overlay-shown');case'gaiagrid-dragdrop-begin':window.removeEventListener('hashchange',this);break;case'context-menu-close':case'gaia-confirm-close':document.body.classList.remove('fixed-overlay-shown');case'gaiagrid-dragdrop-finish':window.addEventListener('hashchange',this);break;case'gaiagrid-layout-ready':this.layoutReady=true;window.removeEventListener('gaiagrid-layout-ready',this);break;case'visibilitychange':if(document.hidden){document.body.style.overflow='hidden';}else{setTimeout(function(){document.body.style.overflow='';});}
break;case'editmode-start':this.grid.style.transition=this.EDIT_MODE_TRANSITION_STYLE;break;case'editmode-end':this.grid.style.transition='';break;case'hashchange':var editor=exports.groupEditor;if(editor&&!editor.hidden){return;}
var _grid=this.grid._grid;if(_grid.dragdrop&&_grid.dragdrop.inEditMode){_grid.dragdrop.exitEditMode();return;}
if(document.hidden){return;}
window.scrollTo({left:0,top:0,behavior:'smooth'});}}};exports.configurator={getSingleVariantApp:function(){return{};},get isSingleVariantReady(){return true;},get isSimPresentOnFirstBoot(){return false;},getItems:function(role){return{};}};exports.app=new App();exports.app.init();}(window));;(function(exports){'use strict';function Search(){this._port=null;this.connected=false;this.pendingRender=false;if(!appManager.app){window.addEventListener('appmanager-ready',function onReady(){window.removeEventListener('appmanager-ready',onReady);this.onAppReady();}.bind(this));}else{this.onAppReady();}
var input=document.getElementById('search');input.addEventListener('click',this.open.bind(this));input.addEventListener('contextmenu',(e)=>{e.stopPropagation();});}
Search.prototype={onAppReady:function onAppReady(){appManager.app.connect('search-results').then(function onConnectionAccepted(ports){ports.forEach(function(port){this._port=port;}.bind(this));this.connected=true;if(this.pendingRender){this.open();}}.bind(this),function onConnectionRejected(){});},open:function openRocketbar(e){window.scrollTo(0,0);e.stopPropagation();e.preventDefault();if(!this.connected){this.pendingRender=true;return;}
this._port.postMessage({action:'render'});}};exports.search=new Search();})(window);

View file

@ -0,0 +1,113 @@
<!DOCTYPE html>
<html lang="en-US" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
<meta name="theme-color" content="transparent">
<title>FirefoxOS Homescreen</title>
<link rel="stylesheet" href="style/css/app.css">
<link rel="stylesheet" href="style/css/search.css">
<link rel="stylesheet" href="shared/elements/gaia_grid/style/external.css">
<meta name="defaultLanguage" content="en-US">
<meta name="availableLanguages" content="ar:201601260729, bg:201601260729, bn-BD:201601260729, ca:201601260729, cs:201601260729, da:201601260729, de:201601260729, el:201601260729, en-US:201601260729, es:201601260729, eu:201601260729, fr:201601260729, gl:201601260729, hr:201601260729, hu:201601260729, it:201601260729, ja:201601260729, km:201601260729, ko:201601260729, lt:201601260729, mk:201601260729, ms:201601260729, ne-NP:201601260729, nl:201601260729, pa:201601260729, pl:201601260729, pt-BR:201601260729, ro:201601260729, ru:201601260729, sk:201601260729, sq:201601260729, sr-Cyrl:201601260729, sr-Latn:201601260729, sv-SE:201601260729, tr:201601260729, zh-CN:201601260729, zh-TW:201601260729">
<link rel="localization" href="/locales-obj/index.{locale}.json">
<!-- <script defer="" src="shared/js/l10n.js"></script> -->
<!-- <link rel="stylesheet" href="shared/style/input_areas.css"> -->
<!-- Those libraries are loaded after rendering icons -->
<!-- <script defer src="shared/js/homescreens/confirm_dialog_helper.js"></script> -->
<!-- <script defer src="js/contextmenu_handler.js"></script> -->
<!-- Lazy load for Confirm dialog component -->
<!-- <script defer src="/shared/js/component_utils.js"></script> -->
<!-- <script defer src="/shared/elements/gaia_buttons/script.js"></script> -->
<!-- <script defer src="/shared/elements/gaia_confirm/script.js"></script> -->
<!-- <script defer src="/shared/elements/gaia_menu/script.js"></script> -->
<!-- Lazy load for Context Menu -->
<!-- <script src="js/contextmenu_ui.js"></script> -->
<!-- <script type="text/javascript" src="shared/js/omadrm/fl.js"></script> -->
<!-- <script type="text/javascript" src="js/wallpaper.js"></script> -->
<!-- <script defer="" src="js/sources/application.js"></script> -->
<!-- <script defer="" src="js/app_manager.js"></script> -->
<!-- <script defer="" src="js/statusbar.js"></script> -->
<!-- <script defer="" src="shared/js/homescreens/vertical_preferences.js"></script> -->
<!-- <script defer="" src="shared/js/bookmarks_database.js"></script> -->
<!-- <script defer="" src="shared/js/lazy_loader.js"></script> -->
<!-- <script defer="" src="shared/js/url_helper.js"></script> -->
<!-- <script defer="" src="shared/js/web_manifest_helper.js"></script> -->
<!-- <script defer="" src="shared/js/icons_helper.js"></script> -->
<!-- <script defer="" src="js/sources/bookmark.js"></script> -->
<!-- <script defer="" src="js/stores/item.js"></script> -->
<!-- <script defer="" src="shared/elements/gaia_grid/js/grid_layout.js"></script> -->
<!-- <script defer src="shared/elements/gaia_grid/js/grid_dragdrop.js"></script> -->
<!-- <script defer="" src="shared/elements/gaia_grid/js/grid_icon_renderer.js"></script> -->
<!-- <script defer="" src="shared/elements/gaia_grid/js/grid_view.js"></script> -->
<!-- <script defer="" src="shared/elements/gaia_grid/script.js"></script> -->
<!-- <script defer="" src="shared/elements/gaia_grid/js/items/grid_item.js"></script> -->
<!-- <script defer="" src="shared/elements/gaia_grid/js/items/bookmark.js"></script> -->
<!-- <script defer="" src="shared/elements/gaia_grid/js/items/divider.js"></script> -->
<!-- <script defer="" src="shared/elements/gaia_grid/js/items/mozapp.js"></script> -->
<!-- <script defer="" src="shared/elements/gaia_grid/js/items/group.js"></script> -->
<!-- <script defer="" src="shared/elements/gaia_grid/js/items/placeholder.js"></script> -->
<!-- Gaia Components -->
<!-- <script defer="" src="shared/elements/config.js"></script> -->
<!-- <link rel="stylesheet" href="shared/elements/gaia-icons/gaia-icons.css"> -->
<link rel="stylesheet" href="app://theme.gaiamobile.org/shared/elements/gaia-theme/gaia-theme.css">
<!-- <script defer src="shared/elements/gaia-header/dist/gaia-header.js"></script> -->
<!-- <script defer="" src="js/app.js"></script> -->
<!-- <script defer="" src="js/search.js"></script> --><script src="./gaia_build_defer_index.js" defer="" type="text/javascript"></script>
<!-- <script defer src="shared/js/icc_helper.js"></script> -->
<!-- <script defer src="shared/js/version_helper.js"></script> -->
<!-- <script defer src="js/configurator.js"></script> -->
<meta content="2.5" name="appVersion"></head>
<body class="theme-media">
<div id="curtain"></div>
<section id="edit-header" role="region">
<gaia-header ignore-dir="">
<h1 data-l10n-id="edit-mode">Edit</h1>
<a href="#" data-l10n-id="edit-done" id="exit-edit-mode">Done</a>
</gaia-header>
</section>
<div id="search" role="button" aria-labelledby="search-input" aria-haspopup="true">
<form id="search-form">
<input id="search-input" x-inputmode="verbatim" role="presentation" placeholder="Search or enter address" data-l10n-id="search-or-enter-address" value="" dir="auto" type="text">
</form>
</div>
<gaia-grid id="icons" dragdrop=""></gaia-grid>
<gaia-menu id="contextmenu-dialog" hidden="">
<button id="homescreen-settings-action" data-l10n-id="homescreen-settings" type="button">Homescreen Settings</button>
<button id="change-wallpaper-action" data-l10n-id="change-wallpaper" type="button">Change Wallpaper</button>
</gaia-menu>
<section id="edit-group" role="region" hidden="">
<gaia-header ignore-dir="" id="edit-group-header" action="close">
<h1 data-l10n-id="edit-group-header">Edit group</h1>
<button id="edit-group-save" disabled="" type="button" data-l10n-id="edit-done">Done</button>
</gaia-header>
<form>
<p>
<input id="edit-group-title" x-inputmode="latin-prose" dir="auto" type="text">
<button id="edit-group-title-clear" type="reset"></button>
</p>
</form>
</section>
</body>
</html>

View file

@ -0,0 +1,20 @@
;'use strict';(function(exports){const HIDDEN_ROLES=['system','input','homescreen','theme','addon','langpack'];const EDIT_MODE_TRANSITION_STYLE='transform 0.25s ease 0s, height 0s ease 0.5s';function App(){window.performance.mark('navigationLoaded');this.grid=document.getElementById('icons');this.grid.addEventListener('iconblobdecorated',this);this.grid.addEventListener('gaiagrid-iconbloberror',this);this.grid.addEventListener('gaiagrid-attention',this);this.grid.addEventListener('gaiagrid-resize',this);this.grid.addEventListener('cached-icons-rendered',this);this.grid.addEventListener('edititem',this);this.grid.addEventListener('editmode-start',this);this.grid.addEventListener('editmode-end',this);window.addEventListener('hashchange',this);window.addEventListener('gaiagrid-saveitems',this);window.addEventListener('online',this.retryFailedIcons.bind(this));var editModeDone=document.getElementById('exit-edit-mode');editModeDone.addEventListener('click',this.exitEditMode);window.addEventListener('gaiagrid-dragdrop-begin',this);window.addEventListener('gaiagrid-dragdrop-finish',this);window.addEventListener('context-menu-open',this);window.addEventListener('context-menu-close',this);window.addEventListener('gaia-confirm-open',this);window.addEventListener('gaia-confirm-close',this);this.layoutReady=false;window.addEventListener('gaiagrid-layout-ready',this);this._iconsToRetry=[];document.addEventListener('visibilitychange',this);window.performance.mark('navigationInteractive');}
App.prototype={HIDDEN_ROLES:HIDDEN_ROLES,EDIT_MODE_TRANSITION_STYLE:EDIT_MODE_TRANSITION_STYLE,retryFailedIcons:function(){if(!this._iconsToRetry.length){return;}
var icons=this.grid.getIcons();var iconId;while((iconId=this._iconsToRetry.shift())){var icon=icons[iconId];if(!icon){continue;}
icon.renderIcon();}},init:function(){this.itemStore=new ItemStore((firstTime)=>{if(!firstTime){return;}
LazyLoader.load(['shared/js/icc_helper.js','shared/js/version_helper.js','js/configurator.js'],function onLoad(){exports.configurator=new Configurator();});});this.itemStore.all(function _all(results){results.forEach(function _eachResult(result){this.grid.add(result);},this);if(this.layoutReady){this.renderGrid();}else{window.addEventListener('gaiagrid-layout-ready',function onReady(){window.removeEventListener('gaiagrid-layout-ready',onReady);this.renderGrid();}.bind(this));}
window.performance.mark('visuallyLoaded');window.performance.mark('contentInteractive');window.addEventListener('localized',this.onLocalized.bind(this));LazyLoader.load(['shared/elements/gaia-header/dist/gaia-header.js','js/contextmenu_handler.js','/shared/js/homescreens/confirm_dialog_helper.js'],function(){window.performance.mark('fullyLoaded');});}.bind(this));},renderGrid:function(){this.grid.setEditHeaderElement(document.getElementById('edit-header'));this.grid.render();},start:function(){this.grid.start();},stop:function(){this.grid.stop();},onLocalized:function(){var items=this.grid.getItems();items.forEach(function eachItem(item){if(!item.name){return;}
item.updateTitle();});this.renderGrid();},exitEditMode:function(e){e.preventDefault();window.dispatchEvent(new CustomEvent('hashchange'));},handleEvent:function(e){switch(e.type){case'cached-icons-rendered':window.dispatchEvent(new CustomEvent('gaiagrid-cached-icons-rendered'));break;case'iconblobdecorated':var item=e.detail;this.itemStore.saveItem(item.detail,()=>{item.element.classList.add('test-icon-cached');});break;case'edititem':var icon=e.detail;if(icon.detail.type!='divider'){return;}
LazyLoader.load('js/edit_group.js',()=>{groupEditor.edit(icon);});break;case'gaiagrid-iconbloberror':this._iconsToRetry.push(e.detail.identifier);break;case'gaiagrid-attention':var offsetTop=this.grid.offsetTop;var scrollTop=window.scrollY;var gridHeight=document.body.clientHeight;if(this.grid._grid.dragdrop.inEditMode){gridHeight-=offsetTop;}else{scrollTop-=offsetTop;}
var rect=e.detail;if(scrollTop+gridHeight<rect.y+rect.height){scrollTop=(rect.y+rect.height)-gridHeight;}
if(scrollTop>rect.y){scrollTop=rect.y;}
if(!this.grid._grid.dragdrop.inEditMode){scrollTop+=offsetTop;}
if(scrollTop!==window.scrollY){document.body.style.overflow='';requestAnimationFrame(()=>{requestAnimationFrame(()=>{window.scrollTo({left:0,top:scrollTop,behavior:'smooth'});});});}
break;case'gaiagrid-resize':var height=e.detail;var oldHeight=this.grid.clientHeight;if(this.gridResizeTimeout!==null){clearTimeout(this.gridResizeTimeout);this.gridResizeTimeout=null;}
if(height<oldHeight){var viewHeight=document.body.clientHeight;var scrollBottom=window.scrollY+viewHeight;var padding=window.getComputedStyle?parseInt(window.getComputedStyle(this.grid).paddingBottom):0;var maxScrollBottom=height+this.grid.offsetTop+padding;if(scrollBottom>=maxScrollBottom){requestAnimationFrame(()=>{requestAnimationFrame(()=>{window.scrollTo({left:0,top:maxScrollBottom-viewHeight,behavior:'smooth'});});});}}
if(height===oldHeight){break;}
this.grid.style.height=height+'px';break;case'gaiagrid-saveitems':this.itemStore.save(this.grid.getItems());break;case'context-menu-open':case'gaia-confirm-open':document.body.classList.add('fixed-overlay-shown');case'gaiagrid-dragdrop-begin':window.removeEventListener('hashchange',this);break;case'context-menu-close':case'gaia-confirm-close':document.body.classList.remove('fixed-overlay-shown');case'gaiagrid-dragdrop-finish':window.addEventListener('hashchange',this);break;case'gaiagrid-layout-ready':this.layoutReady=true;window.removeEventListener('gaiagrid-layout-ready',this);break;case'visibilitychange':if(document.hidden){document.body.style.overflow='hidden';}else{setTimeout(function(){document.body.style.overflow='';});}
break;case'editmode-start':this.grid.style.transition=this.EDIT_MODE_TRANSITION_STYLE;break;case'editmode-end':this.grid.style.transition='';break;case'hashchange':var editor=exports.groupEditor;if(editor&&!editor.hidden){return;}
var _grid=this.grid._grid;if(_grid.dragdrop&&_grid.dragdrop.inEditMode){_grid.dragdrop.exitEditMode();return;}
if(document.hidden){return;}
window.scrollTo({left:0,top:0,behavior:'smooth'});}}};exports.configurator={getSingleVariantApp:function(){return{};},get isSingleVariantReady(){return true;},get isSimPresentOnFirstBoot(){return false;},getItems:function(role){return{};}};exports.app=new App();exports.app.init();}(window));

View file

@ -0,0 +1,5 @@
;'use strict';(function(exports){function AppManager(){var grid=document.querySelector('gaia-grid');var self=this;navigator.mozApps.getSelf().onsuccess=function(evt){self.app=evt.target.result;window.dispatchEvent(new CustomEvent('appmanager-ready'));};grid.addEventListener('removeitem',this);}
AppManager.prototype={dialogVisible:false,get self(){return this.app;},handleItemRemoval:function(item){function errorLogger(err){console.error('Error while trying to remove',item.name,err);}
switch(item.detail.type){case'bookmark':BookmarksDatabase.remove(item.identifier).catch(errorLogger);break;default:console.error('Cannot handle remove for item type ',item.detail.type);}},handleEvent:function(e){var nameObj={name:e.detail&&e.detail.name};switch(e.type){case'removeitem':if(this.dialogVisible){return;}
this.dialogVisible=true;if(e.detail.detail.type=='app'){var request=navigator.mozApps.mgmt.uninstall(e.detail.app);request.onsuccess=()=>{e.detail.removeFromGrid();this.dialogVisible=false;};request.onerror=()=>{console.error('Error while trying to remove',e.detail.name,request.error);this.dialogVisible=false;};break;}
var dialog=new ConfirmDialogHelper({type:'remove',title:{id:'delete-title',args:nameObj},body:{id:'delete-body',args:nameObj},cancel:{title:'cancel',cb:()=>{this.dialogVisible=false;}},confirm:{title:'delete',type:'danger',cb:()=>{e.detail.removeFromGrid();this.handleItemRemoval(e.detail);this.dialogVisible=false;}}});dialog.show(document.body);break;}}};exports.appManager=new AppManager();}(window));

View file

@ -0,0 +1,245 @@
/* global IccHelper, verticalPreferences,
VersionHelper, LazyLoader */
/* exported configurator */
'use strict';
(function(exports) {
// We're going to use the mcc_mnc as a semaphore as well as to store its
// value during the singleVariant file's processing time.
var mcc_mnc;
// Globar configuration
var conf = {};
// Path of the single variant configuration file
var SINGLE_VARIANT_CONF_FILE = 'js/singlevariantconf.json';
// Keeps the list of single variant apps, indexed by manifestURL
var singleVariantApps = {};
var simPresentOnFirstBoot = true;
function loadSettingSIMPresent(currentMccMnc) {
var settings = navigator.mozSettings;
if (!settings) {
console.log('Settings is not available');
return;
}
var req = settings.createLock().get('ftu.simPresentOnFirstBoot');
req.onsuccess = function osv_success(e) {
var simOnFirstBoot = req.result['ftu.simPresentOnFirstBoot'];
simPresentOnFirstBoot = !simOnFirstBoot ||
req.result['ftu.simPresentOnFirstBoot'] === currentMccMnc;
};
req.onerror = function osv_error(e) {
console.error('Error retrieving ftu.simPresentOnFirstBoot. ' + e);
};
}
function loadSingleVariantConf() {
if (!IccHelper) {
console.error('IccHelper isn\'t enabled. SingleVariant configuration' +
' can\'t be loaded');
return;
}
// Given a number returns a three characters string padding with zeroes
// to the left until the desired length (3) is reached
function normalizeCode(aCode) {
var ncode = '' + aCode;
while (ncode.length < 3) {
ncode = '0' + ncode;
}
return ncode;
}
var getMccMnc = function getMccMnc() {
if (IccHelper.iccInfo) {
var mcc = IccHelper.iccInfo.mcc;
var mnc = IccHelper.iccInfo.mnc;
if ((mcc !== undefined) && (mcc !== null) &&
(mnc !== undefined) && (mnc !== null)) {
return normalizeCode(mcc) + '-' + normalizeCode(mnc);
}
}
};
function dispatchSVReadyEvent() {
mcc_mnc = undefined;
window.dispatchEvent(new CustomEvent('singlevariant-ready'));
}
function loadSVConfFileSuccess(loadedData) {
try {
loadSettingSIMPresent(mcc_mnc);
singleVariantApps = {};
if (loadedData && loadedData[mcc_mnc]) {
loadedData[mcc_mnc].forEach(function(app) {
if (app.manifestURL) {
singleVariantApps[app.manifestURL] = app;
} else if (app.id) {
singleVariantApps[app.id] = app;
}
});
} else {
console.log('There is not singleVariant configuration for ' +
mcc_mnc);
}
} catch (e) {
console.error('There was an error loading singleVariant configuration',
e);
} finally {
dispatchSVReadyEvent();
}
}
function loadSVConfFileError(e) {
singleVariantApps = {};
if (e.name === 'NS_ERROR_FILE_NOT_FOUND') {
console.log('No single variant configuration file found');
} else {
console.error('Failed parsing singleVariant configuration file [' +
SINGLE_VARIANT_CONF_FILE + ']: ', e);
}
dispatchSVReadyEvent();
}
var iccHandler = function(evt) {
mcc_mnc = getMccMnc();
if (mcc_mnc) {
IccHelper.removeEventListener('iccinfochange', iccHandler);
LazyLoader.getJSON(SINGLE_VARIANT_CONF_FILE).then(
loadSVConfFileSuccess, loadSVConfFileError
);
// No needed anymore
iccHandler = null;
return true;
}
return false;
};
if (!iccHandler()) { // Maybe we already have the mcc and mnc...
IccHelper.addEventListener('iccinfochange', iccHandler);
}
}
function onLoadInitJSON(loadedData) {
conf = loadedData;
setupColumns();
window.dispatchEvent(new CustomEvent('configuration-ready'));
loadSingleVariantConf();
}
/**
* Sets up the default columns.
*/
function setupColumns() {
var defaultCols = conf && conf.preferences &&
conf.preferences['grid.cols'] || undefined;
if (defaultCols) {
verticalPreferences.get('grid.cols').then(function(cols) {
// Set the number of cols by default in preference's datastore
!cols && verticalPreferences.put('grid.cols', defaultCols);
});
}
}
function onErrorInitJSON(e) {
conf = {};
console.error('Failed parsing homescreen configuration file:' + e);
window.dispatchEvent(new CustomEvent('configuration-ready'));
loadSingleVariantConf();
}
function handlerGridLayout(evt) {
switch(evt.type) {
case 'updated':
if (evt.target.name === 'grid.layout') {
verticalPreferences.removeEventListener('updated', handlerGridLayout);
onLoadInitJSON(evt.target.value);
}
break;
}
}
function load() {
conf = {};
VersionHelper.getVersionInfo().then(function(verInfo) {
if (verInfo.isUpgrade()) {
verticalPreferences.get('grid.layout').then(function(grid) {
if (!grid) {
verticalPreferences.addEventListener('updated', handlerGridLayout);
} else {
onLoadInitJSON(grid);
}
});
} else {
LazyLoader.getJSON('js/init.json').then(
onLoadInitJSON, onErrorInitJSON
);
}
}, function(err) {
console.error('VersionHelper failed to lookup version settings, ' +
'asumming no version upgrade.\n');
});
}
function Configurator() {
load();
}
Configurator.prototype = {
getSection: function(section) {
return conf[section];
},
getGrid: function() {
return conf.grid;
},
getItems: function(role) {
var items = {};
conf.grid.forEach(function forEachSection(section) {
section.forEach(function forEachItem(item) {
if (!item) {
return;
}
if (item.role === role) {
items[item.id] = item;
}
});
});
return items;
},
getSingleVariantApp: function(manifestURL) {
if (manifestURL in singleVariantApps) {
var svApp = singleVariantApps[manifestURL];
if (svApp.location !== undefined) {
return svApp;
}
}
},
get isSingleVariantReady() {
return !mcc_mnc;
},
load: load,
get isSimPresentOnFirstBoot() {
return simPresentOnFirstBoot;
},
loadSettingSIMPresent: loadSettingSIMPresent
};
exports.Configurator = Configurator;
}(window));

View file

@ -0,0 +1,49 @@
'use strict';
/* global LazyLoader, contextMenuUI */
(function(exports) {
function ContextMenuHandler() {
this.container = document.getElementById('icons').parentNode;
this.container.addEventListener('contextmenu', this);
this.container.addEventListener('touchstart', this);
window.addEventListener('hashchange', this);
}
ContextMenuHandler.prototype = {
handleEvent: function(e) {
switch(e.type) {
case 'touchstart':
this.canceled = e.touches.length > 1;
break;
case 'contextmenu':
if (this.canceled || app.grid._grid.dragdrop.inEditMode) {
return;
}
// Prevent the click when the finger is released
e.preventDefault();
var resources = ['/shared/js/component_utils.js',
'/shared/elements/gaia_buttons/script.js',
'/shared/elements/gaia_menu/script.js',
'js/contextmenu_ui.js'];
LazyLoader.load(resources, function loaded() {
// pass the event through for processing
setTimeout(() => { contextMenuUI.show(e); });
});
break;
case 'hashchange':
window.contextMenuUI && contextMenuUI.hide();
break;
}
}
};
exports.contextMenuHandler = new ContextMenuHandler();
}(window));

View file

@ -0,0 +1,93 @@
'use strict';
/* global LazyLoader */
/* global MozActivity */
/* global wallpaper */
/* jshint nonew: false */
(function(exports) {
function ContextMenuUI() {
this.grid = document.getElementById('icons');
this.dialog = document.getElementById('contextmenu-dialog');
this.wallpaperOption = document.getElementById('change-wallpaper-action');
this.settingsOption = document.getElementById('homescreen-settings-action');
this.handleCancel = this._handleCancel.bind(this);
}
ContextMenuUI.prototype = {
show: function(e) {
var nearestIndex = this.grid._grid.getNearestItemIndex(
e.pageX,
e.pageY - this.grid.offsetTop
);
window.dispatchEvent(new CustomEvent('context-menu-open', {
detail: {
nearestIndex: nearestIndex
}
}));
this.dialog.addEventListener('gaiamenu-cancel', this.handleCancel);
this.dialog.removeAttribute('hidden');
this.wallpaperOption.addEventListener('click', this);
this.settingsOption.addEventListener('click', this);
window.addEventListener('visibilitychange', this);
},
hide: function() {
this.dialog.removeEventListener('gaiamenu-cancel', this.handleCancel);
this.dialog.setAttribute('hidden', '');
this.wallpaperOption.removeEventListener('click', this);
this.settingsOption.removeEventListener('click', this);
window.removeEventListener('visibilitychange', this);
window.dispatchEvent(new CustomEvent('context-menu-close'));
},
_handleCancel: function(e) {
this.hide();
},
_actions: {
'change-wallpaper-action': function() {
LazyLoader.load([
'shared/js/omadrm/fl.js',
'js/wallpaper.js'
], function() {
this.hide();
wallpaper.change();
}.bind(this));
},
'homescreen-settings-action': function() {
this.hide();
new MozActivity({
name: 'configure',
data: {
target: 'device',
section: 'homescreens-list'
}
});
}
},
handleEvent: function(e) {
switch (e.type) {
case 'click':
this._actions[e.target.id].call(this);
break;
case 'visibilitychange':
if (document.hidden) {
this.hide();
}
break;
}
}
};
exports.contextMenuUI = new ContextMenuUI();
}(window));

View file

@ -0,0 +1,95 @@
'use strict';
/* global LazyLoader */
(function(exports) {
var resources = ['shared/style/input_areas.css', 'style/css/edit_group.css'];
function GroupEditor() {
this.container = document.getElementById('edit-group');
this.header = document.getElementById('edit-group-header');
this.save = document.getElementById('edit-group-save');
this.form = this.container.querySelector('form');
this.clear = document.getElementById('edit-group-title-clear');
this.nameField = document.getElementById('edit-group-title');
}
GroupEditor.prototype = {
handleEvent: function(e) {
switch(e.type) {
case 'click':
case 'submit':
this.group.name = this.nameField.value;
this.close();
break;
case 'action':
case 'hashchange':
this.nameField.blur();
this.close();
break;
case 'touchstart':
e.preventDefault();
this.nameField.value = '';
this.checkSaveAction();
break;
case 'input':
this.checkSaveAction();
break;
}
},
edit: function(group) {
LazyLoader.load(resources, () => {
this.group = group;
this.attachHandlers();
this.nameField.value = group.name || '';
this.checkSaveAction();
document.body.classList.add('edit-group');
this.container.hidden = false;
setTimeout(() => {
this.nameField.focus();
});
});
},
close: function() {
this.removeHandlers();
this.container.hidden = true;
document.body.classList.remove('edit-group');
},
checkSaveAction: function() {
var name = this.nameField.value.trim();
this.save.disabled = name === this.group.name;
},
attachHandlers: function() {
this.header.addEventListener('action', this);
this.save.addEventListener('click', this);
this.form.addEventListener('input', this);
this.form.addEventListener('submit', this);
this.clear.addEventListener('touchstart', this);
window.addEventListener('hashchange', this);
},
removeHandlers: function() {
this.header.removeEventListener('action', this);
this.save.removeEventListener('click', this);
this.form.removeEventListener('input', this);
this.form.removeEventListener('submit', this);
this.clear.removeEventListener('touchstart', this);
window.removeEventListener('hashchange', this);
},
get hidden() {
return this.container.hidden;
}
};
exports.groupEditor = new GroupEditor();
})(window);

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,4 @@
;(function(exports){'use strict';function Search(){this._port=null;this.connected=false;this.pendingRender=false;if(!appManager.app){window.addEventListener('appmanager-ready',function onReady(){window.removeEventListener('appmanager-ready',onReady);this.onAppReady();}.bind(this));}else{this.onAppReady();}
var input=document.getElementById('search');input.addEventListener('click',this.open.bind(this));input.addEventListener('contextmenu',(e)=>{e.stopPropagation();});}
Search.prototype={onAppReady:function onAppReady(){appManager.app.connect('search-results').then(function onConnectionAccepted(ports){ports.forEach(function(port){this._port=port;}.bind(this));this.connected=true;if(this.pendingRender){this.open();}}.bind(this),function onConnectionRejected(){});},open:function openRocketbar(e){window.scrollTo(0,0);e.stopPropagation();e.preventDefault();if(!this.connected){this.pendingRender=true;return;}
this._port.postMessage({action:'render'});}};exports.search=new Search();})(window);

View file

@ -0,0 +1,17 @@
;'use strict';(function(exports){var appMgr=navigator.mozApps.mgmt;var apps=null;window.performance.mark('homescreenStart@system.gaiamobile.org');appMgr.getAll().onsuccess=function onsuccess(event){apps=event.target.result;window.dispatchEvent(new CustomEvent('navigator-mozapps-ready'));};function ApplicationSource(store){this.store=store;this.entries=[];this.entriesByManifestUrl={};this.svPreviouslyInstalledApps=[];var pendingInstallRequests=[];function addSVEventListener(){window.addEventListener('singlevariant-ready',function svFileReady(ev){window.removeEventListener('singlevariant-ready',svFileReady);for(var i=0;i<pendingInstallRequests;i++){pendingInstallRequests[i]();}});}
addSVEventListener();var self=this;function addIcons(){window.removeEventListener('navigator-mozapps-ready',addIcons);for(var i=0,iLen=apps.length;i<iLen;i++){self.makeIcons(apps[i]);}
apps=null;}
apps?addIcons():window.addEventListener('navigator-mozapps-ready',addIcons);function install(application){var manifest=application.manifest||application.updateManifest;if(manifest.role&&app.HIDDEN_ROLES.indexOf(manifest.role)!==-1){return;}
this.addIconToGrid(application);var svApp=configurator.getSingleVariantApp(application.manifestURL);var lastElem=app.grid.getIndexLastIcon();if(configurator.isSimPresentOnFirstBoot&&svApp&&svApp.location<lastElem&&!this.isPreviouslyInstalled(application.manifestURL)){app.grid.popDivider();app.grid.removeNonVisualElements();lastElem=app.grid.getIndexLastIcon();app.grid.moveTo(lastElem,svApp.location);_moveAhead(svApp.location+1);this.addPreviouslyInstalledSvApp(application.manifestURL);app.itemStore.savePrevInstalledSvApp(this.svPreviouslyInstalledApps);}
app.grid.render();app.itemStore.deferredSave(app.grid.getItems());}
function _moveAhead(startPos){var elems=app.grid.getItems();for(var i=startPos,iLen=elems.length;i<iLen;i++){var item=elems[i];if(item instanceof GaiaGrid.Mozapp){var svApp=configurator.getSingleVariantApp(elems[i].identifier);if(svApp&&i>svApp.location){app.grid.moveTo(i,i-1);}}}}
appMgr.oninstall=function oninstall(event){if(configurator.isSingleVariantReady){install.bind(this)(event.application);}else{pendingInstallRequests.push(install.bind(this,event.application));}}.bind(this);appMgr.onuninstall=function onuninstall(event){var application=event.application;var manifest=application.updateManifest||application.manifest;this.removeIconFromGrid(application.manifestURL);app.itemStore.deferredSave(app.grid.getItems());if(app.HIDDEN_ROLES.indexOf(manifest.role)!==-1){return;}}.bind(this);}
ApplicationSource.prototype={synchronize:function(){var storeItems=this.store._allItems;var toAdd=[];var appIconsByManifestUrl={};for(var i=0,iLen=storeItems.length;i<iLen;i++){var item=storeItems[i];if(!(item instanceof GaiaGrid.Mozapp)){continue;}
appIconsByManifestUrl[item.detail.manifestURL]=item;}
for(i=0,iLen=this.entries.length;i<iLen;i++){var entry=this.entries[i];var manifest=entry.app.updateManifest||entry.app.manifest;if(!appIconsByManifestUrl[entry.detail.manifestURL]&&!manifest.entry_points){toAdd.push(entry);}else{delete appIconsByManifestUrl[entry.detail.manifestURL];}}
for(i in appIconsByManifestUrl){this.removeIconFromGrid(i);}
toAdd.forEach(function _toAdd(newApp){this.addIconToGrid(newApp.app);},this);app.itemStore.deferredSave(app.grid.getItems());},addIconToGrid:function(application){this.makeIcons(application);var appObject=this.mapToApp({manifestURL:application.manifestURL});app.grid.appendItemToExpandedGroup(appObject);app.grid.render();},removeIconFromGrid:function(manifestURL){var icons=app.grid.getIcons();var appObject=icons[manifestURL];if(appObject){appObject.removeFromGrid();}},populate:function(success){success(this.entries);},makeIcons:function(eachApp){var manifest=eachApp.manifest||eachApp.updateManifest;if(app.HIDDEN_ROLES.indexOf(manifest.role)!==-1){return;}
function eachIcon(icon){if(!icon.icon){return;}
icon.setPosition(this.store.getNextPosition());this.entries.push(icon);}
this.entriesByManifestUrl[eachApp.manifestURL]=eachApp;if(manifest.entry_points){for(var i in manifest.entry_points){eachIcon.call(this,new GaiaGrid.Mozapp(eachApp,i));}}else{eachIcon.call(this,new GaiaGrid.Mozapp(eachApp));}},mapToApp:function(entry){var app=this.entriesByManifestUrl[entry.manifestURL];app=app||{manifestURL:entry.manifestURL,manifest:{name:'',icons:[]}};return new GaiaGrid.Mozapp(app,entry.entryPoint,{decoratedIconBlob:entry.decoratedIconBlob});},addPreviouslyInstalledSvApp:function(manifest){this.svPreviouslyInstalledApps.push({manifestURL:manifest});},isPreviouslyInstalled:function(manifest){for(var i=0,elemNum=this.svPreviouslyInstalledApps.length;i<elemNum;i++){if(this.svPreviouslyInstalledApps[i].manifestURL===manifest){return true;}}
return false;}};exports.ApplicationSource=ApplicationSource;}(window));

View file

@ -0,0 +1,8 @@
;'use strict';(function(exports){var eventTypesToListenFor=['added','updated','removed'];function BookmarkSource(store){this.store=store;this.entries=[];eventTypesToListenFor.forEach(function iterateTypes(type){BookmarksDatabase.addEventListener(type,this);},this);}
BookmarkSource.prototype={synchronize:function(){var allAppBookmarks={};var toAdd=[];var icons=app.grid.getIcons();for(var i in icons){var icon=icons[i];if(icon.detail.type!=='bookmark'){continue;}
allAppBookmarks[icon.detail.url]=icon;}
for(var j=0,jLen=this.entries.length;j<jLen;j++){var entry=this.entries[j];if(!allAppBookmarks[entry.detail.url]){toAdd.push(entry);}else{delete allAppBookmarks[entry.detail.url];}}
for(i in allAppBookmarks){this.removeIconFromGrid(allAppBookmarks[i].detail.url);}
for(i=0;i<toAdd.length;i++){this.addIconToGrid(toAdd[i].detail);}
app.itemStore.deferredSave(app.grid.getItems());},populate:function(success){var self=this;BookmarksDatabase.getAll().then(function(systemBookmarks){Object.keys(systemBookmarks).forEach(function(id){self.entries.push(new GaiaGrid.Bookmark(systemBookmarks[id]));});success(self.entries);},success);},handleEvent:function(e){switch(e.type){case'added':case'updated':this.addIconToGrid(e.target);app.itemStore.deferredSave(app.grid.getItems());break;case'removed':var id=e.target.id;this.removeIconFromGrid(id);break;}},addIconToGrid:function(detail){var icons=app.grid.getIcons();var existing=icons[detail.id];if(existing){existing.update(detail);app.grid.render();return;}
var bookmark=new GaiaGrid.Bookmark(detail);bookmark.setPosition(this.store.getNextPosition());this.entries.push(bookmark);app.grid.appendItemToExpandedGroup(bookmark);app.grid.render();},removeIconFromGrid:function(url){var icons=app.grid.getIcons();var appObject=icons[url];if(appObject){appObject.removeFromGrid();}}};exports.BookmarkSource=BookmarkSource;}(window));

View file

@ -0,0 +1,4 @@
;'use strict';(function(exports){const APPEARANCE={OPAQUE:'opaque',SEMI_TRANSPARENT:'semi-transparent'};function StatusBar(){this.threshold=document.getElementById('search').clientHeight;if(!appManager.app){window.addEventListener('appmanager-ready',function onReady(){window.removeEventListener('appmanager-ready',onReady);this.onAppReady();}.bind(this));}else{this.onAppReady();}}
StatusBar.prototype={handleEvent:function(e){switch(e.type){case'editmode-start':window.removeEventListener('context-menu-open',this);window.removeEventListener('context-menu-close',this);window.removeEventListener('gaia-confirm-open',this);window.removeEventListener('gaia-confirm-close',this);case'context-menu-open':case'gaia-confirm-open':window.removeEventListener('scroll',this);this.setAppearance(APPEARANCE.OPAQUE);break;case'editmode-end':window.addEventListener('context-menu-open',this);window.addEventListener('context-menu-close',this);window.addEventListener('gaia-confirm-open',this);window.addEventListener('gaia-confirm-close',this);case'context-menu-close':case'gaia-confirm-close':window.addEventListener('scroll',this);case'scroll':this.setAppearance(this.calculateAppearance());break;case'visibilitychange':if(document.hidden){break;}
this.appearance=null;this.setAppearance(this.calculateAppearance());break;}},onAppReady:function(){var grid=app.grid;window.addEventListener('scroll',this);grid.addEventListener('editmode-start',this);grid.addEventListener('editmode-end',this);window.addEventListener('context-menu-close',this);window.addEventListener('context-menu-open',this);window.addEventListener('gaia-confirm-open',this);window.addEventListener('gaia-confirm-close',this);window.addEventListener('visibilitychange',this);this.setAppearance(APPEARANCE.SEMI_TRANSPARENT);},calculateAppearance:function(){return window.scrollY>this.threshold?APPEARANCE.OPAQUE:APPEARANCE.SEMI_TRANSPARENT;},setAppearance:function(value){if(this.appearance===value){return;}
this.appearance=value;var meta=document.head.querySelector('meta[name="theme-color"]');if(value==APPEARANCE.OPAQUE){meta.content='black';}else{meta.content='transparent';}}};exports.statusBar=new StatusBar();}(window));

View file

@ -0,0 +1,35 @@
;'use strict';(function(exports){const DB_VERSION=1;const DB_NAME='verticalhome';const DB_ITEM_STORE='items';const DB_SV_APP_STORE_NAME='svAppsInstalled';const DATASTORE_NAME='verticalhome_items_migration';const PREFS_STORE='vertical_preferences_store';var db;var datastore;function sort(entries,order){if(!order||!order.length){return entries;}
var newEntries=[];function isEqual(lookFor,compareWith){if(!compareWith.detail||!lookFor){return false;}
if(compareWith instanceof GaiaGrid.Mozapp){if(!lookFor.manifestURL||!compareWith.detail.manifestURL){return false;}
if(compareWith.detail.entryPoint){return lookFor.manifestURL===compareWith.detail.manifestURL&&lookFor.entry_point===compareWith.detail.entryPoint;}else{return lookFor.manifestURL===compareWith.detail.manifestURL;}}else if(compareWith instanceof GaiaGrid.Bookmark){if(!lookFor.id||!compareWith.detail.id){return false;}
return lookFor.id===compareWith.detail.id;}}
for(var i=0,iLen=order.length;i<iLen;i++){for(var j=0,jLen=order[i].length;j<jLen;j++){var ind=entries.findIndex(isEqual.bind(null,order[i][j]));if(ind>=0){newEntries.push(entries.splice(ind,1)[0]);}}
if(i<iLen-1){newEntries.push(new GaiaGrid.Divider());}}
if(entries.length>0){if(configurator.isSimPresentOnFirstBoot){sortUnclassifiedApps(newEntries,entries);}else{newEntries.push(new GaiaGrid.Divider());newEntries=newEntries.concat(entries);}}
for(i=0,iLen=newEntries.length;i<iLen;i++){if(newEntries[i].detail){newEntries[i].detail.index=i;}}
return newEntries;}
function sortUnclassifiedApps(dstEntries,orgEntries){function compareApps(appA,appB){var svAppA=null;var svAppB=null;if(appA){svAppA=configurator.getSingleVariantApp(appA.detail.manifestURL);}
if(appB){svAppB=configurator.getSingleVariantApp(appB.detail.manifestURL);}
var locA=svAppA&&svAppA.location!==undefined&&svAppA.location||Number.MAX_VALUE;var locB=svAppB&&svAppB.location!==undefined&&svAppB.location||Number.MAX_VALUE;var relPos=locA-locB;return relPos?(relPos>0?1:-1):0;}
orgEntries.sort(compareApps);if(!configurator.getSingleVariantApp(orgEntries[0].detail.manifestURL)){dstEntries.push(new GaiaGrid.Divider());dstEntries=dstEntries.concat(orgEntries);}else{var sepAdded=false;for(var i=0,iLen=orgEntries.length;i<iLen;i++){var app=orgEntries[i];var svApp=configurator.getSingleVariantApp(app.detail.manifestURL);if(!svApp){if(!sepAdded){dstEntries.push(new GaiaGrid.Divider());sepAdded=true;}
dstEntries.push(app);}else{if(svApp.location!==undefined){dstEntries.splice(svApp.location,0,app);}else{dstEntries.push(app);}}}}}
function loadTable(table,indexName,iterator,aNext){newTxn(table,'readonly',function(txn,store){var index=store.index(indexName);index.openCursor().onsuccess=function onsuccess(event){var cursor=event.target.result;if(!cursor){return;}
iterator(cursor.value);cursor.continue();};},aNext);}
function newTxn(storeName,txnType,withTxnAndStore,successCb){var txn=db.transaction([storeName],txnType);var store=txn.objectStore(storeName);txn.oncomplete=function(event){if(successCb){successCb(event);}};txn.onerror=function(event){console.warn('Error during transaction.');};withTxnAndStore(txn,store);}
function ItemStore(onsuccess){var self=this;this.applicationSource=new ApplicationSource(this);this.bookmarkSource=new BookmarkSource(this);this.sources=[this.applicationSource,this.bookmarkSource];this.ready=false;var isEmpty=false;self.gridOrder=null;var request=window.indexedDB.open(DB_NAME,DB_VERSION);request.onupgradeneeded=function _onupgradeneeded(event){var db=event.target.result;var oldVersion=event.oldVersion||0;switch(oldVersion){case 0:var objectStore=db.createObjectStore(DB_ITEM_STORE,{keyPath:'index'});objectStore.createIndex('index','index',{unique:true});isEmpty=true;var objectSV=db.createObjectStore(DB_SV_APP_STORE_NAME,{keyPath:'manifestURL'});objectSV.createIndex('indexSV','indexSV',{unique:true});}};request.onsuccess=function _onsuccess(){onsuccess&&onsuccess(isEmpty);db=request.result;var cb=self.fetch.bind(self,self.synchronize.bind(self));if(isEmpty){window.addEventListener('configuration-ready',function onReady(){window.removeEventListener('configuration-ready',onReady);self.gridOrder=configurator.getGrid();self.populate(cb);});}else{self.initSources(cb);}
navigator.mozSetMessageHandler('connection',self.handleIAC.bind(self));};window.addEventListener('gaiagrid-cached-icons-rendered',this);}
ItemStore.prototype={_renderedOnce:false,_deferredSaveArgs:[],_allItems:[],nextPosition:0,all:function(success){if(!this.ready){window.addEventListener('databaseready',this.all.bind(this,success));return;}
success(this._allItems);},saveTable:function(table,objArr,column,checkPersist,aNext){newTxn(table,'readwrite',function(txn,store){store.clear();for(var i=0,iLen=objArr.length;i<iLen;i++){if(!checkPersist||(checkPersist&&objArr[i].persistToDB)){store.put(column?objArr[i][column]:objArr[i]);}}
if(typeof aNext==='function'){aNext();}});},saveMigrationData:function(objArr,column,checkPersist){return datastore.clear().then(()=>{var chain=[];objArr.forEach((object)=>{if(!checkPersist||object.persistToDB){var data=column?object[column]:object;chain.push(datastore.put(data,data.index+1));}});return Promise.all(chain);});},saveItem:function(object,callback){if(object.index==null){console.error('Attempting to save object without `index`');return;}
newTxn(DB_ITEM_STORE,'readwrite',function(txn,store){store.put(object);},callback);},deferredSave:function(){var args=Array.slice(arguments);if(this._renderedOnce){return this.save.apply(this,args);}
this._deferredSaveArgs=args;},save:function(entries,aNext){entries=sort(entries,this.gridOrder);this.gridOrder=null;this.saveTable(DB_ITEM_STORE,entries,'detail',true,aNext);},savePrevInstalledSvApp:function(svApps,aNext){this.saveTable(DB_SV_APP_STORE_NAME,svApps,null,false,aNext);},fetch:function(callback){var cached={};var collected=[];function iterator(value){collected.push(value);}
function iteratorSV(value){this.applicationSource.addPreviouslyInstalledSvApp(value.manifestURL);}
loadTable(DB_SV_APP_STORE_NAME,'indexSV',iteratorSV.bind(this));loadTable(DB_ITEM_STORE,'index',iterator,finish.bind(this));function addIfUnique(item){if(!cached[item.identifier]){cached[item.identifier]=true;this._allItems.push(item);}}
function finish(){for(var i=0,iLen=collected.length;i<iLen;i++){var thisItem=collected[i];if(thisItem.type==='app'){var itemObj=this.applicationSource.mapToApp(thisItem);addIfUnique.call(this,itemObj);}else if(thisItem.type==='divider'){var divider=new GaiaGrid.Divider(thisItem);this._allItems.push(divider);}else if(thisItem.type==='bookmark'){var bookmark=new GaiaGrid.Bookmark(thisItem);addIfUnique.call(this,bookmark);}}
this.notifyReady();if(callback&&typeof callback==='function'){callback();}}},synchronize:function(){this.sources.forEach(function eachSource(source){source.synchronize();});},initSources:function(callback){var pending=this.sources.length;var allEntries=[];var self=this;var current=0;function handleSource(){var source=self.sources[current];current++;source.populate(next);}
handleSource();function next(entries){allEntries=allEntries.concat(entries);if(!(--pending)){callback(allEntries);}else{handleSource();}}},populate:function(callback){this.initSources(function(entries){this.deferredSave(entries,callback);}.bind(this));},notifyReady:function(){this.ready=true;dispatchEvent(new CustomEvent('databaseready'));},getNextPosition:function(){var nextPosition=this.nextPosition;this.nextPosition++;return nextPosition;},handleIAC:function(connectionRequest){if(connectionRequest.keyword!=='verticalhome-migrate'){return;}
var port=connectionRequest.port;port.onmessage=(event)=>{if(event.data.action!=='migrate'){console.error('Unhandled migration action requested:',event.data.action);return;}
this.migrate(event.data.manifestURL);};port.start();},migrate:function(manifestURL){this.migratingTo=manifestURL;console.info('verticalhome migrating to '+this.migratingTo);if(this.migrating){return;}
this.migrating=true;(datastore?Promise.resolve():navigator.getDataStores(DATASTORE_NAME).then(stores=>{datastore=stores[0];return Promise.resolve();},(e)=>{return Promise.reject(e);})).then(()=>{this.all(entries=>{this.saveMigrationData(entries,'detail',true).then(()=>{this.migrating=false;window.navigator.mozSettings.createLock().set({'homescreen.manifestURL':this.migratingTo});navigator.getDataStores(PREFS_STORE).then(stores=>{if(stores.length<1){console.error('Error opening verticalhome prefs datastore');return;}
stores[0].put('migrated',true).then(()=>{window.close();},e=>{console.error('Error storing migration pref',e);window.close();});});});});},e=>{console.error('Error retrieving datastore',e);});},handleEvent:function(e){switch(e.type){case'gaiagrid-cached-icons-rendered':this._renderedOnce=true;window.removeEventListener('gaiagrid-cached-icons-rendered',this);if(this._deferredSaveArgs.length){this.save.apply(this,this._deferredSaveArgs);}
break;}}};exports.ItemStore=ItemStore;}(window));

View file

@ -0,0 +1,59 @@
'use strict';
/* global ForwardLock, MozActivity */
(function(exports) {
function Wallpaper() {
// Do nothing...
}
Wallpaper.prototype = {
change: function() {
// Ask for the locked content key first, because if it does not exist
// we know there is no locked content on the phone and we don't have
// to show the Locked Content app in the activity request.
ForwardLock.getKey(function(secret) {
var activity = new MozActivity({
name: 'pick',
data: {
type: ['wallpaper', 'image/*'],
includeLocked: (secret !== null),
// XXX: This will not work with Desktop Fx / Simulator.
width: Math.ceil(window.screen.width * window.devicePixelRatio),
height: Math.ceil(window.screen.height * window.devicePixelRatio)
}
});
activity.onsuccess = function onWallpaperSuccess() {
var blob = activity.result.blob;
if (!blob) {
return;
}
// If this is a locked image from the locked content app, unlock it
if (blob.type.split('/')[1] === ForwardLock.mimeSubtype) {
ForwardLock.unlockBlob(secret, blob, function(unlocked) {
setWallpaper(unlocked);
});
} else {
setWallpaper(blob);
}
function setWallpaper(blob) {
navigator.mozSettings.createLock().set({
'wallpaper.image': blob
});
}
};
activity.onerror = function onWallpaperError() {
console.warn('pick failed!');
};
});
}
};
exports.wallpaper = new Wallpaper();
}(window));

View file

@ -0,0 +1,18 @@
{
"name": "verticalhome",
"tags": {
"dictionaries": ["jsdoc"]
},
"source": {
"include": ["apps/verticalhome/js/**/*.js"]
},
"plugins": [
"plugins/markdown",
"plugins/summarize"
],
"opts": {
"private": true,
"recurse": true,
"destination": "docs/verticalhome"
}
}

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"ابحث أو أدخل عنوانا"},{"$i":"delete-title","$v":["حذف ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":["سيتم حذف ",{"t":"idOrVar","v":"name"}," وجميع المعلومات الخاصة به."]},{"$i":"delete","$v":"حذف"},{"$i":"cancel","$v":"ألغِ"},{"$i":"homescreen-settings","$v":"إعدادات الشاشة الرئيسية"},{"$i":"change-wallpaper","$v":"تغيير صورة الخلفية"},{"$i":"edit-mode","$v":"حرّر"},{"$i":"edit-done","$v":"تم"},{"$i":"stop-download-title","$v":["توقف ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"هل تريد إيقاف التحميل؟"},{"$i":"stop-download-action","$v":"أوقف"},{"$i":"resume-download-title","$v":"إعادة تشغيل التنزيل"},{"$i":"resume-download-body","$v":["هل تريد تنزيل ",{"t":"idOrVar","v":"name"},"؟"]},{"$i":"resume-download-action","$v":"تنزيل"},{"$i":"edit-group-header","$v":"عدّل المجموعة"},{"$i":"gaia-grid-stop-download-title","$v":["إيقاف ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"هل تريد إيقاف التنزيل الجاري؟"},{"$i":"gaia-grid-stop-download-action","$v":"أوقِف"},{"$i":"gaia-grid-resume-download-title","$v":"أعِد التنزيل"},{"$i":"gaia-grid-resume-download-body","$v":["هل تريد تنزيل ",{"t":"idOrVar","v":"name"},"؟"]},{"$i":"gaia-grid-resume-download-action","$v":"نزِّل"},{"$i":"gaia-grid-cancel","$v":"ألغِ"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"وسّع المجموعة"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"اطو المجموعة"},{"$i":"gaia-grid-enter-group-name","$v":"أدخل اسما للمجموعة"},{"$i":"gaia-menu-cancel","$v":"ألغِ"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Търсете или въведете адрес"},{"$i":"delete-title","$v":["Изтриване на ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," и всички прилежащи данни ще бъдат изтрити."]},{"$i":"delete","$v":"Изтриване"},{"$i":"cancel","$v":"Отказ"},{"$i":"homescreen-settings","$v":"Настройки на началния екран"},{"$i":"change-wallpaper","$v":"Смяна на тапет"},{"$i":"edit-mode","$v":"Редактиране"},{"$i":"edit-done","$v":"Готово"},{"$i":"stop-download-title","$v":["Спиране на ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Желаете ли да спрете текущото изтегляне?"},{"$i":"stop-download-action","$v":"Спиране"},{"$i":"resume-download-title","$v":"Рестартиране на изтеглянето"},{"$i":"resume-download-body","$v":["Желаете ли да изтеглите ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Изтегляне"},{"$i":"edit-group-header","$v":"Редактиране на група"},{"$i":"gaia-grid-stop-download-title","$v":["Спиране на ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Желаете ли да спрете текущото изтегляне?"},{"$i":"gaia-grid-stop-download-action","$v":"Спиране"},{"$i":"gaia-grid-resume-download-title","$v":"Рестартиране на изтеглянето"},{"$i":"gaia-grid-resume-download-body","$v":["Желаете ли да изтеглите ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Изтегляне"},{"$i":"gaia-grid-cancel","$v":"Отказ"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Показване на групата"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Скриване на групата"},{"$i":"gaia-grid-enter-group-name","$v":"Въведете име на група"},{"$i":"gaia-menu-cancel","$v":"Отказ"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"অনুসন্ধান বা ঠিকানা দিন"},{"$i":"delete-title","$v":[{"t":"idOrVar","v":"name"}," অপসারণ"]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," ও এর সব তথ্য অপসারিত হবে।"]},{"$i":"delete","$v":"অপসারণ"},{"$i":"cancel","$v":"বাতিল"},{"$i":"homescreen-settings","$v":"হোমস্ক্রিন সেটিং"},{"$i":"change-wallpaper","$v":"ওয়ালপেপার পরিবর্তন"},{"$i":"edit-mode","$v":"সম্পাদনা"},{"$i":"edit-done","$v":"সম্পন্ন"},{"$i":"stop-download-title","$v":[{"t":"idOrVar","v":"name"}," থামান"]},{"$i":"stop-download-body","$v":"চলতে থাকা ডাউনলোডটি কে কি থামাতে চান?"},{"$i":"stop-download-action","$v":"থামুন"},{"$i":"resume-download-title","$v":"পুনরায় ডাউনলোড শুরু করুন"},{"$i":"resume-download-body","$v":["আপনি কি ",{"t":"idOrVar","v":"name"}," ডাউনলোড করবেন?"]},{"$i":"resume-download-action","$v":"ডাউনলোড"},{"$i":"edit-group-header","$v":"গ্রুপ সম্পাদনা করুন"},{"$i":"gaia-grid-stop-download-title","$v":[{"t":"idOrVar","v":"name"}," বন্ধ করুন"]},{"$i":"gaia-grid-stop-download-body","$v":"আপনি কি আপনার ডাউনলোড থামাতে চান?"},{"$i":"gaia-grid-stop-download-action","$v":"থামুন"},{"$i":"gaia-grid-resume-download-title","$v":"নতুন করে ডাউনলোড করুন"},{"$i":"gaia-grid-resume-download-body","$v":["আপনি কি ",{"t":"idOrVar","v":"name"}," ডাউনলোড করতে চান?"]},{"$i":"gaia-grid-resume-download-action","$v":"ডাউনলোড"},{"$i":"gaia-grid-cancel","$v":"বাতিল করুন"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"দল বর্ধিত করুন"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"দল বন্ধ করুন"},{"$i":"gaia-grid-enter-group-name","$v":"একটি গ্রুপের নাম প্রবেশ করান"},{"$i":"gaia-menu-cancel","$v":"বাতিল"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Escriviu una cerca o adreça"},{"$i":"delete-title","$v":["Elimina ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":["S'eliminarà «",{"t":"idOrVar","v":"name"},"» i totes les seves dades."]},{"$i":"delete","$v":"Elimina"},{"$i":"cancel","$v":"Cancel·la"},{"$i":"homescreen-settings","$v":"Paràmetres de la pantalla d'inici"},{"$i":"change-wallpaper","$v":"Canvia el fons de pantalla"},{"$i":"edit-mode","$v":"Edita"},{"$i":"edit-done","$v":"Fet"},{"$i":"stop-download-title","$v":["Atura ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Voleu aturar la baixada en curs?"},{"$i":"stop-download-action","$v":"Atura"},{"$i":"resume-download-title","$v":"Reinicia la baixada"},{"$i":"resume-download-body","$v":["Voleu baixar ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Baixa"},{"$i":"edit-group-header","$v":"Edita el grup"},{"$i":"gaia-grid-stop-download-title","$v":["Atura ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Voleu aturar la baixada en curs?"},{"$i":"gaia-grid-stop-download-action","$v":"Atura"},{"$i":"gaia-grid-resume-download-title","$v":"Reinicia la baixada"},{"$i":"gaia-grid-resume-download-body","$v":["Voleu baixar ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Baixa"},{"$i":"gaia-grid-cancel","$v":"Cancel·la"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Expandeix el grup"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Redueix el grup"},{"$i":"gaia-grid-enter-group-name","$v":"Escriviu un nom del grup"},{"$i":"gaia-menu-cancel","$v":"Cancel·la"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Zadejte hledání nebo adresu"},{"$i":"delete-title","$v":["Smazání ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":["Aplikace ",{"t":"idOrVar","v":"name"}," a všechna související data budou smazána."]},{"$i":"delete","$v":"Smazat"},{"$i":"cancel","$v":"Zrušit"},{"$i":"homescreen-settings","$v":"Nastavení domovské obrazovky"},{"$i":"change-wallpaper","$v":"Změna tapety"},{"$i":"edit-mode","$v":"Úprava"},{"$i":"edit-done","$v":"Hotovo"},{"$i":"stop-download-title","$v":["Ukončení ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Chcete ukončit probíhající stahování?"},{"$i":"stop-download-action","$v":"Ukončit"},{"$i":"resume-download-title","$v":"Obnovení stahování"},{"$i":"resume-download-body","$v":["Chcete stáhnout ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Stáhnout"},{"$i":"edit-group-header","$v":"Upravit skupinu"},{"$i":"gaia-grid-stop-download-title","$v":["Ukončení ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Chcete ukončit probíhající stahování?"},{"$i":"gaia-grid-stop-download-action","$v":"Ukončit"},{"$i":"gaia-grid-resume-download-title","$v":"Obnovení stahování"},{"$i":"gaia-grid-resume-download-body","$v":["Chcete stáhnout aplikaci ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Stáhnout"},{"$i":"gaia-grid-cancel","$v":"Zrušit"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Rozbalit skupinu"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Sbalit skupinu"},{"$i":"gaia-grid-enter-group-name","$v":"Zadejte jméno skupiny"},{"$i":"gaia-menu-cancel","$v":"Zrušit"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Søg eller indtast adresse"},{"$i":"delete-title","$v":["Slet ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," og alle dens data vil blive slettet."]},{"$i":"delete","$v":"Slet"},{"$i":"cancel","$v":"Annuller"},{"$i":"homescreen-settings","$v":"Indstillinger til startskærm"},{"$i":"change-wallpaper","$v":"Skift baggrund"},{"$i":"edit-mode","$v":"Rediger"},{"$i":"edit-done","$v":"Færdig"},{"$i":"stop-download-title","$v":["Stop ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Vil du stoppe den igangværende filhentning?"},{"$i":"stop-download-action","$v":"Stop"},{"$i":"resume-download-title","$v":"Genstart filhentning"},{"$i":"resume-download-body","$v":["Vil du hente ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Hent"},{"$i":"edit-group-header","$v":"Rediger gruppe"},{"$i":"gaia-grid-stop-download-title","$v":["Stop ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Vil du stoppe den igangværende filhentning?"},{"$i":"gaia-grid-stop-download-action","$v":"Stop"},{"$i":"gaia-grid-resume-download-title","$v":"Genstart filhentning"},{"$i":"gaia-grid-resume-download-body","$v":["Vil du hente ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Hent"},{"$i":"gaia-grid-cancel","$v":"Annuller"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Udvid gruppe"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Sammenfold gruppe"},{"$i":"gaia-grid-enter-group-name","$v":"Angiv et gruppenavn"},{"$i":"gaia-menu-cancel","$v":"Annuller"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Suche oder Adresse"},{"$i":"delete-title","$v":[{"t":"idOrVar","v":"name"}," löschen"]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," und seine Daten werden gelöscht."]},{"$i":"delete","$v":"Löschen"},{"$i":"cancel","$v":"Abbrechen"},{"$i":"homescreen-settings","$v":"Startbildschirm-Einstellungen"},{"$i":"change-wallpaper","$v":"Hintergrund ändern"},{"$i":"edit-mode","$v":"Bearbeiten"},{"$i":"edit-done","$v":"Fertig"},{"$i":"stop-download-title","$v":[{"t":"idOrVar","v":"name"}," anhalten"]},{"$i":"stop-download-body","$v":"Soll der laufende Download angehalten werden?"},{"$i":"stop-download-action","$v":"Anhalten"},{"$i":"resume-download-title","$v":"Download neu starten"},{"$i":"resume-download-body","$v":["Soll ",{"t":"idOrVar","v":"name"}," heruntergeladen werden?"]},{"$i":"resume-download-action","$v":"Herunterladen"},{"$i":"edit-group-header","$v":"Gruppe bearbeiten"},{"$i":"gaia-grid-stop-download-title","$v":[{"t":"idOrVar","v":"name"}," anhalten"]},{"$i":"gaia-grid-stop-download-body","$v":"Soll der laufende Download angehalten werden?"},{"$i":"gaia-grid-stop-download-action","$v":"Anhalten"},{"$i":"gaia-grid-resume-download-title","$v":"Download neu starten"},{"$i":"gaia-grid-resume-download-body","$v":["Soll ",{"t":"idOrVar","v":"name"}," heruntergeladen werden?"]},{"$i":"gaia-grid-resume-download-action","$v":"Herunterladen"},{"$i":"gaia-grid-cancel","$v":"Abbrechen"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Gruppe ausklappen"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Gruppe einklappen"},{"$i":"gaia-grid-enter-group-name","$v":"Gruppennamen eingeben"},{"$i":"gaia-menu-cancel","$v":"Abbrechen"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Διεύθυνση ή αναζήτηση"},{"$i":"delete-title","$v":"Διαγράφη εφαρμογής"},{"$i":"delete-body","$v":["Η εφαρμογή ",{"t":"idOrVar","v":"name"}," και όλα της τα δεδομένα θα διαγραφούν."]},{"$i":"delete","$v":"Διαγραφή"},{"$i":"cancel","$v":"Ακύρωση"},{"$i":"homescreen-settings","$v":"Ρυθμίσεις αρχικής οθόνης"},{"$i":"change-wallpaper","$v":"Αλλαγή ταπετσαρίας"},{"$i":"edit-mode","$v":"Επεξεργασία"},{"$i":"edit-done","$v":"ΟΚ"},{"$i":"stop-download-title","$v":["Διακοπή ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Θέλετε να διακόψετε τη τρέχουσα λήψη;"},{"$i":"stop-download-action","$v":"Διακοπή"},{"$i":"resume-download-title","$v":"Επανεκκίνηση λήψης"},{"$i":"resume-download-body","$v":["Θέλετε να γίνει λήψη του ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Λήψη"},{"$i":"edit-group-header","$v":"Επεξεργασία ομάδας"},{"$i":"gaia-grid-stop-download-title","$v":["Διακοπή ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Θέλετε να διακόψετε τη τρέχουσα λήψη;"},{"$i":"gaia-grid-stop-download-action","$v":"Διακοπή"},{"$i":"gaia-grid-resume-download-title","$v":"Επανεκκίνηση λήψης"},{"$i":"gaia-grid-resume-download-body","$v":["Θέλετε να γίνει λήψη του ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Λήψη"},{"$i":"gaia-grid-cancel","$v":"Ακύρωση"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Επέκταση ομάδας"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Αναδίπλωση ομάδας"},{"$i":"gaia-grid-enter-group-name","$v":"Εισάγετε ένα όνομα ομάδας"},{"$i":"gaia-menu-cancel","$v":"Ακύρωση"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Search or enter address"},{"$i":"delete-title","$v":["Delete ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," and all of its data will be deleted."]},{"$i":"delete","$v":"Delete"},{"$i":"cancel","$v":"Cancel"},{"$i":"homescreen-settings","$v":"Homescreen Settings"},{"$i":"change-wallpaper","$v":"Change Wallpaper"},{"$i":"edit-mode","$v":"Edit"},{"$i":"edit-done","$v":"Done"},{"$i":"stop-download-title","$v":["Stop ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Do you want to stop the download in progress?"},{"$i":"stop-download-action","$v":"Stop"},{"$i":"resume-download-title","$v":"Restart Download"},{"$i":"resume-download-body","$v":["Do you want to download ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Download"},{"$i":"edit-group-header","$v":"Edit group"},{"$i":"gaia-grid-stop-download-title","$v":["Stop ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Do you want to stop the download in progress?"},{"$i":"gaia-grid-stop-download-action","$v":"Stop"},{"$i":"gaia-grid-resume-download-title","$v":"Restart Download"},{"$i":"gaia-grid-resume-download-body","$v":["Do you want to download ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Download"},{"$i":"gaia-grid-cancel","$v":"Cancel"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Expand group"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Collapse group"},{"$i":"gaia-grid-enter-group-name","$v":"Enter a group name"},{"$i":"gaia-menu-cancel","$v":"Cancel"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Busque o escriba dirección"},{"$i":"delete-title","$v":["Borrar ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," y todos sus datos serán borrados."]},{"$i":"delete","$v":"Borrar"},{"$i":"cancel","$v":"Cancelar"},{"$i":"homescreen-settings","$v":"Ajustes pantalla de inicio"},{"$i":"change-wallpaper","$v":"Cambiar fondo de pantalla"},{"$i":"edit-mode","$v":"Editar"},{"$i":"edit-done","$v":"Hecho"},{"$i":"stop-download-title","$v":["Parar ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"¿Desea parar la descarga en curso?"},{"$i":"stop-download-action","$v":"Parar"},{"$i":"resume-download-title","$v":"Reiniciar descarga"},{"$i":"resume-download-body","$v":["¿Quiere descargar ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Descargar"},{"$i":"edit-group-header","$v":"Editar grupo"},{"$i":"gaia-grid-stop-download-title","$v":["Parar ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"¿Desea parar la descarga en curso?"},{"$i":"gaia-grid-stop-download-action","$v":"Parar"},{"$i":"gaia-grid-resume-download-title","$v":"Reiniciar descarga"},{"$i":"gaia-grid-resume-download-body","$v":["¿Desea descargar ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Descargar"},{"$i":"gaia-grid-cancel","$v":"Cancelar"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Expandir grupo"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Contraer grupo"},{"$i":"gaia-grid-enter-group-name","$v":"Escriba nombre de grupo"},{"$i":"gaia-menu-cancel","$v":"Cancelar"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Bilatu / idatzi helbidea"},{"$i":"delete-title","$v":["Ezabatu ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," eta bere datu guztiak ezabatuko dira."]},{"$i":"delete","$v":"Ezabatu"},{"$i":"cancel","$v":"Utzi"},{"$i":"homescreen-settings","$v":"Pantaila nagusiaren ezarpenak"},{"$i":"change-wallpaper","$v":"Aldatu horma-papera"},{"$i":"edit-mode","$v":"Editatu"},{"$i":"edit-done","$v":"Eginda"},{"$i":"stop-download-title","$v":["Gelditu ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Abian dagoen deskarga gelditu nahi duzu?"},{"$i":"stop-download-action","$v":"Gelditu"},{"$i":"resume-download-title","$v":"Berrabiarazi deskarga"},{"$i":"resume-download-body","$v":[{"t":"idOrVar","v":"name"}," deskargatu nahi duzu?"]},{"$i":"resume-download-action","$v":"Deskargatu"},{"$i":"edit-group-header","$v":"Editatu taldea"},{"$i":"gaia-grid-stop-download-title","$v":["Gelditu ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Uneko deskarga gelditu nahi duzu?"},{"$i":"gaia-grid-stop-download-action","$v":"Gelditu"},{"$i":"gaia-grid-resume-download-title","$v":"Berrabiarazi deskarga"},{"$i":"gaia-grid-resume-download-body","$v":[{"t":"idOrVar","v":"name"}," deskargatu nahi duzu?"]},{"$i":"gaia-grid-resume-download-action","$v":"Deskargatu"},{"$i":"gaia-grid-cancel","$v":"Utzi"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Zabaldu taldea"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Tolestu taldea"},{"$i":"gaia-grid-enter-group-name","$v":"Sartu taldearen izena"},{"$i":"gaia-menu-cancel","$v":"Utzi"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Recherche ou adresse"},{"$i":"delete-title","$v":["Supprimer ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," et toutes ses données seront supprimés."]},{"$i":"delete","$v":"Supprimer"},{"$i":"cancel","$v":"Annuler"},{"$i":"homescreen-settings","$v":"Paramètres de l’écran d’accueil"},{"$i":"change-wallpaper","$v":"Changer le fond d’écran"},{"$i":"edit-mode","$v":"Mode édition"},{"$i":"edit-done","$v":"Terminé"},{"$i":"stop-download-title","$v":["Arrêter ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Voulez-vous arrêter le téléchargement en cours ?"},{"$i":"stop-download-action","$v":"Arrêter"},{"$i":"resume-download-title","$v":"Redémarrer le téléchargement"},{"$i":"resume-download-body","$v":["Voulez-vous télécharger ",{"t":"idOrVar","v":"name"}," ?"]},{"$i":"resume-download-action","$v":"Télécharger"},{"$i":"edit-group-header","$v":"Modifier le groupe"},{"$i":"gaia-grid-stop-download-title","$v":["Arrêter ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Voulez-vous arrêter le téléchargement en cours ?"},{"$i":"gaia-grid-stop-download-action","$v":"Arrêter"},{"$i":"gaia-grid-resume-download-title","$v":"Redémarrer le téléchargement"},{"$i":"gaia-grid-resume-download-body","$v":["Voulez-vous télécharger ",{"t":"idOrVar","v":"name"}," ?"]},{"$i":"gaia-grid-resume-download-action","$v":"Télécharger"},{"$i":"gaia-grid-cancel","$v":"Annuler"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Développer le groupe"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Réduire le groupe"},{"$i":"gaia-grid-enter-group-name","$v":"Saisir un nom de groupe"},{"$i":"gaia-menu-cancel","$v":"Annuler"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Buscar ou enderezo"},{"$i":"delete-title","$v":["Eliminar",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":["Eliminarase ",{"t":"idOrVar","v":"name"}," e todos os seus datos."]},{"$i":"delete","$v":"Eliminar"},{"$i":"cancel","$v":"Cancelar"},{"$i":"homescreen-settings","$v":"Axustes pantalla inicial"},{"$i":"change-wallpaper","$v":"Cambiar fondo de pantalla"},{"$i":"edit-mode","$v":"Editar"},{"$i":"edit-done","$v":"Feito"},{"$i":"stop-download-title","$v":["Deter ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Quere deter a descarga en progreso?"},{"$i":"stop-download-action","$v":"Deter"},{"$i":"resume-download-title","$v":"Reiniciar a descarga"},{"$i":"resume-download-body","$v":["Quere descargar ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Descargar"},{"$i":"edit-group-header","$v":"Editar grupo"},{"$i":"gaia-grid-stop-download-title","$v":["Deter ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Quere deter a descarga en progreso?"},{"$i":"gaia-grid-stop-download-action","$v":"Deter"},{"$i":"gaia-grid-resume-download-title","$v":"Reiniciar a descarga"},{"$i":"gaia-grid-resume-download-body","$v":["Quere descargar ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Descargar"},{"$i":"gaia-grid-cancel","$v":"Cancelar"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Expandir grupo"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Contraer grupo"},{"$i":"gaia-grid-enter-group-name","$v":"Escriba un nome de grupo"},{"$i":"gaia-menu-cancel","$v":"Cancelar"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Search or enter address"},{"$i":"delete-title","$v":["Obriši ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," i svi pripadajući podaci će biti obrisani."]},{"$i":"delete","$v":"Obriši"},{"$i":"cancel","$v":"Cancel"},{"$i":"homescreen-settings","$v":"Homescreen Settings"},{"$i":"change-wallpaper","$v":"Promijeni pozadinsku sliku"},{"$i":"edit-mode","$v":"Edit"},{"$i":"edit-done","$v":"Done"},{"$i":"stop-download-title","$v":["Stop ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Do you want to stop the download in progress?"},{"$i":"stop-download-action","$v":"Stop"},{"$i":"resume-download-title","$v":"Ponovno pokretanje preuzimanja"},{"$i":"resume-download-body","$v":["Želite li preuzeti ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Download"},{"$i":"edit-group-header","$v":"Edit group"},{"$i":"gaia-grid-stop-download-title","$v":["Stop ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Do you want to stop the download in progress?"},{"$i":"gaia-grid-stop-download-action","$v":"Stop"},{"$i":"gaia-grid-resume-download-title","$v":"Restart Download"},{"$i":"gaia-grid-resume-download-body","$v":["Do you want to download ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Download"},{"$i":"gaia-grid-cancel","$v":"Cancel"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Expand group"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Collapse group"},{"$i":"gaia-grid-enter-group-name","$v":"Enter a group name"},{"$i":"gaia-menu-cancel","$v":"Cancel"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Keresés vagy cím"},{"$i":"delete-title","$v":[{"t":"idOrVar","v":"name"}," törlése"]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," és minden adata törlésre kerül."]},{"$i":"delete","$v":"Törlés"},{"$i":"cancel","$v":"Mégse"},{"$i":"homescreen-settings","$v":"Kezdőképernyő beállítások"},{"$i":"change-wallpaper","$v":"Háttér módosítása"},{"$i":"edit-mode","$v":"Szerkesztés"},{"$i":"edit-done","$v":"Kész"},{"$i":"stop-download-title","$v":[{"t":"idOrVar","v":"name"}," leálltása"]},{"$i":"stop-download-body","$v":"Le szeretné állítani a folyamatban lévő letöltést?"},{"$i":"stop-download-action","$v":"Leállítás"},{"$i":"resume-download-title","$v":"Letöltés újraindítása"},{"$i":"resume-download-body","$v":["Szeretné letölteni ezt: ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Letöltés"},{"$i":"edit-group-header","$v":"Csoport szerkesztése"},{"$i":"gaia-grid-stop-download-title","$v":[{"t":"idOrVar","v":"name"}," leállítása"]},{"$i":"gaia-grid-stop-download-body","$v":"Le szeretné állítani a folyamatban lévő letöltést?"},{"$i":"gaia-grid-stop-download-action","$v":"Leállítás"},{"$i":"gaia-grid-resume-download-title","$v":"Letöltés újraindítása"},{"$i":"gaia-grid-resume-download-body","$v":["Szeretné letölteni ezt: ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Letöltés"},{"$i":"gaia-grid-cancel","$v":"Mégse"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Csoport kibontása"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Csoport összecsukása"},{"$i":"gaia-grid-enter-group-name","$v":"Írjon be csoportnevet"},{"$i":"gaia-menu-cancel","$v":"Mégse"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Cerca o scrivi un indirizzo"},{"$i":"delete-title","$v":["Elimina ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," e tutti i relativi dati verranno eliminati."]},{"$i":"delete","$v":"Elimina"},{"$i":"cancel","$v":"Annulla"},{"$i":"homescreen-settings","$v":"Impostazioni schermata"},{"$i":"change-wallpaper","$v":"Cambia sfondo"},{"$i":"edit-mode","$v":"Modifica"},{"$i":"edit-done","$v":"Fine"},{"$i":"stop-download-title","$v":["Interrompi ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Interrompere il download in corso?"},{"$i":"stop-download-action","$v":"Interrompi"},{"$i":"resume-download-title","$v":"Riavvio download"},{"$i":"resume-download-body","$v":["Procedere con il download di ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Scarica"},{"$i":"edit-group-header","$v":"Modifica gruppo"},{"$i":"gaia-grid-stop-download-title","$v":["Interrompi ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Interrompere il download in corso?"},{"$i":"gaia-grid-stop-download-action","$v":"Interrompi"},{"$i":"gaia-grid-resume-download-title","$v":"Riavvio download"},{"$i":"gaia-grid-resume-download-body","$v":["Procedere con il download di ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Scarica"},{"$i":"gaia-grid-cancel","$v":"Annulla"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Espandi gruppo"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Contrai gruppo"},{"$i":"gaia-grid-enter-group-name","$v":"Inserire un nome per il gruppo"},{"$i":"gaia-menu-cancel","$v":"Annulla"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"検索語またはアドレス"},{"$i":"delete-title","$v":[{"t":"idOrVar","v":"name"}," の削除"]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," とそのすべてのデータを削除します。"]},{"$i":"delete","$v":"削除"},{"$i":"cancel","$v":"キャンセル"},{"$i":"homescreen-settings","$v":"ホーム画面設定"},{"$i":"change-wallpaper","$v":"壁紙を変更"},{"$i":"edit-mode","$v":"編集"},{"$i":"edit-done","$v":"完了"},{"$i":"stop-download-title","$v":[{"t":"idOrVar","v":"name"}," のダウンロード中止"]},{"$i":"stop-download-body","$v":"ダウンロードを中止しますか?"},{"$i":"stop-download-action","$v":"中止"},{"$i":"resume-download-title","$v":"ダウンロードの再開"},{"$i":"resume-download-body","$v":[{"t":"idOrVar","v":"name"}," をダウンロードしますか?"]},{"$i":"resume-download-action","$v":"ダウンロード"},{"$i":"edit-group-header","$v":"グループの編集"},{"$i":"gaia-grid-stop-download-title","$v":[{"t":"idOrVar","v":"name"}," を中止"]},{"$i":"gaia-grid-stop-download-body","$v":"ダウンロードを中止してもよろしいですか?"},{"$i":"gaia-grid-stop-download-action","$v":"中止"},{"$i":"gaia-grid-resume-download-title","$v":"ダウンロード再開"},{"$i":"gaia-grid-resume-download-body","$v":[{"t":"idOrVar","v":"name"}," のダウンロードを再開しますか?"]},{"$i":"gaia-grid-resume-download-action","$v":"ダウンロード"},{"$i":"gaia-grid-cancel","$v":"キャンセル"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"グループを展開する"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"グループを折りたたむ"},{"$i":"gaia-grid-enter-group-name","$v":"グループ名を入力してください"},{"$i":"gaia-menu-cancel","$v":"キャンセル"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"ស្វែងរក ឬ​បញ្ចូល​អាសយដ្ឋាន"},{"$i":"delete-title","$v":["លុប ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," និង​ទិន្នន័យ​ទាំងអស់​របស់​វា​នឹង​ត្រូវ​លុប។"]},{"$i":"delete","$v":"លុប"},{"$i":"cancel","$v":"បោះបង់"},{"$i":"homescreen-settings","$v":"ការ​កំណត់​អេក្រង់​ដើម"},{"$i":"change-wallpaper","$v":"ប្ដូរ​ផ្ទាំង​រូបភាព"},{"$i":"edit-mode","$v":"កែសម្រួល​"},{"$i":"edit-done","$v":"រួចរាល់"},{"$i":"stop-download-title","$v":["បញ្ឈប់ ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"តើ​អ្នក​ចង់​បញ្ឈប់​ការ​ទាញ​យក​ដែល​កំពុង​ដំណើរការ​ឬ?"},{"$i":"stop-download-action","$v":"ឈប់"},{"$i":"resume-download-title","$v":"ចាប់ផ្ដើម​ទាញយក​ឡើ​ងវិញ"},{"$i":"resume-download-body","$v":["តើ​អ្នក​ចង់​ទាញ​យក ",{"t":"idOrVar","v":"name"},"​ឬ?"]},{"$i":"resume-download-action","$v":"ទាញ​យក"},{"$i":"edit-group-header","$v":"Edit group"},{"$i":"gaia-grid-stop-download-title","$v":["បញ្ឈប់ ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"តើ​អ្នក​ចង់​បញ្ឈប់​កា​រ​ទាញយក​​ដែល​កំពុង​ដំណើរការ?"},{"$i":"gaia-grid-stop-download-action","$v":"បញ្ឈប់"},{"$i":"gaia-grid-resume-download-title","$v":"ចាប់ផ្ដើម​ទាញ​យក​​ឡើងវិញ"},{"$i":"gaia-grid-resume-download-body","$v":["តើ​អ្នក​ចង់​ទាញយក ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"ទាញយក"},{"$i":"gaia-grid-cancel","$v":"បោះបង់"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Expand group"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Collapse group"},{"$i":"gaia-grid-enter-group-name","$v":"Enter a group name"},{"$i":"gaia-menu-cancel","$v":"បោះបង់"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"검색어나 주소 입력"},{"$i":"delete-title","$v":[{"t":"idOrVar","v":"name"}," 삭제"]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," 항목과 데이터가 모두 삭제됩니다."]},{"$i":"delete","$v":"삭제"},{"$i":"cancel","$v":"취소"},{"$i":"homescreen-settings","$v":"홈스크린 설정"},{"$i":"change-wallpaper","$v":"바탕화면 변경"},{"$i":"edit-mode","$v":"수정"},{"$i":"edit-done","$v":"완료"},{"$i":"stop-download-title","$v":[{"t":"idOrVar","v":"name"}," 중지"]},{"$i":"stop-download-body","$v":"진행중인 다운로드를 취소하시겠습니까?"},{"$i":"stop-download-action","$v":"중지"},{"$i":"resume-download-title","$v":"다운로드 재시작"},{"$i":"resume-download-body","$v":[{"t":"idOrVar","v":"name"}," 항목을 다운로드 하시겠습니까?"]},{"$i":"resume-download-action","$v":"다운로드"},{"$i":"edit-group-header","$v":"그룹 편집"},{"$i":"gaia-grid-stop-download-title","$v":[{"t":"idOrVar","v":"name"}," 중지"]},{"$i":"gaia-grid-stop-download-body","$v":"진행중인 다운로드를 취소하시겠습니까?"},{"$i":"gaia-grid-stop-download-action","$v":"중지"},{"$i":"gaia-grid-resume-download-title","$v":"다운로드 재시작"},{"$i":"gaia-grid-resume-download-body","$v":[{"t":"idOrVar","v":"name"}," 항목을 다운로드 하시겠습니까?"]},{"$i":"gaia-grid-resume-download-action","$v":"다운로드"},{"$i":"gaia-grid-cancel","$v":"취소"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"그룹 열기"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"그룹 닫기"},{"$i":"gaia-grid-enter-group-name","$v":"그룹 이름 입력"},{"$i":"gaia-menu-cancel","$v":"취소"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Ieškokite arba įveskite adresą"},{"$i":"delete-title","$v":["„",{"t":"idOrVar","v":"name"},"“ šalinimas"]},{"$i":"delete-body","$v":["Ar pašalinti „",{"t":"idOrVar","v":"name"},"“ ir visus susijusius duomenis?"]},{"$i":"delete","$v":"Šalinti"},{"$i":"cancel","$v":"Atsisakyti"},{"$i":"homescreen-settings","$v":"Pradžios ekrano nuostatos"},{"$i":"change-wallpaper","$v":"Keisti ekrano foną"},{"$i":"edit-mode","$v":"Taisa"},{"$i":"edit-done","$v":"Baigta"},{"$i":"stop-download-title","$v":["„",{"t":"idOrVar","v":"name"},"“ parsiuntimo nutraukimas"]},{"$i":"stop-download-body","$v":"Ar norite nutraukti vykstantį parsiuntimą?"},{"$i":"stop-download-action","$v":"Nutraukti"},{"$i":"resume-download-title","$v":"Parsiuntimo kartojimas"},{"$i":"resume-download-body","$v":["Ar norite parsiųsti „",{"t":"idOrVar","v":"name"},"“?"]},{"$i":"resume-download-action","$v":"Parsiųsti"},{"$i":"edit-group-header","$v":"Edit group"},{"$i":"gaia-grid-stop-download-title","$v":["Parsiuntimo „",{"t":"idOrVar","v":"name"},"“ nutraukimas"]},{"$i":"gaia-grid-stop-download-body","$v":"Ar norite nutraukti vykstantį parsiuntimą?ss?"},{"$i":"gaia-grid-stop-download-action","$v":"Nutraukti"},{"$i":"gaia-grid-resume-download-title","$v":"Parsiuntimo kartojimas"},{"$i":"gaia-grid-resume-download-body","$v":["Ar norite parsiųsti „",{"t":"idOrVar","v":"name"},"“?"]},{"$i":"gaia-grid-resume-download-action","$v":"Parsiųsti"},{"$i":"gaia-grid-cancel","$v":"Atsisakyti"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Expand group"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Collapse group"},{"$i":"gaia-grid-enter-group-name","$v":"Enter a group name"},{"$i":"gaia-menu-cancel","$v":"Atsisakyti"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Search or enter address"},{"$i":"delete-title","$v":["Delete ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," and all of its data will be deleted."]},{"$i":"delete","$v":"Delete"},{"$i":"cancel","$v":"Cancel"},{"$i":"homescreen-settings","$v":"Homescreen Settings"},{"$i":"change-wallpaper","$v":"Change Wallpaper"},{"$i":"edit-mode","$v":"Edit"},{"$i":"edit-done","$v":"Done"},{"$i":"stop-download-title","$v":["Stop ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Do you want to stop the download in progress?"},{"$i":"stop-download-action","$v":"Stop"},{"$i":"resume-download-title","$v":"Restart Download"},{"$i":"resume-download-body","$v":["Do you want to download ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Download"},{"$i":"edit-group-header","$v":"Edit group"},{"$i":"gaia-grid-stop-download-title","$v":["Stop ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Do you want to stop the download in progress?"},{"$i":"gaia-grid-stop-download-action","$v":"Stop"},{"$i":"gaia-grid-resume-download-title","$v":"Restart Download"},{"$i":"gaia-grid-resume-download-body","$v":["Do you want to download ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Download"},{"$i":"gaia-grid-cancel","$v":"Cancel"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Expand group"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Collapse group"},{"$i":"gaia-grid-enter-group-name","$v":"Enter a group name"},{"$i":"gaia-menu-cancel","$v":"Cancel"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Cari atau masukkan alamat"},{"$i":"delete-title","$v":["Hapus ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," dan semua datanya akan dihapuskan."]},{"$i":"delete","$v":"Hapus"},{"$i":"cancel","$v":"Batal"},{"$i":"homescreen-settings","$v":"Tetapan Skrin Utama"},{"$i":"change-wallpaper","$v":"Tukar Kertas Dinding"},{"$i":"edit-mode","$v":"Sunting"},{"$i":"edit-done","$v":"Selesai"},{"$i":"stop-download-title","$v":["Henti ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Adakah anda ingin menghentikan muat turun sedang berlangsung?"},{"$i":"stop-download-action","$v":"Henti"},{"$i":"resume-download-title","$v":"Ulang mula muat turun"},{"$i":"resume-download-body","$v":["Adakah anda ingin muat turun ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Muat turun"},{"$i":"edit-group-header","$v":"Edit group"},{"$i":"gaia-grid-stop-download-title","$v":["Henti ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Adakah anda ingin menghentikan muat turun yang sedang berlangsung?"},{"$i":"gaia-grid-stop-download-action","$v":"Henti"},{"$i":"gaia-grid-resume-download-title","$v":"Mula semula Muat turun"},{"$i":"gaia-grid-resume-download-body","$v":["Adakah anda ingin memuat turun ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Muat Turun"},{"$i":"gaia-grid-cancel","$v":"Batal"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Expand group"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Collapse group"},{"$i":"gaia-grid-enter-group-name","$v":"Enter a group name"},{"$i":"gaia-menu-cancel","$v":"Batal"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Search or enter address"},{"$i":"delete-title","$v":[{"t":"idOrVar","v":"name"}," मेट"]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," र यसका सम्पूर्ण डाटाहरु मेटाइनेछ।"]},{"$i":"delete","$v":"मेट्नुहोस्"},{"$i":"cancel","$v":"Cancel"},{"$i":"homescreen-settings","$v":"Homescreen Settings"},{"$i":"change-wallpaper","$v":"वालपपेर बदल्नुहोस"},{"$i":"edit-mode","$v":"सम्पादन गर्नुहोस्"},{"$i":"edit-done","$v":"पूरा भयो"},{"$i":"stop-download-title","$v":["Stop ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Do you want to stop the download in progress?"},{"$i":"stop-download-action","$v":"Stop"},{"$i":"resume-download-title","$v":"डाउनलोड पुन: सुरु गर्नुहोस"},{"$i":"resume-download-body","$v":["के तपाई ",{"t":"idOrVar","v":"name"}," डाउनलोड गर्न चाहनुहुन्छ?"]},{"$i":"resume-download-action","$v":"Download"},{"$i":"edit-group-header","$v":"Edit group"},{"$i":"gaia-grid-stop-download-title","$v":["बन्द",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"तपाई यो डाउनलोडको प्रगतिलाई रोक्न चाहनुहुन्छ? "},{"$i":"gaia-grid-stop-download-action","$v":"बन्द"},{"$i":"gaia-grid-resume-download-title","$v":"डाउनलोड फेरी सुरु गर्नुहोस्"},{"$i":"gaia-grid-resume-download-body","$v":["के तपाई ",{"t":"idOrVar","v":"name"}," डाउनलोड गर्न चाहनुहुन्छ?"]},{"$i":"gaia-grid-resume-download-action","$v":"डाउनलोड"},{"$i":"gaia-grid-cancel","$v":"रद्द गर्नुहोस्"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Expand group"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Collapse group"},{"$i":"gaia-grid-enter-group-name","$v":"Enter a group name"},{"$i":"gaia-menu-cancel","$v":"रद्द गर्नुहोस्"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Voer zoekterm of adres in"},{"$i":"delete-title","$v":[{"t":"idOrVar","v":"name"}," verwijderen"]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," en alle gegevens ervan zullen worden verwijderd."]},{"$i":"delete","$v":"Verwijderen"},{"$i":"cancel","$v":"Annuleren"},{"$i":"homescreen-settings","$v":"Startscherminstellingen"},{"$i":"change-wallpaper","$v":"Achtergrond wijzigen"},{"$i":"edit-mode","$v":"Bewerken"},{"$i":"edit-done","$v":"Gereed"},{"$i":"stop-download-title","$v":[{"t":"idOrVar","v":"name"}," stoppen"]},{"$i":"stop-download-body","$v":"Wilt u de actieve download stoppen?"},{"$i":"stop-download-action","$v":"Stoppen"},{"$i":"resume-download-title","$v":"Download herstarten"},{"$i":"resume-download-body","$v":["Wilt u ",{"t":"idOrVar","v":"name"}," downloaden?"]},{"$i":"resume-download-action","$v":"Downloaden"},{"$i":"edit-group-header","$v":"Groep bewerken"},{"$i":"gaia-grid-stop-download-title","$v":[{"t":"idOrVar","v":"name"}," stoppen"]},{"$i":"gaia-grid-stop-download-body","$v":"Wilt u de actieve download stoppen?"},{"$i":"gaia-grid-stop-download-action","$v":"Stoppen"},{"$i":"gaia-grid-resume-download-title","$v":"Download herstarten"},{"$i":"gaia-grid-resume-download-body","$v":["Wilt u ",{"t":"idOrVar","v":"name"}," downloaden?"]},{"$i":"gaia-grid-resume-download-action","$v":"Downloaden"},{"$i":"gaia-grid-cancel","$v":"Annuleren"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Groep uitvouwen"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Groep samenvouwen"},{"$i":"gaia-grid-enter-group-name","$v":"Voer een groepsnaam in"},{"$i":"gaia-menu-cancel","$v":"Annuleren"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"ਖੋਜੋ ਜਾਂ ਸਿਰਨਾਵਾਂ ਦਿਓ"},{"$i":"delete-title","$v":[{"t":"idOrVar","v":"name"}," ਹਟਾਓ"]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," ਤੇ ਇਸ ਦਾ ਸਾਰਾ ਡਾਟਾ ਹਟਾਇਆ ਜਾਵੇਗਾ।"]},{"$i":"delete","$v":"ਹਟਾਓ"},{"$i":"cancel","$v":"ਰੱਦ ਕਰੋ"},{"$i":"homescreen-settings","$v":"ਮੁੱਖ ਸਕਰੀਨ ਸੈਟਿੰਗ"},{"$i":"change-wallpaper","$v":"ਵਾਲਪੇਪਰ ਬਦਲੋ"},{"$i":"edit-mode","$v":"ਸੋਧ"},{"$i":"edit-done","$v":"ਮੁਕੰਮਲ"},{"$i":"stop-download-title","$v":[{"t":"idOrVar","v":"name"}," ਰੋਕੋ"]},{"$i":"stop-download-body","$v":"ਕੀ ਤੁਸੀਂ ਜਾਰੀ ਡਾਊਨਲੋਡ ਨੂੰ ਰੋਕਣਾ ਚਾਹੁੰਦੇ ਹੋ?"},{"$i":"stop-download-action","$v":"ਰੋਕੋ"},{"$i":"resume-download-title","$v":"ਡਾਊਨਲੋਡ ਮੁੜ-ਚਾਲੂ"},{"$i":"resume-download-body","$v":["ਕੀ ਤੁਸੀਂ ",{"t":"idOrVar","v":"name"}," ਡਾਊਨਲੋਡ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"]},{"$i":"resume-download-action","$v":"ਡਾਊਨਲੋਡ"},{"$i":"edit-group-header","$v":"Edit group"},{"$i":"gaia-grid-stop-download-title","$v":[{"t":"idOrVar","v":"name"}," ਰੋਕੋ"]},{"$i":"gaia-grid-stop-download-body","$v":"ਕੀ ਤੁਸੀਂ ਚੱਲ ਰਹੇ ਡਾਊਨਲੋਡ ਨੂੰ ਰੋਕਣਾ ਚਾਹੁੰਦੇ ਹੋ?"},{"$i":"gaia-grid-stop-download-action","$v":"ਰੋਕੋ"},{"$i":"gaia-grid-resume-download-title","$v":"ਡਾਊਨਲੋਡ ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ"},{"$i":"gaia-grid-resume-download-body","$v":["ਕੀ ਤੁਸੀਂ ",{"t":"idOrVar","v":"name"}," ਨੂੰ ਡਾਊਨਲੋਡ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"]},{"$i":"gaia-grid-resume-download-action","$v":"ਡਾਊਨਲੋਡ"},{"$i":"gaia-grid-cancel","$v":"ਰੱਦ ਕਰੋ"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Expand group"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Collapse group"},{"$i":"gaia-grid-enter-group-name","$v":"Enter a group name"},{"$i":"gaia-menu-cancel","$v":"ਰੱਦ ਕਰੋ"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Podaj adres lub szukaj"},{"$i":"delete-title","$v":["Usuwanie „",{"t":"idOrVar","v":"name"},"”"]},{"$i":"delete-body","$v":["Aplikacja „",{"t":"idOrVar","v":"name"},"” i wszystkie powiązane z nią dane zostaną usunięte."]},{"$i":"delete","$v":"Usuń"},{"$i":"cancel","$v":"Anuluj"},{"$i":"homescreen-settings","$v":"Ustawienia ekranu głównego"},{"$i":"change-wallpaper","$v":"Zmień tło ekranu"},{"$i":"edit-mode","$v":"Edycja"},{"$i":"edit-done","$v":"Gotowe"},{"$i":"stop-download-title","$v":["Zatrzymywanie pobierania „",{"t":"idOrVar","v":"name"},"”"]},{"$i":"stop-download-body","$v":"Zatrzymać aktywne pobieranie aplikacji?"},{"$i":"stop-download-action","$v":"Zatrzymaj"},{"$i":"resume-download-title","$v":"Wznawianie pobierania"},{"$i":"resume-download-body","$v":["Pobrać aplikację „",{"t":"idOrVar","v":"name"},"”?"]},{"$i":"resume-download-action","$v":"Pobierz"},{"$i":"edit-group-header","$v":"Edycja grupy"},{"$i":"gaia-grid-stop-download-title","$v":["Zatrzymywanie pobierania „",{"t":"idOrVar","v":"name"},"”"]},{"$i":"gaia-grid-stop-download-body","$v":"Zatrzymać aktywne pobieranie aplikacji?"},{"$i":"gaia-grid-stop-download-action","$v":"Zatrzymaj"},{"$i":"gaia-grid-resume-download-title","$v":"Wznawianie pobierania"},{"$i":"gaia-grid-resume-download-body","$v":["Pobrać aplikację „",{"t":"idOrVar","v":"name"},"”?"]},{"$i":"gaia-grid-resume-download-action","$v":"Pobierz"},{"$i":"gaia-grid-cancel","$v":"Anuluj"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Rozwiń grupę"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Zwiń grupę"},{"$i":"gaia-grid-enter-group-name","$v":"Wprowadź nazwę grupy"},{"$i":"gaia-menu-cancel","$v":"Anuluj"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Pesquisar ou navegar"},{"$i":"delete-title","$v":["Apagar ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," e todos os seus dados serão apagados."]},{"$i":"delete","$v":"Apagar"},{"$i":"cancel","$v":"Cancelar"},{"$i":"homescreen-settings","$v":"Configurações da tela principal"},{"$i":"change-wallpaper","$v":"Mudar papel de parede"},{"$i":"edit-mode","$v":"Editar"},{"$i":"edit-done","$v":"Pronto"},{"$i":"stop-download-title","$v":["Parar ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Você quer parar o download em progresso?"},{"$i":"stop-download-action","$v":"Parar"},{"$i":"resume-download-title","$v":"Reiniciar download"},{"$i":"resume-download-body","$v":["Deseja baixar ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Baixar"},{"$i":"edit-group-header","$v":"Editar grupo"},{"$i":"gaia-grid-stop-download-title","$v":["Parar ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Deseja interromper o download em progresso?"},{"$i":"gaia-grid-stop-download-action","$v":"Parar"},{"$i":"gaia-grid-resume-download-title","$v":"Reiniciar Download"},{"$i":"gaia-grid-resume-download-body","$v":["Você deseja transferir ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Download"},{"$i":"gaia-grid-cancel","$v":"Cancelar"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Expandir grupo"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Recolher grupo"},{"$i":"gaia-grid-enter-group-name","$v":"Digite o nome do grupo"},{"$i":"gaia-menu-cancel","$v":"Cancelar"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Caută sau introdu adresa"},{"$i":"delete-title","$v":["Șterge ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," și toate datele sale vor fi șterse."]},{"$i":"delete","$v":"Șterge"},{"$i":"cancel","$v":"Renunță"},{"$i":"homescreen-settings","$v":"Setări pentru ecran principal"},{"$i":"change-wallpaper","$v":"Schimbă fundalul"},{"$i":"edit-mode","$v":"Editează"},{"$i":"edit-done","$v":"Gata"},{"$i":"stop-download-title","$v":["Oprește ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Dorești să oprești descărcarea în desfășurare?"},{"$i":"stop-download-action","$v":"Oprește"},{"$i":"resume-download-title","$v":"Repornește descărcarea"},{"$i":"resume-download-body","$v":["Dorești să descarci ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Descarcă"},{"$i":"edit-group-header","$v":"Editează grupul"},{"$i":"gaia-grid-stop-download-title","$v":["Oprește ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Dorești să oprești descărcarea în desfășurare?"},{"$i":"gaia-grid-stop-download-action","$v":"Oprește"},{"$i":"gaia-grid-resume-download-title","$v":"Repornește descărcarea"},{"$i":"gaia-grid-resume-download-body","$v":["Dorești să descarci ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Descarcă"},{"$i":"gaia-grid-cancel","$v":"Renunță"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Extinde grupul"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Restânge grupul"},{"$i":"gaia-grid-enter-group-name","$v":"Intro un nume de grup"},{"$i":"gaia-menu-cancel","$v":"Renunță"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Поиск или адрес"},{"$i":"delete-title","$v":["Удаление ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," и все его данные будут удалены."]},{"$i":"delete","$v":"Удалить"},{"$i":"cancel","$v":"Отмена"},{"$i":"homescreen-settings","$v":"Параметры Домашнего экрана"},{"$i":"change-wallpaper","$v":"Сменить обои"},{"$i":"edit-mode","$v":"Изменить"},{"$i":"edit-done","$v":"Готово"},{"$i":"stop-download-title","$v":["Остановка ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Вы хотите остановить процесс загрузки?"},{"$i":"stop-download-action","$v":"Остановить"},{"$i":"resume-download-title","$v":"Перезапуск загрузки"},{"$i":"resume-download-body","$v":["Вы хотите загрузить ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Загрузить"},{"$i":"edit-group-header","$v":"Изменить группу"},{"$i":"gaia-grid-stop-download-title","$v":["Остановка ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Вы хотите остановить процесс загрузки?"},{"$i":"gaia-grid-stop-download-action","$v":"Остановить"},{"$i":"gaia-grid-resume-download-title","$v":"Перезапуск загрузки"},{"$i":"gaia-grid-resume-download-body","$v":["Вы хотите загрузить ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Загрузить"},{"$i":"gaia-grid-cancel","$v":"Отмена"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Развернуть группу"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Свернуть группу"},{"$i":"gaia-grid-enter-group-name","$v":"Введите имя группы"},{"$i":"gaia-menu-cancel","$v":"Отмена"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Zadajte adresu/vyhľadávanie"},{"$i":"delete-title","$v":["Odstrániť ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," a všetky jej údaje budú odstránené."]},{"$i":"delete","$v":"Odstrániť"},{"$i":"cancel","$v":"Zrušiť"},{"$i":"homescreen-settings","$v":"Nastavenia Úvodnej obrazovky"},{"$i":"change-wallpaper","$v":"Zmeniť tapetu"},{"$i":"edit-mode","$v":"Upraviť"},{"$i":"edit-done","$v":"Hotovo"},{"$i":"stop-download-title","$v":["Zastaviť ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Naozaj chcete zastaviť prebiehajúce preberanie súboru?"},{"$i":"stop-download-action","$v":"Zastaviť"},{"$i":"resume-download-title","$v":"Reštartovať preberanie"},{"$i":"resume-download-body","$v":["Chcete prevziať ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Prevziať"},{"$i":"edit-group-header","$v":"Úprava skupiny"},{"$i":"gaia-grid-stop-download-title","$v":["Zastaviť ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Naozaj chcete zastaviť prebiehajúce preberanie?"},{"$i":"gaia-grid-stop-download-action","$v":"Zastaviť"},{"$i":"gaia-grid-resume-download-title","$v":"Reštartovanie preberania"},{"$i":"gaia-grid-resume-download-body","$v":["Chcete prevziať ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Prevziať"},{"$i":"gaia-grid-cancel","$v":"Zrušiť"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Rozbaliť skupinu"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Zbaliť skupinu"},{"$i":"gaia-grid-enter-group-name","$v":"Zadajte názov skupiny"},{"$i":"gaia-menu-cancel","$v":"Zrušiť"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Kërkoni ose jepni një adresë"},{"$i":"delete-title","$v":["Fshijeni ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," dhe krejt të dhënat e tij do të fshihen."]},{"$i":"delete","$v":"Fshije"},{"$i":"cancel","$v":"Anulojeni"},{"$i":"homescreen-settings","$v":"Rregullime Kreu"},{"$i":"change-wallpaper","$v":"Ndërroni Sfondin"},{"$i":"edit-mode","$v":"Përpunim"},{"$i":"edit-done","$v":"U bë"},{"$i":"stop-download-title","$v":["Ndaleni ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Doni të ndalet shkarkimi që po kryhet?"},{"$i":"stop-download-action","$v":"Ndale"},{"$i":"resume-download-title","$v":"Riniseni Shkarkimin"},{"$i":"resume-download-body","$v":["Doni të shkarkohet ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Shkarkoje"},{"$i":"edit-group-header","$v":"Përpunoni grupin"},{"$i":"gaia-grid-stop-download-title","$v":["Ndaleni ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Doni të ndalet shkarkimi që po kryhet?"},{"$i":"gaia-grid-stop-download-action","$v":"Ndale"},{"$i":"gaia-grid-resume-download-title","$v":"Rinisni Shkarkimin"},{"$i":"gaia-grid-resume-download-body","$v":["Doni të shkarkohet ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Shkarkoje"},{"$i":"gaia-grid-cancel","$v":"Anulojeni"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Zgjeroje grupin"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Tkurre grupin"},{"$i":"gaia-grid-enter-group-name","$v":"Jepni emër grupi"},{"$i":"gaia-menu-cancel","$v":"Anulojeni"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Појам или адреса"},{"$i":"delete-title","$v":["Обриши ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," и сви његови подаци ће бити обрисани."]},{"$i":"delete","$v":"Обриши"},{"$i":"cancel","$v":"Откажи"},{"$i":"homescreen-settings","$v":"Поставке почетног екрана"},{"$i":"change-wallpaper","$v":"Промени позадинску слику"},{"$i":"edit-mode","$v":"Уређивање"},{"$i":"edit-done","$v":"Готово"},{"$i":"stop-download-title","$v":["Заустави ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Да ли желите да зауставите преузимање?"},{"$i":"stop-download-action","$v":"Заустави"},{"$i":"resume-download-title","$v":"Рестартуј преузимање"},{"$i":"resume-download-body","$v":["Да ли желите да преузмете ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Преузми"},{"$i":"edit-group-header","$v":"Уреди групу"},{"$i":"gaia-grid-stop-download-title","$v":["Заустави ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Да ли желите да зауставите преузимање?"},{"$i":"gaia-grid-stop-download-action","$v":"Заустави"},{"$i":"gaia-grid-resume-download-title","$v":"Рестартуј преузимање"},{"$i":"gaia-grid-resume-download-body","$v":["Да ли желите да преузмете ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Преузми"},{"$i":"gaia-grid-cancel","$v":"Откажи"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Прошири групу"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Скупи групу"},{"$i":"gaia-grid-enter-group-name","$v":"Унесите име групе"},{"$i":"gaia-menu-cancel","$v":"Откажи"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Pojam ili adresa"},{"$i":"delete-title","$v":["Obriši ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," i svi njegovi podaci će biti obrisani."]},{"$i":"delete","$v":"Obriši"},{"$i":"cancel","$v":"Otkaži"},{"$i":"homescreen-settings","$v":"Postavke početnog ekrana"},{"$i":"change-wallpaper","$v":"Promeni pozadinsku sliku"},{"$i":"edit-mode","$v":"Uređivanje"},{"$i":"edit-done","$v":"Gotovo"},{"$i":"stop-download-title","$v":["Zaustavi ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Da li želite da zaustavite preuzimanje?"},{"$i":"stop-download-action","$v":"Zaustavi"},{"$i":"resume-download-title","$v":"Restartuj preuzimanje"},{"$i":"resume-download-body","$v":["Da li želite da preuzmete ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Preuzmi"},{"$i":"edit-group-header","$v":"Uredi grupu"},{"$i":"gaia-grid-stop-download-title","$v":["Zaustavi ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Da li želite da zaustavite preuzimanje?"},{"$i":"gaia-grid-stop-download-action","$v":"Zaustavi"},{"$i":"gaia-grid-resume-download-title","$v":"Restartuj preuzimanje"},{"$i":"gaia-grid-resume-download-body","$v":["Da li želite da preuzmete ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Preuzmi"},{"$i":"gaia-grid-cancel","$v":"Otkaži"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Proširi grupu"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Skupi grupu"},{"$i":"gaia-grid-enter-group-name","$v":"Unesite ime grupe"},{"$i":"gaia-menu-cancel","$v":"Otkaži"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Sök eller ange adress"},{"$i":"delete-title","$v":["Ta bort ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," och all dess data kommer att tas bort."]},{"$i":"delete","$v":"Ta bort"},{"$i":"cancel","$v":"Avbryt"},{"$i":"homescreen-settings","$v":"Inställningar hemskärm"},{"$i":"change-wallpaper","$v":"Ändra bakgrundsbild"},{"$i":"edit-mode","$v":"Redigera"},{"$i":"edit-done","$v":"Klar"},{"$i":"stop-download-title","$v":["Avbryt ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"Vill du avbryta pågående nedladdning?"},{"$i":"stop-download-action","$v":"Avbryt"},{"$i":"resume-download-title","$v":"Återuppta nedladdning"},{"$i":"resume-download-body","$v":["Vill du hämta ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"Hämta"},{"$i":"edit-group-header","$v":"Redigera grupp"},{"$i":"gaia-grid-stop-download-title","$v":["Avbryt ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"Vill du avbryta pågående nedladdning??"},{"$i":"gaia-grid-stop-download-action","$v":"Avbryt"},{"$i":"gaia-grid-resume-download-title","$v":"Återuppta nedladdning"},{"$i":"gaia-grid-resume-download-body","$v":["Vill du hämta ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"gaia-grid-resume-download-action","$v":"Hämta"},{"$i":"gaia-grid-cancel","$v":"Avbryt"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Expandera grupp"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Minimera grupp"},{"$i":"gaia-grid-enter-group-name","$v":"Ange ett gruppnamn"},{"$i":"gaia-menu-cancel","$v":"Avbryt"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"Arama yap veya adres gir"},{"$i":"delete-title","$v":[{"t":"idOrVar","v":"name"}," uygulamasını sil"]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," ve tüm verileri silinecek."]},{"$i":"delete","$v":"Sil"},{"$i":"cancel","$v":"İptal"},{"$i":"homescreen-settings","$v":"Ana ekran ayarları"},{"$i":"change-wallpaper","$v":"Duvar kâğıdını değiştir"},{"$i":"edit-mode","$v":"Düzenle"},{"$i":"edit-done","$v":"Bitti"},{"$i":"stop-download-title","$v":[{"t":"idOrVar","v":"name"}," indirmesini durdur"]},{"$i":"stop-download-body","$v":"Devam eden indirmeyi durdurmak istiyor musunuz?"},{"$i":"stop-download-action","$v":"Durdur"},{"$i":"resume-download-title","$v":"İndirmeyi yeniden başlat"},{"$i":"resume-download-body","$v":[{"t":"idOrVar","v":"name"}," uygulamasını indirmek istiyor musunuz?"]},{"$i":"resume-download-action","$v":"İndir"},{"$i":"edit-group-header","$v":"Grubu düzenle"},{"$i":"gaia-grid-stop-download-title","$v":[{"t":"idOrVar","v":"name"}," indirmesini durdur"]},{"$i":"gaia-grid-stop-download-body","$v":"Devam eden indirmeyi durdurmak istiyor musunuz?"},{"$i":"gaia-grid-stop-download-action","$v":"Durdur"},{"$i":"gaia-grid-resume-download-title","$v":"İndirmeyi yeniden başlat"},{"$i":"gaia-grid-resume-download-body","$v":[{"t":"idOrVar","v":"name"}," indirilsin mi?"]},{"$i":"gaia-grid-resume-download-action","$v":"İndir"},{"$i":"gaia-grid-cancel","$v":"İptal"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"Grubu genişlet"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"Grubu daralt"},{"$i":"gaia-grid-enter-group-name","$v":"Bir grup adı girin"},{"$i":"gaia-menu-cancel","$v":"İptal"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"搜索或输入网址"},{"$i":"delete-title","$v":["删除“",{"t":"idOrVar","v":"name"},"”"]},{"$i":"delete-body","$v":["“",{"t":"idOrVar","v":"name"},"”及其所有数据将被删除。"]},{"$i":"delete","$v":"删除"},{"$i":"cancel","$v":"取消"},{"$i":"homescreen-settings","$v":"主屏幕设置"},{"$i":"change-wallpaper","$v":"更改壁纸"},{"$i":"edit-mode","$v":"编辑"},{"$i":"edit-done","$v":"完成"},{"$i":"stop-download-title","$v":["停止 ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"您确定要停止正在进行的下载吗?"},{"$i":"stop-download-action","$v":"停止"},{"$i":"resume-download-title","$v":"重新开始下载"},{"$i":"resume-download-body","$v":["你是否想下载 ",{"t":"idOrVar","v":"name"},"?"]},{"$i":"resume-download-action","$v":"下载"},{"$i":"edit-group-header","$v":"编辑分组"},{"$i":"gaia-grid-stop-download-title","$v":["停止 ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"您确定要停止正在进行的下载吗?"},{"$i":"gaia-grid-stop-download-action","$v":"停止"},{"$i":"gaia-grid-resume-download-title","$v":"重新开始下载"},{"$i":"gaia-grid-resume-download-body","$v":["你是否想下载 ",{"t":"idOrVar","v":"name"}," ?"]},{"$i":"gaia-grid-resume-download-action","$v":"下载"},{"$i":"gaia-grid-cancel","$v":"取消"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"展开分组"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"折叠分组"},{"$i":"gaia-grid-enter-group-name","$v":"请输入一个分组名称"},{"$i":"gaia-menu-cancel","$v":"取消"}]

View file

@ -0,0 +1 @@
[{"$i":"search-or-enter-address","placeholder":"搜尋或輸入網址"},{"$i":"delete-title","$v":["刪除 ",{"t":"idOrVar","v":"name"}]},{"$i":"delete-body","$v":[{"t":"idOrVar","v":"name"}," 與其所有資料將會被刪除。"]},{"$i":"delete","$v":"刪除"},{"$i":"cancel","$v":"取消"},{"$i":"homescreen-settings","$v":"主畫面選項"},{"$i":"change-wallpaper","$v":"修改桌面背景"},{"$i":"edit-mode","$v":"編輯"},{"$i":"edit-done","$v":"完成"},{"$i":"stop-download-title","$v":["停止 ",{"t":"idOrVar","v":"name"}]},{"$i":"stop-download-body","$v":"您想要停止正在進行中的下載嗎?"},{"$i":"stop-download-action","$v":"停止"},{"$i":"resume-download-title","$v":"重新開始下載"},{"$i":"resume-download-body","$v":["想要下載 ",{"t":"idOrVar","v":"name"}," 嗎?"]},{"$i":"resume-download-action","$v":"下載"},{"$i":"edit-group-header","$v":"編輯群組"},{"$i":"gaia-grid-stop-download-title","$v":["停止 ",{"t":"idOrVar","v":"name"}]},{"$i":"gaia-grid-stop-download-body","$v":"您想要停止正在進行中的下載嗎?"},{"$i":"gaia-grid-stop-download-action","$v":"停止"},{"$i":"gaia-grid-resume-download-title","$v":"重新開始下載"},{"$i":"gaia-grid-resume-download-body","$v":["想要下載 ",{"t":"idOrVar","v":"name"}," 嗎?"]},{"$i":"gaia-grid-resume-download-action","$v":"下載"},{"$i":"gaia-grid-cancel","$v":"取消"},{"$i":"gaia-grid-toggle-collapsed","ariaLabel":"展開群組"},{"$i":"gaia-grid-toggle-expanded","ariaLabel":"摺疊群組"},{"$i":"gaia-grid-enter-group-name","$v":"輸入群組名稱"},{"$i":"gaia-menu-cancel","$v":"取消"}]

View file

@ -0,0 +1 @@
{"name":"Legacy Home Screen","description":"Gaia Home Screen.","launch_path":"/index.html","type":"certified","role":"homescreen","developer":{"name":"The Gaia Team","url":"https://github.com/mozilla-b2g/gaia"},"permissions":{"themeable":{},"mobileconnection":{},"open-remote-window":{},"webapps-manage":{},"systemXHR":{},"settings":{"access":"readwrite"},"moz-extremely-unstable-and-will-change-webcomponents":{}},"default_locale":"en-US","locales":{"ar":{"name":"الشاشة الرئيسية الواردة","description":"الشاشة الرئيسية لجايا"},"bg":{"name":"Legacy Home Screen","description":"Gaia Home Screen."},"bn-BD":{"name":"লেগ্যাসি হোম স্ক্রিন","description":"গাইয়া হোম স্ক্রিন"},"ca":{"name":"Pantalla d'inici antiga","description":"Pantalla d'inici del Gaia."},"cs":{"name":"Klasická domovská obrazovka","description":"Domovská obrazovka systému Gaia"},"da":{"name":"Ældre startskærm","description":"Gaia startskærm."},"de":{"name":"Startbildschirm","description":"Startbildschirm für Gaia"},"el":{"name":"Αρχική οθόνη","description":"Αρχική οθόνη Gaia"},"en-US":{"name":"Legacy Home Screen","description":"Gaia Home Screen."},"es":{"name":"Pantalla de inicio antigua","description":"Pantalla de inicio de Gaia."},"eu":{"name":"Hasiera-pantaila zaharra","description":"Gaia hasiera-pantaila."},"fr":{"name":"Ancien écran d’accueil","description":"Ancien écran d’accueil de Gaia."},"gl":{"name":"Pantalla inicial predeterminada","description":"Pantalla inicial de Gaia."},"hr":{"name":"Legacy Home Screen","description":"Gaia Home Screen."},"hu":{"name":"Legacy Home Screen","description":"Gaia kezdőképernyő"},"it":{"name":"Schermata principale legacy","description":"Schermata principale Gaia."},"ja":{"name":"従来のホーム画面","description":"Gaia のホーム画面"},"km":{"name":"Legacy Home Screen","description":"Gaia Home Screen."},"ko":{"name":"기존 홈 스크린","description":"Gaia 홈 스크린"},"lt":{"name":"Pradžios ekranas","description":"„Gaia“ pradžios ekranas"},"mk":{"name":"Legacy Home Screen","description":"Gaia Home Screen."},"ms":{"name":"Legacy Home Screen","description":"Gaia Home Screen."},"ne-NP":{"name":"Legacy Home Screen","description":"Gaia Home Screen."},"nl":{"name":"Oude startscherm","description":"Gaia-startscherm"},"pa":{"name":"ਮੁੱਖ ਸਕਰੀਨ","description":"ਗੀਗਾ ਮੁੱਖ ਸਕਰੀਨ"},"pl":{"name":"Ekran główny","description":"Ekran główny Gaia"},"pt-BR":{"name":"Tela inicial","description":"Tela inicial do Gaia"},"ro":{"name":"Legacy Home Screen","description":"Gaia Home Screen."},"ru":{"name":"Старый домашний экран","description":"Домашний экран Gaia"},"sk":{"name":"Úvodná obrazovka","description":"Úvodná obrazovka Gaia"},"sq":{"name":"Kryet e Dikurshme","description":"Kreu i Gaia-s"},"sr-Cyrl":{"name":"Првобитни почетни екран","description":"Gaia почетни екран"},"sr-Latn":{"name":"Prvobitni početni ekran","description":"Gaia početni ekran"},"sv-SE":{"name":"Hemskärm","description":"Gaia hemskärm"},"tr":{"name":"Legacy Home Screen","description":"Gaia Home Screen."},"zh-CN":{"name":"旧版主屏幕","description":"Gaia 主屏幕"},"zh-TW":{"name":"傳統主畫面","description":"Gaia 主畫面。"}},"icons":{"84":"/style/icons/vertical_84.png","126":"/style/icons/vertical_126.png","142":"/style/icons/vertical_142.png","189":"/style/icons/vertical_189.png","284":"/style/icons/vertical_284.png"},"orientation":"default","datastores-access":{"bookmarks_store":{"readonly":false,"description":"Display bookmarks"}},"datastores-owned":{"vertical_preferences_store":{"access":"readwrite","description":"Stores preferences"},"verticalhome_items_migration":{"access":"readwrite","description":"Stores grid item configuration"}},"connections":{"verticalhome-migrate":{"handler_path":"/index.html","description":"Exports settings and switches home screen","rules":{"minimumAccessLevel":"certified"}}},"origin":"app://verticalhome.gaiamobile.org","version":"2.5"}

View file

@ -0,0 +1 @@
;window.COMPONENTS_BASE_URL='/shared/elements/';

File diff suppressed because it is too large Load diff

View file

@ -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;
}

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30"><path fill="#667174" fill-opacity=".7" d="m 18.2995,19.66 -5.056,-5.057 5.056,-5.056 c -0.31,-0.516 -0.62,-1.032 -0.93,-1.34 l -5.672,5.673 v 1.652 l 5.675,5.676 c 0.31,-0.515 0.722,-0.928 0.93,-1.547 z"/></svg>

After

Width:  |  Height:  |  Size: 294 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"><path fill="#667174" fill-opacity=".7" d="M11.8,19.9l4.9-4.9l-4.9-4.9c0.3-0.5,0.6-1,0.9-1.3l5.5,5.5c0,0.3,0,0.5,0,0.8c0,0.3,0,0.5,0,0.8l-5.5,5.5 C12.4,20.9,12,20.5,11.8,19.9z"/></svg>

After

Width:  |  Height:  |  Size: 243 B

View file

@ -0,0 +1,18 @@
'use strict';
/* global ComponentUtils */
window.GaiaButtons = (function(win) {
// Extend from the HTMLElement prototype
var proto = Object.create(HTMLElement.prototype);
// Allow baseurl to be overridden (used for demo page)
var baseurl = window.GaiaButtonsBaseurl ||
'/shared/elements/gaia_buttons/';
proto.createdCallback = function() {
ComponentUtils.style.call(this, baseurl);
};
// Register and return the constructor
return document.registerElement('gaia-buttons', { prototype: proto });
})(window);

View file

@ -0,0 +1,281 @@
/* ---------------------------------------
* gaia-buttons:
* Container for buttons e.g:
* action menu, confirm, edit mode, FTU
* --------------------------------------- */
gaia-buttons {
display: flex;
justify-content: center;
align-items: center;
height: 7rem;
box-sizing: border-box;
pointer-events: auto;
}
gaia-buttons:not(.inline) {
position: absolute;
left: 0;
right: 0;
bottom: 0;
z-index: 10;
border-top: 0.1rem solid #e7e7e7;
padding: 0;
background-color: #f4f4f4;
}
/* this 'end' padding must match the buttons 'start' margin */
gaia-buttons:not(.inline):-moz-dir(ltr) { padding-right: 1.5rem; }
gaia-buttons:not(.inline):-moz-dir(rtl) { padding-left: 1.5rem; }
gaia-buttons.inline a,
gaia-buttons.inline button {
margin: 0;
}
button::-moz-focus-inner {
border: none;
outline: none;
}
a,
button {
position: relative;
font-family: sans-serif;
font-style: italic;
width: 100%;
height: 4rem;
margin: 0;
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-decoration: none;
outline: none;
}
:-moz-dir(ltr) a,
:-moz-dir(ltr) button {
margin-left: 1.5rem;
}
:-moz-dir(rtl) a,
:-moz-dir(rtl) button {
margin-right: 1.5rem;
}
/* Recommend */
a.recommend,
button.recommend {
background-color: #00caf2;
color: #fff;
}
/* Danger */
a.danger,
button.danger {
background-color: #e51e1e;
color: #fff;
}
/* Pressed */
a:active,
button:active {
background-color: #b2f2ff;
color: #fff;
}
a::-moz-selection,
button::-moz-selection {
background-color: transparent;
}
/* Disabled */
a[aria-disabled="true"],
button[disabled] {
background-color: rgba(0,0,0,0.05);
color: #c7c7c7;
pointer-events: auto;
}
a[aria-disabled="true"].recommend,
button[disabled].recommend {
background-color: #97cbd5;
color: rgba(255,255,255,0.5);
}
a[aria-disabled="true"].danger,
button[disabled].danger {
background-color: #eb7474;
color: rgba(255,255,255,0.5);
}
a[aria-disabled="true"]::-moz-selection,
button[disabled]::-moz-selection {
-moz-user-select: none;
}
/* Hidden */
[hidden] {
visibility: hidden;
}
/* Icons */
a.icon,
button.icon {
position: relative;
}
a.icon:before,
button.icon:before {
content: "";
width: 3rem;
height: 3rem;
position: absolute;
top: 50%;
margin-top: -1.5rem;
background: transparent no-repeat center center / 100% auto;
}
:-moz-dir(ltr) a.icon:before,
:-moz-dir(ltr) button.icon:before { right: 0.5rem; }
:-moz-dir(rtl) a.icon:before,
:-moz-dir(rtl) button.icon:before { left: 0.5rem; }
a.icon-next:before,
button.icon-next:before {
background-size: 3rem;
}
:-moz-dir(ltr) a.icon-next:before,
:-moz-dir(ltr) button.icon-next:before {
background-image: url(images/right-light.svg);
}
:-moz-dir(rtl) a.icon-next:before,
:-moz-dir(rtl) button.icon-next:before {
background-image: url(images/left-light.svg);
}
a.icon-previous:before,
button.icon-previous:before {
background-size: 3rem;
}
:-moz-dir(ltr) a.icon-previous:before,
:-moz-dir(ltr) button.icon-previous:before {
left: 0.5rem;
background-image: url(images/left-light.svg);
}
:-moz-dir(rtl) a.icon-previous:before,
:-moz-dir(rtl) button.icon-previous:before {
right: 0.5rem;
background-image: url(images/right-light.svg);
}
/* -----------------------------------------------------------------
SKIN: dark
----------------------------------------------------------------- */
gaia-buttons[skin="dark"] {
background: #4d4d4d;
border: none;
}
/* Pressed */
[skin="dark"] a:active,
[skin="dark"] button:active {
background-color: #00aacc;
}
/* Disabled */
[skin="dark"] a[aria-disabled="true"],
[skin="dark"] button[disabled] {
background-color: #565656;
color: rgba(255,255,255,0.4);
}
[skin="dark"] a[aria-disabled="true"].recommend,
[skin="dark"] button[disabled].recommend {
background-color: #006579;
}
[skin="dark"] a[aria-disabled="true"].danger,
[skin="dark"] button[disabled].danger {
background-color: #730f0f;
}
/* -----------------------------------------------------------------
Transitions
----------------------------------------------------------------- */
[transition] {
display: flex;
transition: visibility var(--transition-duration);
}
[transition][hidden] {
pointer-events: none;
}
[transition="slide"] {
transform: translateY(0);
transition: transform var(--transition-duration) ease,
visibility var(--transition-duration);
}
[transition="slide"][hidden] {
transform: translateY(100%);
}
[transition="fade"] {
opacity: 1;
transition: opacity var(--transition-duration) ease,
visibility var(--transition-duration);
}
[transition="fade"][hidden] {
opacity: 0;
}
/* -----------------------------------------------------------------
RESPONSIVE: tablet
----------------------------------------------------------------- */
@media (min-width: 768px) {
gaia-buttons {
height: 10rem;
}
gaia-buttons:not(.inline) {
border-top-width: 0.2rem;
}
/* this 'end' padding must match the buttons 'start' margin */
gaia-buttons:not(.inline):-moz-dir(ltr) { padding-right: 3rem; }
gaia-buttons:not(.inline):-moz-dir(rtl) { padding-left: 3rem; }
a,
button {
font-size: 2rem;
height: 5rem;
line-height: 5rem;
border-radius: 2.5rem;
max-width: 40rem;
}
:-moz-dir(ltr) a,
:-moz-dir(ltr) button {
margin-left: 3rem;
}
:-moz-dir(rtl) a,
:-moz-dir(rtl) button {
margin-right: 3rem;
}
}

View file

@ -0,0 +1,72 @@
'use strict';
/* global ComponentUtils */
/**
* The gaia-confirm component displays a dialog in which the user has a
* choice to confirm or cancel the action. It may be displayed along with a
* title, description, and image. Buttons may also be configured.
* @requires GaiaButtons
*/
window.GaiaConfirm = (function(win) {
// Extend from the HTMLElement prototype
var proto = Object.create(HTMLElement.prototype);
// Allow baseurl to be overridden (used for demo page)
var baseurl = window.GaiaConfirmBaseurl ||
'/shared/elements/gaia_confirm/';
/**
preventDefault and prevent other listeners from hearing abut changes to a
particular event object.
@param {Array[Element]|Null} unless a list of elements to allow events to hit.
@param {Event} event triggered by addEventListener, etc...
*/
function eatEvent(unless, event) {
// prevent handlers from everything else unless the target is on the list.
if (unless && unless.indexOf(event.target) !== -1) {
return;
}
event.preventDefault();
event.stopImmediatePropagation();
}
proto.createdCallback = function() {
var shadow = this.createShadowRoot();
this._template = template.content.cloneNode(true);
shadow.appendChild(this._template);
ComponentUtils.style.call(this, baseurl);
var confirm = this.querySelector('gaia-buttons .confirm');
var cancel = this.querySelector('gaia-buttons .cancel');
if (confirm) {
confirm.addEventListener('click', (e) => {
eatEvent(null, e);
this.dispatchEvent(new CustomEvent('confirm'));
});
}
if (cancel) {
cancel.addEventListener('click', (e) => {
eatEvent(null, e);
this.dispatchEvent(new CustomEvent('cancel'));
});
}
};
var template = document.createElement('template');
template.innerHTML = `<form role="dialog" class="confirm">
<section>
<content select="h1"></content>
<content select="p"></content>
</section>
<content select="gaia-buttons">
</content>
</form>`;
// Register and return the constructor
return document.registerElement('gaia-confirm', { prototype: proto });
})(window);

View file

@ -0,0 +1,155 @@
/* ----------------------------------
* Confirm
* ---------------------------------- */
/* Main dialog setup */
gaia-confirm {
background: #2d2d2d;
overflow: hidden;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
padding-bottom: 7rem;
font-size: 0;
text-align: start;
/* 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;
display: flex;
align-items: stretch;
flex-direction: column;
justify-content: center;
transition: transform ease-in-out 0.3s, visibility 0.3s;
/**
magic number ideally to place confirm dialogs on top.
*/
z-index: 2147483646;
}
gaia-confirm[hidden] {
transform: translateY(100%);
visibility: hidden;
pointer-events: none;
}
.confirm section {
height: 100%;
font-weight: 300;
font-size: 2.2rem;
color: #FAFAFA;
padding: 0 1.5rem;
box-sizing: padding-box;
width: 100%;
display: inline-block;
max-height: 100%;
vertical-align: middle;
white-space: normal;
}
h1 {
font-weight: normal;
font-size: 1.6rem;
line-height: 1.5em;
color: #fff;
margin: 0;
padding: 1rem 1.5rem 0;
overflow: hidden;
max-height: 7rem;
word-wrap: break-word;
}
/* Specific component code */
p {
word-wrap: break-word;
margin: 1rem 0 0;
padding: 1rem 1.5rem;
border-top: 0.1rem solid #686868;
line-height: 3rem;
}
p img {
margin-inline-end: 2rem;
}
p img:-moz-dir(ltr) { float: left; }
p img:-moz-dir(rtl) { float: right; }
p strong {
font-weight: 300;
}
p small {
font-size: 1.4rem;
font-weight: normal;
color: #cbcbcb;
display: block;
}
dl {
border-top: 0.1rem solid #686868;
margin: 1rem 0 0;
overflow: hidden;
padding-top: 1rem;
font-size: 1.6rem;
line-height: 2.2rem;
}
dl > dt {
clear: both;
width: 7rem;
padding-inline-start: 1.5rem;
font-weight: 500;
text-align: start;
}
dl > dt:-moz-dir(ltr) { float: left; }
dl > dt:-moz-dir(rtl) { float: right; }
dl > dd {
padding-inline-end: 1.5rem;
font-weight: 300;
text-overflow: ellipsis;
vertical-align: top;
overflow: hidden;
}
figure {
margin: 1.5rem;
display: flex;
align-items: center;
}
figure img {
padding-inline-end: 1.5rem;
flex-shrink: 0;
}
figure figcaption {
font-size: 2.1rem;
font-weight: 300;
}
ul {
margin: 0;
padding: 2rem 1.5rem;
border-top: 0.1rem solid #686868;
list-style: none;
font-size: 1.6rem;
font-weight: normal;
}
ul li {
word-wrap: break-word;
line-height: 2rem;
padding-bottom: 1.5rem;
}
ul li:last-child {
padding-bottom: 0;
}
ul li ul {
border: none;
margin: 0;
padding: 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,844 @@
'use strict';
/* global devicePixelRatio */
/* global GaiaGrid */
(function(exports) {
const ACTIVE_SCALE = 1.4;
/* This is an alternative delay used to initiate icon movement when in edit
* mode. The normal contextmenu delay is too long once we're in edit mode
* and causes user confusion, but a short delay globally would cause too many
* accidental triggers of edit mode.
*/
const EDIT_LONG_PRESS_DELAY = 200;
/* The movement threshold to use for the above synthetic long-press. */
const EDIT_LONG_PRESS_THRESHOLD = 4 * devicePixelRatio;
/* This delay is the time passed once users stop the finger over an icon and
* the rearrange is performed */
const REARRANGE_DELAY = 30;
/* The page is scrolled via javascript if an icon is being moved, and is
* within a length of a page edge configured by this value */
const EDGE_PAGE_THRESHOLD = 50;
/* This is the delay before calling finish when handling touchend. */
const TOUCH_END_FINISH_DELAY = 20;
/* The maximum frequency with which the grid will be rearranged in response
* to the item position changing, in ms.
*/
const REARRANGE_FREQUENCY = 100;
/* The amount of cool-down time after a rearrange animation. To avoid
* rearranging too frequently and causing jank and user confusion.
*/
const REARRANGE_COOLDOWN = 750;
const SCREEN_HEIGHT = window.innerHeight;
const scrollStep = Math.round(SCREEN_HEIGHT / EDGE_PAGE_THRESHOLD);
/* The scroll step will be 5 times bigger over the edge */
const maxScrollStepFactor = 5;
function DragDrop(gridView) {
this.gridView = gridView;
this.container = gridView.element;
this.scrollable = document.documentElement;
this.container.addEventListener('touchstart', this);
this.container.addEventListener('touchmove', this);
this.container.addEventListener('touchend', this);
window.addEventListener('touchcancel', this);
this.container.addEventListener('click', this);
this.container.addEventListener('contextmenu', this);
}
DragDrop.prototype = {
/**
* The current touchmove target.
* @type {DomElement}
*/
target: null,
/**
* The edit-mode long-press timeout
*/
longPressTimeout: null,
/**
* The position of the first touchstart of the current event block
*/
touchStart: { x: 0, y: 0, screenX: 0, screenY: 0 },
/**
* If we have moved an icon, this indicates that we need to save the state
* @type {boolean}
*/
dirty: false,
/**
* Whether or not we are in edit mode.
* @type {boolean}
*/
inEditMode: false,
/**
* The item being hovered over.
* @type {GaiaGrid.GridItem}
*/
hoverItem: null,
/**
* The group being hovered over.
* @type {GaiaGrid.Group}
*/
hoverGroup: null,
/*
* An element that's aligned to the top of the grid and should be
* considered as obscuring the grid when in edit mode.
*/
editHeaderElement: null,
/**
* The timeout used to rearrange the grid during dragging.
*/
rearrangeGridTimeout: null,
/**
* The time of the last reposition call.
*/
lastRepositionTime: 0,
/**
* Returns the maximum active scale value.
*/
get activeScale() {
return ACTIVE_SCALE;
},
/**
* Returns true if we are currently dragging an icon.
*/
get inDragAction() {
return this.target && this.target.classList.contains('active');
},
/**
* Returns the delay before calling finish in response to a touch-end event.
*/
get touchEndFinishDelay() {
return TOUCH_END_FINISH_DELAY;
},
/**
* Begins the drag/drop interaction.
* Enlarges the icon.
* Sets additional data to make the touchmove handler faster.
*/
begin: function(e) {
// Stop icon launching while we are in active state
this.gridView.stop();
window.dispatchEvent(new CustomEvent('gaiagrid-dragdrop-begin'));
this.hoverItem = null;
this.rearrangeDelay = null;
this.doRearrange = null;
this.enterEditMode();
this.container.classList.add('dragging');
this.icon.scale = ACTIVE_SCALE;
this.icon.setActive(true);
this.container.parentNode.style.overflow = 'hidden';
// Work around e.pageX/e.pageY being null (to make it easier to work with
// injected events, or old versions of Marionette)
this.initialPageX = (typeof e.pageX === 'undefined') ?
this.icon.x : e.pageX;
this.initialPageY = (typeof e.pageY === 'undefined') ?
this.icon.y : e.pageY;
this.currentTouch = {
pageX: this.initialPageX,
pageY: this.initialPageY
};
var items = this.gridView.items;
var lastElement = items[items.length - 1];
this.maxScroll = lastElement.y + lastElement.pixelHeight +
(this.icon.pixelHeight * ACTIVE_SCALE);
// If this is a group, or the sole icon in a group, make sure the
// surrounding groups are marked as invalid-drop so you can't initiate a
// move that would have no result.
var itemIndex = this.icon.detail.index;
if (this.icon.detail.type === 'divider') {
this.icon.element.classList.add('invalid-drop');
if (itemIndex > 0) {
for (var i = itemIndex - 1; i >= 0; i--) {
var item = items[i];
if (item.detail.type === 'divider') {
item.element.classList.add('invalid-drop');
break;
}
}
}
} else {
var itemBefore = itemIndex ? items[itemIndex - 1] : null;
var itemAfter = items[itemIndex + 1];
if ((itemAfter.detail.type === 'placeholder' ||
itemAfter.detail.type === 'divider') &&
(!itemBefore || itemBefore.detail.type === 'divider')) {
if (itemBefore) {
itemBefore.element.classList.add('invalid-drop');
}
var group, groupIndex = itemIndex;
do {
group = items[++groupIndex];
} while (group.detail.type !== 'divider');
group.element.classList.add('invalid-drop');
}
}
// Redraw the icon at the new position and scale
this.updateIconPosition();
// Rearrange grid to highlight the group underneath the icon
this.rearrangeGrid();
},
finish: function() {
// Complete the repositioning timeout
if (this.rearrangeGridTimeout !== null) {
this.rearrangeGrid();
}
// Remove the dragging property after the icon has transitioned into
// place to avoid jank due to animations starting that are disabled
// when dragging.
this.icon.element.addEventListener('transitionend', this);
this.currentTouch = null;
if (this.doRearrange !== null) {
if (this.rearrangeDelay) {
clearTimeout(this.rearrangeDelay);
}
this.doRearrange.call(this);
} else {
this.icon.requestAttention();
}
// Hand back responsibility to Grid view to render the dragged item.
this.icon.scale = 1;
this.icon.setActive(false);
this.icon.element.classList.remove('hovering');
this.target = null;
this.gridView.render();
// Save icon state if we need to
if (this.dirty) {
window.dispatchEvent(new CustomEvent('gaiagrid-saveitems'));
}
this.dirty = false;
setTimeout(function nextTick() {
this.gridView.start();
window.dispatchEvent(new CustomEvent('gaiagrid-dragdrop-finish'));
}.bind(this));
},
finalize: function() {
this.container.parentNode.style.overflow = '';
this.container.classList.remove('dragging');
this.container.classList.remove('hover-over-top');
if (this.icon) {
this.icon.element.removeEventListener('transitionend', this);
this.icon = null;
}
if (this.hoverItem) {
this.hoverItem.element.classList.remove('hovered');
this.hoverItem = null;
}
if (this.hoverGroup) {
this.hoverGroup.element.classList.remove('drop-target');
this.hoverGroup = null;
}
for (var i = 0, iLen = this.gridView.items.length;
i < iLen; i++) {
var item = this.gridView.items[i];
item.element.classList.remove('invalid-drop');
}
},
/**
* The closer to edge the faster (bigger step).
** Distance 0px -> 5 times faster
** Distance 25px -> 2.5 times faster
** Distance 50px (EDGE_PAGE_THRESHOLD) -> 0 times
*/
getScrollStep: function(distanceToEdge) {
var factor = maxScrollStepFactor;
if (distanceToEdge > 0) {
factor *= ((EDGE_PAGE_THRESHOLD - distanceToEdge) /
EDGE_PAGE_THRESHOLD);
}
return Math.round(scrollStep * factor);
},
/**
* Positions the dragged icon, rearranges the grid and scrolls the page if
* needed.
* The page is scrolled via javascript if an icon is being moved,
* and is within a percentage of a page edge.
*/
positionAndScrollIfNeeded: function() {
var touch = this.currentTouch;
if (!touch || !this.inDragAction) {
this.isScrolling = false;
return;
}
var scrollStep;
var docScroll = this.scrollable.scrollTop;
var distanceFromTop = Math.abs(touch.pageY - docScroll);
var distanceFromHeader = distanceFromTop -
(this.editHeaderElement ? this.editHeaderElement.clientHeight : 0);
this.isScrolling = true;
if (distanceFromTop > SCREEN_HEIGHT - EDGE_PAGE_THRESHOLD) {
var maxY = this.maxScroll;
scrollStep = this.getScrollStep(SCREEN_HEIGHT - distanceFromTop);
// We cannot exceed the maximum scroll value
if (touch.pageY >= maxY || maxY - touch.pageY < scrollStep) {
this.isScrolling = false;
}
} else if (touch.pageY > 0 && distanceFromHeader < EDGE_PAGE_THRESHOLD) {
// We cannot go below the minimum scroll value
scrollStep = -this.getScrollStep(distanceFromHeader);
scrollStep = Math.max(scrollStep, -this.scrollable.scrollTop);
if (scrollStep >= 0) {
this.isScrolling = false;
}
} else {
this.isScrolling = false;
}
if (!this.isScrolling) {
this.updateIconPosition();
this.deferredRearrangeGrid();
return;
}
this.updateIconPosition();
this.scrollable.scrollTop += scrollStep;
touch.pageY += scrollStep;
exports.requestAnimationFrame(this.positionAndScrollIfNeeded.bind(this));
},
/**
* Highlights the group of the given icon index, or the group if the index
* belongs to a group.
* @param {Integer} index The grid index of the icon or group.
*/
highlightGroup: function(index) {
for (var i = index, iLen = this.gridView.items.length;
i < iLen; i++) {
var item = this.gridView.items[i];
if (item.detail.type === 'divider') {
if (this.hoverGroup != item) {
if (this.hoverGroup) {
this.hoverGroup.element.classList.remove('drop-target');
}
this.hoverGroup = item;
item.element.classList.add('drop-target');
}
break;
}
}
},
inFirstGroup: function(index) {
for (var i = index; i >= 0; i--) {
if (this.gridView.items[i].detail.type === 'divider') {
return false;
}
}
return true;
},
/**
* Positions an icon on the grid using the current touch coordinates.
*/
updateIconPosition: function() {
var oldX = this.icon.x;
var oldY = this.icon.y;
var newX = this.currentTouch.pageX - (this.initialPageX - this.icon.x);
var newY = this.currentTouch.pageY - (this.initialPageY - this.icon.y);
// Adjust new icon coordinates for the slightly inflated scale so that
// it appears centered around the touch point. Dividers aren't scaled
// during dragging.
if (this.icon.detail.type !== 'divider') {
newX = newX - ((this.icon.scale * this.gridView.layout.gridItemWidth) -
this.gridView.layout.gridItemWidth) / 2;
newY = newY - ((this.icon.scale * this.icon.pixelHeight) -
this.icon.pixelHeight) / 2;
}
this.icon.setCoordinates(newX, newY);
this.icon.render();
this.icon.setCoordinates(oldX, oldY);
},
/**
* Will call rearrangeGrid after a short period, calculated based on how
* recently the grid was last rearranged.
*/
deferredRearrangeGrid: function() {
if (this.rearrangeGridTimeout !== null) {
return;
}
var delay = Math.max(
REARRANGE_FREQUENCY, REARRANGE_COOLDOWN -
Math.max(0, Date.now() - this.lastRepositionTime));
this.rearrangeGridTimeout = setTimeout(() => {
this.rearrangeGridTimeout = null;
this.rearrangeGrid();
}, delay);
},
/**
* Rearranges the grid icons and groups based on the current position of
* the dragged icon.
*/
rearrangeGrid: function() {
if (this.rearrangeGridTimeout !== null) {
clearTimeout(this.rearrangeGridTimeout);
this.rearrangeGridTimeout = null;
}
if (this.isScrolling) {
// We don't want the grid to shift while we're auto-scrolling
return;
}
var iconIsDivider = this.icon.detail.type === 'divider';
var pageX = this.currentTouch.pageX - (this.initialPageX - this.icon.x);
var pageY = this.currentTouch.pageY - (this.initialPageY - this.icon.y);
// Reposition in the icons array if necessary.
// Find the icon with the closest X/Y position of the move,
// and insert ours before it.
var foundIndex = 0;
var insertDividerAtTop = !this.gridView.config.features.disableSections;
pageX += this.gridView.layout.gridItemWidth / 2;
pageY += this.icon.pixelHeight / 2;
if (pageY >= 0) {
foundIndex =
this.gridView.getNearestItemIndex(pageX, pageY, iconIsDivider);
// If we're dragging a group over the first icon, a divider will
// be inserted at the top.
if (!(iconIsDivider && foundIndex === 0)) {
this.container.classList.remove('hover-over-top');
insertDividerAtTop = false;
}
}
// Clear the rearrange callback and hover item if we aren't hovering over
// anything.
this.doRearrange = null;
if (this.rearrangeDelay) {
clearTimeout(this.rearrangeDelay);
this.rearrangeDelay = null;
}
if (this.hoverItem) {
this.hoverItem.element.classList.remove('hovered');
this.hoverItem = null;
}
// Add the 'hovering' class to the dragged icon.
if (foundIndex !== null) {
this.icon.element.classList.add('hovering');
} else {
this.icon.element.classList.remove('hovering');
}
// Nothing to do if we find the dragged icon or no icon
if (!insertDividerAtTop &&
(foundIndex === null || foundIndex === this.icon.detail.index)) {
if (!iconIsDivider) {
this.highlightGroup(this.icon.detail.index);
}
return;
}
var foundItem = this.gridView.items[foundIndex];
// If we're a divider being dragged, only allow dropping on either the
// first item or another divider.
if (iconIsDivider &&
foundIndex > 0 &&
foundItem.detail.type !== 'divider') {
// Remove the hovering class from a group if it's not hovering over
// a valid drop position or itself.
this.icon.element.classList.remove('hovering');
return;
}
// If the item isn't a group, trigger the
// hovered state on the found item.
if (!insertDividerAtTop && !iconIsDivider) {
this.hoverItem = foundItem;
this.hoverItem.element.classList.add('hovered');
}
// Delay rearranging when we're dragging groups to when they're dropped
var rearrangeAfterDelay = !iconIsDivider;
// Determine if we want to create a new divider. We do this when hovering
// over a divider with an icon, or when dragging an icon to the very top
// of the grid.
var createDivider = insertDividerAtTop;
if (!insertDividerAtTop && !iconIsDivider &&
(foundItem.detail.type === 'divider')) {
// Allow dropping into a collapsed group if the new position is in
// the top 2/3 of the group.
if (foundItem.detail.collapsed &&
pageY <= foundItem.y + (foundItem.pixelHeight * 2/3)) {
rearrangeAfterDelay = false;
foundItem.element.classList.remove('hovered');
// When dragging an item forwards, it gets placed after the found
// item, adjust to the item before the divider.
if (this.icon.detail.index < foundIndex) {
foundItem = this.gridView.items[foundIndex - 1];
}
} else {
createDivider = true;
}
}
if (createDivider) {
// Remove the group background highlight if we're between groups
if (this.hoverGroup) {
this.hoverGroup.element.classList.remove('drop-target');
this.hoverGroup = null;
}
// Cancel rearrangement if it would have no effect.
var redundantRearrange = false;
if (insertDividerAtTop) {
if (iconIsDivider) {
redundantRearrange = this.inFirstGroup(this.icon.detail.index - 1);
} else {
redundantRearrange =
(this.icon.detail.index === 0 &&
this.gridView.items[1].detail.type === 'placeholder');
}
} else {
redundantRearrange = this.gridView.items[foundIndex].element.
classList.contains('invalid-drop');
}
if (redundantRearrange) {
if (this.hoverItem) {
this.hoverItem.element.classList.remove('hovered');
this.hoverItem = null;
}
return;
} else if (insertDividerAtTop) {
this.container.classList.add('hover-over-top');
}
this.doRearrange =
this.createNewDivider.bind(this,
insertDividerAtTop ? null : foundItem);
} else {
if (!iconIsDivider) {
// Change the display of the group the icon is hovering over to
// indicate it can be dropped.
this.highlightGroup(foundIndex);
}
this.doRearrange = this.rearrange.bind(this, foundItem);
if (rearrangeAfterDelay) {
this.rearrangeDelay =
setTimeout(this.doRearrange.bind(this), REARRANGE_DELAY);
}
}
},
/**
* Creates a new divider in GridView.items and rearranges the currently
* dragged icon into the newly created section.
* @param {Object} tDivider The divider after which to place a new divider,
* or null to insert a divider at the beginning on the grid.
*/
createNewDivider: function(tDivider) {
var items = this.gridView.items;
var tIndex = tDivider ? items.indexOf(tDivider) + 1 : 0;
// Create the new divider
var newDivider = new GaiaGrid.Divider();
items.splice(tIndex, 0, newDivider);
// Place the dragged item into the new empty section
var sIndex = items.indexOf(this.icon);
this.rearrange(sIndex >= tIndex ? newDivider : tDivider);
// Make sure the new divider/group is in view
newDivider.requestAttention();
},
/**
* Rearranges items in GridView.items
* @param {Object} tItem The item to position the dragged icon at.
*/
rearrange: function(tItem) {
// Clear the rearrange callback
this.doRearrange = null;
this.rearrangeDelay = null;
// We get a reference to the position of this.icon within the items
// array. Because placeholders are shifting around while we are dragging,
// we can't trust the detail.index attribute. This will be fixed on every
// render call though.
var sIndex = this.gridView.items.indexOf(this.icon);
var tIndex = this.gridView.items.indexOf(tItem);
// Check how many items we need to rearrange (if it's a group, there will
// be multiple items.
var eIndex = sIndex;
if (this.icon.detail.type === 'divider') {
for (; sIndex > 0 &&
this.gridView.items[sIndex - 1].detail.type !== 'divider';
sIndex--) {}
// Modify the tIndex to make sure we're inserting immediately after
// another divider or at the start of the container.
if (this.gridView.items[tIndex].detail.type === 'divider') {
tIndex++;
} else {
tIndex = 0;
}
if (sIndex === tIndex) {
// Nothing to do.
return;
}
} else if (sIndex < tIndex) {
tIndex++;
}
// We may have changed tIndex, so refresh our item pointer
tItem = this.gridView.items[tIndex];
// Remove the items from the array
var lastItemOffset = eIndex - sIndex;
var toInsert = this.gridView.items.splice(sIndex, lastItemOffset + 1);
// Craft the parameter list to reinsert the items at the correct place
toInsert.unshift(tItem ? this.gridView.items.indexOf(tItem) :
this.gridView.items.length, 0);
// Reinsert items
this.rearrangeDelay = null;
this.dirty = true;
this.gridView.items.splice.apply(this.gridView.items, toInsert);
var oldX = this.icon.x;
var oldY = this.icon.y;
this.gridView.render();
// In this case, we don't want to compensate for the icon moving, so
// we need to correct our initial values to stop the icon from jumping
// after rearranging.
this.initialPageX -= oldX - this.icon.x;
this.initialPageY -= oldY - this.icon.y;
this.lastRepositionTime = Date.now();
},
enterEditMode: function() {
this.inEditMode = true;
this.container.classList.add('edit-mode');
document.body.classList.add('edit-mode');
this.gridView.element.dispatchEvent(
new CustomEvent('editmode-start'));
document.addEventListener('visibilitychange', this);
this.gridView.render();
},
exitEditMode: function() {
// If we're in the middle of a drag, cancel it.
if (this.icon) {
this.finish();
this.finalize();
}
this.inEditMode = false;
this.cancelLongPressTimeout();
this.container.classList.remove('edit-mode');
document.body.classList.remove('edit-mode');
this.gridView.element.dispatchEvent(new CustomEvent('editmode-end'));
document.removeEventListener('visibilitychange', this);
this.gridView.render();
},
cancelLongPressTimeout: function() {
if (this.longPressTimeout !== null) {
clearTimeout(this.longPressTimeout);
this.longPressTimeout = null;
}
},
inLongPressThreshold: function(x, y) {
return (
Math.abs(x - this.touchStart.screenX) < EDIT_LONG_PRESS_THRESHOLD &&
Math.abs(y - this.touchStart.screenY) < EDIT_LONG_PRESS_THRESHOLD);
},
/**
* General event handler.
*/
handleEvent: function(e) {
switch(e.type) {
case 'visibilitychange':
if (document.hidden) {
this.exitEditMode();
}
break;
case 'touchstart':
this.cancelLongPressTimeout();
if (e.touches.length > 1) {
if (this.inDragAction) {
this.finish();
}
return;
}
if (this.inEditMode && !this.icon) {
this.touchStart.x = e.touches[0].pageX;
this.touchStart.y = e.touches[0].pageY;
this.touchStart.screenX = e.touches[0].screenX;
this.touchStart.screenY = e.touches[0].screenY;
this.longPressTimeout = setTimeout(() => {
this.longPressTimeout = null;
this.handleEvent({
type: 'contextmenu',
target: e.target,
pageX: this.touchStart.x,
pageY: this.touchStart.y,
preventDefault: function() {},
stopImmediatePropagation: function() {}
});
}, EDIT_LONG_PRESS_DELAY);
}
break;
case 'contextmenu':
this.cancelLongPressTimeout();
if (this.icon) {
e.stopImmediatePropagation();
e.preventDefault();
return;
}
if (e.defaultPrevented) {
// other handlers already handled this.
// in the future, we should use the shadow root and dispatch a
// "contextmenu" event from here instead.
return;
}
if (!e.target) {
return;
}
this.icon = this.gridView.findItemFromElement(e.target, true);
if (!this.icon || !this.icon.element || !this.icon.isDraggable() ||
this.icon.detail.type === 'placeholder') {
this.icon = null;
return;
}
e.stopImmediatePropagation();
e.preventDefault();
this.target = this.icon.element;
this.begin(e);
break;
case 'touchmove':
var touch = e.touches[0];
if (this.inDragAction) {
this.currentTouch = {
pageX: touch.pageX,
pageY: touch.pageY
};
if (!this.isScrolling) {
this.positionAndScrollIfNeeded();
}
} else if (this.longPressTimeout !== null &&
!this.inLongPressThreshold(touch.screenX,
touch.screenY)) {
this.cancelLongPressTimeout();
}
break;
case 'click':
case 'touchcancel':
if (this.inDragAction) {
this.finish();
this.finalize();
}
this.cancelLongPressTimeout();
break;
case 'touchend':
if (this.inDragAction) {
// Ensure the app is not launched
e.stopImmediatePropagation();
e.preventDefault();
// As contextmenu event can be synthesized, it's possible for it
// to happen in the same event-loop as touchend, meaning
// finish would be called immediately after begin. This would
// mean that the icon doesn't get a chance to transition and
// the transitionend that we expect won't be called, so finalize
// also won't be called, leaving us in an inconsistent state.
// It would be so great if there was a transitionstart event :(
setTimeout(() => { this.finish(); }, TOUCH_END_FINISH_DELAY);
}
this.cancelLongPressTimeout();
break;
case 'transitionend':
this.finalize();
break;
}
}
};
exports.GridDragDrop = DragDrop;
}(window));

View file

@ -0,0 +1,3 @@
;'use strict';(function(exports){const SHADOW_BLUR=1;const SHADOW_OFFSET_Y=1;const SHADOW_OFFSET_X=1;const SHADOW_COLOR='rgba(0, 0, 0, 0.2)';const DEFAULT_BACKGROUND_COLOR='rgb(228, 234, 238)';const UNSCALED_CANVAS_PADDING=2;const CANVAS_PADDING=UNSCALED_CANVAS_PADDING*devicePixelRatio;function IconRenderer(icon){this._icon=icon;}
IconRenderer.TYPE={CLIP:'clip',FAVICON:'favicon',STANDARD:'standard',};IconRenderer.prototype={unscaledCanvasPadding:UNSCALED_CANVAS_PADDING*2,get _maxSize(){return this._icon.grid.layout.gridMaxIconSize;},_createCanvas:function(){const CANVAS_PADDING_BOTTOM=1*devicePixelRatio;var canvas=document.createElement('canvas');canvas.width=this._maxSize+(CANVAS_PADDING*2);canvas.height=this._maxSize+CANVAS_PADDING+CANVAS_PADDING_BOTTOM;return canvas;},_createClipCanvas:function(){var canvas=document.createElement('canvas');canvas.width=this._maxSize+(CANVAS_PADDING*2);canvas.height=this._maxSize+(CANVAS_PADDING*2);return canvas;},_decorateShadowCanvas:function(canvas){var ctx=canvas.getContext('2d',{willReadFrequently:true});ctx.shadowColor=SHADOW_COLOR;ctx.shadowBlur=SHADOW_BLUR;ctx.shadowOffsetY=SHADOW_OFFSET_Y;ctx.shadowOffsetX=SHADOW_OFFSET_X;return ctx;},clip:function(img){return new Promise((resolve)=>{var shadowCanvas=this._createCanvas();var shadowCtx=this._decorateShadowCanvas(shadowCanvas);var clipCanvas=this._createClipCanvas();var clipCtx=clipCanvas.getContext('2d',{willReadFrequently:true});clipCtx.beginPath();clipCtx.arc(clipCanvas.width/2,clipCanvas.height/2,clipCanvas.height/2,0,2*Math.PI);clipCtx.clip();clipCtx.drawImage(img,0,0,clipCanvas.width,clipCanvas.height);shadowCtx.drawImage(clipCanvas,CANVAS_PADDING,CANVAS_PADDING,this._maxSize,this._maxSize);shadowCanvas.toBlob(resolve);});},favicon:function(img){if(img.width>this._icon.grid.layout.gridIconSize/2){return this.clip(img);}
return new Promise((resolve)=>{var shadowCanvas=this._createCanvas();var shadowCtx=this._decorateShadowCanvas(shadowCanvas);var iconWidth;var iconHeight;shadowCtx.beginPath();shadowCtx.arc(shadowCanvas.width/2,shadowCanvas.height/2,shadowCanvas.height/2-CANVAS_PADDING,0,2*Math.PI,false);shadowCtx.fillStyle=DEFAULT_BACKGROUND_COLOR;shadowCtx.fill();iconWidth=iconHeight=this._maxSize*0.55;shadowCtx.shadowBlur=0;shadowCtx.shadowOffsetY=0;shadowCtx.mozImageSmoothingEnabled=false;shadowCtx.drawImage(img,(shadowCanvas.width-iconWidth)/2,(shadowCanvas.height-iconHeight)/2,iconWidth,iconHeight);shadowCanvas.toBlob(resolve);});},standard:function(img){return new Promise((resolve)=>{var shadowCanvas=this._createCanvas();var shadowCtx=this._decorateShadowCanvas(shadowCanvas);shadowCtx.drawImage(img,CANVAS_PADDING,CANVAS_PADDING,this._maxSize,this._maxSize);shadowCanvas.toBlob(resolve);});}};exports.GridIconRenderer=IconRenderer;}(window));

View file

@ -0,0 +1,9 @@
;'use strict';(function(exports){const maxIconsPerRow=4;const iconScaleFactorMaxIconsPerRow=5;const minIconsPerRow=3;const iconScaleFactorMinIconsPerRow=3.8;const distanceBetweenIconsWithMinIconsPerRow=36;const distanceBetweenIconsWithMaxIconsPerRow=38;const eachTextRowHeight=20;var constraintSize;function GridLayout(gridView){this.gridView=gridView;if(window.verticalPreferences){verticalPreferences.get('grid.cols').then(value=>{this.cols=value;this.onReady();},this.onReady);verticalPreferences.addEventListener('updated',this);}else{this.onReady();}}
GridLayout.prototype={minIconsPerRow:minIconsPerRow,maxIconsPerRow:maxIconsPerRow,_cols:minIconsPerRow,_offsetY:0,_percent:1,_dividerLineHeight:0,get percent(){return this._percent;},get cols(){return this._cols;},set cols(value){if(!value||value===this._cols){return;}
if(window.verticalPreferences){verticalPreferences.put('grid.cols',value);}
this._offsetY=0;this._percent=value==minIconsPerRow?1:minIconsPerRow/maxIconsPerRow;this._cols=value;},get constraintSize(){if(!constraintSize){this.calculateSize();}
return constraintSize;},get gridItemHeight(){var height=this.gridIconSize+
(this._cols===minIconsPerRow?distanceBetweenIconsWithMinIconsPerRow:distanceBetweenIconsWithMaxIconsPerRow);var defaultTextRows=2;var definedRows=parseInt(this.gridView.element.getAttribute('text-rows'),10);if(definedRows>defaultTextRows){height+=(definedRows-defaultTextRows)*eachTextRowHeight;}
return height;},get gridItemWidth(){return this.constraintSize/this._cols;},get gridMaxIconSize(){var baseSize=(this.constraintSize/iconScaleFactorMinIconsPerRow);return baseSize*devicePixelRatio;},get gridIconSize(){var numCols=this._cols;var size=this.constraintSize/numCols;if(numCols===minIconsPerRow){size=this.constraintSize/iconScaleFactorMinIconsPerRow;}else if(numCols===maxIconsPerRow){size=this.constraintSize/iconScaleFactorMaxIconsPerRow;}
return Math.floor(size);},get offsetY(){return this._offsetY;},set offsetY(value){this._offsetY=value;},stepYAxis:function(value){this._offsetY+=value;},handleEvent:function(e){switch(e.type){case'updated':var prop=e.target;if(prop.name==='grid.cols'){this.cols=parseInt(prop.value,10);this.gridView.render();}
break;}},calculateSize:function(){constraintSize=Math.min(window.screen.width,window.screen.height);},onReady:function(){window.dispatchEvent(new CustomEvent('gaiagrid-layout-ready'));}};exports.GridLayout=GridLayout;}(window));

View file

@ -0,0 +1,47 @@
;'use strict';(function(exports){const APP_LAUNCH_TIMEOUT=3000;function GridView(config){this.config=config;this.clickIcon=this.clickIcon.bind(this);this.onVisibilityChange=this.onVisibilityChange.bind(this);if(config.features.zoom){this.zoom=new GridZoom(this);}
this.layout=new GridLayout(this);if(config.element.hasAttribute('cols')){this.layout.cols=parseInt(config.element.getAttribute('cols'),10);}
this.start();}
GridView.prototype={icons:{},items:[],get element(){return this.config.element;},set cols(value){this.layout.cols=value;},_launchingApp:false,add:function(item,insertTo,expandGroup){if(!item){return;}
if(item.identifier){if(this.icons[item.identifier]){console.log('Error, duplicate identifier: ',item.identifier,new Error().stack);return;}
this.icons[item.identifier]=item;}else if(item.detail.type!=='divider'&&item.detail.type!=='placeholder'){console.log('Error, could not load identifier for object: ',JSON.stringify(item.detail));return;}
if(!isNaN(parseFloat(insertTo))&&isFinite(insertTo)){this.items.splice(insertTo,0,item);}else{insertTo=this.items.length;this.items.push(item);}
if(expandGroup){for(var i=insertTo+1,iLen=this.items.length;i<iLen;i++){var divider=this.items[i];if(divider.detail.type==='divider'){if(divider.detail.collapsed){divider.expand();}
break;}}}},getNearestItemIndex:function(x,y,isRow){var foundIndex=null;var leastDistance=null;var itemMiddleOffset=this.layout.gridItemWidth/2;for(var i=0,iLen=this.items.length;i<iLen;i++){var item=this.items[i];if(!item.isDraggable()){continue;}
if(this.config.features.disableSections&&item.detail.type==='divider'){continue;}
if(item.detail.type!=='divider'&&item.element.classList.contains('collapsed')){continue;}
var middleX=item.x+itemMiddleOffset;var middleY=item.y+item.pixelHeight/2;var xDistance=(isRow||item.detail.type==='divider')?0:x-middleX;var yDistance=y-middleY;var distance=Math.sqrt(xDistance*xDistance+
yDistance*yDistance);if(leastDistance===null||distance<leastDistance){leastDistance=distance;foundIndex=i;}}
return foundIndex;},start:function(){this.element.addEventListener('click',this.clickIcon);window.addEventListener('visibilitychange',this.onVisibilityChange);},stop:function(){this.element.removeEventListener('click',this.clickIcon);window.removeEventListener('visibilitychange',this.onVisibilityChange);},findItemFromElement:function(element,excludeCollapsedIcons){while(element&&element.parentNode!==this.element){element=element.parentNode;}
if(!element){return null;}
var i,iLen=this.items.length;var identifier=element.dataset.identifier;var icon=this.icons[identifier];if(!icon){for(i=0;i<iLen;i++){if(this.items[i].element===element){icon=this.items[i];break;}}}
if(icon&&excludeCollapsedIcons){if(icon.detail.type!=='divider'&&icon.detail.type!=='placeholder'&&icon.element.classList.contains('collapsed')){for(i=icon.detail.index+1;i<iLen;i++){if(this.items[i].detail.type==='divider'){return this.items[i];}}
console.warn('Collapsed icon found with no group');icon=null;}}
return icon;},onVisibilityChange:function(){this._launchingApp=false;},clickIcon:function(e){e.preventDefault();var inEditMode=this.dragdrop&&this.dragdrop.inEditMode;var action='launch';if(e.target.classList.contains('remove')){action='remove';}
var icon=this.findItemFromElement(e.target);if(!icon){return;}
if(action==='launch'){if(inEditMode&&e.target.classList.contains('icon')){if(!icon.isEditable()){return;}
action='edit';}else{if(!icon[action]){return;}
icon.element.classList.add('launching');var returnTimeout=500;setTimeout(function stateReturn(){if(icon.element){icon.element.classList.remove('launching');}},returnTimeout);}}
if((icon.detail.type==='app'||icon.detail.type==='bookmark')&&this._launchingApp){return;}
if((icon.detail.type==='app'&&icon.appState==='ready')||icon.detail.type==='bookmark'){this._launchingApp=true;if(this._launchingTimeout){window.clearTimeout(this._launchingTimeout);this._launchingTimeout=null;}
this._launchingTimeout=window.setTimeout(function(){this._launchingTimeout=null;this._launchingApp=false;}.bind(this),APP_LAUNCH_TIMEOUT);}
icon[action](e.target);},cleanItems:function(skipDivider){var appCount=0;var toRemove=[];this.items.forEach(function(item,idx){if(item instanceof GaiaGrid.Divider){if(appCount===0){toRemove.push(idx);}
appCount=0;}else{appCount++;}},this);toRemove.reverse();toRemove.forEach(function(idx){var removed=this.items.splice(idx,1)[0];removed.remove();},this);if(skipDivider){return;}
var lastItem=this.items[this.items.length-1];if(!lastItem||!(lastItem instanceof GaiaGrid.Divider)){this.items.push(new GaiaGrid.Divider());}},removeAllPlaceholders:function(){var toSplice=[];var previousItem;this.items.forEach(function(item,idx){if(item instanceof GaiaGrid.Placeholder){if((!previousItem||(previousItem&&previousItem instanceof GaiaGrid.Divider))&&this.dragdrop&&this.dragdrop.inDragAction){return;}
toSplice.push(idx);}
previousItem=item;},this);toSplice.reverse().forEach(function(idx){this.items.splice(idx,1)[0].remove();},this);},clear:function(){for(var i=0,iLen=this.items.length;i<iLen;i++){var item=this.items[i];if(item.element){this.element.removeChild(item.element);item.element=null;item.lastX=null;item.lastY=null;item.lastScale=null;}}
this.items=[];this.icons={};},createPlaceholders:function(coordinates,idx,count){var isRTL=(document.documentElement.dir==='rtl');for(var i=0;i<count;i++){var item=new GaiaGrid.Placeholder();this.items.splice(idx+i,0,item);item.setPosition(idx+i);var xPosition=(coordinates[0]+i)*this.layout.gridItemWidth;if(isRTL){xPosition=(this.layout.constraintSize-this.layout.gridItemWidth)-
xPosition;}
item.setCoordinates(xPosition,this.layout.offsetY);item.render();}},render:function(options){var self=this;options=options||{};this.removeAllPlaceholders();this.cleanItems(options.skipDivider);var oldHeight=this.layout.offsetY;this.layout.offsetY=0;var x=0;var y=0;function step(item){var pixelHeight=item.pixelHeight;self.layout.stepYAxis(pixelHeight);x=0;y++;}
var pendingCachedIcons=0;var onCachedIconRendered=()=>{if(--pendingCachedIcons<=0){this.element.removeEventListener('cached-icon-rendered',onCachedIconRendered);this.element.dispatchEvent(new CustomEvent('cached-icons-rendered'));}};this.element.addEventListener('cached-icon-rendered',onCachedIconRendered);var nextDivider=null;var oddDivider=true;var isRTL=(document.documentElement.dir==='rtl');for(var idx=0;idx<this.items.length;idx++){var item=this.items[idx];if(options.rerender&&item.element){this.element.removeChild(item.element);item.element=null;}
if(item.detail.type==='divider'){nextDivider=null;}else{if(!nextDivider){for(var i=idx+1;i<this.items.length;i++){if(this.items[i].detail.type==='divider'){nextDivider=this.items[i];oddDivider=!oddDivider;break;}}
if(nextDivider&&!nextDivider.detail.collapsed){this.layout.offsetY+=nextDivider.headerHeight;}}
if(nextDivider&&nextDivider.detail.collapsed){item.setPosition(idx);continue;}}
if(x>0&&item.gridWidth>1&&x+item.gridWidth>=this.layout.cols){var remaining=this.layout.cols-x;this.createPlaceholders([x,y],idx,remaining);idx+=remaining;item=this.items[idx];var lastItemInRow=this.items[idx-1];step(lastItemInRow);}
item.setPosition(idx);if(!options.skipItems){item.hasCachedIcon&&++pendingCachedIcons;var xPosition=x*this.layout.gridItemWidth;if(isRTL){xPosition=(this.layout.constraintSize-this.layout.gridItemWidth)-
xPosition;}
item.setCoordinates(xPosition,this.layout.offsetY);if(!item.active){item.render();}
if(item.detail.type==='divider'){if(oddDivider){item.element.classList.add('odd');}else{item.element.classList.remove('odd');}}}
x+=item.gridWidth;if((x>=this.layout.cols)&&(idx<this.items.length-1)){step(item);}}
if(this.layout.offsetY!=oldHeight){if(this.dragdrop&&this.dragdrop.inDragAction){this.layout.offsetY=oldHeight;}else{this.element.dispatchEvent(new CustomEvent('gaiagrid-resize',{detail:this.layout.offsetY}));}}
this.element.setAttribute('cols',this.layout.cols);pendingCachedIcons===0&&onCachedIconRendered();this.loadDragDrop();},loadDragDrop:function(){if(!this.dragdrop&&this.config.features.dragdrop){LazyLoader.load('shared/elements/gaia_grid/js/grid_dragdrop.js',()=>{if(this.dragdrop){return;}
this.dragdrop=new GridDragDrop(this);});}}};exports.GridView=GridView;}(window));

View file

@ -0,0 +1,160 @@
'use strict';
(function(exports) {
const pinchThreshold = Math.round(window.innerWidth / 12);
function GridZoom(gridView) {
this.gridView = gridView;
this.touches = 0;
this.zoomStartTouches = [];
this.zoomStartDistance = 0;
this.container = document.getElementById('zoom');
this.arrows = this.container.querySelector('.arrows');
this.curtain = this.container.querySelector('.curtain');
this.indicator = this.container.querySelector('.indicator');
this.start();
window.addEventListener('gaiagrid-dragdrop-begin', this.stop.bind(this));
window.addEventListener('gaiagrid-dragdrop-finish', this.start.bind(this));
}
GridZoom.prototype = {
/**
* Starts listening for touchstart events.
* This is what starts listening events to start the drag & drop operation.
*/
start: function() {
window.addEventListener('touchstart', this);
},
/**
* Stops listening for touchstart events.
* This will effectively disable pinch-to-zoom.
*/
stop: function() {
window.removeEventListener('touchstart', this);
},
_attachGestureListeners: function() {
window.addEventListener('touchmove', this);
window.addEventListener('touchend', this);
},
_stopGestureListeners: function() {
window.removeEventListener('touchmove', this);
window.removeEventListener('touchend', this);
},
_resetState: function() {
this.zoomInProgress = false;
this.container.hidden = true;
this.indicator.classList.remove('active');
this.arrows.classList.remove('zooming', 'grow', 'shrink');
this.arrows.style.transform = '';
},
/**
* General Event Handler
*/
handleEvent: function(e) {
if (e.type === 'touchend' && this.zoomStartTouches) {
if (!this.zoomInProgress) {
this._resetState();
}
this._stopGestureListeners();
return;
}
if (!e.touches || e.touches.length !== 2) {
return;
}
// Sort touches by ascending pageX position.
var touches = [e.touches[0], e.touches[1]].sort(function(a, b) {
return a.pageX - b.pageX;
});
var touchDistance = Math.sqrt(
(touches[0].pageX - touches[1].pageX) *
(touches[0].pageX - touches[1].pageX) +
(touches[0].pageY - touches[1].pageY) *
(touches[0].pageY - touches[1].pageY));
var layout = this.gridView.layout;
switch(e.type) {
case 'touchstart':
this.container.hidden = false;
this.zoomStartTouches = touches;
this.zoomStartDistance = touchDistance;
if (layout.cols < layout.maxIconsPerRow) {
this.arrows.classList.add('grow');
} else {
this.arrows.classList.add('shrink');
}
this.indicator.dataset.cols = layout.cols;
this._attachGestureListeners();
break;
case 'touchmove':
if (layout.cols < layout.maxIconsPerRow &&
touchDistance < this.zoomStartDistance &&
Math.abs(touchDistance - this.zoomStartDistance) >
pinchThreshold) {
this.gridView.cols = layout.maxIconsPerRow;
this.zoomInProgress = true;
} else if (layout.cols > layout.minIconsPerRow &&
touchDistance > this.zoomStartDistance &&
Math.abs(touchDistance - this.zoomStartDistance) >
pinchThreshold) {
this.gridView.cols = layout.minIconsPerRow;
this.zoomInProgress = true;
} else {
return;
}
// For now just implement a canned animation
this._stopGestureListeners();
var ontransitionend = function() {
this.arrows.removeEventListener('transitionend', ontransitionend);
// Change the indicator color at the end.
this.indicator.classList.add('active');
this.gridView.render();
// Reset zoom element state after a set time.
var zoomHideTime = 400;
setTimeout(this._resetState.bind(this), zoomHideTime);
}.bind(this);
this.arrows.addEventListener('transitionend', ontransitionend);
this.indicator.dataset.cols = layout.cols;
this.arrows.classList.add('zooming');
// Force a sync reflow
document.body.clientHeight;
var scaleTransform = 'scale(1)';
if (this.zoomInProgress && touchDistance < this.zoomStartDistance) {
scaleTransform = 'scale(0.4)';
}
this.arrows.style.transform = scaleTransform;
break;
}
}
};
exports.GridZoom = GridZoom;
}(window));

View file

@ -0,0 +1,4 @@
;'use strict';(function(exports){const TYPE='bookmark';function Bookmark(record,features){this.detail=record;this.features=features||{};this.detail.type=TYPE;}
Bookmark.prototype={__proto__:GaiaGrid.GridItem.prototype,renderer:GridIconRenderer.TYPE.FAVICON,get pixelHeight(){return this.grid.layout.gridItemHeight;},gridWidth:1,get name(){return this.detail.name;},get icon(){return this.detail.icon||this.defaultIcon;},get identifier(){return this.detail.id;},update:GaiaGrid.GridItem.prototype.updateFromDatastore,isEditable:function(){return this.features&&this.features.isEditable!==false;},isRemovable:function(){return this.features&&this.features.isRemovable!==false;},isDraggable:function(){return this.features&&this.features.isDraggable!==false;},render:function(){GaiaGrid.GridItem.prototype.render.call(this);this.element.classList.add('bookmark');if(this.isEditable()){this.element.classList.add('editable');}},launch:function(){var features={name:this.name,icon:this.icon,remote:true};var url=this.detail.url;if(this.features.search){features.searchName=this.name;features.searchUrl=url;}
window.open(url,'_samescope',Object.keys(features).map(function eachFeature(key){return encodeURIComponent(key)+'='+
encodeURIComponent(features[key]);}).join(','));},edit:function(){new MozActivity({name:'save-bookmark',data:{type:'url',url:this.detail.id}});}};exports.GaiaGrid.Bookmark=Bookmark;}(window));

View file

@ -0,0 +1,3 @@
;'use strict';(function(exports){function Divider(){this.detail={type:'divider',index:0};}
Divider.prototype={__proto__:GaiaGrid.GridItem.prototype,x:0,y:0,headerHeight:0,get pixelHeight(){return(this.grid.layout.cols>3)?50:60;},gridWidth:4,scale:1,render:function(){if(!this.element){var divider=this.element=document.createElement('section');divider.className='divider';var span=document.createElement('span');span.className='spacer';divider.appendChild(span);this.grid.element.appendChild(divider);}
this.element.style.transform='translate(0 ,'+this.y+'px)';},remove:function(){if(this.element){this.element.parentNode.removeChild(this.element);}},isDraggable:function(){return false;}};exports.GaiaGrid.Divider=Divider;}(window));

View file

@ -0,0 +1,31 @@
;'use strict';(function(exports){const ICON_BLOB_DECORATED_EVENT='iconblobdecorated';const ICON_BLOB_ERROR_EVENT='gaiagrid-iconbloberror';const FETCH_XHR_TIMEOUT=10000;function fetchBlob(uri){return new Promise(function(accept,reject){var xhr=new XMLHttpRequest({mozAnon:true,mozSystem:true});xhr.open('GET',uri,true);xhr.responseType='blob';xhr.timeout=FETCH_XHR_TIMEOUT;xhr.send();xhr.onload=function(){var status=xhr.status;if(status!==0&&status!==200){reject(new Error('Got HTTP status '+status+' trying to load '+uri));return;}
accept(xhr.response);};xhr.onerror=xhr.ontimeout=function(){reject(new Error('Error while HTTP GET: ',uri));};});}
function GridItem(){this.detail={};}
GridItem.prototype={x:0,y:0,pixelHeight:0,gridWidth:1,scale:1,persistToDB:true,lastX:null,lastY:null,lastScale:null,get hasCachedIcon(){return this.detail&&this.detail.decoratedIconBlob;},renderer:GridIconRenderer.TYPE.STANDARD,iconState:'none',get defaultIcon(){return'/shared/elements/gaia_grid/images/default_icon.png';},get grid(){return document.getElementsByTagName('gaia-grid')[0]._grid;},isRemovable:function(){return false;},isEditable:function(){return false;},isDraggable:function(){return true;},isIconFromOrigin:function(){return this.icon.startsWith('http')||this.icon.startsWith('app:');},setPosition:function(position){this.detail.index=position;},setCoordinates:function(x,y){this.x=x;this.y=y;},requestAttention:function(){var rect={x:this.x,y:this.y,width:this.gridWidth*this.grid.layout.gridItemWidth,height:this.pixelHeight};this.grid.element.dispatchEvent(new CustomEvent('gaiagrid-attention',{detail:rect}));},closestIconSizeFromList:function(choices){if(!choices){return 0;}
var sizes=Object.keys(choices);if(!sizes.length){return 0;}
var maxSize=this.grid.layout.gridMaxIconSize;var filter=(a)=>a>=maxSize?a:0;var bestSize=Math.min(...sizes.map(filter));bestSize=bestSize||Math.max(...sizes);return bestSize||0;},closestIconFromList:function(choices){var icon;if(Array.isArray(choices)){var manifest={'icons':choices};var maxSize=this.grid.layout.gridMaxIconSize;icon=window.IconsHelper.getBestIconFromWebManifest(manifest,maxSize);return icon?(new URL(icon,this.app.manifestURL)).href:null;}
var accurateSize=this.closestIconSizeFromList(choices);if(accurateSize===0){return this.defaultIcon;}
icon=choices[accurateSize];if(!UrlHelper.hasScheme(icon)){icon=this.app.origin+icon;}
return icon;},renderIconFromSrc:function(url){var background=new Image();background.src=url;background.onload=this._decorateIcon.bind(this,background);},renderIconFromBlob:function(blob){var background=new Image();background.src=URL.createObjectURL(blob);background.onload=()=>{this._decorateIcon(background);URL.revokeObjectURL(background.src);};background.onerror=()=>{URL.revokeObjectURL(background.src);if(this.hasCachedIcon){this._stampElementWithIcon('blobcache');this._displayDecoratedIcon(this.detail.decoratedIconBlob,true);return;}
this.renderIconFromSrc(this.defaultIcon);this._stampElementWithIcon(this.defaultIcon);};},_decorateIcon:function(img){var strategy=this.detail.renderer||this.renderer;this.rendererInstance=new GridIconRenderer(this);this.rendererInstance[strategy](img).then(this._displayDecoratedIcon.bind(this));},_displayDecoratedIcon:function(blob,isCachedIcon){if(!this.element){return;}
var style=this.element.style;if(!style.backgroundSize){style.height=this.grid.layout.gridItemHeight+'px';var backgroundHeight=((this.grid.layout.gridIconSize*(1/this.grid.layout.percent))+
GridIconRenderer.prototype.unscaledCanvasPadding);if(this.grid.layout.gridItemHeight>backgroundHeight){style.backgroundSize=backgroundHeight+'px';}else{style.backgroundSize=style.height;}}
if(isCachedIcon){var url=URL.createObjectURL(blob);style.backgroundImage='url('+url+')';this.element.dataset.backgroundImage=url;var img=new Image();img.onload=img.onerror=()=>{this.grid.element.dispatchEvent(new CustomEvent('cached-icon-rendered'));};img.src=url;return;}
this._compareBlobs(blob,this.detail.decoratedIconBlob).then((equal)=>{if(equal){return;}
style.backgroundImage='url('+URL.createObjectURL(blob)+')';this.detail.decoratedIconBlob=blob;this.grid.element.dispatchEvent(new CustomEvent(ICON_BLOB_DECORATED_EVENT,{detail:this}));var bgImg=this.element.dataset.backgroundImage;bgImg&&URL.revokeObjectURL(bgImg);});},_compareBlobs:function(blob1,blob2){return new Promise(function(resolve){if(!blob1||!blob2||blob1.type!==blob2.type||blob1.size!==blob2.size){resolve(false);return;}
var startBytes=127;var bytesHash=16;var reader=new FileReader();reader.onloadend=function(){var result1=reader.result;reader=new FileReader();reader.onloadend=reader.onerror=function(){resolve(result1===reader.result);};reader.readAsDataURL(blob2.slice(startBytes,startBytes+bytesHash));};reader.onerror=function(){resolve(false);};reader.readAsDataURL(blob1.slice(startBytes,startBytes+bytesHash));});},fetchIconBlob:function(){return fetchBlob(this.icon);},_stampElementWithIcon:function(uri){if(!this.element||uri.startsWith('data:')){return;}
if(uri.length>255){uri=uri.slice(0,255);}
this.element.dataset.testIcon=uri;},renderIcon:function(renderCachedIcon){var icon=this.icon;this.iconState='pending';if(!icon){return;}
if(renderCachedIcon&&this.hasCachedIcon){this._displayDecoratedIcon(this.detail.decoratedIconBlob,true);var resolveIcon=()=>{this.grid.element.removeEventListener('cached-icons-rendered',resolveIcon);this.doRenderIcon(icon);};this.grid.element.addEventListener('cached-icons-rendered',resolveIcon);}else{this.doRenderIcon(icon);}},doRenderIcon:function(icon){if(!this.isIconFromOrigin()){this._stampElementWithIcon(icon);this.renderIconFromSrc(icon);this.iconState='success';return Promise.resolve();}
var eventTarget=this.grid.element;var blobNotFound=()=>{this.iconState='error';if(!this.hasCachedIcon){this.renderIconFromSrc(this.defaultIcon);this._stampElementWithIcon(this.defaultIcon);}else{this._stampElementWithIcon('blobcache');}
eventTarget.dispatchEvent(new CustomEvent(ICON_BLOB_ERROR_EVENT,{detail:this}));};return this.fetchIconBlob().then((blob)=>{if(!blob){return blobNotFound();}
this.renderIconFromBlob(blob);this.iconState='success';this._stampElementWithIcon(icon);}).catch((err)=>{blobNotFound();});},removeFromGrid:function(){var idx=this.grid.items.indexOf(this);if(idx===-1){console.error('Attempting to remove self before item has been added!');return;}
this.grid.items.splice(idx,1);delete this.grid.icons[this.identifier];if(this.element){this.element.parentNode.removeChild(this.element);}
this.grid.render({from:idx-1});},remove:function(){this.grid.element.dispatchEvent(new CustomEvent('removeitem',{detail:this}));},render:function(){var scale=this.grid.layout.percent*this.scale;if(!this.element){var tile=document.createElement('div');tile.className='icon';tile.dataset.identifier=this.identifier;tile.dataset.isDraggable=this.isDraggable();tile.setAttribute('role','link');tile.setAttribute('tabindex',0);tile.style.width=(this.grid.layout.constraintSize/3)+'px';var nameContainerEl=document.createElement('p');nameContainerEl.style.marginTop=((this.grid.layout.gridIconSize*(1/this.grid.layout.percent))+
(GridIconRenderer.prototype.unscaledCanvasPadding/2))+'px';tile.appendChild(nameContainerEl);var nameEl=document.createElement('span');nameEl.className='title';nameEl.setAttribute('dir','auto');nameContainerEl.appendChild(nameEl);if(this.isRemovable()){var removeEl=document.createElement('span');removeEl.className='remove';tile.appendChild(removeEl);}
this.element=tile;this.updateTitle();this.renderIcon(true);this.grid.element.appendChild(tile);}
this.transform(this.x,this.y,scale);},transform:function(x,y,scale,element){scale=scale||1;if(!element){if(x===this.lastX&&y===this.lastY&&scale===this.lastScale){return;}
element=this.element;this.lastX=x;this.lastY=y;this.lastScale=scale;}
element.style.transform='translate('+x+'px,'+y+'px) scale('+scale+')';},setActive:function(active){if(active){this.element.classList.add('active');this.active=true;}else{this.element.classList.remove('active');this.active=false;}},updateTitle:function(){if(!this.element){return;}
var nameEl=this.element.querySelector('.title');if(this.asyncName){this.asyncName().then(function(name){nameEl.textContent=name;});}else{nameEl.textContent=this.name;}},updateFromDatastore:function(record){var iconChanged=record.icon!==this.icon;var nameChanged=record.name!==this.name;var type=this.detail.type;var lastIcon=this.icon;record.type=type;this.detail=record;if(nameChanged){this.updateTitle();}
if(iconChanged&&record.icon){this.renderIcon();}else if(!record.icon){this.detail.icon=lastIcon;}}};exports.GaiaGrid.GridItem=GridItem;}(window));

View file

@ -0,0 +1,20 @@
;'use strict';(function(exports){const COLLAPSE_RATIO=0.33;const COLLAPSED_GROUP_SIZE=6;const COLLAPSED_GROUP_MARGIN_LEFT=23;const COLLAPSED_GROUP_MARGIN_RIGHT=53;const TOGGLE_TIMEOUT=250;function Group(detail){this.detail=detail||{};this.detail.type='divider';this.detail.index=0;this.pendingCollapse=this.detail.collapsed=!!this.detail.collapsed;}
Group.prototype={__proto__:GaiaGrid.GridItem.prototype,gridWidth:4,get headerHeight(){return this.detail.collapsed?20:30;},pendingCollapse:false,pendingCollapseTimeout:null,backgroundHeight:0,lastBackgroundHeight:null,separatorHeight:0,collapseRatio:COLLAPSE_RATIO,get pixelHeight(){return this.detail.collapsed?this.backgroundHeight:this.separatorHeight;},get size(){var size=0;for(var i=this.detail.index-1,items=this.grid.items;i>=0&&items[i].detail.type!=='divider';i--){size++;}
return size;},_createElement:function(){var group=this.element=document.createElement('section');group.className='divider group newly-created';var span=document.createElement('span');span.className='background';group.appendChild(span);this.backgroundSpanElement=span;span=document.createElement('span');span.className='shadow';group.appendChild(span);this.shadowSpanElement=span;span=document.createElement('span');span.className='header';group.appendChild(span);this.headerSpanElement=span;span=document.createElement('span');span.className='gripper';this.headerSpanElement.appendChild(span);var button=document.createElement('button');button.className='toggle';button.dataset.l10nId='gaia-grid-toggle-expanded';this.headerSpanElement.appendChild(button);this.toggleElement=button;span=document.createElement('span');span.className='separator';group.appendChild(span);this.dividerSpanElement=span;this.dividerSpanElement.appendChild(document.createElement('span'));this.grid.element.appendChild(group);this.separatorHeight=this.dividerSpanElement.clientHeight;this.lastBackgroundHeight=null;},_renderChildren:function(nApps){var isRTL=(document.documentElement.dir==='rtl');if(!this.detail.collapsed){this.element.classList.remove('collapsed');return;}
this.element.classList.add('collapsed');var y=this.y;var index=this.detail.index;var width=Math.round((this.grid.layout.constraintSize-
COLLAPSED_GROUP_MARGIN_LEFT-COLLAPSED_GROUP_MARGIN_RIGHT)/COLLAPSED_GROUP_SIZE);var x=isRTL?(this.grid.layout.constraintSize-COLLAPSED_GROUP_MARGIN_RIGHT):COLLAPSED_GROUP_MARGIN_LEFT;y+=this.headerHeight;var maxGridItemWidth=this.grid.layout.constraintSize/this.grid.layout.minIconsPerRow;this.collapseRatio=(maxGridItemWidth/this.grid.layout.gridItemWidth)*COLLAPSE_RATIO;for(var i=index-nApps;i<index;i++){var item=this.grid.items[i];if(this.detail.collapsed){item.scale=this.collapseRatio;var itemVisible=(i-(index-nApps))<COLLAPSED_GROUP_SIZE;if(!itemVisible){item.setCoordinates(isRTL?x+width:x-width,y);}else{item.setCoordinates(x,y);x+=isRTL?-width:width;}
item.render();item.element.classList.add('collapsed');if(!itemVisible){item.element.classList.add('hidden');}}}},getRealYPosition:function(nApps){if(this.detail.collapsed){return this.y;}
return this.grid.items[this.detail.index-nApps].y-
this.headerHeight;},render:function(){var createdElements=false;if(!this.element){createdElements=true;this._createElement();}
var nApps=this.size;this._renderChildren(nApps);var y=this.getRealYPosition(nApps);if(y!==this.lastY){this.headerSpanElement.style.transform='translate(0px, '+y+'px)';}
if(this.toggleElement){var toggleLabel=this.detail.collapsed?'collapsed':'expanded';this.toggleElement.dataset.l10nId='gaia-grid-toggle-'+toggleLabel;}
if(this.detail.collapsed){this.backgroundHeight=Math.round(this.collapseRatio*this.grid.layout.gridIconSize*1.5);}else{var height=Math.ceil(nApps/this.grid.layout.cols);this.backgroundHeight=(height||1)*this.grid.layout.gridItemHeight;}
this.backgroundHeight+=this.headerHeight;if(y!=this.lastY||this.backgroundHeight!==this.lastBackgroundHeight){this.backgroundSpanElement.style.transform='translate(0px, '+y+'px) scale(1, '+this.backgroundHeight+')';this.shadowSpanElement.style.transform='translateY('+y+'px)';this.shadowSpanElement.style.height=this.backgroundHeight+'px';this.dividerSpanElement.style.transform='translate(0px, '+(y+this.backgroundHeight)+'px)';}
this.lastBackgroundHeight=this.backgroundHeight;this.lastY=y;this.backgroundHeight+=this.separatorHeight;if(createdElements){this.element.clientTop;this.element.classList.remove('newly-created');}},forEachItem:function(callback){var nApps=this.size;var index=this.detail.index;for(var i=index-nApps;i<index;i++){callback(this.grid.items[i]);}},setActive:function(active){GaiaGrid.GridItem.prototype.setActive.call(this,active);this.collapse();var callback=active?function(item){item.element.classList.add('active');}:function(item){item.element.classList.remove('active');};this.forEachItem(callback);},_rerenderOnToggle:function(){if(this.pendingCollapseTimeout){clearTimeout(this.pendingCollapseTimeout);this.pendingCollapseTimeout=null;}
if(this.toggleElement){this.toggleElement.classList.add('toggling');setTimeout(()=>{this.toggleElement.classList.remove('toggling');},TOGGLE_TIMEOUT);}
this.pendingCollapseTimeout=setTimeout(()=>{this.detail.collapsed=this.pendingCollapse;this.pendingCollapseTimeout=null;if(!this.detail.collapsed){this.forEachItem(function(item){item.scale=1;if(item.element){item.element.classList.remove('collapsed');item.element.classList.remove('hidden');}});}
if(this.active){this.render();}
this.grid.render();var dragging=this.grid.dragdrop&&this.grid.dragdrop.inDragAction;if(dragging){this.grid.dragdrop.updateIconPosition();}else{window.dispatchEvent(new CustomEvent('gaiagrid-saveitems'));this.requestAttention();}},20);},collapse:function(){if(this.detail.collapsed){return;}
this.pendingCollapse=true;this._rerenderOnToggle();},expand:function(){if(!this.detail.collapsed){return;}
this.pendingCollapse=false;this._rerenderOnToggle();},launch:function(target){if(target!==this.toggleElement){return;}
if(this.detail.collapsed){this.expand();}else{this.collapse();}},remove:function(){if(this.element){this.element.parentNode.removeChild(this.element);}},isDraggable:function(){return true;},requestAttention:function(){var rect={x:0,y:this.getRealYPosition(this.size),width:this.gridWidth*this.grid.layout.gridItemWidth,height:this.backgroundHeight};this.grid.element.dispatchEvent(new CustomEvent('gaiagrid-attention',{detail:rect}));}};exports.GaiaGrid.Divider=Group;}(window));

View file

@ -0,0 +1,51 @@
'use strict';
/* global GaiaGrid */
/* global GridIconRenderer */
/* global MozActivity */
/* jshint nonew: false */
(function(exports) {
const TYPE = 'marketplace-app';
/**
* Represents a single bookmark icon on the homepage.
*/
function MarketPlaceApp(record) {
this.detail = record;
this.detail.type = TYPE;
}
MarketPlaceApp.prototype = {
__proto__: GaiaGrid.Bookmark.prototype,
renderer: GridIconRenderer.TYPE.STANDARD,
/**
* Returns the icon image path.
*/
get icon() {
var icon = this._accurateIcon;
if (!icon) {
icon = this._accurateIcon = this.closestIconFromList(
this.detail.icons);
}
return icon;
},
launch: function() {
new MozActivity({
name: 'marketplace-app',
data: {
slug: this.detail.slug
}
});
},
};
exports.GaiaGrid.MarketPlaceApp = MarketPlaceApp;
}(window));

View file

@ -0,0 +1,19 @@
;'use strict';(function(exports){const IDENTIFIER_SEP='-';var MOZAPP_EVENTS=['downloadsuccess','downloaderror','downloadavailable','downloadapplied','progress'];var APP_LOADING='loading';var APP_ERROR='error';var APP_UNRECOVERABLE='unrecoverable';var APP_PAUSED='paused';var APP_READY='ready';function localizeString(str){var userLang=document.documentElement.lang;if(navigator.mozL10n&&navigator.mozL10n.ctx.qps.indexOf(userLang)!==-1){return navigator.mozL10n.qps[userLang].translate(str);}
return str;}
function Mozapp(app,entryPoint,details){this.app=app;this.entryPoint=entryPoint;this.detail={type:'app',manifestURL:app.manifestURL,entryPoint:entryPoint,index:0,decoratedIconBlob:details&&details.decoratedIconBlob};MOZAPP_EVENTS.forEach(function(type){this.app['on'+type]=this.handleEvent.bind(this);},this);this.setAppState(this._determineState(app));}
Mozapp.HIDDEN_ROLES=['system','input','homescreen','search','addon','langpack'];Mozapp.prototype={__proto__:GaiaGrid.GridItem.prototype,_isHiddenRole:function(){var manifest=this.app.manifest;if(!manifest||!manifest.role){return null;}
return Mozapp.HIDDEN_ROLES.indexOf(manifest.role)!==-1;},_determineState:function(app){if(app.installState==='pending'&&!app.downloadAvailable&&!app.readyToApplyDownload){return APP_UNRECOVERABLE;}
if(app.downloading){return APP_LOADING;}
if(app.downloadError&&app.downloadError.name){if(app.downloadError.name==='DOWNLOAD_CANCELED'){return APP_PAUSED;}
return APP_ERROR;}
if(app.installState==='pending'){return APP_PAUSED;}
return APP_READY;},handleEvent:function(event){switch(event.type){case'progress':case'downloaderror':case'downloadsuccess':this.setAppState(this._determineState(this.app));break;case'downloadapplied':if(this._isHiddenRole()){console.warn('Removing hidden app from the grid',this.name);return this.removeFromGrid();}
delete this._accurateIcon;delete this._accurateIconSize;this.setAppState(this._determineState(this.app));this.renderIcon();window.dispatchEvent(new CustomEvent('downloadapplied',{detail:{id:this.app.manifestURL}}));break;}},fetchIconBlob:function(){if(!this._accurateIconSize){this._accurateIconSize=this.closestIconSizeFromList(this.descriptor.icons);}
var result=this._accurateIconSize?navigator.mozApps.mgmt.getIcon(this.app,this._accurateIconSize,this.entryPoint||''):GaiaGrid.GridItem.prototype.fetchIconBlob.call(this);return result;},get pixelHeight(){return this.grid.layout.gridItemHeight;},gridWidth:1,get name(){var userLang=document.documentElement.lang;if(navigator.mozL10n&&userLang in navigator.mozL10n.qps){return navigator.mozL10n.qps[userLang].translate(this.descriptor.short_name||this.descriptor.name);}
var locales=this.descriptor.locales;var localized=locales&&locales[userLang]&&(locales[userLang].short_name||locales[userLang].name);return localized||this.descriptor.short_name||this.descriptor.name;},asyncName:function(){var userLang=document.documentElement.lang;var ep=this.entryPoint||undefined;if(!this.app.getLocalizedValue){return new Promise((resolve,reject)=>{reject();});}
return this.app.getLocalizedValue('short_name',userLang,ep).then(shortName=>localizeString(shortName),this.app.getLocalizedValue.bind(this.app,'name',userLang,ep)).then(name=>localizeString(name),()=>this.name);},get icon(){var icon=this._accurateIcon;if(!icon){icon=this._accurateIcon=this.closestIconFromList(this.descriptor.icons);}
return icon;},get descriptor(){var manifest=this.app.manifest||this.app.updateManifest;if(this.entryPoint&&manifest.entry_points&&manifest.entry_points[this.entryPoint]){return manifest.entry_points[this.entryPoint];}
return manifest;},identifierSeparator:IDENTIFIER_SEP,get identifier(){var identifier=[this.app.manifestURL];if(this.entryPoint){identifier.push(this.entryPoint);}
return identifier.join(IDENTIFIER_SEP);},isRemovable:function(){return this.app.removable;},unrecoverableError:function(){navigator.mozApps.mgmt.uninstall(this.app);},cancel:function(){var dialog=new ConfirmDialogHelper({type:'pause',title:{id:'gaia-grid-stop-download-title',args:{name:this.name}},body:'gaia-grid-stop-download-body',cancel:{title:'gaia-grid-cancel'},confirm:{title:'gaia-grid-stop-download-action',type:'danger',cb:()=>this.app.cancelDownload()}});dialog.show(document.body);},resume:function(){var dialog=new ConfirmDialogHelper({type:'resume',title:'gaia-grid-resume-download-title',body:{id:'gaia-grid-resume-download-body',args:{name:this.name}},cancel:{title:'gaia-grid-cancel'},confirm:{title:'gaia-grid-resume-download-action',cb:()=>{this.setAppState(APP_LOADING);this.app.download();}}});dialog.show(document.body);},setAppState:function(state){this.appState=state;if(this.element){this.element.dataset.appState=state;}},render:function(){var needsStateSet=!this.element;GaiaGrid.GridItem.prototype.render.apply(this,arguments);if(needsStateSet){this.setAppState(this.appState);}},launch:function(){var app=this.app;switch(this._determineState(app)){case APP_UNRECOVERABLE:return this.unrecoverableError();case APP_ERROR:case APP_PAUSED:return this.resume();case APP_LOADING:return this.cancel();}
window.performance.mark('appLaunch@'+app.origin);if(this.entryPoint){return app.launch(this.entryPoint);}
return app.launch();}};exports.GaiaGrid.Mozapp=Mozapp;}(window));

View file

@ -0,0 +1,3 @@
;'use strict';(function(exports){function Placeholder(){this.detail={type:'placeholder',index:0};}
Placeholder.prototype={__proto__:GaiaGrid.GridItem.prototype,get pixelHeight(){return this.grid.layout.gridItemHeight;},createsGroupOnDrop:false,gridWidth:1,persistToDB:false,get name(){return'';},render:function(){if(!this.element){var tile=document.createElement('div');tile.className='icon placeholder';tile.style.height=this.pixelHeight+'px';this.element=tile;this.grid.element.appendChild(tile);}
this.transform(this.x,this.y,this.grid.layout.percent);},remove:function(){if(this.element){this.element.parentNode.removeChild(this.element);}}};exports.GaiaGrid.Placeholder=Placeholder;}(window));

View file

@ -0,0 +1,7 @@
;window.GaiaGrid=(function(win){'use strict';var proto=Object.create(HTMLElement.prototype);var baseurl=window.GaiaGridBaseurl||'/shared/elements/gaia_grid/';proto.createdCallback=function(){var shadow=this.createShadowRoot();this._template=template.content.cloneNode(true);this._styleHack();this._grid=new GridView({element:this,features:{dragdrop:this.getAttribute('dragdrop')!==null,zoom:this.getAttribute('zoom')!==null,disableSections:this.getAttribute('disable-sections')!==null}});shadow.appendChild(this._template);};proto.add=function(){this._grid.add.apply(this._grid,arguments);};proto.clear=function(){this._grid.clear.apply(this._grid,arguments);};proto.render=function(){this._grid.layout.calculateSize();this._grid.render.apply(this._grid,arguments);};proto.start=function(){this._grid.start.apply(this._grid,arguments);};proto.stop=function(){this._grid.stop.apply(this._grid,arguments);};proto.getIcons=function(){return this._grid.icons;};proto.getItems=function(){return this._grid.items;};proto.getIcon=function(identifier){return this._grid.icons[identifier];};proto.removeIconByIdentifier=function(identifier){delete this._grid.icons[identifier];};proto.removeItemByIndex=function(itemIndex){this._grid.items.splice(itemIndex,1);};proto.popDivider=function(){var items=this._grid.items;if(items.length&&items[items.length-1].detail.type==='divider'){return items.pop();}
return null;};proto.appendItem=function(item){var items=this._grid.items;var lastIndex=items.length-1;if(items[lastIndex].detail.type==='divider'){this.add(item,lastIndex);}else{this.add(item);}};proto.appendItemToExpandedGroup=function(item){var items=this._grid.items;var lastIndex=items.length-1;if(items[lastIndex].detail.type==='divider'&&items[lastIndex].detail.collapsed){items[lastIndex].expand();}
this.appendItem(item);};proto.setEditHeaderElement=function(element){if(this._grid.dragdrop){this._grid.dragdrop.editHeaderElement=element;}};Object.defineProperty(proto,'maxIconSize',{get:function(){return this._grid.layout.gridMaxIconSize;}});proto.getIndexLastIcon=function(){var items=this._grid.items;for(var i=this._grid.items.length-1;i>=0;i--){if(items[i]instanceof GaiaGrid.Mozapp){return i;}}};proto.removeNonVisualElements=function(){var nonVisualElements=[GaiaGrid.Placeholder];function isNonVisual(elem){var retVal=false;for(var i=0,iLen=nonVisualElements.length;i<iLen&&!retVal;i++){retVal=elem instanceof nonVisualElements[i];}
return retVal;}
var i=0;var iLen=this._grid.items.length;while(i<iLen){this._grid.items[i].detail.index=i;if(isNonVisual(this._grid.items[i])){this._grid.items.splice(i,1);iLen-=1;}else{i+=1;}}};proto.moveTo=function(orig,dst){this._grid.items.splice(dst,0,this._grid.items.splice(orig,1)[0]);};proto._styleHack=function(){var style=this._template.querySelector('style');this.appendChild(style.cloneNode(true));};var stylesheet=baseurl+'style.css';var template=document.createElement('template');template.innerHTML=`<style scoped>
@import url(${stylesheet});</style>
<content></content>`;return document.registerElement('gaia-grid',{prototype:proto});})(window);

View file

@ -0,0 +1,409 @@
.icon[data-app-state="loading"]:after {
content: "";
background: no-repeat top center url('images/app_install_spinner.png');
background-size: contain;
height: 8.4rem;
position: absolute;
top: 0;
left: 0;
width: 100%;
/**
Keyframe must be defined outside of the web component.
See bug 1018269
*/
animation: rotate 2.25s linear infinite;
}
.icon[data-app-state="loading"] {
/**
We must align this value with the value of [data-app-state]:after height the background size
here is overridden at the element level elsewhere which causes the spinner to be aligned too
low.
*/
background-size: 8.4rem !important;
background-image: url('images/app_installing.png') !important;
}
.icon[data-app-state="unrecoverable"] {
background-image: url('images/app_install_unrecoverable.png') !important;
}
.icon[data-app-state="error"] {
background-image: url('images/app_install_failed.png') !important;
}
.icon[data-app-state="paused"] {
background-image: url('images/app_install_canceled.png') !important;
}
.icon {
position: absolute;
transform-origin: 0 0;
display: inline-block;
text-align: center;
background: no-repeat top center;
z-index: 3;
outline: 0;
}
.icon.launching {
opacity: .65;
}
/* XXX: Override the .remove element */
.edit-mode .collection.hovered .remove {
background: url(images/add.png) no-repeat;
background-size: 2rem;
}
.icon p {
pointer-events: none;
height: 3.2rem;
width: 100%;
margin: 0;
padding: 0;
}
.icon .title {
display: inline-block;
margin-top: 0.1rem;
/* We need this rule in order not to hide the drop shadow */
padding: 0 0.2rem 1rem;
text-shadow: 0.1rem 0.1rem 0.3rem rgba(0, 0, 0, 0.3),
0.2rem 0.4rem 1rem rgba(0, 0, 0, 0.4);
font-size: 1.4rem;
color: #fff;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
width: calc(100% - 0.4rem);
box-sizing: border-box;
vertical-align: top;
transition: opacity var(--transition-duration);
}
/* We allow more space for text in the search app by hooking into the text-rows attribute on gaia-grid. */
[text-rows="3"] .icon .title {
height: 5.8rem;
}
[cols="4"] .icon .title {
/* Font size is the same independent on grid configuration */
font-size: calc(1.2rem * 1.333);
margin-top: 0.5rem;
line-height: 1.94rem;
}
.edit-mode .icon.collapsed {
pointer-events: none;
}
.icon.collapsed .title {
opacity: 0;
}
.icon.hidden {
pointer-events: none;
opacity: 0;
}
.divider {
position: absolute;
width: 100%;
padding-top: 2.3rem;
border-left: 0.6rem solid transparent;
border-right: 0.6rem solid transparent;
box-sizing: border-box;
z-index: 2;
}
[cols="4"] .divider {
padding-top: 1.6rem;
}
.divider span.spacer {
position: absolute;
bottom: 0;
display: block;
background: linear-gradient(to bottom, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0.5));
margin: 0 25%;
width: 50%;
height: 0.2rem;
transition: opacity var(--transition-duration);
}
.dragging .icon.active:not(.hidden) {
z-index: 6;
opacity: 0.65;
}
.dragging .divider:not(.group),
.icon:not(.active),
.dropped {
transition: transform var(--transition-duration),
opacity var(--transition-duration);
}
.icon.active {
will-change: transform;
}
.edit-mode .icon .remove {
display: block;
position: absolute;
top: 0.1rem;
left: 0.5rem;
width: 2.6rem;
height: 2.6rem;
background: url(images/remove.png) no-repeat;
background-size: 2rem;
/*
Ensure that remove is on top of the icon and has some extra
padding so it is easy to click.
*/
z-index: 200;
padding: 0.5rem;
}
.icon .remove,
.icon.collapsed .remove,
.edit-mode .icon.active .remove {
display: none;
}
.edit-mode .icon.editable .title {
background-color: rgba(132, 132, 132, 0.7);
border-radius: 2rem;
margin-top: .4rem;
padding: 0 1rem;
width: auto;
max-width: 100%;
}
/*
Disable events for placeholders, so we don't trigger touch events in edit mode.
We only do this in edit-mode, otherwise we might trigger entering edit mode
instead of the context menu.
*/
.edit-mode .placeholder {
pointer-events: none;
}
#confirm-message {
z-index: 100;
}
.dragging .group.active {
z-index: 5;
}
.divider.group {
border: none;
padding: 0;
}
.group > span {
display: block;
position: absolute;
width: 100%;
transition: background-color var(--transition-duration),
opacity var(--transition-duration);
}
.group:not(.active):not(.newly-created) > span {
transition: background-color var(--transition-duration),
opacity var(--transition-duration),
transform var(--transition-duration);
}
.group.active > span {
will-change: transform;
}
.group .header {
height: 4rem;
z-index: 4;
}
.group .header span,
.group .header button {
position: absolute;
height: 4rem;
top: 0;
background-position: center top;
background-repeat: no-repeat;
background-size: 100% 2rem;
transition: transform 0.25s, opacity 0.25s;
}
.group .header .gripper {
left: calc(50% - 4.2rem);
width: 8.4rem;
background-image: url('images/move_gripper.png');
opacity: 0;
transform: translate(0, -100%);
pointer-events: none;
}
.edit-mode .group:not(.collapsed) .header .gripper {
opacity: 1;
transform: translate(0, 0);
pointer-events: auto;
}
.group .header .toggle {
width: 5.34rem;
right: 0;
border: none;
margin: 0;
padding: 0;
background-color: transparent;
background-image: url('images/collapse_arrow.png');
transform-origin: 50% 1.6rem;
pointer-events: auto;
}
.group .header .toggle.toggling {
opacity: 0.5;
transition: transform 0.25s;
}
.group.collapsed .header .toggle {
transform: translateY(2rem) rotateZ(180deg);
}
.group.active .header .toggle {
opacity: 0.5;
}
.group .background {
background-color: rgba(255, 255, 255, 0.15);
opacity: 0;
pointer-events: none;
height: 0.1rem;
transform-origin: 0 0;
}
.group.odd:not(.newly-created) .background,
.edit-mode .group:not(.newly-created) .background {
opacity: 1;
}
.group.active .background {
background-color: rgba(51, 51, 51, 0.9);
}
.group.hovering .background,
.group.drop-target .background {
background-color: rgba(27, 185, 225, 0.5);
}
.group .shadow {
background-color: rgba(255, 255, 255, 0.15);
opacity: 0;
pointer-events: none;
}
.edit-mode .group.active .shadow {
background-color: transparent;
box-shadow: 0 0.9rem 1.2rem rgba(0, 0, 0, 0.63);
opacity: 1;
}
.group .separator {
margin: 0;
height: 0.8rem;
pointer-events: none;
}
.group .separator > span {
display: block;
width: 100%;
height: 100%;
transition: transform 0.25s, opacity 0.25s;
opacity: 0;
}
.group.odd .separator {
opacity: 1;
}
.group.odd .separator > span {
background-color: rgba(255, 255, 255, 0.15);
opacity: 1;
}
.edit-mode .group .separator,
.edit-mode .group .separator > span {
opacity: 0;
}
/* For preventing entering edit mode when long-pressing on a placeholder */
.edit-mode .group .background,
.edit-mode .group .shadow,
.group.collapsed .header,
.group.collapsed .background,
.group.collapsed .shadow {
pointer-events: none;
}
.edit-mode .group.collapsed .background {
pointer-events: auto;
}
.dragging .group:not(.active) .separator {
opacity: 1;
}
.dragging .group:not(.active):not(.invalid-drop) .separator > span {
background-color: #0095dd;
transform: scaleY(0.325);
opacity: 0.4;
}
.dragging .group.hovered:not(.active) .separator > span {
transform: scaleY(1);
opacity: 1;
}
/* A hint element for dragging items to the top of the group */
.edit-mode::after {
content: ' ';
display: block;
width: 100%;
height: 0.8rem;
z-index: 2;
opacity: 0;
background-color: #0095dd;
position: relative;
top: -0.8rem;
transition: opacity 0.25s;
}
.edit-mode.hover-over-top::after {
opacity: 1;
}
/* Shift container downwards when hovering over the top to reveal the group
* creation hint.
*/
.edit-mode {
transition: transform 0.25s;
}
.edit-mode.hover-over-top {
transform: translateY(0.8rem);
}
/* RTL View */
:-moz-dir(rtl) .group .header .toggle {
left: 0;
right: unset;
}

View file

@ -0,0 +1,24 @@
/**
Some css properties are global (keyframes) and cannot be specified
to to only apply to our shadow dom so we hack around this by including
this file without scoping it.
*/
/**
Bug 1018269 - we need to specify the keyframe outside
of the web component...
*/
@keyframes rotate {
from {
transform: rotate(1deg)
}
to {
transform: rotate(360deg)
}
}
:-moz-dir(rtl) gaia-grid {
direction: ltr;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

View file

@ -0,0 +1,62 @@
'use strict';
/* global ComponentUtils */
window.GaiaMenu = (function(win) {
// Extend from HTMLElement prototype
var proto = Object.create(HTMLElement.prototype);
// Allow baseurl to be overridden (used for demo page)
var baseurl = window.GaiaMenuBaseurl ||
'/shared/elements/gaia_menu/';
proto.createdCallback = function () {
var shadow = this.createShadowRoot();
this._template = template.content.cloneNode(true);
var cancelButton = this._template.querySelector('.gaia-menu-cancel button');
cancelButton.addEventListener('click', function () {
this.hide();
this.dispatchEvent(new CustomEvent('gaiamenu-cancel'));
}.bind(this));
shadow.appendChild(this._template);
ComponentUtils.style.call(this, baseurl);
document.l10n.ready.then(this.localize.bind(this));
document.addEventListener('DOMRetranslated', this.localize.bind(this));
};
proto.localize = function() {
document.l10n.formatValue('gaia-menu-cancel').then(value => {
this.shadowRoot.querySelector('button').textContent = value;
});
};
proto.show = function() {
this.removeAttribute('hidden');
};
proto.hide = function() {
this.setAttribute('hidden', 'hidden');
};
var template = document.createElement('template');
template.innerHTML =
`<form role="dialog" data-type="action">
<content select="header"></content>
<menu>
<content select="button"></content>
<span class="gaia-menu-cancel">
<button>Cancel</button>
</span>
</menu>
</form>`;
// Register and return the constructor
return document.registerElement('gaia-menu', { prototype: proto });
})(window);

View file

@ -0,0 +1,314 @@
/* ----------------------------------
* gaia_menu
* ---------------------------------- */
/* default alignment follows the UI direction, not the content direction */
:-moz-dir(ltr) [dir] { text-align: left; }
:-moz-dir(rtl) [dir] { text-align: right; }
/* Main dialog setup */
gaia-menu {
background-color: #2d2d2d;
overflow: hidden;
position: fixed;
z-index: 100;
top: 0;
left: 0;
right: 0;
bottom: 0;
padding: 0 0 7rem;
/**
* Using "font-size: 0" to avoid the unwanted visual space (about 3px) created
* by white spaces and line breaks in the code between inline-block elements.
*/
font-size: 0;
color: #fff;
display: block;
transition: transform ease-in-out var(--transition-duration),
visibility var(--transition-duration);
}
gaia-menu[hidden] {
transform: translateY(100%);
visibility: hidden;
}
gaia-menu:before {
content: '';
display: inline-block;
vertical-align: top;
width: 0.1rem;
height: 100%;
margin-inline-start: -0.1rem;
}
header {
-moz-box-sizing: border-box;
font-size: 1.6rem;
position: absolute;
top: 0;
left: 0;
right: 0;
z-index: 10;
height: 5rem;
line-height: 4.9rem;
color: #fff;
white-space: nowrap;
text-overflow: ellipsis;
display: block;
overflow: hidden;
font-weight: normal;
padding: 0 3rem;
border-bottom: 0.1rem solid #616262;
}
header h1 {
font-size: 1.6rem;
line-height: 4.9rem;
color: #fff;
white-space: nowrap;
text-overflow: ellipsis;
display: block;
overflow: hidden;
margin: 0;
height: 100%;
font-weight: normal;
}
/* Generic set of actions in toolbar */
header menu.toolbar {
height: 100%;
margin: 0 -3rem;
margin-inline-start: 1rem;
padding: 0;
}
header:-moz-dir(ltr) menu.toolbar { float: right; }
header:-moz-dir(rtl) menu.toolbar { float: left; }
header menu.toolbar a,
header menu.toolbar button {
-moz-box-sizing: border-box;
position: relative;
width: auto;
min-width: 5rem;
height: 4.9rem;
margin-bottom: 0;
padding: 0 1rem;
border-radius: 0;
line-height: 4.9rem;
background: none;
text-align: center;
text-shadow: none;
z-index: 5;
}
header:-moz-dir(ltr) menu.toolbar a,
header:-moz-dir(ltr) menu.toolbar button {
float: left;
}
header:-moz-dir(rtl) menu.toolbar a,
header:-moz-dir(rtl) menu.toolbar button {
float: right;
}
header a,
header button {
border: none;
padding: 0;
overflow: hidden;
font-weight: 400;
font-size: 1.5rem;
line-height: 1.1em;
color: #fff;
border-radius: 0;
text-decoration: none;
}
button::-moz-focus-inner {
outline: none;
border: none;
}
/* Pressed state */
header a:active .icon:after,
header button:active .icon:after,
header menu.toolbar a:active,
header menu.toolbar button:active {
background: #008aaa;
}
/* Disabled state */
header menu.toolbar a[aria-disabled="true"],
header menu.toolbar button[disabled] {
opacity: 0.5;
pointer-events: none;
}
/* Icon definitions */
header .icon {
position: relative;
float: none;
display: inline-block;
vertical-align: top;
width: 4rem;
height: 4.9rem;
margin: 0 -1rem;
background: transparent no-repeat center center / 3rem auto;
font-size: 0;
overflow: hidden;
}
header .icon.icon-close {
background-image: url(images/icons/close.png);
}
header .icon.icon-back {
background-image: url(images/icons/back.png);
}
/* Navigation links (back, cancel, etc) */
header > button,
header > a {
width: 5rem;
height: 4.9rem;
background: none;
overflow: visible;
margin: 0 -1rem;
margin-inline-start: -3rem;
position: relative;
}
header:-moz-dir(ltr) > button,
header:-moz-dir(ltr) > a {
float: left;
}
header:-moz-dir(rtl) > button,
header:-moz-dir(rtl) > a {
float: right;
}
header > button::-moz-focus-inner {
border: 0;
padding: 0;
}
header > button .icon,
header > a .icon {
position: static;
display: block;
width: 3rem;
height: 4.9rem;
margin: 0;
overflow: visible;
font-size: 0;
}
header > button .icon:after,
header > a .icon:after {
content: "";
position: absolute;
offset-inline-start: 0;
top: 0;
z-index: -1;
width: 3rem;
height: 4.9rem;
}
/* Content */
section {
color: #fff;
position: absolute;
top: 7rem;
left: 1.5rem;
right: 1.5rem;
bottom: 2rem;
font-size: 1.6rem;
overflow: scroll;
}
/* Specific component code */
menu {
margin: 0;
padding: 0;
max-height: calc(100% - 13.5rem); /*header(5rem) + footer(7rem) + padding(1.5rem)*/
height: auto;
padding-top: 1.5rem;
overflow: auto;
width: auto;
border: none;
background: none;
position: absolute;
left: 0;
right: 0;
bottom: 7rem;
}
button {
width: calc(100% - 3rem);
height: 4rem;
-moz-box-sizing: border-box;
vertical-align: middle;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
font-weight: normal;
line-height: 4rem;
outline: none;
font-size: 1.6rem;
text-shadow: none;
padding: 0 1.2rem;
margin: 0 1.5rem 1rem;
background: rgba(87, 87, 87, 0.8);
border: none;
border-radius: 0;
position: relative;
color: #fff;
font-family: sans-serif;
font-style: italic;
}
button:-moz-dir(ltr) { text-align: left; }
button:-moz-dir(rtl) { text-align: right; }
span.gaia-menu-cancel {
position: fixed;
width: 100%;
background: #4d4d4d;
height: 7rem;
offset-inline-start: 0;
bottom: 0;
}
span.gaia-menu-cancel button {
position: fixed;
bottom: 0;
offset-inline-start: 0;
color: #333;
background: #d8d8d8;
text-align: center;
border: none;
margin-bottom: 1.5rem;
border-radius: 2rem;
}
button:nth-last-child(2) {
margin-bottom: 1.5rem;
}
/* Press state */
button:active,
span.gaia-menu-cancel button:active {
background: #00aacc;
color: #fff;
}
/* Disabled */
button[disabled] {
background-color: rgba(87, 87, 87, 0.8);
color: rgba(255, 255, 255, 0.4);
opacity: 0.5;
pointer-events: none;
}
button[disabled]:last-child {
background-color: #e7e7e7;
color: #a6a6a6;
opacity: 1;
}

View file

@ -0,0 +1,24 @@
;'use strict';(function(exports){var datastore;var DATASTORE_NAME='bookmarks_store';var readyState;var listeners=Object.create(null);function init(){return new Promise(function doInit(resolve,reject){if(readyState==='initialized'){resolve();return;}
if(readyState==='initializing'){document.addEventListener('ds-initialized',function oninitalized(){document.removeEventListener('ds-initialized',oninitalized);resolve();});return;}
readyState='initializing';if(!navigator.getDataStores){console.error('Bookmark store: DataStore API is not working');reject({name:'NO_DATASTORE'});readyState='failed';return;}
navigator.getDataStores(DATASTORE_NAME).then(function(ds){if(ds.length<1){console.error('Bookmark store: Cannot get access to the Store');reject({name:'NO_ACCESS_TO_DATASTORE'});readyState='failed';return;}
datastore=ds[0];datastore.addEventListener('change',onchangeHandler);readyState='initialized';document.dispatchEvent(new CustomEvent('ds-initialized'));resolve();},reject);});}
function doGetAll(resolve,reject){var result=Object.create(null);var cursor=datastore.sync();function cursorResolve(task){switch(task.operation){case'update':case'add':result[task.data.id]=task.data;break;case'remove':delete result[task.data.id];break;case'clear':result=Object.create(null);break;case'done':resolve(result);return;}
cursor.next().then(cursorResolve,reject);}
cursor.next().then(cursorResolve,reject);}
function get(id){return new Promise(function doGet(resolve,reject){init().then(function onInitialized(){datastore.get(id).then(resolve,reject);},reject);});}
function getAll(){return new Promise(function doGet(resolve,reject){init().then(doGetAll.bind(null,resolve,reject),reject);});}
function onchangeHandler(event){var operation=event.operation;var callbacks=listeners[operation];callbacks&&callbacks.forEach(function iterCallback(callback){datastore.get(event.id).then(function got(result){callback.method.call(callback.context||this,{type:operation,target:result||event});});});}
function addEventListener(type,callback){var context;if(!(type in listeners)){listeners[type]=[];}
var cb=callback;if(typeof cb==='object'){context=cb;cb=cb.handleEvent;}
if(cb){listeners[type].push({method:cb,context:context});init();}}
function removeEventListener(type,callback){if(!(type in listeners)){return false;}
var callbacks=listeners[type];var length=callbacks.length;for(var i=0;i<length;i++){var thisCallback=callback;if(typeof thisCallback==='object'){thisCallback=callback.handleEvent;}
if(callbacks[i]&&callbacks[i].method===thisCallback){callbacks.splice(i,1);return true;}}
return false;}
function add(data){return new Promise(function doAdd(resolve,reject){init().then(function onInitialized(){var id=data.url;Object.defineProperty(data,'id',{enumerable:true,configurable:false,writable:false,value:id});datastore.add(data,id).then(function add_success(){resolve(true);},function add_error(){datastore.put(data,id).then(function put_success(){resolve();},reject);});},reject);});}
function getRevisionId(){return new Promise(function doGet(resolve,reject){init().then(function onInitialized(){resolve(datastore.revisionId);},reject);});}
function put(data){return new Promise(function doAdd(resolve,reject){init().then(function onInitialized(){datastore.put(data,data.id).then(function success(){resolve();},reject);},reject);});}
function remove(id){return new Promise(function doRemove(resolve,reject){init().then(function onInitialized(){datastore.remove(id).then(resolve,reject);},reject);});}
function clear(){return new Promise(function doClear(resolve,reject){init().then(function onInitialized(){datastore.clear().then(resolve,reject);},reject);});}
exports.BookmarksDatabase={get:get,getAll:getAll,getRevisionId:getRevisionId,addEventListener:addEventListener,removeEventListener:removeEventListener,add:add,put:put,remove:remove,clear:clear};}(window));

View file

@ -0,0 +1,45 @@
(function(exports) {
'use strict';
/**
* ComponentUtils is a utility which allows us to use web components earlier
* than we should be able to by polyfilling and fixing platform deficiencies.
*/
exports.ComponentUtils = {
/**
* Injects a style.css into both the shadow root and outside the shadow
* root so we can style projected content. Bug 992249.
*/
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';
// Wait for the stylesheet to load before injecting
// it into the shadow-dom. This is to work around
// bug 1003294, let's review once landed.
style.addEventListener('load', function() {
// Put a clone of the stylesheet into the shadow-dom.
// We have to use two <style> nodes, to work around
// the lack of `:host` (bug 992245) and `:content`
// (bug 992249) selectors. Once we have those we
// can do all our styling from a single style-sheet
// within the shadow-dom.
if (self.shadowRoot) {
self.shadowRoot.appendChild(style.cloneNode(true));
}
self.style.visibility = '';
});
}
};
}(window));

View file

@ -0,0 +1,147 @@
/* global LazyLoader */
(function(exports) {
'use strict';
var resources = ['/shared/js/component_utils.js',
'/shared/elements/gaia_buttons/script.js',
'/shared/elements/gaia_confirm/script.js',
'/shared/elements/gaia_menu/script.js'];
/**
Generic dialog helper this _depends_ on <gaia-confirm> but is not required
to be loaded as part of the main gaia-confirm script.
*/
function ConfirmDialogHelper(config) {
this.config = config;
}
ConfirmDialogHelper.prototype = {
show: function(parent) {
LazyLoader.load(resources, this._show.bind(this, parent));
},
_show: function(parent) {
var config = this.config;
var wrapper = document.createElement('div');
// only include a cancel button if the config was given...
var cancelButton = config.cancel ?
'<button class="cancel" type="button"></button>' :
'';
wrapper.innerHTML =
'<gaia-confirm>' +
'<h1></h1>' +
'<p></p>' +
'<gaia-buttons skin="dark">' +
cancelButton +
'<button class="confirm" type="button"></button>' +
'</gaia-buttons>' +
'</gaia-confirm>';
var element = wrapper.firstElementChild;
this.element = element;
element.dataset.type = config.type;
element.addEventListener('confirm', this);
element.addEventListener('cancel', this);
// XXX: Primarily here for pressing the home screen button.
// The home button triggers a hashchange of the homescreen.
window.addEventListener('hashchange', this);
// TODO: Add visibility change handling...
var title = element.querySelector('h1');
var body = element.querySelector('p');
var cancel = element.querySelector('.cancel');
var confirm = element.querySelector('.confirm');
var setL10nAttributes = function (element, options){
if ('string' === typeof options) {
navigator.mozL10n.setAttributes(element, options);
}
if(options.id) {
navigator.mozL10n.setAttributes(element, options.id, options.args);
}
};
setL10nAttributes(title, config.title);
setL10nAttributes(body, config.body);
setL10nAttributes(confirm, config.confirm.title);
if (config.cancel) {
setL10nAttributes(cancel, config.cancel.title);
}
if (config.confirm.type) {
confirm.classList.add(config.confirm.type);
}
document.activeElement.blur();
element.setAttribute('hidden', '');
parent.appendChild(element);
// This nested requestAnimationFrame is to work around the coalescing
// of the style changes associated with removing of the 'hidden'
// attribute with the creation of the element.
// For whatever reason, flushing the style with the usual trick of
// accessing clientTop doesn't work, and a setTimeout requires an
// unreasonably lengthy timeout (>50ms) to work, and that may not be
// a reliable solution.
// This work-around, though gross, appears to work consistently without
// introducing too much lag or extra work.
window.requestAnimationFrame(() => {
window.requestAnimationFrame(() => {
element.removeAttribute('hidden');
window.dispatchEvent(new CustomEvent('gaia-confirm-open'));
});
});
},
destroy: function() {
if (!this.element) {
return;
}
// Ensure cleanup of our hacks!
window.removeEventListener('hashchange', this);
this.element.addEventListener('transitionend',
function removeAfterHide(e) {
if (e.target !== this.element) {
return;
}
this.element.parentNode.removeChild(this.element);
this.element = null;
window.dispatchEvent(new CustomEvent('gaia-confirm-close'));
}.bind(this));
this.element.setAttribute('hidden', '');
},
handleEvent: function(e) {
// Ensure we hide the dialog in the face of other errors.
this.destroy();
switch (e.type) {
case 'hashchange':
// Hashchange is only here to trigger this to call destroy.
break;
case 'confirm':
var confirm = this.config.confirm.cb;
confirm && confirm();
break;
case 'cancel':
var cancel = this.config.cancel.cb;
cancel && cancel();
break;
}
}
};
// This name is intentionally verbose.
window.ConfirmDialogHelper = ConfirmDialogHelper;
}(window));

View file

@ -0,0 +1,16 @@
;'use strict';(function(exports){var datastore;var DATASTORE_NAME='vertical_preferences_store';var readyState;var listeners=Object.create(null);function init(){return new Promise(function doInit(resolve,reject){if(readyState==='initialized'){resolve();return;}
if(readyState==='initializing'){document.addEventListener('vps-initialized',function oninitalized(){document.removeEventListener('vps-initialized',oninitalized);resolve();});return;}
readyState='initializing';if(!navigator.getDataStores){console.error('Preferences store: DataStore API is not working');reject({name:'NO_DATASTORE'});readyState='failed';return;}
navigator.getDataStores(DATASTORE_NAME).then(function(ds){if(ds.length<1){console.error('Preferences store: Cannot get access to the Store');reject({name:'NO_ACCESS_TO_DATASTORE'});readyState='failed';return;}
datastore=ds[0];datastore.addEventListener('change',onchangeHandler);readyState='initialized';document.dispatchEvent(new CustomEvent('vps-initialized'));resolve();},reject);});}
function onchangeHandler(event){var operation=event.operation;var callbacks=listeners[operation];callbacks&&callbacks.forEach(function iterCallback(callback){datastore.get(event.id).then(function got(result){callback.method.call(callback.context||this,{type:operation,target:{name:event.id,value:result}});});});}
function addEventListener(type,callback){var context;if(!(type in listeners)){listeners[type]=[];}
var cb=callback;if(typeof cb==='object'){context=cb;cb=cb.handleEvent;}
if(cb){listeners[type].push({method:cb,context:context});init();}}
function removeEventListener(type,callback){if(!(type in listeners)){return false;}
var callbacks=listeners[type];var length=callbacks.length;for(var i=0;i<length;i++){var thisCallback=callback;if(typeof thisCallback==='object'){thisCallback=callback.handleEvent;}
if(callbacks[i]&&callbacks[i].method===thisCallback){callbacks.splice(i,1);return true;}}
return false;}
function get(id){return new Promise(function doGet(resolve,reject){init().then(function onInitialized(){datastore.get(id).then(resolve,reject);},reject);});}
function put(id,value){return new Promise(function doAdd(resolve,reject){init().then(function onInitialized(){datastore.put(value,id).then(function success(){resolve();},reject);},reject);});}
exports.verticalPreferences={get:get,put:put,addEventListener:addEventListener,removeEventListener:removeEventListener};}(window));

View file

@ -0,0 +1,186 @@
'use strict';
/**
* IccHelper redirect calls to ICC related APIs to correct object. IccHelper is
* created for backward compatibility of gaia master after the patch of
* bug 814637 landed in m-c. In the patch the interface provided by IccManager
* was moved to a MozIcc object. Details please refer to the URL[1].
* The helper *MUST* be removed once all gaia developement no longer depend
* on b2g26.
* [1]: https://wiki.mozilla.org/WebAPI/WebIccManager/Multi-SIM
*/
(function(exports) {
var _iccManager = navigator.mozIccManager;
var _iccProxy = null;
Object.defineProperty(exports, 'IccHelper', {
configurable: true,
get: function() {
return _iccProxy;
},
// This is for code that sets value to IccHelper. And for unit tests that
// mock IccHelper.
set: function(value) {
_iccProxy = value;
}
});
if (_iccManager && _iccManager.getIccById) {
var activeIccObj = null;
var eventListeners = {};
var cachedEventListeners = {}; // cache on + 'eventName' event handlers
var events = ['cardstatechange', 'iccinfochange',
'stkcommand', 'stksessionend'];
var getters = ['iccInfo', 'cardState'];
var methods = ['sendStkResponse', 'sendStkMenuSelection',
'sendStkTimerExpiration', 'sendStkEventDownload'];
var domRequests = ['getCardLock', 'unlockCardLock', 'setCardLock',
'getCardLockRetryCount', 'readContacts',
'updateContact', 'iccOpenChannel', 'iccExchangeAPDU',
'iccCloseChannel'];
var getterTemplate = function(name) {
return function() {
if (activeIccObj) {
return activeIccObj[name];
} else {
return null;
}
};
};
var methodTemplate = function(name) {
return function() {
if (activeIccObj) {
return activeIccObj[name].apply(activeIccObj, arguments);
}
};
};
// Multi-SIM API available
var createIccProxy = function() {
var iccProxy = {
addEventListener: function(eventName, callback) {
if (typeof callback !== 'function') {
return;
}
if (events.indexOf(eventName) === -1) {
return;
}
var listeners = eventListeners[eventName];
if (listeners == null) {
listeners = eventListeners[eventName] = [];
}
if (listeners.indexOf(callback) === -1) {
listeners.push(callback);
}
},
removeEventListener: function(eventName, callback) {
var listeners = eventListeners[eventName];
if (listeners) {
var index = listeners.indexOf(callback);
if (index !== -1) {
listeners.splice(index, 1);
}
}
}
};
getters.forEach(function(getter) {
Object.defineProperty(iccProxy, getter, {
enumerable: true,
get: getterTemplate(getter)
});
});
methods.forEach(function(method) {
iccProxy[method] = methodTemplate(method);
});
domRequests.forEach(function(request) {
iccProxy[request] = methodTemplate(request);
});
events.forEach(function(eventName) {
// Define 'on' + eventName properties
// Assigning an event handler and adding an event listener are
// handled separately. We need to simulate the same behavior in
// IccHelper.
Object.defineProperty(iccProxy, 'on' + eventName, {
enumerable: true,
set: function(newListener) {
var oldListener = cachedEventListeners[eventName];
if (oldListener) {
iccProxy.removeEventListener(eventName, oldListener);
}
cachedEventListeners[eventName] = newListener;
if (newListener) {
iccProxy.addEventListener(eventName, newListener);
}
},
get: function() {
return cachedEventListeners[eventName];
}
});
});
return iccProxy;
};
// Initialize icc proxy
_iccProxy = createIccProxy();
if (_iccManager.iccIds && _iccManager.iccIds.length) {
activeIccObj = _iccManager.getIccById(_iccManager.iccIds[0]);
if (activeIccObj) {
// register to callback
events.forEach(function(eventName) {
activeIccObj.addEventListener(eventName, function(event) {
var listeners = eventListeners[eventName];
if (listeners) {
listeners.forEach(function(listener) {
listener(event);
});
}
});
});
}
}
_iccManager.oniccdetected = function(event) {
if (_iccProxy.cardState == null) {
activeIccObj = _iccManager.getIccById(event.iccId);
if (activeIccObj) {
// register to callback
events.forEach(function(eventName) {
activeIccObj.addEventListener(eventName, function(event) {
var listeners = eventListeners[eventName];
if (listeners) {
listeners.forEach(function(listener) {
listener(event);
});
}
});
});
// trigger cardstatechange and iccinfochange manually when a mozIcc
// object becomes valid (detected).
['cardstatechange', 'iccinfochange'].forEach(function(eventName) {
if (eventListeners[eventName]) {
eventListeners[eventName].forEach(function(listener) {
listener();
});
}
});
}
}
};
} else {
_iccProxy = _iccManager;
}
})(window);

View file

@ -0,0 +1,32 @@
;'use strict';(function IconsHelper(exports){const ICON_CACHE_PERIOD=24*60*60*1000;const FETCH_XHR_TIMEOUT=10000;const DEBUG=false;var dataStore=null;function getDefaultIconSize(){var dpr=window.devicePixelRatio;return(dpr&&dpr>1)?142:84;}
function sizeIsNearer(size1,size2,targetSize){var delta1=Math.abs(targetSize-size1);var delta2=Math.abs(targetSize-size2);return(delta1<=delta2);}
function getIcon(uri,iconTargetSize,placeObj={},siteObj={}){var iconUrl=null;iconTargetSize=iconTargetSize*window.devicePixelRatio;if(siteObj.webManifestUrl&&siteObj.webManifest){iconUrl=getBestIconFromWebManifest(siteObj.webManifest,iconTargetSize);if(DEBUG&&iconUrl){console.log('Icon from Web Manifest');}}
if(!iconUrl&&siteObj.manifest&&siteObj.manifest.icons){iconUrl=getBestIconFromWebManifest({icons:_convertToWebManifestIcons(siteObj.manifest,siteObj.origin||siteObj.manifest.origin)},iconTargetSize);if(DEBUG&&iconUrl){console.log('Icon from Firefox App Manifest');}}
if(!iconUrl&&placeObj&&placeObj.icons){iconUrl=getBestIconFromMetaTags(placeObj.icons,iconTargetSize);if(DEBUG&&iconUrl){console.log('Icon from Meta tags');}}
if(!iconUrl){var a=document.createElement('a');a.href=uri;iconUrl=a.origin+'/favicon.ico';if(iconTargetSize){iconUrl+='#-moz-resolution='+iconTargetSize+','+iconTargetSize;}
DEBUG&&console.log('Icon from favicon.ico');}
return new Promise(resolve=>{resolve(iconUrl);});}
function getIconBlob(uri,iconTargetSize,placeObj={},siteObj={}){return new Promise((resolve,reject)=>{getIcon(uri,iconTargetSize,placeObj,siteObj).then(iconUrl=>{getStore().then(iconStore=>{iconStore.get(iconUrl).then(iconObj=>{if(!iconObj||!iconObj.timestamp||Date.now()-iconObj.timestamp>=ICON_CACHE_PERIOD){return fetchIconBlob(iconUrl).then(iconBlob=>{var img=document.createElement('img');var icon=new Icon(img,uri);icon.renderBlob(iconBlob,{size:iconTargetSize,onLoad:function(blob){var iconObj={blob:blob,originalUrl:iconUrl.toString(),timestamp:Date.now()};resolve(iconObj);iconStore.add(iconObj,iconUrl);},onerror:function(e){reject(`Failed to fetch icon ${iconUrl}`);}});}).catch(err=>{reject(`Failed to fetch icon ${iconUrl}: ${err}`);});}
return resolve(iconObj);}).catch(err=>{reject(`Failed to get icon from dataStore: ${err}`);});}).catch(err=>{reject(`Error opening the dataStore: ${err}`);});});});}
function setElementIcon(icon,targetSize){return getIconBlob(icon.bookmark.url,targetSize,icon.bookmark,icon.bookmark).then(iconObj=>{if(iconObj.blob){icon.icon=iconObj.blob;return Promise.resolve();}else if(icon.bookmark.icon){return fetchIconBlob(icon.bookmark.icon).then(iconBlob=>{icon.icon=iconBlob;return Promise.resolve();},Promise.reject.bind(Promise));}
return Promise.reject('No icon data found');},Promise.reject.bind(Promise));}
function getBestIconFromWebManifest(webManifest,iconSize){var icons=webManifest.icons;if(!icons){return null;}
var maxSize=10000;var bestSize=maxSize;var iconURL=null;iconSize=iconSize||getDefaultIconSize();icons.forEach((potentialIcon)=>{if(!iconURL){iconURL=potentialIcon.src;}
var sizes=Array.from(potentialIcon.sizes);var nearestSize=getNearestSize(sizes,iconSize,bestSize);if(nearestSize!==bestSize&&sizeIsNearer(nearestSize,bestSize,iconSize)){iconURL=potentialIcon.src;bestSize=nearestSize;}});return iconURL?iconURL:null;}
function _convertToWebManifestIcons(manifest,origin){return Object.keys(manifest.icons).map(function(size){var url=manifest.icons[size];var sizes=[size+'x'+size];url=url.indexOf('http')>-1?url:origin+url;return{src:new URL(url),sizes:sizes};});}
function getBestIconFromMetaTags(icons,iconSize){if(!icons){return null;}
iconSize=iconSize||getDefaultIconSize();var iconURL=null;var bestSize=10000;Object.keys(icons).forEach((uri)=>{var potentialIcon=icons[uri];if(!iconURL){iconURL=uri;}
var sizes=Array.from(potentialIcon.sizes);var nearestSize=getNearestSize(sizes,iconSize,bestSize);if(nearestSize!==bestSize&&sizeIsNearer(nearestSize,bestSize,iconSize)){iconURL=uri;bestSize=nearestSize;}
if(potentialIcon.rel==='apple-touch-icon'||potentialIcon.rel==='apple-touch-icon-precomposed'){var moreInfoUrl='https://developer.mozilla.org/en-US/'+'Apps/Build/Icon_implementation_for_apps#General_icons_for_web_apps';console.warn('Warning: The apple-touch icons are being used '+'as a fallback only. They will be deprecated in '+'the future. See '+moreInfoUrl);}});return iconURL||null;}
function getNearestSize(sizes,iconSize,bestSize){var bogusSize=10000;if(!bestSize){bestSize=bogusSize;}
var nearestSize=sizes.reduce(function(nearestSize,sizeString,idx){var size=widthFromSizeString(sizeString);if(isNaN(size)){return nearestSize;}
if(sizeIsNearer(size,nearestSize,iconSize)){return size;}else{return nearestSize;}},bestSize);return nearestSize===bogusSize?-1:nearestSize;}
function widthFromSizeString(size){size=size||'';var xIndex=size.indexOf('x');if(!xIndex){return NaN;}
return parseInt(size.substr(0,xIndex));}
function getStore(){return new Promise(resolve=>{if(dataStore){return resolve(dataStore);}
navigator.getDataStores('icons').then(stores=>{dataStore=stores[0];return resolve(dataStore);});});}
function clear(){return getStore().then(iconStore=>{iconStore.clear();});}
function fetchIcon(iconUrl){return new Promise((resolve,reject)=>{fetchIconBlob(iconUrl).then((iconBlob)=>{var img=document.createElement('img');img.src=URL.createObjectURL(iconBlob);img.onload=()=>{var iconSize=Math.max(img.naturalWidth,img.naturalHeight);resolve({blob:iconBlob,url:iconUrl,size:iconSize,timestamp:Date.now()});};img.onerror=()=>{reject(new Error(`Error while loading image.`));};}).catch((e)=>{reject(new Error(`Error while loading image: ${e}`));});});}
function fetchIconBlob(iconUrl){return new Promise((resolve,reject)=>{var xhr=new XMLHttpRequest({mozAnon:true,mozSystem:true});xhr.open('GET',iconUrl,true);xhr.responseType='blob';xhr.timeout=FETCH_XHR_TIMEOUT;xhr.send();xhr.onload=()=>{if(xhr.readyState===XMLHttpRequest.DONE&&xhr.status===200){var iconBlob=xhr.response;resolve(iconBlob);return;}
reject(new Error(`Got HTTP status ${xhr.status} trying to load ${iconUrl}.`));};xhr.onerror=xhr.ontimeout=()=>{reject(new Error(`Error while getting ${iconUrl}.`));};});}
exports.IconsHelper={getIcon:getIcon,getIconBlob:getIconBlob,setElementIcon:setElementIcon,getBestIconFromWebManifest:getBestIconFromWebManifest,getBestIconFromMetaTags:getBestIconFromMetaTags,fetchIcon:fetchIcon,fetchIconBlob:fetchIconBlob,get defaultIconSize(){return getDefaultIconSize();},clear:clear,getNearestSize:getNearestSize,};})(window);

Some files were not shown because too many files have changed in this diff Show more