Restore Gaia settings and media workflows, extend native network adapters, and align the APK payload. Generate French/English changelogs and website entries from the simplified JSON source. Validation: shared JS and Tundra unit tests; desktop workflows and persistence; signed APK payload parity; Sargo RAM and installed startup with boot readback. Android runtime qualification is recorded separately.
1177 lines
No EOL
164 KiB
JavaScript
1177 lines
No EOL
164 KiB
JavaScript
;var _createClass=(function(){function defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if('value'in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError('Cannot call a class as a function');}}
|
||
(function(){'use strict';function emit(listeners,...args){const type=args.shift();if(listeners['*']){listeners['*'].slice().forEach(listener=>listener.apply(this,args));}
|
||
if(listeners[type]){listeners[type].slice().forEach(listener=>listener.apply(this,args));}}
|
||
function addEventListener(listeners,type,listener){if(!(type in listeners)){listeners[type]=[];}
|
||
listeners[type].push(listener);}
|
||
function removeEventListener(listeners,type,listener){const typeListeners=listeners[type];const pos=typeListeners.indexOf(listener);if(pos===-1){return;}
|
||
typeListeners.splice(pos,1);}
|
||
let Client=(function(){function Client(remote){_classCallCheck(this,Client);this.id=this;this.remote=remote;const listeners={};this.on=(...args)=>addEventListener(listeners,...args);this.emit=(...args)=>emit(listeners,...args);}
|
||
_createClass(Client,[{key:'method',value:function method(name,...args){return this.remote[name](...args);}}]);return Client;})();function broadcast(type,data){Array.from(this.ctxs.keys()).forEach(client=>client.emit(type,data));}
|
||
function L10nError(message,id,lang){this.name='L10nError';this.message=message;this.id=id;this.lang=lang;}
|
||
L10nError.prototype=Object.create(Error.prototype);L10nError.prototype.constructor=L10nError;function load(type,url){return new Promise(function(resolve,reject){const xhr=new XMLHttpRequest();if(xhr.overrideMimeType){xhr.overrideMimeType(type);}
|
||
xhr.open('GET',url,true);if(type==='application/json'){xhr.responseType='json';}
|
||
xhr.addEventListener('load',function io_onload(e){if(e.target.status===200||e.target.status===0){resolve(e.target.response||e.target.responseText);}else{reject(new L10nError('Not found: '+url));}});xhr.addEventListener('error',reject);xhr.addEventListener('timeout',reject);try{xhr.send(null);}catch(e){if(e.name==='NS_ERROR_FILE_NOT_FOUND'){reject(new L10nError('Not found: '+url));}else{throw e;}}});}
|
||
const io={extra:function(code,ver,path,type){return navigator.mozApps.getLocalizationResource(code,ver,path,type);},app:function(code,ver,path,type){switch(type){case'text':return load('text/plain',path);case'json':return load('application/json',path);default:throw new L10nError('Unknown file type: '+type);}}};function fetchResource(res,{code,src,ver}){const url=res.replace('{locale}',code);const type=res.endsWith('.json')?'json':'text';return io[src](code,ver,url,type);}
|
||
const KNOWN_MACROS=['plural'];const MAX_PLACEABLE_LENGTH=2500;const FSI='';const PDI='';const resolutionChain=new WeakSet();function format(ctx,lang,args,entity){if(typeof entity==='string'){return[{},entity];}
|
||
if(resolutionChain.has(entity)){throw new L10nError('Cyclic reference detected');}
|
||
resolutionChain.add(entity);let rv;try{rv=resolveValue({},ctx,lang,args,entity.value,entity.index);}finally{resolutionChain.delete(entity);}
|
||
return rv;}
|
||
function resolveIdentifier(ctx,lang,args,id){if(KNOWN_MACROS.indexOf(id)>-1){return[{},ctx._getMacro(lang,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==='__proto__'){throw new L10nError('Illegal id: '+id);}
|
||
const entity=ctx._getEntity(lang,id);if(entity){return format(ctx,lang,args,entity);}
|
||
throw new L10nError('Unknown reference: '+id);}
|
||
function subPlaceable(locals,ctx,lang,args,id){let newLocals,value;try{[newLocals,value]=resolveIdentifier(ctx,lang,args,id);}catch(err){return[{error:err},FSI+'{{ '+id+' }}'+PDI];}
|
||
if(typeof value==='number'){const formatter=ctx._getNumberFormatter(lang);return[newLocals,formatter.format(value)];}
|
||
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+')');}
|
||
return[newLocals,FSI+value+PDI];}
|
||
return[{},FSI+'{{ '+id+' }}'+PDI];}
|
||
function interpolate(locals,ctx,lang,args,arr){return arr.reduce(function([localsSeq,valueSeq],cur){if(typeof cur==='string'){return[localsSeq,valueSeq+cur];}else{const[,value]=subPlaceable(locals,ctx,lang,args,cur.name);return[localsSeq,valueSeq+value];}},[locals,'']);}
|
||
function resolveSelector(ctx,lang,args,expr,index){let selectorName;if(index[0].type==='call'&&index[0].expr.type==='prop'&&index[0].expr.expr.name==='cldr'){selectorName='plural';}else{selectorName=index[0].name;}
|
||
const selector=resolveIdentifier(ctx,lang,args,selectorName)[1];if(typeof selector!=='function'){return selector;}
|
||
const argValue=index[0].args?resolveIdentifier(ctx,lang,args,index[0].args[0].name)[1]:undefined;if(selectorName==='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,ctx,lang,args,expr,index){if(!expr){return[locals,expr];}
|
||
if(typeof expr==='string'||typeof expr==='boolean'||typeof expr==='number'){return[locals,expr];}
|
||
if(Array.isArray(expr)){return interpolate(locals,ctx,lang,args,expr);}
|
||
if(index){const selector=resolveSelector(ctx,lang,args,expr,index);if(selector in expr){return resolveValue(locals,ctx,lang,args,expr[selector]);}}
|
||
const defaultKey=expr.__default||'other';if(defaultKey in expr){return resolveValue(locals,ctx,lang,args,expr[defaultKey]);}
|
||
throw new L10nError('Unresolvable value');}
|
||
const 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;}
|
||
const 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';}};function getPluralRule(code){const index=locales2rules[code.replace(/-.*$/,'')];if(!(index in pluralRules)){return function(){return'other';};}
|
||
return pluralRules[index];}
|
||
const L20nIntl=typeof Intl!=='undefined'?Intl:{NumberFormat:function(){return{format:function(v){return v;}};}};let Context=(function(){function Context(env,langs,resIds){_classCallCheck(this,Context);this.langs=langs;this.resIds=resIds;this.env=env;this.emit=(type,evt)=>env.emit(type,evt,this);}
|
||
_createClass(Context,[{key:'_formatTuple',value:function _formatTuple(lang,args,entity,id,key){try{return format(this,lang,args,entity);}catch(err){err.id=key?id+'::'+key:id;err.lang=lang;this.emit('resolveerror',err);return[{error:err},err.id];}}},{key:'_formatEntity',value:function _formatEntity(lang,args,entity,id){const[,value]=this._formatTuple(lang,args,entity,id);const formatted={value,attrs:null};if(entity.attrs){formatted.attrs=Object.create(null);for(let key in entity.attrs){const[,attrValue]=this._formatTuple(lang,args,entity.attrs[key],id,key);formatted.attrs[key]=attrValue;}}
|
||
return formatted;}},{key:'_formatValue',value:function _formatValue(lang,args,entity,id){return this._formatTuple(lang,args,entity,id)[1];}},{key:'fetch',value:function fetch(langs=this.langs){if(langs.length===0){return Promise.resolve(langs);}
|
||
return Promise.all(this.resIds.map(resId=>this.env._getResource(langs[0],resId))).then(()=>langs);}},{key:'_resolve',value:function _resolve(langs,keys,formatter,prevResolved){const lang=langs[0];if(!lang){return reportMissing.call(this,keys,formatter,prevResolved);}
|
||
let hasUnresolved=false;const resolved=keys.map((key,i)=>{if(prevResolved&&prevResolved[i]!==undefined){return prevResolved[i];}
|
||
const[id,args]=Array.isArray(key)?key:[key,undefined];const entity=this._getEntity(lang,id);if(entity){return formatter.call(this,lang,args,entity,id);}
|
||
this.emit('notfounderror',new L10nError('"'+id+'"'+' not found in '+lang.code,id,lang));hasUnresolved=true;});if(!hasUnresolved){return resolved;}
|
||
return this.fetch(langs.slice(1)).then(nextLangs=>this._resolve(nextLangs,keys,formatter,resolved));}},{key:'formatEntities',value:function formatEntities(...keys){return this.fetch().then(langs=>this._resolve(langs,keys,this._formatEntity));}},{key:'formatValues',value:function formatValues(...keys){return this.fetch().then(langs=>this._resolve(langs,keys,this._formatValue));}},{key:'_getEntity',value:function _getEntity(lang,id){const cache=this.env.resCache;for(let i=0,resId;resId=this.resIds[i];i++){const resource=cache.get(resId+lang.code+lang.src);if(resource instanceof L10nError){continue;}
|
||
if(id in resource){return resource[id];}}
|
||
return undefined;}},{key:'_getNumberFormatter',value:function _getNumberFormatter(lang){if(!this.env.numberFormatters){this.env.numberFormatters=new Map();}
|
||
if(!this.env.numberFormatters.has(lang)){const formatter=L20nIntl.NumberFormat(lang);this.env.numberFormatters.set(lang,formatter);return formatter;}
|
||
return this.env.numberFormatters.get(lang);}},{key:'_getMacro',value:function _getMacro(lang,id){switch(id){case'plural':return getPluralRule(lang.code);default:return undefined;}}}]);return Context;})();function reportMissing(keys,formatter,resolved){const missingIds=new Set();keys.forEach((key,i)=>{if(resolved&&resolved[i]!==undefined){return;}
|
||
const id=Array.isArray(key)?key[0]:key;missingIds.add(id);resolved[i]=formatter===this._formatValue?id:{value:id,attrs:null};});this.emit('notfounderror',new L10nError('"'+Array.from(missingIds).join(', ')+'"'+' not found in any language',missingIds));return resolved;}
|
||
var MAX_PLACEABLES=100;var PropertiesParser={patterns:null,entryIds:null,emit: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(emit,source){if(!this.patterns){this.init();}
|
||
this.emit=emit;var entries={};var lines=source.match(this.patterns.entries);if(!lines){return entries;}
|
||
for(var i=0;i<lines.length;i++){var line=lines[i];if(this.patterns.comment.test(line)){continue;}
|
||
while(this.patterns.multiline.test(line)&&i<lines.length){line=line.slice(0,-1)+lines[++i].trim();}
|
||
var entityMatch=line.match(this.patterns.entity);if(entityMatch){try{this.parseEntity(entityMatch[1],entityMatch[2],entries);}catch(e){if(!this.emit){throw e;}}}}
|
||
return entries;},parseEntity:function(id,value,entries){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 this.error('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 this.error('Attribute can\'t start with "$"');}}else{attr=null;}
|
||
this.setEntityValue(name,attr,key,this.unescapeString(value),entries);},setEntityValue:function(id,attr,key,rawValue,entries){var value=rawValue.indexOf('{{')>-1?this.parseString(rawValue):rawValue;var isSimpleValue=typeof value==='string';var root=entries;var isSimpleNode=typeof entries[id]==='string';if(!entries[id]&&(attr||key||!isSimpleValue)){entries[id]=Object.create(null);isSimpleNode=false;}
|
||
if(attr){if(isSimpleNode){const val=entries[id];entries[id]=Object.create(null);entries[id].value=val;}
|
||
if(!entries[id].attrs){entries[id].attrs=Object.create(null);}
|
||
if(!entries[id].attrs&&!isSimpleValue){entries[id].attrs[attr]=Object.create(null);}
|
||
root=entries[id].attrs;id=attr;}
|
||
if(key){isSimpleNode=false;if(typeof root[id]==='string'){const val=root[id];root[id]=Object.create(null);root[id].index=this.parseIndex(val);root[id].value=Object.create(null);}
|
||
root=root[id].value;id=key;isSimpleValue=true;}
|
||
if(isSimpleValue){if(id in root){throw this.error('Duplicated id: '+id);}
|
||
root[id]=value;}else{if(!root[id]){root[id]=Object.create(null);}
|
||
root[id].value=value;}},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 this.error('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({type:'idOrVar',name: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 String.fromCodePoint(parseInt(token,16));});},parseIndex:function(str){var match=str.match(this.patterns.index);if(!match){throw new L10nError('Malformed index');}
|
||
if(match[2]){return[{type:'call',expr:{type:'prop',expr:{type:'glob',name:'cldr'},prop:'plural',cmpt:false},args:[{type:'idOrVar',name:match[2]}]}];}else{return[{type:'idOrVar',name:match[1]}];}},error:function(msg,type='parsererror'){const err=new L10nError(msg);if(this.emit){this.emit(type,err);}
|
||
return err;}};const MAX_PLACEABLES$1=100;var L20nParser={parse:function(emit,string){this._source=string;this._index=0;this._length=string.length;this.entries=Object.create(null);this.emit=emit;return this.getResource();},getResource:function(){this.getWS();while(this._index<this._length){try{this.getEntry();}catch(e){if(e instanceof L10nError){this.getJunkEntry();if(!this.emit){throw e;}}else{throw e;}}
|
||
if(this._index<this._length){this.getWS();}}
|
||
return this.entries;},getEntry:function(){if(this._source[this._index]==='<'){++this._index;const id=this.getIdentifier();if(this._source[this._index]==='['){++this._index;return this.getEntity(id,this.getItemList(this.getExpression,']'));}
|
||
return this.getEntity(id);}
|
||
if(this._source.startsWith('/*',this._index)){return this.getComment();}
|
||
throw this.error('Invalid entry');},getEntity:function(id,index){if(!this.getRequiredWS()){throw this.error('Expected white space');}
|
||
const ch=this._source[this._index];const hasIndex=index!==undefined;const value=this.getValue(ch,hasIndex,hasIndex);let attrs;if(value===undefined){if(ch==='>'){throw this.error('Expected ">"');}
|
||
attrs=this.getAttributes();}else{const ws1=this.getRequiredWS();if(this._source[this._index]!=='>'){if(!ws1){throw this.error('Expected ">"');}
|
||
attrs=this.getAttributes();}}
|
||
++this._index;if(id in this.entries){throw this.error('Duplicate entry ID "'+id,'duplicateerror');}
|
||
if(!attrs&&!index&&typeof value==='string'){this.entries[id]=value;}else{this.entries[id]={value,attrs,index};}},getValue:function(ch=this._source[this._index],index=false,required=true){switch(ch){case'\'':case'"':return this.getString(ch,1);case'{':return this.getHash(index);}
|
||
if(required){throw this.error('Unknown value type');}
|
||
return;},getWS:function(){let cc=this._source.charCodeAt(this._index);while(cc===32||cc===10||cc===9||cc===13){cc=this._source.charCodeAt(++this._index);}},getRequiredWS:function(){const pos=this._index;let cc=this._source.charCodeAt(pos);while(cc===32||cc===10||cc===9||cc===13){cc=this._source.charCodeAt(++this._index);}
|
||
return this._index!==pos;},getIdentifier:function(){const start=this._index;let cc=this._source.charCodeAt(this._index);if(cc>=97&&cc<=122||cc>=65&&cc<=90||cc===95){cc=this._source.charCodeAt(++this._index);}else{throw this.error('Identifier has to start with [a-zA-Z_]');}
|
||
while(cc>=97&&cc<=122||cc>=65&&cc<=90||cc>=48&&cc<=57||cc===95){cc=this._source.charCodeAt(++this._index);}
|
||
return this._source.slice(start,this._index);},getUnicodeChar:function(){for(let i=0;i<4;i++){let cc=this._source.charCodeAt(++this._index);if(cc>96&&cc<103||cc>64&&cc<71||cc>47&&cc<58){continue;}
|
||
throw this.error('Illegal unicode escape sequence');}
|
||
this._index++;return String.fromCharCode(parseInt(this._source.slice(this._index-4,this._index),16));},stringRe:/"|'|{{|\\/g,getString:function(opchar,opcharLen){const body=[];let placeables=0;this._index+=opcharLen;const start=this._index;let bufStart=start;let buf='';while(true){this.stringRe.lastIndex=this._index;const match=this.stringRe.exec(this._source);if(!match){throw this.error('Unclosed string literal');}
|
||
if(match[0]==='"'||match[0]==='\''){if(match[0]!==opchar){this._index+=opcharLen;continue;}
|
||
this._index=match.index+opcharLen;break;}
|
||
if(match[0]==='{{'){if(placeables>MAX_PLACEABLES$1-1){throw this.error('Too many placeables, maximum allowed is '+MAX_PLACEABLES$1);}
|
||
placeables++;if(match.index>bufStart||buf.length>0){body.push(buf+this._source.slice(bufStart,match.index));buf='';}
|
||
this._index=match.index+2;this.getWS();body.push(this.getExpression());this.getWS();this._index+=2;bufStart=this._index;continue;}
|
||
if(match[0]==='\\'){this._index=match.index+1;const ch2=this._source[this._index];if(ch2==='u'){buf+=this._source.slice(bufStart,match.index)+this.getUnicodeChar();}else if(ch2===opchar||ch2==='\\'){buf+=this._source.slice(bufStart,match.index)+ch2;this._index++;}else if(this._source.startsWith('{{',this._index)){buf+=this._source.slice(bufStart,match.index)+'{{';this._index+=2;}else{throw this.error('Illegal escape sequence');}
|
||
bufStart=this._index;}}
|
||
if(body.length===0){return buf+this._source.slice(bufStart,this._index-opcharLen);}
|
||
if(this._index-opcharLen>bufStart||buf.length>0){body.push(buf+this._source.slice(bufStart,this._index-opcharLen));}
|
||
return body;},getAttributes:function(){const attrs=Object.create(null);while(true){this.getAttribute(attrs);const ws1=this.getRequiredWS();const ch=this._source.charAt(this._index);if(ch==='>'){break;}else if(!ws1){throw this.error('Expected ">"');}}
|
||
return attrs;},getAttribute:function(attrs){const key=this.getIdentifier();let index;if(this._source[this._index]==='['){++this._index;this.getWS();index=this.getItemList(this.getExpression,']');}
|
||
this.getWS();if(this._source[this._index]!==':'){throw this.error('Expected ":"');}
|
||
++this._index;this.getWS();const hasIndex=index!==undefined;const value=this.getValue(undefined,hasIndex);if(key in attrs){throw this.error('Duplicate attribute "'+key,'duplicateerror');}
|
||
if(!index&&typeof value==='string'){attrs[key]=value;}else{attrs[key]={value,index};}},getHash:function(index){const items=Object.create(null);++this._index;this.getWS();let defKey;while(true){const[key,value,def]=this.getHashItem();items[key]=value;if(def){if(defKey){throw this.error('Default item redefinition forbidden');}
|
||
defKey=key;}
|
||
this.getWS();const comma=this._source[this._index]===',';if(comma){++this._index;this.getWS();}
|
||
if(this._source[this._index]==='}'){++this._index;break;}
|
||
if(!comma){throw this.error('Expected "}"');}}
|
||
if(defKey){items.__default=defKey;}else if(!index){throw this.error('Unresolvable Hash Value');}
|
||
return items;},getHashItem:function(){let defItem=false;if(this._source[this._index]==='*'){++this._index;defItem=true;}
|
||
const key=this.getIdentifier();this.getWS();if(this._source[this._index]!==':'){throw this.error('Expected ":"');}
|
||
++this._index;this.getWS();return[key,this.getValue(),defItem];},getComment:function(){this._index+=2;const start=this._index;const end=this._source.indexOf('*/',start);if(end===-1){throw this.error('Comment without a closing tag');}
|
||
this._index=end+2;},getExpression:function(){let exp=this.getPrimaryExpression();while(true){let ch=this._source[this._index];if(ch==='.'||ch==='['){++this._index;exp=this.getPropertyExpression(exp,ch==='[');}else if(ch==='('){++this._index;exp=this.getCallExpression(exp);}else{break;}}
|
||
return exp;},getPropertyExpression:function(idref,computed){let exp;if(computed){this.getWS();exp=this.getExpression();this.getWS();if(this._source[this._index]!==']'){throw this.error('Expected "]"');}
|
||
++this._index;}else{exp=this.getIdentifier();}
|
||
return{type:'prop',expr:idref,prop:exp,cmpt:computed};},getCallExpression:function(callee){this.getWS();return{type:'call',expr:callee,args:this.getItemList(this.getExpression,')')};},getPrimaryExpression:function(){const ch=this._source[this._index];switch(ch){case'$':++this._index;return{type:'var',name:this.getIdentifier()};case'@':++this._index;return{type:'glob',name:this.getIdentifier()};default:return{type:'id',name:this.getIdentifier()};}},getItemList:function(callback,closeChar){const items=[];let closed=false;this.getWS();if(this._source[this._index]===closeChar){++this._index;closed=true;}
|
||
while(!closed){items.push(callback.call(this));this.getWS();let ch=this._source.charAt(this._index);switch(ch){case',':++this._index;this.getWS();break;case closeChar:++this._index;closed=true;break;default:throw this.error('Expected "," or "'+closeChar+'"');}}
|
||
return items;},getJunkEntry:function(){const pos=this._index;let nextEntity=this._source.indexOf('<',pos);let nextComment=this._source.indexOf('/*',pos);if(nextEntity===-1){nextEntity=this._length;}
|
||
if(nextComment===-1){nextComment=this._length;}
|
||
let nextEntry=Math.min(nextEntity,nextComment);this._index=nextEntry;},error:function(message,type='parsererror'){const pos=this._index;let start=this._source.lastIndexOf('<',pos-1);const lastClose=this._source.lastIndexOf('>',pos-1);start=lastClose>start?lastClose+1:start;const context=this._source.slice(start,pos+10);const msg=message+' at pos '+pos+': `'+context+'`';const err=new L10nError(msg);if(this.emit){this.emit(type,err);}
|
||
return err;}};function walkEntry(entry,fn){if(typeof entry==='string'){return fn(entry);}
|
||
const newEntry=Object.create(null);if(entry.value){newEntry.value=walkValue(entry.value,fn);}
|
||
if(entry.index){newEntry.index=entry.index;}
|
||
if(entry.attrs){newEntry.attrs=Object.create(null);for(let key in entry.attrs){newEntry.attrs[key]=walkEntry(entry.attrs[key],fn);}}
|
||
return newEntry;}
|
||
function walkValue(value,fn){if(typeof value==='string'){return fn(value);}
|
||
if(value.type){return value;}
|
||
const newValue=Array.isArray(value)?[]:Object.create(null);const keys=Object.keys(value);for(let i=0,key;key=keys[i];i++){newValue[key]=walkValue(value[key],fn);}
|
||
return newValue;}
|
||
function createGetter(id,name){let _pseudo=null;return function getPseudo(){if(_pseudo){return _pseudo;}
|
||
const reAlphas=/[a-zA-Z]/g;const reVowels=/[aeiouAEIOU]/g;const reWords=/[^\W0-9_]+/g;const reExcluded=/(%[EO]?\w|\{\s*.+?\s*\}|&[#\w]+;|<\s*.+?\s*>)/;const charMaps={'fr-x-psaccent':'ȦƁƇḒḖƑƓĦĪĴĶĿḾȠǾƤɊŘŞŦŬṼẆẊẎẐ[\\]^_`ȧƀƈḓḗƒɠħīĵķŀḿƞǿƥɋřşŧŭṽẇẋẏẑ','ar-x-psbidi':'∀ԐↃpƎɟפHIſӼ˥WNOԀÒᴚS⊥∩ɅMXʎZ[\\]ᵥ_,ɐqɔpǝɟƃɥıɾʞʅɯuodbɹsʇnʌʍxʎz'};const mods={'fr-x-psaccent':val=>val.replace(reVowels,match=>match+match.toLowerCase()),'ar-x-psbidi':val=>val.replace(reWords,match=>''+match+'')};const replaceChars=(map,val)=>val.replace(reAlphas,match=>map.charAt(match.charCodeAt(0)-65));const transform=val=>replaceChars(charMaps[id],mods[id](val));const apply=(fn,val)=>{if(!val){return val;}
|
||
const parts=val.split(reExcluded);const modified=parts.map(function(part){if(reExcluded.test(part)){return part;}
|
||
return fn(part);});return modified.join('');};return _pseudo={name:transform(name),process:str=>apply(transform,str)};};}
|
||
const pseudo=Object.defineProperties(Object.create(null),{'fr-x-psaccent':{enumerable:true,get:createGetter('fr-x-psaccent','Runtime Accented')},'ar-x-psbidi':{enumerable:true,get:createGetter('ar-x-psbidi','Runtime Bidi')}});let Env=(function(){function Env(fetchResource){_classCallCheck(this,Env);this.fetchResource=fetchResource;this.resCache=new Map();this.resRefs=new Map();this.numberFormatters=null;this.parsers={properties:PropertiesParser,l20n:L20nParser};const listeners={};this.emit=emit.bind(this,listeners);this.addEventListener=addEventListener.bind(this,listeners);this.removeEventListener=removeEventListener.bind(this,listeners);}
|
||
_createClass(Env,[{key:'createContext',value:function createContext(langs,resIds){const ctx=new Context(this,langs,resIds);resIds.forEach(resId=>{const usedBy=this.resRefs.get(resId)||0;this.resRefs.set(resId,usedBy+1);});return ctx;}},{key:'destroyContext',value:function destroyContext(ctx){ctx.resIds.forEach(resId=>{const usedBy=this.resRefs.get(resId)||0;if(usedBy>1){return this.resRefs.set(resId,usedBy-1);}
|
||
this.resRefs.delete(resId);this.resCache.forEach((val,key)=>key.startsWith(resId)?this.resCache.delete(key):null);});}},{key:'_parse',value:function _parse(syntax,lang,data){const parser=this.parsers[syntax];if(!parser){return data;}
|
||
const emit=(type,err)=>this.emit(type,amendError(lang,err));return parser.parse.call(parser,emit,data);}},{key:'_create',value:function _create(lang,entries){if(lang.src!=='pseudo'){return entries;}
|
||
const pseudoentries=Object.create(null);for(let key in entries){pseudoentries[key]=walkEntry(entries[key],pseudo[lang.code].process);}
|
||
return pseudoentries;}},{key:'_getResource',value:function _getResource(lang,res){const cache=this.resCache;const id=res+lang.code+lang.src;if(cache.has(id)){return cache.get(id);}
|
||
const syntax=res.substr(res.lastIndexOf('.')+1);const saveEntries=data=>{const entries=this._parse(syntax,lang,data);cache.set(id,this._create(lang,entries));};const recover=err=>{err.lang=lang;this.emit('fetcherror',err);cache.set(id,err);};const langToFetch=lang.src==='pseudo'?{code:'en-US',src:'app',ver:lang.ver}:lang;const resource=this.fetchResource(res,langToFetch).then(saveEntries,recover);cache.set(id,resource);return resource;}}]);return Env;})();function amendError(lang,err){err.lang=lang;return err;}
|
||
function prioritizeLocales(def,availableLangs,requested){let supportedLocale;for(let i=0;i<requested.length;i++){const locale=requested[i];if(availableLangs.indexOf(locale)!==-1){supportedLocale=locale;break;}}
|
||
if(!supportedLocale||supportedLocale===def){return[def];}
|
||
return[supportedLocale,def];}
|
||
function negotiateLanguages({appVersion,defaultLang,availableLangs},additionalLangs,prevLangs,requestedLangs){const allAvailableLangs=Object.keys(availableLangs).concat(Object.keys(additionalLangs)).concat(Object.keys(pseudo));const newLangs=prioritizeLocales(defaultLang,allAvailableLangs,requestedLangs);const langs=newLangs.map(code=>({code:code,src:getLangSource(appVersion,availableLangs,additionalLangs,code),ver:appVersion}));return{langs,haveChanged:!arrEqual(prevLangs,newLangs)};}
|
||
function arrEqual(arr1,arr2){return arr1.length===arr2.length&&arr1.every((elem,i)=>elem===arr2[i]);}
|
||
function getMatchingLangpack(appVersion,langpacks){for(let i=0,langpack;langpack=langpacks[i];i++){if(langpack.target===appVersion){return langpack;}}
|
||
return null;}
|
||
function getLangSource(appVersion,availableLangs,additionalLangs,code){if(additionalLangs&&additionalLangs[code]){const lp=getMatchingLangpack(appVersion,additionalLangs[code]);if(lp&&(!(code in availableLangs)||parseInt(lp.revision)>availableLangs[code])){return'extra';}}
|
||
if(code in pseudo&&!(code in availableLangs)){return'pseudo';}
|
||
return'app';}
|
||
let Remote=(function(){function Remote(fetchResource,broadcast){_classCallCheck(this,Remote);this.broadcast=broadcast;this.env=new Env(fetchResource);this.ctxs=new Map();}
|
||
_createClass(Remote,[{key:'registerView',value:function registerView(view,resources,meta,additionalLangs,requestedLangs){const{langs}=negotiateLanguages(meta,additionalLangs,[],requestedLangs);this.ctxs.set(view,this.env.createContext(langs,resources));return langs;}},{key:'unregisterView',value:function unregisterView(view){this.ctxs.delete(view);return true;}},{key:'formatEntities',value:function formatEntities(view,keys){return this.ctxs.get(view).formatEntities(...keys);}},{key:'formatValues',value:function formatValues(view,keys){return this.ctxs.get(view).formatValues(...keys);}},{key:'changeLanguages',value:function changeLanguages(view,meta,additionalLangs,requestedLangs){const oldCtx=this.ctxs.get(view);const prevLangs=oldCtx.langs;const newLangs=negotiateLanguages(meta,additionalLangs,prevLangs,requestedLangs);this.ctxs.set(view,this.env.createContext(newLangs.langs,oldCtx.resIds));return newLangs;}},{key:'requestLanguages',value:function requestLanguages(requestedLangs){this.broadcast('languageschangerequest',requestedLangs);}},{key:'getName',value:function getName(code){return pseudo[code].name;}},{key:'processString',value:function processString(code,str){return pseudo[code].process(str);}}]);return Remote;})();const observerConfig={attributes:true,characterData:false,childList:true,subtree:true,attributeFilter:['data-l10n-id','data-l10n-args']};const observers=new WeakMap();function initMutationObserver(view){observers.set(view,{roots:new Set(),observer:new MutationObserver(mutations=>translateMutations(view,mutations))});}
|
||
function translateRoots(view){return Promise.all([...observers.get(view).roots].map(root=>_translateFragment(view,root)));}
|
||
function observe(view,root){const obs=observers.get(view);if(obs){obs.roots.add(root);obs.observer.observe(root,observerConfig);}}
|
||
function disconnect(view,root,allRoots){const obs=observers.get(view);if(obs){obs.observer.disconnect();if(allRoots){return;}
|
||
obs.roots.delete(root);obs.roots.forEach(other=>obs.observer.observe(other,observerConfig));}}
|
||
function reconnect(view){const obs=observers.get(view);if(obs){obs.roots.forEach(root=>obs.observer.observe(root,observerConfig));}}
|
||
const reOverlay=/<|&#?\w+;/;const 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']}};function overlayElement(element,translation){const value=translation.value;if(typeof value==='string'){if(!reOverlay.test(value)){element.textContent=value;}else{const tmpl=element.ownerDocument.createElement('template');tmpl.innerHTML=value;overlay(element,tmpl.content);}}
|
||
for(let key in translation.attrs){const attrName=camelCaseToDashed(key);if(isAttrAllowed({name:attrName},element)){element.setAttribute(attrName,translation.attrs[key]);}}}
|
||
function overlay(sourceElement,translationElement){const result=translationElement.ownerDocument.createDocumentFragment();let k,attr;let childElement;while(childElement=translationElement.childNodes[0]){translationElement.removeChild(childElement);if(childElement.nodeType===childElement.TEXT_NODE){result.appendChild(childElement);continue;}
|
||
const index=getIndexOfType(childElement);const sourceChild=getNthElementOfType(sourceElement,childElement,index);if(sourceChild){overlay(sourceChild,childElement);result.appendChild(sourceChild);continue;}
|
||
if(isElementAllowed(childElement)){const sanitizedChild=childElement.ownerDocument.createElement(childElement.nodeName);overlay(sanitizedChild,childElement);result.appendChild(sanitizedChild);continue;}
|
||
result.appendChild(translationElement.ownerDocument.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){const attrName=attr.name.toLowerCase();const 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'){const type=element.type.toLowerCase();if(type==='submit'||type==='button'||type==='reset'){return true;}}
|
||
return false;}
|
||
function getNthElementOfType(context,element,index){let nthOfType=0;for(let i=0,child;child=context.children[i];i++){if(child.nodeType===child.ELEMENT_NODE&&child.tagName===element.tagName){if(nthOfType===index){return child;}
|
||
nthOfType++;}}
|
||
return null;}
|
||
function getIndexOfType(element){let index=0;let child;while(child=element.previousElementSibling){if(child.tagName===element.tagName){index++;}}
|
||
return index;}
|
||
function camelCaseToDashed(string){if(string==='ariaValueText'){return'aria-valuetext';}
|
||
return string.replace(/[A-Z]/g,function(match){return'-'+match.toLowerCase();}).replace(/^-/,'');}
|
||
const reHtml=/[&<>]/g;const htmlEntities={'&':'&','<':'<','>':'>'};function setAttributes(element,id,args){element.setAttribute('data-l10n-id',id);if(args){element.setAttribute('data-l10n-args',JSON.stringify(args));}}
|
||
function getAttributes(element){return{id:element.getAttribute('data-l10n-id'),args:JSON.parse(element.getAttribute('data-l10n-args'))};}
|
||
function getTranslatables(element){const nodes=Array.from(element.querySelectorAll('[data-l10n-id]'));if(typeof element.hasAttribute==='function'&&element.hasAttribute('data-l10n-id')){nodes.push(element);}
|
||
return nodes;}
|
||
function translateMutations(view,mutations){const targets=new Set();for(let mutation of mutations){switch(mutation.type){case'attributes':targets.add(mutation.target);break;case'childList':for(let addedNode of mutation.addedNodes){if(addedNode.nodeType===addedNode.ELEMENT_NODE){if(addedNode.childElementCount){getTranslatables(addedNode).forEach(targets.add.bind(targets));}else{if(addedNode.hasAttribute('data-l10n-id')){targets.add(addedNode);}}}}
|
||
break;}}
|
||
if(targets.size===0){return;}
|
||
translateElements(view,Array.from(targets));}
|
||
function _translateFragment(view,frag){return translateElements(view,getTranslatables(frag));}
|
||
function getElementsTranslation(view,elems){const keys=elems.map(elem=>{const id=elem.getAttribute('data-l10n-id');const args=elem.getAttribute('data-l10n-args');return args?[id,JSON.parse(args.replace(reHtml,match=>htmlEntities[match]))]:id;});return view.formatEntities(...keys);}
|
||
function translateElements(view,elements){return getElementsTranslation(view,elements).then(translations=>applyTranslations(view,elements,translations));}
|
||
function applyTranslations(view,elems,translations){disconnect(view,null,true);for(let i=0;i<elems.length;i++){overlayElement(elems[i],translations[i]);}
|
||
reconnect(view);}
|
||
if(typeof NodeList==='function'&&!NodeList.prototype[Symbol.iterator]){NodeList.prototype[Symbol.iterator]=Array.prototype[Symbol.iterator];}
|
||
function documentReady(){if(document.readyState!=='loading'){return Promise.resolve();}
|
||
return new Promise(resolve=>{document.addEventListener('readystatechange',function onrsc(){document.removeEventListener('readystatechange',onrsc);resolve();});});}
|
||
function getDirection(code){const tag=code.split('-')[0];return['ar','he','fa','ps','ur'].indexOf(tag)>=0?'rtl':'ltr';}
|
||
if(navigator.languages===undefined){navigator.languages=[navigator.language];}
|
||
function getResourceLinks(head){return Array.prototype.map.call(head.querySelectorAll('link[rel="localization"]'),el=>el.getAttribute('href'));}
|
||
function getMeta(head){let availableLangs=Object.create(null);let defaultLang=null;let appVersion=null;const metas=Array.from(head.querySelectorAll('meta[name="availableLanguages"],'+'meta[name="defaultLanguage"],'+'meta[name="appVersion"]'));for(let meta of metas){const name=meta.getAttribute('name');const content=meta.getAttribute('content').trim();switch(name){case'availableLanguages':availableLangs=getLangRevisionMap(availableLangs,content);break;case'defaultLanguage':const[lang,rev]=getLangRevisionTuple(content);defaultLang=lang;if(!(lang in availableLangs)){availableLangs[lang]=rev;}
|
||
break;case'appVersion':appVersion=content;}}
|
||
return{defaultLang,availableLangs,appVersion};}
|
||
function getLangRevisionMap(seq,str){return str.split(',').reduce((seq,cur)=>{const[lang,rev]=getLangRevisionTuple(cur);seq[lang]=rev;return seq;},seq);}
|
||
function getLangRevisionTuple(str){const[lang,rev]=str.trim().split(':');return[lang,parseInt(rev)];}
|
||
const viewProps=new WeakMap();let View=(function(){function View(client,doc){_classCallCheck(this,View);this.pseudo={'fr-x-psaccent':createPseudo(this,'fr-x-psaccent'),'ar-x-psbidi':createPseudo(this,'ar-x-psbidi')};const initialized=documentReady().then(()=>init(this,client));this._interactive=initialized.then(()=>client);this.ready=initialized.then(langs=>translateView(this,langs));initMutationObserver(this);viewProps.set(this,{doc:doc,ready:false});client.on('languageschangerequest',requestedLangs=>this.requestLanguages(requestedLangs));}
|
||
_createClass(View,[{key:'requestLanguages',value:function requestLanguages(requestedLangs,isGlobal){const method=isGlobal?client=>client.method('requestLanguages',requestedLangs):client=>changeLanguages(this,client,requestedLangs);return this._interactive.then(method);}},{key:'handleEvent',value:function handleEvent(){return this.requestLanguages(navigator.languages);}},{key:'formatEntities',value:function formatEntities(...keys){return this._interactive.then(client=>client.method('formatEntities',client.id,keys));}},{key:'formatValue',value:function formatValue(id,args){return this._interactive.then(client=>client.method('formatValues',client.id,[[id,args]])).then(values=>values[0]);}},{key:'formatValues',value:function formatValues(...keys){return this._interactive.then(client=>client.method('formatValues',client.id,keys));}},{key:'translateFragment',value:function translateFragment(frag){return _translateFragment(this,frag);}},{key:'observeRoot',value:function observeRoot(root){observe(this,root);}},{key:'disconnectRoot',value:function disconnectRoot(root){disconnect(this,root);}}]);return View;})();View.prototype.setAttributes=setAttributes;View.prototype.getAttributes=getAttributes;function createPseudo(view,code){return{getName:()=>view._interactive.then(client=>client.method('getName',code)),processString:str=>view._interactive.then(client=>client.method('processString',code,str))};}
|
||
function init(view,client){const doc=viewProps.get(view).doc;const resources=getResourceLinks(doc.head);const meta=getMeta(doc.head);view.observeRoot(doc.documentElement);return getAdditionalLanguages().then(additionalLangs=>client.method('registerView',client.id,resources,meta,additionalLangs,navigator.languages));}
|
||
function changeLanguages(view,client,requestedLangs){const doc=viewProps.get(view).doc;const meta=getMeta(doc.head);return getAdditionalLanguages().then(additionalLangs=>client.method('changeLanguages',client.id,meta,additionalLangs,requestedLangs)).then(({langs,haveChanged})=>haveChanged?translateView(view,langs):undefined);}
|
||
function getAdditionalLanguages(){if(navigator.mozApps&&navigator.mozApps.getAdditionalLanguages){return navigator.mozApps.getAdditionalLanguages().catch(()=>Object.create(null));}
|
||
return Promise.resolve(Object.create(null));}
|
||
function translateView(view,langs){const props=viewProps.get(view);const html=props.doc.documentElement;if(props.ready){return translateRoots(view).then(()=>setAllAndEmit(html,langs));}
|
||
const translated=langs[0].code===html.getAttribute('lang')?Promise.resolve():translateRoots(view).then(()=>setLangDir(html,langs));return translated.then(()=>{setLangs(html,langs);props.ready=true;});}
|
||
function setLangs(html,langs){const codes=langs.map(lang=>lang.code);html.setAttribute('langs',codes.join(' '));}
|
||
function setLangDir(html,langs){const code=langs[0].code;html.setAttribute('lang',code);html.setAttribute('dir',getDirection(code));}
|
||
function setAllAndEmit(html,langs){setLangDir(html,langs);setLangs(html,langs);html.parentNode.dispatchEvent(new CustomEvent('DOMRetranslated',{bubbles:false,cancelable:false}));}
|
||
const remote=new Remote(fetchResource,broadcast);const client=new Client(remote);document.l10n=new View(client,document);window.addEventListener('languagechange',document.l10n);document.addEventListener('additionallanguageschange',document.l10n);navigator.mozL10n={setAttributes:document.l10n.setAttributes,getAttributes:document.l10n.getAttributes,formatValue:(...args)=>document.l10n.formatValue(...args),translateFragment:(...args)=>document.l10n.translateFragment(...args),once:cb=>document.l10n.ready.then(cb),ready:cb=>document.l10n.ready.then(()=>{document.addEventListener('DOMRetranslated',cb);cb();})};})();;(function(global){'use strict';const helperCache=new Map();const knownObjects={datetime:{create:function(options){const customOptions=Object.assign({},options);if(options.hour){customOptions.hour12=navigator.mozHour12;}
|
||
return Intl.DateTimeFormat(navigator.languages,customOptions);},isAffected:function(obj,reason){if(['languagechange','moztimechange'].includes(reason)){return true;}
|
||
if(reason==='timeformatchange'){return'hour'in obj.options;}
|
||
return false;}},mozdatetime:{create:function(options){const customOptions=Object.assign({},options);if(options.hour){customOptions.hour12=navigator.mozHour12;}
|
||
return mozIntl.DateTimeFormat(navigator.languages,customOptions);},isAffected:function(obj,reason){if(['languagechange','moztimechange'].includes(reason)){return true;}
|
||
if(reason==='timeformatchange'){return'hour'in obj.options;}
|
||
return false;}},mozduration:{create:function(options){return mozIntl.DurationFormat(navigator.languages,options);},isAffected:function(obj,reason){return reason==='languagechange';}},number:{create:function(options){return Intl.NumberFormat(navigator.languages,options);},isAffected:function(obj,reason){return reason==='languagechange';}},collator:{create:function(options){return Intl.Collator(navigator.languages,options);},isAffected:function(obj,reason){return reason==='languagechange';}},};global.IntlHelper={define:function(name,type,options){if(!knownObjects.hasOwnProperty(type)){throw new Error('Unknown type: '+type);}
|
||
if(helperCache.has(name)){throw new Error('Intl Object with name "'+name+'" already exists');}
|
||
helperCache.set(name,{options,type,intlObject:undefined,listeners:new Set()});},get:function(name){if(!helperCache.has(name)){throw new Error('Intl Object with name "'+name+'" is not defined');}
|
||
const obj=helperCache.get(name);if(!knownObjects.hasOwnProperty(obj.type)){throw new Error('Unknown type: '+obj.type);}
|
||
if(obj.intlObject===undefined){obj.intlObject=knownObjects[obj.type].create(obj.options);}
|
||
return obj.intlObject;},observe:function(names,cb){if(typeof names==='string'){names=[names];}
|
||
for(var name of names){if(!helperCache.has(name)){throw new Error('Intl Object with name "'+name+'" is not defined');}
|
||
const obj=helperCache.get(name);obj.listeners.add(cb);}},unobserve:function(name,cb){const obj=helperCache.get(name);obj.listeners.delete(cb);},_fireObservers:function(affectedObjects,...args){const affectedCallbacks=new Set();affectedObjects.forEach(obj=>obj.listeners.forEach(cb=>affectedCallbacks.add(cb)));affectedCallbacks.forEach(cb=>{try{cb(...args);}catch(e){console.error('Error in callback: '+e.toString());console.error(e.stack);}});},handleEvent:function(evt){const affectedObjects=resetObjects(evt.type);if(evt.type==='languagechange'&&navigator.mozL10n){waitOnDOMLocalized(()=>global.IntlHelper._fireObservers(affectedObjects));}else{global.IntlHelper._fireObservers(affectedObjects);}},_resetObjectCache:function(){helperCache.clear();}};function waitOnDOMLocalized(cb){const resolver=()=>{document.removeEventListener('DOMRetranslated',resolver);window.removeEventListener('localized',resolver);cb();};document.addEventListener('DOMRetranslated',resolver,false);window.addEventListener('localized',resolver,false);}
|
||
function resetObjects(reason){const affectedObjects=new Set();helperCache.forEach((obj,name)=>{if(knownObjects[obj.type].isAffected(obj,reason)){obj.intlObject=undefined;affectedObjects.add(obj);}});return affectedObjects;}
|
||
window.addEventListener('timeformatchange',global.IntlHelper,false);window.addEventListener('languagechange',global.IntlHelper,false);window.addEventListener('moztimechange',global.IntlHelper,false);})(this);;'use strict';var ScreenLayout={defaultQueries:{tiny:'(max-width: 767px)',small:'(min-width: 768px) and (max-width: 991px)',medium:'(min-width: 992px) and (max-width: 1200px)',large:'(min-width: 1201px)',hardwareHomeButton:window.VulpesCompat?'(min-width: 0px)':'(-moz-physical-home-button)'},init:function sl_init(){this.queries=(function(qs){var result={};for(var key in qs){result[key]=window.matchMedia(qs[key]);}
|
||
return result;})(this.defaultQueries);},_isOnRealDevice:undefined,isOnRealDevice:function sl_isOnRealDevice(){if(typeof(this._isOnRealDevice)!=='undefined'){return this._isOnRealDevice;}
|
||
if(window.innerWidth===screen.availWidth){this._isOnRealDevice=true;}else{this._isOnRealDevice=false;}
|
||
return this._isOnRealDevice;},getCurrentLayout:function sl_getCurrentLayout(type){if(type===undefined){for(var name in this.defaultQueries){if(this.queries[name]&&this.queries[name].matches){return name;}}}
|
||
if(typeof this.queries[type]!=='undefined'){return this.queries[type].matches;}
|
||
return false;},watch:function sl_watch(name,media){var mediaString=media||this.queries[name].media;if(!mediaString){return;}
|
||
this.unwatch(name);this.queries[name]=window.matchMedia(mediaString);this.boundHandleChange=this.handleChange.bind(this);this.queries[name].addListener(this.boundHandleChange);},unwatch:function sl_unwatch(name){if(this.queries[name]){this.queries[name].removeListener(this.boundHandleChange);}},handleChange:function sl_handleChange(evt){for(var key in this.queries){if(this.queries[key].media!==evt.media){continue;}
|
||
window.dispatchEvent(new CustomEvent('screenlayoutchange',{detail:{name:key,status:evt.matches}}));}}};ScreenLayout.init();;(function(root,factory){'use strict';if(typeof define==='function'&&define.amd){define(factory);}else if(typeof exports==='object'){module.exports=factory();}else{root.Sanitizer=factory();}}(this,function(){'use strict';var Sanitizer={_entity:/[&<>"'/]/g,_entities:{'&':'&','<':'<','>':'>','"':'"','\'':''','/':'/'},getEntity:function(s){return Sanitizer._entities[s];},escapeHTML:function(strings,...values){var result='';for(var i=0;i<strings.length;i++){result+=strings[i];if(i<values.length){result+=String(values[i]).replace(Sanitizer._entity,Sanitizer.getEntity);}}
|
||
return result;},createSafeHTML:function(strings,...values){var escaped=Sanitizer.escapeHTML(strings,...values);return{__html:escaped,toString:function(){return'[object WrappedHTMLObject]';},info:'This is a wrapped HTML object. See https://developer.mozilla.or'+'g/en-US/Firefox_OS/Security/Security_Automation for more.'};},unwrapSafeHTML:function(...htmlObjects){var markupList=htmlObjects.map(function(obj){return obj.__html;});return markupList.join('');}};return Sanitizer;}));;'use strict';var MediaDB=(function(){function MediaDB(mediaType,metadataParser,options){this.mediaType=mediaType;this.metadataParser=metadataParser;if(!options){options={};}
|
||
this.indexes=options.indexes||[];this.version=options.version||1;this.mimeTypes=options.mimeTypes;this.autoscan=(options.autoscan!==undefined)?options.autoscan:true;this.state=MediaDB.OPENING;this.scanning=false;this.initialScanComplete=false;this.parsingBigFiles=false;this.updateRecord=options.updateRecord;this.reparsedRecord=options.reparsedRecord;if(options.excludeFilter&&(options.excludeFilter instanceof RegExp)){this.clientExcludeFilter=options.excludeFilter;}
|
||
this.batchHoldTime=options.batchHoldTime||100;this.batchSize=options.batchSize||0;this.dbname='MediaDB/'+this.mediaType+'/';var media=this;this.details={eventListeners:{},pendingInsertions:[],pendingDeletions:[],whenDoneProcessing:[],pendingCreateNotifications:[],pendingDeleteNotifications:[],pendingNotificationTimer:null,newestFileModTime:0};if(!this.metadataParser){this.metadataParser=function(file,callback){setTimeout(function(){callback({});},0);};}
|
||
var dbVersion=(0xFFFF&this.version)<<16|(0xFFFF&MediaDB.VERSION);var openRequest=indexedDB.open(this.dbname,dbVersion);openRequest.onerror=function(e){console.error('MediaDB():',openRequest.error.name);};openRequest.onblocked=function(e){console.error('indexedDB.open() is blocked in MediaDB()');};openRequest.onupgradeneeded=function(e){var db=openRequest.result;var transaction=e.target.transaction;var oldVersion=e.oldVersion;var oldDbVersion=0xFFFF&oldVersion;var oldClientVersion=0xFFFF&(oldVersion>>16);if(oldClientVersion===0){oldDbVersion=2;oldClientVersion=oldVersion/oldDbVersion;}
|
||
if(0===db.objectStoreNames.length){createObjectStores(db);}else{handleUpgrade(db,transaction,oldDbVersion,oldClientVersion);}};openRequest.onsuccess=function(e){media.db=openRequest.result;media.db.onerror=function(event){console.error('MediaDB: ',event.target.error&&event.target.error.name);};changeState(media,MediaDB.ENUMERABLE);var cursorRequest=media.db.transaction('files','readonly').objectStore('files').index('date').openCursor(null,'prev');cursorRequest.onerror=function(){console.error('MediaDB initialization error',cursorRequest.error);};cursorRequest.onsuccess=function(){var cursor=cursorRequest.result;if(cursor){media.details.newestFileModTime=cursor.value.date;}
|
||
else{media.details.newestFileModTime=0;}
|
||
initDeviceStorage();};};function createObjectStores(db){var filestore=db.createObjectStore('files',{keyPath:'name'});filestore.createIndex('date','date');media.indexes.forEach(function(indexName){if(indexName==='name'||indexName==='date'){return;}
|
||
filestore.createIndex(indexName,indexName);});}
|
||
function enumerateOldFiles(store,callback){var openCursorReq=store.openCursor();openCursorReq.onsuccess=function(){var cursor=openCursorReq.result;if(cursor){callback(cursor.value);cursor.continue();}};}
|
||
function handleUpgrade(db,trans,oldDbVersion,oldClientVersion){media.state=MediaDB.UPGRADING;var evtDetail={'oldMediaDBVersion':oldDbVersion,'oldClientVersion':oldClientVersion,'newMediaDBVersion':MediaDB.VERSION,'newClientVersion':media.version};dispatchEvent(media,'upgrading',evtDetail);var store=trans.objectStore('files');if(media.version!=oldClientVersion){upgradeIndexesChanges(store);}
|
||
var clientUpgradeNeeded=(media.version!=oldClientVersion)&&media.updateRecord;if((2!=oldDbVersion||3!=MediaDB.VERSION)&&!clientUpgradeNeeded){return;}
|
||
enumerateOldFiles(store,function doUpgrade(dbfile){if(2==oldDbVersion&&3==MediaDB.VERSION){upgradeDBVer2to3(store,dbfile);}
|
||
if(clientUpgradeNeeded){handleClientUpgrade(store,dbfile,oldClientVersion);}});}
|
||
function upgradeIndexesChanges(store){var dbIndexes=store.indexNames;var clientIndexes=media.indexes;for(var i=0;i<dbIndexes.length;i++){if('name'===dbIndexes[i]||'date'===dbIndexes[i]){continue;}
|
||
if(clientIndexes.indexOf(dbIndexes[i])<0){store.deleteIndex(dbIndexes[i]);}}
|
||
for(i=0;i<clientIndexes.length;i++){if(!dbIndexes.contains(clientIndexes[i])){store.createIndex(clientIndexes[i],clientIndexes[i]);}}}
|
||
function upgradeDBVer2to3(store,dbfile){if(dbfile.name[0]==='/'){return;}
|
||
store.delete(dbfile.name);dbfile.name='/sdcard/'+dbfile.name;store.add(dbfile);}
|
||
function handleClientUpgrade(store,dbfile,oldClientVersion){try{dbfile.metadata=media.updateRecord(dbfile,oldClientVersion,media.version);if(dbfile.needsReparse&&!media.reparsedRecord){console.warn('client app requested reparse, but no reparsedRecord was set');delete dbfile.needsReparse;}
|
||
store.put(dbfile);}catch(ex){console.warn('client app updates record, '+dbfile.name+', failed: '+ex.message);}}
|
||
function initDeviceStorage(){var details=media.details;details.storages=navigator.getDeviceStorages(mediaType);details.availability={};getStorageAvailability();function getStorageAvailability(){var next=0;getNextAvailability();function getNextAvailability(){if(next>=details.storages.length){setupHandlers();return;}
|
||
var s=details.storages[next++];var name=s.storageName;var req=s.available();req.onsuccess=function(e){details.availability[name]=req.result;getNextAvailability();};req.onerror=function(e){details.availability[name]='unavailable';getNextAvailability();};}}
|
||
function setupHandlers(){for(var i=0;i<details.storages.length;i++){details.storages[i].addEventListener('change',changeHandler);}
|
||
details.dsEventListener=changeHandler;sendInitialEvent();}
|
||
function sendInitialEvent(){var state=getState(details.availability);changeState(media,state);if(media.autoscan){scan(media);}}
|
||
function getState(availability){var n=0;var a=0;var u=0;var s=0;for(var name in availability){n++;switch(availability[name]){case'available':a++;break;case'unavailable':u++;break;case'shared':s++;break;}}
|
||
if(s>0){return MediaDB.UNMOUNTED;}
|
||
if(u===n){return MediaDB.NOCARD;}
|
||
return MediaDB.READY;}
|
||
function changeHandler(e){switch(e.reason){case'modified':case'deleted':fileChangeHandler(e);return;case'available':case'unavailable':case'shared':volumeChangeHandler(e);return;default:return;}}
|
||
function volumeChangeHandler(e){var storageName=e.target.storageName;if(details.availability[storageName]===e.reason){return;}
|
||
var oldState=media.state;details.availability[storageName]=e.reason;var newState=getState(details.availability);if(newState!==oldState){changeState(media,newState);if(newState===MediaDB.READY){if(media.autoscan){scan(media);}}
|
||
else{endscan(media);}}
|
||
else if(newState===MediaDB.READY){if(e.reason==='available'){dispatchEvent(media,'ready');if(media.autoscan){scan(media);}}
|
||
else if(e.reason==='unavailable'){dispatchEvent(media,'cardremoved');deleteAllFiles(storageName);}}}
|
||
function fileChangeHandler(e){var filename=e.path;if(ignoreName(media,filename)){return;}
|
||
if(e.reason==='modified'){insertRecord(media,filename);}else{deleteRecord(media,filename);}}
|
||
function deleteAllFiles(storageName){var storagePrefix=storageName?'/'+storageName+'/':'';var store=media.db.transaction('files').objectStore('files');var cursorRequest=store.openCursor();cursorRequest.onsuccess=function(){var cursor=cursorRequest.result;if(cursor){if(cursor.value.name.startsWith(storagePrefix)){deleteRecord(media,cursor.value.name);}
|
||
cursor.continue();}};}}}
|
||
MediaDB.prototype={close:function close(){this.db.close();for(var i=0;i<this.details.storages.length;i++){var s=this.details.storages[i];s.removeEventListener('change',this.details.dsEventListener);}
|
||
changeState(this,MediaDB.CLOSED);},addEventListener:function addEventListener(type,listener){if(!this.details.eventListeners.hasOwnProperty(type)){this.details.eventListeners[type]=[];}
|
||
var listeners=this.details.eventListeners[type];if(listeners.indexOf(listener)!==-1){return;}
|
||
listeners.push(listener);},removeEventListener:function removeEventListener(type,listener){if(!this.details.eventListeners.hasOwnProperty(type)){return;}
|
||
var listeners=this.details.eventListeners[type];var position=listeners.indexOf(listener);if(position===-1){return;}
|
||
listeners.splice(position,1);},getFileInfo:function getFile(filename,callback,errback){if(this.state===MediaDB.OPENING){throw Error('MediaDB is not ready. State: '+this.state);}
|
||
var media=this;var read=media.db.transaction('files','readonly').objectStore('files').get(filename);read.onerror=function(){var msg='MediaDB.getFileInfo: unknown filename: '+filename;if(errback){errback(msg);}else{console.error(msg);}};read.onsuccess=function(){if(callback){callback(read.result);}};},getFile:function getFile(filename,callback,errback){if(this.state!==MediaDB.READY){throw Error('MediaDB is not ready. State: '+this.state);}
|
||
var storage=navigator.getDeviceStorage(this.mediaType);var getRequest=storage.get(filename);getRequest.onsuccess=function(){callback(getRequest.result);};getRequest.onerror=function(){var errmsg=getRequest.error&&getRequest.error.name;if(errback){errback(errmsg);}else{console.error('MediaDB.getFile:',errmsg);}};},deleteFile:function deleteFile(filename){if(this.state!==MediaDB.READY){throw Error('MediaDB is not ready. State: '+this.state);}
|
||
var storage=navigator.getDeviceStorage(this.mediaType);storage.delete(filename).onerror=function(e){console.error('MediaDB.deleteFile(): Failed to delete',filename,'from DeviceStorage:',e.target.error);};},addFile:function addFile(filename,file){if(this.state!==MediaDB.READY){throw Error('MediaDB is not ready. State: '+this.state);}
|
||
var media=this;var storage=navigator.getDeviceStorage(media.mediaType);var deletereq=storage.delete(filename);deletereq.onsuccess=deletereq.onerror=save;function save(){var request=storage.addNamed(file,filename);request.onerror=function(){console.error('MediaDB: Failed to store',filename,'in DeviceStorage:',request.error);};}},updateMetadata:function(filename,metadata,callback){if(this.state===MediaDB.OPENING){throw Error('MediaDB is not ready. State: '+this.state);}
|
||
var media=this;var read=media.db.transaction('files','readonly').objectStore('files').get(filename);read.onerror=function(){console.error('MediaDB.updateMetadata called with unknown filename');};read.onsuccess=function(){var fileinfo=read.result;Object.keys(metadata).forEach(function(key){fileinfo.metadata[key]=metadata[key];});var write=media.db.transaction('files','readwrite').objectStore('files').put(fileinfo);write.onerror=function(){console.error('MediaDB.updateMetadata: database write failed',write.error&&write.error.name);};if(callback){write.onsuccess=function(){callback();};}};},count:function(key,range,callback){if(this.state!==MediaDB.READY&&this.state!==MediaDB.ENUMERABLE){throw Error('MediaDB is not ready or enumerable. State: '+this.state);}
|
||
if(arguments.length===1){callback=key;range=undefined;key=undefined;}
|
||
else if(arguments.length===2){callback=range;range=key;key=undefined;}
|
||
var store=this.db.transaction('files').objectStore('files');if(key&&key!=='name'){store=store.index(key);}
|
||
var countRequest=store.count(range||null);countRequest.onerror=function(){console.error('MediaDB.count() failed with',countRequest.error);};countRequest.onsuccess=function(e){callback(e.target.result);};},enumerate:function enumerate(key,range,direction,callback){if(this.state!==MediaDB.READY&&this.state!==MediaDB.ENUMERABLE){throw Error('MediaDB is not ready or enumerable. State: '+this.state);}
|
||
var handle={state:'enumerating'};if(arguments.length===1){callback=key;key=undefined;}
|
||
else if(arguments.length===2){callback=range;range=undefined;}
|
||
else if(arguments.length===3){callback=direction;direction=undefined;}
|
||
var store=this.db.transaction('files').objectStore('files');if(key&&key!=='name'){store=store.index(key);}
|
||
var cursorRequest=store.openCursor(range||null,direction||'next');cursorRequest.onerror=function(){console.error('MediaDB.enumerate() failed with',cursorRequest.error);handle.state='error';};cursorRequest.onsuccess=function(){if(handle.state==='cancelling'){handle.state='cancelled';return;}
|
||
var cursor=cursorRequest.result;if(cursor){try{var fileinfo=cursor.value;if(!fileinfo.fail){callback(fileinfo);}}
|
||
catch(e){console.warn('MediaDB.enumerate(): callback threw',e,e.stack);}
|
||
cursor.continue();}
|
||
else{handle.state='complete';callback(null);}};return handle;},advancedEnumerate:function(key,range,direction,index,callback){if(this.state!==MediaDB.READY){throw Error('MediaDB is not ready. State: '+this.state);}
|
||
var handle={state:'enumerating'};var store=this.db.transaction('files').objectStore('files');if(key&&key!=='name'){store=store.index(key);}
|
||
var cursorRequest=store.openCursor(range||null,direction||'next');var isTarget=false;cursorRequest.onerror=function(){console.error('MediaDB.enumerate() failed with',cursorRequest.error);handle.state='error';};cursorRequest.onsuccess=function(){if(handle.state==='cancelling'){handle.state='cancelled';return;}
|
||
var cursor=cursorRequest.result;if(cursor){try{if(index===0){isTarget=true;}
|
||
var fileinfo=cursor.value;if(!fileinfo.fail&&isTarget){callback(cursor.value);cursor.continue();}
|
||
else{cursor.advance(index);isTarget=true;}}
|
||
catch(e){console.warn('MediaDB.enumerate(): callback threw',e,e.stack);}}
|
||
else{handle.state='complete';callback(null);}};return handle;},enumerateAll:function enumerateAll(key,range,direction,callback){var batch=[];if(arguments.length===1){callback=key;key=undefined;}
|
||
else if(arguments.length===2){callback=range;range=undefined;}
|
||
else if(arguments.length===3){callback=direction;direction=undefined;}
|
||
return this.enumerate(key,range,direction,function(fileinfo){if(fileinfo!==null){batch.push(fileinfo);}else{callback(batch);}});},cancelEnumeration:function cancelEnumeration(handle){if(handle.state==='enumerating'){handle.state='cancelling';}},getAll:function getAll(callback){if(this.state!==MediaDB.READY&&this.state!==MediaDB.ENUMERABLE){throw Error('MediaDB is not ready or enumerable. State: '+this.state);}
|
||
var store=this.db.transaction('files').objectStore('files');var request=store.mozGetAll();request.onerror=function(){console.error('MediaDB.getAll() failed with',request.error);};request.onsuccess=function(){var all=request.result;var good=all.filter(function(fileinfo){return!fileinfo.fail;});callback(good);};},scan:function(){scan(this);},freeSpace:function freeSpace(callback){if(this.state!==MediaDB.READY){throw Error('MediaDB is not ready. State: '+this.state);}
|
||
var storage=navigator.getDeviceStorage(this.mediaType);var freereq=storage.freeSpace();freereq.onsuccess=function(){callback(freereq.result);};}};MediaDB.VERSION=3;MediaDB.OPENING='opening';MediaDB.UPGRADING='upgrading';MediaDB.ENUMERABLE='enumerable';MediaDB.READY='ready';MediaDB.NOCARD='nocard';MediaDB.UNMOUNTED='unmounted';MediaDB.CLOSED='closed';function ignore(media,file){if(ignoreName(media,file.name)){return true;}
|
||
if(media.mimeTypes&&media.mimeTypes.indexOf(file.type)===-1){return true;}
|
||
return false;}
|
||
function ignoreName(media,filename){if(media.clientExcludeFilter&&media.clientExcludeFilter.test(filename)){return true;}else{return(filename[0]==='.'||filename.indexOf('/.')!==-1);}}
|
||
function scan(media){media.scanning=true;dispatchEvent(media,'scanstart');quickScan(media.details.newestFileModTime);function quickScan(timestamp){var options;if(timestamp>0){media.details.firstscan=false;options={since:new Date(timestamp+1)};}
|
||
else{media.details.firstscan=true;media.details.records=[];options={};}
|
||
scanDS(media.details.storages,null,options).then(processFiles).catch(handleScanError);function processFiles(files){if(!media.scanning){return;}
|
||
files=files.sort(function(a,b){return b.lastModifiedDate-a.lastModifiedDate;});for(var i=0;i<files.length;i++){insertRecord(media,files[i]);}
|
||
whenDoneProcessing(media,function(){sendNotifications(media);if(media.details.firstscan){endscan(media);}
|
||
else{fullScan();}});}
|
||
function handleScanError(error){console.warn('Error while scanning',error);endscan(media);}}
|
||
function fullScan(){if(media.state!==MediaDB.READY){endscan(media);return;}
|
||
var dsfiles;scanDS(media.details.storages).then(function(files){dsfiles=files;getDBFiles();}).catch(function(error){console.warn('Error while scanning',error);endscan(media);});function getDBFiles(){var store=media.db.transaction('files').objectStore('files');var getAllRequest=store.mozGetAll();getAllRequest.onsuccess=function(){if(!media.scanning){return;}
|
||
var dbfiles=getAllRequest.result;compareLists(dbfiles,dsfiles);};}
|
||
function compareLists(dbfiles,dsfiles){dsfiles.sort(function(a,b){if(a.name<b.name){return-1;}else{return 1;}});var dsindex=0,dbindex=0;while(true){var dsfile;if(dsindex<dsfiles.length){dsfile=dsfiles[dsindex];}else{dsfile=null;}
|
||
var dbfile;if(dbindex<dbfiles.length){dbfile=dbfiles[dbindex];}else{dbfile=null;}
|
||
if(dsfile===null&&dbfile===null){break;}
|
||
if(dbfile===null){insertRecord(media,dsfile);dsindex++;continue;}
|
||
if(dsfile===null){deleteRecord(media,dbfile.name);dbindex++;continue;}
|
||
if(dsfile.name===dbfile.name){var lastModified=dsfile.lastModifiedDate;var timeDifference=lastModified.getTime()-dbfile.date;var sameTime=(timeDifference===0||((Math.abs(timeDifference)<=12*60*60*1000)&&(timeDifference%10*60*1000===0)));var sameSize=dsfile.size===dbfile.size;if(!sameTime||!sameSize){deleteRecord(media,dbfile.name);insertRecord(media,dsfile);}else if(dbfile.needsReparse){deleteRecord(media,dbfile.name);insertRecord(media,dsfile,dbfile.metadata);}
|
||
dsindex++;dbindex++;continue;}
|
||
if(dsfile.name<dbfile.name){insertRecord(media,dsfile);dsindex++;continue;}
|
||
if(dsfile.name>dbfile.name){deleteRecord(media,dbfile.name);dbindex++;continue;}
|
||
console.error('Assertion failed');}
|
||
insertRecord(media,null);}}
|
||
function scanDS(storage,directory,options){if(Array.isArray(storage)){return Promise.all(storage.map((s)=>scanDS(s,directory,options))).then(function(arrays){return Array.prototype.concat.apply([],arrays);});}
|
||
return new Promise(function(resolve,reject){var files=[];var cursor=storage.enumerate(directory||'',options||{});cursor.onerror=function(){if(cursor.error.name==='NotFoundError'){resolve(files);}
|
||
else{reject(cursor.error);}};cursor.onsuccess=function(){var result=cursor.result;if(result){if(!ignore(media,result)){files.push(result);}
|
||
cursor.continue();}
|
||
else{resolve(files);}};});}}
|
||
function endscan(media){if(media.scanning){media.initialScanComplete=true;media.scanning=false;media.parsingBigFiles=false;dispatchEvent(media,'scanend');}}
|
||
function insertRecord(media,fileOrName,oldMetadata){var details=media.details;details.pendingInsertions.push([fileOrName,oldMetadata]);if(details.processingQueue){return;}
|
||
processQueue(media);}
|
||
function deleteRecord(media,filename){var details=media.details;details.pendingDeletions.push(filename);if(details.processingQueue){return;}
|
||
processQueue(media);}
|
||
function whenDoneProcessing(media,f){var details=media.details;if(details.processingQueue){details.whenDoneProcessing.push(f);}else{f();}}
|
||
function processQueue(media){var details=media.details;details.processingQueue=true;next();function next(){if(details.pendingDeletions.length>0){deleteFiles();}
|
||
else if(details.pendingInsertions.length>0){insertFile(...details.pendingInsertions.shift());}
|
||
else{details.processingQueue=false;if(details.whenDoneProcessing.length>0){var functions=details.whenDoneProcessing;details.whenDoneProcessing=[];functions.forEach(function(f){f();});}}}
|
||
function deleteFiles(){var transaction=media.db.transaction('files','readwrite');var store=transaction.objectStore('files');deleteNextFile();function deleteNextFile(){if(details.pendingDeletions.length===0){next();return;}
|
||
var filename=details.pendingDeletions.shift();var request=store.delete(filename);request.onerror=function(){console.warn('MediaDB: Unknown file in deleteRecord:',filename,request.error);deleteNextFile();};request.onsuccess=function(){queueDeleteNotification(media,filename);deleteNextFile();};}}
|
||
function insertFile(f,oldMetadata){if(f===null){sendNotifications(media);endscan(media);next();return;}
|
||
if(typeof f==='string'){var storage=navigator.getDeviceStorage(media.mediaType);var getreq=storage.get(f);getreq.onerror=function(){console.warn('MediaDB: Unknown file in insertRecord:',f,getreq.error);next();};getreq.onsuccess=function(){if(media.mimeTypes&&ignore(media,getreq.result)){next();}else{parseMetadata(getreq.result,f,oldMetadata);}};}
|
||
else{parseMetadata(f,f.name,oldMetadata);}}
|
||
function parseMetadata(file,filename,oldMetadata){if(!file.lastModifiedDate){console.warn('MediaDB: parseMetadata: no lastModifiedDate for',filename,'using Date.now() until #793955 is fixed');}
|
||
var fileinfo={name:filename,type:file.type,size:file.size,date:file.lastModifiedDate?file.lastModifiedDate.getTime():Date.now()};if(fileinfo.date>details.newestFileModTime){details.newestFileModTime=fileinfo.date;}
|
||
media.metadataParser(file,gotMetadata,metadataError,parsingBigFile);function parsingBigFile(){media.parsingBigFiles=true;}
|
||
function metadataError(e){console.warn('MediaDB: error parsing metadata for',filename,':',e);fileinfo.fail=true;storeRecord(fileinfo);}
|
||
function gotMetadata(metadata){fileinfo.metadata=metadata;if(oldMetadata&&media.reparsedRecord){fileinfo.metadata=media.reparsedRecord(oldMetadata,metadata);}
|
||
storeRecord(fileinfo);if(!media.scanning){media.parsingBigFiles=false;}}}
|
||
function storeRecord(fileinfo){if(media.details.firstscan){media.details.records.push(fileinfo);if(!fileinfo.fail){queueCreateNotification(media,fileinfo);}
|
||
next();}
|
||
else{var transaction=media.db.transaction('files','readwrite');var store=transaction.objectStore('files');var request=store.add(fileinfo);request.onsuccess=function(){if(!fileinfo.fail){queueCreateNotification(media,fileinfo);}
|
||
next();};request.onerror=function(event){if(request.error.name==='ConstraintError'){event.stopPropagation();event.preventDefault();var putrequest=store.put(fileinfo);putrequest.onsuccess=function(){queueDeleteNotification(media,fileinfo.name);if(!fileinfo.fail){queueCreateNotification(media,fileinfo);}
|
||
next();};putrequest.onerror=function(){console.error('MediaDB: unexpected ConstraintError','in insertRecord for file:',fileinfo.name);next();};}
|
||
else{console.error('MediaDB: unexpected error in insertRecord:',request.error,'for file:',fileinfo.name);next();}};}}}
|
||
function queueCreateNotification(media,fileinfo){var creates=media.details.pendingCreateNotifications;creates.push(fileinfo);if(media.batchSize&&creates.length>=media.batchSize){sendNotifications(media);}else{resetNotificationTimer(media);}}
|
||
function queueDeleteNotification(media,filename){var deletes=media.details.pendingDeleteNotifications;deletes.push(filename);if(media.batchSize&&deletes.length>=media.batchSize){sendNotifications(media);}else{resetNotificationTimer(media);}}
|
||
function resetNotificationTimer(media){var details=media.details;if(details.pendingNotificationTimer){clearTimeout(details.pendingNotificationTimer);}
|
||
details.pendingNotificationTimer=setTimeout(function(){sendNotifications(media);},media.scanning?media.batchHoldTime:100);}
|
||
function sendNotifications(media){var details=media.details;if(details.pendingNotificationTimer){clearTimeout(details.pendingNotificationTimer);details.pendingNotificationTimer=null;}
|
||
if(details.pendingDeleteNotifications.length>0){var deletions=details.pendingDeleteNotifications;details.pendingDeleteNotifications=[];dispatchEvent(media,'deleted',deletions);}
|
||
if(details.pendingCreateNotifications.length>0){var creations=details.pendingCreateNotifications;details.pendingCreateNotifications=[];if(details.firstscan&&details.records.length>0){var transaction=media.db.transaction('files','readwrite');var store=transaction.objectStore('files');for(var i=0;i<details.records.length;i++){store.add(details.records[i]);}
|
||
details.records.length=0;transaction.oncomplete=function(){dispatchEvent(media,'created',creations);};}
|
||
else{dispatchEvent(media,'created',creations);}}}
|
||
function dispatchEvent(media,type,detail){var handler=media['on'+type];var listeners=media.details.eventListeners[type];if(!handler&&(!listeners||listeners.length===0)){return;}
|
||
var event={type:type,target:media,currentTarget:media,timestamp:Date.now(),detail:detail};if(typeof handler==='function'){try{handler.call(media,event);}
|
||
catch(e){console.warn('MediaDB: ','on'+type,'event handler threw',e,e.stack);}}
|
||
if(!listeners){return;}
|
||
for(var i=0;i<listeners.length;i++){try{var listener=listeners[i];if(typeof listener==='function'){listener.call(media,event);}
|
||
else{listener.handleEvent(event);}}
|
||
catch(e){console.warn('MediaDB: ',type,'event listener threw',e,e.stack);}}}
|
||
function changeState(media,state){if(media.state!==state){media.state=state;switch(state){case MediaDB.READY:case MediaDB.ENUMERABLE:dispatchEvent(media,state);break;default:dispatchEvent(media,'unavailable',state);break;}}}
|
||
return MediaDB;}());;'use strict';var MediaUtils={formatDate:function(timestamp){if(!timestamp||timestamp===undefined||isNaN(timestamp)){return;}
|
||
return new Date(timestamp).toLocaleString(navigator.languages,{'month':'numeric','year':'numeric','day':'numeric'});},getLocalizedSizeTokens:function(size){if(!size||size===undefined||isNaN(size)){return Promise.resolve('');}
|
||
var units=['B','KB','MB','GB','TB','PB','EB','ZB','YB'];var i=0;while(size>=1024&&i<(units.length-1)){size/=1024;++i;}
|
||
var sizeDecimal=i<2?Math.round(size):Math.round(size*10)/10;return document.l10n.formatValue('byteUnit-'+units[i]).then((unit)=>{return{size:sizeDecimal,unit};});},getLocalizedSize:function(size){return this.getLocalizedSizeTokens(size).then((args)=>{return document.l10n.formatValue('fileSize',args);});},formatDuration:function(duration){function padLeft(num,length){var r=String(num);while(r.length<length){r='0'+r;}
|
||
return r;}
|
||
duration=Math.round(duration);var minutes=Math.floor(duration/60);var seconds=duration%60;if(minutes<60){return padLeft(minutes,2)+':'+padLeft(seconds,2);}
|
||
var hours=Math.floor(minutes/60);minutes=Math.floor(minutes%60);return hours+':'+padLeft(minutes,2)+':'+padLeft(seconds,2);},populateMediaInfo:function(data){for(var id in data){if(data.hasOwnProperty(id)){var element=document.getElementById(id);if(element){if(typeof data[id]==='string'){element.setAttribute('data-l10n-id',data[id]);}else if(data[id].hasOwnProperty('raw')){element.removeAttribute('data-l10n-id');element.textContent=data[id].raw;}else{document.l10n.setAttributes(element,data[id].id,data[id].args);}}}}},binarySearch:function(array,element,comparator,from,to){if(comparator===undefined){comparator=function(a,b){return a-b;};}
|
||
if(from===undefined){return MediaUtils.binarySearch(array,element,comparator,0,array.length);}
|
||
if(from===to){return from;}
|
||
var mid=Math.floor((from+to)/2);var result=comparator(element,array[mid]);if(result<0){return MediaUtils.binarySearch(array,element,comparator,from,mid);}
|
||
else{return MediaUtils.binarySearch(array,element,comparator,mid+1,to);}}};;'use strict';var BlobView=(function(){function fail(msg){throw Error(msg);}
|
||
var decoderCache={};function getDecoder(encoding){if(encoding in decoderCache){return decoderCache[encoding];}
|
||
var decoder=decoderCache[encoding]=new TextDecoder(encoding);return decoder;}
|
||
function BlobView(blob,sliceOffset,sliceLength,slice,viewOffset,viewLength,littleEndian)
|
||
{this.blob=blob;this.sliceOffset=sliceOffset;this.sliceLength=sliceLength;this.slice=slice;this.viewOffset=viewOffset;this.viewLength=viewLength;this.littleEndian=littleEndian;this.view=new DataView(slice,viewOffset,viewLength);this.buffer=slice;this.byteLength=viewLength;this.byteOffset=viewOffset;this.index=0;}
|
||
BlobView.get=function(blob,offset,length,callback,littleEndian){if(offset<0){fail('negative offset');}
|
||
if(length<0){fail('negative length');}
|
||
if(offset>blob.size){fail('offset larger than blob size');}
|
||
if(offset+length>blob.size){length=blob.size-offset;}
|
||
var slice=blob.slice(offset,offset+length);var reader=new FileReader();reader.readAsArrayBuffer(slice);reader.onloadend=function(){var result=null;if(reader.result){result=new BlobView(blob,offset,length,reader.result,0,length,littleEndian||false);}
|
||
callback(result,reader.error);};};BlobView.getFromArrayBuffer=function(buffer,offset,length,littleEndian){return new BlobView(null,offset,length,buffer,offset,length,littleEndian);};BlobView.prototype={constructor:BlobView,getMore:function(offset,length,callback){if(!this.blob){fail('no blob backing this BlobView');}
|
||
if(offset>=this.sliceOffset&&offset+length<=this.sliceOffset+this.sliceLength){callback(new BlobView(this.blob,this.sliceOffset,this.sliceLength,this.slice,offset-this.sliceOffset,length,this.littleEndian));}
|
||
else{BlobView.get(this.blob,offset,length,callback,this.littleEndian);}},littleEndian:function(){this.littleEndian=true;},bigEndian:function(){this.littleEndian=false;},getUint8:function(offset){return this.view.getUint8(offset);},getInt8:function(offset){return this.view.getInt8(offset);},getUint16:function(offset,le){return this.view.getUint16(offset,le!==undefined?le:this.littleEndian);},getInt16:function(offset,le){return this.view.getInt16(offset,le!==undefined?le:this.littleEndian);},getUint32:function(offset,le){return this.view.getUint32(offset,le!==undefined?le:this.littleEndian);},getInt32:function(offset,le){return this.view.getInt32(offset,le!==undefined?le:this.littleEndian);},getFloat32:function(offset,le){return this.view.getFloat32(offset,le!==undefined?le:this.littleEndian);},getFloat64:function(offset,le){return this.view.getFloat64(offset,le!==undefined?le:this.littleEndian);},readByte:function(){return this.view.getInt8(this.index++);},readUnsignedByte:function(){return this.view.getUint8(this.index++);},readShort:function(le){var val=this.view.getInt16(this.index,le!==undefined?le:this.littleEndian);this.index+=2;return val;},readUnsignedShort:function(le){var val=this.view.getUint16(this.index,le!==undefined?le:this.littleEndian);this.index+=2;return val;},readInt:function(le){var val=this.view.getInt32(this.index,le!==undefined?le:this.littleEndian);this.index+=4;return val;},readUnsignedInt:function(le){var val=this.view.getUint32(this.index,le!==undefined?le:this.littleEndian);this.index+=4;return val;},readFloat:function(le){var val=this.view.getFloat32(this.index,le!==undefined?le:this.littleEndian);this.index+=4;return val;},readDouble:function(le){var val=this.view.getFloat64(this.index,le!==undefined?le:this.littleEndian);this.index+=8;return val;},tell:function(){return this.index;},remaining:function(){return this.byteLength-this.index;},seek:function(index){if(index<0){fail('negative index');}
|
||
if(index>this.byteLength){fail('index greater than buffer size');}
|
||
this.index=index;},advance:function(n){var index=this.index+n;if(index<0){fail('advance past beginning of buffer');}
|
||
if(index>this.byteLength){fail('advance past end of buffer');}
|
||
this.index=index;},getUnsignedByteArray:function(offset,n){return new Uint8Array(this.buffer,offset+this.viewOffset,n);},readUnsignedByteArray:function(n){var val=new Uint8Array(this.buffer,this.index+this.viewOffset,n);this.index+=n;return val;},getBit:function(offset,bit){var byte=this.view.getUint8(offset);return(byte&(1<<bit))!==0;},getUint24:function(offset,le){var b1,b2,b3;if(le!==undefined?le:this.littleEndian){b1=this.view.getUint8(offset);b2=this.view.getUint8(offset+1);b3=this.view.getUint8(offset+2);}
|
||
else{b3=this.view.getUint8(offset);b2=this.view.getUint8(offset+1);b1=this.view.getUint8(offset+2);}
|
||
return(b3<<16)+(b2<<8)+b1;},readUint24:function(le){var value=this.getUint24(this.index,le);this.index+=3;return value;},getBinaryText:function(offset,len){var bytes=new Uint8Array(this.buffer,offset+this.viewOffset,len);return String.fromCharCode.apply(String,bytes);},readBinaryText:function(len){var s=this.getBinaryText(this.index,len);this.index+=len;return s;},getLatin1Text:function(offset,len){var bytes=new Uint8Array(this.buffer,offset+this.viewOffset,len);return getDecoder('latin1').decode(bytes);},readLatin1Text:function(len){var s=this.getLatin1Text(this.index,len);this.index+=len;return s;},getUTF8Text:function(offset,len){var bytes=new Uint8Array(this.buffer,offset+this.viewOffset,len);return getDecoder('utf-8').decode(bytes);},readUTF8Text:function(len){var s=this.getUTF8Text(this.index,len);this.index+=len;return s;},getUTF16Text:function(offset,len,le){if(len%2){fail('len must be a multiple of two');}
|
||
var bytes=new Uint8Array(this.buffer,offset+this.viewOffset,len);if(le===null||le===undefined){var BOM=(bytes[0]<<8)+bytes[1];if(BOM===0xFEFF){bytes=bytes.subarray(2);le=false;}else if(BOM===0xFFFE){bytes=bytes.subarray(2);le=true;}else{le=true;}}
|
||
var encoding=le?'utf-16le':'utf-16be';return getDecoder(encoding).decode(bytes);},readUTF16Text:function(len,le){var s=this.getUTF16Text(this.index,len,le);this.index+=len;return s;},getID3Uint28BE:function(offset){var b1=this.view.getUint8(offset)&0x7f;var b2=this.view.getUint8(offset+1)&0x7f;var b3=this.view.getUint8(offset+2)&0x7f;var b4=this.view.getUint8(offset+3)&0x7f;return(b1<<21)|(b2<<14)|(b3<<7)|b4;},readID3Uint28BE:function(){var value=this.getID3Uint28BE(this.index);this.index+=4;return value;},readNullTerminatedLatin1Text:function(size,advance_by_size=false){var bytes=new Uint8Array(this.buffer,this.viewOffset+this.index,size);var nil=bytes.indexOf(0);if(nil!==-1){bytes=bytes.subarray(0,nil);}
|
||
var s=getDecoder('latin1').decode(bytes);if(nil===-1||advance_by_size){this.index+=size;}else{this.index+=nil+1;}
|
||
return s;},readNullTerminatedUTF8Text:function(size,advance_by_size=false){var bytes=new Uint8Array(this.buffer,this.viewOffset+this.index,size);var nil=bytes.indexOf(0);if(nil!==-1){bytes=bytes.subarray(0,nil);}
|
||
var s=getDecoder('utf-8').decode(bytes);if(nil===-1||advance_by_size){this.index+=size;}else{this.index+=nil+1;}
|
||
return s;},readNullTerminatedUTF16Text:function(size,le,advance_by_size=false){if(size%2){fail('size must be a multiple of two');}
|
||
for(var len=0;len<size;len+=2){if(this.getUint16(this.index+len,le)===0){break;}}
|
||
var s=this.getUTF16Text(this.index,len,le);if(len===size||advance_by_size){this.index+=size;}else{this.index+=len+2;}
|
||
return s;}};return{get:BlobView.get,getFromArrayBuffer:BlobView.getFromArrayBuffer};}());;'use strict';function getVideoRotation(blob,rotationCallback){function MP4Parser(blob,handlers){BlobView.get(blob,0,Math.min(1024,blob.size),function(data,error){if(data.byteLength<=8||data.getBinaryText(4,4)!=='ftyp'){handlers.errorHandler('not an MP4 file');return;}
|
||
parseAtom(data);});function parseAtom(data){var offset=data.sliceOffset+data.viewOffset;var size=data.readUnsignedInt();var type=data.readBinaryText(4);var contentOffset=8;if(size===0){size=blob.size-offset;}
|
||
else if(size===1){size=data.readUnsignedInt()*4294967296+data.readUnsignedInt();contentOffset=16;}
|
||
var handler=handlers[type]||handlers.defaultHandler;if(typeof handler==='function'){data.getMore(data.sliceOffset+data.viewOffset,size,function(atom){var rv=handler(atom);if(rv!=='done'){parseAtomAt(data,offset+size);}});}
|
||
else if(handler==='children'){var skip=(type==='meta')?4:0;parseAtomAt(data,offset+contentOffset+skip);}
|
||
else if(handler==='skip'||!handler){parseAtomAt(data,offset+size);}
|
||
else if(handler==='done'){return;}}
|
||
function parseAtomAt(data,offset){if(offset>=blob.size){if(handlers.eofHandler){handlers.eofHandler();}
|
||
return;}
|
||
else{data.getMore(offset,16,parseAtom);}}}
|
||
MP4Parser(blob,{errorHandler:function(msg){rotationCallback(msg);},eofHandler:function(){rotationCallback(null);},defaultHandler:'skip',moov:'children',trak:'children',tkhd:function(data){data.advance(48);var a=data.readUnsignedInt();var b=data.readUnsignedInt();data.advance(4);var c=data.readUnsignedInt();var d=data.readUnsignedInt();if(a===0&&d===0){if(b===0x00010000&&c===0xFFFF0000){rotationCallback(90);}
|
||
else if(b===0xFFFF0000&&c===0x00010000){rotationCallback(270);}
|
||
else{rotationCallback('unexpected rotation matrix');}}
|
||
else if(b===0&&c===0){if(a===0x00010000&&d===0x00010000){rotationCallback(0);}
|
||
else if(a===0xFFFF0000&&d===0xFFFF0000){rotationCallback(180);}
|
||
else{rotationCallback('unexpected rotation matrix');}}
|
||
else{rotationCallback('unexpected rotation matrix');}
|
||
return'done';}});};(function(exports){'use strict';function ManifestHelper_get(prop){var manifest=this;var value=manifest[prop];var lang=document.documentElement.lang||'';if(manifest.locales){[lang,lang.substr(0,lang.indexOf('-'))].some(function tryLanguage(lang){if(this[lang]&&this[lang][prop]){value=this[lang][prop];return true;}},manifest.locales);}
|
||
if(typeof value==='object'&&!(value instanceof Array)){value=new ManifestHelper(value);}
|
||
return value;}
|
||
function ManifestHelper(manifest){for(var prop in manifest){Object.defineProperty(this,prop,{get:ManifestHelper_get.bind(manifest,prop),enumerable:true});}}
|
||
Object.defineProperty(ManifestHelper.prototype,'displayName',{get:function displayName(){return this.short_name||this.name;}});exports.ManifestHelper=ManifestHelper;}(window));;'use strict';var VideoStats=(function(){var startQuality;var startTime;var endQuality;var endTime;var video;function start(v){video=v;if(!video.getVideoPlaybackQuality){return;}
|
||
startQuality=video.getVideoPlaybackQuality();startTime=video.currentTime;endQuality=null;endTime=null;}
|
||
function stop(){if(!video){dump('Warning: no stats have been recorded. '+'Make sure start() has been called');return;}
|
||
if(!video.getVideoPlaybackQuality){return;}
|
||
endQuality=video.getVideoPlaybackQuality();endTime=video.currentTime;}
|
||
function print(){if(!video){dump('Warning: no stats have been recorded. '+'Make sure start() has been called');return;}
|
||
if(!video.getVideoPlaybackQuality){return;}
|
||
if(!startQuality||!endQuality){dump('Warning: no stats have been recorded. '+'Make sure start() and stop() have been called');return;}
|
||
var segmentDuration=(endQuality.creationTime-startQuality.creationTime)/1000;var startRendered=startQuality.totalVideoFrames-startQuality.droppedVideoFrames;var endRendered=endQuality.totalVideoFrames-endQuality.droppedVideoFrames;var segmentRendered=endRendered-startRendered;var fps=segmentRendered/segmentDuration;dump('Video statistics start');dump('Dimensions: '+video.videoWidth+'x'+video.videoHeight);dump('Complete duration: '+MediaUtils.formatDuration(video.duration));dump('Start time: '+MediaUtils.formatDuration(startTime));dump('End time: '+MediaUtils.formatDuration(endTime));dump('Total frames: '+endQuality.totalVideoFrames);dump('Decoded frames: '+
|
||
(endQuality.totalVideoFrames-endQuality.corruptedVideoFrames));dump('Corrupted frames: '+endQuality.corruptedVideoFrames);dump('Rendered frames: '+
|
||
(endQuality.totalVideoFrames-endQuality.droppedVideoFrames));dump('Dropped frames: '+endQuality.droppedVideoFrames);dump('Average rendered FPS: '+fps.toFixed(2));dump('Video statistics end');}
|
||
return{start:start,stop:stop,dump:print};})();;'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 Dialogs={confirm:function(options,onConfirm,onCancel){LazyLoader.load('shared/style/confirm.css',function(){var dialog=$('confirm-dialog');var msgEle=$('confirm-msg');var cancelButton=$('confirm-cancel');var confirmButton=$('confirm-ok');var addText=function(element,prefix,defaultId){if(options[prefix+'Id']){document.l10n.setAttributes(element,options[prefix+'Id'],options[prefix+'Args']);}
|
||
else if(options[prefix]||options[prefix+'Text']){var textOption=options[prefix]||options[prefix+'Text'];element.textContent=textOption;}
|
||
else if(defaultId){element.setAttribute('data-l10n-id',defaultId);}};addText(msgEle,'message');addText(cancelButton,'cancel','cancel');addText(confirmButton,'confirm','ok');if(options.danger){confirmButton.classList.add('danger');}else{confirmButton.classList.remove('danger');}
|
||
if(options.bodyClass){document.body.classList.add(options.bodyClass);}
|
||
dialog.classList.remove('hidden');function close(ev){if(options.bodyClass){document.body.classList.remove(options.bodyClass);}
|
||
dialog.classList.add('hidden');cancelButton.removeEventListener('click',onCancelClick);confirmButton.removeEventListener('click',onConfirmClick);ev.preventDefault();ev.stopPropagation();return false;}
|
||
var onCancelClick=function(ev){close(ev);if(onCancel){onCancel();}
|
||
return false;};var onConfirmClick=function(ev){close(ev);if(onConfirm){onConfirm();}
|
||
return false;};cancelButton.addEventListener('click',onCancelClick);confirmButton.addEventListener('click',onConfirmClick);});}};;window.COMPONENTS_BASE_URL='/shared/elements/';;(function(exports){'use strict';exports.ComponentUtils={style:function(baseUrl){if(window.VulpesCompat){window.VulpesCompat.componentStyle(this,baseUrl).catch(console.error);return;}var style=document.createElement('style');var url=baseUrl+'style.css';var self=this;style.setAttribute('scoped','');style.innerHTML='@import url('+url+');';this.appendChild(style);this.style.visibility='hidden';style.addEventListener('load',function(){if(self.shadowRoot){self.shadowRoot.appendChild(style.cloneNode(true));}
|
||
self.style.visibility='';});}};}(window));;(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.GaiaHeader=f()}})(function(){var define,module,exports;return(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){;(function(define){define(function(require,exports,module){'use strict';var debug=0?console.log.bind(console):function(){};var cache={};var MIN=16;var MAX=24;var BUFFER=3;module.exports=function(config){debug('font fit',config);var space=config.space-BUFFER;var min=config.min||MIN;var max=config.max||MAX;var text=trim(config.text);var fontSize=max;var textWidth;var font;do{font=config.font.replace(/\d+px/,fontSize+'px');textWidth=getTextWidth(text,font);}while(textWidth>space&&fontSize!==min&&fontSize--);return{textWidth:textWidth,fontSize:fontSize,overflowing:textWidth>space};};function getTextWidth(text,font){var ctx=getCanvasContext(font);var width=ctx.measureText(text).width;debug('got text width',width);return width;}
|
||
function getCanvasContext(font){debug('get canvas context',font);var cached=cache[font];if(cached){return cached;}
|
||
var canvas=document.createElement('canvas');canvas.setAttribute('moz-opaque','true');canvas.setAttribute('width','1px');canvas.setAttribute('height','1px');debug('created canvas',canvas);var ctx=canvas.getContext('2d',{willReadFrequently:true});ctx.font=font;return cache[font]=ctx;}
|
||
function trim(text){return text.replace(/\s+/g,' ').trim();}});})(typeof define=='function'&&define.amd?define:(function(n,w){'use strict';return typeof module=='object'?function(c){c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){return w[n];},m.exports,m);w[n]=m.exports;};})('font-fit',this));},{}],2:[function(require,module,exports){;(function(define){'use strict';define(function(require,exports,module){var textContent=Object.getOwnPropertyDescriptor(Node.prototype,'textContent');var innerHTML=Object.getOwnPropertyDescriptor(Element.prototype,'innerHTML');var removeAttribute=Element.prototype.removeAttribute;var setAttribute=Element.prototype.setAttribute;var noop=function(){};exports.register=function(name,props){var baseProto=getBaseProto(props.extends);var template=props.template||baseProto.templateString;var extensible=props.extensible=props.hasOwnProperty('extensible')?props.extensible:true;delete props.extends;if(template){if(extensible&&props.template){props.templateString=props.template;}
|
||
var output=processCss(template,name);props.template=document.createElement('template');props.template.innerHTML=output.template;props.lightCss=output.lightCss;props.globalCss=props.globalCss||'';props.globalCss+=output.globalCss;}
|
||
injectGlobalCss(props.globalCss);delete props.globalCss;var descriptors=mixin(props.attrs||{},base.descriptors);props._attrs=props.attrs;delete props.attrs;var proto=createProto(baseProto,props);Object.defineProperties(proto,descriptors);try{return document.registerElement(name,{prototype:proto});}catch(e){if(e.name!=='NotSupportedError'){throw e;}}};var base={properties:{GaiaComponent:true,attributeChanged:noop,attached:noop,detached:noop,created:noop,createdCallback:function(){if(this.dirObserver){addDirObserver();}
|
||
injectLightCss(this);this.created();},attributeChangedCallback:function(name,from,to){var prop=toCamelCase(name);if(this._attrs&&this._attrs[prop]){this[prop]=to;}
|
||
this.attributeChanged(name,from,to);},attachedCallback:function(){if(this.dirObserver){this.setInnerDirAttributes=setInnerDirAttributes.bind(null,this);document.addEventListener('dirchanged',this.setInnerDirAttributes);}
|
||
this.attached();},detachedCallback:function(){if(this.dirObserver){document.removeEventListener('dirchanged',this.setInnerDirAttributes);}
|
||
this.detached();},setupShadowRoot:function(){if(!this.template){return;}
|
||
var node=document.importNode(this.template.content,true);this.createShadowRoot().appendChild(node);if(this.dirObserver){setInnerDirAttributes(this);}
|
||
return this.shadowRoot;},setAttr:function(name,value){var internal=this.shadowRoot.firstElementChild;setAttribute.call(internal,name,value);setAttribute.call(this,name,value);},removeAttr:function(name){var internal=this.shadowRoot.firstElementChild;removeAttribute.call(internal,name);removeAttribute.call(this,name);}},descriptors:{textContent:{set:function(value){textContent.set.call(this,value);if(this.lightStyle){this.appendChild(this.lightStyle);}},get:function(){return textContent.get();}},innerHTML:{set:function(value){innerHTML.set.call(this,value);if(this.lightStyle){this.appendChild(this.lightStyle);}},get:innerHTML.get}}};var defaultPrototype=createProto(HTMLElement.prototype,base.properties);function getBaseProto(proto){if(!proto){return defaultPrototype;}
|
||
proto=proto.prototype||proto;return!proto.GaiaComponent?createProto(proto,base.properties):proto;}
|
||
function createProto(proto,props){return mixin(Object.create(proto),props);}
|
||
var hasShadowCSS=(function(){var div=document.createElement('div');try{div.querySelector(':host');div.querySelector('::content');return true;}
|
||
catch(e){return false;}})();var regex={shadowCss:/(?:\:host|\:\:content)[^{]*\{[^}]*\}/g,':host':/(?:\:host)/g,':host()':/\:host\((.+)\)(?: \:\:content)?/g,':host-context':/\:host-context\((.+)\)([^{,]+)?/g,'::content':/(?:\:\:content)/g};function processCss(template,name){var globalCss='';var lightCss='';if(!hasShadowCSS){template=template.replace(regex.shadowCss,function(match){var hostContext=regex[':host-context'].exec(match);if(hostContext){globalCss+=match.replace(regex['::content'],'').replace(regex[':host-context'],'$1 '+name+'$2').replace(/ +/g,' ');}else{lightCss+=match.replace(regex[':host()'],name+'$1').replace(regex[':host'],name).replace(regex['::content'],name);}
|
||
return'';});}
|
||
return{template:template,lightCss:lightCss,globalCss:globalCss};}
|
||
function injectGlobalCss(css){if(!css){return;}
|
||
var style=document.createElement('style');style.innerHTML=css.trim();headReady().then(function(){document.head.appendChild(style);});}
|
||
function headReady(){return new Promise(function(resolve){if(document.head){return resolve();}
|
||
window.addEventListener('load',function fn(){window.removeEventListener('load',fn);resolve();});});}
|
||
function injectLightCss(el){if(hasShadowCSS){return;}
|
||
var stylesheet=el.querySelector('style');if(!stylesheet){stylesheet=document.createElement('style');stylesheet.setAttribute('scoped','');stylesheet.appendChild(document.createTextNode(el.lightCss));el.appendChild(stylesheet);}
|
||
el.lightStyle=stylesheet;}
|
||
function toCamelCase(string){return string.replace(/-(.)/g,function replacer(string,p1){return p1.toUpperCase();});}
|
||
var dirObserver;function setInnerDirAttributes(component){var dir=component.dir||document.dir;Array.from(component.shadowRoot.children).forEach(element=>{if(element.nodeName!=='STYLE'){element.dir=dir;}});}
|
||
function addDirObserver(){if(dirObserver){return;}
|
||
dirObserver=new MutationObserver(onChanged);dirObserver.observe(document.documentElement,{attributeFilter:['dir'],attributes:true});function onChanged(mutations){document.dispatchEvent(new Event('dirchanged'));}}
|
||
function mixin(target,source){for(var key in source){target[key]=source[key];}
|
||
return target;}});})(typeof define=='function'&&define.amd?define:(function(n,w){'use strict';return typeof module=='object'?function(c){c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-component',this));},{}],3:[function(require,module,exports){(function(define){'use strict';define(function(require,exports,module){var base=window.GAIA_ICONS_BASE_URL||window.COMPONENTS_BASE_URL||'bower_components/';if(!document.documentElement){window.addEventListener('load',load);}else{load();}
|
||
function load(){if(isLoaded()){return;}
|
||
var link=document.createElement('link');link.rel='stylesheet';link.type='text/css';link.href=base+'gaia-icons/gaia-icons.css';document.head.appendChild(link);exports.loaded=true;}
|
||
function isLoaded(){return exports.loaded||document.querySelector('link[href*=gaia-icons]')||document.documentElement.classList.contains('gaia-icons-loaded');}});})(typeof define=='function'&&define.amd?define:(function(n,w){'use strict';return typeof module=='object'?function(c){c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-icons',this));},{}],4:[function(require,module,exports){;(function(define){'use strict';define(function(require,exports,module){var component=require('gaia-component');var fontFit=require('font-fit');require('gaia-icons');var debug=0?console.log.bind(console):function(){};const KNOWN_ACTIONS={menu:'menu',back:'back',close:'close'};const TITLE_FONT='italic 300 24px FiraSans';const TITLE_PADDING=10;const MINIMUM_FONT_SIZE_CENTERED=20;const MINIMUM_FONT_SIZE_UNCENTERED=16;const MAXIMUM_FONT_SIZE=23;module.exports=component.register('gaia-header',{extensible:false,dirObserver:true,created:function(){debug('created');this.setupShadowRoot();this.els={actionButton:this.shadowRoot.querySelector('.action-button'),titles:this.getElementsByTagName('h1')};this.els.actionButton.addEventListener('click',e=>this.onActionButtonClick(e));this.observer=new MutationObserver(this.onMutation.bind(this));this.ignoreDir=this.hasAttribute('ignore-dir');this.titleEnd=this.getAttribute('title-end');this.titleStart=this.getAttribute('title-start');this.noFontFit=this.getAttribute('no-font-fit');this.notFlush=this.hasAttribute('not-flush');this.action=this.getAttribute('action');this.unresolved={};this.pending={};this._resizeThrottlingId=null;this.onResize=this.onResize.bind(this);},attached:function(){debug('attached');this.runFontFitSoon();this.observerStart();window.addEventListener('resize',this.onResize);},detached:function(){debug('detached');window.removeEventListener('resize',this.onResize);this.observerStop();this.clearPending();},clearPending:function(){for(var key in this.pending){this.pending[key].clear();delete this.pending[key];}
|
||
window.cancelAnimationFrame(this._resizeThrottlingId);this._resizeThrottlingId=null;},runFontFit:function(){debug('run font-fit');if(this.noFontFit){return Promise.resolve();}
|
||
var titles=this.els.titles;var space=this.getTitleSpace();var styles=[].map.call(titles,el=>this.getTitleStyle(el,space));return this.setTitleStylesSoon(styles);},runFontFitSoon:function(){debug('run font-fit soon');if(this.pending.runFontFitSoon){return;}
|
||
this.pending.runFontFitSoon=this.nextTick(()=>{delete this.pending.runFontFitSoon;this.runFontFit();});},getTitleStyle:function(el,space){debug('get el style',el,space);var text=el.textContent;var styleId=space.start+text+space.end+'#'+space.value;if(!text||!text.trim()){return debug('exit: no text');}
|
||
if(getStyleId(el)===styleId){return debug('exit: no change');}
|
||
var marginStart=this.getTitleMarginStart();var textSpace=space.value-Math.abs(marginStart);var fontFitResult=this.fontFit(text,textSpace,{min:MINIMUM_FONT_SIZE_CENTERED});var overflowing=fontFitResult.overflowing;var padding={start:0,end:0};if(overflowing){debug('title overflowing');padding.start=!space.start?TITLE_PADDING:0;padding.end=!space.end?TITLE_PADDING:0;textSpace=space.value-padding.start-padding.end;fontFitResult=this.fontFit(text,textSpace);marginStart=0;}
|
||
return{id:styleId,fontSize:fontFitResult.fontSize,marginStart:marginStart,overflowing:overflowing,padding:padding};},setTitleStylesSoon:function(styles){debug('set title styles soon',styles);var key='setStyleTitlesSoon';this._titleStyles=styles;if(this.unresolved[key]){return this.unresolved[key];}
|
||
this.unresolved[key]=new Promise((resolve)=>{this.pending[key]=this.nextTick(()=>{var styles=this._titleStyles;var els=this.els.titles;[].forEach.call(els,(el,i)=>{if(!styles[i]){return debug('exit');}
|
||
this.setTitleStyle(el,styles[i]);});delete this._titleStyles;delete this.unresolved[key];delete this.pending[key];resolve();});});},setTitleStyle:function(el,style){debug('set title style',style);this.observerStop();if(this.ignoreDir){el.style.marginLeft=style.marginStart+'px';el.style.paddingLeft=style.padding.start+'px';el.style.paddingRight=style.padding.end+'px';}else{el.style.marginInlineStart=style.marginStart+'px';el.style.paddingInlineStart=style.padding.start+'px';el.style.paddingInlineEnd=style.padding.end+'px';}
|
||
el.style.fontSize=style.fontSize+'px';setStyleId(el,style.id);this.observerStart();},fontFit:function(text,space,opts={}){debug('font fit:',text,space,opts);var fontFitArgs={font:TITLE_FONT,min:opts.min||MINIMUM_FONT_SIZE_UNCENTERED,max:MAXIMUM_FONT_SIZE,text:text,space:space};return fontFit(fontFitArgs);},observerStart:function(){if(this.observing){return;}
|
||
this.observer.observe(this,{childList:true,attributes:true,subtree:true});this.observing=true;debug('observer started');},observerStop:function(){if(!this.observing){return;}
|
||
this.observer.disconnect();this.observing=false;debug('observer stopped');},onResize:function(e){debug('onResize',this._resizeThrottlingId);if(this._resizeThrottlingId!==null){return;}
|
||
this._resizeThrottlingId=window.requestAnimationFrame(()=>{this._resizeThrottlingId=null;this.runFontFitSoon();});},onMutation:function(mutations){debug('on mutation',mutations);if(!this.pending.runFontFitSoon){this.runFontFit();}},getTitleSpace:function(){var start=this.titleStart;var end=this.titleEnd;var space=this.getWidth()-start-end;var result={value:space,start:start,end:end};debug('get title space',result);return result;},getWidth:function(){var value=this.notFlush?this.clientWidth:window.innerWidth;debug('get width',value);return value;},triggerAction:function(){if(this.action){this.els.actionButton.click();}},onActionButtonClick:function(){debug('action button click');var config={detail:{type:this.action}};var e=new CustomEvent('action',config);setTimeout(()=>this.dispatchEvent(e));},getTitleMarginStart:function(){var start=this.titleStart;var end=this.titleEnd;var marginStart=end-start;debug('get title margin start',marginStart);return marginStart;},getButtonsBeforeTitle:function(){var children=this.children;var l=children.length;var els=[];for(var i=0;i<l;i++){var el=children[i];if(el.tagName==='H1'){break;}
|
||
if(!contributesToLayout(el)){continue;}
|
||
els.push(el);}
|
||
if(this.action){els.push(this.els.actionButton);}
|
||
return els;},getButtonsAfterTitle:function(){var children=this.children;var els=[];for(var i=children.length-1;i>=0;i--){var el=children[i];if(el.tagName==='H1'){break;}
|
||
if(!contributesToLayout(el)){continue;}
|
||
els.push(el);}
|
||
return els;},sumButtonWidths:function(buttons){var defaultWidth=50;var sum=buttons.reduce((prev,button)=>{var isStandardButton=button===this.els.actionButton;var width=isStandardButton?defaultWidth:button.clientWidth;return prev+width;},0);debug('sum button widths',buttons,sum);return sum;},attrs:{action:{get:function(){return this._action;},set:function(value){var action=KNOWN_ACTIONS[value];if(action===this._action){return;}
|
||
this.setAttr('action',action);this._action=action;}},titleStart:{get:function(){debug('get title-start');if('_titleStart'in this){return this._titleStart;}
|
||
var buttons=this.getButtonsBeforeTitle();var value=this.sumButtonWidths(buttons);debug('get title-start',buttons,value);return value;},set:function(value){debug('set title-start',value);value=parseInt(value,10);if(value===this._titleStart||isNaN(value)){return;}
|
||
this.setAttr('title-start',value);this._titleStart=value;debug('set');}},titleEnd:{get:function(){debug('get title-end');if('_titleEnd'in this){return this._titleEnd;}
|
||
var buttons=this.getButtonsAfterTitle();return this.sumButtonWidths(buttons);},set:function(value){debug('set title-end',value);value=parseInt(value,10);if(value===this._titleEnd||isNaN(value)){return;}
|
||
this.setAttr('title-end',value);this._titleEnd=value;}},noFontFit:{get:function(){return this._noFontFit||false;},set:function(value){debug('set no-font-fit',value);value=!!(value||value==='');if(value===this.noFontFit){return;}
|
||
this._noFontFit=value;if(value){this.setAttr('no-font-fit','');}
|
||
else{this.removeAttr('no-font-fit');}}},ignoreDir:{get:function(){return this._ignoreDir||false;},set:function(value){debug('set ignore-dir',value);value=!!(value||value==='');if(value===this.ignoreDir){return;}
|
||
this._ignoreDir=value;this.dirObserver=!value;if(value){this.setAttr('ignore-dir','');}
|
||
else{this.removeAttr('ignore-dir');}}}},template:`<div class="inner">
|
||
<button class="action-button">
|
||
<content select="[l10n-action]"></content>
|
||
</button>
|
||
<content></content>
|
||
</div>
|
||
|
||
<style>
|
||
|
||
:host {
|
||
display: block;
|
||
-moz-user-select: none;
|
||
|
||
--gaia-header-button-color:
|
||
var(--header-button-color,
|
||
var(--header-color,
|
||
var(--link-color,
|
||
inherit)));
|
||
}
|
||
|
||
/**
|
||
* [hidden]
|
||
*/
|
||
|
||
:host[hidden] {
|
||
display: none;
|
||
}
|
||
|
||
/** Reset
|
||
---------------------------------------------------------*/
|
||
|
||
::-moz-focus-inner { border: 0; }
|
||
|
||
/** Inner
|
||
---------------------------------------------------------*/
|
||
|
||
.inner {
|
||
display: flex;
|
||
min-height: 50px;
|
||
-moz-user-select: none;
|
||
|
||
background:
|
||
var(--header-background,
|
||
var(--background,
|
||
#fff));
|
||
}
|
||
|
||
/** Action Button
|
||
---------------------------------------------------------*/
|
||
|
||
/**
|
||
* 1. Hidden by default
|
||
*/
|
||
|
||
.action-button {
|
||
position: relative;
|
||
|
||
display: none; /* 1 */
|
||
width: 50px;
|
||
font-size: 30px;
|
||
margin: 0;
|
||
padding: 0;
|
||
border: 0;
|
||
outline: 0;
|
||
|
||
align-items: center;
|
||
background: none;
|
||
cursor: pointer;
|
||
transition: opacity 200ms 280ms;
|
||
color:
|
||
var(--header-action-button-color,
|
||
var(--header-icon-color,
|
||
var(--gaia-header-button-color)));
|
||
}
|
||
|
||
/**
|
||
* [action=back]
|
||
* [action=menu]
|
||
* [action=close]
|
||
*
|
||
* 1. For icon vertical-alignment
|
||
*/
|
||
|
||
[action=back] .action-button,
|
||
[action=menu] .action-button,
|
||
[action=close] .action-button {
|
||
display: flex; /* 1 */
|
||
}
|
||
|
||
/**
|
||
* :active
|
||
*/
|
||
|
||
.action-button:active {
|
||
transition: none;
|
||
opacity: 0.2;
|
||
}
|
||
|
||
/** Action Button Icon
|
||
---------------------------------------------------------*/
|
||
|
||
.action-button:before {
|
||
font-family: 'gaia-icons';
|
||
font-style: normal;
|
||
text-rendering: optimizeLegibility;
|
||
font-weight: 500;
|
||
}
|
||
|
||
[action=close] .action-button:before { content: 'close' }
|
||
[action=menu] .action-button:before { content: 'menu' }
|
||
|
||
[action=back]:-moz-dir(ltr) .action-button:before { content: 'left' }
|
||
[action=back]:-moz-dir(rtl) .action-button:before { content: 'right' }
|
||
|
||
/** Action Button Icon
|
||
---------------------------------------------------------*/
|
||
|
||
/**
|
||
* 1. To enable vertical alignment.
|
||
*/
|
||
|
||
.action-button:before {
|
||
display: block;
|
||
}
|
||
|
||
/** Action Button Text
|
||
---------------------------------------------------------*/
|
||
|
||
/**
|
||
* To provide custom localized content for
|
||
* the action-button, we allow the user
|
||
* to provide an element with the class
|
||
* .l10n-action. This node is then
|
||
* pulled inside the real action-button.
|
||
*
|
||
* Example:
|
||
*
|
||
* <gaia-header action="back">
|
||
* <span l10n-action aria-label="Back">Localized text</span>
|
||
* <h1>title</h1>
|
||
* </gaia-header>
|
||
*/
|
||
|
||
::content [l10n-action] {
|
||
position: absolute;
|
||
left: 0;
|
||
top: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
font-size: 0;
|
||
}
|
||
|
||
/** Title
|
||
---------------------------------------------------------*/
|
||
|
||
/**
|
||
* 1. Vertically center text. We can't use flexbox
|
||
* here as it breaks text-overflow ellipsis
|
||
* without an inner div.
|
||
*/
|
||
|
||
::content h1 {
|
||
flex: 1;
|
||
margin: 0;
|
||
padding: 0;
|
||
overflow: hidden;
|
||
|
||
white-space: nowrap;
|
||
text-overflow: ellipsis;
|
||
text-align: center;
|
||
line-height: 50px; /* 1 */
|
||
font-weight: 300;
|
||
font-style: italic;
|
||
font-size: 24px;
|
||
|
||
color:
|
||
var(--header-title-color,
|
||
var(--header-color,
|
||
var(--title-color,
|
||
var(--text-color,
|
||
inherit))));
|
||
}
|
||
|
||
/**
|
||
* [ignore-dir]
|
||
*
|
||
* When the <gaia-header> component has an [ignore-dir] attribute, header
|
||
* direction is forced to LTR but we still want the <h1> text to be reversed
|
||
* so that strings like '1 selected' become 'selected 1'.
|
||
*
|
||
* When we're happy for <gaia-header> to be fully RTL responsive we won't need
|
||
* these rules anymore, but this depends on all Gaia apps being ready.
|
||
*
|
||
* This should be safe to remove when bug 1179459 lands.
|
||
*/
|
||
|
||
:host[ignore-dir] {
|
||
direction: ltr;
|
||
}
|
||
|
||
:host[ignore-dir]:-moz-dir(rtl) h1 {
|
||
direction: rtl;
|
||
}
|
||
|
||
/** Buttons
|
||
---------------------------------------------------------*/
|
||
|
||
::content a,
|
||
::content button {
|
||
position: relative;
|
||
z-index: 1;
|
||
box-sizing: border-box;
|
||
display: flex;
|
||
width: auto;
|
||
height: auto;
|
||
min-width: 50px;
|
||
margin: 0;
|
||
padding: 0 10px;
|
||
outline: 0;
|
||
border: 0;
|
||
|
||
font-size: 14px;
|
||
line-height: 1;
|
||
align-items: center;
|
||
justify-content: center;
|
||
text-decoration: none;
|
||
text-align: center;
|
||
background: none;
|
||
border-radius: 0;
|
||
font-style: italic;
|
||
cursor: pointer;
|
||
transition: opacity 200ms 280ms;
|
||
color: var(--gaia-header-button-color);
|
||
}
|
||
|
||
/**
|
||
* :active
|
||
*/
|
||
|
||
::content a:active,
|
||
::content button:active {
|
||
transition: none;
|
||
opacity: 0.2;
|
||
}
|
||
|
||
/**
|
||
* [hidden]
|
||
*/
|
||
|
||
::content a[hidden],
|
||
::content button[hidden] {
|
||
display: none;
|
||
}
|
||
|
||
/**
|
||
* [disabled]
|
||
*/
|
||
|
||
::content a[disabled],
|
||
::content button[disabled] {
|
||
pointer-events: none;
|
||
color: var(--header-disabled-button-color);
|
||
}
|
||
|
||
/** Icon Buttons
|
||
---------------------------------------------------------*/
|
||
|
||
/**
|
||
* Icons are a different color to text
|
||
*/
|
||
|
||
::content .icon,
|
||
::content [data-icon] {
|
||
color:
|
||
var(--header-icon-color,
|
||
var(--gaia-header-button-color));
|
||
}
|
||
|
||
/**
|
||
* If users want their action button
|
||
* to be in the component's light-dom
|
||
* they can add an .action class
|
||
* to make it look like the
|
||
* shadow action button.
|
||
*/
|
||
|
||
::content .action {
|
||
color:
|
||
var(--header-action-button-color,
|
||
var(--header-icon-color,
|
||
var(--gaia-header-button-color)));
|
||
}
|
||
|
||
/**
|
||
* [data-icon]:empty
|
||
*
|
||
* Icon buttons with no textContent,
|
||
* should always be 50px.
|
||
*
|
||
* This is to prevent buttons being
|
||
* larger than they should be before
|
||
* icon-font has loaded.
|
||
*/
|
||
|
||
::content [data-icon]:empty {
|
||
width: 50px;
|
||
}
|
||
|
||
</style>`,nextTick:nextTick});function contributesToLayout(el){return el.localName!=='style'&&!el.hasAttribute('l10n-action');}
|
||
function setStyleId(el,id){el._styleId=id;}
|
||
function getStyleId(el){return el._styleId;}
|
||
function nextTick(fn){var cleared;Promise.resolve().then(()=>{if(!cleared){fn();}});return{clear:function(){cleared=true;}};}});})(typeof define=='function'&&define.amd?define:(function(n,w){'use strict';return typeof module=='object'?function(c){c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-header',this));},{"font-fit":1,"gaia-component":2,"gaia-icons":3}]},{},[4])(4)});;'use strict';window.GaiaMenu=(function(win){var proto=Object.create(HTMLElement.prototype);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>`;return document.registerElement('gaia-menu',{prototype:proto});})(window);;'use strict';var metadataQueue=[];var processingQueue=false;var stopParsingMetadataCallback=null;var noMoreWorkCallback=null;function addToMetadataQueue(fileinfo){metadataQueue.push(fileinfo);startParsingMetadata();}
|
||
function startParsingMetadata(){if(processingQueue){return;}
|
||
if(metadataQueue.length===0){if(noMoreWorkCallback){noMoreWorkCallback();noMoreWorkCallback=null;}
|
||
return;}
|
||
if(document.hidden||playerShowing){return;}
|
||
if(videodb.state!==MediaDB.READY){return;}
|
||
processingQueue=true;showThrobber();processFirstQueuedItem();}
|
||
function stopParsingMetadata(callback){if(!processingQueue){if(callback){callback();}
|
||
return;}
|
||
stopParsingMetadataCallback=callback||true;}
|
||
function processFirstQueuedItem(){if(stopParsingMetadataCallback){var callback=stopParsingMetadataCallback;stopParsingMetadataCallback=null;processingQueue=false;hideThrobber();if(callback!==true){callback();}
|
||
return;}
|
||
if(metadataQueue.length===0){processingQueue=false;hideThrobber();updateDialog();if(typeof(noMoreWorkCallback)==='function'){noMoreWorkCallback();}
|
||
return;}
|
||
var fileinfo=metadataQueue.shift();videodb.getFile(fileinfo.name,function(file){getMetadata(file,function(metadata){fileinfo.metadata=metadata;videodb.updateMetadata(fileinfo.name,metadata,function(){if(metadata.isVideo){videodb.getFileInfo(fileinfo.name,function(dbfileinfo){addVideo(dbfileinfo);});}});setTimeout(processFirstQueuedItem);});},function(err){console.error('getFile error: ',fileinfo.name,err);processFirstQueuedItem();});}
|
||
function getMetadata(videofile,callback){var offscreenVideo=document.createElement('video');var metadata={};if(!offscreenVideo.canPlayType(videofile.type)){metadata.isVideo=false;callback(metadata);return;}
|
||
var url=URL.createObjectURL(videofile);offscreenVideo.preload='metadata';offscreenVideo.src=url;const METADATA_TIMEOUT=3000;var timeoutId=setTimeout(function(){console.error('No loadedmetadata or error events seen yet.','Assuming video file is corrupt:',videofile.name);offscreenVideo.onerror();},METADATA_TIMEOUT);offscreenVideo.onerror=function(e){console.error('Can\'t play video',videofile.name,e);metadata.isVideo=false;clearTimeout(timeoutId);unload();callback(metadata);};offscreenVideo.onloadedmetadata=function(){clearTimeout(timeoutId);if(!offscreenVideo.videoWidth){metadata.isVideo=false;unload();callback(metadata);return;}
|
||
metadata.isVideo=true;metadata.title=readFromMetadata('title')||fileNameToVideoName(videofile.name);metadata.duration=offscreenVideo.duration;metadata.width=offscreenVideo.videoWidth;metadata.height=offscreenVideo.videoHeight;if(/.3gp$/.test(videofile.name)){getVideoRotation(videofile,function(rotation){if(typeof rotation==='number'){metadata.rotation=rotation;}
|
||
else if(typeof rotation==='string'){console.warn('Video rotation:',rotation);}
|
||
createThumbnail();});}else{metadata.rotation=0;createThumbnail();}};function readFromMetadata(lowerCaseKey){var tags=offscreenVideo.mozGetMetadata();for(var key in tags){if(key.toLowerCase()===lowerCaseKey){return tags[key];}}
|
||
return;}
|
||
function createThumbnail(){var t=Math.min(5,offscreenVideo.duration/10);offscreenVideo.fastSeek(t);var failed=false;var timeout=setTimeout(fail,10000);offscreenVideo.onerror=fail;function fail(){console.warn('Seek failed while creating thumbnail for',videofile.name,'. Ignoring corrupt file.');failed=true;clearTimeout(timeout);offscreenVideo.onerror=null;metadata.isVideo=false;unload();callback(metadata);}
|
||
offscreenVideo.onseeked=function(){if(failed){return;}
|
||
clearTimeout(timeout);captureFrame(offscreenVideo,metadata,function(poster){metadata.poster=poster;unload();callback(metadata);});};}
|
||
function unload(){URL.revokeObjectURL(offscreenVideo.src);offscreenVideo.removeAttribute('src');offscreenVideo.load();}
|
||
function fileNameToVideoName(filename){filename=filename.split('/').pop().replace(/\.(webm|ogv|ogg|mp4|3gp)$/,'').replace(/[_\.]/g,' ');return filename.charAt(0).toUpperCase()+filename.slice(1);}}
|
||
function captureFrame(player,metadata,callback){try{var canvas=document.createElement('canvas');canvas.width=THUMBNAIL_WIDTH;canvas.height=THUMBNAIL_HEIGHT;var ctx=canvas.getContext('2d',{willReadFrequently:true});var vw=player.videoWidth,vh=player.videoHeight;var tw,th;switch(metadata.rotation){case 90:ctx.translate(THUMBNAIL_WIDTH,0);ctx.rotate(Math.PI/2);tw=THUMBNAIL_HEIGHT;th=THUMBNAIL_WIDTH;break;case 180:ctx.translate(THUMBNAIL_WIDTH,THUMBNAIL_HEIGHT);ctx.rotate(Math.PI);tw=THUMBNAIL_WIDTH;th=THUMBNAIL_HEIGHT;break;case 270:ctx.translate(0,THUMBNAIL_HEIGHT);ctx.rotate(-Math.PI/2);tw=THUMBNAIL_HEIGHT;th=THUMBNAIL_WIDTH;break;default:tw=THUMBNAIL_WIDTH;th=THUMBNAIL_HEIGHT;break;}
|
||
var scale=Math.min(tw/vw,th/vh),w=scale*vw,h=scale*vh,x=(tw-w)/2/scale,y=(th-h)/2/scale;ctx.scale(scale,scale);ctx.drawImage(player,x,y);canvas.toBlob(done,'image/jpeg');}
|
||
catch(e){console.error('Exception in captureFrame:',e,e.stack);done(null);}
|
||
function done(blob){canvas.width=0;ctx=canvas=null;callback(blob);}};'use strict';function initDB(){videodb=new MediaDB('videos',null,{excludeFilter:/DCIM\/\d{3}MZLLA\/\.VID_\d{4}\.(?:3gp|mp4|webm)$/});videodb.onupgrading=function(evt){storageState=MediaDB.UPGRADING;updateDialog();};videodb.onunavailable=function(event){storageState=event.detail;if(playerShowing){hidePlayer(true);}
|
||
updateDialog();};videodb.oncardremoved=function(){if(playerShowing){hidePlayer(true);}};videodb.onscanend=function(){if(!firstScanEnded){firstScanEnded=true;window.performance.mark('fullyLoaded');}
|
||
updateDialog();updateLoadingSpinner();};videodb.oncreated=function(event){event.detail.forEach(videoCreated);};videodb.ondeleted=function(event){event.detail.forEach(videoDeleted);};videodb.onenumerable=function(){storageState=false;updateDialog();enumerateDB();};videodb.onready=function(){storageState=false;updateDialog();startParsingMetadata();};}
|
||
var enumerated=false;function enumerateDB(){if(enumerated){return;}
|
||
enumerated=true;var firstBatchDisplayed=false;var batch=[];var batchSize=4;videodb.enumerate('date',null,'prev',function(videoinfo){if(videoinfo===null){flush();return;}
|
||
var isVideo=videoinfo.metadata.isVideo;if(isVideo===false){return;}
|
||
if(isVideo===undefined){addToMetadataQueue(videoinfo);return;}
|
||
if(isVideo===true){batch.push(videoinfo);if(batch.length>=batchSize){flush();batchSize*=2;}}});function flush(){batch.forEach(addVideo);batch.length=0;if(!firstBatchDisplayed){firstBatchDisplayed=true;window.performance.mark('visuallyLoaded');window.performance.mark('contentInteractive');setTimeout(function(){var headers=document.querySelectorAll('gaia-header');for(var i=0;i<headers.length;++i){headers[i].removeAttribute('no-font-fit');}});}}}
|
||
function addVideo(videodata){if(!videodata||!videodata.metadata.isVideo){return;}
|
||
var view=thumbnailList.addItem(videodata);view.addTapListener(thumbnailClickHandler);view.updateTitleText();if(thumbnailList.count===1){updateDialog();}}
|
||
function videoCreated(videoinfo){addToMetadataQueue(videoinfo);}
|
||
function videoDeleted(filename){if(currentVideo&&filename===currentVideo.name){resetCurrentVideo();}
|
||
thumbnailList.removeItem(filename);if(thumbnailList.count===0){updateDialog();hideSelectView();}};'use strict';function ThumbnailList(groupClass,container){if(!groupClass||!container){throw new Error('group class or container cannot be null or undefined');}
|
||
this.thumbnailMap={};this.groupMap={};this.itemGroups=[];this.count=0;this.groupClass=groupClass;this.container=container;document.addEventListener('DOMRetranslated',this.localize.bind(this));}
|
||
ThumbnailList.prototype.addItem=function(item){if(!item){return null;}
|
||
if(this.thumbnailMap[item.name]){return this.thumbnailMap[item.name];}
|
||
var _this=this;function createItemGroup(item,before){var group=new _this.groupClass(item);_this.container.insertBefore(group.htmlNode,before?before.htmlNode:null);return group;}
|
||
function getItemGroup(item){var groupID=_this.groupClass.getGroupID(item);var i;for(i=0;i<_this.itemGroups.length;i++){if(_this.itemGroups[i].groupID===groupID){return _this.itemGroups[i];}else if(_this.groupClass.compareGroupID(_this.itemGroups[i].groupID,groupID)<0){break;}}
|
||
var createdGroup=createItemGroup(item,_this.itemGroups[i]);_this.itemGroups.splice(i,0,createdGroup);return createdGroup;}
|
||
var group=getItemGroup(item);var thumbnail=group.addItem(item);this.groupMap[item.name]=group;this.thumbnailMap[item.name]=thumbnail;this.count++;return thumbnail;};ThumbnailList.prototype.removeItem=function(filename){if(!this.thumbnailMap[filename]){return;}
|
||
var group=this.groupMap[filename];group.removeItem(this.thumbnailMap[filename]);if(!group.getCount()){this.container.removeChild(group.htmlNode);this.itemGroups.splice(this.itemGroups.indexOf(group),1);}
|
||
this.count--;delete this.groupMap[filename];delete this.thumbnailMap[filename];};ThumbnailList.prototype.reset=function(){for(var name in this.thumbnailMap){this.groupMap[name].removeItem(this.thumbnailMap[name]);}
|
||
this.container.innerHTML='';this.thumbnailMap={};this.itemGroups=[];this.groupMap={};this.count=0;};ThumbnailList.prototype.isPickMode=function(){return this.container.classList.contains('pick');};ThumbnailList.prototype.setPickMode=function(pick){if(pick){this.container.classList.add('pick');}else{this.container.classList.remove('pick');}};ThumbnailList.prototype.isSelectMode=function(){return this.container.classList.contains('select');};ThumbnailList.prototype.setSelectMode=function(select){if(select){this.container.classList.add('select');}else{this.container.classList.remove('select');}};ThumbnailList.prototype.updateAllThumbnailTitles=function(){var self=this;if(this.pendingTitleTextUpdate&&this.pendingTitleTextUpdate.length){this.pendingTitleTextUpdate.length=0;}
|
||
var thumbnailKeys=Object.keys(this.thumbnailMap);this.pendingTitleTextUpdate=thumbnailKeys;setTimeout(updateNextThumbnailBatch);function updateNextThumbnailBatch(){for(var i=0;i<10;i++){if(thumbnailKeys.length===0){return;}
|
||
var nextKey=thumbnailKeys.shift();self.thumbnailMap[nextKey].updateTitleText();}
|
||
setTimeout(updateNextThumbnailBatch);}};ThumbnailList.prototype.findNextThumbnail=function(filename){var currentGroup=this.groupMap[filename];if(!currentGroup){return this.itemGroups.length?this.itemGroups[0].thumbnails[0]:null;}
|
||
var currentThumbnail=this.thumbnailMap[filename];var idx;if(currentGroup.thumbnails.length===1){idx=this.itemGroups.indexOf(currentGroup);if(idx===0){if(this.itemGroups.length>1){currentThumbnail=this.itemGroups[1].thumbnails[0];}else{currentThumbnail=null;}}else{var thumbnails=this.itemGroups[idx-1].thumbnails;currentThumbnail=thumbnails[thumbnails.length-1];}}else{idx=currentGroup.thumbnails.indexOf(currentThumbnail);if(idx===0){currentThumbnail=currentGroup.thumbnails[1];}else{currentThumbnail=currentGroup.thumbnails[idx-1];}}
|
||
return currentThumbnail;};ThumbnailList.prototype.localize=function(){this.itemGroups.forEach(function(group){group.localize();});};;'use strict';function ThumbnailDateGroup(item){if(!item){throw new Error('item should not be null or undefined.');}
|
||
this.thumbnails=[];this.groupID=ThumbnailDateGroup.getGroupID(item);this.date=item.date;var wrappedHtmlText=ThumbnailDateGroup.view();var dummyDiv=document.createElement('DIV');dummyDiv.innerHTML=Sanitizer.unwrapSafeHTML(wrappedHtmlText);var domNode=dummyDiv.firstElementChild;if(!domNode){throw new Error('the template is empty');}
|
||
this.htmlNode=domNode;this.container=domNode.querySelector('.thumbnail-group-container');this.header=domNode.querySelector('.thumbnail-group-header');this.localize();}
|
||
ThumbnailDateGroup.view=function(){return Sanitizer.createSafeHTML`<li role="presentation">
|
||
<div class="thumbnail-group-header" role="heading"
|
||
aria-level="1"></div>
|
||
<ul class="thumbnail-group-container" role="listbox"
|
||
data-l10n-id="videos-list" aria-multiselectable="true"></ul>
|
||
</li>`;};ThumbnailDateGroup.getGroupID=function(item){var dateObj=new Date(item.date);var month=dateObj.getMonth()+1;return'group_'+dateObj.getFullYear()+'-'+
|
||
(month<10?'0'+month:month);};ThumbnailDateGroup.compareGroupID=function(id1,id2){return id1>id2?1:(id1<id2?-1:0);};ThumbnailDateGroup.prototype.addItem=function(item){if(!item){return;}
|
||
var _this=this;function getInsertPosition(thumbnail){if(_this.thumbnails.length===0||thumbnail.data.date>_this.thumbnails[0].data.date){return 0;}
|
||
else if(thumbnail.data.date<_this.thumbnails[_this.thumbnails.length-1].data.date){return _this.thumbnails.length;}
|
||
else{return MediaUtils.binarySearch(_this.thumbnails,thumbnail,function(a,b){return b.data.date-a.data.date;});}}
|
||
var thumbnail=new ThumbnailItem(item);var insertPosition=getInsertPosition(thumbnail);this.container.insertBefore(thumbnail.htmlNode,this.container.children[insertPosition]);this.thumbnails.splice(insertPosition,0,thumbnail);return thumbnail;};ThumbnailDateGroup.prototype.getCount=function(){return this.thumbnails.length;};ThumbnailDateGroup.prototype.removeItem=function(thumbnail){var idx=this.thumbnails.indexOf(thumbnail);if(idx<0){return;}
|
||
this.thumbnails.splice(idx,1);this.container.removeChild(thumbnail.htmlNode);};ThumbnailDateGroup.prototype.localize=function(){var date=new Date(this.date);var formatter=IntlHelper.get('date-group');this.header.textContent=formatter.format(date);this.thumbnails.forEach(function(thumbnail){thumbnail.localize();});};;'use strict';function ThumbnailItem(videoData){if(!videoData){throw new Error('videoData should not be null or undefined.');}
|
||
this.posterNode=null;this.unwatchedNode=null;this.detailNode=null;this.titleNode=null;this.htmlNode=null;this.tapListeners=[];this.data=videoData;var _this=this;render();function convertToDOM(wrappedHTML){var dummyDiv=document.createElement('div');dummyDiv.innerHTML=Sanitizer.unwrapSafeHTML(wrappedHTML);var domNode=dummyDiv.firstElementChild;if(!domNode){throw new Error('the template does not contain any element');}
|
||
_this.htmlNode=domNode;_this.posterNode=domNode.querySelector('.img');_this.detailNode=domNode.querySelector('.details');_this.titleNode=domNode.querySelector('.title');_this.unwatchedNode=domNode.querySelector('.unwatched');_this.sizeNode=domNode.querySelector('.size-text');}
|
||
function render(){var duration='';if(isFinite(_this.data.metadata.duration)){duration=MediaUtils.formatDuration(_this.data.metadata.duration);}
|
||
var videoType='';if(_this.data.type){var pos=_this.data.type.indexOf('/');videoType=(pos>-1?_this.data.type.slice(pos+1):_this.data.type);}
|
||
var wrappedHtmlText=ThumbnailItem.view({'title':_this.data.metadata.title,'durationText':duration,'typeText':videoType});convertToDOM(wrappedHtmlText);_this.updatePoster(_this.data.metadata.bookmark||_this.data.metadata.poster);_this.setWatched(_this.data.metadata.watched);if(_this.detailNode){_this.detailNode.dataset.title=_this.data.metadata.title;}
|
||
_this.htmlNode.addEventListener('click',dispatchClick);_this.localize();}
|
||
function dispatchClick(){_this.tapListeners.forEach(function(listener){if(listener.handleEvent){listener.handleEvent(_this.data);}else if((typeof listener)==='function'){listener(_this.data);}});}}
|
||
ThumbnailItem.titleMaxLines=2;ThumbnailItem.view=function({title,durationText,typeText}){return Sanitizer.createSafeHTML`<li class="thumbnail" role="option">
|
||
<div class="inner">
|
||
<div class="unwatched"></div>
|
||
<img class="img" role="presentation"></img>
|
||
<div class="details">
|
||
<span class="title">${title}</span>
|
||
<span class="duration-text after line-break">${durationText}</span>
|
||
<span class="size-type-group">
|
||
<span class="size-text after"></span>
|
||
<span class="type-text after">${typeText}</span>
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</li>`;};ThumbnailItem.prototype.addTapListener=function(listener){if(!listener){return;}
|
||
this.tapListeners[this.tapListeners.length]=listener;};ThumbnailItem.prototype.removeTapListener=function(listener){if(!listener){return;}
|
||
var idx=this.tapListeners.indexOf(listener);if(idx>-1){this.tapListeners.splice(idx,1);}};ThumbnailItem.prototype.setWatched=function(watched){if(!this.unwatchedNode){return;}
|
||
this.unwatchedNode.hidden=watched;};ThumbnailItem.prototype.updatePoster=function(imageblob){if(!this.posterNode){return;}
|
||
if(this.posterNode.dataset.uri){URL.revokeObjectURL(this.posterNode.dataset.uri);}
|
||
if(imageblob){this.posterNode.classList.remove('default');var imageUri=URL.createObjectURL(imageblob);this.posterNode.dataset.uri=imageUri;this.posterNode.src=imageUri;}else{this.posterNode.classList.add('default');this.posterNode.dataset.uri='';this.posterNode.src='style/images/default_thumbnail.png';}};ThumbnailItem.prototype.updateTitleText=function(){this.titleNode.textContent=VideoUtils.getTruncated(this.data.metadata.title,{node:this.titleNode,maxLine:ThumbnailItem.titleMaxLines});};ThumbnailItem.prototype.localize=function(){if(this.sizeNode&&isFinite(this.data.size)){MediaUtils.getLocalizedSizeTokens(this.data.size).then((args)=>{document.l10n.setAttributes(this.sizeNode,'fileSize',args);});}};;'use strict';var VideoUtils={fitContainer:function(container,player,videoRotation){var containerWidth=container.clientWidth;var containerHeight=container.clientHeight;if(!player.videoWidth||!player.videoHeight){return;}
|
||
var width,height;var rotation=videoRotation||0;switch(rotation){case 0:case 180:width=player.videoWidth;height=player.videoHeight;break;case 90:case 270:width=player.videoHeight;height=player.videoWidth;}
|
||
var xscale=containerWidth/width;var yscale=containerHeight/height;var scale=Math.min(xscale,yscale);width*=scale;height*=scale;var left=((containerWidth-width)/2);var top=((containerHeight-height)/2);var transform;switch(rotation){case 0:transform='translate('+left.toFixed(4)+'px,'+
|
||
top.toFixed(4)+'px)';break;case 90:transform='translate('+(left+width).toFixed(4)+'px,'+
|
||
top.toFixed(4)+'px) '+'rotate(90deg)';break;case 180:transform='translate('+(left+width).toFixed(4)+'px,'+
|
||
(top+height).toFixed(4)+'px) '+'rotate(180deg)';break;case 270:transform='translate('+left.toFixed(4)+'px,'+
|
||
(top+height).toFixed(4)+'px) '+'rotate(270deg)';break;}
|
||
transform+=' scale('+scale.toFixed(4)+')';player.style.transform=transform;},getTruncated:function(oldName,options){var maxLine=options.maxLine||2;var node=options.node;var ellipsisCharacter=options.ellipsisCharacter||'...';if(node===null){return oldName;}
|
||
var realVisibility=node.style.visibility;var realWordBreak=node.style.wordBreak;node.style.visibility='hidden';node.style.wordBreak='break-all';node.textContent='.';var baseHeight=node.clientHeight;var computedStyle=window.getComputedStyle(node,null);var paddingTop=parseInt(computedStyle.getPropertyValue('padding-top'),10);var paddingBottom=parseInt(computedStyle.getPropertyValue('padding-bottom'),10);var padding=paddingTop+paddingBottom;var lineHeight=baseHeight-padding;node.textContent=oldName;var originalTitleHeight=node.clientHeight-padding;var linesForOriginalTitle=(originalTitleHeight/lineHeight);if(linesForOriginalTitle<=maxLine){node.style.visibility=realVisibility;node.style.wordBreak=realWordBreak;return oldName;}
|
||
function titleTooLong(pos){node.textContent=oldName.slice(0,pos)+ellipsisCharacter;var tempTitleHeight=node.clientHeight-padding;return(tempTitleHeight/lineHeight)>maxLine;}
|
||
var low=0;var high=oldName.length-1;var mid;var ellipsisIndex=0;do{mid=Math.floor((low+high)/2);if(titleTooLong(mid)){high=mid-1;}
|
||
else{ellipsisIndex=mid;low=mid+1;}}
|
||
while(low<=high);var newName=oldName.slice(0,ellipsisIndex)+ellipsisCharacter;node.style.visibility=realVisibility;node.style.wordBreak=realWordBreak;return newName;}};;'use strict';var ForwardRewindController=(function(){var isLongPressing=false;var intervalId=null;var forwardButton;var backwardButton;var videoToolbar;var player;var seekHelper;function init(video,forward,backward,seeker){forwardButton=forward;backwardButton=backward;player=video;seekHelper=seeker;videoToolbar=forward.parentElement;videoToolbar.addEventListener('click',handleButtonClick);videoToolbar.addEventListener('contextmenu',handlePlayerLongPress);videoToolbar.addEventListener('touchend',stopFastSeeking);}
|
||
function uninit(video,forward,backward){videoToolbar.removeEventListener('click',handleButtonClick);videoToolbar.removeEventListener('contextmenu',handlePlayerLongPress);videoToolbar.removeEventListener('touchend',stopFastSeeking);forwardButton=null;backwardButton=null;player=null;}
|
||
function handleButtonClick(event){if(event.target===forwardButton){startFastSeeking(1);}else if(event.target===backwardButton){startFastSeeking(-1);}else{return;}}
|
||
function handlePlayerLongPress(event){if(event.target===forwardButton){isLongPressing=true;startFastSeeking(1);}else if(event.target===backwardButton){isLongPressing=true;startFastSeeking(-1);}else{return;}}
|
||
function startFastSeeking(direction){var offset=direction*10;if(isLongPressing){intervalId=window.setInterval(function(){seekVideo(player.currentTime+offset);},1000);}else{seekVideo(player.currentTime+offset);}}
|
||
function stopFastSeeking(){if(intervalId){window.clearInterval(intervalId);intervalId=null;isLongPressing=false;}}
|
||
function seekVideo(seekTime){if(seekTime>=player.duration||seekTime<0){if(isLongPressing){stopFastSeeking();}
|
||
if(seekTime>=player.duration){seekTime=player.duration;pause();}
|
||
else{seekTime=0;}}
|
||
if(seekHelper){seekHelper.seekTo(seekTime);}
|
||
else{player.fastSeek(seekTime);}}
|
||
return{init:init,uninit:uninit,stopFastSeeking:stopFastSeeking};}());;(function(exports){'use strict';exports.VideoLoadingChecker=VideoLoadingChecker;function VideoLoadingChecker(player,overlay,overlayTitle,overlayText){this.player=player;this.overlay=overlay;this.overlayTitle=overlayTitle;this.overlayText=overlayText;}
|
||
VideoLoadingChecker.prototype={ensureVideoLoads:function vpc_ensureVideoLoads(callback){var self=this;var videoLoadedTimeoutId=setTimeout(showOverlay.bind(null,this),1500);this.player.addEventListener('loadedmetadata',handleLoadedMetadata);function handleLoadedMetadata(){clearTimeout(videoLoadedTimeoutId);videoLoadedTimeoutId=null;self.player.removeEventListener('loadedmetadata',handleLoadedMetadata);hideOverlay(self);if(callback){callback();}}},ensureVideoPlays:function(){this.playingTimeout=setTimeout(showOverlay.bind(null,this),1500);this.playingListener=this.cancelEnsureVideoPlays.bind(this);this.player.addEventListener('timeupdate',this.playingListener);},cancelEnsureVideoPlays:function(){hideOverlay(this);if(this.playingTimeout){clearTimeout(this.playingTimeout);this.playingTimeout=null;}
|
||
if(this.playingListener){this.player.removeEventListener('timeupdate',this.playingListener);this.playingListener=null;}}};function showOverlay(checker){checker.overlayTitle.setAttribute('data-l10n-id','video-hardware-in-use-title');checker.overlayText.setAttribute('data-l10n-id','video-hardware-in-use-text');checker.overlay.classList.remove('hidden');document.body.classList.add('in-use-overlay');}
|
||
function hideOverlay(checker){document.body.classList.remove('in-use-overlay');checker.overlay.classList.add('hidden');}}(window));;(function(exports){'use strict';function Seeker(player){this.player=player;this.seekStartedAt=null;this.currentSeekTime=null;this.nextSeekTime=null;this.player.addEventListener('seeked',this);}
|
||
Seeker.SEEK_INTERVAL=200;Seeker.SEEK_DISTANCE=10;Seeker.prototype.seekTo=function(time){if(this.currentSeekTime===time){return;}
|
||
var now=performance.now();if(this.currentSeekTime===null||time===0||Math.abs(this.currentSeekTime-time)>Seeker.SEEK_DISTANCE||now-this.seekStartedAt>Seeker.SEEK_INTERVAL)
|
||
{this.player.fastSeek(time);this.seekStartedAt=now;this.currentSeekTime=time;this.nextSeekTime=null;}
|
||
else{this.nextSeekTime=time;}};Seeker.prototype.handleEvent=function(){this.currentSeekTime=null;this.seekStartedAt=null;if(this.nextSeekTime!==null){this.seekTo(this.nextSeekTime);}};exports.Seeker=Seeker;}(window));;(function(exports){'use strict';function Captions(player){this.player=player;}
|
||
Captions.prototype.remove=function(){for(var track of this.player.querySelectorAll('track')){if(track.src&&track.src.startsWith('blob:')){URL.revokeObjectURL(track.src);}
|
||
track.remove();}};Captions.prototype.findAndDisplay=function(filepath){if(!filepath){return;}
|
||
var basename=filepath.substring(0,filepath.lastIndexOf('.'));var captionsFilename=basename+'.vtt';var sdcard=navigator.getDeviceStorage('sdcard');if(!sdcard)return;var request=sdcard.get(captionsFilename);request.onsuccess=function(){var track=document.createElement('track');track.src=URL.createObjectURL(request.result);track.default=true;this.player.appendChild(track);track.track.mode='showing';}.bind(this);};exports.Captions=Captions;}(window));;'use strict';const LAYOUT_MODE={list:'layout-list',selection:'layout-selection',fullscreenPlayer:'layout-fullscreen-player'};var dom={};var ids=['thumbnail-list-title','thumbnails','thumbnails-video-button','thumbnails-select-button','thumbnails-delete-button','thumbnails-share-button','thumbnails-select-top','thumbnails-number-selected','player-view','fullscreen-button','spinner-overlay','thumbnails-single-delete-button','thumbnails-single-share-button','thumbnails-single-info-button','info-view','info-close-button','player','overlay','overlay-title','overlay-text','overlay-menu','overlay-action-button','player-header','video-container','videoBar','videoControlBar','close','play','playHead','timeSlider','elapsedTime','video-title','duration-text','elapsed-text','bufferedTime','slider-wrapper','throbber','picker-close','picker-title','picker-header','picker-done','options','options-view','seek-backward','seek-forward','in-use-overlay','in-use-overlay-title','in-use-overlay-text'];ids.forEach(function createElementRef(name){dom[toCamelCase(name)]=document.getElementById(name);});dom.player.mozAudioChannelType='content';function $(id){return document.getElementById(id);}
|
||
var seeker=new Seeker(dom.player);var captions=new Captions(dom.player);var playing=false;var playerShowing=false;var controlShowing=false;var controlFadeTimeout=null;var selectedFileNames=[];var selectedFileNamesToBlobs={};var videodb;var currentVideo;var currentVideoBlob;var firstScanEnded=false;var THUMBNAIL_WIDTH;var THUMBNAIL_HEIGHT;var HAVE_NOTHING=0;var storageState;var currentOverlay;var dragging=false;var touchStartID=null;var sliderRect;var thumbnailList;var pendingPick;var videoHardwareReleased=false;var restoreTime=null;var isPhone;var isPortrait;var currentLayoutMode;var pendingUpdateTitleText=false;var FROMCAMERA=/DCIM\/\d{3}MZLLA\/VID_\d{4}\.(?:3gp|mp4|webm)$/;var loadingChecker=new VideoLoadingChecker(dom.player,dom.inUseOverlay,dom.inUseOverlayTitle,dom.inUseOverlayText);var lastPlayTime=0;init();dom.player.addEventListener('play',function(){lastPlayTime=window.performance.now();});dom.player.addEventListener('mozinterruptbegin',function(){if((window.performance.now()-lastPlayTime)>50){pause();lastPlayTime=0;}});document.addEventListener('visibilitychange',function visibilityChange(){if(document.hidden){stopParsingMetadata();if(playing){pause();}}
|
||
else{if(playerShowing){if(videoHardwareReleased){restoreVideo();}
|
||
setControlsVisibility(true);}else{startParsingMetadata();}}});var acm=navigator.mozAudioChannelManager;if(acm){acm.addEventListener('headphoneschange',function onheadphoneschange(){if(!acm.headphones&&playing){setVideoPlaying(false);}});}
|
||
navigator.mozSetMessageHandler('activity',handleActivityEvents);function init(){window.performance.mark('navigationLoaded');IntlHelper.define('date-group','datetime',{month:'long',year:'numeric',});thumbnailList=new ThumbnailList(ThumbnailDateGroup,dom.thumbnails);ThumbnailItem.titleMaxLines=isPhone?2:(isPortrait?4:2);initDB();addUIEventListeners();initLayout();initThumbnailSize();function addUIEventListeners(){if(!navigator.mozHasPendingMessage('activity')){initOptionsButtons();}
|
||
document.l10n.ready.then(function(){initPlayerControls();});ForwardRewindController.init(dom.player,dom.seekForward,dom.seekBackward,seeker);dom.overlayActionButton.addEventListener('click',function(){if(pendingPick){cancelPick();}else if(currentOverlay==='empty'){launchCameraApp();}});window.performance.mark('navigationInteractive');}}
|
||
function initThumbnailSize(){if(isPhone){THUMBNAIL_WIDTH=210*window.devicePixelRatio;THUMBNAIL_HEIGHT=120*window.devicePixelRatio;}else{var shortEdge=Math.min(window.innerWidth,window.innerHeight);THUMBNAIL_WIDTH=424*window.devicePixelRatio*shortEdge/800;THUMBNAIL_HEIGHT=Math.round(THUMBNAIL_WIDTH*4/7);}}
|
||
function initLayout(){ScreenLayout.watch('portrait','(orientation: portrait)');isPhone=ScreenLayout.getCurrentLayout('tiny');isPortrait=ScreenLayout.getCurrentLayout('portrait');if(isPhone||isPortrait){dom.spinnerOverlay.classList.add('hidden');setDisabled(dom.playerView,false);}else{dom.spinnerOverlay.classList.remove('hidden');setDisabled(dom.playerView,true);}
|
||
window.addEventListener('screenlayoutchange',handleScreenLayoutChange);switchLayout(LAYOUT_MODE.list);}
|
||
function initPlayerControls(){dom.sliderWrapper.addEventListener('touchstart',handleSliderTouchStart);dom.sliderWrapper.addEventListener('touchmove',handleSliderTouchMove);dom.sliderWrapper.addEventListener('touchend',handleSliderTouchEnd);dom.player.addEventListener('timeupdate',timeUpdated);dom.player.addEventListener('seeked',updateVideoControlSlider);dom.player.addEventListener('ended',playerEnded);dom.play.addEventListener('click',handlePlayButtonClick);dom.playerHeader.addEventListener('action',handleCloseButtonClick);dom.pickerDone.addEventListener('click',postPickResult);dom.options.addEventListener('click',showOptionsView);dom.videoContainer.addEventListener('click',toggleVideoControls);dom.timeSlider.addEventListener('keypress',handleSliderKeypress);}
|
||
function initOptionsButtons(){dom.thumbnailsVideoButton.addEventListener('click',launchCameraApp);dom.thumbnailsSelectButton.addEventListener('click',showSelectView);dom.thumbnailsSelectTop.addEventListener('action',hideSelectView);dom.thumbnailsDeleteButton.addEventListener('click',deleteSelectedItems);dom.thumbnailsShareButton.addEventListener('click',shareSelectedItems);dom.infoCloseButton.addEventListener('click',hideInfoView);dom.optionsView.addEventListener('gaiamenu-cancel',hideOptionsView);dom.fullscreenButton.addEventListener('click',toggleFullscreenPlayer);addEventListeners('.single-delete-button','click',deleteCurrentVideo);addEventListeners('.single-share-button','click',shareCurrentVideo);addEventListeners('.single-info-button','click',showInfoView);}
|
||
function addEventListeners(selector,type,listener){var elements=document.body.querySelectorAll(selector);for(var i=0;i<elements.length;i++){elements[i].addEventListener(type,listener);}}
|
||
function toggleFullscreenPlayer(){if(currentLayoutMode===LAYOUT_MODE.list){switchLayout(LAYOUT_MODE.fullscreenPlayer);scheduleVideoControlsAutoHiding();}else{switchLayout(LAYOUT_MODE.list);}
|
||
VideoUtils.fitContainer(dom.videoContainer,dom.player,currentVideo.metadata.rotation||0);}
|
||
function toggleVideoControls(e){if(controlFadeTimeout){clearTimeout(controlFadeTimeout);controlFadeTimeout=null;}
|
||
if(!pendingPick){e.cancelBubble=!controlShowing;setControlsVisibility(!controlShowing);}}
|
||
function handleScreenLayoutChange(){isPortrait=ScreenLayout.getCurrentLayout('portrait');if(!isPhone){if(!isPortrait&&(!firstScanEnded||processingQueue)){dom.spinnerOverlay.classList.remove('hidden');setDisabled(dom.playerView,true);}else{dom.spinnerOverlay.classList.add('hidden');setDisabled(dom.playerView,false);}
|
||
if(currentLayoutMode===LAYOUT_MODE.list){if(isPortrait){hidePlayer(true);}else{showPlayer(currentVideo,false,false,true);}}
|
||
ThumbnailItem.titleMaxLines=isPortrait?4:2;}
|
||
if(currentLayoutMode!==LAYOUT_MODE.fullscreenPlayer){if(!thumbnailList){return;}
|
||
thumbnailList.updateAllThumbnailTitles();}else{pendingUpdateTitleText=true;}
|
||
if(dom.player.readyState!==HAVE_NOTHING){VideoUtils.fitContainer(dom.videoContainer,dom.player,currentVideo.metadata.rotation||0);}}
|
||
function switchLayout(mode){var oldMode=currentLayoutMode;if(oldMode){document.body.classList.remove(currentLayoutMode);}
|
||
currentLayoutMode=mode;document.body.classList.add(currentLayoutMode);if(oldMode===LAYOUT_MODE.fullscreenPlayer&&pendingUpdateTitleText){pendingUpdateTitleText=false;thumbnailList.updateAllThumbnailTitles();}}
|
||
function handleActivityEvents(a){var activityName=a.source.name;if(activityName==='pick'){pendingPick=a;showPickView();}}
|
||
function showInfoView(){hideOptionsView();var length=isFinite(currentVideo.metadata.duration)?MediaUtils.formatDuration(currentVideo.metadata.duration):'';var type=currentVideo.type;if(type){var index=currentVideo.type.indexOf('/');type=index>-1?currentVideo.type.slice(index+1):currentVideo.type;}
|
||
var resolution=(currentVideo.metadata.width&¤tVideo.metadata.height)?currentVideo.metadata.width+'x'+
|
||
currentVideo.metadata.height:'';return MediaUtils.getLocalizedSizeTokens(currentVideo.size).then((args)=>{var data={'info-name':{raw:currentVideo.metadata.title},'info-length':{raw:length},'info-size':{id:'fileSize',args:args},'info-type':{raw:type},'info-date':{raw:MediaUtils.formatDate(currentVideo.date)},'info-resolution':{raw:resolution}};MediaUtils.populateMediaInfo(data);setNFCSharing(false);dom.infoView.classList.remove('hidden');document.body.classList.add('info-view');});}
|
||
function hideInfoView(){setNFCSharing(true);dom.infoView.classList.add('hidden');document.body.classList.remove('info-view');}
|
||
function showSelectView(){hidePlayer(true,function(){switchLayout(LAYOUT_MODE.selection);thumbnailList.setSelectMode(true);clearSelection();});}
|
||
function hideSelectView(){clearSelection();thumbnailList.setSelectMode(false);switchLayout(LAYOUT_MODE.list);if(!isPhone&&!isPortrait&¤tVideo){showPlayer(currentVideo,false,false,true);}}
|
||
function showOptionsView(){if(playing){pause();}
|
||
dom.optionsView.removeAttribute('hidden');document.body.classList.add('options-view');}
|
||
function hideOptionsView(){dom.optionsView.setAttribute('hidden',true);document.body.classList.remove('options-view');}
|
||
function setDisabled(element,disabled){element.classList.toggle('disabled',disabled);element.setAttribute('aria-disabled',disabled);}
|
||
function setSelected(element,selected){element.classList.toggle('selected',selected);element.setAttribute('aria-selected',selected);}
|
||
function clearSelection(){Array.forEach(selectedFileNames,function(name){setSelected(thumbnailList.thumbnailMap[name].htmlNode,false);});selectedFileNames=[];selectedFileNamesToBlobs={};setDisabled(dom.thumbnailsDeleteButton,true);setDisabled(dom.thumbnailsShareButton,true);document.l10n.setAttributes(dom.thumbnailsNumberSelected,'number-selected2',{n:0});}
|
||
function updateSelection(videodata){var thumbnail=thumbnailList.thumbnailMap[videodata.name];var selected=!thumbnail.htmlNode.classList.contains('selected');setSelected(thumbnail.htmlNode,selected);var filename=videodata.name;if(selected){selectedFileNames.push(filename);videodb.getFile(filename,function(blob){selectedFileNamesToBlobs[filename]=blob;});}
|
||
else{delete selectedFileNamesToBlobs[filename];var i=selectedFileNames.indexOf(filename);if(i!==-1){selectedFileNames.splice(i,1);}}
|
||
var numSelected=selectedFileNames.length;document.l10n.setAttributes(dom.thumbnailsNumberSelected,'number-selected2',{n:numSelected});var noneSelected=numSelected===0;setDisabled(dom.thumbnailsDeleteButton,noneSelected);setDisabled(dom.thumbnailsShareButton,noneSelected);}
|
||
function launchCameraApp(){var a=new MozActivity({name:'record',data:{type:'videos'}});a.onerror=function(){if(a.error.name==='NO_PROVIDER'){document.l10n.formatValue('share-noprovider').then((msg)=>{alert(msg);});}else{console.warn('share activity error:',a.error.name);}};}
|
||
function resetCurrentVideo(){if(!currentVideo){return;}
|
||
var currentThumbnail=thumbnailList.thumbnailMap[currentVideo.name];currentThumbnail.htmlNode.classList.remove('focused');var nextThumbnail=thumbnailList.findNextThumbnail(currentVideo.name);if(nextThumbnail){currentVideo=nextThumbnail.data;nextThumbnail.htmlNode.classList.add('focused');}else{currentVideo=null;}}
|
||
function deleteSelectedItems(){if(selectedFileNames.length===0){return;}
|
||
LazyLoader.load('shared/style/confirm.css',function(){document.body.classList.add('confirm-dialog');Dialogs.confirm({messageId:'delete-n-items?',messageArgs:{n:selectedFileNames.length},cancelId:'cancel',confirmId:'delete',danger:true},function(){for(var i=0;i<selectedFileNames.length;i++){deleteFile(selectedFileNames[i]);}
|
||
clearSelection();document.body.classList.remove('confirm-dialog');},function(){document.body.classList.remove('confirm-dialog');});});}
|
||
function deleteFile(filename){if(FROMCAMERA.test(filename)){var postername=filename.replace(/\.(?:3gp|mp4|webm)$/,'.jpg');navigator.getDeviceStorage('pictures').delete(postername);}
|
||
videodb.deleteFile(filename);}
|
||
function shareSelectedItems(){var blobs=selectedFileNames.map(function(name){return selectedFileNamesToBlobs[name];});share(blobs);}
|
||
function share(blobs){if(blobs.length===0){return;}
|
||
var names=[],fullpaths=[];blobs.forEach(function(blob){var name=blob.name;fullpaths.push(name);name=name.substring(name.lastIndexOf('/')+1);names.push(name);});if(playerShowing){releaseVideo();}
|
||
var a=new MozActivity({name:'share',data:{type:'video/*',number:blobs.length,blobs:blobs,filenames:names,filepaths:fullpaths}});a.onsuccess=restoreVideo;a.onerror=function(){if(a.error.name==='NO_PROVIDER'){document.l10n.formatValue('share-noprovider').then((msg)=>{alert(msg);});}else{console.warn('share activity error:',a.error.name);}
|
||
restoreVideo();};}
|
||
function updateDialog(){if(thumbnailList.count!==0&&(!storageState||playerShowing)){showOverlay(null);}else if(storageState===MediaDB.UPGRADING){showOverlay('upgrade');}else if(storageState===MediaDB.NOCARD){showOverlay('nocard');}else if(storageState===MediaDB.UNMOUNTED){showOverlay('pluggedin');}else if(firstScanEnded&&thumbnailList.count===0&&metadataQueue.length===0){showOverlay('empty');}}
|
||
function updateLoadingSpinner(){if(processingQueue){noMoreWorkCallback=updateLoadingSpinner;}else{window.performance.mark('scanEnd');dom.spinnerOverlay.classList.add('hidden');setDisabled(dom.playerView,false);if(thumbnailList.count){currentVideo=currentVideo||thumbnailList.itemGroups[0].thumbnails[0].data;if(!isPhone&&!isPortrait){showPlayer(currentVideo,false,false,true);}}}}
|
||
function thumbnailClickHandler(videodata){if(!isPhone&&!isPortrait){if(!firstScanEnded||processingQueue){return;}}
|
||
if(currentLayoutMode===LAYOUT_MODE.list){hidePlayer(true,function(){stopParsingMetadata(function(){var fullscreen=pendingPick||isPhone||isPortrait;showPlayer(videodata,!pendingPick,fullscreen,pendingPick);});});}
|
||
else if(currentLayoutMode===LAYOUT_MODE.selection){updateSelection(videodata);}}
|
||
function showOverlay(id){LazyLoader.load('shared/style/confirm.css',function(){currentOverlay=id;if(id===null){document.body.classList.remove('overlay');dom.overlay.classList.add('hidden');return;}
|
||
var text,title;if(pendingPick||id==='empty'){dom.overlayMenu.classList.remove('hidden');dom.overlayActionButton.classList.remove('hidden');dom.overlayActionButton.setAttribute('data-l10n-id',pendingPick?'overlay-cancel-button':'overlay-camera-button');}else{dom.overlayMenu.classList.add('hidden');dom.overlayActionButton.classList.add('hidden');}
|
||
if(id==='nocard'){title='nocard2-title';text='nocard3-text';}else{title=id+'-title';text=id+'-text';}
|
||
dom.overlayTitle.setAttribute('data-l10n-id',title);dom.overlayText.setAttribute('data-l10n-id',text);dom.overlay.classList.remove('hidden');document.body.classList.add('overlay');});}
|
||
function setControlsVisibility(visible){if(isPhone||isPortrait||currentLayoutMode!==LAYOUT_MODE.list){dom.playerView.classList[visible?'remove':'add']('video-controls-hidden');controlShowing=visible;}else{controlShowing=true;}
|
||
dom.videoContainer.setAttribute('data-l10n-id',controlShowing?'hide-controls-button':'show-controls-button');if(controlShowing){updateVideoControlSlider();}}
|
||
function movePlayHead(percent){if(document.documentElement.dir==='ltr'){dom.playHead.style.left=percent;}
|
||
else{dom.playHead.style.right=percent;}}
|
||
function updateVideoControlSlider(){var percent=(dom.player.currentTime/dom.player.duration)*100;if(isNaN(percent)){return;}
|
||
percent+='%';dom.elapsedText.textContent=MediaUtils.formatDuration(dom.player.currentTime);dom.elapsedTime.style.width=percent;if(!dragging){movePlayHead(percent);}}
|
||
function setVideoPlaying(playing){if(playing){play();}else{pause();}}
|
||
function deleteCurrentVideo(){hideOptionsView();setNFCSharing(false);LazyLoader.load('shared/style/confirm.css',function(){document.body.classList.add('confirm-dialog');Dialogs.confirm({messageId:'delete-video?',cancelId:'cancel',confirmId:'delete',danger:true},function _onSuccess(){deleteFile(currentVideo.name);if(!isPhone&&!isPortrait){if(currentVideo){showPlayer(currentVideo,false,true,true);}}else{hidePlayer(false);}
|
||
document.body.classList.remove('confirm-dialog');},function _onError(){setNFCSharing(true);document.body.classList.remove('confirm-dialog');});});}
|
||
function handlePlayButtonClick(){setVideoPlaying(dom.player.paused);}
|
||
function handleCloseButtonClick(){if(isPhone||isPortrait){hidePlayer(true);}else{toggleFullscreenPlayer();}}
|
||
function postPickResult(){pendingPick.postResult({type:currentVideoBlob.type,blob:currentVideoBlob});cleanupPick();}
|
||
function shareCurrentVideo(){hideOptionsView();videodb.getFile(currentVideo.name,function(blob){share([blob]);});}
|
||
function handleSliderTouchStart(event){if(null!=touchStartID){return;}
|
||
touchStartID=event.changedTouches[0].identifier;dragging=true;sliderRect=dom.sliderWrapper.getBoundingClientRect();if(dom.player.duration===Infinity){return;}
|
||
handleSliderTouchMove(event);}
|
||
function setVideoUrl(player,video,callback){function handleLoadedMetadata(){dom.player.onloadedmetadata=null;callback();}
|
||
function loadVideo(url){loadingChecker.ensureVideoLoads(handleLoadedMetadata);player.src=url;}
|
||
captions.remove();if('name'in video){videodb.getFile(video.name,function(file){captions.findAndDisplay(file.name);var url=URL.createObjectURL(file);loadVideo(url);if(pendingPick){currentVideoBlob=file;}});}else if('url'in video){loadVideo(video.url);}}
|
||
function scheduleVideoControlsAutoHiding(){controlFadeTimeout=setTimeout(function(){setControlsVisibility(false);},250);}
|
||
function setNFCSharing(enable){if(!window.navigator.mozNfc){return;}
|
||
if(enable){window.navigator.mozNfc.onpeerready=function(event){videodb.getFile(currentVideo.name,function(file){event.peer.sendFile(file);});};}else{window.navigator.mozNfc.onpeerready=null;}}
|
||
function showPlayer(video,autoPlay,enterFullscreen,keepControls){if(currentVideo){var old=thumbnailList.thumbnailMap[currentVideo.name];old.htmlNode.classList.remove('focused');}
|
||
currentVideo=video;var thumbnail=thumbnailList.thumbnailMap[currentVideo.name];thumbnail.htmlNode.classList.add('focused');updateDialog();dom.player.preload='metadata';function doneSeeking(){dom.player.onseeked=null;setControlsVisibility(true);if(!keepControls){scheduleVideoControlsAutoHiding();}
|
||
if(autoPlay){play();}else{pause();}
|
||
dom.player.hidden=false;}
|
||
dom.player.hidden=true;setVideoUrl(dom.player,currentVideo,function(){if(enterFullscreen){switchLayout(LAYOUT_MODE.fullscreenPlayer);}
|
||
var formattedDuration=MediaUtils.formatDuration(dom.player.duration);dom.durationText.textContent=formattedDuration;timeUpdated();setButtonPaused(false);playerShowing=true;var rotation;if('metadata'in currentVideo){if(currentVideo.metadata.currentTime===dom.player.duration){currentVideo.metadata.currentTime=0;}
|
||
dom.videoTitle.textContent=currentVideo.metadata.title;dom.player.currentTime=currentVideo.metadata.currentTime||0;rotation=currentVideo.metadata.rotation;}else{dom.videoTitle.textContent=currentVideo.title||'';dom.player.currentTime=0;rotation=0;}
|
||
document.l10n.setAttributes(dom.timeSlider,'seek-bar',{duration:formattedDuration});dom.timeSlider.setAttribute('aria-valuemin',0);dom.timeSlider.setAttribute('aria-valuemax',dom.player.duration);dom.timeSlider.setAttribute('aria-valuenow',dom.player.currentTime);dom.timeSlider.setAttribute('aria-valuetext',MediaUtils.formatDuration(dom.player.currentTime));VideoUtils.fitContainer(dom.videoContainer,dom.player,rotation||0);if(dom.player.seeking){dom.player.onseeked=doneSeeking;}else{doneSeeking();}
|
||
setNFCSharing(true);});}
|
||
function hidePlayer(updateVideoMetadata,callback){if(!playerShowing){if(callback){callback();}
|
||
return;}
|
||
dom.player.pause();setNFCSharing(false);function completeHidingPlayer(){switchLayout(LAYOUT_MODE.list);setButtonPaused(false);playerShowing=false;updateDialog();captions.remove();dom.player.removeAttribute('src');dom.player.load();startParsingMetadata();if(callback){callback();}}
|
||
if(!('metadata'in currentVideo)||!updateVideoMetadata||pendingPick){completeHidingPlayer();return;}
|
||
var video=currentVideo;var thumbnail=thumbnailList.thumbnailMap[video.name];if(dom.player.currentTime===0){video.metadata.bookmark=null;updateMetadata();}
|
||
else{captureFrame(dom.player,video.metadata,function(bookmark){video.metadata.bookmark=bookmark;updateMetadata();});}
|
||
function updateMetadata(){thumbnail.updatePoster(video.metadata.bookmark||video.metadata.poster);if(!video.metadata.watched){video.metadata.watched=true;thumbnail.setWatched(true);}
|
||
video.metadata.currentTime=dom.player.currentTime;videodb.updateMetadata(video.name,video.metadata);completeHidingPlayer();}}
|
||
function playerEnded(){if(dragging){return;}
|
||
if(playing){dom.player.currentTime=0;pause();}}
|
||
function setButtonPaused(paused){dom.play.classList.toggle('paused',paused);dom.play.setAttribute('data-l10n-id',paused?'play-button':'pause-button');}
|
||
function play(){loadingChecker.ensureVideoPlays();setButtonPaused(false);VideoStats.start(dom.player);dom.player.play();playing=true;}
|
||
function pause(){loadingChecker.cancelEnsureVideoPlays();setButtonPaused(true);if(dragging){dragging=false;dom.playHead.classList.remove('active');}
|
||
dom.player.pause();playing=false;VideoStats.stop();VideoStats.dump();}
|
||
function timeUpdated(){if(controlShowing){if(dom.player.duration===Infinity||dom.player.duration===0){return;}
|
||
updateVideoControlSlider();}
|
||
dom.timeSlider.setAttribute('aria-valuenow',dom.player.currentTime);dom.timeSlider.setAttribute('aria-valuetext',MediaUtils.formatDuration(dom.player.currentTime));}
|
||
function handleSliderTouchEnd(event){if(!event.changedTouches.identifiedTouch(touchStartID)){return;}
|
||
touchStartID=null;if(!dragging){return;}
|
||
dragging=false;dom.playHead.classList.remove('active');updateVideoControlSlider();if(dom.player.currentTime===dom.player.duration){pause();}}
|
||
function handleSliderTouchMove(event){if(!dragging){return;}
|
||
var touch=event.changedTouches.identifiedTouch(touchStartID);if(!touch){return;}
|
||
function getTouchPos(){return(document.documentElement.dir==='ltr')?(touch.clientX-sliderRect.left):(sliderRect.right-touch.clientX);}
|
||
var touchPos=getTouchPos();var pos=touchPos/sliderRect.width;pos=Math.max(pos,0);pos=Math.min(pos,1);var percent=pos*100+'%';dom.playHead.classList.add('active');movePlayHead(percent);dom.elapsedTime.style.width=percent;seeker.seekTo(dom.player.duration*pos);}
|
||
function handleSliderKeypress(event){var step=Math.max(dom.player.duration/20,2);if(event.keyCode===event.DOM_VK_DOWN){seeker.seekTo(dom.player.currentTime-step);}else if(event.keyCode===event.DOM_VK_UP){seeker.seekTo(dom.player.currentTime+step);}}
|
||
function toCamelCase(str){return str.replace(/\-(.)/g,function replacer(str,p1){return p1.toUpperCase();});}
|
||
function showPickView(){thumbnailList.setPickMode(true);document.body.classList.add('pick-activity');dom.pickerHeader.addEventListener('action',cancelPick);if(!isPhone&&!isPortrait){thumbnailList.updateAllThumbnailTitles();}}
|
||
function cancelPick(){pendingPick.postError('pick cancelled');cleanupPick();}
|
||
function cleanupPick(){pendingPick=null;currentVideoBlob=null;hidePlayer(false);}
|
||
function showThrobber(){dom.throbber.classList.remove('hidden');dom.throbber.classList.add('throb');}
|
||
function hideThrobber(){dom.throbber.classList.remove('throb');setTimeout(function(){dom.throbber.classList.add('hidden');},100);}
|
||
function releaseVideo(){if(videoHardwareReleased){return;}
|
||
videoHardwareReleased=true;if(dom.player.readyState>0){restoreTime=dom.player.currentTime;}
|
||
else{restoreTime=0;}
|
||
captions.remove();dom.player.removeAttribute('src');dom.player.load();}
|
||
function restoreVideo(){if(!videoHardwareReleased){return;}
|
||
videoHardwareReleased=false;setVideoUrl(dom.player,currentVideo,function(){VideoUtils.fitContainer(dom.videoContainer,dom.player,currentVideo.metadata.rotation||0);dom.player.currentTime=restoreTime;});}
|
||
window.addEventListener('storage',function(e){if(e.key==='view-activity-wants-to-use-hardware'&&e.newValue&&!document.hidden&&playerShowing&&!videoHardwareReleased){console.log('The video app view activity needs to play a video.');console.log('Pausing the video and returning to the thumbnails.');console.log('See bug 1088456.');handleCloseButtonClick();}}); |