;'use strict';function $(id){return document.getElementById(id);} function $$(expr){return document.querySelectorAll(expr);} var mozFMRadio=navigator.mozFM||navigator.mozFMRadio||{speakerEnabled:false,frequency:null,enabled:false,antennaAvailable:true,signalStrength:1,frequencyLowerBound:87.5,frequencyUpperBound:108,channelWidth:0.1,onsignalstrengthchange:function emptyFunction(){},onfrequencychange:function emptyFunction(){},onenabled:function emptyFunction(){},ondisabled:function emptyFunction(){},onantennaavailablechange:function emptyFunction(){},disable:function fm_disable(){if(!this.enabled){return;} this.enabled=false;var self=this;window.setTimeout(function(){self.ondisabled();},500);return{};},enable:function fm_enable(frequency){if(this.enabled){return;} this.enabled=true;var self=this;window.setTimeout(function(){self.onenabled();self.setFrequency(frequency);},500);return{};},setFrequency:function fm_setFrequency(freq){freq=parseFloat(freq.toFixed(1));var previousValue=this.frequency;this.frequency=freq;if(previousValue!=freq){this.onfrequencychange();} return{};},seekUp:function fm_seekUp(){var self=this;if(this._seekRequest){return;} this._seekRequest={};this._seekTimeout=window.setTimeout(function su_timeout(){self.setFrequency(self.frequency+0.5);if(self._seekRequest.onsuccess){self._seekRequest.onsuccess();} self._clearSeekRequest();},1000);return this._seekRequest;},seekDown:function fm_seekDown(){var self=this;if(this._seekRequest){return;} this._seekRequest={};this._seekTimeout=window.setTimeout(function sd_timeout(){self.setFrequency(self.frequency-0.5);if(self._seekRequest.onsuccess){self._seekRequest.onsuccess();} self._clearSeekRequest();},1000);return this._seekRequest;},cancelSeek:function fm_cancelSeek(){this._clearSeekRequest();var request={};window.setTimeout(function(){if(request.onsuccess){request.onsuccess();}},0);return request;},_clearSeekRequest:function fm_clearSeek(){if(this._seekTimeout){window.clearTimeout(this._seekTimeout);this._seekTimeout=null;} if(this._seekRequest&&this._seekRequest.onerror){this._seekRequest.onerror();this._seekRequest=null;}}};(function(aGlobal){aGlobal.SpeakerManager=aGlobal.SpeakerManager||aGlobal.MozSpeakerManager;if(aGlobal.SpeakerManager){return;} function SpeakerManager(){this.speakerforced=false;} SpeakerManager.prototype={set forcespeaker(enable){if(this.speakerforced!=enable){this.speakerforced=enable;if(this.onspeakerforcedchange){this.onspeakerforcedchange();}}}};aGlobal.SpeakerManager=SpeakerManager;})(window);var enabling=false;function updatePowerUI(){var enabled=mozFMRadio.enabled;var powerSwitch=$('power-switch');if(enabled){window.performance.mark('fmRadioEnabled');powerSwitch.setAttribute('data-l10n-id','power-switch-off');}else{powerSwitch.setAttribute('data-l10n-id','power-switch-on');} console.log('Power status: '+(enabled?'on':'off'));powerSwitch.dataset.enabled=enabled;powerSwitch.dataset.enabling=enabling;} var airplaneModeEnabled=false;function updateWarningModeUI(){$('airplane-mode-warning').hidden=!airplaneModeEnabled;$('antenna-warning').hidden=mozFMRadio.antennaAvailable||airplaneModeEnabled;$('container').classList.toggle('hidden-block',airplaneModeEnabled||!mozFMRadio.antennaAvailable);} function updateFrequencyBarUI(){var frequencyBar=$('frequency-bar');if(enabling){frequencyBar.classList.add('dim');}else{frequencyBar.classList.remove('dim');}} function updateEnablingState(enablingState){enabling=enablingState;updatePowerUI();updateFrequencyBarUI();} function enableFMRadio(frequency){if(airplaneModeEnabled){return;} var request=mozFMRadio.enable(frequency);request.onerror=function onerror_enableFMRadio(event){updateEnablingState(false);};updateEnablingState(true);} function cancelSeekAndSetFreq(frequency){function setFreq(){mozFMRadio.setFrequency(frequency);} var seeking=!!$('power-switch').getAttribute('data-seeking');if(!seeking){setFreq();}else{var request=mozFMRadio.cancelSeek();request.onsuccess=setFreq;request.onerror=setFreq;}} var frequencyDialer={unit:2,_bandUpperBound:0,_bandLowerBound:0,_minFrequency:0,_maxFrequency:0,_currentFreqency:0,_translateX:0,init:function(){updateWarningModeUI();this._initUI();this.setFrequency(mozFMRadio.frequency);this._addEventListeners();},_addEventListeners:function(){function _removeEventListeners(){document.body.removeEventListener('touchend',fd_body_touchend,false);document.body.removeEventListener('touchmove',fd_body_touchmove,false);} function cloneEvent(evt){if('touches'in evt){evt=evt.touches[0];} return{x:evt.clientX,y:evt.clientX,timestamp:evt.timeStamp};} var self=this;var SPEED_THRESHOLD=0.1;var currentEvent,startEvent,currentSpeed;var tunedFrequency=0;function toFixed(frequency){return parseFloat(frequency.toFixed(1));} function _calcSpeed(){var movingSpace=startEvent.x-currentEvent.x;var deltaTime=currentEvent.timestamp-startEvent.timestamp;var speed=movingSpace/deltaTime;currentSpeed=parseFloat(speed.toFixed(2));} function _calcTargetFrequency(){return tunedFrequency-getMovingSpace()/self._space;} function getMovingSpace(){var movingSpace=currentEvent.x-startEvent.x;return movingSpace;} function fd_body_touchmove(event){event.stopPropagation();currentEvent=cloneEvent(event);_calcSpeed();var dialer=$('frequency-dialer');var translateX=self._translateX+getMovingSpace();self._translateX=translateX;var count=dialer.childNodes.length;for(var i=0;iSPEED_THRESHOLD){var direction=currentSpeed>0?1:-1;tunedFrequency+=Math.min(Math.abs(currentSpeed)*3,3)*direction;} tunedFrequency=self.setFrequency(toFixed(tunedFrequency));cancelSeekAndSetFreq(tunedFrequency);currentEvent=null;startEvent=null;currentSpeed=0;} function fd_touchstart(event){event.stopPropagation();$('frequency-dialer').classList.remove('animation-on');startEvent=currentEvent=cloneEvent(event);tunedFrequency=self._currentFreqency;_removeEventListeners();document.body.addEventListener('touchmove',fd_body_touchmove,false);document.body.addEventListener('touchend',fd_body_touchend,false);} function fd_key(event){if(event.keyCode===event.DOM_VK_UP){tunedFrequency=self._currentFreqency+0.1;}else if(event.keyCode===event.DOM_VK_DOWN){tunedFrequency=self._currentFreqency-0.1;}else{return;} tunedFrequency=self.setFrequency(toFixed(tunedFrequency));cancelSeekAndSetFreq(tunedFrequency);} var dialerContainer=$('dialer-container');dialerContainer.addEventListener('touchstart',fd_touchstart,false);dialerContainer.addEventListener('keypress',fd_key,false);},_initUI:function(){$('frequency-dialer').innerHTML='';var lower=this._bandLowerBound=mozFMRadio.frequencyLowerBound;var upper=this._bandUpperBound=mozFMRadio.frequencyUpperBound;var unit=this.unit;this._minFrequency=lower-lower%unit;this._maxFrequency=upper+unit-upper%unit;var unitCount=(this._maxFrequency-this._minFrequency)/unit;for(var i=0;iend){endMaskWidth+=unitWidth;}} var container=document.createElement('div');container.classList.add('dialer-unit-mark-box');if(startMaskWidth>0){var markEl=document.createElement('div');markEl.classList.add('dialer-unit-mark-mask-start');markEl.style.width=startMaskWidth+'px';container.appendChild(markEl);} if(endMaskWidth>0){var markEnd=document.createElement('div');markEnd.classList.add('dialer-unit-mark-mask-end');markEnd.style.width=endMaskWidth+'px';container.appendChild(markEnd);} var width=(100/this.unit)+'%';for(var j=0;j=start&&frequency<=end;var unit=document.createElement('div');unit.classList.add('dialer-unit-floor');if(!showFloor){unit.classList.add('hidden-block');} unit.style.width=width;unit.appendChild(document.createTextNode(frequency));container.appendChild(unit);} var dialerUnit=document.createElement('div');dialerUnit.className='dialer-unit';dialerUnit.appendChild(container);$('frequency-dialer').appendChild(dialerUnit);},_updateUI:function(frequency,ignoreDialer){document.l10n.setAttributes($('frequency'),'frequency-MHz',{value:frequency.toFixed(1)});if(true!==ignoreDialer){this._translateX=(this._minFrequency-frequency)*this._space;var dialer=$('frequency-dialer');var count=dialer.childNodes.length;for(var i=0;ithis._bandUpperBound){frequency=this._bandUpperBound;} this._currentFreqency=frequency;this._updateUI(frequency,ignoreDialer);return frequency;},getFrequency:function(){return this._currentFreqency;}};var historyList={_historyList:[],KEYNAME:'historylist',SIZE:1,init:function hl_init(callback){var self=this;window.asyncStorage.getItem(this.KEYNAME,function storage_getItem(value){self._historyList=value||[];if(typeof callback=='function'){callback();}});},_save:function hl_save(){window.asyncStorage.setItem(this.KEYNAME,this._historyList);},add:function hl_add(freq){if(freq==null){return;} var self=this;self._historyList.push({name:freq+'',frequency:freq});if(self._historyList.length>self.SIZE){self._historyList.shift();} self._save();},last:function hl_last(){if(this._historyList.length===0){return null;} else{return this._historyList[this._historyList.length-1];}}};var favoritesList={_favList:null,KEYNAME:'favlist',init:function(callback){var self=this;window.asyncStorage.getItem(this.KEYNAME,function storage_getItem(value){self._favList=value||{};self._showListUI();if(typeof callback=='function'){callback();}});var _container=$('fav-list-container');_container.addEventListener('click',function _onclick(event){var frequency=self._getElemFreq(event.target);if(!frequency){return;} if(event.target.classList.contains('fav-list-remove-button')){self.remove(frequency);updateFreqUI();}else{if(mozFMRadio.enabled){cancelSeekAndSetFreq(frequency);}else{enableFMRadio(frequency);}}});},_save:function(){window.asyncStorage.setItem(this.KEYNAME,this._favList);},_showListUI:function(){var self=this;this.forEach(function(f){self._addItemToListUI(f);});},_addItemToListUI:function(item){var container=$('fav-list-container');var elem=document.createElement('div');elem.id=this._getUIElemId(item);elem.className='fav-list-item';elem.setAttribute('role','option');var subElem=document.createElement('div');subElem.className='fav-list-frequency';document.l10n.setAttributes(subElem,'fav-frequency-MHz',{value:item.frequency.toFixed(1)});elem.appendChild(subElem);subElem=document.createElement('div');subElem.className='fav-list-remove-button';elem.appendChild(subElem);if(container.childNodes.length===0){container.appendChild(elem);}else{var childNodes=container.childNodes;for(var i=0;i