Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
642
assets/webapps/sms.gaiamobile.org/gaia_build_defer_index.js
Normal file
642
assets/webapps/sms.gaiamobile.org/gaia_build_defer_index.js
Normal file
|
|
@ -0,0 +1,642 @@
|
|||
;(function(){'use strict';if(navigator.mozIccManager){return;}
|
||||
navigator.mozIccManager={iccIds:[]};})();;window.COMPONENTS_BASE_URL='/shared/elements/';;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(){'use strict';if(window.navigator.mozHour12||window.navigator.hour12){return;}
|
||||
window.navigator.mozHour12=undefined;var _setMozHour12=function(result){if(result===null){result=undefined;}
|
||||
if(window.navigator.mozHour12!==result){window.navigator.mozHour12=result;window.dispatchEvent(new CustomEvent('timeformatchange'));}};var _hour12Handler=function(event){_setMozHour12(event.settingValue);};var _kLocaleTime='locale.hour12';var req=window.navigator.mozSettings.createLock().get(_kLocaleTime);req.onsuccess=function(){_setMozHour12(req.result[_kLocaleTime]);};window.navigator.mozSettings.addObserver(_kLocaleTime,_hour12Handler);})();;(function(exports){'use strict';var priv=new WeakMap();var rmatcher=/\$\{([^}]+)\}/g;var rentity=/[&<>"']/g;var rentities={'&':'&','<':'<','>':'>','"':'"','\'':'''};function extract(node){var nodeId;if(typeof node==='string'){nodeId=node;node=document.getElementById(node);}else if(node){nodeId=node.id;}
|
||||
if(!node){console.error('Can not find the node passed to Template',nodeId);return'';}
|
||||
if(!node.firstChild){console.error('Node passed to Template should have a comment node',nodeId);return'';}
|
||||
node=node.firstChild;do{if(node.nodeType===Node.COMMENT_NODE){return(node.nodeValue||'').trim();}}while((node=node.nextSibling));console.error('Nodes passed to Template should have a comment node',nodeId);return'';}
|
||||
function Template(idOrNode){if(!(this instanceof Template)){return new Template(idOrNode);}
|
||||
priv.set(this,{idOrNode:idOrNode});}
|
||||
Template.prototype.extract=function(){var members=priv.get(this);if(!members.tmpl){members.tmpl=extract(members.idOrNode);delete members.idOrNode;}
|
||||
return members.tmpl;};Template.prototype.toString=function(){return this.extract().slice();};Template.prototype.interpolate=function(data={},options={}){var safeList=options.safe;if(safeList&&!Array.isArray(safeList)){throw new TypeError(`If present "options.safe" must be an Array, not ${typeof options.safe}`);}
|
||||
var hasSafeProperties=safeList&&safeList.length;return this.extract().replace(rmatcher,function(match,property){property=property.trim();if(!(property in data)){throw new Error(`No value provided for template identifier "${property}"`);}
|
||||
var unsafeString=data[property];if(typeof unsafeString!=='string'){throw new TypeError(`"data.${property}" must be a String, not ${typeof unsafeString}`);}
|
||||
var isPropertySafe=hasSafeProperties&&safeList.includes(property);return isPropertySafe?unsafeString:Template.escape(unsafeString);});};Template.prototype.prepare=function(data,options){var self=this;return{toString:function t_toString(){return self.interpolate(data,options);},toDocumentFragment:function t_toDocumentFragment(){var template=document.createElement('template');template.innerHTML=this.toString();return template.content.cloneNode(true);}};};Template.escape=function escape(str){if(typeof str!=='string'){return'';}
|
||||
return str.replace(rentity,function(s){return rentities[s];});};exports.Template=Template;}(this));;this.asyncStorage=(function(){'use strict';var DBNAME='asyncStorage';var DBVERSION=1;var STORENAME='keyvaluepairs';var db=null;function withDatabase(f){if(db){f();}else{var openreq=indexedDB.open(DBNAME,DBVERSION);openreq.onerror=function withStoreOnError(){console.error('asyncStorage: can\'t open database:',openreq.error.name);};openreq.onupgradeneeded=function withStoreOnUpgradeNeeded(){openreq.result.createObjectStore(STORENAME);};openreq.onsuccess=function withStoreOnSuccess(){db=openreq.result;f();};}}
|
||||
function withStore(type,callback,oncomplete){withDatabase(function(){var transaction=db.transaction(STORENAME,type);if(oncomplete){transaction.oncomplete=oncomplete;}
|
||||
callback(transaction.objectStore(STORENAME));});}
|
||||
function getItem(key,callback){var req;withStore('readonly',function getItemBody(store){req=store.get(key);req.onerror=function getItemOnError(){console.error('Error in asyncStorage.getItem(): ',req.error.name);};},function onComplete(){var value=req.result;if(value===undefined){value=null;}
|
||||
callback(value);});}
|
||||
function setItem(key,value,callback){withStore('readwrite',function setItemBody(store){var req=store.put(value,key);req.onerror=function setItemOnError(){console.error('Error in asyncStorage.setItem(): ',req.error.name);};},callback);}
|
||||
function removeItem(key,callback){withStore('readwrite',function removeItemBody(store){var req=store.delete(key);req.onerror=function removeItemOnError(){console.error('Error in asyncStorage.removeItem(): ',req.error.name);};},callback);}
|
||||
function clear(callback){withStore('readwrite',function clearBody(store){var req=store.clear();req.onerror=function clearOnError(){console.error('Error in asyncStorage.clear(): ',req.error.name);};},callback);}
|
||||
function length(callback){var req;withStore('readonly',function lengthBody(store){req=store.count();req.onerror=function lengthOnError(){console.error('Error in asyncStorage.length(): ',req.error.name);};},function onComplete(){callback(req.result);});}
|
||||
function key(n,callback){if(n<0){callback(null);return;}
|
||||
var req;withStore('readonly',function keyBody(store){var advanced=false;req=store.openCursor();req.onsuccess=function keyOnSuccess(){var cursor=req.result;if(!cursor){return;}
|
||||
if(n===0||advanced){return;}
|
||||
advanced=true;cursor.advance(n);};req.onerror=function keyOnError(){console.error('Error in asyncStorage.key(): ',req.error.name);};},function onComplete(){var cursor=req.result;callback(cursor?cursor.key:null);});}
|
||||
return{getItem:getItem,setItem:setItem,removeItem:removeItem,clear:clear,length:length,key:key};}());;'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();}());;function StickyHeader(scrollable,sticky){'use strict';var headers=scrollable.getElementsByTagName('header');var stickyPosition;var stickyStyle=sticky.style;this._throttledRefresh=function(){var display=false;if(stickyPosition===undefined){stickyPosition=sticky.offsetHeight+sticky.offsetTop;}
|
||||
for(var i=1,length=headers.length;i<length;i++){if(headers[i].offsetTop-scrollable.scrollTop>stickyPosition){var lookupIndex=1;var header=headers[i-lookupIndex];while(header&&header.offsetHeight===0){lookupIndex++;header=headers[i-lookupIndex];}
|
||||
stickyStyle.backgroundImage='-moz-element(#'+header.id+')';display=true;break;}}
|
||||
sticky.classList.toggle('has-content',display);this.throttle=null;}.bind(this);this.refresh=function(){if(!this.throttle){this.throttle=setTimeout(this._throttledRefresh,0);}}.bind(this);scrollable.addEventListener('scroll',this.refresh);};(function(exports){'use strict';function getThumbnail(contact){return getOnePhoto(contact,'begin');}
|
||||
function getFullResolution(contact){return getOnePhoto(contact,'end');}
|
||||
function getOnePhoto(contact,position){if(!contact||!contact.photo||!contact.photo.length){return null;}
|
||||
if(contact.photo.length===1){return contact.photo[0];}
|
||||
var photos=contact.photo;var category=contact.category;if(Array.isArray(category)&&category.indexOf('fb_linked')!==-1){if(photos.length>=4){return photos[(position=='begin')?1:0];}
|
||||
return photos[0];}
|
||||
photos=photosBySize(contact);var index=(position=='begin')?0:photos.length-1;return photos[index];}
|
||||
function photosBySize(contact){var photos=contact.photo.slice(0);photos.sort(function(p1,p2){if(size(p1)<size(p2)){return-1;}
|
||||
if(size(p1)>size(p2)){return 1;}
|
||||
return 0;});return photos;}
|
||||
function size(photo){if(typeof photo=='string'){return photo.length;}
|
||||
return photo.size;}
|
||||
exports.ContactPhotoHelper={getThumbnail:getThumbnail,getFullResolution:getFullResolution};})(window);;'use strict';var fb=self.fb||{};self.fb=fb;fb.utils=self.fb.utils||{};self.fb.utils=fb.utils;if(typeof fb.utils.Request!=='function'){fb.utils.Request=function(){this.done=function(result){this.result=result;if(typeof this.onsuccess==='function'){var ev={};ev.target=this;window.setTimeout(function(){this.onsuccess(ev);}.bind(this),0);}};this.failed=function(error){this.error=error;if(typeof this.onerror==='function'){var ev={};ev.target=this;window.setTimeout(function(){this.onerror(ev);}.bind(this),0);}};};};'use strict';var fb=self.fb||{};self.fb=fb;(function(){var contacts=fb.contacts||{};fb.contacts=contacts;var datastore;var DATASTORE_NAME='Gaia_Facebook_Friends';var INDEX_ID=1;var readyState='notInitialized';var INITIALIZE_EVENT='fb_ds_init';var revisionId;function createIndex(){return{byTel:Object.create(null),treeTel:[]};}
|
||||
var index;function safeError(err){if(err&&err.name){return err;}
|
||||
return{name:'UnknownError'};}
|
||||
function notifyOpenSuccess(cb){readyState='initialized';if(typeof cb==='function'){window.setTimeout(cb,0);}
|
||||
var ev=new CustomEvent(INITIALIZE_EVENT);document.dispatchEvent(ev);}
|
||||
function initError(outRequest,error){outRequest.failed(error);}
|
||||
function handleInitError(err,errorCb){readyState='error';contacts.error=err;if(typeof errorCb==='function'){window.setTimeout(function(){errorCb(err);},0);}
|
||||
document.dispatchEvent(new CustomEvent(INITIALIZE_EVENT));}
|
||||
function defaultError(request){return defaultErrorCb.bind(null,request);}
|
||||
function defaultErrorCb(request,error){request.failed(error);}
|
||||
function setIndex(obj){index=(obj||createIndex());}
|
||||
function successGet(outReq,data){outReq.done(data);}
|
||||
function errorGet(outReq,uid,err){window.console.error('Error while getting object for UID: ',uid);outReq.failed(err.name);}
|
||||
Object.defineProperty(contacts,'datastore',{get:function getDataStore(){return datastore;},enumerable:false,configurable:false});Object.defineProperty(contacts,'dsIndex',{get:function getIndex(){return index;},set:setIndex,enumerable:false,configurable:false});contacts.get=function(uid){var outRequest=new fb.utils.Request();window.setTimeout(function get(){contacts.init(function(){doGet(uid,outRequest);},function(err){initError(outRequest,err);});},0);return outRequest;};function doGet(uid,outRequest){var successCb=successGet.bind(null,outRequest);var errorCb=errorGet.bind(null,outRequest,uid);datastore.get(uid).then(successCb,errorCb);}
|
||||
contacts.getByPhone=function(tel){var outRequest=new fb.utils.Request();window.setTimeout(function get_by_phone(){contacts.init(function get_by_phone(){doGetByPhone(tel,outRequest);},function(err){initError(outRequest,err);});},0);return outRequest;};function doGetByPhone(tel,outRequest){var dsId;var normalizedNumber=navigator.mozPhoneNumberService.normalize(tel);if(datastore.revisionId!==revisionId){window.console.info('Datastore revision id has changed!');datastore.get(INDEX_ID).then(function success(obj){setIndex(obj);revisionId=datastore.revisionId;dsId=index.byTel[normalizedNumber];if(typeof dsId!=='undefined'){datastore.get(dsId).then(function success(friend){outRequest.done(friend);},defaultError(outRequest));}
|
||||
else{outRequest.done(null);}},function(err){err=safeError(err);window.console.error('The index cannot be refreshed: ',err.name);outRequest.failed(err);});}
|
||||
else{dsId=index.byTel[normalizedNumber];if(typeof dsId!=='undefined'){datastore.get(dsId).then(function success(friend){outRequest.done(friend);},defaultError(outRequest));}
|
||||
else{outRequest.done(null);}}}
|
||||
contacts.search=function(by,number){var outRequest=new fb.utils.Request();window.setTimeout(function do_search(){contacts.init(function do_search_init(){if(by==='phone'){doSearchByPhone(number,outRequest);}},function(err){initError(outRequest,err);});},0);return outRequest;};function doSearchByPhone(number,outRequest){var normalizedNumber=navigator.mozPhoneNumberService.normalize(number);LazyLoader.load(['/shared/js/fb/fb_tel_index.js','/shared/js/binary_search.js'],function(){var toSearchNumber=normalizedNumber;if(number.charAt(0)==='+'){toSearchNumber=number.substring(1);}
|
||||
if(datastore.revisionId!==revisionId){window.console.info('Datastore revision id has changed!');datastore.get(INDEX_ID).then(function success(obj){setIndex(obj);revisionId=datastore.revisionId;var results=TelIndexer.search(index.treeTel,toSearchNumber);var out=null;if(results.length>0){out=datastore.get.apply(datastore,results);}
|
||||
return out;},function(err){err=safeError(err);window.console.error('The index cannot be refreshed: ',err.name);outRequest.failed(err);}).then(function success(objList){if(objList&&!Array.isArray(objList)){objList=[objList];}
|
||||
else{objList=[];}
|
||||
outRequest.done(objList);},function error(err){err=safeError(err);window.console.error('Error while retrieving result data: ',err.name);outRequest.failed(err);});}
|
||||
else{var results=TelIndexer.search(index.treeTel,toSearchNumber);if(results.length>0){datastore.get.apply(datastore,results).then(function success(objList){if(!Array.isArray(objList)){objList=[objList];}
|
||||
outRequest.done(objList);},function error(err){err=safeError(err);window.console.error('Error while retrieving result data: ',err.name);outRequest.failed(err);});}
|
||||
else{outRequest.done(results);}}});}
|
||||
contacts.refresh=function(){var outRequest=new fb.utils.Request();window.setTimeout(function clear(){contacts.init(function(){doRefresh(outRequest);},function(err){initError(outRequest,err);});},0);return outRequest;};function doRefresh(outRequest){datastore.get(INDEX_ID).then(function success(obj){setIndex(obj);outRequest.done();},defaultError(outRequest));}
|
||||
contacts.getLength=function(){var retRequest=new fb.utils.Request();window.setTimeout(function(){contacts.init(function get_all(){doGetLength(retRequest);},function(err){initError(retRequest,err);});},0);return retRequest;};function doGetLength(outRequest){datastore.getLength().then(function success(length){outRequest.done(length-1);},function error(err){outRequest.failed(safeError(err));});}
|
||||
contacts.restart=function(){readyState='notInitialized';};contacts.init=function(cb,errorCb){if(!navigator.getDataStores){handleInitError({name:'DatastoreNotFound'},errorCb);return;}
|
||||
if(readyState==='initialized'){cb();return;}
|
||||
if(readyState==='initializing'){document.addEventListener(INITIALIZE_EVENT,function oninitalized(){cb();document.removeEventListener(INITIALIZE_EVENT,oninitalized);});return;}
|
||||
readyState='initializing';navigator.getDataStores(DATASTORE_NAME).then(function success(ds){if(ds.length<1){handleInitError({name:'DatastoreNotFound'},errorCb);return;}
|
||||
datastore=ds[0];datastore.getLength().then(function(length){if(length===0&&datastore.readOnly===false){window.console.info('Adding index as length is 0');setIndex(createIndex());return datastore.add(index);}
|
||||
else if(length>0){return datastore.get(INDEX_ID);}
|
||||
else if(datastore.readOnly===true){window.console.warn('The datastore is empty and readonly');}
|
||||
return null;}).then(function add_index_success(v){if(typeof v!=='number'){setIndex(v);}
|
||||
revisionId=datastore.revisionId;notifyOpenSuccess(cb);},function add_index_error(err){err=safeError(err);window.console.error('Error while setting the index: ',err.name);handleInitError(err,errorCb);});},function error(err){err=safeError(err);window.console.error('FB: Error while opening the DataStore: ',err.name);handleInitError(err,errorCb);});};})();;'use strict';var fb=self.fb||{};self.fb=fb;if(!self.AuxFB){self.AuxFb=(function(){var CATEGORY='facebook';var NOT_LINKED='not_linked';var LINKED='fb_linked';function populate(source,target,propertyNames){propertyNames.forEach(function(property){var propertyValue=source[property];if(propertyValue){if(Array.isArray(propertyValue)){target[property]=propertyValue.slice(0,propertyValue.length);}else{target[property]=propertyValue;}}});}
|
||||
function mergeFbData(dcontact,fbdata){var multipleFields=['email','tel','photo','org','adr'];multipleFields.forEach(function(field){if(!dcontact[field]){dcontact[field]=[];}
|
||||
var items=fbdata[field];if(items){items.forEach(function(item){var dupList=checkDuplicates(field,item,dcontact[field],fbdata.shortTelephone);if(dupList.length===0){dcontact[field].push(item);}});}});var singleFields=['bday','anniversary'];singleFields.forEach(function(field){if(!dcontact[field]){dcontact[field]=fbdata[field];}});mergeNames(dcontact,fbdata);}
|
||||
function mergeNames(devContact,fbContact){var namesChanged=false;var nameFields=['givenName','familyName'];nameFields.forEach(function(anameField){var fieldValue=devContact[anameField];var fbValue=fbContact[anameField];if((!Array.isArray(fieldValue)||fieldValue.length===0)&&Array.isArray(fbValue)&&fbValue.length>0){namesChanged=true;devContact[anameField]=(fieldValue&&fieldValue[0])||[];devContact[anameField].push(fbValue[0]);}});if(namesChanged){var givenName=devContact.givenName[0]||'';var familyName=devContact.familyName[0]||'';devContact.name=[givenName+' '+familyName];}}
|
||||
function isFbContact(devContact){return(devContact&&devContact.category&&devContact.category.indexOf(CATEGORY)!==-1);}
|
||||
function isFbLinked(devContact){return(devContact&&devContact.category&&devContact.category.indexOf(LINKED)!==-1);}
|
||||
function getData(devContact){var outReq=new fb.utils.Request();window.setTimeout(function do_getData(){var uid=getFriendUid(devContact);if(uid){var fbreq=fb.contacts.get(uid);fbreq.onsuccess=function(){var fbdata=fbreq.result;var out=mergeContact(devContact,fbdata);outReq.done(out);};fbreq.onerror=function(){outReq.failed(fbreq.error);};}
|
||||
else{outReq.done(devContact);}},0);return outReq;}
|
||||
function getFriendUid(devContact){var out=devContact.uid;if(!out){if(isFbLinked(devContact)){out=getLinkedTo(devContact);}
|
||||
else if(devContact.category){var idx=devContact.category.indexOf(CATEGORY);if(idx!==-1){out=devContact.category[idx+2];}}}
|
||||
return out;}
|
||||
function getLinkedTo(devContact){var out;if(devContact.category){var idx=devContact.category.indexOf(LINKED);if(idx!==-1){out=devContact.category[idx+1];}}
|
||||
return out;}
|
||||
function mergeContact(devContact,fbContact){var out=devContact;if(fbContact){out=Object.create(null);out.updated=devContact.updated;out.published=devContact.published;populate(devContact,out,Object.getOwnPropertyNames(devContact));populate(devContact,out,Object.getOwnPropertyNames(Object.getPrototypeOf(devContact)));mergeFbData(out,fbContact);}
|
||||
return out;}
|
||||
function getContactByNumber(number,onsuccess,onerror){var req=fb.contacts.getByPhone(number);req.onsuccess=function get_by_phone_success(e){var fbData=req.result;if(fbData){fb.getMozContactByUid(fbData.uid,function merge(result){if(Array.isArray(result)&&result[0]){var finalContact=fb.mergeContact(result[0],fbData);onsuccess(finalContact);}
|
||||
else{onsuccess(null);}},function error_get_mozContact(err){console.error('Error getting mozContact: ',err.name);onerror(err);});}
|
||||
else{onsuccess(null);}};req.onerror=function(){onerror(req.error);};}
|
||||
function checkDuplicates(field,fbItem,devContactItems,extraFbItems){var potentialDuplicatesFields=['email','tel'];var out=[];if(devContactItems&&potentialDuplicatesFields.indexOf(field)!==-1){var total=devContactItems.length;for(var i=0;i<total;i++){var localValue=devContactItems[i].value;var fbValue=fbItem.value;if(localValue){var trimedLocal=localValue.trim();if(trimedLocal===fbValue||(field==='tel'&&Array.isArray(extraFbItems)&&extraFbItems.indexOf(trimedLocal)!==-1)){out.push(trimedLocal);out.push(fbValue);}}}}
|
||||
return out;}
|
||||
function getMozContactByUid(uid,onsuccess,onerror){var filter={filterBy:['category'],filterValue:uid,filterOp:'contains'};var req=navigator.mozContacts.find(filter);req.onsuccess=function(){onsuccess(req.result);};req.onerror=function(){onerror(req.error);};}
|
||||
return{'isFbContact':isFbContact,'isFbLinked':isFbLinked,'getData':getData,'getFriendUid':getFriendUid,'getLinkedTo':getLinkedTo,'mergeContact':mergeContact,'getContactByNumber':getContactByNumber,'getMozContactByUid':getMozContactByUid,'checkDuplicates':checkDuplicates,get CATEGORY(){return CATEGORY;},get LINKED(){return LINKED;},get NOT_LINKED(){return NOT_LINKED;}};})();var props=Object.keys(self.AuxFb);for(var j=0,end=props.length;j<end;j++){var prop=props[j];if(typeof self.fb[prop]==='function'){self.fb[prop]=self.AuxFb[prop];}
|
||||
else{Object.defineProperty(self.fb,prop,{value:(function(){return self.AuxFb[prop];})(),writable:false,enumerable:true,configurable:false});}}};(function(exports){'use strict';function ensureValidEventName(eventName){if(!eventName||typeof eventName!=='string'){throw new Error('Event name should be a valid non-empty string!');}}
|
||||
function ensureValidHandler(handler){if(typeof handler!=='function'){throw new Error('Handler should be a function!');}}
|
||||
function ensureAllowedEventName(allowedEvents,eventName){if(allowedEvents&&allowedEvents.indexOf(eventName)<0){throw new Error('Event "'+eventName+'" is not allowed!');}}
|
||||
var eventDispatcher={on:function(eventName,handler){ensureValidEventName(eventName);ensureAllowedEventName(this.allowedEvents,eventName);ensureValidHandler(handler);var handlers=this.listeners.get(eventName);if(!handlers){handlers=new Set();this.listeners.set(eventName,handlers);}
|
||||
handlers.add(handler);},once:function(eventName,handler){ensureValidHandler(handler);var once=(parameters)=>{eventDispatcher.off.call(this,eventName,once);handler(parameters);};eventDispatcher.on.call(this,eventName,once);},off:function(eventName,handler){ensureValidEventName(eventName);ensureAllowedEventName(this.allowedEvents,eventName);ensureValidHandler(handler);var handlers=this.listeners.get(eventName);if(!handlers){return;}
|
||||
handlers.delete(handler);if(!handlers.size){this.listeners.delete(eventName);}},offAll:function(eventName){if(typeof eventName==='undefined'){this.listeners.clear();return;}
|
||||
ensureValidEventName(eventName);ensureAllowedEventName(this.allowedEvents,eventName);var handlers=this.listeners.get(eventName);if(!handlers){return;}
|
||||
handlers.clear();this.listeners.delete(eventName);},emit:function(eventName,parameters){ensureValidEventName(eventName);ensureAllowedEventName(this.allowedEvents,eventName);var handlers=this.listeners.get(eventName);if(!handlers){return;}
|
||||
handlers.forEach(function(handler){try{handler(parameters);}catch(e){console.error(e);}});}};exports.EventDispatcher={mixin:function(target,allowedEvents){if(!target||typeof target!=='object'){throw new Error('Object to mix into should be valid object!');}
|
||||
if(typeof allowedEvents!=='undefined'&&!Array.isArray(allowedEvents)){throw new Error('Allowed events should be a valid array of strings!');}
|
||||
Object.keys(eventDispatcher).forEach(function(method){if(typeof target[method]!=='undefined'){throw new Error('Object to mix into already has "'+method+'" property defined!');}
|
||||
target[method]=eventDispatcher[method].bind(this);},{listeners:new Map(),allowedEvents:allowedEvents});return target;}};})(self);;(function(exports){'use strict';var rdashes=/-(.)/g;var rescape=/[.?*+^$[\]\\(){}|-]/g;var rparams=/([^?=&]+)(?:=([^&]*))?/g;var rnondialablechars=/[^,#+\*\d]/g;var rmail=/[\w-]+@[\w\-]/;var Utils={date:{shared:new Date(),formatters:{'time':{options:{hour:'numeric',minute:'numeric',},formatter:null},'full':{options:{month:'2-digit',day:'2-digit',year:'numeric',},formatter:null},'full-wt':{options:{month:'2-digit',day:'2-digit',year:'numeric',hour:'numeric',minute:'numeric',},formatter:null},'day':{options:{weekday:'long',},formatter:null},'day-wt':{options:{weekday:'long',hour:'numeric',minute:'numeric',},formatter:null},},},escapeRegex:function ut_escapeRegex(str){if(typeof str!=='string'){return'';}
|
||||
return str.replace(rescape,'\\$&');},getFormattedHour:function ut_getFormattedHour(time){this.date.shared.setTime(+time);return this._getFormatter('time',false).format(this.date.shared);},getDayDate:function re_getDayDate(time){this.date.shared.setTime(+time);this.date.shared.setHours(0,0,0,0);return this.date.shared.getTime();},resetDateFormatters:function ut_resetDateFormatters(){for(var type in this.date.formatters){this.date.formatters[type].formatter=null;}},_getFormatter:function ut_getFormatter(type,withTime){if(withTime){type+='-wt';}
|
||||
if(!this.date.formatters[type].formatter){var options=Object.assign({},this.date.formatters[type].options);if(options.hour){options.hour12=navigator.mozHour12;}
|
||||
this.date.formatters[type].formatter=Intl.DateTimeFormat(navigator.languages,options);}
|
||||
return this.date.formatters[type].formatter;},setHeaderDate:function ut_setHeaderDate({time,element,withTime}){var formatter;var today=Utils.getDayDate(Date.now());var otherDay=Utils.getDayDate(time);var dayDiff=(today-otherDay)/86400000;this.date.shared.setTime(+time);if(isNaN(dayDiff)){element.setAttribute('data-l10n-id','incorrectDate');return;}
|
||||
if(dayDiff<0){formatter=this._getFormatter('full',withTime);element.removeAttribute('data-l10n-id');element.textContent=formatter.format(this.date.shared);return;}
|
||||
if(dayDiff===0){if(withTime){document.l10n.setAttributes(element,'todayWithTime',{time:this.getFormattedHour(this.date.shared)});}else{element.setAttribute('data-l10n-id','today');}}else if(dayDiff===1){if(withTime){document.l10n.setAttributes(element,'yesterdayWithTime',{time:this.getFormattedHour(this.date.shared)});}else{element.setAttribute('data-l10n-id','yesterday');}}else if(dayDiff<6){formatter=this._getFormatter('day',withTime);element.removeAttribute('data-l10n-id');element.textContent=formatter.format(this.date.shared);}else{formatter=this._getFormatter('full',withTime);element.removeAttribute('data-l10n-id');element.textContent=formatter.format(this.date.shared);}},getContactDetails:function ut_getContactDetails(number,contacts,include){var details={};include=include||{};function updateDetails(contact){var name,phone,i,length,subscriber,org;name=contact.name[0];org=contact.org&&contact.org[0];length=contact.tel?contact.tel.length:0;subscriber=number.length>7?number.substr(-8):number;for(i=0;i<length;i++){if(contact.tel[i].value.indexOf(subscriber)!==-1){phone=contact.tel[i];break;}}
|
||||
details.isContact=true;if(include.photoURL){var photo=ContactPhotoHelper.getThumbnail(contact);if(photo){details.photoURL=window.URL.createObjectURL(photo);}}
|
||||
details.name=name;details.org=details.org||org;}
|
||||
if(!contacts||(Array.isArray(contacts)&&contacts.length===0)){details.title='';}else if(!Array.isArray(contacts)){updateDetails(contacts);details.title=details.name||details.org;}else{for(var i=0,l=contacts.length;i<l;i++){updateDetails(contacts[i]);if(details.name){break;}}
|
||||
details.title=details.name||details.org;}
|
||||
return details;},getPhoneDetails:function ut_getPhoneDetails(input,tels){var length=tels.length;var hasUniqueCarriers=true;var hasUniqueTypes=true;var found,tel,type,carrier;for(var i=0;i<length;i++){tel=tels[i];if(tel.value&&Utils.probablyMatches(tel.value,input)){found=tel;}
|
||||
if(carrier&&carrier===tel.carrier){hasUniqueCarriers=false;}
|
||||
if(type&&type===tel.type[0]){hasUniqueTypes=false;}
|
||||
carrier=tel.carrier;type=(tel.type&&tel.type[0])||'';}
|
||||
if(!found){return null;}
|
||||
return{type:(found.type&&found.type[0])||'',carrier:hasUniqueCarriers||hasUniqueTypes?found.carrier:'',number:found.value};},removeNonDialables:function ut_removeNonDialables(input){return input.replace(rnondialablechars,'');},probablyMatches:function ut_probablyMatches(a,b){var service=navigator.mozPhoneNumberService;if(typeof a!=='string'||typeof b!=='string'){return false;}
|
||||
if(Settings.supportEmailRecipient&&Utils.isEmailAddress(a)&&Utils.isEmailAddress(b)){return a===b;}
|
||||
if(service&&service.normalize){a=service.normalize(a);b=service.normalize(b);}else{a=Utils.removeNonDialables(a);b=Utils.removeNonDialables(b);}
|
||||
return a===b||a.slice(-7)===b.slice(-7);},multiRecipientMatch:function ut_multiRecipientMatch(a,b){a=[].concat(a);b=[].concat(b);var blen=b.length;if(a.length!==blen){return false;}
|
||||
return a.every(function(number){for(var i=0;i<blen;i++){if(Utils.probablyMatches(number,b[i])){return true;}}});},getResizedImgBlob:function ut_getResizedImgBlob(blob,limit,callback){var defaultLimit=295*1024;if(typeof limit==='function'){callback=limit;limit=defaultLimit;}
|
||||
limit=limit===0?defaultLimit:Math.min(limit,defaultLimit);if(blob.size<limit){setTimeout(function blobCb(){callback(blob);});return;}
|
||||
var ratio=Math.sqrt(blob.size/limit);Utils._resizeImageBlobWithRatio({blob:blob,limit:limit,ratio:ratio,callback:callback});},getSizeForL10n:function ut_getSizeForL10n(size){var sizeKB=size/1024;var sizeMB=sizeKB/1024;if(size<1000){return{l10nId:'attachmentSizeB',l10nArgs:{n:size}};}else if(sizeKB<1000){return{l10nId:'attachmentSizeKB',l10nArgs:{n:sizeKB.toFixed(1)}};}
|
||||
return{l10nId:'attachmentSizeMB',l10nArgs:{n:sizeMB.toFixed(1)}};},_resizeImageBlobWithRatio:function ut_resizeImageBlobWithRatio(obj){var blob=obj.blob;var callback=obj.callback;var limit=obj.limit;var ratio=Math.ceil(obj.ratio);var qualities=[0.65,0.5,0.25];var sampleSize=1;var sampleSizeHash='';if(blob.size<limit||ratio<=1){setTimeout(function blobCb(){callback(blob);});return;}
|
||||
if(blob.type==='image/jpeg'){if(ratio>=8){sampleSize=8;}else{sampleSize=ratio=Utils.getClosestSampleSize(ratio);}
|
||||
sampleSizeHash='#-moz-samplesize='+sampleSize;}
|
||||
var img=document.createElement('img');var url=window.URL.createObjectURL(blob);img.src=url+sampleSizeHash;img.onload=function onBlobLoaded(){window.URL.revokeObjectURL(url);var targetWidth=img.width*sampleSize/ratio;var targetHeight=img.height*sampleSize/ratio;var canvas=document.createElement('canvas');canvas.width=targetWidth;canvas.height=targetHeight;var context=canvas.getContext('2d',{willReadFrequently:true});context.drawImage(img,0,0,targetWidth,targetHeight);img.src='';var level=0;function cleanup(){canvas.width=canvas.height=0;canvas=null;}
|
||||
function ensureSizeLimit(resizedBlob){if(resizedBlob.size<limit){cleanup();setTimeout(callback.bind(null,resizedBlob));}else{resizedBlob=null;if(level<qualities.length){canvas.toBlob(ensureSizeLimit,'image/jpeg',qualities[level++]);}else{cleanup();setTimeout(Utils._resizeImageBlobWithRatio.bind(Utils,{blob:blob,limit:limit,ratio:ratio*2,callback:callback}));}}}
|
||||
canvas.toBlob(ensureSizeLimit,blob.type);};},getClosestSampleSize:function ut_getClosestSampleSize(ratio){if(ratio>=8){return 8;}
|
||||
if(ratio>=4){return 4;}
|
||||
if(ratio>=2){return 2;}
|
||||
return 1;},camelCase:function ut_camelCase(str){return str.replace(rdashes,function replacer(str,p1){return p1.toUpperCase();});},typeFromMimeType:function ut_typeFromMimeType(mime){var MAX_MIME_TYPE_LENGTH=256;if(typeof mime!=='string'||mime.length>MAX_MIME_TYPE_LENGTH){return null;}
|
||||
var index=mime.indexOf('/');if(index===-1){return null;}
|
||||
var mainPart=mime.slice(0,index);var secondPart=mime.substr(index+1).toLowerCase();switch(mainPart){case'image':return'img';case'text':if(secondPart.indexOf('vcard')!==-1){return'vcard';}
|
||||
if(secondPart!=='plain'){return'ref';}
|
||||
return mainPart;case'video':case'audio':case'application':return mainPart;default:return null;}},params:function(input){var parsed={};input.replace(rparams,function($0,$1,$2){if($2==='true'){$2=true;}else if($2==='false'){$2=false;}
|
||||
parsed[$1]=$2;});return parsed;},url(base,params){if(base.indexOf('?')===-1){base+='?';}else{base+='&';}
|
||||
for(var key in params){if(params[key]==null){continue;}
|
||||
base+=encodeURIComponent(key)+'='+
|
||||
encodeURIComponent(params[key])+'&';}
|
||||
return base.slice(0,-1);},basicContact:function(number,records){var record;if(Array.isArray(records)){if(records.length>0){record=records[0];}}else if(records!==null){record=records;}
|
||||
if(!record&&!number){return;}
|
||||
var telLength=(record&&record.tel)?record.tel.length:0;var tel;for(var i=0;i<telLength;i++){if(record.tel[i].value===number){tel=record.tel[i];break;}}
|
||||
if(!tel){tel={type:[''],value:number,carrier:''};}
|
||||
var details=Utils.getContactDetails(tel,record);var info=Utils.getDisplayObject(details.title||null,tel);return info;},getDisplayObject:function(theTitle,tel){var number=tel.value;var type=tel.type&&tel.type.length?tel.type[0]:'';var data={name:theTitle||number,number:number,type:type,carrier:tel.carrier||''};if(Settings.supportEmailRecipient){data.email=number;data.emailHTML='';}
|
||||
return data;},asyncLoadRevokeURL:function(url){setTimeout(function(){var image=new Image();image.src=url;image.onload=image.onerror=function revokePhotoURL(){window.URL.revokeObjectURL(this.src);};});},isEmailAddress:function(email){return rmail.test(email);},closeNotificationsForThread:function(threadId){var targetTag='threadId:'+threadId;return Notification.get({tag:targetTag}).then(function onSuccess(notifications){for(var i=0;i<notifications.length;i++){notifications[i].close();}}).catch(function onError(reason){console.error('Notification.get(tag: '+targetTag+'): ',reason);});},debounce:function(func,waitTime){var timeout,args,context;var executeLater=function(){func.apply(context,args);timeout=context=args=null;};return function(){context=this;args=arguments;if(timeout){clearTimeout(timeout);}
|
||||
timeout=setTimeout(executeLater,waitTime);};},throttle:function(func,delay=300,options={}){var timeout=null;var previous=0;var preventFirstCall=!!options.preventFirstCall;var preventLastCall=!!options.preventLastCall;if(typeof func!=='function'){throw new Error('func must be a Function');}
|
||||
if(typeof delay!=='number'||delay<0){throw new Error('delay must be a positive number');}
|
||||
return function(...args){var now=Date.now();if(!previous&&preventFirstCall){previous=now;}
|
||||
var remaining=delay-(now-previous);if(remaining<=0){if(timeout){clearTimeout(timeout);timeout=null;}
|
||||
previous=now;func.apply(this,args);}else if(!timeout&&!preventLastCall){timeout=setTimeout(()=>{previous=preventFirstCall?0:Date.now();timeout=null;func.apply(this,args);},remaining);}};},alert:function(message,title){var deferred=this.Promise.defer();var dialog=new Dialog({title:title||'modal-dialog-default-title',body:message,options:{cancel:{text:'modal-dialog-ok-button',method:deferred.resolve}}});dialog.show();return deferred.promise;},confirm:function(message,title,confirmOptions){var confirmButtonText=confirmOptions&&confirmOptions.text||'modal-dialog-ok-button';var confirmButtonClassName=confirmOptions&&confirmOptions.className||'recommend';var deferred=this.Promise.defer();var dialog=new Dialog({title:title||'modal-dialog-default-title',body:message,options:{cancel:{text:'modal-dialog-cancel-button',method:deferred.reject},confirm:{text:confirmButtonText,className:confirmButtonClassName,method:deferred.resolve}}});dialog.show();return deferred.promise;},Promise:{defer:function(){var deferred={};deferred.promise=new Promise(function(resolve,reject){deferred.resolve=resolve;deferred.reject=reject;});return deferred;},async:function(generatorFunction){return function asyncGenerator(){var generator=generatorFunction.apply(this,arguments);function handle(result){if(result.done){return Promise.resolve(result.value);}
|
||||
return Promise.resolve(result.value).then((result)=>handle(generator.next(result)),(error)=>handle(generator.throw(error)));}
|
||||
try{return handle(generator.next());}catch(error){return Promise.reject(error);}};}},getSimNameByIccId(iccId){var index=Settings.getServiceIdByIccId(iccId);if(index===null){return Promise.resolve('');}
|
||||
return document.l10n.formatValue('sim-id-label',{id:index+1});},initializeShimHost(appInstanceId){var shimHostIframe=document.querySelector('.shim-host');var promise=typeof shimHostIframe.contentWindow.bootstrap==='function'?Promise.resolve():new Promise((resolve)=>{shimHostIframe.addEventListener('load',function onLoad(){shimHostIframe.removeEventListener('load',onLoad);resolve();});});return promise.then(()=>{window.mozSetMessageHandler=function(type,handler){navigator.mozSetMessageHandler(type,(request)=>handler(request));};shimHostIframe.contentWindow.bootstrap(appInstanceId);});},onceDocumentIsVisible(){if(!document.hidden){return Promise.resolve();}
|
||||
var defer=this.Promise.defer();document.addEventListener('visibilitychange',function waitVisibility(){document.removeEventListener('visibilitychange',waitVisibility);defer.resolve();});return defer.promise;}};exports.Utils=Utils;}(this));;(function(window){'use strict';var NavigationFactory=window.NavigationFactory=function(window){const debug=[()=>{},(arg1,...args)=>console.log('[Navigation] '+arg1,...args),(arg1,...args)=>console.log('[Navigation] (%s) '+arg1,Date.now(),...args),][0];const NGA_VIEWS=Object.freeze([Object.freeze({name:'thread',url:'views/conversation/index.html',behavior:'ConversationView',previous:'thread-list'}),Object.freeze({name:'thread-list',url:'views/inbox/index.html',behavior:'InboxView'}),Object.freeze({name:'report-view',behavior:'ReportView',previous:'thread',partOf:'thread'}),Object.freeze({name:'composer',behavior:'ConversationView',previous:'thread-list',partOf:'thread'}),Object.freeze({name:'group-view',behavior:'GroupView',previous:'thread',partOf:'thread'})]);const OA_VIEWS=Object.freeze([Object.freeze({name:'thread-list',url:'index.html',behavior:'InboxView'}),Object.freeze({name:'thread',behavior:'ConversationView',previous:'thread-list',partOf:'thread-list'}),Object.freeze({name:'composer',behavior:'ConversationView',previous:'thread-list',partOf:'thread-list'}),Object.freeze({name:'group-view',behavior:'GroupView',previous:'thread',partOf:'thread-list'}),Object.freeze({name:'report-view',behavior:'ReportView',previous:'thread',partOf:'thread-list'})]);const VIEWS=isUsingOldArchitecture()?OA_VIEWS:NGA_VIEWS;const priv={pendingInit:Symbol('pendingInit')};var currentState;var navigationTransition;function setLocation(url){debug('Setting location',url);window.location.assign(url);}
|
||||
function isUsingOldArchitecture(){debug('isUsingOldArchitecture()');var pathname=window.location.pathname;var result=(pathname==='/'||pathname==='/index.html');debug('isUsingOldArchitecture() =>',result);return result;}
|
||||
function findViewNameFromHash(hash){debug('findViewNameFromHash(%s)',hash);if(!hash||!hash.startsWith('#/')){return null;}
|
||||
var endOfViewName=hash.indexOf('?');if(endOfViewName<0){endOfViewName=undefined;}
|
||||
return hash.slice(2,endOfViewName);}
|
||||
function findViewFromLocation(location){debug('findViewFromLocation(%s)',location.href);var pathName=location.pathname;if(pathName.endsWith('/')){pathName+='index.html';}
|
||||
var hash=location.hash;var viewNameFromHash=findViewNameFromHash(hash);var viewFromHash=findViewFromName(viewNameFromHash);if(viewNameFromHash&&!viewFromHash){console.error('We found no view from the hash %s',hash);return null;}
|
||||
var viewFromPath=VIEWS.find((view)=>pathName.endsWith('/'+view.url))||null;if(!viewFromPath){console.error('We found no view from the path %s',pathName);return null;}
|
||||
if(viewFromHash&&viewFromHash.partOf&&viewFromHash.partOf!==viewFromPath.name){console.error('The view %s found from the hash %s is not part of view %s',viewFromHash.name,hash,viewFromPath.name);viewFromHash=null;}
|
||||
return viewFromHash||viewFromPath;}
|
||||
function findViewFromName(name){debug('findViewFromName(%s)',name);var view=VIEWS.find((view)=>view.name===name)||null;debug('findViewFromName() => %s',view&&view.name);return view;}
|
||||
function findContainerView(view){debug('findContainerView(%s)',view.name);if(view.partOf){debug('findContainerView: %s is part of view %s',view.name,view.partOf);view=findViewFromName(view.partOf);}
|
||||
debug('findContainerView() => %s',view.name);return view;}
|
||||
var readyDefer=Utils.Promise.defer();function waitForReady(){if(!readyDefer){return Promise.reject(new Error('waitForReady was called but status is ready already.'));}
|
||||
return readyDefer.promise;}
|
||||
function startNavigationFromCurrentLocation(){var location=window.location;debug('startNavigationFromCurrentLocation(), location=%s',location);var newPanel=findViewFromLocation(location);if(!newPanel){return Promise.reject(new Error('Couldn\'t find a view from location '+location.href));}
|
||||
var args=Utils.params(decodeURIComponent(location.hash));debug('startNavigationFromCurrentLocation:','found panel',newPanel.name,'with args',args);return startNavigation({newPanel,args});}
|
||||
function startNavigation(opts){var{newPanel,args,partial}=opts;args=args||{};debug('startNavigation(newPanel=%s, partial=%s)',newPanel&&newPanel.name,partial);if(navigationTransition&&(!navigationTransition.partial||partial)){debug('startNavigation: previous navigation exists, deferring.');return navigationTransition.defer.promise.then(()=>startNavigation(opts));}
|
||||
var newContainerView=newPanel&&findContainerView(newPanel);var containerView=currentState&&findContainerView(currentState.panel);var leaveDocument=currentState&&containerView!==newContainerView;if(newPanel&&!leaveDocument){var behaviorObject=window[newPanel.behavior];var viewReady=behaviorObject&&(typeof behaviorObject.isReady!=='function'||behaviorObject.isReady());if(!viewReady){return waitForReady().then(()=>startNavigation(opts));}}
|
||||
document.activeElement.blur();if(!navigationTransition){navigationTransition={stepsRun:[],defer:Utils.Promise.defer()};}
|
||||
navigationTransition.partial=partial;navigationTransition.leaveDocument=leaveDocument;if('meta'in args){throw new Error('Arguments cannot have a `meta` property.');}
|
||||
navigationTransition.transitionArgs={meta:{next:newPanel?{panel:newPanel.name,args}:null,prev:currentState?{panel:currentState.panel.name,args:currentState.args}:null}};Object.assign(navigationTransition.transitionArgs,args);navigationTransition.states={from:currentState,to:{panel:newPanel,args}};return Promise.resolve();}
|
||||
function setFutureState(){debug('setFutureState()');currentState=navigationTransition.states.to;}
|
||||
function endNavigation(){debug('endNavigation()');if(navigationTransition){navigationTransition.defer.resolve();navigationTransition=null;}}
|
||||
function onNavigationError(e=new Error('RejectedPromise')){console.error('Navigation error',e);endNavigation();return Promise.reject(e);}
|
||||
function catchStepError(e){if(e){console.error('[Navigation] got an exception: (%s) %s',e,e.stack&&e.stack.replace(/\n/g,'|'));}else{debug('[Navigation] got a rejected promise');}}
|
||||
function executeNavigationStep(stepName){debug('executeNavigationStep(%s)',stepName);if(!navigationTransition){return Promise.reject(new Error('Trying to execute the navigation step '+stepName+' but no transition is started yet.'));}
|
||||
if(navigationTransition.stepsRun.indexOf(stepName)>=0){debug('executeNavigationStep: step %s has already run.',stepName);return Promise.resolve();}
|
||||
var stateKey=stepName.endsWith('Leave')?'from':'to';var state=navigationTransition.states[stateKey];if(!state){debug('Nothing to execute for step',stepName);return Promise.resolve();}
|
||||
var panel=state.panel;var resultPromise=Promise.resolve();var viewObject=window[panel.behavior];if(viewObject[stepName]){resultPromise=resultPromise.then(()=>viewObject[stepName](navigationTransition.transitionArgs));}
|
||||
return resultPromise.then(()=>{navigationTransition.stepsRun.push(stepName);debug(`Finished executeNavigationStep(${stepName})`);});}
|
||||
var previousAnimationDefer;function waitForPanelAnimation(panelElement){if(previousAnimationDefer){previousAnimationDefer.reject(new Error('A new animation started'));}
|
||||
var defer=Utils.Promise.defer();previousAnimationDefer=defer;var timeout;function onAnimationEnd(e){panelElement.removeEventListener('animationend',onAnimationEnd);clearTimeout(timeout);debug('animationend',e&&e.type);defer.resolve();}
|
||||
panelElement.addEventListener('animationend',onAnimationEnd);timeout=setTimeout(onAnimationEnd,500);return defer.promise.then(()=>previousAnimationDefer=null);}
|
||||
function switchPanel(){debug('switchPanel()');if(!navigationTransition){throw new Error('Trying to switch panel but no transition is started yet.');}
|
||||
var from=navigationTransition.states.from;var to=navigationTransition.states.to;var oldView;var oldPanelElement;if(from){oldView=from.panel;oldPanelElement=document.querySelector(`.panel-${oldView.behavior}`);if(!oldPanelElement){throw new Error('Couldn\'t find the container element for view '+oldView.name);}}
|
||||
var newView=to.panel;if(!newView){throw new Error('Trying to switch panel, but no new view is defined!');}
|
||||
var newPanelElement=document.querySelector(`.panel-${newView.behavior}`);if(!newPanelElement){return Promise.reject(new Error('Couldn\'t find the container element for view '+newView.name));}
|
||||
if(newPanelElement===oldPanelElement){return Promise.resolve();}
|
||||
var isGoingBack=oldView&&oldView.previous===newView.name;newPanelElement.style='';newPanelElement.classList.remove('panel-hidden');newPanelElement.classList.add('panel-active');var doSlideAnimation=from&&from.panel&&from.panel.behavior!==newView.behavior;var doFadeInAnimation=!from||!from.panel;var animationPromise;if(doSlideAnimation){var shouldGoRight=isGoingBack^(document.dir==='rtl');newPanelElement.style.animationName=shouldGoRight?'left-to-current':'right-to-current';oldPanelElement.style.animationName=shouldGoRight?'current-to-right':'current-to-left';}else if(doFadeInAnimation){newPanelElement.style.animationName='fade-in';}
|
||||
if(doFadeInAnimation||doSlideAnimation){animationPromise=waitForPanelAnimation(newPanelElement).catch(()=>{}).then(()=>{if(oldPanelElement){oldPanelElement.style='';}
|
||||
newPanelElement.style='';});}
|
||||
return(animationPromise||Promise.resolve()).then(()=>{if(oldPanelElement){oldPanelElement.classList.remove('panel-active');oldPanelElement.setAttribute('aria-hidden','true');}
|
||||
newPanelElement.setAttribute('aria-hidden','false');});}
|
||||
function onHashChange(){debug('onHashChange, location=',window.location);startNavigationFromCurrentLocation().then(()=>executeNavigationStep('beforeLeave')).then(()=>executeNavigationStep('beforeEnter').catch(catchStepError)).then(setFutureState).then(switchPanel).then(()=>executeNavigationStep('afterEnter').catch(catchStepError)).then(()=>executeNavigationStep('afterLeave').catch(catchStepError)).then(endNavigation).then(()=>Navigation.emit('navigated')).catch(onNavigationError);}
|
||||
function attachHistoryListener(){window.addEventListener('hashchange',onHashChange);}
|
||||
function detachHistoryListener(){window.removeEventListener('hashchange',onHashChange);}
|
||||
var Navigation={back(){debug('back()');return startNavigation({partial:true}).then(()=>executeNavigationStep('beforeLeave')).then(()=>window.history.back()).then(()=>navigationTransition.defer.promise,onNavigationError);},toPanel(viewName,args){debug('toPanel(%s)',viewName);var view=findViewFromName(viewName);if(!view){return Promise.reject(new Error(`Couldn't find view ${viewName}`));}
|
||||
if(this.isCurrentPanel(viewName,args)){debug('View %s is the current view.',viewName);return Promise.resolve();}
|
||||
if(navigationTransition){debug('toPanel: previous navigation exists, deferring.');return navigationTransition.defer.promise.then(()=>this.toPanel(viewName,args));}
|
||||
this[priv.pendingInit]=false;var hash='#';if(view.partOf){hash+='/'+viewName;}
|
||||
hash=Utils.url(hash,args);return startNavigation({newPanel:view,args,partial:true}).then(()=>executeNavigationStep('beforeLeave')).then(()=>{var nextLocation;if(navigationTransition.leaveDocument){var containerView=findContainerView(view);nextLocation='/'+containerView.url+hash;}else{nextLocation=hash;}
|
||||
setLocation(nextLocation);}).then(()=>navigationTransition.defer.promise,onNavigationError);},init(){debug('init()');attachHistoryListener();if(navigator.mozHasPendingMessage('notification')){this[priv.pendingInit]=true;return Promise.reject();}
|
||||
this[priv.pendingInit]=false;return startNavigationFromCurrentLocation().then(setFutureState).then(()=>executeNavigationStep('beforeEnter').catch(catchStepError)).then(switchPanel).then(()=>executeNavigationStep('afterEnter').catch(catchStepError)).then(endNavigation).then(()=>Navigation.emit('navigated')).catch(onNavigationError);},[priv.pendingInit]:false,hasPendingInit(){return this[priv.pendingInit];},cleanup(){detachHistoryListener();},isDefaultPanel(){return currentState?!currentState.panel.partOf:!findViewNameFromHash(window.location.hash);},isCurrentPanel(panelName,args){debug('isCurrentPanel(%s)',panelName);if(!currentState||!panelName){return false;}
|
||||
if(panelName!==currentState.panel.name){return false;}
|
||||
if(!args){return true;}
|
||||
var currentArgs=currentState.args||{};for(var arg in args){if(args[arg]!=currentArgs[arg]){return false;}}
|
||||
return true;},setReady(){debug('setReady()');Array.from(document.querySelectorAll('.panel-hidden')).forEach((panel)=>{panel.classList.remove('panel-hidden');});readyDefer.resolve();readyDefer=null;}};return EventDispatcher.mixin(Navigation,['navigated']);};window.Navigation=NavigationFactory(window);})(window);;(function(exports){'use strict';var channel=null;const BROADCAST_CHANNEL_NAME='messages-channel';const ALLOWED_EVENTS=['draft-saved','draft-deleted'];function postMessage(name,parameters){if(!channel){throw new Error('Channel is not created!');}
|
||||
if(!name){throw new Error('Name should be defined!');}
|
||||
channel.postMessage(parameters!==undefined?{name:name,parameters:parameters}:{name:name});}
|
||||
const Dispatcher=EventDispatcher.mixin({connect:function(){if(channel){return;}
|
||||
channel=new BroadcastChannel(BROADCAST_CHANNEL_NAME);channel.addEventListener('message',onMessage);exports.addEventListener('unload',()=>this.disconnect());},disconnect:function(){if(!channel){return;}
|
||||
channel.close();channel.removeEventListener('message',onMessage);channel=null;}},ALLOWED_EVENTS);const originalEmitter=Dispatcher.emit.bind(Dispatcher);Dispatcher.emit=function(eventName,parameters){if(ALLOWED_EVENTS.indexOf(eventName)<0){throw new Error('Event "'+eventName+'" is not allowed!');}
|
||||
postMessage(eventName,parameters);};function onMessage(message){try{originalEmitter(message.data.name,message.data.parameters);}catch(error){console.error('Error while emitting event "%s" with parameters "%s"',message.data&&message.data.name,JSON.stringify(message.data&&message.data.parameters),error);}}
|
||||
exports.InterInstanceEventDispatcher=Dispatcher;})(window);;(function(exports){'use strict';var updateTimer=null;var TimeHeaders={init:function th_init(){onvisibilityChange();document.addEventListener('visibilitychange',onvisibilityChange);window.addEventListener('timeformatchange',ontimeFormatChange);window.addEventListener('languagechange',onlanguageChange);},startScheduler:function th_startScheduler(){var now=Date.now(),nextTimeout=new Date(now+60000);nextTimeout.setSeconds(0);nextTimeout.setMilliseconds(0);this.stopScheduler();updateTimer=setTimeout(function(){this.updateAll('header[data-time-update=repeat]');this.startScheduler();}.bind(this),nextTimeout.getTime()-now);},stopScheduler:function th_stopScheduler(){clearTimeout(updateTimer);},updateAll:function th_updateAll(selector){selector=selector||'[data-time-update]';var elements=document.querySelectorAll(selector),length=elements.length,i;for(i=0;i<length;i++){this.update(elements[i]);}},update:function th_update(element){var ts=element.dataset.time;if(!ts){return;}
|
||||
if(element.dataset.dateOnly==='true'){Utils.setHeaderDate({time:ts,element:element,withTime:false});}else if(element.dataset.timeOnly==='true'){element.removeAttribute('data-l10n-id');element.textContent=Utils.getFormattedHour(ts);}else{Utils.setHeaderDate({time:ts,element:element,withTime:true});}}};function onvisibilityChange(){if(document.hidden){TimeHeaders.stopScheduler();}
|
||||
else{TimeHeaders.updateAll();TimeHeaders.startScheduler();}}
|
||||
function ontimeFormatChange(){Utils.resetDateFormatters();TimeHeaders.updateAll();}
|
||||
function onlanguageChange(){Utils.resetDateFormatters();TimeHeaders.updateAll();}
|
||||
exports.TimeHeaders=TimeHeaders;}(this));;(function(exports){'use strict';var unknownNumbers=[];var filterFns={contains:function(a,b){a=a.toLowerCase();b=b.toLowerCase();return a.includes(b);},equality:function(a,b){a=a.toLowerCase();b=b.toLowerCase();return a===b;}};function isMatch(contact,criteria,filterFn){var found={};outer:for(var i=0,ilen=criteria.terms.length;i<ilen;i++){var term=criteria.terms[i];for(var j=0,jlen=criteria.fields.length;j<jlen;j++){var field=criteria.fields[j];if(!contact[field]){continue;}
|
||||
for(var k=0,klen=contact[field].length;k<klen;k++){var value=contact[field][k];if(typeof value.value!=='undefined'){value=value.value;}
|
||||
if((found[term]=filterFn(value.trim(),term))){continue outer;}}}}
|
||||
return Object.keys(found).every(function(key){return found[key];});}
|
||||
var rspaces=/\s+/;var Contacts={findBy:function contacts_findBy(filter,callback){var lower=[];var filterValue=(filter.filterValue||'').trim();var terms;if(!navigator.mozContacts||!filterValue.length){return Promise.resolve([]);}
|
||||
terms=filterValue.split(rspaces);filter.filterValue=terms.length===1?terms[0]:terms.reduce(function(initial,term){lower.push(term.toLowerCase());return term.length>initial.length?term:initial;},'');if(filter.filterValue.length<3){filter.filterLimit=10;}
|
||||
lower.splice(lower.indexOf(filter.filterValue.toLowerCase()),1);lower.push.apply(lower,terms);return navigator.mozContacts.find(filter).then((contacts)=>{var results;if(terms.length>1){var fields=['tel','givenName','familyName'];if(Settings.supportEmailRecipient){fields.push('email');}
|
||||
var criteria={fields:fields,terms:lower};results=contacts.filter((contact)=>isMatch(contact,criteria,filterFns.contains));}else{results=contacts;}
|
||||
return results;}).catch((e)=>{console.error('Got an error while looking up contacts.',e.name,e);return[];});},findByString:function contacts_findByString(filterValue){return Promise.all([this.findContactByString(filterValue),this.findByUnknown(filterValue)]).then(([known,unknown])=>{return(known||[]).concat(unknown);});},findContactByString:function contacts_findContactByString(filterValue){var props=['tel','givenName','familyName'];if(Settings.supportEmailRecipient){props.push('email');}
|
||||
return this.findBy({filterBy:props,filterOp:'contains',filterValue:filterValue});},findByUnknown:function contacts_findByUnknown(filterValue){var list=[];for(var i=0,length=unknownNumbers.length;i<length;i++){if(list.length>2){break;}
|
||||
var num=unknownNumbers[i];if(num.includes(filterValue)){var obj={name:[num],tel:[{value:num}],source:'unknown'};list.push(obj);}}
|
||||
return Promise.resolve(list);},findExact:function contacts_findExact(filterValue){return this.findBy({filterBy:['givenName','familyName'],filterOp:'contains',filterValue:filterValue}).then((contacts)=>{var contact=contacts.length?contacts[0]:null;var criteria={fields:['name'],terms:[filterValue]};var isExact=false;if(contact){isExact=isMatch(contact,criteria,filterFns.equality);}
|
||||
return isExact?[contact]:[];});},findByPhoneNumber:function contacts_findByPhone(filterValue){return this.findBy({filterBy:['tel'],filterOp:'match',filterValue:filterValue.replace(/\s+/g,'')}).then((contacts)=>{if(contacts.length){return contacts;}
|
||||
var defer=Utils.Promise.defer();fb.getContactByNumber(filterValue,function fbByPhone(fbContact){defer.resolve(fbContact?[fbContact]:[]);},function error_fbByPhone(err){if(err.name!=='DatastoreNotFound'){console.error('Error while retrieving fb by phone: ',err.name);}
|
||||
defer.resolve([]);});return defer.promise;});},findByAddress:function contacts_findByAddress(fValue){if(Settings.supportEmailRecipient&&Utils.isEmailAddress(fValue)){return this.findExactByEmail(fValue);}else{return this.findByPhoneNumber(fValue);}},findExactByEmail:function contacts_findExactByEmail(fValue){return this.findBy({filterBy:['email'],filterOp:'equals',filterValue:fValue});},addUnknown:function addUnknown(number){var index=unknownNumbers.indexOf(number);if(index===-1){unknownNumbers.push(number);}},clearUnknown:function clearUnknown(){unknownNumbers.length=0;},getunknownLength:function getunknownLength(){return unknownNumbers.length;}};exports.Contacts=Contacts;}(this));;(function(exports){'use strict';[['asyncStorage','/shared/js/async_storage.js'],['EventDispatcher','/shared/js/event_dispatcher.js'],['Utils','/views/shared/js/utils.js']].forEach(([dependencyName,dependencyPath])=>{if(!(dependencyName in self)){importScripts(dependencyPath);}});var draftIndex=new Map();var deferredDraftRequest=null;var Drafts={get size(){return draftIndex.size;},init(){InterInstanceEventDispatcher.on('draft-saved',(draft)=>this.request(true).then(()=>this.emit('saved',draft)));InterInstanceEventDispatcher.on('draft-deleted',(draft)=>this.request(true).then(()=>this.emit('deleted',draft)));},add:function(draft){if(!draft||!(draft instanceof Draft)){throw new Error('Draft should be valid Draft instance.');}
|
||||
this.delete(draft);var drafts=draftIndex.get(draft.threadId)||[];drafts.push(draft);draftIndex.set(draft.threadId,drafts);this.emit('saved',draft);InterInstanceEventDispatcher.emit('draft-saved',draft);return this;},delete:function(draft){if(!draft||!(draft instanceof Draft)){throw new Error('Draft should be valid Draft instance.');}
|
||||
var drafts=draftIndex.get(draft.threadId);if(!drafts||!drafts.length){return this;}
|
||||
var isDeleted=false;if(draft.threadId){drafts.length=0;isDeleted=true;}else{var indexToRemove=drafts.findIndex((storedDraft)=>storedDraft.id===draft.id);if(indexToRemove>-1){isDeleted=true;drafts.splice(indexToRemove,1);}}
|
||||
if(isDeleted){this.emit('deleted',draft);InterInstanceEventDispatcher.emit('draft-deleted',draft);}
|
||||
return this;},byThreadId:function(threadId){if(!threadId){throw new Error('Thread Id is not defined');}
|
||||
var threadDrafts=draftIndex.get(threadId);return threadDrafts&&threadDrafts.length?threadDrafts[threadDrafts.length-1]:null;},byDraftId:function(id){id=+id;for(var draft of this.getAllThreadless()){if(draft.id===id){return draft;}}
|
||||
return null;},getAll:function*(){for(var[threadId,drafts]of draftIndex){yield*threadId?drafts.slice(-1):drafts;}},getAllThreadless:function(){return draftIndex.get(null)||[];},clear:function(){draftIndex=new Map();deferredDraftRequest=null;return this;},store:function(){var defer=Utils.Promise.defer();asyncStorage.setItem('draft index',[...draftIndex],()=>{defer.resolve();});return defer.promise;},request:function(force){if(deferredDraftRequest&&!force){return deferredDraftRequest.promise;}
|
||||
deferredDraftRequest=Utils.Promise.defer();asyncStorage.getItem('draft index',function(records){records&&records.forEach((record)=>{record[1]=record[1].map((draft)=>new Draft(draft));});draftIndex=new Map(records||[]);deferredDraftRequest.resolve();});return deferredDraftRequest.promise;}};exports.Drafts=EventDispatcher.mixin(Drafts,['saved','deleted']);function Draft(opts){var draft=opts||{};if(draft.id&&typeof draft.id!=='number'){throw new Error('Draft id must be a number');}
|
||||
this.id=draft.id||guid();this.recipients=draft.recipients||[];this.content=draft.content||[];this.subject=draft.subject||'';this.timestamp=+draft.timestamp||Date.now();this.threadId=draft.threadId||null;this.type=draft.type;this.isEdited=false;}
|
||||
function guid(){return+(Date.now()+''+(Math.random()*1000|0));}
|
||||
exports.Draft=Draft;}(this));;(function(exports){'use strict';var threads=new Map();var messageMap=new Map();function Thread(thread){var length=Thread.FIELDS.length;var key;for(var i=0;i<length;i++){key=Thread.FIELDS[i];this[key]=thread[key];}
|
||||
this.messages=new Map();}
|
||||
Thread.prototype.getDraft=function(){return this.isDraft?Drafts.byDraftId(this.id):Drafts.byThreadId(this.id);};Thread.FIELDS=['body','id','lastMessageSubject','lastMessageType','participants','timestamp','unreadCount','isDraft'];Thread.fromMessage=function(record,options){var participants=[];if(typeof record.delivery!=='undefined'){if(record.delivery==='received'||record.delivery==='not-downloaded'){participants=[record.sender];}else{participants=record.receivers||[record.receiver];}}
|
||||
return new Thread({id:record.threadId,participants:participants,body:record.body,timestamp:record.timestamp,unreadCount:(options&&options.unread)?1:0,lastMessageType:record.type||'sms',isDraft:false});};Thread.fromDraft=function(draft,options){var participants=draft.recipients&&draft.recipients.length?draft.recipients:[''];var body=draft.content&&draft.content.length?draft.content.find(function(content){if(typeof content==='string'){return true;}}):'';return new Thread({id:draft.threadId||draft.id,participants:participants,body:body,timestamp:new Date(draft.timestamp),unreadCount:(options&&options.unread)?1:0,lastMessageType:draft.type||'sms',isDraft:true});};Thread.create=function(record,options){if(record instanceof Thread){return record;}
|
||||
return record.delivery?Thread.fromMessage(record,options):Thread.fromDraft(record,options);};var Threads=exports.Threads={registerMessage:function(message){var threadId=+message.threadId;var messageId=+message.id;if(!this.has(threadId)){this.set(threadId,Thread.create(message));}
|
||||
this.get(threadId).messages.set(messageId,message);messageMap.set(messageId,threadId);},unregisterMessage:function(id){id=+id;var threadId=messageMap.get(id);if(this.has(threadId)){this.get(threadId).messages.delete(id);}
|
||||
messageMap.delete(id);},set:function(id,thread){var old,length,key;id=+id;if(threads.has(id)){old=threads.get(id);length=Thread.FIELDS.length;for(var i=0;i<length;i++){key=Thread.FIELDS[i];old[key]=thread[key];}
|
||||
return threads;}
|
||||
return threads.set(id,new Thread(thread));},get:function(id){return threads.get(+id);},has:function(id){return threads.has(+id);},delete:function(id){id=+id;var thread=this.get(id);if(!thread){return;}
|
||||
threads.delete(id);var draft=thread.getDraft();if(draft){Drafts.delete(draft).store();}},clear:function(){threads=new Map();},forEach:function(callback){threads.forEach(function(v,k){callback(v,k);});},keys:function(){return threads.keys();},get size(){if(typeof threads.size==='function'){return+threads.size();}
|
||||
return+threads.size;}};Threads.Messages={get(id){id=+id;var threadId=messageMap.get(id);if(Threads.has(threadId)){return Threads.get(threadId).messages.get(id);}
|
||||
return null;}};exports.Thread=Thread;}(this));;(function(exports){'use strict';const privateMembers=new WeakMap();function createBdiNode(content){var bdi=document.createElement('bdi');bdi.textContent=content;return bdi;}
|
||||
var InboxView={DRAFT_SAVED_DURATION:5000,FIRST_PANEL_THREAD_COUNT:9,timeouts:{onDraftSaved:null},count:0,inEditMode:false,notifyAboutSavedDraftWithId:null,init:function inbox_init(){this.tmpl={thread:Template('messages-thread-tmpl')};['container','no-messages','read-unread-button','check-uncheck-all-button','composer-link','delete-button','edit-header','options-button','settings-button','edit-mode','edit-form','draft-saved-banner'].forEach(function(id){this[Utils.camelCase(id)]=document.getElementById('threads-'+id);},this);this.mainWrapper=document.getElementById('main-wrapper');this.composerLink.addEventListener('click',this.launchComposer.bind(this));this.readUnreadButton.addEventListener('click',()=>{this.markReadUnread(this.selectionHandler.selectedList,this.readUnreadButton.dataset.action==='mark-as-read');});this.deleteButton.addEventListener('click',()=>{this.delete(this.selectionHandler.selectedList);});this.editHeader.addEventListener('action',this.cancelEdit.bind(this));this.optionsButton.addEventListener('click',this.showOptions.bind(this));this.settingsButton.addEventListener('click',function oSettings(){ActivityPicker.openSettings();});this.container.addEventListener('click',this);this.container.addEventListener('contextmenu',this);this.editForm.addEventListener('submit',this);navigator.mozContacts.addEventListener('contactchange',this.updateContactsInfo.bind(this));MessageManager.on('message-sending',this.onMessageSending.bind(this));MessageManager.on('message-received',this.onMessageReceived.bind(this));MessageManager.on('threads-deleted',this.onThreadsDeleted.bind(this));Drafts.on('deleted',this.onDraftDeleted.bind(this));Drafts.on('saved',this.onDraftSaved.bind(this));privateMembers.set(this,{groupThreadTitleMaxLength:(window.innerWidth-100)/10});this.once('fully-loaded',()=>{this.ensureReadAheadSetting();});this.once('visually-loaded',()=>{this.initStickyHeader();});this.sticky=null;},initStickyHeader:function inbox_initStickyHeader(){if(!this.sticky){this.sticky=new StickyHeader(this.container,document.getElementById('sticky'));}},beforeEnter:function inbox_beforeEnter(args={}){if(this.notifyAboutSavedDraftWithId){this.showDraftSavedBanner();this.notifyAboutSavedDraftWithId=null;}},beforeLeave:function inbox_beforeLeave(){this.cancelEdit();},getIdIterator:function inbox_getIdIterator(){return Threads.keys();},setContact:function inbox_setContact(node){var threadId=node.dataset.threadId;var draftId=node.dataset.draftId;var threadOrDraft=draftId?Drafts.byDraftId(+draftId):Threads.get(+threadId);if(!threadOrDraft){throw new Error('Thread node is invalid!');}
|
||||
var threadNumbers=threadOrDraft.participants||threadOrDraft.recipients;var titleContainer=node.querySelector('.threadlist-item-title');var title=titleContainer.firstElementChild;var picture=node.querySelector('.threadlist-item-picture');if(!threadNumbers||!threadNumbers.length){title.setAttribute('data-l10n-id','no-recipient');return;}
|
||||
function*updateThreadNode(number){var contact=yield InboxView.findContact(number,{photoURL:true});var isContact=!!contact.isContact;picture.classList.toggle('has-picture',isContact);picture.classList.toggle('default-picture',isContact&&!contact.photoURL);title.textContent=contact.title||number;var photoUrl=node.dataset.photoUrl;if(photoUrl){window.URL.revokeObjectURL(photoUrl);}
|
||||
if(contact.photoURL){node.dataset.photoUrl=contact.photoURL;}else if(photoUrl){node.dataset.photoUrl='';}
|
||||
if(contact.photoURL){picture.firstElementChild.style.backgroundImage=['url('+contact.photoURL+')','url(/views/inbox/style/images/default_contact_image.png)'].join(', ');}else{picture.firstElementChild.style.backgroundImage=null;}}
|
||||
function*updateGroupThreadNode(numbers,titleMaxLength){var contactTitle,number;var i=0;var threadTitleLength=0;var groupTitle=document.createElement('span');var separatorNode=document.createElement('span');separatorNode.setAttribute('data-l10n-id','thread-participant-separator');picture.firstElementChild.textContent=numbers.length;picture.classList.add('has-picture','group-picture');while(i<numbers.length&&threadTitleLength<titleMaxLength){number=numbers[i++];contactTitle=(yield InboxView.findContact(number)).title||number;if(threadTitleLength>0){groupTitle.appendChild(separatorNode.cloneNode(true));}
|
||||
groupTitle.appendChild(createBdiNode(contactTitle));threadTitleLength+=contactTitle.length;}
|
||||
titleContainer.replaceChild(groupTitle,title);}
|
||||
if(!title.textContent){title.textContent=threadNumbers[0];}
|
||||
if(threadNumbers.length===1){return Utils.Promise.async(updateThreadNode)(threadNumbers[0]);}
|
||||
return Utils.Promise.async(updateGroupThreadNode)(threadNumbers,privateMembers.get(this).groupThreadTitleMaxLength);},findContact:function(number,options){return Contacts.findByAddress(number).then(function(contacts){var details=Utils.getContactDetails(number,contacts,options);if(!details.isContact){Contacts.addUnknown(number);}
|
||||
return details;});},handleEvent:function inbox_handleEvent(event){var parent=event.target.parentNode;var threadId=parent.dataset.threadId;switch(event.type){case'click':if(this.inEditMode){return;}
|
||||
if(threadId){event.preventDefault();var draftId=parent.dataset.draftId;if(draftId){Navigation.toPanel('composer',{draftId:+draftId,});}else{Navigation.toPanel('thread',{id:+threadId});}}
|
||||
break;case'contextmenu':if(this.inEditMode||!threadId){return;}
|
||||
event.preventDefault();event.stopPropagation();var params={type:'action',header:{l10nId:'thread-options'},items:[{l10nId:'delete-thread',method:this.delete.bind(this,[threadId])}]};var thread=Threads.get(+threadId);if(!thread.isDraft){var isRead=thread.unreadCount>0;var l10nKey=isRead?'mark-as-read':'mark-as-unread';params.items.push({l10nId:l10nKey,method:this.markReadUnread.bind(this,[threadId],isRead)});}
|
||||
params.items.push({l10nId:'cancel'});var options=new OptionMenu(params);options.show();break;case'submit':event.preventDefault();break;}},launchComposer:function inbox_launchComposer(e){e.preventDefault();Navigation.toPanel('composer');},updateSelectionStatus:function inbox_updateSelectionStatus(){var selected=this.selectionHandler;if(this.selectionHandler.allSelected()){this.checkUncheckAllButton.setAttribute('data-l10n-id','deselect-all');}else{this.checkUncheckAllButton.setAttribute('data-l10n-id','select-all');}
|
||||
if(selected.selectedCount){this.deleteButton.disabled=false;document.l10n.setAttributes(this.editMode,'selected-threads',{n:selected.selectedCount});var hasUnreadselected=selected.selectedList.some((id)=>{var thread=Threads.get(id);if(thread&&thread.unreadCount){return thread.unreadCount>0;}
|
||||
return false;});var allDraft=selected.selectedList.every((id)=>{return(Threads.get(id).isDraft);});if(allDraft){this.readUnreadButton.disabled=true;}else{if(!hasUnreadselected){this.readUnreadButton.dataset.action='mark-as-unread';}else{this.readUnreadButton.dataset.action='mark-as-read';}
|
||||
this.readUnreadButton.disabled=false;}}else{this.deleteButton.disabled=true;this.readUnreadButton.disabled=true;document.l10n.setAttributes(this.editMode,'selectThreads-title');}},markReadUnread:function inbox_markReadUnread(selected,isRead){selected.forEach((id)=>{var thread=Threads.get(+id);var readStatusMatched=!!thread.unreadCount^isRead;var markable=thread&&!thread.isDraft&&(isRead||!thread.getDraft());if(markable&&!readStatusMatched){thread.unreadCount=isRead?0:1;this.mark(thread.id,isRead?'read':'unread');MessageManager.markThreadRead(thread.id,isRead);}});this.cancelEdit();},removeConversationDOM(conversationId){var li=document.getElementById('thread-'+conversationId);var parent;var photoUrl=li&&li.dataset.photoUrl;if(photoUrl){window.URL.revokeObjectURL(photoUrl);}
|
||||
if(li){parent=li.parentNode;li.remove();}
|
||||
if(parent&&!parent.firstElementChild){parent.previousSibling.remove();parent.remove();this.sticky&&this.sticky.refresh();if(!this.container.querySelector('li')){this.setEmpty(true);}}},delete:function inbox_delete(selected){function performDeletion(){var threadIdsToDelete=[],messageIdsToDelete=[],threadCountToDelete=0;function exitEditMode(){InboxView.cancelEdit();WaitingScreen.hide();}
|
||||
function onAllThreadMessagesRetrieved(){if(!--threadCountToDelete){MessageManager.deleteMessages(messageIdsToDelete);threadIdsToDelete.forEach(function(threadId){InboxView.deleteThread(threadId);});messageIdsToDelete=threadIdsToDelete=null;exitEditMode();}}
|
||||
function onThreadMessageRetrieved(message){messageIdsToDelete.push(message.id);return true;}
|
||||
WaitingScreen.show();threadIdsToDelete=selected.reduce(function(list,value){var threadId=+value;if(Threads.get(threadId).isDraft){InboxView.deleteThread(threadId);}else{list.push(threadId);}
|
||||
return list;},[]);if(!threadIdsToDelete.length){exitEditMode();return;}
|
||||
threadCountToDelete=threadIdsToDelete.length;threadIdsToDelete.forEach(function(threadId){MessageManager.getMessages({filter:{threadId:threadId},each:onThreadMessageRetrieved,end:onAllThreadMessagesRetrieved});});}
|
||||
return Utils.confirm({id:'deleteThreads-confirmation-message',args:{n:selected.length}},null,{text:'delete',className:'danger'}).then(performDeletion.bind(this));},setEmpty:function inbox_setEmpty(empty){var panel=document.querySelector('.panel-InboxView');panel.classList.toggle('threadlist-is-empty',!!empty);},showOptions:function inbox_options(){var params={items:[{l10nId:'selectThreads-label',method:this.startEdit.bind(this)},{l10nId:'settings',method:function oSettings(){ActivityPicker.openSettings();}},{l10nId:'cancel',incomplete:true}]};new OptionMenu(params).show();},startEdit:function inbox_edit(){function editModeSetup(){this.inEditMode=true;this.selectionHandler.cleanForm();this.mainWrapper.classList.toggle('edit');}
|
||||
this.editHeader.removeAttribute('no-font-fit');if(!this.selectionHandler){LazyLoader.load(['/views/shared/js/selection_handler.js','/shared/style/edit_mode.css','/shared/style/switches.css','/views/shared/style/edit-mode.css','/shared/style/tabs.css','/views/inbox/style/edit-mode.css'],()=>{this.selectionHandler=new SelectionHandler({container:this.container,checkUncheckAllButton:this.checkUncheckAllButton,updateSelectionStatus:this.updateSelectionStatus.bind(this),getIdIterator:this.getIdIterator.bind(this),isInEditMode:this.isInEditMode.bind(this)});this.editForm.classList.remove('hide');editModeSetup.call(this);});}else{editModeSetup.call(this);}},isInEditMode:function inbox_isInEditMode(){return this.inEditMode;},cancelEdit:function inbox_cancelEdit(){this.inEditMode=false;this.mainWrapper.classList.remove('edit');},renderDrafts:function inbox_renderDrafts(){return Drafts.request().then(()=>{for(var draft of Drafts.getAll()){if(draft.threadId){if(document.getElementById(`thread-${draft.threadId}`)){this.updateThread(Threads.get(draft.threadId),{conversationDraft:true});}}else{this.setEmpty(false);if(!Threads.has(draft.id)){var thread=Thread.create(draft);Threads.set(draft.id,thread);this.appendThread(thread);}}}
|
||||
this.sticky&&this.sticky.refresh();});},prepareRendering:function inbox_prepareRendering(){this.container.innerHTML='';this.renderDrafts();},startRendering:function inbox_startRenderingThreads(){this.setEmpty(false);},finalizeRendering:function inbox_finalizeRendering(empty){if(empty){this.setEmpty(true);}
|
||||
if(!empty){TimeHeaders.updateAll('header[data-time-update]');}
|
||||
this.sticky&&this.sticky.refresh();},ensureReadAheadSetting:function inbox_ensureReadAheadSettting(){Settings.setReadAheadThreadRetrieval(this.FIRST_PANEL_THREAD_COUNT);},renderThreads:function inbox_renderThreads(){window.performance.mark('willRenderThreads');var hasThreads=false;var firstPanelCount=this.FIRST_PANEL_THREAD_COUNT;this.prepareRendering();function onRenderThread(thread){Threads.set(thread.id,thread);if(!hasThreads){hasThreads=true;this.startRendering();}
|
||||
this.appendThread(thread);if(--firstPanelCount===0){this.emit('visually-loaded');}}
|
||||
function onThreadsRendered(){this.finalizeRendering(!(hasThreads||Drafts.size));if(firstPanelCount>0){this.emit('visually-loaded');}}
|
||||
MessageManager.getThreads({each:onRenderThread.bind(this),end:onThreadsRendered.bind(this),done:()=>Drafts.request().then(()=>this.emit('fully-loaded'))});},updateConversationContent(node,record){var id=record.id;var thread=Threads.get(id);var isDraft=thread.isDraft;var draft=thread.getDraft();var body=record.body;var type=record.lastMessageType;var iconLabel='';if(draft&&draft.timestamp>=record.timestamp){body=draft.content.find((content)=>typeof content==='string');type=draft.type;}
|
||||
node.dataset.lastMessageType=type;if(draft){node.classList.add('draft');if(isDraft){node.dataset.draftId=draft.id;node.classList.add('is-draft');iconLabel='is-draft';}else{node.classList.add('has-draft');iconLabel='has-draft';}}else{node.classList.remove('draft','has-draft','is-draft');}
|
||||
if(record.unreadCount>0){node.classList.add('unread');iconLabel='unread-thread';}else{node.classList.remove('unread');}
|
||||
node.querySelector('.js-conversation-body').textContent=body||'';var stateIndicator=node.querySelector('.js-conversation-state');if(iconLabel){document.l10n.setAttributes(stateIndicator,iconLabel);}else{stateIndicator.removeAttribute('data-l10n-id');}},createThread:function inbox_createThread(record){var li=document.createElement('li');var timestamp=+record.timestamp;var id=record.id;var thread=Threads.get(id);var isDraft=thread.isDraft;var draft=thread.getDraft();li.id='thread-'+id;li.dataset.threadId=id;li.dataset.time=timestamp;li.classList.add('threadlist-item');li.innerHTML=this.tmpl.thread.interpolate({hash:isDraft?'#/composer':'#/thread?id='+id,mode:isDraft?'drafts':'threads',id:String(isDraft?draft.id:id),timestamp:String(timestamp)},{safe:['id']});this.updateConversationContent(li,record);TimeHeaders.update(li.querySelector('time'));return li;},deleteThread:function(threadId){Threads.delete(threadId);this.removeConversationDOM(threadId);Utils.closeNotificationsForThread(threadId);},insertThreadContainer:function inbox_insertThreadContainer(group,timestamp){var headers=InboxView.container.getElementsByTagName('header');var groupFound=false;for(var i=0;i<headers.length;i++){if(timestamp>=headers[i].dataset.time){groupFound=true;InboxView.container.insertBefore(group,headers[i].parentNode);break;}}
|
||||
if(!groupFound){InboxView.container.appendChild(group);}},updateThread(record,options={}){var thread=Thread.create(record,options);var threadUINode=document.getElementById('thread-'+thread.id);var threadUITime=threadUINode?+threadUINode.dataset.time:NaN;var recordTime=+thread.timestamp;Threads.set(thread.id,thread);var newMessageReceived=options.unread;if(newMessageReceived&&threadUITime>recordTime){this.mark(thread.id,'unread');return;}
|
||||
if(options.deleted&&threadUITime===recordTime){return;}
|
||||
if(threadUINode&&options.conversationDraft){this.updateConversationContent(threadUINode,record);return;}
|
||||
if(threadUINode){this.removeConversationDOM(thread.id);}
|
||||
this.setEmpty(false);if(this.appendThread(thread)){this.sticky&&this.sticky.refresh();}},onMessageSending:function inbox_onMessageSending(e){this.updateThread(e.message);},onMessageReceived:function inbox_onMessageReceived(e){var markAsRead=Navigation.isCurrentPanel('thread',{id:e.message.threadId});this.updateThread(e.message,{unread:!markAsRead});},onThreadsDeleted:function inbox_onThreadDeleted(e){e.ids.forEach(function(threadId){if(Threads.has(threadId)){this.deleteThread(threadId);}},this);},appendThread:function inbox_appendThread(thread){var timestamp=+thread.timestamp;var firstThreadInContainer=false;var node=this.createThread(thread);this.setContact(node);var threadsContainerID='threadsContainer_'+
|
||||
Utils.getDayDate(timestamp);var threadsContainer=document.getElementById(threadsContainerID);if(!threadsContainer){var threadsContainerWrapper=InboxView.createThreadContainer(timestamp);threadsContainer=threadsContainerWrapper.childNodes[1];InboxView.insertThreadContainer(threadsContainerWrapper,timestamp);firstThreadInContainer=true;}
|
||||
var threads=threadsContainer.getElementsByTagName('li');var threadFound=false;for(var i=0,l=threads.length;i<l;i++){if(timestamp>threads[i].dataset.time){threadFound=true;threadsContainer.insertBefore(node,threads[i]);break;}}
|
||||
if(!threadFound){threadsContainer.appendChild(node);}
|
||||
if(this.inEditMode){this.selectionHandler.unselect(thread.id);this.updateSelectionStatus();}
|
||||
return firstThreadInContainer;},createThreadContainer:function inbox_createThreadContainer(timestamp){var threadContainer=document.createElement('div');var headerDOM=document.createElement('header');headerDOM.id='header_'+timestamp;headerDOM.dataset.timeUpdate='repeat';headerDOM.dataset.time=timestamp;headerDOM.dataset.dateOnly=true;var threadsContainerDOM=document.createElement('ul');threadsContainerDOM.id='threadsContainer_'+
|
||||
Utils.getDayDate(timestamp);Utils.setHeaderDate({time:timestamp,element:headerDOM});threadContainer.appendChild(headerDOM);threadContainer.appendChild(threadsContainerDOM);return threadContainer;},updateContactsInfo:function inbox_updateContactsInfo(){Contacts.clearUnknown();if(!this.container){return;}
|
||||
var threads=this.container.getElementsByTagName('li');[].forEach.call(threads,this.setContact.bind(this));},mark:function inbox_mark(id,current){var li=document.getElementById('thread-'+id);if(li){li.classList.toggle('unread',current==='unread');}},onDraftDeleted:function inbox_onDraftDeleted(draft){var thread=Threads.get(draft.threadId||draft.id);if(!thread){return;}
|
||||
if(thread.isDraft){this.deleteThread(thread.id);}else{this.updateThread(thread,{conversationDraft:true});}
|
||||
if(draft.id===this.notifyAboutSavedDraftWithId){this.notifyAboutSavedDraftWithId=null;}},onDraftSaved:function inbox_onDraftSaved(draft){if(draft.threadId){this.updateThread(Threads.get(draft.threadId),{conversationDraft:true});}else{this.updateThread(draft);}
|
||||
if(!Navigation.isCurrentPanel('thread-list')){this.notifyAboutSavedDraftWithId=draft.id;}},showDraftSavedBanner:function(){this.draftSavedBanner.classList.remove('hide');clearTimeout(this.timeouts.onDraftSaved);this.timeouts.onDraftSaved=null;this.timeouts.onDraftSaved=setTimeout(()=>this.draftSavedBanner.classList.add('hide'),this.DRAFT_SAVED_DURATION);}};exports.InboxView=EventDispatcher.mixin(InboxView,['visually-loaded','fully-loaded']);}(this));;'use strict';var Settings={SERVICE_ID_KEYS:{mmsServiceId:'ril.mms.defaultServiceId',smsServiceId:'ril.sms.defaultServiceId'},READ_AHEAD_THREADS_KEY:'ril.sms.maxReadAheadEntries',MMS_SIZE_OVERHEAD:5*1024,_serviceIds:null,supportEmailRecipient:true,maxConcatenatedMessages:10,mmsSizeLimitation:295*1024,mmsServiceId:null,smsServiceId:null,init:function settings_init(){var keyHandlerSet={'dom.mms.operatorSizeLimitation':this.initMmsSizeLimitation.bind(this),'operatorResource.sms.maxConcat':this.initSmsMaxConcatenatedMsg.bind(this)};var settings=navigator.mozSettings;var conns=navigator.mozMobileConnections;function setHandlerMap(key){var req=settings.createLock().get(key);req.onsuccess=function settings_getSizeSuccess(){var handler=keyHandlerSet[key];handler(req.result[key]);};}
|
||||
this._serviceIds=[];if(!settings){return;}
|
||||
if(conns&&conns.length>1){for(var prop in this.SERVICE_ID_KEYS){var setting=this.SERVICE_ID_KEYS[prop];keyHandlerSet[setting]=this.initServiceId.bind(this,setting,prop);}
|
||||
for(var i=0,l=conns.length;i<l;i++){this._serviceIds.push(conns[i].iccId);}}
|
||||
for(var key in keyHandlerSet){setHandlerMap(key);}},initSmsMaxConcatenatedMsg:function initSmsMaxConcatenatedMsg(num){if(num&&!isNaN(num)){this.maxConcatenatedMessages=num;}},initMmsSizeLimitation:function initMmsSizeLimitation(size){if(size&&!isNaN(size)){this.mmsSizeLimitation=size-this.MMS_SIZE_OVERHEAD;}},initServiceId:function initMmsServiceId(settingName,propName,id){if(id!==undefined){Settings[propName]=id;}
|
||||
navigator.mozSettings.addObserver(settingName,function(e){Settings[propName]=e.settingValue;});},setMmsSimServiceId:function setSimServiceId(id){navigator.mozSettings.createLock().set({'ril.mms.defaultServiceId':id,'ril.data.defaultServiceId':id});},switchMmsSimHandler:function switchSimHandler(targetId){var conn=window.navigator.mozMobileConnections[targetId];return new Promise(function(resolve,reject){if(conn){if(conn.data.state==='registered'){resolve();}else{conn.addEventListener('datachange',function onDataChange(){if(conn.data.state==='registered'){conn.removeEventListener('datachange',onDataChange);resolve();}});this.setMmsSimServiceId(targetId);}}else{reject('Invalid connection');}}.bind(this));},isDualSimDevice:function isDualSimDevice(){return this._serviceIds&&this._serviceIds.length>1;},hasSeveralSim:function hasSeveralSim(){if(!this.isDualSimDevice()){return false;}
|
||||
var simCount=this._serviceIds.reduce(function(simCount,iccId){return iccId===null?simCount:simCount+1;},0);return simCount>1;},getServiceIdByIccId:function getServiceIdByIccId(iccId){if(!this._serviceIds){return null;}
|
||||
var index=this._serviceIds.indexOf(iccId);return index>-1?index:null;},setReadAheadThreadRetrieval:function(value){if(!navigator.mozSettings){return;}
|
||||
var setting={};setting[this.READ_AHEAD_THREADS_KEY]=value;navigator.mozSettings.createLock().set(setting);}};;'use strict';(function(exports){var MessageManager={init:function mm_init(){this._mozMobileMessage=navigator.mozMobileMessage;this._mozMobileMessage.addEventListener('received',this.onMessageReceived.bind(this));this._mozMobileMessage.addEventListener('sending',this.onMessageSending.bind(this));this._mozMobileMessage.addEventListener('sent',this.onMessageSent.bind(this));this._mozMobileMessage.addEventListener('failed',this.onMessageFailed.bind(this));this._mozMobileMessage.addEventListener('readsuccess',this.onReadSuccess.bind(this));this._mozMobileMessage.addEventListener('deliverysuccess',this.onDeliverySuccess.bind(this));this._mozMobileMessage.addEventListener('deleted',this.onDeleted.bind(this));},onMessageSending:function mm_onMessageSending(e){Threads.registerMessage(e.message);this.emit('message-sending',{message:e.message});},onMessageFailed:function mm_onMessageFailed(e){this.emit('message-failed-to-send',{message:e.message});},onDeliverySuccess:function mm_onDeliverySuccess(e){this.emit('message-delivered',{message:e.message});},onReadSuccess:function mm_onReadSuccess(e){this.emit('message-read',{message:e.message});},onMessageSent:function mm_onMessageSent(e){this.emit('message-sent',{message:e.message});},onMessageReceived:function mm_onMessageReceived(e){var message=e.message;if(message.messageClass&&message.messageClass==='class-0'){return;}
|
||||
if(message.delivery==='not-downloaded'&&message.deliveryInfo[0].deliveryStatus==='pending'){return;}
|
||||
Threads.registerMessage(message);this.emit('message-received',{message:message});},onDeleted:function(e){if(e.deletedThreadIds&&e.deletedThreadIds.length){this.emit('threads-deleted',{ids:e.deletedThreadIds});}},getThreads:function mm_getThreads(options){var each=options.each;var end=options.end;var done=options.done;var cursor=null;try{cursor=this._mozMobileMessage.getThreads();}catch(e){console.error('Error occurred while retrieving threads:',e.name,e);end&&end();done&&done();return;}
|
||||
cursor.onsuccess=function onsuccess(){if(this.result){each&&each(this.result);this.continue();return;}
|
||||
end&&end();done&&done();};cursor.onerror=function onerror(){console.error('Reading the database. Error: '+this.error.name);done&&done();};},getMessage:function mm_getMsg(id){return this._mozMobileMessage.getMessage(id);},retrieveMMS:function mm_retrieveMMS(id){return this._mozMobileMessage.retrieveMMS(id);},getMessages:function mm_getMgs(options){var each=options.each;var invert=options.invert;var end=options.end;var endArgs=options.endArgs;var done=options.done;var filter=options.filter;var cursor=this._mozMobileMessage.getMessages(filter,!invert);cursor.onsuccess=function onsuccess(){if(!this.done){var shouldContinue=true;if(each){shouldContinue=each(this.result);}
|
||||
if(shouldContinue!==false){this.continue();}else{done&&done();}}else{end&&end(endArgs);done&&done();}};cursor.onerror=function onerror(){var msg='Reading the database. Error: '+this.error.name;console.log(msg);done&&done();};},_sanitizeServiceId:function mm_sanitizeServiceId(serviceId){if(serviceId==null||isNaN(+serviceId)){serviceId=null;}else{serviceId=+serviceId;}
|
||||
return serviceId;},_getSendOptionsFromServiceId:function mm_gSOFSI(serviceId){var sendOpts;if(serviceId!=null&&Settings.hasSeveralSim()){sendOpts={serviceId:serviceId};}
|
||||
return sendOpts;},sendSMS:function mm_send(opts){var recipients=opts.recipients||[],content=opts.content,serviceId=this._sanitizeServiceId(opts.serviceId),onsuccess=opts.onsuccess,onerror=opts.onerror,oncomplete=opts.oncomplete;if(!Array.isArray(recipients)){recipients=[recipients];}
|
||||
var i=0;var requestResult={hasError:false,return:[]};var sendOpts=this._getSendOptionsFromServiceId(serviceId);var requests=this._mozMobileMessage.send(recipients,content,sendOpts);var numberOfRequests=requests.length;requests.forEach(function(request,idx){request.onsuccess=function onSuccess(event){onsuccess&&onsuccess(event.target.result);requestResult.return.push({success:true,result:event.target.result,recipient:recipients[idx]});if(i===numberOfRequests-1){oncomplete&&oncomplete(requestResult);}
|
||||
i++;};request.onerror=function onError(event){console.error('Error Sending: '+JSON.stringify(event.target.error));onerror&&onerror(event.target.error);requestResult.hasError=true;requestResult.return.push({success:false,code:event.target.error,recipient:recipients[idx]});if(i===numberOfRequests-1){oncomplete&&oncomplete(requestResult);}
|
||||
i++;};});},sendMMS:function mm_sendMMS(opts){var request;var recipients=opts.recipients,subject=opts.subject,content=opts.content,serviceId=opts.serviceId=this._sanitizeServiceId(opts.serviceId),onsuccess=opts.onsuccess,onerror=opts.onerror;if(!Array.isArray(recipients)){recipients=[recipients];}
|
||||
var message=SMIL.generate(content);var sendOpts=this._getSendOptionsFromServiceId(serviceId);request=this._mozMobileMessage.sendMMS({receivers:recipients,subject:subject,smil:message.smil,attachments:message.attachments},sendOpts);request.onsuccess=function onSuccess(event){onsuccess&&onsuccess(event.target.result);};request.onerror=function onError(event){onerror&&onerror(event.target.error);};},resendMessage:function mm_resendMessage(opts){var message=opts.message;if(!message){throw new Error('Message to resend is not defined.');}
|
||||
var serviceId=Settings.getServiceIdByIccId(message.iccId);var sendOpts=this._getSendOptionsFromServiceId(serviceId);var onsuccess=opts.onsuccess;var onerror=opts.onerror;var request;if(message.type==='sms'){request=this._mozMobileMessage.send(message.receiver,message.body,sendOpts);}
|
||||
if(message.type==='mms'){request=this._mozMobileMessage.sendMMS({receivers:message.receivers,subject:message.subject,smil:message.smil,attachments:message.attachments},sendOpts);}
|
||||
request.onsuccess=function onSuccess(evt){MessageManager.deleteMessages(message.id);onsuccess&&onsuccess(evt.target.result);};request.onerror=function onError(evt){MessageManager.deleteMessages(message.id);onerror&&onerror(evt.target.error);};},deleteMessages:function mm_deleteMessages(id){return this._mozMobileMessage.delete(id).then(null,(e)=>{console.error(`Deleting in the database. [${e.name}] ${e.message || ''}`);return null;});},markThreadRead:function mm_markThreadRead(threadId,isRead=true){var filter={};filter.threadId=+threadId;filter.read=!isRead;var messagesUnreadIDs=[];var changeStatusOptions={each:function addUnreadMessage(message){messagesUnreadIDs.push(message.id);return true;},filter:filter,invert:true,end:function handleUnread(){MessageManager.markMessagesRead(messagesUnreadIDs,isRead);}};MessageManager.getMessages(changeStatusOptions);},markMessagesRead:function mm_markMessagesRead(list,isRead=true){if(!this._mozMobileMessage||!list.length){return;}
|
||||
var id=list.pop();var req=this._mozMobileMessage.markMessageRead(id,isRead,true);req.onsuccess=(function onsuccess(){if(!list.length||!isRead){return;}else if(isRead){this.markMessagesRead(list,isRead);}}).bind(this);req.onerror=function onerror(){console.error('Error while marking message %d as read: %s',id,this.error.name);};},getSegmentInfo:function mm_getSegmentInfo(text){if(!(this._mozMobileMessage&&this._mozMobileMessage.getSegmentInfoForText)){return Promise.reject(new Error('mozMobileMessage is unavailable.'));}
|
||||
var defer=Utils.Promise.defer();var request=this._mozMobileMessage.getSegmentInfoForText(text);request.onsuccess=function onsuccess(e){defer.resolve(e.target.result);};request.onerror=function onerror(e){defer.reject(e.target.error);};return defer.promise;},_isMessageBelongTo1to1Conversation:function isMessageBelongTo1to1Conversation(number,message){var isIncoming=message.delivery==='received'||message.delivery==='not-downloaded';if(isIncoming){return Utils.probablyMatches(message.sender,number);}else{switch(message.type){case'sms':return Utils.probablyMatches(message.receiver,number);case'mms':return message.receivers.length===1&&Utils.probablyMatches(message.receivers[0],number);default:console.error('Got an unknown message type: '+message.type);return false;}}},findThreadFromNumber:function mm_findThread(number){function checkCandidate(message){var isMessageInThread=MessageManager._isMessageBelongTo1to1Conversation(number,message);if(isMessageInThread){threadId=message.threadId;return false;}}
|
||||
var threadId=null;var deferred=Utils.Promise.defer();MessageManager.getMessages({filter:{numbers:[number]},each:checkCandidate,done:function(){if(threadId==null){deferred.reject(new Error('No thread found for number: '+number));return;}else{deferred.resolve(threadId);return;}}});return deferred.promise;},ensureThreadRegistered(threadId){var getOneMessageForThread=(threadId)=>{var defer=Utils.Promise.defer();this.getMessages({each:function(message){defer.resolve(message);return false;},done:function(){defer.reject(new Error('found no message'));},filter:{threadId:threadId}});return defer.promise;};if(Threads.has(threadId)){return Promise.resolve();}
|
||||
return getOneMessageForThread(threadId).then((message)=>Threads.registerMessage(message));}};Object.defineProperty(exports,'MessageManager',{get:function(){delete exports.MessageManager;exports.MessageManager=EventDispatcher.mixin(MessageManager,['message-sending','message-failed-to-send','message-delivered','message-read','message-sent','message-received','threads-deleted']);return exports.MessageManager;},configurable:true,enumerable:true});})(window);;(function(exports){'use strict';const APPLICATION_READY_CLASS_NAME='js-app-ready';const INSTANCE_ID=Date.now();var app={isReady:function app_isReady(){return document.body.classList.contains(APPLICATION_READY_CLASS_NAME);},setReady:function app_setReady(){if(this.isReady()){throw new Error('Application should be marked as ready only once!');}
|
||||
document.body.classList.add(APPLICATION_READY_CLASS_NAME);if(navigator.mozAudioChannelManager){navigator.mozAudioChannelManager.volumeControlChannel='notification';}},whenReady:function whenReady(){if(this.isReady()){return Promise.resolve();}
|
||||
return new Promise(function(resolve,reject){var bodyClassObserver=new MutationObserver(function(){try{if(this.isReady()){bodyClassObserver.disconnect();resolve();}}catch(e){reject(e);}}.bind(this));bodyClassObserver.observe(document.body,{attributes:true,attributeFilter:['class']});}.bind(this));},get instanceId(){return INSTANCE_ID;}};exports.App=app;})(this);;'use strict';(function(exports){var debug=0?(arg1,...args)=>console.log('[Startup] '+arg1,...args):()=>{};var Startup=exports.Startup={_lazyLoadScripts:['/shared/js/settings_listener.js','/shared/js/mime_mapper.js','/shared/js/notification_helper.js','/shared/js/option_menu.js','/shared/js/gesture_detector.js','/shared/js/settings_url.js','/shared/js/mobile_operator.js','/shared/js/multi_sim_action_button.js','/shared/js/image_utils.js','/shared/elements/gaia_sim_picker/script.js','/views/shared/js/waiting_screen.js','/views/shared/js/errors.js','/views/shared/js/dialog.js','/views/shared/js/error_dialog.js','/views/conversation/js/link_helper.js','/views/conversation/js/link_action_handler.js','/views/shared/js/contact_renderer.js','/views/shared/js/activity_picker.js','/views/conversation/js/information.js','/views/shared/js/shared_components.js','/views/shared/js/task_runner.js','/views/shared/js/silent_sms.js','/views/conversation/js/recipients.js','/views/conversation/js/attachment.js','/views/conversation/js/attachment_renderer.js','/views/conversation/js/conversation.js','/views/conversation/js/subject_composer.js','/views/conversation/js/compose.js','/views/shared/js/wbmp.js','/views/shared/js/smil.js','/views/shared/js/notify.js','/views/shared/js/activity_handler.js','/views/shared/js/system_message_handler.js','/views/shared/js/localization_helper.js','/lib/bridge/client.js','/services/js/activity/activity_client.js','/services/js/messaging/messaging_client.js','/services/js/moz_mobile_connections/moz_mobile_connections_client.js'],_lazyLoadStyles:['/shared/style/confirm.css','/shared/style/status.css','/shared/style/input_areas.css','/shared/style/progress_activity.css','/views/shared/style/composer.css','/views/conversation/style/message.css','/views/conversation/style/report_view.css','/views/conversation/style/attachment.css','/views/conversation/style/conversation.css','/views/new_message/style/new_message.css','/views/new_message/style/recipients.css'],_lazyLoadInit:function(){var lazyLoadPromise=LazyLoader.load([...this._lazyLoadScripts,...this._lazyLoadStyles]).then(()=>{LocalizationHelper.init();InterInstanceEventDispatcher.connect();SilentSms.init();if(navigator.mozHasPendingMessage('activity')){ActivityHandler.init();}else{SystemMessageHandler.init();}
|
||||
TimeHeaders.init();ConversationView.init();MessagingClient.init(App.instanceId);MozMobileConnectionsClient.init(App.instanceId);Information.initDefaultViews();Navigation.setReady();window.performance.mark('contentInteractive');Settings.init();window.performance.mark('objectsInitEnd');});return lazyLoadPromise;},init:function(){var loaded=function(){window.removeEventListener('DOMContentLoaded',loaded);window.performance.mark('navigationLoaded');Utils.initializeShimHost(App.instanceId);MessageManager.init();Drafts.init();InboxView.init();Navigation.init();InboxView.once('fully-loaded',()=>{window.performance.mark('fullyLoaded');App.setReady();});InboxView.once('visually-loaded',()=>{window.performance.mark('visuallyLoaded');});if(Navigation.isDefaultPanel()&&!navigator.mozHasPendingMessage('notification')&&!navigator.mozHasPendingMessage('activity')){debug('Rendering threads now.');InboxView.once('visually-loaded',()=>{this._lazyLoadInit();});InboxView.renderThreads();}else{debug('Not using default panel, waiting for navigated event');Navigation.once('navigated',()=>InboxView.renderThreads());this._lazyLoadInit();}
|
||||
window.performance.mark('navigationInteractive');}.bind(this);window.addEventListener('DOMContentLoaded',loaded);}};Startup.init();})(window);
|
||||
BIN
assets/webapps/sms.gaiamobile.org/icons/sms_126.png
Normal file
BIN
assets/webapps/sms.gaiamobile.org/icons/sms_126.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
BIN
assets/webapps/sms.gaiamobile.org/icons/sms_142.png
Normal file
BIN
assets/webapps/sms.gaiamobile.org/icons/sms_142.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
BIN
assets/webapps/sms.gaiamobile.org/icons/sms_189.png
Normal file
BIN
assets/webapps/sms.gaiamobile.org/icons/sms_189.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.4 KiB |
BIN
assets/webapps/sms.gaiamobile.org/icons/sms_284.png
Normal file
BIN
assets/webapps/sms.gaiamobile.org/icons/sms_284.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.3 KiB |
BIN
assets/webapps/sms.gaiamobile.org/icons/sms_84.png
Normal file
BIN
assets/webapps/sms.gaiamobile.org/icons/sms_84.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
623
assets/webapps/sms.gaiamobile.org/index.html
Normal file
623
assets/webapps/sms.gaiamobile.org/index.html
Normal file
|
|
@ -0,0 +1,623 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en-US" dir="ltr">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
|
||||
<meta charset="utf-8">
|
||||
<meta name="theme-group" content="theme-communications">
|
||||
<meta name="theme-color" content="var(--header-background)">
|
||||
<title>Messages</title>
|
||||
<!--App Style root.css-->
|
||||
<link rel="stylesheet" type="text/css" href="views/shared/style/root.css">
|
||||
<!-- Stable Building blocks -->
|
||||
<link rel="stylesheet" type="text/css" href="shared/style/animations.css">
|
||||
<link rel="stylesheet" type="text/css" href="shared/style/action_menu.css">
|
||||
<link rel="stylesheet" type="text/css" href="shared/style/option_menu.css">
|
||||
<link rel="stylesheet" type="text/css" href="shared/style/buttons.css">
|
||||
<link rel="stylesheet" type="text/css" href="shared/style/lists.css">
|
||||
<link rel="stylesheet" type="text/css" href="shared/elements/gaia-icons/gaia-icons.css">
|
||||
<!-- App styles -->
|
||||
<link rel="stylesheet" type="text/css" href="views/shared/style/sms.css">
|
||||
<link rel="stylesheet" type="text/css" href="views/shared/style/panel.css">
|
||||
<link rel="stylesheet" type="text/css" href="views/shared/style/notification.css">
|
||||
<link rel="stylesheet" type="text/css" href="views/shared/style/common.css">
|
||||
<link rel="stylesheet" type="text/css" href="views/inbox/style/inbox.css">
|
||||
<!-- Lazy load styles
|
||||
<link rel="stylesheet" type="text/css" href="shared/style/confirm.css">
|
||||
<link rel="stylesheet" type="text/css" href="shared/style/edit_mode.css">
|
||||
<link rel="stylesheet" type="text/css" href="shared/style/input_areas.css">
|
||||
<link rel="stylesheet" type="text/css" href="shared/style/switches.css">
|
||||
<link rel="stylesheet" type="text/css" href="shared/style/progress_activity.css">
|
||||
<link rel="stylesheet" type="text/css" href="shared/style/status.css">
|
||||
<link rel="stylesheet" type="text/css" href="shared/style/tabs.css" >
|
||||
<link rel="stylesheet" type="text/css" href="views/shared/style/edit-mode.css">
|
||||
<link rel="stylesheet" type="text/css" href="views/shared/style/composer.css">
|
||||
<link rel="stylesheet" type="text/css" href="views/conversation/style/message.css">
|
||||
<link rel="stylesheet" type="text/css" href="views/conversation/style/report_view.css">
|
||||
<link rel="stylesheet" type="text/css" href="views/conversation/style/attachment.css">
|
||||
<link rel="stylesheet" type="text/css" href="views/conversation/style/conversation.css">
|
||||
<link rel="stylesheet" type="text/css" href="views/conversation/style/edit-mode.css">
|
||||
<link rel="stylesheet" type="text/css" href="views/new_message/style/new_message.css">
|
||||
<link rel="stylesheet" type="text/css" href="views/new_message/style/recipients.css">
|
||||
<link rel="stylesheet" type="text/css" href="views/inbox/style/edit-mode.css">
|
||||
-->
|
||||
|
||||
<!-- Localization -->
|
||||
<meta name="defaultLanguage" content="en-US">
|
||||
<meta name="availableLanguages" content="ar:201601260729, bg:201601260729, bn-BD:201601260729, ca:201601260729, cs:201601260729, da:201601260729, de:201601260729, el:201601260729, en-US:201601260729, es:201601260729, eu:201601260729, fr:201601260729, gl:201601260729, hr:201601260729, hu:201601260729, it:201601260729, ja:201601260729, km:201601260729, ko:201601260729, lt:201601260729, mk:201601260729, ms:201601260729, ne-NP:201601260729, nl:201601260729, pa:201601260729, pl:201601260729, pt-BR:201601260729, ro:201601260729, ru:201601260729, sk:201601260729, sq:201601260729, sr-Cyrl:201601260729, sr-Latn:201601260729, sv-SE:201601260729, tr:201601260729, zh-CN:201601260729, zh-TW:201601260729">
|
||||
<link rel="localization" href="/locales-obj/index.{locale}.json">
|
||||
|
||||
|
||||
<!-- ICC manager shim for desktop and B2GDroid -->
|
||||
<!-- <script defer="" src="mocks/navigator_moz_icc_manager.js"></script> -->
|
||||
<!-- Firefox Desktop shims -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Web Components -->
|
||||
<!-- <script defer="" src="/shared/elements/config.js"></script> -->
|
||||
<link rel="stylesheet" type="text/css" href="app://theme.gaiamobile.org/shared/elements/gaia-theme/gaia-theme.css">
|
||||
<script async="" src="/shared/elements/gaia-header/dist/gaia-header.js"></script>
|
||||
|
||||
|
||||
<!--
|
||||
<script defer src="shared/js/component_utils.js"></script>
|
||||
<script defer src="shared/elements/gaia_menu/script.js"></script>
|
||||
<script defer src="shared/elements/gaia_sim_picker/script.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="shared/elements/gaia_menu/style.css">
|
||||
<link rel="stylesheet" type="text/css" href="shared/elements/gaia_sim_picker/style.css">
|
||||
-->
|
||||
<!-- Shared code -->
|
||||
<!-- <script defer="" src="shared/js/intl/l20n.js"></script> -->
|
||||
<!-- Should be removed when bug 1172732 lands -->
|
||||
<!-- <script defer="" src="shared/js/date_time_helper.js"></script> -->
|
||||
<!-- <script defer="" src="shared/js/template.js"></script> -->
|
||||
<!-- <script defer="" src="shared/js/async_storage.js"></script> -->
|
||||
<!-- <script defer="" src="shared/js/lazy_loader.js"></script> -->
|
||||
<!-- <script defer="" src="shared/js/sticky_header.js"></script> -->
|
||||
<!-- <script defer="" src="shared/js/contact_photo_helper.js"></script> -->
|
||||
<!-- <script defer="" src="shared/js/fb/fb_request.js"></script> -->
|
||||
<!-- <script defer="" src="shared/js/fb/fb_data_reader.js"></script> -->
|
||||
<!-- <script defer="" src="shared/js/fb/fb_reader_utils.js"></script> -->
|
||||
<!-- <script defer="" src="shared/js/event_dispatcher.js"></script> -->
|
||||
<!-- <script defer="" src="views/shared/js/utils.js"></script> -->
|
||||
<!-- <script defer="" src="views/shared/js/navigation.js"></script> -->
|
||||
<!-- <script defer="" src="views/shared/js/inter_instance_event_dispatcher.js"></script> -->
|
||||
<!-- <script defer="" src="views/shared/js/time_headers.js"></script> -->
|
||||
<!-- <script defer="" src="views/shared/js/contacts.js"></script> -->
|
||||
<!-- <script defer="" src="services/js/drafts.js"></script> -->
|
||||
<!-- <script defer="" src="services/js/threads.js"></script> -->
|
||||
<!-- <script defer="" src="views/inbox/js/inbox.js"></script> -->
|
||||
<!-- <script defer="" src="views/shared/js/settings.js"></script> -->
|
||||
<!-- <script defer="" src="services/js/message_manager.js"></script> -->
|
||||
<!-- <script defer="" src="views/shared/js/app.js"></script> -->
|
||||
<!-- <script defer="" src="views/shared/js/startup.js"></script> --><script src="./gaia_build_defer_index.js" defer="" type="text/javascript"></script>
|
||||
<!-- Lazy load scripts
|
||||
<script defer src="shared/js/notification_helper.js"></script>
|
||||
<script defer src="shared/js/gesture_detector.js"></script>
|
||||
<script defer src="shared/js/settings_url.js"></script>
|
||||
<script defer src="shared/js/mime_mapper.js"></script>
|
||||
<script defer src="shared/js/mobile_operator.js"></script>
|
||||
<script defer src="shared/js/settings_listener.js"></script>
|
||||
<script defer src="shared/js/multi_sim_action_button.js"></script>
|
||||
<script defer src="shared/js/option_menu.js"></script>
|
||||
<script defer src="shared/js/image_utils.js"></script>
|
||||
<script defer src="views/shared/js/errors.js"></script>
|
||||
<script defer src="views/shared/js/shared_components.js"></script>
|
||||
<script defer src="views/shared/js/dialog.js"></script>
|
||||
<script defer src="views/shared/js/error_dialog.js"></script>
|
||||
<script defer src="views/shared/js/task_runner.js"></script>
|
||||
<script defer src="views/shared/js/silent_sms.js"></script>
|
||||
<script defer src="views/conversation/js/recipients.js"></script>
|
||||
<script defer src="views/conversation/js/attachment.js"></script>
|
||||
<script defer src="views/conversation/js/attachment_renderer.js"></script>
|
||||
<script defer src="views/conversation/js/conversation.js"></script>
|
||||
<script defer src="views/conversation/js/subject_composer.js"></script>
|
||||
<script defer src="views/conversation/js/compose.js"></script>
|
||||
<script defer src="views/shared/js/waiting_screen.js"></script>
|
||||
<script defer src="views/shared/js/activity_picker.js"></script>
|
||||
<script defer src="views/shared/js/wbmp.js"></script>
|
||||
<script defer src="views/shared/js/smil.js"></script>
|
||||
<script defer src="views/conversation/js/link_helper.js"></script>
|
||||
<script defer src="views/conversation/js/link_action_handler.js"></script>
|
||||
<script defer src="views/shared/js/notify.js"></script>
|
||||
<script defer src="lib/bridge/client.js"></script>
|
||||
<script defer src="services/js/activity/activity_client.js"></script>
|
||||
<script defer src="services/js/messaging/messaging_client.js"></script>
|
||||
<script defer src="services/js/moz_mobile_connections/moz_mobile_connections_client.js"></script>
|
||||
<script defer src="views/shared/js/activity_handler.js"></script>
|
||||
<script defer src="views/shared/js/system_message_handler.js"></script>
|
||||
<script defer src="views/shared/js/contact_renderer.js"></script>
|
||||
<script defer src="views/shared/js/localization_helper.js"></script>
|
||||
<script defer src="views/conversation/js/information.js"></script>
|
||||
-->
|
||||
<meta content="2.5" name="appVersion"></head>
|
||||
|
||||
<body role="application" class="skin-comms theme-communications">
|
||||
<iframe src="/views/shared/shim_host.html" class="shim-host" hidden=""></iframe>
|
||||
<article id="main-wrapper" class="wrapper">
|
||||
<section class="panel panel-InboxView panel-hidden" role="region" aria-hidden="true">
|
||||
<!-- title-start and title-end indicates the button widths respectively
|
||||
at the start and end of the line -->
|
||||
<!-- see https://github.com/gaia-components/gaia-header/ for more information -->
|
||||
<!-- WARNING: the actual value depends on the actual CSS being used in gaia-header -->
|
||||
<gaia-header class="view-header regular-header" title-start="0" title-end="100">
|
||||
<h1 data-l10n-id="messages">Messages</h1>
|
||||
<a aria-label="New message" href="#/composer" id="threads-composer-link" data-icon="compose" data-l10n-id="composeLink"></a>
|
||||
<a aria-label="Actions" id="threads-options-button" data-icon="more" data-l10n-id="actionsButton"></a>
|
||||
<a aria-label="Settings" id="threads-settings-button" data-icon="settings" data-l10n-id="settingsButton"></a>
|
||||
</gaia-header>
|
||||
<article id="threads-container" class="view-body edit-container" data-type="list">
|
||||
</article>
|
||||
|
||||
<div id="threads-no-messages">
|
||||
<div id="no-result-message">
|
||||
<p data-l10n-id="noMessages-title">No messages</p>
|
||||
<p data-l10n-id="noMessages-text-2">Start a conversation now</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form id="threads-edit-form" role="dialog" data-type="edit" class="hide">
|
||||
<section role="region" class="theme-settings">
|
||||
<gaia-header id="threads-edit-header" action="close" no-font-fit="">
|
||||
<h1 id="threads-edit-mode" data-l10n-id="selectThreads-title">Select</h1>
|
||||
<button id="threads-check-uncheck-all-button" class="edit-button" data-l10n-id="select-all">Select all</button>
|
||||
</gaia-header>
|
||||
</section>
|
||||
<div class="bottom-tab" role="region">
|
||||
<ul class="bb-tablist">
|
||||
<li role="presentation">
|
||||
<button id="threads-delete-button" class="disable-when-dialog-animates" data-action="delete-button"></button>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<button id="threads-read-unread-button" data-action="mark-as-read"></button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<section id="threads-draft-saved-banner" class="hide" role="status">
|
||||
<p data-l10n-id="message-draft-saved">Message saved as draft</p>
|
||||
</section>
|
||||
|
||||
<div id="sticky"></div>
|
||||
</section>
|
||||
|
||||
<section class="panel panel-ConversationView panel-hidden editable-select-mode" role="region" aria-hidden="true">
|
||||
<gaia-header id="messages-header" class="view-header regular-header" action="back" no-font-fit="">
|
||||
<h1 id="messages-header-text"></h1>
|
||||
<button aria-label="Call" id="messages-call-number-button" data-icon="call" class="hide" data-l10n-id="callButton"></button>
|
||||
<button aria-label="Actions" id="messages-options-button" data-icon="more" data-l10n-id="actionsButton"></button>
|
||||
</gaia-header>
|
||||
<div id="messages-subheader" class="subheader">
|
||||
<section id="messages-to-field">
|
||||
<section data-l10n-id="to" id="to-label">To:</section>
|
||||
<!-- When overflow occurs in the recipients list, scrolling is
|
||||
commonly triggered automatically through focus and keyboard events.
|
||||
In these cases, white space described by CSS `padding-bottom` will
|
||||
not be automatically scrolled into view (because the element will
|
||||
only scroll far enough to bring the cursor into view). A container
|
||||
element is necessary to consistently render this vertical space
|
||||
(instead realized with CSS `margin-bottom`). -->
|
||||
<div id="messages-recipients-list-container" class="bb-editable" role="group" aria-labelledby="to-label">
|
||||
<section id="messages-recipients-list" class="singleline">
|
||||
</section>
|
||||
</div>
|
||||
<menu type="toolbar">
|
||||
<a id="messages-contact-pick-button">
|
||||
<span class="icon icon-user"></span>
|
||||
</a>
|
||||
</menu>
|
||||
</section>
|
||||
<div id="contact-carrier" class="carrier-wrapper"></div>
|
||||
<!-- Notifications in this container will be rendered on top of the
|
||||
Compose field. These notifications should be hidden automatically so
|
||||
they do not prevent the user from inputting text. -->
|
||||
<div class="overlay">
|
||||
<section id="messages-subject-max-length-notice" role="notification" class="hide">
|
||||
<p data-l10n-id="messages-max-subject-length-text">Maximum length of subject reached.</p>
|
||||
</section>
|
||||
<section id="messages-max-length-notice" role="notification" class="hide">
|
||||
<p></p>
|
||||
</section>
|
||||
<section id="messages-sms-counter-notice" role="notification" class="hide">
|
||||
<p></p>
|
||||
</section>
|
||||
<section id="messages-convert-notice" role="notification" class="hide">
|
||||
<p></p>
|
||||
</section>
|
||||
<section id="messages-resize-notice" role="notification" class="hide">
|
||||
<p data-l10n-id="resize-image">Resizing the attached image</p>
|
||||
</section>
|
||||
<section id="messages-new-message-notice" role="notification" class="hide">
|
||||
<div class="text-container">
|
||||
<div data-l10n-id="new-message-notice-text">New message from</div>
|
||||
<div dir="auto" class="contact">Contact</div>
|
||||
</div>
|
||||
<div class="button-container">
|
||||
<button class="notice-button" data-l10n-id="new-message-notice-a-text">Read it</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<article id="composer-container" class="view-body">
|
||||
<div class="flex-composer">
|
||||
<div id="messages-container" data-type="list" class="article-list"></div>
|
||||
<form id="messages-compose-form" role="search" class="bottom" data-message-type="sms">
|
||||
<section class="mms-label-line">
|
||||
<section class="subject-composer js-subject-composer hide">
|
||||
<div class="subject-composer-input" role="textbox" aria-multiline="false" contenteditable="true">
|
||||
</div>
|
||||
<div class="subject-composer-placeholder" data-l10n-id="messagesSubjectInput_placeholder">Subject</div>
|
||||
</section>
|
||||
<span class="mms-label" data-l10n-id="mms-label">MMS</span>
|
||||
</section>
|
||||
<section class="content-composer">
|
||||
<div class="messages-attach-container">
|
||||
<button id="messages-attach-button" aria-label="Add attachment" data-l10n-id="attach-button" type="button"></button>
|
||||
</div>
|
||||
<div class="composer-message-input-container">
|
||||
<div title="Message" id="messages-input" name="message" x-inputmode="-moz-sms" data-l10n-id="messagesInput" role="textbox" aria-multiline="true" contenteditable="true">
|
||||
</div>
|
||||
</div>
|
||||
<div class="composer-button-container">
|
||||
<span class="message-counter js-message-counter"></span>
|
||||
<button id="messages-send-button" class="icon" aria-label="Send" data-l10n-id="send-button" type="submit">
|
||||
<div aria-label="using SIM {{ n }}" class="js-sim-indication sim-indication" data-l10n-id="send-button-sim-indication">{{ n }}</div>
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
</div>
|
||||
</article>
|
||||
<form role="dialog" id="messages-edit-form" data-type="edit" class="hide">
|
||||
<section role="region" class="theme-settings">
|
||||
<gaia-header id="messages-edit-header" action="close" no-font-fit="">
|
||||
<h1 id="messages-edit-mode" data-l10n-id="deleteMessages-title">Delete messages</h1>
|
||||
<button id="messages-check-uncheck-all-button" class="edit-button" data-l10n-id="select-all">Select all</button>
|
||||
</gaia-header>
|
||||
</section>
|
||||
<div class="bottom-tab" role="region">
|
||||
<ul class="bb-tablist">
|
||||
<li role="presentation">
|
||||
<button id="messages-delete-button" class="disable-when-dialog-animates" data-action="delete-button"></button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</form>
|
||||
<section id="messages-recipient-suggestions" class="article-list hide" data-type="list">
|
||||
<ul class="contact-list recipient-suggestions-list" role="listbox"></ul>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section class="panel panel-GroupView panel-hidden" role="region" aria-hidden="true">
|
||||
<gaia-header id="information-group-header" class="header" action="back" no-font-fit="">
|
||||
<h1 data-l10n-id="participant" class="header-text">participant</h1>
|
||||
</gaia-header>
|
||||
<article class="view-body article-list" data-type="list">
|
||||
<ul class="contact-list"></ul>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="panel panel-ReportView panel-hidden" role="region" aria-hidden="true">
|
||||
<gaia-header id="information-report-header" class="header" action="close" no-font-fit="">
|
||||
<h1 data-l10n-id="message-report">Message report</h1>
|
||||
</gaia-header>
|
||||
<article class="view-body article-list report-view container" data-type="list">
|
||||
<div class="description">
|
||||
<p class="type"></p>
|
||||
<p class="subject">
|
||||
<span data-l10n-id="message-subject">Subject:</span>
|
||||
<span class="detail"></span>
|
||||
</p>
|
||||
<p class="sent-block">
|
||||
<span class="sent-title"></span>
|
||||
<span class="sent-timestamp l10n-contains-date detail"></span>
|
||||
</p>
|
||||
<p class="received-block">
|
||||
<span data-l10n-id="message-received">Received:</span>
|
||||
<span class="received-timestamp l10n-contains-date detail"></span>
|
||||
</p>
|
||||
<p class="lateness-block">
|
||||
<span data-l10n-id="message-lateness">Lateness:</span>
|
||||
<span class="lateness">
|
||||
<span class="lateness-month detail"></span>
|
||||
<span class="lateness-day detail"></span>
|
||||
<span class="lateness-hour detail"></span>
|
||||
<span class="lateness-minute detail"></span>
|
||||
<span class="lateness-second detail"></span>
|
||||
</span>
|
||||
</p>
|
||||
<p class="size-block">
|
||||
<span data-l10n-id="message-size-was">Message size:</span>
|
||||
<span class="size detail"></span>
|
||||
</p>
|
||||
<p class="sim-info hide">
|
||||
<span data-l10n-id="message-via">Via:</span>
|
||||
<span class="sim-detail detail"></span>
|
||||
</p>
|
||||
</div>
|
||||
<span class="contact-title"></span>
|
||||
<ul class="contact-list"></ul>
|
||||
<button class="resend-btn" data-l10n-id="message-resend">Resend</button>
|
||||
</article>
|
||||
</section>
|
||||
</article>
|
||||
|
||||
<article id="loading">
|
||||
<form role="dialog" data-type="confirm" class="loading-container">
|
||||
<section>
|
||||
<p class="loading-header" data-l10n-id="deleting-messages">Deleting…</p>
|
||||
<div role="status">
|
||||
<progress class="small"></progress>
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
</article>
|
||||
|
||||
<!--
|
||||
- Templates
|
||||
-->
|
||||
|
||||
<div id="contact-suggestion-tmpl" class="hide">
|
||||
<!--
|
||||
<li role="presentation">
|
||||
<a class="suggestion js-contact-info" role="option"
|
||||
data-number="${number}" data-source="contacts" data-name="${name}"
|
||||
data-type="${type}" data-carrier="${carrier}">
|
||||
${photoHTML}
|
||||
<p class="name"><bdi class="ellipsis-dir-fix">${nameHTML}</bdi></p>
|
||||
<p class="number">${phoneDetailsHTML}</p>
|
||||
</a>
|
||||
</li>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="contact-report-tmpl" class="hide">
|
||||
<!--
|
||||
<li>
|
||||
<div class="js-contact-info">
|
||||
${photoHTML}
|
||||
<p class="name"><bdi class="ellipsis-dir-fix">${nameHTML}</bdi></p>
|
||||
<p class="number">${phoneDetailsHTML}</p>
|
||||
</div>
|
||||
</li>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="contact-suggestion-unknown-tmpl" class="hide">
|
||||
<!--
|
||||
<li role="presentation">
|
||||
<a class="suggestion" role="option"
|
||||
data-number="${number}" data-source="contacts" data-name="${name}"
|
||||
data-type="${type}" data-carrier="${carrier}">
|
||||
${photoHTML}
|
||||
<p class="name">${phoneDetailsHTML}</p>
|
||||
<p class="number">
|
||||
<span data-l10n-id="unknown-contact-title">Unknown Contact</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="contact-prompt-tmpl" class="hide">
|
||||
<!--
|
||||
<div class="contact-header">
|
||||
${photoHTML}
|
||||
<p class="name"><bdi class="ellipsis-dir-fix">${name}</bdi></p>
|
||||
<p class="details">${phoneDetailsHTML}</p>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="contact-photo-tmpl" class="hide">
|
||||
<!--
|
||||
<aside role="img" data-l10n-id="contact-photo" aria-label="Contact photo" class="pack-end">
|
||||
<span class="contact-photo" data-type="img"></span>
|
||||
</aside>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="contact-highlight-tmpl" class="hide">
|
||||
<!--
|
||||
<span class="highlight">${str}</span>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="messages-number-tmpl" class="hide">
|
||||
<!--
|
||||
<div class="suggestion js-contact-info" data-number="${number}" data-source="manual" data-name="${number}">
|
||||
<p class="name"><bdi class="ellipsis-dir-fix">${number}</bdi></p>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="information-report-tmpl" class="hide">
|
||||
<!--
|
||||
<span class="icon"></span>
|
||||
<span data-l10n-id="${titleL10n}"></span>
|
||||
<span class="timestamp l10n-contains-date"
|
||||
data-l10n-date="${timestamp}"
|
||||
data-l10n-date-format="${messageL10nDateFormat}"
|
||||
>${reportDateL10n}</span>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="messages-not-downloaded-tmpl" class="hide">
|
||||
<!--
|
||||
<span class="not-downloaded-message l10n-contains-date"
|
||||
data-l10n-id="${messageL10nId}"
|
||||
data-l10n-args="${messageL10nArgs}"
|
||||
data-l10n-date="${messageL10nDate}"
|
||||
data-l10n-date-format="${messageL10nDateFormat}"></span>
|
||||
<button type="button" class="download" data-l10n-id="${downloadL10nId}"></button>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="messages-date-group-tmpl" class="hide">
|
||||
<!--
|
||||
<div id="${id}" class="messages-date-group" data-timestamp="${timestamp}">
|
||||
<header
|
||||
class="messages-date-group-header"
|
||||
data-time-update="${headerTimeUpdate}"
|
||||
data-time="${headerTime}"
|
||||
data-date-only="${headerDateOnly}">
|
||||
</header>
|
||||
<ul class="message-list"></ul>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="messages-message-tmpl" class="hide">
|
||||
<!--
|
||||
<label class="pack-checkbox danger">
|
||||
<input type="checkbox" value="${id}">
|
||||
<span></span>
|
||||
</label>
|
||||
<section class="bubble">
|
||||
<h1 class="message-subject">
|
||||
${subject}
|
||||
</h1>
|
||||
<div class="message-content">
|
||||
<p class="message-content-body" tabindex="-1">${bodyHTML}</p>
|
||||
<div class="message-details">
|
||||
${simInformationHTML}
|
||||
<time data-time-update="true" data-time-only="true" data-time="${timestamp}"></time>
|
||||
${messageStatusHTML}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="messages-message-sim-information-tmpl" class="hide">
|
||||
<!--
|
||||
<span class="message-sim-information"
|
||||
data-l10n-id="sim-id-label"
|
||||
data-l10n-args="${simNumberL10nArgs}">
|
||||
</span>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="messages-message-status-tmpl" class="hide">
|
||||
<!--
|
||||
<div class="message-status" data-l10n-id="${statusL10nId}"
|
||||
aria-label="Message status"
|
||||
role="status">
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="messages-late-arrival-notice-tmpl" class="hide">
|
||||
<!--
|
||||
<div class="late-arrival-icon" data-l10n-id="late-notice-label" aria-label="Late arrival"></div>
|
||||
<div class="late-arrival-notice"></div>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="messages-thread-tmpl" class="hide">
|
||||
<!--
|
||||
<label class="pack-checkbox negative">
|
||||
<input type="checkbox" value="${id}" data-mode="${mode}">
|
||||
<span></span>
|
||||
</label>
|
||||
<a href="${hash}">
|
||||
<aside role="note" class="icon icon-unread icon-draft js-conversation-state"></aside>
|
||||
<aside class="pack-end threadlist-item-picture"
|
||||
role="img" aria-label="Contact photo"
|
||||
data-l10n-id="contact-photo">
|
||||
<span data-type="img"></span>
|
||||
</aside>
|
||||
<p class="threadlist-item-title"><bdi class="ellipsis-dir-fix"></bdi></p>
|
||||
<p class="summary">
|
||||
<time data-time-update="true" data-time-only="true" data-time="${timestamp}"></time>
|
||||
<span class="mms-icon" data-l10n-id="mms-label">MMS</span>
|
||||
<span dir="auto" class="body-text js-conversation-body ellipsis-dir-fix"></span>
|
||||
</p>
|
||||
</a>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="messages-recipient-tmpl" class="hide">
|
||||
<!--
|
||||
<span class="${className}" x-inputmode="verbatim"
|
||||
contenteditable="${editable}" role="${role}"
|
||||
data-number="${number}" data-source="${source}" data-name="${name}"
|
||||
data-carrier="${carrier}" data-type="${type}" dir="auto">
|
||||
${name}
|
||||
</span>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="attachment-nopreview-tmpl" class="hide">
|
||||
<!--
|
||||
<div class="attachment ${errorClass}" data-attachment-type="${type}">
|
||||
<div class="thumbnail-placeholder ${type}-placeholder">
|
||||
</div>
|
||||
<div class="js-size-indicator size-indicator" data-l10n-id="${sizeL10nId}" data-l10n-args="${sizeL10nArgs}"></div>
|
||||
</div>
|
||||
<div class="file-name" dir="auto"></div>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="attachment-preview-tmpl" class="hide">
|
||||
<!--
|
||||
<div class="attachment">
|
||||
<div class="thumbnail"></div>
|
||||
<div class="js-size-indicator size-indicator" data-l10n-id="${sizeL10nId}" data-l10n-args="${sizeL10nArgs}"></div>
|
||||
</div>
|
||||
<div class="file-name" dir="auto"></div>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="attachment-draft-tmpl" class="hide">
|
||||
<!--
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
|
||||
<meta charset="utf-8">
|
||||
<base href="${baseURL}">
|
||||
<link rel="stylesheet" type="text/css" href="views/conversation/style/attachment_draft.css">
|
||||
<link rel="stylesheet" type="text/css" href="views/conversation/style/attachment.css">
|
||||
</head>
|
||||
<body class="attachment-draft ${cssClass}">${baseHTML}</body>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<!--
|
||||
Please, don't change template markup alignment, it's done this way to
|
||||
remove any whitespace symbols between inline elements.
|
||||
-->
|
||||
<div id="phone-details-tmpl" class="hide">
|
||||
<!--
|
||||
<span class="${hasTypeClass} ${hasCarrierClass}"><span
|
||||
dir="auto" class="phone-type"
|
||||
data-l10n-id="${type}">${type}</span><span
|
||||
class="phone-type-separator"
|
||||
data-l10n-id="phone-type-separator"></span><span
|
||||
class="phone-number" dir="ltr">${number}</span><span
|
||||
class="phone-carrier-separator"
|
||||
data-l10n-id="phone-carrier-separator"></span><span
|
||||
class="phone-carrier" dir="auto">${carrier}</span>
|
||||
</span>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="messages-group-header-tmpl" class="hide">
|
||||
<!--
|
||||
<span class="group-header-title"><bdi class="ellipsis-dir-fix">${name}</bdi> <bdi dir="ltr">(+${participantCount})</bdi></span>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="messages-header-tmpl" class="hide">
|
||||
<!--
|
||||
<bdi class="ellipsis-dir-fix">${name}</bdi>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<gaia-sim-picker id="sim-picker" tabindex="-1" class="hide"></gaia-sim-picker>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
24
assets/webapps/sms.gaiamobile.org/jsdoc.json
Normal file
24
assets/webapps/sms.gaiamobile.org/jsdoc.json
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"name": "sms",
|
||||
"tags": {
|
||||
"dictionaries": ["jsdoc"]
|
||||
},
|
||||
"source": {
|
||||
"include": [
|
||||
"apps/sms/views/conversation/js/**/*.js",
|
||||
"apps/sms/views/inbox/js/**/*.js",
|
||||
"apps/sms/views/new_message/js/**/*.js",
|
||||
"apps/sms/views/shared/js/**/*.js",
|
||||
"apps/sms/services/js/**/*.js"
|
||||
]
|
||||
},
|
||||
"plugins": [
|
||||
"plugins/markdown",
|
||||
"plugins/summarize"
|
||||
],
|
||||
"opts": {
|
||||
"private": true,
|
||||
"recurse": true,
|
||||
"destination": "docs/sms"
|
||||
}
|
||||
}
|
||||
3
assets/webapps/sms.gaiamobile.org/lib/bridge/client.js
Normal file
3
assets/webapps/sms.gaiamobile.org/lib/bridge/client.js
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,4 @@
|
|||
;!((define)=>{define((require,exports,module)=>{var debug=0?function(arg1,...args){var type=`[${self.constructor.name}][${location.pathname}]`;console.log(`[ClientStream]${type} - "${arg1}"`,...args);}:()=>{};module.exports=(client,utils)=>{client._activeStreams=[];client.on('streamevent',onStreamEvent);client.stream=function(name){debug('stream open',name);var args=[].slice.call(arguments,1);var stream=new ClientStream(client,utils);var self=this;this.method('_stream',name,stream.id,this.id,args).then(()=>{debug('stream connected',name);stream._connected.resolve();}).catch(err=>{debug('error',err);onStreamEvent({type:'abort',id:stream.id,data:err});});this._activeStreams[stream.id]=stream;stream.emitter.on('cancel',onEnd);stream.emitter.on('abort',onEnd);stream.emitter.on('close',onEnd);function onEnd(){debug('end');delete self._activeStreams[stream.id];stream.destroy();}
|
||||
return stream;};function onStreamEvent(data){debug('stream event',data.type);var stream=client._activeStreams[data.streamId];stream.emitter.emit(data.type,data.data);}};function ClientStream(client,utils){this.id=utils.uuid();this.client=client;this.emitter=new utils.Emitter();this.emitter.on('close',this.onClose.bind(this));this.emitter.on('abort',this.onAbort.bind(this));this._connected=defer();this.connected=this._connected.promise;this._closed=defer();this.closed=this._closed.promise;debug('initialized');}
|
||||
ClientStream.prototype={listen(callback){debug('listen',callback);this.emitter.on('write',callback);},unlisten(callback){debug('unlisten',callback);this.emitter.off('write',callback);},cancel(reason){debug('cancel',reason);return this.client.method('_streamcancel',this.id,reason).then(result=>{debug('cancelled',result);this.emitter.emit('cancel');return result;}).catch(e=>{this.emitter.emit('cancel');});},onAbort(reason){debug('abort',reason);this._closed.reject(reason);},onClose(){debug('close');this._closed.resolve();},destroy(){debug('destroy');this.emitter.off();}};function defer(){var result={};result.promise=new Promise((resolve,reject)=>{result.resolve=resolve;result.reject=reject;});return result;}});})((typeof define)[0]=='f'&&define.amd?define:((n,w)=>{return(typeof
|
||||
module)[0]=='o'?c=>{c(require,exports,module);}:(c)=>{var m={exports:{}};c(n=>w[n],m.exports,m);w[n]=m.exports;};})('streamClient',this));
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
!((define)=>{define((require,exports,module)=>{
|
||||
|
||||
/**
|
||||
* Mini Logger
|
||||
*
|
||||
* @type {Function}
|
||||
*/
|
||||
|
||||
var debug = 0 ? function(arg1, ...args) {
|
||||
var type = `[${self.constructor.name}][${location.pathname}]`;
|
||||
console.log(`[ServiceStream]${type} - "${arg1}"`, ...args);
|
||||
} : () => {};
|
||||
|
||||
module.exports = function(service) {
|
||||
debug('attaching plugin');
|
||||
|
||||
service
|
||||
.method('_stream', onStream)
|
||||
.method('_streamcancel', onStreamCancel);
|
||||
|
||||
service._streamHandlers = {};
|
||||
service._activeStreams = [];
|
||||
|
||||
service.stream = function(name, fn) {
|
||||
debug('register stream', name);
|
||||
this._streamHandlers[name] = fn;
|
||||
return this;
|
||||
};
|
||||
|
||||
function onStream(name, id, clientId, args) {
|
||||
debug('on stream open', name);
|
||||
var e = {
|
||||
preventDefault: () => e.defaultPrevented = true,
|
||||
arguments: arguments
|
||||
};
|
||||
|
||||
// Allow other plugins to override default behaviour
|
||||
service.emit('before-stream', e);
|
||||
if (e.defaultPrevented) return;
|
||||
|
||||
var fn = service._streamHandlers[name];
|
||||
if (!fn) throw error(1, name);
|
||||
|
||||
var stream = new ServiceStream(id, service, clientId);
|
||||
service._activeStreams[id] = stream;
|
||||
|
||||
// Always pass stream object as first
|
||||
// argument to simplify the process
|
||||
fn.apply(service, [stream].concat(args));
|
||||
}
|
||||
|
||||
function onStreamCancel(id, reason) {
|
||||
debug('stream cancel');
|
||||
var stream = service._activeStreams[id];
|
||||
delete service._activeStreams[id];
|
||||
return stream.cancel(reason);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Writable Stream instance passed to the
|
||||
* `service.stream` implementation
|
||||
*
|
||||
* @param {Object} options
|
||||
* @param {String} options.id Stream ID used to sync client and service streams
|
||||
* @param {BroadcastChannel} options.channel Channel used to postMessage
|
||||
* @param {String} options.serviceId ID of the service
|
||||
* @param {String} options.clientId ID of client that should receive message
|
||||
*/
|
||||
|
||||
function ServiceStream(streamId, service, clientId) {
|
||||
this.id = streamId;
|
||||
this.service = service;
|
||||
this.clientId = clientId;
|
||||
this.writable = true;
|
||||
debug('initialized');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prototype assigned to variable
|
||||
* to improve compression.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
var ServiceStreamPrototype = ServiceStream.prototype;
|
||||
|
||||
/**
|
||||
* Services that allows clients to
|
||||
* cancel the operation before it's
|
||||
* complete should override the
|
||||
* `stream.cancel` method.
|
||||
*
|
||||
* @param {*} [reason] Data sent from client about the cancellation
|
||||
* @returns {(Promise|*)}
|
||||
*/
|
||||
|
||||
ServiceStreamPrototype.cancel = function(reason) {
|
||||
var err = new TypeError('service should implement stream.cancel()');
|
||||
return Promise.reject(err);
|
||||
};
|
||||
|
||||
/**
|
||||
* Signal to client that action was
|
||||
* aborted during the process, this
|
||||
* should be used as a way to
|
||||
* communicate errors.
|
||||
*
|
||||
* @param {*} [data] Reason of failure
|
||||
* @returns {Promise}
|
||||
* @public
|
||||
*/
|
||||
|
||||
ServiceStreamPrototype.abort = function(data) {
|
||||
debug('abort', data);
|
||||
this._post('abort', data);
|
||||
this.writable = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends a chunk of data to the client.
|
||||
*
|
||||
* @param {*} data Chunk of data to be sent to client.
|
||||
* @returns {Promise}
|
||||
* @public
|
||||
*/
|
||||
|
||||
ServiceStreamPrototype.write = function(data) {
|
||||
debug('write', data);
|
||||
this._post('write', data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes the stream, signals that
|
||||
* action was completed with success.
|
||||
*
|
||||
* According to whatwg streams spec,
|
||||
* WritableStream#close() doesn't send data.
|
||||
*
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
ServiceStreamPrototype.close = function() {
|
||||
debug('close');
|
||||
this._post('close');
|
||||
this.writable = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Validate the current state and
|
||||
* call cancel on the target stream.
|
||||
*
|
||||
* Called by the Service when client
|
||||
* sends a 'streamcancel' message.
|
||||
*
|
||||
* @param {*} [reason] Reason for cancelation sent by the client
|
||||
* @returns {Promise}
|
||||
* @private
|
||||
*/
|
||||
|
||||
ServiceStreamPrototype._cancel = function(reason) {
|
||||
debug('cancel', reason);
|
||||
return this.cancel(reason)
|
||||
.then(result => {
|
||||
this.writable = false;
|
||||
return result;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Validate the current state and post message to client.
|
||||
*
|
||||
* @param {String} type 'write', 'abort' or 'close'
|
||||
* @param {String} state 'writable', 'aborted' or 'closed'
|
||||
* @param {*} [data] Data to be sent to the client
|
||||
* @returns {Promise}
|
||||
* @private
|
||||
*/
|
||||
|
||||
ServiceStreamPrototype._post = function(type, data) {
|
||||
debug('post', type, data, this.writable);
|
||||
if (!this.writable) return Promise.reject();
|
||||
this.service.broadcast('streamevent', {
|
||||
streamId: this.id,
|
||||
type: type,
|
||||
data: data
|
||||
}, [this.clientId]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create new `Error` from registery.
|
||||
*
|
||||
* @param {Number} id Error Id
|
||||
* @return {Error}
|
||||
* @private
|
||||
*/
|
||||
function error(id) {
|
||||
var args = [].slice.call(arguments, 1);
|
||||
return new Error({
|
||||
1: 'stream "' + args[0] + '" doesn\'t exist'
|
||||
}[id]);
|
||||
}
|
||||
|
||||
});})((typeof define)[0]=='f'&&define.amd?define:((n,w)=>{return(typeof
|
||||
module)[0]=='o'?c=>{c(require,exports,module);}:(c)=>{var m={exports:{}};
|
||||
c(n=>w[n],m.exports,m);w[n]=m.exports;};})('streamService',this));
|
||||
27
assets/webapps/sms.gaiamobile.org/lib/bridge/service.js
Normal file
27
assets/webapps/sms.gaiamobile.org/lib/bridge/service.js
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
var $jscomp={scope:{},global:this},Symbol;$jscomp.initSymbol=function(){$jscomp.global.Symbol||(Symbol=$jscomp.Symbol);$jscomp.initSymbol=function(){}};$jscomp.symbolCounter_=0;$jscomp.Symbol=function(k){return"jscomp_symbol_"+k+$jscomp.symbolCounter_++};$jscomp.initSymbolIterator=function(){$jscomp.initSymbol();Symbol.iterator||(Symbol.iterator=Symbol("iterator"));$jscomp.initSymbolIterator=function(){}};
|
||||
$jscomp.makeIterator=function(k){$jscomp.initSymbolIterator();if(k[Symbol.iterator])return k[Symbol.iterator]();if(!(k instanceof Array||"string"==typeof k||k instanceof String))throw new TypeError(k+" is not iterable");var c=0;return{next:function(){return c==k.length?{done:!0}:{done:!1,value:k[c++]}}}};$jscomp.arrayFromIterator=function(k){for(var c,e=[];!(c=k.next()).done;)e.push(c.value);return e};$jscomp.arrayFromIterable=function(k){return k instanceof Array?k:$jscomp.arrayFromIterator($jscomp.makeIterator(k))};
|
||||
$jscomp.arrayFromArguments=function(k){for(var c=[],e=0;e<k.length;e++)c.push(k[e]);return c};$jscomp.inherits=function(k,c){function e(){}e.prototype=c.prototype;k.prototype=new e;k.prototype.constructor=k;for(var l in c)if($jscomp.global.Object.defineProperties){var a=$jscomp.global.Object.getOwnPropertyDescriptor(c,l);void 0!==a&&$jscomp.global.Object.defineProperty(k,l,a)}else k[l]=c[l]};
|
||||
(function(k){"object"===typeof exports&&"undefined"!==typeof module?module.exports=k():"function"===typeof define&&define.amd?define([],k):("undefined"!==typeof window?window:"undefined"!==typeof global?global:"undefined"!==typeof self?self:this).bridge=k()})(function(){return function c(e,l,a){function m(h,f){if(!l[h]){if(!e[h]){var g="function"==typeof require&&require;if(!f&&g)return g(h,!0);if(p)return p(h,!0);g=Error("Cannot find module '"+h+"'");throw g.code="MODULE_NOT_FOUND",g;}g=l[h]={exports:{}};
|
||||
e[h][0].call(g.exports,function(d){var b=e[h][1][d];return m(b?b:d)},g,g.exports,c,e,l,a)}return l[h].exports}for(var p="function"==typeof require&&require,n=0;n<a.length;n++)m(a[n]);return m}({1:[function(c,e,l){var a=e.exports=self.bridge||{};a.service=c("../src/service");"u"!="undefined"[0]?(void 0)([],function(){return a}):self.bridge=a},{"../src/service":5}],2:[function(c,e,l){function a(c){if(c)return Object.assign(c,a.prototype)}e.exports=a;a.prototype={on:function(a,c){this._callbacks||(this._callbacks=
|
||||
{});this._callbacks[a]||(this._callbacks[a]=[]);this._callbacks[a].push(c);return this},off:function(a,c){if(this._callbacks)switch(arguments.length){case 0:this._callbacks={};break;case 1:delete this._callbacks[a];break;default:var e=this._callbacks[a];if(!e)return;var h=e.indexOf(c);~h&&e.splice(h,1)}return this},emit:function(a,c){if(this._callbacks)for(var e=this._callbacks[a]||[],e=e.concat(this._callbacks["*"]||[]),h=0;h<e.length;h++)e[h].call(this,c,a);return this}};c=a.prototype;c.off=c.off;
|
||||
c.on=c.on},{}],3:[function(c,e,l){function a(b){this.cancelled=!1;this.listeners=[];this.deferred=f();this.listen=this.listen.bind(this);this.onMessage=this.onMessage.bind(this);this.onTimeout=this.onTimeout.bind(this);"object"===typeof b?this.setupInbound(b):this.setupOutbound(b);d("initialized",this.type)}function m(b){this.name=b;this.ports=new Set;this.onMessage=this.onMessage.bind(this);this.listen=this.listen.bind(this);this.unlisten=this.unlisten.bind(this);d("receiver initialized",b)}function p(b,
|
||||
d){for(var a=1;a<arguments.length;++a);return Error({1:".send() can only be called once",2:"response already sent for this message",3:"a port must be defined",4:"timeout"}[b])}var n=c("./port-adaptors"),h=c("../emitter");c=c("../utils");var f=c.deferred,g=c.uuid;l=e.exports=function(b){return new a(b)};l.receiver=function(b,d){return new m(b,d)};l.Receiver=m;l.Message=a;var d={0:function(){},1:function(b){return performance.mark("["+self.constructor.name+"][Message] - "+b)},2:function(b,d){for(var a=
|
||||
[],f=1;f<arguments.length;++f)a[f-1]=arguments[f];console.log.apply(console,[].concat(["[Message]"+("["+self.constructor.name+"]["+location.pathname+"]")+' - "'+b+'"'],$jscomp.arrayFromIterable(a)))}}[0];a.prototype={setupOutbound:function(b){this.id=g();this.type=b;this.sent=!1;this.recipient="*"},setupInbound:function(b){d("inbound");this.hasResponded=!1;this.setSourcePort(b.source||b.target);this.event=b;Object.assign(this,b.data)},setSourcePort:function(b){d("set source",b.constructor.name);this.sourcePort=
|
||||
n(b,{ready:!0});return this},set:function(b,a){d("set",b,a);"object"==typeof b?Object.assign(this,b):this[b]=a;return this},serialize:function(){return{id:this.id,type:this.type,data:this.data,recipient:this.recipient,noRespond:this.noRespond}},preventDefault:function(){d("prevent default");this.defaultPrevented=!0},send:function(b){d("send",this.type);if(this.sent)throw p(1);var a=this.serialize(),f=!this.noRespond;this.port=b?n(b):this.port;if(!this.port)throw p(3);f?(this.listen(this.port),this.setResponseTimeout()):
|
||||
this.deferred.resolve();this.port.postMessage(a,this.getTransfer());d("sent",a);return this.deferred.promise},setResponseTimeout:function(){!1!==this.timeout&&(this._timer=setTimeout(this.onTimeout,this.timeout||2E3))},clearResponseTimeout:function(){clearTimeout(this._timer)},getTransfer:function(){return this.transfer||this.event&&this.event.ports},onMessage:function(b){if(b.data.response&&b.data.id===this.id&&!this.cancelled)this.onResponse(b)},onTimeout:function(){d("response timeout",this.type);
|
||||
this.silentTimeout||this.deferred.reject(p(4));this.teardown()},listen:function(b){d("add response listener",b);b=n(b);b.addListener(this.onMessage,this.listen);this.listeners.push(b);return this},unlisten:function(){var b=this;d("remove response listeners");this.listeners.forEach(function(d){return d.removeListener(b.onMessage)});this.listeners=[]},cancel:function(){this.teardown();this.cancelled=!0;this.emit("cancel")},teardown:function(){this.clearResponseTimeout();this.unlisten()},respond:function(b){function a(b){d("resolve",
|
||||
b);c({type:"resolve",value:b})}function f(b){a:switch(b&&b.constructor.name){case "DOMException":case "Error":b={message:b.message};break a;case "DOMError":b={message:b.message,name:b.name};break a}d("reject",b);c({type:"reject",value:b})}function c(b){g.response=b;g.sourcePort.postMessage({id:g.id,response:b},g.transfer);d("responded with:",b)}d("respond",b,this.id);if(this.hasResponded)throw p(2);if(this.sourcePort&&!this.noRespond){this.hasResponded=!0;var g=this;this.error&&f(this.error);Promise.resolve(b).then(a,
|
||||
f).catch(f)}},forward:function(b){var a=this;d("forward");return this.set("silentTimeout",!0).send(b).then(function(b){return a.respond(b.value)})},onResponse:function(b){d("on response",b.data);var a=b.data.response,f="reject"==a.type?a.value:a;a.event=b;this.response=a;this.teardown();this.deferred[this.response.type](f);this.emit("response",a)}};h(a.prototype);m.prototype={listen:function(b){d("listen");b=n(b||self,{receiver:!0});if(!this.ports.has(b))return b.addListener(this.onMessage,this.listen),
|
||||
this.ports.add(b),this},unlisten:function(){var b=this;d("unlisten");this.ports.forEach(function(d){return d.removeListener(b.onMessage)})},onMessage:function(b){if(b.data.id&&b.data.type&&this.isRecipient(b.data.recipient)&&(d("receiver on message",b.data),b=new a(b),this.emit("message",b),!b.defaultPrevented))try{this.emit(b.type,b)}catch(f){throw b.error=f,b.respond(),f;}},isRecipient:function(b){return b==this.name||"*"==b||"*"==this.name},destroy:function(){this.unlisten();delete this.name;return this}};
|
||||
h(m.prototype)},{"../emitter":2,"../utils":6,"./port-adaptors":4}],4:[function(c,e,l){function a(d){this.target=d}function m(d,b,a){d.addEventListener(b,a)}function p(d,b,a){b={data:b,source:self};a&&(b.ports=a);d.dispatchEvent(new MessageEvent("message",b))}var n=c("../utils").deferred;e.exports=function(d,b){if(!d)throw Error({1:"target is undefined"}[1]);if(d&&d.addListener)return d;var g=f[d.constructor.name];return g?g(d,b):new a(d,b)};var h=a.prototype={constructor:a,addListener:function(d){this.target.addEventListener("message",
|
||||
d)},removeListener:function(d){this.target.removeEventListener("message",d)},postMessage:function(d,b){this.target.postMessage(d,b)}},f={HTMLIFrameElement:function(d){var b=g(d);return{addListener:function(b){window.addEventListener("message",b)},removeListener:function(b){window.removeEventListener("message",b)},postMessage:function(a,f){b.then(function(){return p(d.contentWindow,a,f)})}}},BroadcastChannel:function(a,b){function f(){var b=n();a.postMessage("ready?");m(a,"message",function q(f){"ready"==
|
||||
f.data&&(a.removeEventListener("message",q),b.resolve())});return b.promise}var g=b&&b.receiver,c=b&&b.ready,c=c||g?Promise.resolve():f();g&&(a.postMessage("ready"),m(a,"message",function(b){"ready?"==b.data&&a.postMessage("ready")}));return{target:a,addListener:h.addListener,removeListener:h.removeListener,postMessage:function(b,f){c.then(function(){return a.postMessage(b,f)})}}},Window:function(a,b){var f=b&&b.ready||a===parent||a===self,f=f?Promise.resolve():g(a);return{addListener:function(b){window.addEventListener("message",
|
||||
b)},removeListener:function(b){window.removeEventListener("message",b)},postMessage:function(b,g){f.then(function(){return p(a,b,g)})}}},SharedWorker:function(f){f.port.start();return new a(f.port)},SharedWorkerGlobalScope:function(){var a=[];return{postMessage:function(){},addListener:function(b,f){this.onconnect=function(b){b=b.ports[0];a.push(b);b.start();f(b)};self.addEventListener("connect",this.onconnect)},removeListener:function(b){self.removeEventListener("connect",this.onconnect);a.forEach(function(a){a.close();
|
||||
a.removeEventListener("message",b)})}}}},g=function(){if("undefined"!=typeof window){var a=window.opener||window.parent,b=new WeakSet;a!=self&&m(window,"DOMContentLoaded",function r(){window.removeEventListener("DOMContentLoaded",r);p(a,"load")});m(self,"message",function(a){return"load"==a.data&&b.add(a.source)});return function(a){var f=a.contentWindow||a;if(b.has(f)||f==window.parent)return Promise.resolve();var d=n();m(window,"message",function q(b){"load"==b.data&&b.source==f&&(window.removeEventListener("message",
|
||||
q),d.resolve())});return d.promise}}}()},{"../utils":6}],5:[function(c,e,l){function a(f){if(!(this instanceof a))return new a(f);n.Receiver.call(this,f);this.clients={};this.methods={};this.on("_disconnect",this.onDisconnect.bind(this)).on("_connect",this.onConnect.bind(this)).on("_method",this.onMethod.bind(this)).on("_off",this.onOff.bind(this)).on("_on",this.onOn.bind(this));this.destroy=this.destroy.bind(this);h("initialized",f)}function m(a){var g=[].slice.call(arguments,1);return Error({4:'method "'+
|
||||
g[0]+"\" doesn't exist"}[a])}var p=c("./utils").uuid,n=c("./message");c=n.Receiver;e.exports=a;var h={0:function(){},1:function(a){return performance.mark("["+self.constructor.name+"][Service] - "+a)},2:function(a,g){for(var d=[],b=1;b<arguments.length;++b)d[b-1]=arguments[b];console.log.apply(console,[].concat(["[Service]"+("["+self.constructor.name+"]["+location.pathname+"]")+' - "'+a+'"'],$jscomp.arrayFromIterable(d)))}}[0];a.prototype=Object.create(c.prototype);a.prototype.inWindow="Window"===
|
||||
constructor.name;a.prototype.method=function(a,g){this.methods[a]=g;return this};a.prototype.broadcast=function(a,g,d){var b=this;h("broadcast",a,g,d);this.eachClient(function(c){if(!d||~d.indexOf(c.id))h("broadcasting to",c.id),b.push(a,g,c.id,{noRespond:!0})});return this};a.prototype.push=function(a,g,d,b){b=b&&b.noRespond;var c=this.getClient(d);return n("_push").set({recipient:d,noRespond:b,data:{type:a,data:g}}).send(c.port)};a.prototype.eachClient=function(a){for(var c in this.clients)a(this.clients[c])};
|
||||
a.prototype.getClient=function(a){return this.clients[a]};a.prototype.onConnect=function(a){h("connection attempt",a.data,this.name);var c=a.data,d=c.clientId;d&&c.service===this.name&&!this.clients[d]&&(this.emit("before-connect",a),a.defaultPrevented||(this.upgradeChannel(a),this.addClient(d,a.sourcePort),a.respond(),this.emit("connected",d),h("connected",d)))};a.prototype.upgradeChannel=function(a){if(!this.inWindow||"Window"!==a.data.originEnv){var c=a.event.ports;if(c=c&&c[0])a.setSourcePort(c),
|
||||
this.listen(c),c.start();h("channel upgraded")}};a.prototype.onDisconnect=function(a){var c=this.clients[a.data];c&&(this.emit("before-disconnect",a),a.defaultPrevented||(this.removeClient(c.id),a.respond(),this.emit("disconnected",c.id),h("disconnected",c.id)))};a.prototype.onMethod=function(a){h("on method",a.data);this.emit("before-method",a);if(!a.defaultPrevented){var c=a.data,d=c.name,b=this.methods[d],e;if(!b)throw m(4,d);try{e=b.apply(this,c.args)}catch(l){a.error=l}a.respond(e)}};a.prototype.onOn=
|
||||
function(a){h("on on",a.data);this.emit("on",a.data)};a.prototype.onOff=function(a){h("on off");this.emit("off",a.data)};a.prototype.addClient=function(a,c){this.clients[a]={id:a,port:c}};a.prototype.removeClient=function(a){delete this.clients[a]};a.prototype.plugin=function(a){a(this,{uuid:p});return this};a.prototype.disconnect=function(a){this.removeClient(a.id);n("disconnect").set({recipient:a.id,noRespond:!0}).send(a.port)};a.prototype.destroy=function(){delete this.clients;this.unlisten();
|
||||
this.off()};e=a.prototype;e.broadcast=e.broadcast;e.destroy=e.destroy;e.method=e.method;e.plugin=e.plugin},{"./message":3,"./utils":6}],6:[function(c,e,l){l.uuid=function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var c=16*Math.random()|0;return("x"==a?c:c&3|8).toString(16)})};l.deferred=function(){var a={};a.promise=new Promise(function(c,e){a.resolve=c;a.reject=e});return a}},{}]},{},[1])(1)});
|
||||
671
assets/webapps/sms.gaiamobile.org/lib/sww.js
Normal file
671
assets/webapps/sms.gaiamobile.org/lib/sww.js
Normal file
|
|
@ -0,0 +1,671 @@
|
|||
(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){
|
||||
var sww = require('./lib/sww.js');
|
||||
|
||||
self.ServiceWorkerWare = sww.ServiceWorkerWare;
|
||||
self.StaticCacher = sww.StaticCacher;
|
||||
self.SimpleOfflineCache = sww.SimpleOfflineCache;
|
||||
|
||||
},{"./lib/sww.js":5}],2:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
// Inspired by expressjs and shed (https://github.com/wibblymat/shed)
|
||||
function Router(options) {
|
||||
this.options = options;
|
||||
this.stack = [];
|
||||
}
|
||||
|
||||
Router.prototype.ALL_METHODS = 'all';
|
||||
Router.prototype.methods = ['get', 'post', 'put', 'delete', 'head',
|
||||
Router.prototype.ALL_METHODS];
|
||||
|
||||
/**
|
||||
* Add a new route to the stack.
|
||||
* @param method (String) http verb to handle the request
|
||||
* @param path (Regexp) string or regexp to match urls
|
||||
* @param handler (Function) payload to be executed if url matches.
|
||||
*/
|
||||
Router.prototype.add = function r_add(method, path, handler) {
|
||||
var pathRegex;
|
||||
|
||||
method = this._sanitizeMethod(method);
|
||||
|
||||
// Parse simle string path into regular expression for path matching
|
||||
pathRegex = this._parseSimplePath(path);
|
||||
|
||||
this.stack.push({
|
||||
method: method,
|
||||
path: pathRegex,
|
||||
handler: handler
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the utility methods .get .post ... etc.
|
||||
*/
|
||||
Router.prototype.methods.forEach(function(method) {
|
||||
Router.prototype[method] = function(path, handler) {
|
||||
return this.add(method, path, handler);
|
||||
};
|
||||
});
|
||||
|
||||
Router.prototype.proxyMethods = function r_proxyPrototype(obj) {
|
||||
var self = this;
|
||||
this.methods.forEach(function(method) {
|
||||
obj[method] = function(path, mw) {
|
||||
if (typeof mw.onFetch !== 'function' && typeof mw !== 'function') {
|
||||
throw new Error('This middleware cannot handle fetch request');
|
||||
}
|
||||
var handler = typeof mw.onFetch !== 'undefined' ?
|
||||
mw.onFetch.bind(mw) : mw;
|
||||
self.add(method, path, handler);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Matches the given url and methods with the routes stored in
|
||||
* the stack.
|
||||
*/
|
||||
Router.prototype.match = function r_match(method, url) {
|
||||
method = this._sanitizeMethod(method);
|
||||
var matches = [];
|
||||
|
||||
var self = this;
|
||||
this.stack.forEach(function eachRoute(route) {
|
||||
if (!(method === route.method || route.method === self.ALL_METHODS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (route.path.test(url)) {
|
||||
matches.push(route.handler);
|
||||
}
|
||||
});
|
||||
|
||||
return matches;
|
||||
};
|
||||
|
||||
Router.prototype._sanitizeMethod = function(method) {
|
||||
var sanitizedMethod = method.toLowerCase().trim();
|
||||
if (this.methods.indexOf(sanitizedMethod) === -1) {
|
||||
throw new Error('Method "' + method + '" is not supported');
|
||||
}
|
||||
return sanitizedMethod;
|
||||
};
|
||||
|
||||
/**
|
||||
* Simple path-to-regex translation based on the Express "string-based path"
|
||||
* syntax.
|
||||
*/
|
||||
Router.prototype._parseSimplePath = function(path) {
|
||||
// Check for named placeholder crowding
|
||||
if (/\:[a-zA-Z0-9]+\:[a-zA-Z0-9]+/g.test(path)) {
|
||||
throw new Error('Invalid usage of named placeholders');
|
||||
}
|
||||
|
||||
// Check for mixed placeholder crowdings
|
||||
var mixedPlaceHolders =
|
||||
/(\*\:[a-zA-Z0-9]+)|(\:[a-zA-Z0-9]+\:[a-zA-Z0-9]+)|(\:[a-zA-Z0-9]+\*)/g;
|
||||
if (mixedPlaceHolders.test(path.replace(/\\\*/g,''))) {
|
||||
throw new Error('Invalid usage of named placeholders');
|
||||
}
|
||||
|
||||
// Try parsing the string and converting special characters into regex
|
||||
try {
|
||||
// Parsing anonymous placeholders with simple backslash-escapes
|
||||
path = path.replace(/(.|^)\*/g, function(m,escape) {
|
||||
return escape==='\\' ? '\\*' : (escape+'(.*?)');
|
||||
});
|
||||
|
||||
// Parsing named placeholders with backslash-escapes
|
||||
path = path.replace(/(.|^)\:([a-zA-Z0-9]+)/g, function(m,escape,tag) {
|
||||
return escape==='\\' ? (':'+tag) : (escape+'(.+?)');
|
||||
});
|
||||
|
||||
return new RegExp(path + '$');
|
||||
}
|
||||
|
||||
// Failed to parse final path as a RegExp
|
||||
catch (ex) {
|
||||
throw new Error('Invalid path specified');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
module.exports = Router;
|
||||
|
||||
},{}],3:[function(require,module,exports){
|
||||
/* global Promise */
|
||||
'use strict';
|
||||
|
||||
var cacheHelper = require('sw-cache-helper');
|
||||
|
||||
var debug = 0 ? console.log.bind(console, '[SimpleOfflineCache]') :
|
||||
function(){};
|
||||
|
||||
// Default Match options, not exposed.
|
||||
var DEFAULT_MATCH_OPTIONS = {
|
||||
ignoreSearch: false,
|
||||
ignoreMethod: false,
|
||||
ignoreVary: false
|
||||
};
|
||||
var DEFAULT_MISS_POLICY = 'fetchAndChace';
|
||||
// List of different policies
|
||||
var MISS_POLICIES = [
|
||||
DEFAULT_MISS_POLICY
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for the middleware that serves the content of a
|
||||
* cache specified by it's name.
|
||||
* @param {string} cacheName Name of the cache that will be serving the content
|
||||
* @param {object} [options] Object use to setup the cache matching alternatives
|
||||
* @param {string} [missPolicy] Name of the policy to follow if a request miss
|
||||
* when hitting the cache.
|
||||
*/
|
||||
function SimpleOfflineCache(cacheName, options, missPolicy) {
|
||||
this.cacheName = cacheName || cacheHelper.defaultCacheName;
|
||||
this.options = options || DEFAULT_MATCH_OPTIONS;
|
||||
this.missPolicy = missPolicy || DEFAULT_MISS_POLICY;
|
||||
if (MISS_POLICIES.indexOf(this.missPolicy) === -1) {
|
||||
console.warn('Policy ' + missPolicy + ' not supported');
|
||||
this.missPolicy = DEFAULT_MISS_POLICY;
|
||||
}
|
||||
}
|
||||
|
||||
SimpleOfflineCache.prototype.onFetch = function soc_onFetch(request, response) {
|
||||
// If another middleware layer already have a response, the simple cache
|
||||
// just pass through the response and does nothing.
|
||||
if (response) {
|
||||
return Promise.resolve(response);
|
||||
}
|
||||
|
||||
var clone = request.clone();
|
||||
var _this = this;
|
||||
debug('Handing fetch event: %s', clone.url);
|
||||
return this.ensureCache().then(function(cache) {
|
||||
return cache.match(request.clone(), _this.options).then(function(res) {
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
|
||||
// So far we just support one policy
|
||||
switch(_this.missPolicy) {
|
||||
case DEFAULT_MISS_POLICY:
|
||||
return cacheHelper.fetchAndCache(request, cache);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
SimpleOfflineCache.prototype.ensureCache = function soc_ensureCache() {
|
||||
return cacheHelper.getCache(this.cacheName).then(function(cache) {
|
||||
return cache;
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = SimpleOfflineCache;
|
||||
|
||||
},{"sw-cache-helper":6}],4:[function(require,module,exports){
|
||||
/* globals caches, Promise, Request */
|
||||
'use strict';
|
||||
|
||||
function StaticCacher(fileList) {
|
||||
if (!Array.isArray(fileList) || fileList.length === 0) {
|
||||
throw new Error('Invalid file list');
|
||||
}
|
||||
this.files = fileList;
|
||||
}
|
||||
|
||||
StaticCacher.prototype.onInstall = function sc_onInstall() {
|
||||
var self = this;
|
||||
return this.getDefaultCache().then(function(cache) {
|
||||
return self.addAll(cache, self.files);
|
||||
});
|
||||
};
|
||||
|
||||
StaticCacher.prototype.getDefaultCache = function sc_getDefaultCache() {
|
||||
return caches.open('offline');
|
||||
};
|
||||
|
||||
StaticCacher.prototype.addAll = function(cache, urls) {
|
||||
if (!cache) {
|
||||
throw new Error('Need a cache to store things');
|
||||
}
|
||||
// Polyfill until chrome implements it
|
||||
if (typeof cache.addAll !== 'undefined') {
|
||||
return cache.addAll(urls);
|
||||
}
|
||||
|
||||
var promises = [];
|
||||
var self = this;
|
||||
urls.forEach(function(url) {
|
||||
promises.push(self.fetchAndCache(new Request(url), cache));
|
||||
});
|
||||
|
||||
return Promise.all(promises);
|
||||
};
|
||||
|
||||
StaticCacher.prototype.fetchAndCache =
|
||||
function sc_fetchAndCache(request, cache) {
|
||||
|
||||
return fetch(request.clone()).then(function(response) {
|
||||
if (parseInt(response.status) < 400) {
|
||||
cache.put(request.clone(), response.clone());
|
||||
}
|
||||
return response;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
module.exports = StaticCacher;
|
||||
|
||||
},{}],5:[function(require,module,exports){
|
||||
/* global fetch, BroadcastChannel, clients, Promise, Request, Response */
|
||||
'use strict';
|
||||
|
||||
var debug = 1 ? console.log.bind(console, '[ServiceWorkerWare]') : function(){};
|
||||
var StaticCacher = require('./staticcacher.js');
|
||||
var SimpleOfflineCache = require('./simpleofflinecache.js');
|
||||
var Router = require('./router.js');
|
||||
|
||||
var ERROR = 'error';
|
||||
var CONTINUE = 'continue';
|
||||
var TERMINATE = 'terminate';
|
||||
var TERMINATION_TOKEN = {};
|
||||
|
||||
function DEFAULT_FALLBACK_MW(request) {
|
||||
return fetch(request);
|
||||
}
|
||||
|
||||
function ServiceWorkerWare(fallbackMw) {
|
||||
this.middleware = [];
|
||||
this.router = new Router({});
|
||||
this.router.proxyMethods(this);
|
||||
this.fallbackMw = fallbackMw || DEFAULT_FALLBACK_MW;
|
||||
}
|
||||
|
||||
ServiceWorkerWare.prototype.init = function sww_init() {
|
||||
// lifecycle events
|
||||
addEventListener('install', this);
|
||||
addEventListener('activate', this);
|
||||
addEventListener('beforeevicted', this);
|
||||
addEventListener('evicted', this);
|
||||
|
||||
// network events
|
||||
addEventListener('fetch', this);
|
||||
|
||||
// misc events
|
||||
addEventListener('message', this);
|
||||
// XXX: Add default configuration
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle and forward all events related to SW
|
||||
*/
|
||||
ServiceWorkerWare.prototype.handleEvent = function sww_handleEvent(evt) {
|
||||
debug('Event received: ' + evt.type);
|
||||
switch(evt.type) {
|
||||
case 'install':
|
||||
this.onInstall(evt);
|
||||
break;
|
||||
case 'fetch':
|
||||
this.onFetch(evt);
|
||||
break;
|
||||
case 'activate':
|
||||
case 'message':
|
||||
case 'beforeevicted':
|
||||
case 'evicted':
|
||||
this.forwardEvent(evt);
|
||||
break;
|
||||
default:
|
||||
debug('Unhandled event ' + evt.type);
|
||||
}
|
||||
};
|
||||
|
||||
ServiceWorkerWare.prototype.onFetch = function sww_onFetch(evt) {
|
||||
var steps = this.router.match(evt.request.method, evt.request.url);
|
||||
|
||||
// Push the fallback middleware at the end of the list.
|
||||
// XXX bug 1165860: Decorating fallback MW with `stopIfResponse` until
|
||||
// 1165860 lands
|
||||
steps.push((function(req, res) {
|
||||
if (res) {
|
||||
return Promise.resolve(res);
|
||||
}
|
||||
return this.fallbackMw(req, res);
|
||||
}).bind(this));
|
||||
|
||||
evt.respondWith(this.executeMiddleware(steps, evt.request));
|
||||
};
|
||||
|
||||
/**
|
||||
* Run the middleware pipeline and inform if errors preventing respondWith()
|
||||
* to swallow the error.
|
||||
*
|
||||
* @param {Array} the middleware pipeline
|
||||
* @param {Request} the request for the middleware
|
||||
*/
|
||||
ServiceWorkerWare.prototype.executeMiddleware = function (middleware, request) {
|
||||
var response = this.runMiddleware(middleware, 0, request, null);
|
||||
response.catch(function (error) { console.error(error); });
|
||||
return response;
|
||||
};
|
||||
|
||||
/**
|
||||
* Pass through the middleware pipeline, executing each middleware in a
|
||||
* sequence according to the result from each execution.
|
||||
*
|
||||
* Each middleware will be passed with the request and response from the
|
||||
* previous one in the pipeline. The response from the latest one will be
|
||||
* used to answer from the service worker. The middleware will receive,
|
||||
* as the last parameter, a function to stop the pipeline and answer
|
||||
* immediately.
|
||||
*
|
||||
* A middleware run can lead to continuing execution, interruption of the
|
||||
* pipeline or error. The next action to be performed is calculated according
|
||||
* the conditions of the middleware execution and its return value.
|
||||
* See normalizeMwAnswer() for details.
|
||||
*
|
||||
* @param {Array} middleware pipeline.
|
||||
* @param {Number} middleware to execute in the pipeline.
|
||||
* @param {Request} the request for the middleware.
|
||||
* @param {Response} the response for the middleware.
|
||||
*/
|
||||
ServiceWorkerWare.prototype.runMiddleware =
|
||||
function (middleware, current, request, response) {
|
||||
if (current >= middleware.length) {
|
||||
return Promise.resolve(response);
|
||||
}
|
||||
|
||||
var mw = middleware[current];
|
||||
var endWith = ServiceWorkerWare.endWith;
|
||||
var answer = mw(request, response, endWith);
|
||||
var normalized =
|
||||
ServiceWorkerWare.normalizeMwAnswer(answer, request, response);
|
||||
|
||||
return normalized.then(function (info) {
|
||||
switch (info.nextAction) {
|
||||
case TERMINATE:
|
||||
return Promise.resolve(info.response);
|
||||
|
||||
case ERROR:
|
||||
return Promise.reject(info.error);
|
||||
|
||||
case CONTINUE:
|
||||
var next = current + 1;
|
||||
var request = info.request;
|
||||
var response = info.response;
|
||||
return this.runMiddleware(middleware, next, request, response);
|
||||
}
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
/**
|
||||
* A function to force interruption of the pipeline.
|
||||
*
|
||||
* @param {Response} the response object that will be used to answer from the
|
||||
* service worker.
|
||||
*/
|
||||
ServiceWorkerWare.endWith = function (response) {
|
||||
if (arguments.length === 0) {
|
||||
throw new Error('Type error: endWith() must be called with a value.');
|
||||
}
|
||||
return [TERMINATION_TOKEN, response];
|
||||
};
|
||||
|
||||
/**
|
||||
* A middleware is supposed to return a promise resolving in a pair of request
|
||||
* and response for the next one or to indicate that it wants to answer
|
||||
* immediately.
|
||||
*
|
||||
* To allow flexibility, the middleware is allowed to return other values
|
||||
* rather than the promise. For instance, it is allowed to return only a
|
||||
* request meaning the next middleware will be passed that request but the
|
||||
* previous response untouched.
|
||||
*
|
||||
* The function takes into account all the scenarios to compute the request
|
||||
* and response for the next middleware or the intention to terminate
|
||||
* immediately.
|
||||
*
|
||||
* @param {Any} non normalized answer from the middleware.
|
||||
* @param {Request} request passed as parameter to the middleware.
|
||||
* @param {Response} response passed as parameter to the middleware.
|
||||
*/
|
||||
ServiceWorkerWare.normalizeMwAnswer = function (answer, request, response) {
|
||||
if (!answer || !answer.then) {
|
||||
answer = Promise.resolve(answer);
|
||||
}
|
||||
return answer.then(function (value) {
|
||||
var nextAction = CONTINUE;
|
||||
var error, nextRequest, nextResponse;
|
||||
var isArray = Array.isArray(value);
|
||||
|
||||
if (isArray && value[0] === TERMINATION_TOKEN) {
|
||||
nextAction = TERMINATE;
|
||||
nextRequest = request;
|
||||
nextResponse = value[1] || response;
|
||||
}
|
||||
else if (value === null) {
|
||||
nextRequest = request;
|
||||
nextResponse = null;
|
||||
}
|
||||
else if (isArray && value.length === 2) {
|
||||
nextRequest = value[0];
|
||||
nextResponse = value[1];
|
||||
}
|
||||
else if (value instanceof Response) {
|
||||
nextRequest = request;
|
||||
nextResponse = value;
|
||||
}
|
||||
else if (value instanceof Request) {
|
||||
nextRequest = value;
|
||||
nextResponse = response;
|
||||
}
|
||||
else {
|
||||
var msg = 'Type error: middleware must return a Response, ' +
|
||||
'a Request, a pair [Response, Request] or a Promise ' +
|
||||
'resolving to one of these types.';
|
||||
nextAction = ERROR;
|
||||
error = new Error(msg);
|
||||
}
|
||||
|
||||
return {
|
||||
nextAction: nextAction,
|
||||
request: nextRequest,
|
||||
response: nextResponse,
|
||||
error: error
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Walk all the middle ware installed asking if they have prerequisites
|
||||
* (on the way of a promise to be resolved) when installing the SW
|
||||
*/
|
||||
ServiceWorkerWare.prototype.onInstall = function sww_oninstall(evt) {
|
||||
var waitingList = [];
|
||||
this.middleware.forEach(function(mw) {
|
||||
if (typeof mw.onInstall !== 'undefined') {
|
||||
waitingList.push(mw.onInstall());
|
||||
}
|
||||
});
|
||||
evt.waitUntil(Promise.all(waitingList));
|
||||
};
|
||||
|
||||
/**
|
||||
* Register a new middleware layer, they will treat the request in
|
||||
* the order that this layers have been defined.
|
||||
* A middleware layer can behave in the ServiceWorker in two ways:
|
||||
* - Listening to SW lifecycle events (install, activate, message).
|
||||
* - Handle a request.
|
||||
* To handle each case (or both) the middleware object should provide
|
||||
* the following methods:
|
||||
* - on<SW LiveCiclyeEvent>: for listening to SW lifeciclye events
|
||||
* - onFetch: for handling fetch urls
|
||||
*/
|
||||
ServiceWorkerWare.prototype.use = function sww_use() {
|
||||
// If the first parameter is not a function we will understand that
|
||||
// is the path to handle, and the handler will be the second parameter
|
||||
if (arguments.length === 0) {
|
||||
throw new Error('No arguments given');
|
||||
}
|
||||
var mw = arguments[0];
|
||||
var path = '*';
|
||||
var method = this.router.ALL_METHODS;
|
||||
if (typeof mw === 'string') {
|
||||
path = arguments[0];
|
||||
mw = arguments[1];
|
||||
var kind = typeof mw;
|
||||
if (!mw || !(kind === 'object' || kind === 'function')) {
|
||||
throw new Error('No middleware specified');
|
||||
}
|
||||
if (Router.prototype.methods.indexOf(arguments[2]) !== -1) {
|
||||
method = arguments[2];
|
||||
}
|
||||
}
|
||||
|
||||
this.middleware.push(mw);
|
||||
// Add to the router just if middleware object is able to handle onFetch
|
||||
// or if we have a simple function
|
||||
var handler = null;
|
||||
if (typeof mw.onFetch === 'function') {
|
||||
handler = mw.onFetch.bind(mw);
|
||||
} else if (typeof mw === 'function') {
|
||||
handler = mw;
|
||||
}
|
||||
if (handler) {
|
||||
this.router.add(method, path, handler);
|
||||
}
|
||||
// XXX: Attaching the broadcastMessage to mw that implements onMessage.
|
||||
// We should provide a way to get a reference to the SWW object and do
|
||||
// the broadcast from there
|
||||
if (typeof mw.onMessage === 'function') {
|
||||
mw.broadcastMessage = this.broadcastMessage;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Forward the event received to any middleware layer that has a 'on<Event>'
|
||||
* handler
|
||||
*/
|
||||
ServiceWorkerWare.prototype.forwardEvent = function sww_forwardEvent(evt) {
|
||||
this.middleware.forEach(function(mw) {
|
||||
var handlerName = 'on' + evt.type.replace(/^[a-z]/,
|
||||
function(m){
|
||||
return m.toUpperCase();
|
||||
}
|
||||
);
|
||||
if (typeof mw[handlerName] !== 'undefined') {
|
||||
mw[handlerName].call(mw, evt);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Broadcast a message to all worker clients
|
||||
* @param msg Object the message
|
||||
* @param channel String (Used just in Firefox Nightly) using broadcastchannel
|
||||
* api to deliver the message, this parameter can be undefined as we listen for
|
||||
* a channel undefined in the client.
|
||||
*/
|
||||
ServiceWorkerWare.prototype.broadcastMessage = function sww_broadcastMessage(
|
||||
msg, channel) {
|
||||
// XXX: Until https://bugzilla.mozilla.org/show_bug.cgi?id=1130685 is fixed
|
||||
// we can use BroadcastChannel API in Firefox Nightly
|
||||
if (typeof BroadcastChannel === 'function') {
|
||||
var bc = new BroadcastChannel(channel);
|
||||
bc.postMessage(msg);
|
||||
bc.close();
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
// This is suppose to be the way of broadcasting a message, unfortunately
|
||||
// it's not working yet in Chrome Canary
|
||||
return clients.matchAll().then(function(consumers) {
|
||||
consumers.forEach(function(client) {
|
||||
client.postMessage(msg);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
ServiceWorkerWare.decorators = {
|
||||
|
||||
ifNoResponse: function (mw) {
|
||||
return function (req, res, endWith) {
|
||||
if (res) { return [req, res]; }
|
||||
return mw(req, res, endWith);
|
||||
};
|
||||
},
|
||||
|
||||
stopAfter: function (mw) {
|
||||
return function (req, res, endWith) {
|
||||
var answer = mw(req, res, endWith);
|
||||
var normalized = ServiceWorkerWare.normalizeMwAnswer(answer, req, res);
|
||||
|
||||
return normalized.then(function (info) {
|
||||
if (info.nextAction === 'error') {
|
||||
return Promise.reject(info.error);
|
||||
}
|
||||
return endWith(info.response);
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
ServiceWorkerWare: ServiceWorkerWare,
|
||||
StaticCacher: StaticCacher,
|
||||
SimpleOfflineCache: SimpleOfflineCache
|
||||
};
|
||||
|
||||
},{"./router.js":2,"./simpleofflinecache.js":3,"./staticcacher.js":4}],6:[function(require,module,exports){
|
||||
/* global caches, fetch, Promise, Request, module*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var CacheHelper = {
|
||||
defaultCacheName: 'offline',
|
||||
getCache: function getCache(name) {
|
||||
return caches.open(name);
|
||||
},
|
||||
getDefaultCache: function getDefaultCache() {
|
||||
return this.getCache(this.defaultCacheName);
|
||||
},
|
||||
fetchAndCache: function fetchAndChache(request, cache) {
|
||||
return fetch(request.clone()).then(function(response) {
|
||||
var clone = response.clone();
|
||||
if (parseInt(clone.status) < 400) {
|
||||
cache.put(request.clone(), response.clone());
|
||||
}
|
||||
|
||||
return response.clone();
|
||||
});
|
||||
},
|
||||
addAll: function addAll(cache, urls) {
|
||||
if (!cache) {
|
||||
throw new Error('Need a cache to store things');
|
||||
}
|
||||
// Polyfill until chrome implements it
|
||||
if (typeof cache.addAll !== 'undefined') {
|
||||
return cache.addAll(urls);
|
||||
}
|
||||
|
||||
var promises = [];
|
||||
var self = this;
|
||||
urls.forEach(function(url) {
|
||||
promises.push(self.fetchAndCache(new Request(url), cache));
|
||||
});
|
||||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = CacheHelper;
|
||||
})();
|
||||
|
||||
},{}]},{},[1])
|
||||
|
||||
|
||||
//# sourceMappingURL=sww.js.map
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue