Publish Vulpes Preview 15 sources for desktop, Android and Tundra

Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,14 @@
<element name="conference-group-details" extends="form">
<template>
<header></header>
<menu>
<ul id="group-call-details-list">
</ul>
<span class="last-button-container">
<button id="group-hide" data-l10n-id="close">
Close
</button>
</span>
</menu>
</template>
</element>

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,338 @@
<!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>Dialer</title>
<!-- CSS -->
<link rel="stylesheet" type="text/css" href="app://theme.gaiamobile.org/shared/elements/gaia-theme/gaia-theme.css">
<link rel="stylesheet" type="text/css" href="/style/oncall.css">
<link rel="stylesheet" type="text/css" href="/style/conference_group_ui.css">
<link rel="stylesheet" type="text/css" href="/style/oncall_status_bar.css">
<link rel="stylesheet" type="text/css" href="/style/status.css">
<link rel="stylesheet" type="text/css" href="/shared/style/dialer/keypad.css">
<link rel="stylesheet" type="text/css" href="/shared/style/dialer/overlay.css">
<link rel="stylesheet" type="text/css" href="/shared/style/status.css">
<link rel="stylesheet" type="text/css" href="/shared/style/action_menu.css">
<!-- Localization -->
<!-- <script defer="" type="text/javascript" src="/shared/js/lazy_loader.js"></script> -->
<meta name="defaultLanguage" content="en-US">
<meta name="availableLanguages" content="ar:201601260730, bg:201601260730, bn-BD:201601260730, ca:201601260730, cs:201601260730, da:201601260730, de:201601260730, el:201601260730, en-US:201601260730, es:201601260730, eu:201601260730, fr:201601260730, gl:201601260730, hr:201601260730, hu:201601260730, it:201601260730, ja:201601260730, km:201601260730, ko:201601260730, lt:201601260730, mk:201601260730, ms:201601260730, ne-NP:201601260730, nl:201601260730, pa:201601260730, pl:201601260730, pt-BR:201601260730, ro:201601260730, ru:201601260730, sk:201601260730, sq:201601260730, sr-Cyrl:201601260730, sr-Latn:201601260730, sv-SE:201601260730, tr:201601260730, zh-CN:201601260730, zh-TW:201601260730">
<link rel="localization" href="/locales-obj/index.{locale}.json">
<!-- <script defer="" type="application/javascript" src="/shared/js/l10n.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/shared/js/moz_intl.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/js/index.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/shared/js/settings_listener.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/shared/js/settings_url.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/shared/js/async_storage.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/shared/js/contact_photo_helper.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/shared/js/font_size_utils.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/shared/js/date_time_helper.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/shared/js/simple_phone_matcher.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/shared/js/dialer/contacts.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/shared/js/dialer/tone_player.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/shared/js/dialer/dtmf_tone.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/shared/js/dialer/keypad.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/shared/js/dialer/utils.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/shared/js/dialer/font_size_manager.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/shared/js/dialer/voicemail.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/shared/js/bluetooth_helper.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/js/call_screen.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/js/calls_handler.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/js/conference_group_handler.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/js/conference_group_ui.js"></script> -->
<!-- <script defer="" type="application/javascript" src="/js/handled_call.js"></script> -->
<!-- Lazy load these:
<script defer type="application/javascript" src="/shared/js/fb/fb_request.js"></script>
<script defer type="application/javascript" src="/shared/js/fb/fb_data_reader.js"></script>
<script defer type="application/javascript" src="/shared/js/fb/fb_reader_utils.js"></script>
-->
<!-- incoming call / swiper on locked screen-->
<link rel="stylesheet" type="text/css" href="/style/lockscreen.css">
<!-- <script defer="" src="/shared/js/settings_listener.js"></script> -->
<!-- <script defer="" src="/shared/js/mobile_operator.js"></script> -->
<!-- <script defer="" src="/shared/js/lockscreen_slide.js"></script> -->
<!-- <script defer="" src="/shared/js/screen_layout.js"></script> -->
<!-- <script defer="" src="/shared/js/simslot.js"></script> -->
<!-- <script defer="" src="/shared/js/simslot_manager.js"></script> -->
<!-- <script defer="" src="/shared/js/lockscreen_connection_info_manager.js"></script> --><script src="./gaia_build_defer_index.js" defer="" type="text/javascript"></script>
<meta content="2.5" name="appVersion"></head>
<body class="skin-comms theme-communications">
<article id="call-screen" data-layout="" class="displayed" aria-labelledby="call-number-wrapper, group-call-number-wrapper">
<div id="lockscreen-header">
<div id="lockscreen-conn-states">
</div>
<div id="lockscreen-clock-widget">
<div id="lockscreen-clock-time"></div>
<div id="lockscreen-date"></div>
</div>
</div>
<article id="calls" data-count="0">
<section id="handled-call-template" role="dialog" hidden="">
<div aria-label="Hang Up" class="hangup-button" role="button" data-l10n-id="hangup-a11y-button"></div>
<div id="call-number-wrapper" class="numberWrapper direction-status-bar">
<div class="number font-light"><bdi></bdi></div>
<span role="button" id="switch-calls-button"></span>
</div>
<div class="additionalContactInfo font-light">
<span class="tel-type" dir="auto"></span>
<span class="separator"></span>
<span class="tel" dir="ltr"></span>
</div>
<div class="duration">
<span class="font-light"></span>
<div class="total-duration"></div>
<div class="direction"></div>
</div>
<div class="sim">
<!-- Depending on the context, none or only one of those will be displayed -->
<span class="via-sim"></span>
<span class="sim-number"></span>
</div>
</section>
<section id="group-call" hidden="">
<div id="group-call-number-wrapper" class="numberWrapper">
<div id="group-show"></div>
<div id="group-call-label" class="number font-light"></div>
</div>
<div id="group-call-summary" class="additionalContactInfo font-light">
<span class="tel-type" dir="auto"></span>
<span class="separator"></span>
<span class="tel" dir="ltr"></span>
</div>
<div class="duration">
<span class="font-light"></span>
<div class="total-duration"></div>
<div class="direction"></div>
</div>
</section>
</article>
<form id="group-call-details" role="dialog" data-type="action" class="overlay"><!--
<header></header>
<menu>
<ul id="group-call-details-list">
</ul>
<span class="last-button-container">
<button id="group-hide" data-l10n-id="close">
Close
</button>
</span>
</menu>
--></form>
<form id="bluetooth-menu" role="dialog" data-type="action" class="overlay">
<header data-l10n-id="select-audio-sources">Select audio sources</header>
<menu>
<button data-l10n-id="bluetooth-handsfree-device" id="btmenu-btdevice">Bluetooth handsfree device</button>
<button data-l10n-id="receiver" id="btmenu-receiver">Receiver</button>
<button data-l10n-id="speaker" id="btmenu-speaker">Speaker</button>
<button data-l10n-id="cancel" id="btmenu-cancel">Cancel</button>
</menu>
</form>
<article id="main-container">
<div id="contact-background"></div>
<div id="lockscreen-masked-background" class="blank"></div>
<div id="lockscreen-area"></div>
<div id="actions-container">
<div id="swiper-wrapper">
<div id="lockscreen-icon-container">
<div id="lockscreen-area-hangup" class="lockscreen-icon-area lockscreen-icon-left dark" role="button" data-l10n-id="hangup-a11y-button" aria-label="Hang Up">
<div class="lockscreen-icon">
</div>
</div>
<div id="lockscreen-area-pickup" class="lockscreen-icon-area lockscreen-icon-right dark" role="button" data-l10n-id="pickup-a11y-button" aria-label="Pick up">
<div class="lockscreen-icon">
</div>
</div>
<div id="lockscreen-area-slide" class="lockscreen-icon-area lockscreen-icon-center">
<div id="lockscreen-canvas-wrapper">
<canvas id="lockscreen-canvas"></canvas>
</div>
</div>
</div>
</div>
<section id="statusMsg" role="status">
<p></p>
</section>
<footer id="call-options">
<section id="co-advanced">
<div class="grid-wrapper grid">
<span class="grid-cell options-column">
<button aria-label="Mute" id="mute" class="co-advanced-option grid center" data-l10n-id="mute">
<span class="icon icon-mute"></span>
</button>
</span>
<span class="grid-cell options-column">
<button aria-label="Toggle keypad" id="keypad-visibility" class="co-advanced-option grid center" data-l10n-id="toggleKeypad">
<span class="icon icon-keypad-visibility"></span>
</button>
</span>
<span id="place-new-call-container" class="grid-cell options-column">
<button aria-label="New call" id="place-new-call" disabled="" class="co-advanced-option grid center" data-l10n-id="newCall">
<span class="icon icon-place-new-call"></span>
</button>
</span>
<span class="grid-cell options-column">
<button aria-label="Speaker" id="speaker" class="co-advanced-option grid" data-l10n-id="speakerOption">
<span class="icon icon-speaker"></span>
</button>
<button aria-label="Bluetooth" id="bt" class="co-advanced-option grid hide" data-l10n-id="bluetoothOption" hidden="">
<span class="icon icon-bt"></span>
</button>
</span>
<span id="hold-and-merge-container" class="grid-cell options-column">
<button aria-label="On hold" id="on-hold" class="co-advanced-option grid" disabled="" data-l10n-id="onHoldOption">
<span class="icon icon-on-hold"></span>
</button>
<button aria-label="Merge" id="merge" class="co-advanced-option grid hide" data-l10n-id="merge">
<span class="icon icon-merge"></span>
</button>
</span>
</div>
</section>
<footer id="callbar">
<button aria-label="Hang Up" id="callbar-hang-up" data-l10n-id="hangup-a11y-button">
<div class="callbar-inner-button">
</div>
</button>
<button aria-label="Pick up" id="callbar-answer" data-l10n-id="pickup-a11y-button">
<div class="callbar-inner-button">
</div>
</button>
</footer>
</footer>
</div>
</article>
</article>
<article id="incoming-container">
<header dir="ltr">
<button aria-label="Hang Up" id="incoming-end" data-l10n-id="hangup-a11y-button">
</button>
<button aria-label="Hold" id="incoming-answer" data-l10n-id="hold">
</button>
</header>
<section id="incoming-info">
<div class="incoming-number-info">
<span id="incoming-number" dir="auto"></span>
<div id="incoming-number-additional-info" class="font-light">
<span id="incoming-number-additional-info-tel-type" dir="auto"></span>
<span class="separator"></span>
<span id="incoming-number-additional-info-tel" dir="ltr"></span>
</div>
</div>
<div id="incoming-sim" class="sim"></div>
<button id="incoming-ignore" data-l10n-id="ignore">Ignore Call</button>
</section>
</article>
<article id="views">
<article id="keyboard-view" class="view">
<div id="phone-number-view-container">
<div>
<div class="grid-wrapper">
<input aria-label="Phone number" id="phone-number-view" class="phone-number-font font-light" readonly="readonly" data-l10n-id="phoneNumberInput" type="text">
</div>
</div>
<div aria-label="Delete" id="keypad-delete" role="key" data-l10n-id="keypadDelete">
<div></div>
</div>
</div>
<article id="keyboard-container">
<section id="keypad" dir="ltr">
<div class="keypad-row">
<div class="keypad-key" role="key" data-value="1">
<span>1</span>
<em aria-label="Voicemail" class="keypad-subicon voicemail" data-l10n-id="voiceMailKey"></em>
</div>
<div class="keypad-key" role="key" data-value="2">
<span>2</span>
<em>ABC</em>
</div>
<div class="keypad-key" role="key" data-value="3">
<span>3</span>
<em>DEF</em>
</div>
</div>
<div class="keypad-row">
<div class="keypad-key" role="key" data-value="4">
<span>4</span>
<em>GHI</em>
</div>
<div class="keypad-key" role="key" data-value="5">
<span>5</span>
<em>JKL</em>
</div>
<div class="keypad-key" role="key" data-value="6">
<span>6</span>
<em>MNO</em>
</div>
</div>
<div class="keypad-row">
<div class="keypad-key" role="key" data-value="7">
<span>7</span>
<em>PQRS</em>
</div>
<div class="keypad-key" role="key" data-value="8">
<span>8</span>
<em>TUV</em>
</div>
<div class="keypad-key" role="key" data-value="9">
<span>9</span>
<em>WXYZ</em>
</div>
</div>
<div class="keypad-row">
<div aria-label="Asterisk" class="keypad-key keypad-key-centered" role="key" data-value="*" data-l10n-id="asterisk">
<div class="asterisk">*</div>
</div>
<div class="keypad-key" role="key" data-value="0">
<span>0</span>
<em class="font-size-plus">+</em>
</div>
<div aria-label="Hash sign" class="keypad-key keypad-key-centered" role="key" data-type="dial" data-value="#" data-l10n-id="hashSign">
<div class="sharp">#</div>
</div>
</div>
</section>
<section id="keypad-callbar">
<div>
<span aria-label="Add contact" role="button" id="keypad-callbar-add-contact" data-type="action" data-value="add-contact" data-l10n-id="dialerAddContact" disabled="" aria-disabled="true">
<div class="icon-add-contact"></div>
</span>
</div>
<div>
<span aria-label="Make call" role="button" id="keypad-callbar-call-action" data-type="action" data-value="make-call" data-l10n-id="makeCall">
<div>
</div>
</span>
</div>
</section>
<section id="keypad-hidebar">
<button id="keypad-hidebar-mute-action" class="kh__button kh__button--mute"></button>
<button id="keypad-hidebar-hang-up-action-wrapper" class="kh__call-end-button"></button>
<button id="keypad-hidebar-hide-keypad-action" class="kh__button kh__button--hide"></button>
</section>
</article>
</article>
</article>
</body>
</html>

View file

@ -0,0 +1,10 @@
;'use strict';var CallScreen={_ticker:null,_screenWakeLock:null,_typedNumber:'',callEndPromptTime:2000,body:document.body,screen:document.getElementById('call-screen'),lockscreenConnStates:document.getElementById('lockscreen-conn-states'),views:document.getElementById('views'),calls:document.getElementById('calls'),mainContainer:document.getElementById('main-container'),contactBackground:document.getElementById('contact-background'),callOptions:document.getElementById('call-options'),callToolbar:document.getElementById('co-advanced'),muteButton:document.getElementById('mute'),speakerButton:document.getElementById('speaker'),bluetoothButton:document.getElementById('bt'),keypadButton:document.getElementById('keypad-visibility'),placeNewCallButton:document.getElementById('place-new-call'),holdButton:document.getElementById('on-hold'),mergeButton:document.getElementById('merge'),holdAndMergeContainer:document.getElementById('hold-and-merge-container'),hideBarMuteButton:document.getElementById('keypad-hidebar-mute-action'),bluetoothMenu:document.getElementById('bluetooth-menu'),switchToDeviceButton:document.getElementById('btmenu-btdevice'),switchToReceiverButton:document.getElementById('btmenu-receiver'),switchToSpeakerButton:document.getElementById('btmenu-speaker'),bluetoothMenuCancel:document.getElementById('btmenu-cancel'),answerButton:document.getElementById('callbar-answer'),rejectButton:document.getElementById('callbar-hang-up'),incomingContainer:document.getElementById('incoming-container'),incomingInfo:document.getElementById('incoming-info'),incomingNumber:document.getElementById('incoming-number'),incomingSim:document.getElementById('incoming-sim'),incomingNumberAdditionalTel:document.getElementById('incoming-number-additional-info-tel'),incomingNumberAdditionalTelType:document.getElementById('incoming-number-additional-info-tel-type'),incomingAnswer:document.getElementById('incoming-answer'),incomingEnd:document.getElementById('incoming-end'),incomingIgnore:document.getElementById('incoming-ignore'),lockedClockTime:document.getElementById('lockscreen-clock-time'),lockedDate:document.getElementById('lockscreen-date'),statusMessage:document.getElementById('statusMsg'),showStatusMessage:function cs_showStatusMessage(message){var STATUS_TIME=2000;var paragraph=this.statusMessage.querySelector('p');var self=this;if(typeof(message)==='string'){navigator.mozL10n.setAttributes(paragraph,message);}else if(message.id){navigator.mozL10n.setAttributes(paragraph,message.id,message.args);}
this.statusMessage.classList.add('visible');this.statusMessage.addEventListener('transitionend',function tend(evt){evt.stopPropagation();self.statusMessage.removeEventListener('transitionend',tend);setTimeout(function hide(){self.statusMessage.classList.remove('visible');},STATUS_TIME);});},updateCallsDisplay:function cs_updateCallsDisplay(){var visibleCalls=this.calls.querySelectorAll('section:not([hidden])').length;this.body.classList.toggle('single-line',visibleCalls<=1);this.calls.classList.toggle('big-duration',visibleCalls<=1);CallsHandler.updateAllPhoneNumberDisplays();},hidePlaceNewCallButton:function cs_hidePlaceNewCallButton(){this.callToolbar.classList.add('no-add-call');},showPlaceNewCallButton:function cs_showPlaceNewCallButton(){this.callToolbar.classList.remove('no-add-call');},set holdAndAnswerOnly(enabled){this.incomingContainer.classList.toggle('hold-and-answer-only',enabled);},set cdmaCallWaiting(enabled){this.calls.classList.toggle('switch',enabled);this.callToolbar.classList.toggle('no-add-call',enabled);},get inStatusBarMode(){return window.innerHeight<=40;},init:function cs_init(){this.muteButton.addEventListener('click',this.toggleMute.bind(this));this.hideBarMuteButton.addEventListener('click',this.toggleMute.bind(this));this.keypadButton.addEventListener('click',this.showKeypad.bind(this));this.placeNewCallButton.addEventListener('click',this.placeNewCall.bind(this));this.speakerButton.addEventListener('click',this.toggleSpeaker.bind(this));this.bluetoothButton.addEventListener('click',this.toggleBluetoothMenu.bind(this));this.holdButton.addEventListener('click',CallsHandler.holdOrResumeSingleCall.bind(this));this.mergeButton.addEventListener('click',CallsHandler.mergeCalls.bind(this));this.answerButton.addEventListener('click',CallsHandler.answer);this.rejectButton.addEventListener('click',CallsHandler.end);this.switchToDeviceButton.addEventListener('click',this.switchToDefaultOut.bind(this,false));this.switchToReceiverButton.addEventListener('click',this.switchToReceiver.bind(this));this.switchToSpeakerButton.addEventListener('click',this.switchToSpeaker.bind(this));this.bluetoothMenuCancel.addEventListener('click',this.toggleBluetoothMenu.bind(this));this.incomingAnswer.addEventListener('click',CallsHandler.holdAndAnswer);this.incomingEnd.addEventListener('click',CallsHandler.endAndAnswer);this.incomingIgnore.addEventListener('click',CallsHandler.ignore);this.calls.addEventListener('click',CallsHandler.toggleCalls.bind(this));window.addEventListener('resize',this.resizeHandler.bind(this));SettingsListener.observe('wallpaper.image',null,this._wallpaperImageHandler.bind(this));this._lockScreenLayoutInitialized=false;navigator.mozSettings.addObserver('lockscreen.locked',this._lockscreenStateChange.bind(this));this.syncSpeakerEnabled();},initLockScreenConnInfoManager:function cs_initLockScreenConnInfoManager(){if(window.navigator.mozMobileConnections){new window.LockScreenConnInfoManager(CallScreen.lockscreenConnStates);}},initLockScreenSlide:function cs_initLockScreenSlide(){this.hangUpIcon=document.getElementById('lockscreen-area-hangup');this.pickUpIcon=document.getElementById('lockscreen-area-pickup');this.initUnlockerEvents();new LockScreenSlide({useNewStyle:true,IDs:{overlay:'main-container',areas:{left:'lockscreen-area-hangup',right:'lockscreen-area-pickup'},},trackNew:{strokeColorTop:'rgba(0, 0, 0, 0)',strokeColorBottom:'rgba(0, 0, 0, 0)',fillColorTop:'rgba(0, 0, 0, 0.1)',fillColorBottom:'rgba(0, 0, 0, 0.1)'},colors:{left:{touchedColor:'224, 0, 0',touchedColorStop:'255, 255, 255'},right:{touchedColor:'0, 173, 173',touchedColorStop:'255, 255, 255'}},iconBG:{left:{color:'rgba(224, 0, 0, 0.80)'},right:{color:'rgba(0, 173, 173, 0.80)'}},resourcesNew:{larrow:'/style/images/lock_screen/lockscreen_toggle_arrow_left.png',rarrow:'/style/images/lock_screen/lockscreen_toggle_arrow_right.png'}});},_lockscreenStateChange:function cs_lockscreenStateChange(event){if(event.settingValue){if(this.screen.dataset.layout==='incoming'){this.initLockScreenLayout();this.render('incoming-locked');}
this.initUnlockerEvents();}else{if(this.screen.dataset.layout==='incoming-locked'){this.render('incoming');}
this.suspendUnlockerEvents();}},_wallpaperImageHandler:function cs_wallpaperImageHandler(image){this.mainContainer.style.backgroundImage='url('+
(typeof image==='string'?image:URL.createObjectURL(image))+')';},setCallerContactImage:function cs_setCallerContactImage(){var activeCallForContactImage=CallsHandler.activeCallForContactImage;var blob=activeCallForContactImage&&activeCallForContactImage.photo;var background=blob?'url('+URL.createObjectURL(blob)+')':'';this.contactBackground.style.backgroundImage=background;},insertCall:function cs_insertCall(node){this.calls.appendChild(node);this.updateCallsDisplay();},removeCall:function cs_removeCall(node){if(node.parentNode){node.parentNode.removeChild(node);this.updateCallsDisplay();}},resizeHandler:function cs_resizeHandler(){if(!this.body.classList.contains('showKeypad')){this.updateCallsDisplay(this.inStatusBarMode);}else if(this.inStatusBarMode){this._typedNumber=KeypadManager._phoneNumber;KeypadManager.restorePhoneNumber();}else{KeypadManager.updatePhoneNumber(this._typedNumber,'begin',true);}},_lockScreenLayoutInitialized:false,initLockScreenLayout:function cs_initLockScreenLayout(){this.showClock(new Date());if(!this._lockScreenLayoutInitialized){this.initLockScreenConnInfoManager();this.initLockScreenSlide();this._lockScreenLayoutInitialized=true;}},toggleMute:function cs_toggleMute(){this.muteButton.classList.toggle('active-state');this.hideBarMuteButton.classList.toggle('active-state');this.calls.classList.toggle('muted');CallsHandler.toggleMute();},unmute:function cs_unmute(){this.muteButton.classList.remove('active-state');this.hideBarMuteButton.classList.remove('active-state');this.calls.classList.remove('muted');CallsHandler.unmute();},toggleSpeaker:function cs_toggleSpeaker(){this.speakerButton.classList.toggle('active-state');CallsHandler.toggleSpeaker();},toggleBluetoothMenu:function cs_toggleBluetoothMenu(value){if(typeof value!='boolean'){this.bluetoothMenu.classList.toggle('display');}else{this.bluetoothMenu.classList.toggle('display',value);}},switchToSpeaker:function cs_switchToReceiver(){this.speakerButton.classList.add('active-state');this.bluetoothButton.classList.add('active-state');CallsHandler.switchToSpeaker();this.toggleBluetoothMenu(false);},switchToReceiver:function cs_switchToReceiver(){this.speakerButton.classList.remove('active-state');this.bluetoothButton.classList.remove('active-state');CallsHandler.switchToReceiver();this.toggleBluetoothMenu(false);},setShowIsHeld:function cs_setShowIsHeld(enabled){this.holdButton.classList.toggle('active-state',enabled);},switchToDefaultOut:function cs_switchToDefaultOut(doNotConnect){this.speakerButton.classList.remove('active-state');this.bluetoothButton.classList.add('active-state');CallsHandler.switchToDefaultOut(doNotConnect);this.toggleBluetoothMenu(false);},setBTReceiverIcon:function cs_setBTReceiverIcon(enabled){if(enabled){this.speakerButton.classList.add('hide');this.bluetoothButton.classList.remove('hide');}else{this.speakerButton.classList.remove('hide');this.bluetoothButton.classList.add('hide');}},showKeypad:function cs_showKeypad(){KeypadManager.render('oncall');this.body.classList.add('showKeypad');},hideKeypad:function cs_hideKeypad(){KeypadManager.restorePhoneNumber();KeypadManager.restoreAdditionalContactInfo();this.body.classList.remove('showKeypad');},placeNewCall:function cs_placeNewCall(){new MozActivity({name:'dial',data:{type:'webtelephony/number',number:''}});},render:function cs_render(layout_type){this.screen.dataset.layout=layout_type;},showClock:function cs_showClock(now){var formatter=mozIntl.DateTimeFormat(navigator.languages,{hour12:navigator.mozHour12,dayperiod:false,hour:'numeric',minute:'numeric'});var timeText=formatter.format(now);var dateText=now.toLocaleString(navigator.languages,{weekday:'long',month:'long',day:'numeric'});this.lockedClockTime.textContent=timeText;this.lockedDate.textContent=dateText;},showIncoming:function cs_showIncoming(){this.body.classList.remove('showKeypad');this.callOptions.classList.add('transparent');this.incomingContainer.classList.add('displayed');this._screenWakeLock=navigator.requestWakeLock('screen');},hideIncoming:function cs_hideIncoming(){this.callOptions.classList.remove('transparent');this.incomingContainer.classList.remove('displayed');if(this._screenWakeLock){this._screenWakeLock.unlock();this._screenWakeLock=null;}
this.setCallerContactImage();},enableKeypadButton:function cs_enableKeypadButton(){this.keypadButton.removeAttribute('disabled');},disableKeypadButton:function cs_disableKeypadButton(){this.keypadButton.setAttribute('disabled','disabled');},syncSpeakerEnabled:function cs_syncSpeakerEnabled(){if(navigator.mozTelephony.speakerEnabled){this.speakerButton.classList.add('active-state');}else{this.speakerButton.classList.remove('active-state');}},enableMuteButton:function cs_enableMuteButton(){this.muteButton.removeAttribute('disabled');},disableMuteButton:function cs_disableMuteButton(){this.muteButton.setAttribute('disabled','disabled');},enablePlaceNewCallButton:function cs_enablePlaceNewCallButton(){this.placeNewCallButton.removeAttribute('disabled');},disablePlaceNewCallButton:function cs_disablePlaceNewCallButton(){this.placeNewCallButton.setAttribute('disabled','disabled');},enableSpeakerButton:function cs_enableSpeakerButton(){this.speakerButton.removeAttribute('disabled');},disableSpeakerButton:function cs_disableSpeakerButton(){this.speakerButton.setAttribute('disabled','disabled');},showOnHoldButton:function cs_showOnHoldButton(){this.holdButton.classList.remove('hide');},hideOnHoldButton:function cs_hideOnHoldButton(){this.holdButton.classList.add('hide');},enableOnHoldButton:function cs_enableOnHoldButton(){this.holdButton.removeAttribute('disabled');},disableOnHoldButton:function cs_disableOnHoldButton(){this.holdButton.setAttribute('disabled','disabled');},showMergeButton:function cs_showMergeButton(){this.mergeButton.classList.remove('hide');},hideMergeButton:function cs_hideMergeButton(){this.mergeButton.classList.add('hide');},showOnHoldAndMergeContainer:function cs_showOnHoldAndMergeContainer(){this.holdAndMergeContainer.style.display='block';},hideOnHoldAndMergeContainer:function cs_hideOnHoldAndMergeContainer(){this.holdAndMergeContainer.style.display='none';},createTicker:function(durationNode){var durationChildNode=durationNode.querySelector('span');if(durationNode.dataset.tickerId){return false;}
durationChildNode.removeAttribute('data-l10n-id');durationChildNode.textContent='00:00';durationNode.classList.add('isTimer');var ticker=setInterval(function ut_updateTimer(startTime){var delta=Math.round((Date.now()-startTime)/1000)*1000;Utils.prettyDuration(durationChildNode,delta);},1000,Date.now());durationNode.dataset.tickerId=ticker;return true;},stopTicker:function(durationNode){durationNode.classList.remove('isTimer');clearInterval(durationNode.dataset.tickerId);delete durationNode.dataset.tickerId;},handleEvent:function cs_handleEvent(evt){var state=null,statePrev=null;switch(evt.type){case'lockscreenslide-unlocker-initializer':break;case'lockscreenslide-near-left':state=evt.detail.state;statePrev=evt.detail.statePrev;if(state==='accelerating'){CallScreen.hangUpIcon.classList.add('triggered');}else{CallScreen.hangUpIcon.classList.remove('triggered');}
break;case'lockscreenslide-near-right':state=evt.detail.state;statePrev=evt.detail.statePrev;if(state==='accelerating'){CallScreen.pickUpIcon.classList.add('triggered');}else{CallScreen.pickUpIcon.classList.remove('triggered');}
break;case'lockscreenslide-unlocking-start':break;case'lockscreenslide-unlocking-stop':break;case'lockscreenslide-activate-left':CallsHandler.end();break;case'lockscreenslide-activate-right':CallsHandler.answer();break;}},cdmaConferenceCall:function cs_cdmaConferenceCall(){this.hidePlaceNewCallButton();this.calls.classList.add('cdma-conference-call');},initUnlockerEvents:function cs_initUnlockerEvents(){window.addEventListener('lockscreenslide-unlocker-initializer',this);window.addEventListener('lockscreenslide-near-left',this);window.addEventListener('lockscreenslide-near-right',this);window.addEventListener('lockscreenslide-unlocking-start',this);window.addEventListener('lockscreenslide-activate-left',this);window.addEventListener('lockscreenslide-activate-right',this);window.addEventListener('lockscreenslide-unlocking-stop',this);},suspendUnlockerEvents:function cs_initUnlockerEvents(){window.removeEventListener('lockscreenslide-unlocker-initializer',this);window.removeEventListener('lockscreenslide-near-left',this);window.removeEventListener('lockscreenslide-near-right',this);window.removeEventListener('lockscreenslide-unlocking-start',this);window.removeEventListener('lockscreenslide-activate-left',this);window.removeEventListener('lockscreenslide-activate-right',this);window.removeEventListener('lockscreenslide-unlocking-stop',this);},getScenario:function cs_getScenario(){var scenario;if(this.inStatusBarMode){scenario=FontSizeManager.STATUS_BAR;}else if(this.body.classList.contains('single-line')){scenario=FontSizeManager.SINGLE_CALL;}else{scenario=FontSizeManager.CALL_WAITING;}
return scenario;}};

View file

@ -0,0 +1,85 @@
;'use strict';var CallsHandler=(function callsHandler(){var CALLS_LIMIT=2;var CDMA_CALLS_LIMIT=2;var handledCalls=[];var exitCallScreenTimeout=null;var toneInterval=null;var telephony=window.navigator.mozTelephony;telephony.oncallschanged=onCallsChanged;var conn=window.navigator.mozMobileConnections&&window.navigator.mozMobileConnections[0];if(conn&&conn.voice&&conn.voice.network&&conn.voice.network.mcc){SimplePhoneMatcher.mcc=conn.voice.network.mcc;}
var btHelper=new BluetoothHelper();var screenLock;function setup(){if(telephony){telephony.muted=false;if(telephony.ownAudioChannel){telephony.ownAudioChannel();}}
btHelper.getConnectedDevicesByProfile(btHelper.profiles.HFP,function(result){CallScreen.setBTReceiverIcon(!!(result&&result.length));});btHelper.onhfpstatuschanged=function(evt){CallScreen.setBTReceiverIcon(evt.status);};var acm=navigator.mozAudioChannelManager;if(acm){acm.addEventListener('headphoneschange',function onheadphoneschange(){if(acm.headphones){CallScreen.switchToDefaultOut();}});}
btHelper.onscostatuschanged=function onscostatuschanged(evt){if(evt.status){CallScreen.switchToDefaultOut();}};navigator.mozSetMessageHandler('headset-button',handleHSCommand);navigator.mozSetMessageHandler('bluetooth-dialer-command',handleBTCommand);}
var highPriorityWakeLock=null;function onCallsChanged(){if(!highPriorityWakeLock&&telephony.calls.length>0){highPriorityWakeLock=navigator.requestWakeLock('high-priority');}
if(highPriorityWakeLock&&telephony.calls.length===0){highPriorityWakeLock.unlock();highPriorityWakeLock=null;}
if(telephony.active){telephony.active.addEventListener('disconnected',handleDisconnectAndPlayBusyTone);}
telephony.calls.forEach(function callIterator(call){var alreadyAdded=handledCalls.some(function hcIterator(hc){return(hc.call===call);});if(!alreadyAdded){addCall(call);}});function hcIterator(call){return(call===hc.call);}
for(var index=(handledCalls.length-1);index>=0;index--){var hc=handledCalls[index];var stillHere=telephony.calls.some(hcIterator)||telephony.conferenceGroup.calls.some(hcIterator);if(!stillHere){removeCall(index);}}
if(cdmaCallWaiting()){handleCallWaiting(telephony.calls[0]);}else{if(isCdma3WayCall()){CallScreen.hidePlaceNewCallButton();}else if(handledCalls.length!==0){CallScreen.showPlaceNewCallButton();}}
updateMergeAndOnHoldStatus();updateMuteAndSpeakerStatus();CallScreen.setCallerContactImage();exitCallScreenIfNoCalls(CallScreen.callEndPromptTime);}
function addCall(call){if(handledCalls.length&&(call.state!='incoming')&&(call.state!='dialing')){return;}
if(telephony.calls.length>CALLS_LIMIT){HandledCall(call);call.hangUp();return;}
if(handledCalls.length===0){CallScreen.unmute();CallScreen.enableKeypadButton();CallScreen.switchToDefaultOut(true);}
var hc=new HandledCall(call);handledCalls.push(hc);CallScreen.insertCall(hc.node);if(call.state==='incoming'){turnScreenOn(call);}
if(handledCalls.length>1){if(call.state==='incoming'){hc.hide();handleCallWaiting(call);}else{updatePlaceNewCall();hc.show();}}else{if(window.location.hash.startsWith('#locked')&&(call.state==='incoming')){CallScreen.initLockScreenLayout();CallScreen.render('incoming-locked');}else{CallScreen.render(call.state);}}}
function removeCall(index){handledCalls.splice(index,1);if(handledCalls.length===0){CallScreen.disableKeypadButton();return;}
CallScreen.hideIncoming();var remainingCall=handledCalls[0];if(remainingCall.call.state==='incoming'){remainingCall.show();setTimeout(function nextTick(){if(remainingCall.call.state==='incoming'){CallScreen.render('incoming');}});return;}}
function turnScreenOn(call){screenLock=navigator.requestWakeLock('screen');call.addEventListener('statechange',function callStateChange(){call.removeEventListener('statechange',callStateChange);if(screenLock){screenLock.unlock();screenLock=null;}});}
function handleDisconnectAndPlayBusyTone(evt){if(evt.call.disconnectedReason==='Busy'){var sequence=[[480,620,500],[0,0,500],[480,620,500],[0,0,500],[480,620,500],[0,0,500]];var sequenceDuration=sequence.reduce(function(prev,curr){return prev+curr[2];},0);TonePlayer.playSequence(sequence);exitCallScreenIfNoCalls(sequenceDuration);}}
function handleCallWaiting(call){var number=call.secondId?call.secondId.number:call.id.number;if(!number){navigator.mozL10n.setAttributes(CallScreen.incomingNumber,'withheld-number');navigator.mozL10n.translateFragment(CallScreen.incomingNumber);FontSizeManager.adaptToSpace(FontSizeManager.SECOND_INCOMING_CALL,CallScreen.incomingNumber,false,'end');return;}
if(navigator.mozIccManager.iccIds.length>1){navigator.mozL10n.setAttributes(CallScreen.incomingSim,'sim-number',{n:call.serviceId+1});}else{CallScreen.incomingSim.hidden=true;}
Contacts.findByNumber(number,function lookupContact(contact,matchingTel){if(contact&&contact.name){CallScreen.incomingInfo.classList.add('additionalInfo');CallScreen.incomingNumber.textContent=contact.name;var additionalL10n=Utils.getPhoneNumberAdditionalInfo(matchingTel);navigator.mozL10n.setAttributes(CallScreen.incomingNumberAdditionalTelType,additionalL10n.id,additionalL10n.args);CallScreen.incomingNumberAdditionalTel.textContent=number;}else{CallScreen.incomingInfo.classList.remove('additionalInfo');CallScreen.incomingNumber.textContent=number;CallScreen.incomingNumberAdditionalTelType.removeAttribute('data-l10n-id');CallScreen.incomingNumberAdditionalTelType.textContent='';CallScreen.incomingNumberAdditionalTel.textContent='';}
FontSizeManager.adaptToSpace(FontSizeManager.SECOND_INCOMING_CALL,CallScreen.incomingNumber,false,'end');if(contact&&contact.name){FontSizeManager.ensureFixedBaseline(FontSizeManager.SECOND_INCOMING_CALL,CallScreen.incomingNumber);}});if(cdmaCallWaiting()){CallScreen.holdAndAnswerOnly=true;}
CallScreen.showIncoming();playWaitingTone(call);}
function exitCallScreenIfNoCalls(timeout){if(handledCalls.length===0){document.body.classList.toggle('no-handled-calls',true);if(exitCallScreenTimeout!==null){clearTimeout(exitCallScreenTimeout);exitCallScreenTimeout=null;}
exitCallScreenTimeout=setTimeout(function(evt){exitCallScreenTimeout=null;if(handledCalls.length===0){window.close();}else{document.body.classList.toggle('no-handled-calls',false);}},timeout);}}
function updateAllPhoneNumberDisplays(){handledCalls.forEach(function(call){if(!call._leftGroup){call.restorePhoneNumber();}});}
window.addEventListener('resize',updateAllPhoneNumberDisplays);function numOpenLines(){return telephony.calls.length+
(telephony.conferenceGroup.calls.length?1:0);}
function handleBTCommand(message){var command=message.command;switch(command){case'CHUP':end();break;case'ATA':answer();break;case'CHLD=0':hangupWaitingCalls();break;case'CHLD=1':if((handledCalls.length===1)&&!cdmaCallWaiting()){end();}else{endAndAnswer();}
break;case'CHLD=2':if((handledCalls.length===1)&&!cdmaCallWaiting()){holdOrResumeSingleCall();}else{holdAndAnswer();}
break;case'CHLD=3':mergeCalls();break;default:var partialCommand=command.substring(0,3);if(partialCommand==='VTS'){KeypadManager.press(command.substring(4));}
break;}}
var lastHeadsetPress=0;function handleHSCommand(message){switch(message){case'headset-button-press':lastHeadsetPress=Date.now();return;case'headset-button-release':if((Date.now()-lastHeadsetPress)>1000){return;}
break;default:return;}
if(telephony.active){end();}else if((handledCalls.length>1)||cdmaCallWaiting()){holdAndAnswer();}else{answer();}}
function answer(){if(!handledCalls.length){return;}
handledCalls[0].call.answer();}
function holdAndAnswer(){if((handledCalls.length<2)&&!cdmaCallWaiting()){return;}
if(telephony.active){telephony.active.hold();if(cdmaCallWaiting()){btHelper.answerWaitingCall();}}else if(handledCalls.length>=2){var lastCall=handledCalls[handledCalls.length-1].call;lastCall.answer();}else{handledCalls[0].call.hold();}
CallScreen.hideIncoming();if(cdmaCallWaiting()){handledCalls[0].updateCallNumber();CallScreen.cdmaCallWaiting=true;stopWaitingTone();}}
function endAndAnswer(){if((handledCalls.length<2)&&!cdmaCallWaiting()){return;}
if(telephony.active===telephony.conferenceGroup){endConferenceCall().then(function(){CallScreen.hideIncoming();},function(){});return;}
if(cdmaCallWaiting()){handledCalls[0].call.hold();stopWaitingTone();btHelper.answerWaitingCall();}else{var callToEnd=telephony.active||handledCalls[handledCalls.length-2].call;var callToAnswer;handledCalls.some(function(handledCall){if(handledCall.call!==callToEnd){callToAnswer=handledCall.call;return true;}});if(callToEnd&&callToAnswer){callToEnd.addEventListener('disconnected',function ondisconnected(){callToEnd.removeEventListener('disconnected',ondisconnected);callToAnswer.answer();});callToEnd.hangUp();}else if(callToEnd){callToEnd.hangUp();}else if(callToAnswer){callToAnswer.answer();}}
CallScreen.hideIncoming();if(cdmaCallWaiting()){handledCalls[0].updateCallNumber();CallScreen.cdmaCallWaiting=true;}}
function toggleCalls(){if(CallScreen.incomingContainer.classList.contains('displayed')&&!cdmaCallWaiting()){return;}
if(numOpenLines()<2&&!cdmaCallWaiting()){if(!telephony.active){holdOrResumeSingleCall();}
return;}
telephony.active.hold();btHelper.toggleCalls();}
function holdOrResumeSingleCall(){if(numOpenLines()!==1||(telephony.calls.length&&(telephony.calls[0].state==='incoming'||!telephony.calls[0].switchable))){return;}
if(telephony.active){telephony.active.hold();}else{var line=telephony.calls.length?telephony.calls[0]:telephony.conferenceGroup;line.resume();}}
function hangupWaitingCalls(){handledCalls.forEach(function(handledCall){var callState=handledCall.call.state;if(callState==='held'||(callState==='incoming'&&handledCalls.length>1)){handledCall.call.hangUp();}});}
function ignore(){if(cdmaCallWaiting()){stopWaitingTone();btHelper.ignoreWaitingCall();}else{var ignoreIndex=handledCalls.length-1;handledCalls[ignoreIndex].call.hangUp();}
CallScreen.hideIncoming();}
function endConferenceCall(){return telephony.conferenceGroup.hangUp().then(function(){ConferenceGroupHandler.signalConferenceEnded();},function(){console.error('Failed to hangup Conference Call');});}
function end(){var callToEnd;if(telephony.active){callToEnd=telephony.active;}else if(numOpenLines()===1){if(telephony.conferenceGroup.calls.length){callToEnd=telephony.conferenceGroup;}else{callToEnd=telephony.calls[0];}}else{if(!handledCalls.length){return;}
var lastCallIndex=handledCalls.length-1;callToEnd=handledCalls[lastCallIndex].call;}
if(callToEnd.calls){endConferenceCall();}else{callToEnd.hangUp();}}
function unmute(){telephony.muted=false;}
function switchToSpeaker(){btHelper.disconnectSco();if(!telephony.speakerEnabled){telephony.speakerEnabled=true;}}
function switchToDefaultOut(doNotConnect){if(telephony.speakerEnabled){telephony.speakerEnabled=false;}
if(!doNotConnect&&telephony.active&&!document.hidden){btHelper.connectSco();}}
function switchToReceiver(){btHelper.disconnectSco();if(telephony.speakerEnabled){telephony.speakerEnabled=false;}}
function toggleMute(){telephony.muted=!telephony.muted;}
function toggleSpeaker(){if(telephony.speakerEnabled){CallsHandler.switchToDefaultOut();}else{CallsHandler.switchToSpeaker();}}
function playWaitingTone(call){var sequence=[[440,440,100],[0,0,100],[440,440,100]];toneInterval=window.setInterval(function playTone(){TonePlayer.playSequence(sequence);},10000);TonePlayer.playSequence(sequence);call.addEventListener('statechange',function callStateChange(){call.removeEventListener('statechange',callStateChange);window.clearInterval(toneInterval);});}
function stopWaitingTone(){window.clearInterval(toneInterval);}
function activeCall(){var telephonyActiveCall=telephony.active;var active=null;for(var i=0;i<handledCalls.length;i++){var handledCall=handledCalls[i];if(telephonyActiveCall===handledCall.call){active=handledCall;break;}}
return active;}
function activeCallForContactImage(){if(handledCalls.length===1){return handledCalls[0];}
return[activeCall()].concat(handledCalls).find(function(elem){return!elem||!elem.call.group;});}
function cdmaCallWaiting(){return((telephony.calls.length===1)&&(telephony.calls[0].state==='connected')&&(telephony.calls[0].secondId));}
function isFirstCallOnCdmaNetwork(){var cdmaTypes=['evdo0','evdoa','evdob','1xrtt','is95a','is95b'];if(handledCalls.length!==0){var ci=handledCalls[0].call.serviceId;var type=window.navigator.mozMobileConnections[ci].voice.type;return(cdmaTypes.indexOf(type)!==-1);}else{return false;}}
function isCdma3WayCall(){return isFirstCallOnCdmaNetwork()&&((telephony.calls.length===CDMA_CALLS_LIMIT)||(telephony.conferenceGroup.calls.length>0));}
function mergeCalls(){if(telephony.conferenceGroup.calls.length===0&&telephony.calls.length===2){telephony.conferenceGroup.add(telephony.calls[0],telephony.calls[1]).catch(function(){CallScreen.showStatusMessage('conferenceAddError');});}else if(telephony.conferenceGroup.calls.length>0&&telephony.calls.length===1){telephony.conferenceGroup.add(telephony.calls[0]).catch(function(){CallScreen.showStatusMessage('conferenceAddError');});}else{console.warn('Cannot join conference call.');}}
function isEstablishingCall(){return telephony.calls.some(function(call){return call.state==='dialing'||call.state==='alerting';});}
function isAnyCallOnHold(){return telephony.calls.some(call=>call.state==='held')||(telephony.conferenceGroup&&telephony.conferenceGroup.state==='held');}
function isAnyCallSwitchable(){return telephony.calls.some(call=>call.switchable)||((telephony.conferenceGroup.calls.length>0)&&telephony.conferenceGroup.calls.every(call=>call.switchable));}
function isEveryCallMergeable(){return telephony.calls.every(call=>call.mergeable);}
function updatePlaceNewCall(){if(isEstablishingCall()||(numOpenLines()===0)){CallScreen.disablePlaceNewCallButton();}else{CallScreen.enablePlaceNewCallButton();}}
function updateMergeAndOnHoldStatus(){var isEstablishing=isEstablishingCall();if(numOpenLines()===0){CallScreen.disableOnHoldButton();}else if(numOpenLines()>1&&!isEstablishing){CallScreen.hideOnHoldButton();if(isEveryCallMergeable()){CallScreen.showOnHoldAndMergeContainer();CallScreen.showMergeButton();}else{CallScreen.hideOnHoldAndMergeContainer();}}else{CallScreen.hideMergeButton();CallScreen.setShowIsHeld(!telephony.active&&isAnyCallOnHold());if(isEstablishing){CallScreen.disableOnHoldButton();}else{CallScreen.enableOnHoldButton();}
if(isAnyCallSwitchable()){CallScreen.showOnHoldAndMergeContainer();CallScreen.showOnHoldButton();}else{CallScreen.hideOnHoldAndMergeContainer();}}}
function updateMuteAndSpeakerStatus(){if(telephony.active){CallScreen.enableMuteButton();CallScreen.enableSpeakerButton();}else{CallScreen.disableMuteButton();CallScreen.disableSpeakerButton();}}
return{setup:setup,answer:answer,holdAndAnswer:holdAndAnswer,endAndAnswer:endAndAnswer,toggleCalls:toggleCalls,ignore:ignore,end:end,toggleMute:toggleMute,toggleSpeaker:toggleSpeaker,unmute:unmute,switchToReceiver:switchToReceiver,switchToSpeaker:switchToSpeaker,switchToDefaultOut:switchToDefaultOut,holdOrResumeSingleCall:holdOrResumeSingleCall,checkCalls:onCallsChanged,mergeCalls:mergeCalls,updateAllPhoneNumberDisplays:updateAllPhoneNumberDisplays,updatePlaceNewCall:updatePlaceNewCall,exitCallScreenIfNoCalls:exitCallScreenIfNoCalls,updateMergeAndOnHoldStatus:updateMergeAndOnHoldStatus,updateMuteAndSpeakerStatus:updateMuteAndSpeakerStatus,get activeCall(){return activeCall();},get activeCallForContactImage(){return activeCallForContactImage();},isFirstCallOnCdmaNetwork:isFirstCallOnCdmaNetwork};})();

View file

@ -0,0 +1,13 @@
;'use strict';var ConferenceGroupHandler=(function(){function initStringAutoResize(){var mutationObserverConfig={childList:true};var mutationObserver=new MutationObserver(function(mutations){if(groupDurationChildNode.hasAttribute('data-l10n-id')&&groupDurationChildNode.getAttribute('data-l10n-id')==='callEnded'){mutationObserver.disconnect();FontSizeManager.adaptToSpace(CallScreen.getScenario(),groupLabel,false,'end');mutationObserver.observe(groupDurationChildNode,mutationObserverConfig);}});mutationObserver.observe(groupDurationChildNode,mutationObserverConfig);}
var bdiCount=document.createElement('bdi');var groupLine=document.getElementById('group-call');var groupLabel=document.getElementById('group-call-label');groupLabel.appendChild(bdiCount);var groupDuration=document.querySelector('#group-call > .duration');var groupDurationChildNode=groupDuration.querySelector('span');var groupTotalDurationChildNode=groupDuration.querySelector('.total-duration');var telephony=window.navigator.mozTelephony;if(telephony.conferenceGroup){telephony.conferenceGroup.oncallschanged=onCallsChanged;telephony.conferenceGroup.onstatechange=onStateChange;}
initStringAutoResize();function onCallsChanged(){var calls=telephony.conferenceGroup.calls;CallScreen.updateCallsDisplay();if(!calls.length){ConferenceGroupUI.hideGroupDetails();}
var id='conferenceCall';var args={n:calls.length};navigator.mozL10n.setAttributes(bdiCount,id,args);ConferenceGroupUI.setGroupDetailsHeader({id:id,args:args});if(telephony.conferenceGroup.calls.length>=2){CallsHandler.checkCalls();}
if(CallsHandler.isFirstCallOnCdmaNetwork()){CallScreen.cdmaConferenceCall();}}
function show(){groupLine.hidden=false;groupLine.classList.remove('ended');groupLine.classList.remove('held');CallScreen.createTicker(groupDuration);CallScreen.setCallerContactImage();}
function end(){groupTotalDurationChildNode.textContent=groupDurationChildNode.textContent;navigator.mozL10n.setAttributes(groupDurationChildNode,'callEnded');groupLine.classList.add('ended');groupLine.classList.remove('held');CallScreen.stopTicker(groupDuration);setTimeout(function(evt){groupLine.hidden=true;CallScreen.updateCallsDisplay();},CallScreen.callEndPromptTime);}
function onStateChange(){switch(telephony.conferenceGroup.state){case'connected':show();CallScreen.render('connected');break;case'held':groupLine.classList.add('held');CallScreen.render('connected-hold');break;case'':end();CallsHandler.checkCalls();break;}}
function signalConferenceEnded(){ConferenceGroupUI.markCallsAsEnded();}
function addToGroupDetails(node){ConferenceGroupUI.addCall(node);}
function removeFromGroupDetails(node){ConferenceGroupUI.removeCall(node);}
function isGroupDetailsShown(){return ConferenceGroupUI.isGroupDetailsShown();}
return{addToGroupDetails:addToGroupDetails,removeFromGroupDetails:removeFromGroupDetails,signalConferenceEnded:signalConferenceEnded,isGroupDetailsShown:isGroupDetailsShown,get currentDuration(){return groupDurationChildNode.textContent;}};})();

View file

@ -0,0 +1,16 @@
;'use strict';var ConferenceGroupUI=(function(){var groupCalls=document.getElementById('group-call-details'),groupCallsList,groupCallsHeader,initialized=false,bdiGroupCallsCountElt;document.getElementById('group-show').addEventListener('click',showGroupDetails);function _init(callback){if(initialized){callback();}
LazyLoader.load([groupCalls],function(){groupCallsHeader=groupCalls.querySelector('header');groupCallsList=document.getElementById('group-call-details-list');document.getElementById('group-hide').addEventListener('click',_hideGroupDetails);if(!initialized){bdiGroupCallsCountElt=document.createElement('bdi');groupCallsHeader.appendChild(bdiGroupCallsCountElt);}
initialized=true;callback();});}
function _hideGroupDetails(evt){if(evt){evt.preventDefault();}
if(!navigator.mozTelephony.conferenceGroup.calls.length){_removeAllCalls();}
groupCalls.classList.remove('display');}
function _removeAllCalls(){var callNodes=groupCalls.querySelectorAll('.handled-call');for(var i=0;i<callNodes.length;i++){removeCall(callNodes[i]);}}
function addCall(node){_init(function(){groupCallsList.appendChild(node);});}
function removeCall(node){if(node.parentNode){node.parentNode.removeChild(node);}}
function showGroupDetails(evt){if(evt){evt.stopPropagation();}
groupCalls.classList.add('display');}
function hideGroupDetails(){setTimeout(_hideGroupDetails,ConferenceGroupUI.isGroupDetailsShown()?CallScreen.callEndPromptTime:0);}
function isGroupDetailsShown(){return groupCalls.classList.contains('display');}
function markCallsAsEnded(){_init(function(){var callElems=groupCallsList.getElementsByTagName('SECTION');for(var i=0;i<callElems.length;i++){callElems[i].dataset.groupHangup='groupHangup';}});}
function setGroupDetailsHeader(text){_init(function(){if(typeof(text)==='string'){navigator.mozL10n.setAttributes(bdiGroupCallsCountElt,text);}else{navigator.mozL10n.setAttributes(bdiGroupCallsCountElt,text.id,text.args);}});}
return{addCall:addCall,removeCall:removeCall,showGroupDetails:showGroupDetails,hideGroupDetails:hideGroupDetails,isGroupDetailsShown:isGroupDetailsShown,markCallsAsEnded:markCallsAsEnded,setGroupDetailsHeader:setGroupDetailsHeader};})();

View file

@ -0,0 +1,40 @@
'use strict';
/* global CallScreen */
console.error('This file is not to be shipped.');
console.error('It just helps to fake a call.');
(function() {
// Don't execute on the phone
if (navigator.mozTelephony.conferenceGroup) {
return;
}
// To use it, you need to include at the end of the <head>
// <script defer src="/js/fake-oncall-desktop.js"></script>
// in index.html
// Then access http://callscreen.gaiamobile.org:8080
var handledCall = document.getElementById('handled-call-template');
handledCall.id = '';
handledCall.hidden = false;
handledCall.classList.add('additionalInfo');
handledCall.classList.add('additionalContactInfo');
handledCall.classList.add('incoming');
handledCall.classList.add('handled-call');
handledCall.querySelector('.number').innerHTML = 'Joe Smith';
handledCall.querySelector('.additionalContactInfo').textContent =
'work, 12345';
var duration = handledCall.querySelector('.duration');
var time = duration.querySelector('span');
duration.classList.add('isTimer');
time.textContent = '9:42';
CallScreen.updateCallsDisplay();
CallScreen.render('connected'); // Change this for various states
CallScreen.screen.classList.add('displayed');
CallScreen.calls.classList.add('muted');
CallScreen.groupCalls.classList.add('held');
})();

View file

@ -0,0 +1,26 @@
;'use strict';function HandledCall(aCall){this.photo=null;this._leftGroup=false;this.call=aCall;aCall.addEventListener('statechange',this);aCall.ongroupchange=(function onGroupChange(){if(this.call.group){ConferenceGroupHandler.addToGroupDetails(this.node);this._leftGroup=false;}else if(this._wasUnmerged()){if(ConferenceGroupHandler.isGroupDetailsShown()){this.node.parentNode.insertBefore(this.node.cloneNode(true),this.node);}
CallScreen.insertCall(this.node);this._leftGroup=false;}else{this._leftGroup=!this.node.dataset.groupHangup;}}).bind(this);this._initialState=this.call.state;this._cachedInfo=null;this._cachedAdditionalTel=null;this._cachedAdditionalTelType=null;this._removed=false;this._wasConnected=false;this.node=document.getElementById('handled-call-template').cloneNode(true);this.node.id='';this.node.classList.add('handled-call');this.node.hidden=false;this.durationNode=this.node.querySelector('.duration');this.durationChildNode=this.node.querySelector('.duration span');this.totalDurationNode=this.node.querySelector('.total-duration');this.viaSimNode=this.node.querySelector('.sim .via-sim');this.simNumberNode=this.node.querySelector('.sim .sim-number');this.numberNode=this.node.querySelector('.numberWrapper .number bdi');this.outerNode=this.node.querySelector('.numberWrapper .number');this.groupCallNumberNode=document.getElementById('group-call-label');this.additionalTelNode=this.node.querySelector('.additionalContactInfo .tel');this.additionalTelTypeNode=this.node.querySelector('.additionalContactInfo .tel-type');this.hangupButton=this.node.querySelector('.hangup-button');this.hangupButton.onclick=(function(){this.call.hangUp();}.bind(this));this.updateCallNumber();this.createCustomStyles();this.mutationObserverConfig={childList:true};this.mutationObserver=new MutationObserver(this.observeMutation.bind(this));this.mutationObserver.observe(this.durationChildNode,this.mutationObserverConfig);navigator.mozL10n.setAttributes(this.durationChildNode,(this.call.state==='incoming')?'incoming':'connecting');this.updateDirection();if(navigator.mozIccManager.iccIds.length>1){this.node.classList.add('sim-info');var n=this.call.serviceId+1;navigator.mozL10n.setAttributes(this.viaSimNode,'via-sim',{n:n});navigator.mozL10n.setAttributes(this.simNumberNode,'sim-number',{n:n});}else{this.viaSimNode.hidden=true;this.simNumberNode.hidden=true;}
if(this._initialState==='connected'){this.connected();}}
HandledCall.prototype.createCustomStyles=function hc_createCustomStyles(){const CUSTOM_STYLE_ID='call-ended-custom-style';var style=document.getElementById(CUSTOM_STYLE_ID);if(!style){style=document.createElement('style');style.id=CUSTOM_STYLE_ID;document.head.appendChild(style);}
this.callEndedStyleSheet=style.sheet;};HandledCall.prototype.computeCallEndedFontSizeRules=function hc_computeCallEndedFontSizeRules(){while(this.callEndedStyleSheet.cssRules.length>0){this.callEndedStyleSheet.deleteRule(0);}
var computedStyle=window.getComputedStyle(this.durationChildNode);var fontFamily=computedStyle.fontFamily;var allowedSizes=[16,17,18,19,20,21,22,23,24,25,26,27];var info=FontSizeUtils.getMaxFontSizeInfo(this.durationChildNode.textContent,allowedSizes,fontFamily,180);var rule='@media (min-height: 4.5em) {'+' #calls.big-duration > section.ended .duration > span,'+' #calls.big-duration > section.ended .total-duration {'+' font-size: '+(info.fontSize/10.0)+'rem;'+' }'+'}';this.callEndedStyleSheet.insertRule(rule,this.callEndedStyleSheet.cssRules.length);};HandledCall.prototype.observeMutation=function hc_observeMutation(mutations){if(this.durationChildNode.hasAttribute('data-l10n-id')&&this.durationChildNode.getAttribute('data-l10n-id')==='callEnded'){this.mutationObserver.disconnect();this.computeCallEndedFontSizeRules();this.mutationObserver.observe(this.durationChildNode,this.mutationObserverConfig);}};HandledCall.prototype._wasUnmerged=function hc_wasUnmerged(){return!this.node.dataset.groupHangup&&this.call.state!='disconnecting'&&this.call.state!='disconnected';};HandledCall.prototype.handleEvent=function hc_handle(evt){CallsHandler.updatePlaceNewCall();CallsHandler.updateMergeAndOnHoldStatus();CallsHandler.updateMuteAndSpeakerStatus();switch(evt.call.state){case'connected':CallScreen.render('connected');this.connected();break;case'disconnected':this.disconnected();break;case'held':this.node.classList.add('held');CallScreen.render('connected-hold');break;}};HandledCall.prototype.updateCallNumber=function hc_updateCallNumber(){var number=this.call.id.number;var self=this;CallScreen.setCallerContactImage();if(this.call.secondId){this.replacePhoneNumber('switch-calls');this.replaceAdditionalContactInfo(null,null);return;}
if(!number){this.replacePhoneNumber('withheld-number');return;}
var isEmergencyNumber=this.call.emergency;if(isEmergencyNumber){this.node.classList.add('emergency');this.replacePhoneNumber({raw:number},'end');this.replaceAdditionalContactInfo('emergencyNumber');return;}
Voicemail.check(number,this.call.serviceId).then(function(isVoicemailNumber){if(isVoicemailNumber){self.replacePhoneNumber('voiceMail');}else{Contacts.findByNumber(number,lookupContact);checkICCMessage();}});function checkICCMessage(){var callMessageReq=navigator.mozSettings.createLock().get('icc.callmessage');callMessageReq.onsuccess=function onCallMessageSuccess(){self._iccCallMessage=callMessageReq.result['icc.callmessage'];if(self._iccCallMessage){self.replacePhoneNumber({raw:self._iccCallMessage},'end');navigator.mozSettings.createLock().set({'icc.callmessage':null});}};}
function lookupContact(contact,matchingTel,contactsWithSameNumber){if(self._iccCallMessage){return;}
if(contact){var primaryInfo=Utils.getPhoneNumberPrimaryInfo(matchingTel,contact);if(primaryInfo){self.replacePhoneNumber({raw:primaryInfo},'end');}else{self.replacePhoneNumber('withheld-number');}
self.replaceAdditionalContactInfo({raw:matchingTel.value},Utils.getPhoneNumberAdditionalInfo(matchingTel));var photo=ContactPhotoHelper.getFullResolution(contact);if(photo){self.photo=photo;CallScreen.setCallerContactImage();}
return;}
self.replacePhoneNumber({raw:number},'end');self.replaceAdditionalContactInfo(self._cachedAdditionalTel,self._cachedAdditionalTelType);}};HandledCall.prototype.replaceAdditionalContactInfo=function hc_replaceAdditionalContactInfo(additionalTel,additionalTelType){if(!additionalTel&&!additionalTelType){this.additionalTelNode.removeAttribute('data-l10n-id');this.additionalTelNode.textContent='';this.additionalTelTypeNode.removeAttribute('data-l10n-id');this.additionalTelTypeNode.textContent='';this.node.classList.remove('additionalInfo');}else{if(typeof(additionalTel)==='string'){navigator.mozL10n.setAttributes(this.additionalTelNode,additionalTel);}else if(additionalTel.id){navigator.mozL10n.setAttributes(this.additionalTelNode,additionalTel.id,additionalTel.args);}else if(additionalTel.raw){this.additionalTelNode.removeAttribute('data-l10n-id');this.additionalTelNode.textContent=additionalTel.raw;}
if(additionalTelType){navigator.mozL10n.setAttributes(this.additionalTelTypeNode,additionalTelType.id,additionalTelType.args);}
this.node.classList.add('additionalInfo');}
this._cachedAdditionalTel=additionalTel;this._cachedAdditionalTelType=additionalTelType||null;};HandledCall.prototype.restoreAdditionalContactInfo=function hc_restoreAdditionalContactInfo(){this.replaceAdditionalContactInfo(this._cachedAdditionalTel,this._cachedAdditionalTelType);};HandledCall.prototype.formatPhoneNumber=function hc_formatPhoneNumber(ellipsisSide){if(this._removed){return;}
if(this.call.group){this.numberNode.style='';return;}
var scenario=CallScreen.getScenario();if(scenario===FontSizeManager.CALL_WAITING&&this.call.state==='incoming'&&CallScreen.incomingContainer.classList.contains('displayed')){scenario=FontSizeManager.SECOND_INCOMING_CALL;}
FontSizeManager.adaptToSpace(scenario,this.outerNode,false,ellipsisSide);if(this.node.classList.contains('additionalInfo')){FontSizeManager.ensureFixedBaseline(scenario,this.numberNode);}else{FontSizeManager.resetFixedBaseline(this.numberNode);}};HandledCall.prototype.renderPhoneNumber=function hc_renderPhoneNumber(number,ellipsisSide){if(typeof(number)==='string'){navigator.mozL10n.setAttributes(this.numberNode,number);}else if(number.id){navigator.mozL10n.setAttributes(this.numberNode,number.id,number.args);this.numberNode.style.fontSize='';}else if(number.raw){this.numberNode.removeAttribute('data-l10n-id');this.numberNode.textContent=number.raw;this.formatPhoneNumber(ellipsisSide);}};HandledCall.prototype.replacePhoneNumber=function hc_replacePhoneNumber(number,ellipsisSide){this.renderPhoneNumber(number,ellipsisSide);this._cachedInfo=number;};HandledCall.prototype.restorePhoneNumber=function hc_restorePhoneNumber(){this._cachedInfo&&this.replacePhoneNumber(this._cachedInfo,'end');};HandledCall.prototype.updateDirection=function hc_updateDirection(){var classList=this.node.classList;if(this._initialState==='incoming'){classList.add('incoming');this.node.setAttribute('data-l10n-id','incoming_screen_reader');}else{classList.add('outgoing');this.node.setAttribute('data-l10n-id','outgoing_screen_reader');}
if(this.call.state==='connected'){classList.add('ongoing');}};HandledCall.prototype.remove=function hc_remove(){this._removed=true;this.call.removeEventListener('statechange',this);this.photo=null;var self=this;CallScreen.stopTicker(this.durationNode);var currentDuration=ConferenceGroupHandler.isGroupDetailsShown()?ConferenceGroupHandler.currentDuration:this.durationChildNode.textContent;this.node.classList.add('ended');this.durationNode.classList.remove('isTimer');navigator.mozL10n.setAttributes(this.durationChildNode,'callEnded');var totalDuration=!!currentDuration.match(/\d+/g)?currentDuration:'';this.totalDurationNode.textContent=totalDuration;setTimeout(function(evt){CallScreen.removeCall(self.node);self.node=null;},CallScreen.callEndPromptTime);};HandledCall.prototype.connected=function hc_connected(){this.show();this.node.classList.remove('held');this.updateDirection();CallScreen.createTicker(this.durationNode);CallScreen.syncSpeakerEnabled();this.updateCallNumber();this._wasConnected=true;};HandledCall.prototype.disconnected=function hc_disconnected(){if(this._leftGroup){if(typeof(this._cachedInfo)==='string'){CallScreen.showStatusMessage(this._cachedInfo);}else if(this._cachedInfo.id){const disconnectedMessageL10n={'withheld-number':'withheld-number-left-call','voiceMail':'voicemail-left-call'};var id=disconnectedMessageL10n[this._cachedInfo.id];CallScreen.showStatusMessage(id);}else if(this._cachedInfo.raw){CallScreen.showStatusMessage({id:'caller-left-call',args:{caller:this._cachedInfo.raw}});}
this._leftGroup=false;}
if(this._wasConnected){TonePlayer.playSequence([[480,620,250]]);}
this._wasConnected=false;this.remove();};HandledCall.prototype.show=function hc_show(){if(this.node){this.node.hidden=false;}
CallScreen.updateCallsDisplay();};HandledCall.prototype.hide=function hc_hide(){if(this.node){this.node.hidden=true;}
CallScreen.updateCallsDisplay();};

View file

@ -0,0 +1,3 @@
;'use strict';function onLoadCallScreen(evt){window.removeEventListener('load',onLoadCallScreen);CallsHandler.setup();CallScreen.init();KeypadManager.init(true);}
function unloadCallScreen(evt){}
window.addEventListener('load',onLoadCallScreen);window.addEventListener('unload',unloadCallScreen);

View file

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

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

View file

@ -0,0 +1 @@
{"name":"Callscreen","description":"Gaia Callscreen","type":"certified","role":"system","launch_path":"/index.html","developer":{"name":"The Gaia Team","url":"https://github.com/mozilla-b2g/gaia"},"orientation":"default","permissions":{"themeable":{},"telephony":{},"bluetooth":{},"voicemail":{},"contacts":{"access":"readonly"},"mobileconnection":{},"attention":{},"settings":{"access":"readwrite"},"time":{},"audio-channel-telephony":{},"audio-channel-system":{},"idle":{},"device-storage:sdcard":{"access":"readonly"},"phonenumberservice":{},"moz-extremely-unstable-and-will-change-webcomponents":{}},"messages":[{"bluetooth-dialer-command":"/index.html"},{"headset-button":"/index.html"}],"datastores-access":{"Gaia_Facebook_Friends":{"readonly":true,"description":"Facebook Friends"}},"icons":{"84":"/style/icons/dialer_84.png","126":"/style/icons/dialer_126.png","142":"/style/icons/dialer_142.png","189":"/style/icons/dialer_189.png","284":"/style/icons/dialer_284.png"},"locales":{"ar":{"name":"شاشة المكالمات","description":"شاشة المكالمات الخاصة ب Gaia"},"bg":{"name":"Обаждания","description":"Обаждания на Gaia"},"bn-BD":{"name":"কলস্ক্রীন","description":"Gaia কলস্ক্রীন"},"ca":{"name":"Pantalla de trucada","description":"Pantalla de trucada del Gaia"},"cs":{"name":"Okno s hovorem","description":"Okno s hovorem Gaia"},"da":{"name":"Opkaldsskærm","description":"Gaia Opkaldsskærm"},"de":{"name":"Anrufbildschirm","description":"Anrufbildschirm für Gaia"},"el":{"name":"Οθόνη Κλήσης","description":"Οθόνη Κλήσης Gaia"},"en-US":{"name":"Callscreen","description":"Gaia Callscreen"},"es":{"name":"Pantalla de llamada","description":"Pantalla Gaia de llamada"},"eu":{"name":"Dei-pantaila","description":"Gaia dei-pantaila"},"fr":{"name":"Écran d’appel","description":"Écran d’appel de Gaia"},"gl":{"name":"Pantalla de chamada","description":"Pantalla de chamada de Gaia"},"hr":{"name":"Callscreen","description":"Gaia Callscreen"},"hu":{"name":"Hívásképernyő","description":"Gaia hívásképernyő"},"it":{"name":"Callscreen","description":"Gaia Callscreen"},"ja":{"name":"通話画面","description":"Gaia 通話画面"},"km":{"name":"អេក្រង់​ការ​ហៅ","description":"អេក្រង់​ការ​ហៅ Gaia"},"ko":{"name":"통화화면","description":"Gaia 통화화면"},"lt":{"name":"Callscreen","description":"Gaia Callscreen"},"mk":{"name":"Callscreen","description":"Gaia Callscreen"},"ms":{"name":"Skrin Panggilan","description":"Skrin Panggilan Gaia"},"ne-NP":{"name":"Callscreen","description":"Gaia Callscreen"},"nl":{"name":"Oproepscherm","description":"Gaia-oproepscherm"},"pa":{"name":"Callscreen","description":"Gaia Callscreen"},"pl":{"name":"Połączenia","description":"Ekran połączeń Gaia"},"pt-BR":{"name":"Tela de chamada","description":"Gaia Callscreen"},"ro":{"name":"Ecran de apelare","description":"Ecran de apelare Gaia"},"ru":{"name":"Экран звонка","description":"Экран звонка Gaia"},"sk":{"name":"Callscreen","description":"Gaia Callscreen"},"sq":{"name":"Callscreen","description":"Gaia Callscreen"},"sr-Cyrl":{"name":"Екран позива","description":"Gaia екран позива"},"sr-Latn":{"name":"Ekran poziva","description":"Gaia ekran poziva"},"sv-SE":{"name":"Samtalsskärm","description":"Gaia samtalsskärm"},"tr":{"name":"Arama ekranı","description":"Gaia arama ekranı"},"zh-CN":{"name":"通话界面","description":"Gaia 通话界面"},"zh-TW":{"name":"通話畫面","description":"Gaia 通話畫面"}},"default_locale":"en-US","origin":"app://callscreen.gaiamobile.org","version":"2.5"}

View file

@ -0,0 +1,14 @@
;this.asyncStorage=(function(){'use strict';var DBNAME='asyncStorage';var DBVERSION=1;var STORENAME='keyvaluepairs';var db=null;function withDatabase(f){if(db){f();}else{var openreq=indexedDB.open(DBNAME,DBVERSION);openreq.onerror=function withStoreOnError(){console.error('asyncStorage: can\'t open database:',openreq.error.name);};openreq.onupgradeneeded=function withStoreOnUpgradeNeeded(){openreq.result.createObjectStore(STORENAME);};openreq.onsuccess=function withStoreOnSuccess(){db=openreq.result;f();};}}
function withStore(type,callback,oncomplete){withDatabase(function(){var transaction=db.transaction(STORENAME,type);if(oncomplete){transaction.oncomplete=oncomplete;}
callback(transaction.objectStore(STORENAME));});}
function getItem(key,callback){var req;withStore('readonly',function getItemBody(store){req=store.get(key);req.onerror=function getItemOnError(){console.error('Error in asyncStorage.getItem(): ',req.error.name);};},function onComplete(){var value=req.result;if(value===undefined){value=null;}
callback(value);});}
function setItem(key,value,callback){withStore('readwrite',function setItemBody(store){var req=store.put(value,key);req.onerror=function setItemOnError(){console.error('Error in asyncStorage.setItem(): ',req.error.name);};},callback);}
function removeItem(key,callback){withStore('readwrite',function removeItemBody(store){var req=store.delete(key);req.onerror=function removeItemOnError(){console.error('Error in asyncStorage.removeItem(): ',req.error.name);};},callback);}
function clear(callback){withStore('readwrite',function clearBody(store){var req=store.clear();req.onerror=function clearOnError(){console.error('Error in asyncStorage.clear(): ',req.error.name);};},callback);}
function length(callback){var req;withStore('readonly',function lengthBody(store){req=store.count();req.onerror=function lengthOnError(){console.error('Error in asyncStorage.length(): ',req.error.name);};},function onComplete(){callback(req.result);});}
function key(n,callback){if(n<0){callback(null);return;}
var req;withStore('readonly',function keyBody(store){var advanced=false;req=store.openCursor();req.onsuccess=function keyOnSuccess(){var cursor=req.result;if(!cursor){return;}
if(n===0||advanced){return;}
advanced=true;cursor.advance(n);};req.onerror=function keyOnError(){console.error('Error in asyncStorage.key(): ',req.error.name);};},function onComplete(){var cursor=req.result;callback(cursor?cursor.key:null);});}
return{getItem:getItem,setItem:setItem,removeItem:removeItem,clear:clear,length:length,key:key};}());

View file

@ -0,0 +1,13 @@
;'use strict';var BluetoothHelper=function(){var profiles={'HFP':0x111E,'A2DP':0x110D};var _bluetooth=window.navigator.mozBluetooth;var _isReady=false;var _callbacks=[];var _adapter=null;var _oldAdapter=null;var _v2=true;var _ready=function(callback){if(!callback||!_bluetooth){return;}
if(_isReady){callback();}else{_callbacks.push(callback);}};var _handleRequest=function(request,callback,errorcb){request.onsuccess=function(){if(callback){callback(request.result);}};request.onerror=function(){console.log('Error handling bluetooth request');if(errorcb){errorcb();}};};var _processCallbacks=function(){if(_adapter){_isReady=true;_callbacks.forEach(function(callback){callback();});_callbacks=[];}else{console.log('BluetoothHelper(): connot get default adapter yet');}};var _fetchAdapterV2=function(){_bluetooth.onattributechanged=function onManagerAttributeChanged(evt){for(var i in evt.attrs){switch(evt.attrs[i]){case'defaultAdapter':console.log('defaultAdapter changed. address:',_bluetooth.defaultAdapter.address);_adapter=_bluetooth.defaultAdapter;_processCallbacks();break;default:break;}}};_adapter=_bluetooth.defaultAdapter;if(_adapter){_processCallbacks();}};var _fetchAdapter=function(){var req=_bluetooth.getDefaultAdapter();if(req){req.onsuccess=function(){if(_adapter){_oldAdapter=_adapter;}
_isReady=true;_adapter=req.result;if(_oldAdapter&&_oldAdapter.onpairedstatuschanged){_adapter.onpairedstatuschanged=_oldAdapter.onpairedstatuschanged;}
_callbacks.forEach(function(callback){callback();});_callbacks=[];};req.onerror=function(){console.log('BluetoothHelper(): connot get default adapter!!!');};}};var _getAdapter=function(){if(_v2){_fetchAdapterV2();}else{_fetchAdapter();}};var _resetAdapter=function(){if(_adapter){_oldAdapter=_adapter;}
_isReady=false;_adapter=null;};if(_bluetooth){if(typeof(_bluetooth.onattributechanged)==='undefined'){_v2=false;}
if(_v2){_bluetooth.onadapteradded=function onAdapterAdded(evt){_getAdapter();};}else{_bluetooth.addEventListener('enabled',_getAdapter);_bluetooth.addEventListener('adapteradded',_getAdapter);_bluetooth.addEventListener('disabled',_resetAdapter);}
_getAdapter();}
return{profiles:profiles,answerWaitingCall:function(){_ready(function(){_adapter.answerWaitingCall();});},ignoreWaitingCall:function(){_ready(function(){_adapter.ignoreWaitingCall();});},toggleCalls:function(){_ready(function(){_adapter.toggleCalls();});},getConnectedDevicesByProfile:function(profileID,cb){_ready(function(){_handleRequest(_adapter.getConnectedDevices(profileID),cb);});},connectSco:function(cb){_ready(function(){_handleRequest(_adapter.connectSco(),cb);});},disconnectSco:function(cb){_ready(function(){_handleRequest(_adapter.disconnectSco(),cb);});},getPairedDevices:function(cb){_ready(function(){_handleRequest(_adapter.getPairedDevices(),cb);});},getAddress:function(cb){if(_v2){console.log('getAddress function is deprecated');return;}
_ready(function(){var address=_adapter.address;cb(address);});},setPairingConfirmation:function(address,confirmed){if(_v2){console.log('setPairingConfirmation API is deprecated');return;}
_ready(function(){_adapter.setPairingConfirmation(address,confirmed);});},setPinCode:function(address,pincode){if(_v2){console.log('setPairingConfirmation API is deprecated');return;}
_ready(function(){_adapter.setPinCode(address,pincode);});},setPasskey:function(address,key){if(_v2){console.log('setPairingConfirmation API is deprecated');return;}
_ready(function(){_adapter.setPasskey(address,key);});},isScoConnected:function(cb,errorcb){_ready(function(){_handleRequest(_adapter.isScoConnected(),cb,errorcb);});},sendMediaMetaData:function(metadata,cb,errorcb){_ready(function(){_handleRequest(_adapter.sendMediaMetaData(metadata),cb,errorcb);});},sendMediaPlayStatus:function(metadata,cb,errorcb){_ready(function(){_handleRequest(_adapter.sendMediaPlayStatus(metadata),cb,errorcb);});},set onhfpstatuschanged(callback){_ready(function(){_adapter.onhfpstatuschanged=callback;});},set onscostatuschanged(callback){_ready(function(){_adapter.onscostatuschanged=callback;});},set ona2dpstatuschanged(callback){_ready(function(){_adapter.ona2dpstatuschanged=callback;});},set onrequestmediaplaystatus(callback){_ready(function(){_adapter.onrequestmediaplaystatus=callback;});},set onpairedstatuschanged(callback){if(_v2){console.log('onpairedstatuschanged API is deprecated');return;}
_ready(function(){_adapter.onpairedstatuschanged=callback;});},v2:_v2,enable:function(){if(_v2){_ready(function(){_adapter.enable();});}else{console.log('enable is not support in v1 API!');}},disable:function(){if(_v2){_ready(function(){_adapter.disable();});}else{console.log('disable is not support in v1 API!');}}};};

View file

@ -0,0 +1,13 @@
;(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);

View file

@ -0,0 +1,3 @@
;(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);})();

View file

@ -0,0 +1,15 @@
;'use strict';var Contacts={_FB_FILES:['/shared/js/fb/fb_request.js','/shared/js/fb/fb_data_reader.js','/shared/js/fb/fb_reader_utils.js'],getRevision:function getRevision(callback){var mozContacts=navigator.mozContacts;if(!mozContacts){callback(null);return;}
var req=mozContacts.getRevision();req.onsuccess=function onsuccess(event){callback(event.target.result);};req.onerror=function onerror(event){console.log('Error '+event.target.error);callback(null);};},findByNumber:function findByNumber(number,callback){LazyLoader.load(this._FB_FILES,this._findByNumber.bind(this,number,callback));},_findByNumber:function _findByNumber(number,callback){if(!number){callback(null);return;}
var options;var variants;if(number.length<7){variants=[number];options={filterBy:['tel'],filterOp:'equals',filterValue:number};}else{variants=SimplePhoneMatcher.generateVariants(number);var sanitizedNumber=SimplePhoneMatcher.sanitizedNumber(number);options={filterBy:['tel'],filterOp:'match',filterValue:sanitizedNumber};}
var mozContacts=navigator.mozContacts;if(!mozContacts){callback(null);return;}
var request=mozContacts.find(options);request.onsuccess=function findCallback(){var contacts=request.result;if(contacts.length===0){fb.getContactByNumber(number,function fb_ready(finalContact){var objMatching=null;if(finalContact){objMatching={value:number,type:'personal',carrier:null};}
callback(finalContact,objMatching);},function fb_err(err){callback(null);});return;}
var matches=contacts.map(function getTels(contact){return contact.tel.map(function getNumber(tel){return tel.value;});});var matchResult=SimplePhoneMatcher.bestMatch(variants,matches);var contact=contacts[matchResult.bestMatchIndex];var contactsWithSameNumber;if(contacts.length>1){contactsWithSameNumber=contacts.length-1;}
var matchingTel=contact.tel[matchResult.localIndex];if(fb.isFbLinked(contact)){var req=fb.getData(contact);req.onsuccess=function(){callback(req.result,matchingTel,contactsWithSameNumber);};req.onerror=function(){window.console.error('Error while getting FB Data');callback(contact,matchingTel,contactsWithSameNumber);};}
else{callback(contact,matchingTel,contactsWithSameNumber);}};request.onerror=function findError(){callback(null);};},_mergeOneFbContact:function _mergeOneFbContact(contacts,index){return new Promise(function(resolve,reject){var fbReq=fb.getData(contacts[index]);fbReq.onsuccess=function(){var originalTel=contacts[index].tel;contacts[index]=fbReq.result;contacts[index].tel=originalTel;resolve();};fbReq.onerror=function(){console.error('Could not merge Facebook data for',contacts[index].id);reject();};});},_mergeFbContacts:function _mergeFbContacts(contacts,callback){if(!callback||!(callback instanceof Function)){return;}
if(!contacts){callback(null);}
LazyLoader.load(this._FB_FILES,function(){var pending=contacts.length;var onContactMerged=function(){if(--pending===0){callback(contacts);}};for(var i=0,length=contacts.length;i<length;i++){if(fb.isFbContact(contacts[i])){this._mergeOneFbContact(contacts,i).then(onContactMerged,onContactMerged);}else{onContactMerged();}}}.bind(this));},_findContacts:function _findContacts(options,callback){if(!callback||!(callback instanceof Function)){return;}
if(!navigator.mozContacts||!options){callback(null);return;}
var self=this;var req=navigator.mozContacts.find(options);req.onsuccess=function onsuccess(){var contacts=req.result;if(!contacts.length){callback(null);return;}
self._mergeFbContacts(contacts,callback);};req.onerror=function onerror(){console.error('Contact finding error. Error: '+req.errorCode);callback(null);};},findListByNumber:function findListByNumber(number,limit,callback){var self=this;asyncStorage.getItem('order.lastname',function(value){var sortKey=value?'familyName':'givenName';var options={filterBy:['tel'],filterOp:'contains',filterValue:number,sortBy:sortKey,sortOrder:'ascending',filterLimit:limit};self._findContacts(options,callback);});},getLength:function getLength(prop){if(!prop||!prop.length){return 0;}
return prop.length;},sendEmailOrPick:function sendEmailOrPick(address){try{new MozActivity({name:'new',data:{type:'mail',URI:'mailto:'+address}});}catch(e){console.error('WebActivities unavailable? : '+e);}}};

View file

@ -0,0 +1,2 @@
;'use strict';function DtmfTone(tone,short,serviceId){this.tone=tone;this.short=short;this.serviceId=serviceId;this.timer=0;}
DtmfTone.kShortToneLength=120;DtmfTone.prototype={play:function dt_play(){clearTimeout(this.timer);navigator.mozTelephony.stopTone(this.serviceId);navigator.mozTelephony.startTone(this.tone,this.serviceId);if(this.short){this.timer=window.setTimeout(function dt_stopTone(serviceId){navigator.mozTelephony.stopTone(serviceId);},DtmfTone.kShortToneLength,this.serviceId);}},stop:function dt_stop(){clearTimeout(this.timer);navigator.mozTelephony.stopTone(this.serviceId);}};

View file

@ -0,0 +1,17 @@
;'use strict';var FontSizeManager=(function fontSizeManager(){var DIAL_PAD=0,SINGLE_CALL=1,CALL_WAITING=2,STATUS_BAR=3,SECOND_INCOMING_CALL=4;var _sizes={};_sizes[DIAL_PAD]={min:2.6,max:4.1};_sizes[SINGLE_CALL]={min:2.3,max:3.4,line:3.4};_sizes[CALL_WAITING]={min:2.3,max:2.5,line:1.3};_sizes[STATUS_BAR]={min:1.7,max:1.7};_sizes[SECOND_INCOMING_CALL]={min:2.3,max:2.5,line:3.7};var _defaultFontSize;function _getRootFontSize(){_defaultFontSize=_defaultFontSize||parseInt(window.getComputedStyle(document.body,null).getPropertyValue('font-size'));return _defaultFontSize;}
function _getMinFontSize(scenario){return Math.round(_sizes[scenario].min*_getRootFontSize());}
function _getMaxFontSize(scenario){return Math.round(_sizes[scenario].max*_getRootFontSize());}
function _getAllowedFontSizes(scenario){var minFontSize=_getMinFontSize(scenario);var maxFontSize=_getMaxFontSize(scenario);var allowedSizes=[];for(var size=minFontSize;size<=maxFontSize;size+=4){allowedSizes.push(size);}
if(allowedSizes.indexOf(maxFontSize)===-1){allowedSizes.push(maxFontSize);}
return allowedSizes;}
function adaptToSpace(scenario,view,forceMaxFontSize,ellipsisSide){var computedStyle=window.getComputedStyle(view);if((!view.value&&!view.textContent)||!computedStyle){return;}
var viewWidth=view.getBoundingClientRect().width;var viewFont=computedStyle.fontFamily;var allowedSizes;if(forceMaxFontSize){allowedSizes=[_getMaxFontSize(scenario)];}else{allowedSizes=_getAllowedFontSizes(scenario);}
var infos=FontSizeUtils.getMaxFontSizeInfo(view.value||view.textContent,allowedSizes,viewFont,viewWidth);var newFontSize=infos.fontSize;if(view.style.fontSize!==newFontSize){view.style.fontSize=newFontSize+'px';}
if(infos&&infos.overflow){var overflowCount=FontSizeUtils.getOverflowCount(view.value||view.textContent,newFontSize,viewFont,viewWidth);overflowCount+=2;_useEllipsis(view,overflowCount,ellipsisSide);view.dataset.ellipsedCharacters=overflowCount;}else{view.dataset.ellipsedCharacters=0;}}
function _useEllipsis(view,overflowCount,ellipsisSide){var side=ellipsisSide||'begin';var localizedSide=(side==='begin'?'left':'right');var value=view.value||view.textContent;if(localizedSide=='left'){value='\u2026'+value.substr(-value.length+overflowCount);}else if(localizedSide=='right'){value=value.substr(0,value.length-overflowCount)+'\u2026';}
if(view.value){view.value=value;}else{var el=view.querySelector('bdi')||view;el.textContent=value;}}
function ensureFixedBaseline(scenario,view){var initialLineHeight=_sizes[scenario].line;if(!initialLineHeight){return;}
var maxFontSize=_getMaxFontSize(scenario);var fontSize=parseInt(window.getComputedStyle(view).fontSize,10);view.style.lineHeight=initialLineHeight*_getRootFontSize()+
(maxFontSize-fontSize)/2+'px';}
function resetFixedBaseline(view){view.style.removeProperty('line-height');}
return{DIAL_PAD:DIAL_PAD,SINGLE_CALL:SINGLE_CALL,CALL_WAITING:CALL_WAITING,STATUS_BAR:STATUS_BAR,SECOND_INCOMING_CALL:SECOND_INCOMING_CALL,adaptToSpace:adaptToSpace,ensureFixedBaseline:ensureFixedBaseline,resetFixedBaseline:resetFixedBaseline};})();

View file

@ -0,0 +1,47 @@
;'use strict';var gTonesFrequencies={'1':[697,1209],'2':[697,1336],'3':[697,1477],'4':[770,1209],'5':[770,1336],'6':[770,1477],'7':[852,1209],'8':[852,1336],'9':[852,1477],'*':[941,1209],'0':[941,1336],'#':[941,1477]};var KeypadManager={kMaxDigits:50,_phoneNumber:'',_onCall:false,_keypadSoundIsEnabled:false,_shortTone:false,_vibrationEnabled:false,kVibrationDuration:50,_insertPosition:null,onValueChanged:null,get phoneNumberView(){delete this.phoneNumberView;this.phoneNumberView=document.getElementById('phone-number-view');return this.phoneNumberView;},get phoneNumberViewContainer(){delete this.phoneNumberViewContainer;this.phoneNumberViewContainer=document.getElementById('phone-number-view-container');return this.phoneNumberViewContainer;},get keypad(){delete this.keypad;this.keypad=document.getElementById('keypad');return this.keypad;},get callBar(){delete this.callBar;this.callBar=document.getElementById('keypad-callbar');return this.callBar;},get hideBar(){delete this.hideBar;this.hideBar=document.getElementById('keypad-hidebar');return this.hideBar;},get callBarAddContact(){delete this.callBarAddContact;this.callBarAddContact=document.getElementById('keypad-callbar-add-contact');return this.callBarAddContact;},get callBarCallAction(){delete this.callBarCallAction;this.callBarCallAction=document.getElementById('keypad-callbar-call-action');return this.callBarCallAction;},get callBarCancelAction(){delete this.callBarCancelAction;this.callBarCancelAction=document.getElementById('keypad-callbar-cancel');return this.callBarCancelAction;},get deleteButton(){delete this.deleteButton;this.deleteButton=document.getElementById('keypad-delete');return this.deleteButton;},get hideBarHangUpAction(){delete this.hideBarHangUpAction;this.hideBarHangUpAction=document.getElementById('keypad-hidebar-hang-up-action-wrapper');return this.hideBarHangUpAction;},get hideBarHideAction(){delete this.hideBarHideAction;this.hideBarHideAction=document.getElementById('keypad-hidebar-hide-keypad-action');return this.hideBarHideAction;},multiSimActionButton:null,init:function kh_init(oncall){this._onCall=!!oncall;this._lastPressedKey=null;this.phoneNumberView.value='';this.phoneNumberView.addEventListener('click',this._updateInsertPosition.bind(this));this._phoneNumber='';var keyHandler=this.keyHandler.bind(this);this.keypad.addEventListener('contextmenu',keyHandler);this.keypad.addEventListener('touchstart',keyHandler,true);this.keypad.addEventListener('touchmove',keyHandler,true);this.keypad.addEventListener('touchend',keyHandler,true);this.keypad.addEventListener('touchcancel',keyHandler,true);this.deleteButton.addEventListener('touchstart',keyHandler);this.deleteButton.addEventListener('touchend',keyHandler);if(this.callBarAddContact){this.callBarAddContact.addEventListener('click',this.addContact.bind(this));}
if(this.callBarCallAction){if(typeof MultiSimActionButton!=='undefined'){this.multiSimActionButton=new MultiSimActionButton(this.callBarCallAction,CallHandler.call,'ril.telephony.defaultServiceId',this.phoneNumber.bind(this));}
this.callBarCallAction.addEventListener('click',this.fetchLastCalled.bind(this));}
if(this.callBarCancelAction){this.callBarCancelAction.addEventListener('click',function(){window.parent.LockScreen.switchPanel();});}
if(this.hideBarHideAction){this.hideBarHideAction.addEventListener('click',this.callbarBackAction);}
if(this.hideBarHangUpAction){this.hideBarHangUpAction.addEventListener('click',this.hangUpCallFromKeypad);}
TonePlayer.init('system');this.render();LazyLoader.load(['/shared/style/action_menu.css','/dialer/js/suggestion_bar.js']);this._observePreferences();},render:function hk_render(layoutType){if(layoutType=='oncall'){if(CallsHandler.activeCall){var activeCall=CallsHandler.activeCall.call;this._phoneNumber=activeCall.id.number;}
this._isKeypadClicked=false;this.phoneNumberViewContainer.classList.add('keypad-visible');if(this.callBar){this.callBar.classList.add('hide');}
if(this.hideBar){this.hideBar.classList.remove('hide');}
this.deleteButton.classList.add('hide');}else{this.phoneNumberViewContainer.classList.remove('keypad-visible');if(this.callBar){this.callBar.classList.remove('hide');}
if(this.hideBar){this.hideBar.classList.add('hide');}
this.deleteButton.classList.remove('hide');}},phoneNumber:function hk_phoneNumber(){return this._phoneNumber;},fetchLastCalled:function hk_fetchLastCalled(){if(this._phoneNumber!==''){return;}
var self=this;CallLogDBManager.getGroupAtPosition(1,'lastEntryDate',true,'dialing',function hk_ggap_callback(result){if(result&&(typeof result==='object')&&result.number){self.updatePhoneNumber(result.number);}});},addContact:function hk_addContact(event){var number=this._phoneNumber;if(!number){return;}
LazyLoader.load(['/dialer/js/add_contact_menu.js'],function(){AddContactMenu.show(number);});},callbarBackAction:function hk_callbarBackAction(event){CallScreen.hideKeypad();},hangUpCallFromKeypad:function hk_hangUpCallFromKeypad(event){CallScreen.hideKeypad();CallsHandler.end();},_lastPressedKey:null,_dtmfTone:null,_playDtmfTone:function kh_playDtmfTone(key){var serviceId=0;if(!this._onCall){return;}
if(CallsHandler.activeCall){serviceId=CallsHandler.activeCall.call.serviceId;}else{serviceId=navigator.mozTelephony.active.calls[0].serviceId;}
if(this._dtmfTone){this._dtmfTone.stop();this._dtmfTone=null;}
this._dtmfTone=new DtmfTone(key,this._shortTone,serviceId);this._dtmfTone.play();},_stopDtmfTone:function kh_stopDtmfTone(){if(!this._dtmfTone){return;}
this._dtmfTone.stop();this._dtmfTone=null;},_touchStart:function kh_touchStart(key){this._longPress=false;this._lastPressedKey=key;if(key!=='delete'&&!this._onCall&&(this._phoneNumber.length>=this.kMaxDigits)){return;}
if(key!='delete'){if(this._keypadSoundIsEnabled){TonePlayer.start(gTonesFrequencies[key],!this._onCall||this._shortTone);}
if(this._vibrationEnabled){navigator.vibrate(this.kVibrationDuration);}
this._playDtmfTone(key);}
if(((key=='0'||key=='*')&&!this._onCall)||key=='delete'){this._holdTimer=setTimeout(function(self){self.restoreCaretPosition();if(key=='delete'){self._clearPhoneNumber();}else if(key==='0'){self._replaceLastKey('+');}else if(key==='*'){var isAtTheEnd=self._insertPosition===null;var isFirst=self._insertPosition===1||(isAtTheEnd&&self._phoneNumber.length===1);if(!isFirst){self._replaceLastKey(',');}else{self._deleteAtInsertPosition();}}
self._longPress=true;self._updatePhoneNumberView('begin',false);},400,this);}
if(key==='1'&&this._phoneNumber===''){this._holdTimer=setTimeout(function vm_call(self){self._longPress=true;self._callVoicemail();self._phoneNumber='';self._updatePhoneNumberView('begin',false);},400,this);}
if(key=='delete'){this._deleteAtInsertPosition();}else if(this.phoneNumberViewContainer.classList.contains('keypad-visible')){if(!this._isKeypadClicked){this._isKeypadClicked=true;this._phoneNumber=key;this.replaceAdditionalContactInfo('');}else{this._insertAtCaret(key);}}else{this._insertAtCaret(key);}
if(key==='#'&&!this._onCall){if(this._phoneNumber==='*#06#'){this.multiSimActionButton.performAction();return;}else if(this._isSpeedDialNumber(this._phoneNumber)){this._handleSpeedDial(this._phoneNumber.slice(0,-1));return;}}
setTimeout(function(self){self._updatePhoneNumberView('begin',false);},0,this);},_touchMove:function kh_touchMove(touch){var target=document.elementFromPoint(touch.pageX,touch.pageY);var key=(target&&target.dataset)?target.dataset.value:null;if(key!==this._lastPressedKey||key==='delete'){this._stopDtmfTone();}},_touchEnd:function kh_touchEnd(key){this._lastPressedKey=null;if(key!=='delete'){this._stopDtmfTone();}
if(this._keypadSoundIsEnabled){TonePlayer.stop();}
this.restoreCaretPosition();if(this._longPress){this._longPress=false;this._holdTimer=null;return;}
if(this._holdTimer){clearTimeout(this._holdTimer);}},keyHandler:function kh_keyHandler(event){event.preventDefault();if(event.type=='contextmenu'){return;}
var key=event.target.dataset.value;if(!key){return;}
event.stopPropagation();switch(event.type){case'touchstart':if(this._lastPressedKey){return;}
event.target.classList.add('active');this._touchStart(key);break;case'touchmove':this._touchMove(event.touches[0]);break;case'touchend':case'touchcancel':if(key!==this._lastPressedKey){return;}
event.target.classList.remove('active');this._touchEnd(key);break;}},_isSpeedDialNumber:function(number){return!!number.match(/^[0-9][0-9]{0,2}\#$/);},_getSpeedDialNumber:function(index){var self=this;var cardIndex;index--;return new Promise(function(resolve,reject){LazyLoader.load(['/shared/js/sim_settings_helper.js'],function(){SimSettingsHelper.getCardIndexFrom('outgoingCall',function(defaultCardIndex){if(defaultCardIndex==SimSettingsHelper.ALWAYS_ASK_OPTION_VALUE){LazyLoader.load(['/shared/js/component_utils.js','/shared/elements/gaia_sim_picker/script.js'],function(){var simPicker=document.getElementById('sim-picker');simPicker.getOrPick(defaultCardIndex,null,function(pickedCardIndex){cardIndex=pickedCardIndex;resolve();});});}else{cardIndex=defaultCardIndex;resolve();}});});}).then(function(){return self._getSimContactsList(cardIndex).then(function(simContactsList){if((index>=0)&&(index<simContactsList.length)){return simContactsList[index].number;}else{return Promise.reject('noContactsWereFound');}});});},_handleSpeedDial:function(index){var self=this;this.updatePhoneNumber('','begin',false);this._getSpeedDialNumber(+index).then(function(number){self.updatePhoneNumber(number,'begin',false);},function(error){if(error){ConfirmDialog.show(error,null,{title:'noContactsFoundDialogOk',callback:ConfirmDialog.hide});}});},_createSimContactList:function(contacts){var numbers=new Array(contacts.length);for(var i=0;i<contacts.length;i++){numbers[i]={id:contacts[i].id,number:contacts[i].tel[0].value,};}
numbers.sort(function(a,b){if(a.id.length==b.id.length){return(a.id>b.id)?1:0;}else{return(a.id.length>b.id.length)?1:0;}});return numbers;},_getSimContactsList:function(cardIndex){var self=this;var canceled=false;return new Promise(function(resolve,reject){LazyLoader.load(['/shared/style/confirm.css','/shared/js/confirm.js',document.getElementById('confirmation-message')],function(){var iccId=navigator.mozIccManager.iccIds[cardIndex];var icc=navigator.mozIccManager.getIccById(iccId);if(!icc){reject('noSimCardToLoadContactsFrom');return;}
var req=icc.readContacts('adn');req.onsuccess=function(event){var adnContacts=event.target.result;var contacts=self._createSimContactList(adnContacts);if(!canceled){ConfirmDialog.hide();}
resolve(contacts);};req.onerror=function(error){console.error('Could not retrieve the ADN contacts from SIM card '+
cardIndex+', got error '+error.name);reject('noContactsWereFound');};ConfirmDialog.show('loadingSimContacts',null,{title:'cancel',callback:function(){canceled=true;ConfirmDialog.hide();reject();}});});});},sanitizePhoneNumber:function(number){return number.replace(/\s+/g,'');},updatePhoneNumber:function kh_updatePhoneNumber(number,ellipsisSide,forceMaxFontSize){number=this.sanitizePhoneNumber(number);this._phoneNumber=number;this._updatePhoneNumberView(ellipsisSide,forceMaxFontSize);},press:function(value){this._playDtmfTone(value);TonePlayer.start(gTonesFrequencies[value],true);setTimeout((function nextTick(){TonePlayer.stop();this._stopDtmfTone();}).bind(this));},_updatePhoneNumberView:function kh_updatePhoneNumberview(ellipsisSide,forceMaxFontSize){var phoneNumber=this._phoneNumber;if(this._onCall){this.renderPhoneNumber(phoneNumber,ellipsisSide);}else{var visibility;if(phoneNumber.length>0){visibility='visible';this.callBarAddContact.removeAttribute('disabled');}else{visibility='hidden';this.callBarAddContact.setAttribute('disabled','disabled');}
this.deleteButton.style.visibility=visibility;this.phoneNumberView.blur();this.phoneNumberView.value=phoneNumber;FontSizeManager.adaptToSpace(FontSizeManager.DIAL_PAD,this.phoneNumberView,forceMaxFontSize,ellipsisSide);}
if(this.onValueChanged){this.onValueChanged(this._phoneNumber);}},renderPhoneNumber:function kh_replacePhoneNumber(phoneNumber,ellipsisSide){if(this._onCall&&CallsHandler.activeCall){CallsHandler.activeCall.renderPhoneNumber({raw:phoneNumber},ellipsisSide);}},restorePhoneNumber:function kh_restorePhoneNumber(){if(this._onCall&&CallsHandler.activeCall){CallsHandler.activeCall.restorePhoneNumber();}},replaceAdditionalContactInfo:function kh_replaceAdditionalContactInfo(additionalContactInfo){var call=CallsHandler.activeCall;if(this._onCall&&call){call.replaceAdditionalContactInfo(additionalContactInfo);}},restoreAdditionalContactInfo:function kh_restoreAdditionalContactInfo(){if(this._onCall&&CallsHandler.activeCall){CallsHandler.activeCall.restoreAdditionalContactInfo();}},_callVoicemail:function(){if(navigator.mozIccManager.iccIds.length<=1){this._callVoicemailForSim(0);return;}
var self=this;var key='ril.voicemail.defaultServiceId';var req=navigator.mozSettings.createLock().get(key);req.onsuccess=function(){LazyLoader.load(['/shared/js/component_utils.js','/shared/elements/gaia_sim_picker/script.js'],function(){var simPicker=document.getElementById('sim-picker');navigator.mozL10n.formatValue('voiceMail').then(string=>{simPicker.getOrPick(req.result[key],string,self._callVoicemailForSim.bind(self));});});};},_callVoicemailForSim:function(cardIndex){var settings=navigator.mozSettings;if(!settings){return;}
var transaction=settings.createLock();var request=transaction.get('ril.iccInfo.mbdn');request.onsuccess=(function(){var numbers=request.result['ril.iccInfo.mbdn'];var number;if(typeof numbers=='string'){number=numbers;}else{number=numbers&&numbers[cardIndex];}
var voicemail=navigator.mozVoicemail;if(!number&&voicemail){number=voicemail.getNumber(cardIndex);}
if(number){CallHandler.call(number,cardIndex);}else{this._showNoVoicemailDialog();}}).bind(this);request.onerror=function(){};},_showNoVoicemailDialog:function hk_showNoVoicemailDialog(){var voicemailDialog={title:'voicemailNoNumberTitle',text:'voicemailNoNumberText',confirm:{title:'voicemailNoNumberSettings',recommend:true,callback:this.showVoicemailSettings},cancel:{title:'voicemailNoNumberCancel',callback:this._hideNoVoicemailDialog}};LazyLoader.load(['/shared/js/custom_dialog.js'],function(){CustomDialog.show(voicemailDialog.title,voicemailDialog.text,voicemailDialog.cancel,voicemailDialog.confirm);});},_hideNoVoicemailDialog:function kh_hideNoVoicemailDialog(){CustomDialog.hide();},showVoicemailSettings:function kh_showVoicemailSettings(){var activity=new window.MozActivity({name:'configure',data:{target:'device',section:'call'}});activity.onerror=function(){console.warn('Configure activity error:',activity.error.name);};},_observePreferences:function kh_observePreferences(){var self=this;LazyLoader.load('/shared/js/settings_listener.js',function(){SettingsListener.observe('phone.ring.keypad',false,function(value){self._keypadSoundIsEnabled=!!value;});SettingsListener.observe('phone.dtmf.type','long',function(value){self._shortTone=(value==='short');});SettingsListener.observe('keyboard.vibration',false,function(value){self._vibrationEnabled=!!value;});});},_updateInsertPosition:function kh_updateInsertPosition(){this._insertPosition=this._realStartPosition();},_replaceLastKey:function kh_replaceLastKey(newKey){this._deleteAtInsertPosition();this.restoreCaretPosition();this._insertAtCaret(newKey);},_insertAtCaret:function kh_insertAtCaret(key){if(this._insertPosition===null){this._phoneNumber+=key;}else{var start=this._realStartPosition();var end=this._realEndPosition();this._phoneNumber=this._phoneNumber.substring(0,start)+key+
this._phoneNumber.substring(end);this._insertPosition=start+1;}},_deleteAtInsertPosition:function kh_deleteAtInsertPosition(){if(this._insertPosition===null){this._phoneNumber=this._phoneNumber.slice(0,-1);}else{var start=this._realStartPosition();var end=this._realEndPosition();if(start>0&&start===end){start=end-1;}
this._phoneNumber=this._phoneNumber.substring(0,start)+
this._phoneNumber.substring(end);this._insertPosition=this._phoneNumber?start:null;}},_clearPhoneNumber:function kh_clearPhoneNumber(){if(this._insertPosition===null){this._phoneNumber='';}else{var start=this._realStartPosition();this._phoneNumber=this._phoneNumber.substring(start);this._insertPosition=this._phoneNumber?0:null;}},restoreCaretPosition:function kh_restoreCaretPosition(){if(this._insertPosition!==null){var caretPosition=this._caretPosition(this._insertPosition);this.phoneNumberView.selectionStart=caretPosition;this.phoneNumberView.selectionEnd=caretPosition;this.phoneNumberView.focus();}else{this.phoneNumberView.blur();}},_realStartPosition:function kh_realStartPosition(){var start=this.phoneNumberView.selectionStart;return this._realPosition(this.phoneNumberView,start);},_realEndPosition:function kh_realEndPosition(){var end=this.phoneNumberView.selectionEnd;return this._realPosition(this.phoneNumberView,end);},_caretPosition:function kh_caretPosition(realPosition){return realPosition-this._ellipsisOffset(this.phoneNumberView);},_realPosition:function kh_realPosition(input,position){return position+this._ellipsisOffset(this.phoneNumberView);},_ellipsisOffset:function kh_ellipsisOffset(input){var ellipsedCharacters=+input.dataset.ellipsedCharacters;return ellipsedCharacters?(ellipsedCharacters-1):0;}};

View file

@ -0,0 +1,9 @@
;'use strict';const kMasterVolume=0.5;const kToneVolume=0.7;const kShortPressDuration=0.15;const kAttackDuration=0.025;const kDecayDuration=0.025;const kReleaseDuration=0.05;var TonePlayer={_audioContext:null,_channel:null,_gainNode:null,_playingNodes:[],_maybeTrashAudio:null,_initialized:false,init:function tp_init(channel){var telephony=navigator.mozTelephony;this._reset();this._channel=channel;this._maybeTrashAudio=(function tp_maybeTrashAudio(){var callIsActive=telephony&&(telephony.calls.length||telephony.conferenceGroup.calls.length);if(document.hidden&&!((this._channel==='telephony')&&callIsActive)){this._trashAudio();}}).bind(this);window.addEventListener('visibilitychange',this._maybeTrashAudio);telephony&&telephony.addEventListener('callschanged',this._maybeTrashAudio);this._initialized=true;},teardown:function tp_teardown(){var telephony=navigator.mozTelephony;telephony&&telephony.removeEventListener('callschanged',this._maybeTrashAudio);window.removeEventListener('visibilitychange',this._maybeTrashAudio);this._reset();this._initialized=false;},_reset:function tp_reset(){this._audioContext=null;this._channel=null;this._gainNode=null;this._playingNodes=[];this._maybeTrashAudio=null;},_ensureAudio:function tp_ensureAudio(){if(this._audioContext||!this._initialized){return;}
this._audioContext=new AudioContext();},_trashAudio:function tp_trashAudio(){this.stop();this._audioContext=null;},_startAt:function tp_startAt(frequencies,when,duration){var context=this._audioContext;var sampleRate=context.sampleRate;var envelope=context.createBuffer(1,(duration?duration:0.05)*sampleRate,sampleRate);for(var i=0;i<envelope.length;i++){var factor=kToneVolume;var t=i/sampleRate;if(t<=kAttackDuration){factor=t/kAttackDuration;}else if(t-kAttackDuration<=kDecayDuration){factor=1.0-(1.0-kToneVolume)*(t-kAttackDuration)/kDecayDuration;}
if(!duration){factor-=kToneVolume;}else if(t>duration-kReleaseDuration){factor*=(duration-t)/kReleaseDuration;}
envelope.getChannelData(0)[i]=factor*kMasterVolume;}
var gainNode=context.createGain();gainNode.connect(context.destination);if(!duration){this._gainNode=gainNode;}
var envelopeNode=context.createBufferSource();envelopeNode.buffer=envelope;envelopeNode.start(when);envelopeNode.connect(gainNode.gain);gainNode.gain.setValueAtTime(duration?0.0:kToneVolume*kMasterVolume,0.0);for(i=0;i<frequencies.length;++i){var oscNode=this._audioContext.createOscillator();oscNode.type='sine';oscNode.frequency.value=frequencies[i];oscNode.start(when);if(duration){oscNode.stop(Math.max(when,context.currentTime+0.5)+duration);}else{this._playingNodes.push(oscNode);}
oscNode.connect(gainNode);}},start:function tp_start(frequencies,shortPress){this._ensureAudio();this._startAt(frequencies,0,shortPress?kShortPressDuration:0);},stop:function tp_stop(){if(!this._gainNode){return;}
var context=this._audioContext;var sampleRate=context.sampleRate;var gain=this._gainNode.gain;this._gainNode=null;var ramp=context.createBuffer(1,kReleaseDuration*sampleRate,sampleRate);for(var i=0;i<ramp.length;i++){ramp.getChannelData(0)[i]=(ramp.length-i-1)/ramp.length*kToneVolume*kMasterVolume;}
var rampNode=context.createBufferSource();rampNode.buffer=ramp;rampNode.start();rampNode.connect(gain);gain.setValueAtTime(0.0,0.0);while(this._playingNodes.length){this._playingNodes.pop().stop(context.currentTime+kReleaseDuration+0.5);}},playSequence:function tp_playSequence(sequence){this._ensureAudio();var when=this._audioContext.currentTime+0.2;for(var index=0;index<sequence.length;++index){var step=sequence[index];var frequencies=step.slice(0,2);var duration=step[2]/1000;this._startAt(frequencies,when,duration);when+=duration;}}};

View file

@ -0,0 +1,9 @@
;'use strict';var Utils={prettyDate:function ut_prettyDate(time){var f=Intl.DateTimeFormat(navigator.languages,{hour12:navigator.mozHour12,hour:'numeric',minute:'numeric'});return f.format(new Date(time));},prettyDuration:function(node,duration,l10nPrefix){var elapsed=new Date(duration);var h=elapsed.getUTCHours();var m=elapsed.getUTCMinutes();var s=elapsed.getUTCSeconds();var l10nId=l10nPrefix||'callDuration';var durationL10n={h:h+'',m:m+'',s:s+''};if(l10nId==='callDuration'){durationL10n={h:(h>9?'':'0')+h,m:(m>9?'':'0')+m,s:(s>9?'':'0')+s};}
if(l10nPrefix==='callDurationTextFormat'&&h===0&&m===0){l10nId+='Seconds';}else{l10nId+=h>0?'Hours':'Minutes';}
navigator.mozL10n.setAttributes(node,l10nId,durationL10n);},setHeaderDate:function ut_setHeaderDate(elem,time){var diff=(Date.now()-time)/1000;var day_diff=Math.floor(diff/86400);var formattedTime;if(isNaN(day_diff)){elem.setAttribute('data-l10n-id','incorrectDate');return;}else if(day_diff===0){elem.setAttribute('data-l10n-id','today');return;}else if(day_diff===1){elem.setAttribute('data-l10n-id','yesterday');return;}else if(day_diff<6){formattedTime=(new Date(time)).toLocaleString(navigator.languages,{weekday:'long',});}else{formattedTime=(new Date(time)).toLocaleString(navigator.languages,{year:'2-digit',month:'2-digit',day:'2-digit'});}
elem.removeAttribute('data-l10n-id');elem.textContent=formattedTime;},getPhoneNumberPrimaryInfo:function ut_getPhoneNumberPrimaryInfo(matchingTel,contact){if(contact){if(contact.name&&contact.name.length&&contact.name[0]!==''){return contact.name;}else if(contact.org&&contact.org.length&&contact.org[0]!==''){return contact.org;}}
if(matchingTel){return matchingTel.value;}
return null;},toCamelCase:function ut_toCamelCase(str){return str.replace(/\-(.)/g,function replacer(str,p1){return p1.toUpperCase();});},_phoneTypesL10n:{'mobile':'phone_type_mobile','home':'phone_type_home','work':'phone_type_work','personal':'phone_type_personal','faxHome':'phone_type_fax_home','faxOffice':'phone_type_fax_office','faxOther':'phone_type_fax_other','other':'phone_type_other'},getPhoneNumberAdditionalInfo:function ut_getPhoneNumberAdditionalInfo(matchingTel){var type=matchingTel.type||'mobile';var carrier=matchingTel.carrier;if(Array.isArray(type)){type=type[0];}
var id;var args={};if(this._phoneTypesL10n.hasOwnProperty(type)){id=this._phoneTypesL10n[type];}else{id='phone_type_custom';args.type=type;}
if(carrier){id+='_and_carrier';args.carrier=carrier;}
return{id:id,args:Object.keys(args).length?args:null};},isPhoneType:function ut_isPhoneType(type){return this._phoneTypesL10n.hasOwnProperty(type);}};

View file

@ -0,0 +1,5 @@
;'use strict';(function(exports){var Voicemail={check:function vm_check(number,cardIndex){return new Promise(function(resolve,reject){if(!number){resolve(false);return;}
var serviceId=cardIndex;var voicemail=navigator.mozVoicemail;if(voicemail){var voicemailNumber=voicemail.getNumber(serviceId);if(voicemailNumber===number){resolve(true);return;}}
var settings=navigator.mozSettings;var req=settings.createLock().get('ril.iccInfo.mbdn');req.onsuccess=function getVoicemailNumber(){var isVoicemailNumber=false;var voicemailNumbers=req.result['ril.iccInfo.mbdn'];var voicemailNumber;if(typeof voicemailNumbers==='string'){voicemailNumber=voicemailNumbers;}else{voicemailNumber=voicemailNumbers&&voicemailNumbers[serviceId];}
if(voicemailNumber===number){isVoicemailNumber=true;}
resolve(isVoicemailNumber);};req.onerror=function getVoicemailNumberError(){resolve(false);};});}};exports.Voicemail=Voicemail;}(window));

View file

@ -0,0 +1,423 @@
'use strict';
/* global LazyLoader, TelIndexer */
// Reader Module for FB Data in a Datastore
// To use this library you need to include 'shared/js/fb/fb_request.js'
// WARNING: This file lazy loads 'shared/js/fb/fb_tel_index.js'
var fb = self.fb || {};
self.fb = fb;
(function() {
var contacts = fb.contacts || {};
fb.contacts = contacts;
var datastore;
// Datastore name declared on the manifest.webapp
var DATASTORE_NAME = 'Gaia_Facebook_Friends';
// Record Id for the index
var INDEX_ID = 1;
// Indicates the initialization state
var readyState = 'notInitialized';
// Custom event for notifying initializations
var INITIALIZE_EVENT = 'fb_ds_init';
// Last known revision Id. Used to determine whether the index has to
// be reloaded or not
var revisionId;
// Creates the internal Object in the datastore that will act as an index
function createIndex() {
return {
// By tel number and all its possible variants
// (We are not supporting dups right now)
byTel: Object.create(null),
// Prefix tree for enabling searching by partial tel numbers
treeTel: []
};
}
// The index we need to keep the correspondance between FB Friends and
// datastore Ids
var index;
// Ensures a proper error object is returned
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);
}
// We resume other callers state
document.dispatchEvent(new CustomEvent(INITIALIZE_EVENT));
}
// Creates a default handler for errors
function defaultError(request) {
return defaultErrorCb.bind(null, request);
}
// Creates a default handler for success
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
});
/**
* Allows to obtain the FB friend information by UID
*
*
*/
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);
}
/**
* Allows to get FB information by tel number (short or long)
* The tel number must be complete
*
*/
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!');
// Refreshing the index just in case
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);
}
}
}
/**
* Allows to search for friends by different criteria.
* Numbers can be partial and partial matchings will be found
*
* by === tel : By Tel number
*
*/
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;
// TODO: Temporal way of searching for international numbers
// A follow-up is needed by using PhoneNumber.js exposed to Gaia
if (number.charAt(0) === '+') {
toSearchNumber = number.substring(1);
}
if (datastore.revisionId !== revisionId) {
window.console.info('Datastore revision id has changed!');
// Refreshing the index
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);
}
}
});
}
/**
* Refreshes the index data
*
*/
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));
}
/**
* Allows to obtain how many records contain he FB Database
*
*/
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;
};
/**
* Allows to return the total number of records in the DataStore (minus 1)
* That's because the index object also counts
*
*/
function doGetLength(outRequest) {
datastore.getLength().then(function success(length) {
outRequest.done(length - 1);
},
function error(err) {
outRequest.failed(safeError(err));
});
}
// Needed only for testing purposes
contacts.restart = function() {
readyState = 'notInitialized';
};
/**
* Initialization function
*
*/
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];
// Checking the length as the index should be there
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) {
// Index is created in order not to cause errors
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);
});
};
})();

View file

@ -0,0 +1,325 @@
'use strict';
// Includes convenience functions for FB Contact Data
// To use this library you need to include:
// 'shared/js/fb/fb_request.js' and 'shared/js/fb/fb_data_reader.js'
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';
// Shallow copy from source to target object
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;
}
}
});
}
// Auxiliary function for merging
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) {
// If there are no duplicates the merge is done
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];
}
});
// To support the case in which the contact does not have a local name
mergeNames(dcontact, fbdata);
}
// Auxiliary function for merging names
function mergeNames(devContact, fbContact) {
var namesChanged = false;
var nameFields = ['givenName', 'familyName'];
nameFields.forEach(function(anameField) {
// If the device contact does not have name fields setted
// we use the Facebook ones
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];
}
}
/**
* Returns truthy if the device contact is a FB Friend
*
*/
function isFbContact(devContact) {
return (devContact && devContact.category &&
devContact.category.indexOf(CATEGORY) !== -1);
}
/**
* Returns truthy if the device contact is linked to a FB Friend
*
*/
function isFbLinked(devContact) {
return (devContact && devContact.category &&
devContact.category.indexOf(LINKED) !== -1);
}
/**
* Gets all the data enriching the local contact with FB information
*
*/
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;
}
/**
* Returns the FB Friend UID associated to a device contact
*
*/
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;
}
/**
* Gets the UID of the FB Friend a device contact is linked to
*
*/
function getLinkedTo(devContact) {
var out;
if (devContact.category) {
var idx = devContact.category.indexOf(LINKED);
if (idx !== -1) {
out = devContact.category[idx + 1];
}
}
return out;
}
/**
* Merge a device contact with a FB Friend
*
*/
function mergeContact(devContact, fbContact) {
var out = devContact;
if (fbContact) {
out = Object.create(null);
out.updated = devContact.updated;
out.published = devContact.published;
// The id comes from devContact and the rest of properties like
// familyName, propertyName, etc... are defined in the proto object
populate(devContact, out, Object.getOwnPropertyNames(devContact));
populate(devContact, out,
Object.getOwnPropertyNames(Object.getPrototypeOf(devContact)));
mergeFbData(out, fbContact);
}
return out;
}
/**
* Returns a FB Contact (enriched with FB info) which has the tel number
*
*/
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);
};
}
// Checks whether there is a duplicate for the field value
// both in FB and in the local device Contact data
// Returns an array with the values which are duplicated or empty if
// no duplicates were found
// Parameters are: field on which to search, the corresponding fbItem
// the local device items, and extra FB Items which corresp to the short
// telephone numbers allowing to filter out dups with intl-ed numbers
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;
// Checking for telephone international number matching
if (localValue) {
var trimedLocal = localValue.trim();
if (trimedLocal === fbValue ||
(field === 'tel' && Array.isArray(extraFbItems) &&
extraFbItems.indexOf(trimedLocal) !== -1)) {
out.push(trimedLocal);
out.push(fbValue);
}
} // if(localValue)
} // for
} // if(devContactItems)
return out;
}
/**
* Returns the mozContact associated to a certain FB UID
*
*/
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;
}
};
})();
// This boilerplate code sets the AuxFb properties to the fb object
var props = Object.keys(self.AuxFb);
for (var j = 0, end = props.length; j < end; j++) {
/* jshint loopfunc: true */
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
});
}
}
}

View file

@ -0,0 +1,39 @@
'use strict';
var fb = self.fb || {};
self.fb = fb;
// Only will be executed in the case of not loading fb.utils previously
// i.e. dialer and call log FB integration
fb.utils = self.fb.utils || {};
self.fb.utils = fb.utils;
if (typeof fb.utils.Request !== 'function') {
/**
* Request auxiliary object to support asynchronous calls
*
*/
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);
}
};
};
}

View file

@ -0,0 +1,8 @@
;(function(exports){'use strict';var FontSizeUtils={_cachedContexts:{},_getCachedContext:function(fontSize,fontFamily,fontStyle){fontStyle=fontStyle||'italic';var cache=this._cachedContexts;var ctx=cache[fontSize]&&cache[fontSize][fontFamily]?cache[fontSize][fontFamily][fontStyle]:null;if(!ctx){var canvas=document.createElement('canvas');canvas.setAttribute('moz-opaque','true');canvas.setAttribute('width','1');canvas.setAttribute('height','1');ctx=canvas.getContext('2d',{willReadFrequently:true});ctx.font=fontStyle+' '+fontSize+'px '+fontFamily;if(!cache[fontSize]){cache[fontSize]={};}
if(!cache[fontSize][fontFamily]){cache[fontSize][fontFamily]={};}
cache[fontSize][fontFamily][fontStyle]=ctx;}
return ctx;},resetCache:function(){this._cachedContexts={};},getFontWidth:function(string,fontSize,fontFamily,fontStyle){var ctx=this._getCachedContext(fontSize,fontFamily,fontStyle);return ctx.measureText(string).width;},getMaxFontSizeInfo:function(string,allowedSizes,fontFamily,maxWidth){var fontSize;var resultWidth;var i=allowedSizes.length-1;do{fontSize=allowedSizes[i];resultWidth=this.getFontWidth(string,fontSize,fontFamily);i--;}while(resultWidth>maxWidth&&i>=0);return{fontSize:fontSize,overflow:resultWidth>maxWidth,textWidth:resultWidth};},_overflowCountCache:-1,getOverflowCount:function(string,fontSize,fontFamily,maxWidth){var substring;var resultWidth;var overflowCount=-1;if(string.length>this._overflowCountCache){substring=string.substr(0,string.length-this._overflowCountCache);resultWidth=this.getFontWidth(substring,fontSize,fontFamily);if(resultWidth>maxWidth){overflowCount=this._overflowCountCache;}}
do{overflowCount++;substring=string.substr(0,string.length-overflowCount);resultWidth=this.getFontWidth(substring,fontSize,fontFamily);}while(substring.length>0&&resultWidth>maxWidth);this._overflowCountCache=overflowCount;return overflowCount;},getContentWidth:function(style){var width=parseInt(style.width,10);if(style.boxSizing==='border-box'){width-=(parseInt(style.paddingRight,10)+
parseInt(style.paddingLeft,10));}
return width;},getStyleProperties:function(element){var style=window.getComputedStyle(element);var contentWidth=this.getContentWidth(style);if(isNaN(contentWidth)){contentWidth=0;}
return{fontFamily:style.fontFamily,contentWidth:contentWidth,paddingRight:parseInt(style.paddingRight,10),paddingLeft:parseInt(style.paddingLeft,10),offsetLeft:element.offsetLeft};},getWindowWidth:function(){return window.innerWidth;}};exports.FontSizeUtils=FontSizeUtils;}(this));

View file

@ -0,0 +1,245 @@
;(function(window,undefined){'use strict';function L10nError(message,id,loc){this.name='L10nError';this.message=message;this.id=id;this.loc=loc;}
L10nError.prototype=Object.create(Error.prototype);L10nError.prototype.constructor=L10nError;var io={_load:function(type,url,callback,sync){var xhr=new XMLHttpRequest();var needParse;if(xhr.overrideMimeType){xhr.overrideMimeType(type);}
xhr.open('GET',url,!sync);if(type==='application/json'){if(sync){needParse=true;}else{xhr.responseType='json';}}
xhr.addEventListener('load',function io_onload(e){if(e.target.status===200||e.target.status===0){var res=e.target.response||e.target.responseText;callback(null,needParse?JSON.parse(res):res);}else{callback(new L10nError('Not found: '+url));}});xhr.addEventListener('error',callback);xhr.addEventListener('timeout',callback);try{xhr.send(null);}catch(e){if(e.name==='NS_ERROR_FILE_NOT_FOUND'){callback(new L10nError('Not found: '+url));}else{throw e;}}},load:function(url,callback,sync){return io._load('text/plain',url,callback,sync);},loadJSON:function(url,callback,sync){return io._load('application/json',url,callback,sync);}};function EventEmitter(){}
EventEmitter.prototype.emit=function ee_emit(){if(!this._listeners){return;}
var args=Array.prototype.slice.call(arguments);var type=args.shift();if(!this._listeners[type]){return;}
var typeListeners=this._listeners[type].slice();for(var i=0;i<typeListeners.length;i++){typeListeners[i].apply(this,args);}};EventEmitter.prototype.addEventListener=function ee_add(type,listener){if(!this._listeners){this._listeners={};}
if(!(type in this._listeners)){this._listeners[type]=[];}
this._listeners[type].push(listener);};EventEmitter.prototype.removeEventListener=function ee_rm(type,listener){if(!this._listeners){return;}
var typeListeners=this._listeners[type];var pos=typeListeners.indexOf(listener);if(pos===-1){return;}
typeListeners.splice(pos,1);};function getPluralRule(lang){var locales2rules={'af':3,'ak':4,'am':4,'ar':1,'asa':3,'az':0,'be':11,'bem':3,'bez':3,'bg':3,'bh':4,'bm':0,'bn':3,'bo':0,'br':20,'brx':3,'bs':11,'ca':3,'cgg':3,'chr':3,'cs':12,'cy':17,'da':3,'de':3,'dv':3,'dz':0,'ee':3,'el':3,'en':3,'eo':3,'es':3,'et':3,'eu':3,'fa':0,'ff':5,'fi':3,'fil':4,'fo':3,'fr':5,'fur':3,'fy':3,'ga':8,'gd':24,'gl':3,'gsw':3,'gu':3,'guw':4,'gv':23,'ha':3,'haw':3,'he':2,'hi':4,'hr':11,'hu':0,'id':0,'ig':0,'ii':0,'is':3,'it':3,'iu':7,'ja':0,'jmc':3,'jv':0,'ka':0,'kab':5,'kaj':3,'kcg':3,'kde':0,'kea':0,'kk':3,'kl':3,'km':0,'kn':0,'ko':0,'ksb':3,'ksh':21,'ku':3,'kw':7,'lag':18,'lb':3,'lg':3,'ln':4,'lo':0,'lt':10,'lv':6,'mas':3,'mg':4,'mk':16,'ml':3,'mn':3,'mo':9,'mr':3,'ms':0,'mt':15,'my':0,'nah':3,'naq':7,'nb':3,'nd':3,'ne':3,'nl':3,'nn':3,'no':3,'nr':3,'nso':4,'ny':3,'nyn':3,'om':3,'or':3,'pa':3,'pap':3,'pl':13,'ps':3,'pt':3,'rm':3,'ro':9,'rof':3,'ru':11,'rwk':3,'sah':0,'saq':3,'se':7,'seh':3,'ses':0,'sg':0,'sh':11,'shi':19,'sk':12,'sl':14,'sma':7,'smi':7,'smj':7,'smn':7,'sms':7,'sn':3,'so':3,'sq':3,'sr':11,'ss':3,'ssy':3,'st':3,'sv':3,'sw':3,'syr':3,'ta':3,'te':3,'teo':3,'th':0,'ti':4,'tig':3,'tk':3,'tl':4,'tn':3,'to':0,'tr':0,'ts':3,'tzm':22,'uk':11,'ur':3,'ve':3,'vi':0,'vun':3,'wa':4,'wae':3,'wo':0,'xh':3,'xog':3,'yo':0,'zh':0,'zu':3};function isIn(n,list){return list.indexOf(n)!==-1;}
function isBetween(n,start,end){return typeof n===typeof start&&start<=n&&n<=end;}
var pluralRules={'0':function(){return'other';},'1':function(n){if((isBetween((n%100),3,10))){return'few';}
if(n===0){return'zero';}
if((isBetween((n%100),11,99))){return'many';}
if(n===2){return'two';}
if(n===1){return'one';}
return'other';},'2':function(n){if(n!==0&&(n%10)===0){return'many';}
if(n===2){return'two';}
if(n===1){return'one';}
return'other';},'3':function(n){if(n===1){return'one';}
return'other';},'4':function(n){if((isBetween(n,0,1))){return'one';}
return'other';},'5':function(n){if((isBetween(n,0,2))&&n!==2){return'one';}
return'other';},'6':function(n){if(n===0){return'zero';}
if((n%10)===1&&(n%100)!==11){return'one';}
return'other';},'7':function(n){if(n===2){return'two';}
if(n===1){return'one';}
return'other';},'8':function(n){if((isBetween(n,3,6))){return'few';}
if((isBetween(n,7,10))){return'many';}
if(n===2){return'two';}
if(n===1){return'one';}
return'other';},'9':function(n){if(n===0||n!==1&&(isBetween((n%100),1,19))){return'few';}
if(n===1){return'one';}
return'other';},'10':function(n){if((isBetween((n%10),2,9))&&!(isBetween((n%100),11,19))){return'few';}
if((n%10)===1&&!(isBetween((n%100),11,19))){return'one';}
return'other';},'11':function(n){if((isBetween((n%10),2,4))&&!(isBetween((n%100),12,14))){return'few';}
if((n%10)===0||(isBetween((n%10),5,9))||(isBetween((n%100),11,14))){return'many';}
if((n%10)===1&&(n%100)!==11){return'one';}
return'other';},'12':function(n){if((isBetween(n,2,4))){return'few';}
if(n===1){return'one';}
return'other';},'13':function(n){if((isBetween((n%10),2,4))&&!(isBetween((n%100),12,14))){return'few';}
if(n!==1&&(isBetween((n%10),0,1))||(isBetween((n%10),5,9))||(isBetween((n%100),12,14))){return'many';}
if(n===1){return'one';}
return'other';},'14':function(n){if((isBetween((n%100),3,4))){return'few';}
if((n%100)===2){return'two';}
if((n%100)===1){return'one';}
return'other';},'15':function(n){if(n===0||(isBetween((n%100),2,10))){return'few';}
if((isBetween((n%100),11,19))){return'many';}
if(n===1){return'one';}
return'other';},'16':function(n){if((n%10)===1&&n!==11){return'one';}
return'other';},'17':function(n){if(n===3){return'few';}
if(n===0){return'zero';}
if(n===6){return'many';}
if(n===2){return'two';}
if(n===1){return'one';}
return'other';},'18':function(n){if(n===0){return'zero';}
if((isBetween(n,0,2))&&n!==0&&n!==2){return'one';}
return'other';},'19':function(n){if((isBetween(n,2,10))){return'few';}
if((isBetween(n,0,1))){return'one';}
return'other';},'20':function(n){if((isBetween((n%10),3,4)||((n%10)===9))&&!(isBetween((n%100),10,19)||isBetween((n%100),70,79)||isBetween((n%100),90,99))){return'few';}
if((n%1000000)===0&&n!==0){return'many';}
if((n%10)===2&&!isIn((n%100),[12,72,92])){return'two';}
if((n%10)===1&&!isIn((n%100),[11,71,91])){return'one';}
return'other';},'21':function(n){if(n===0){return'zero';}
if(n===1){return'one';}
return'other';},'22':function(n){if((isBetween(n,0,1))||(isBetween(n,11,99))){return'one';}
return'other';},'23':function(n){if((isBetween((n%10),1,2))||(n%20)===0){return'one';}
return'other';},'24':function(n){if((isBetween(n,3,10)||isBetween(n,13,19))){return'few';}
if(isIn(n,[2,12])){return'two';}
if(isIn(n,[1,11])){return'one';}
return'other';}};var index=locales2rules[lang.replace(/-.*$/,'')];if(!(index in pluralRules)){return function(){return'other';};}
return pluralRules[index];}
var MAX_PLACEABLES=100;var PropertiesParser={patterns:null,entryIds:null,init:function(){this.patterns={comment:/^\s*#|^\s*$/,entity:/^([^=\s]+)\s*=\s*(.*)$/,multiline:/[^\\]\\$/,index:/\{\[\s*(\w+)(?:\(([^\)]*)\))?\s*\]\}/i,unicode:/\\u([0-9a-fA-F]{1,4})/g,entries:/[^\r\n]+/g,controlChars:/\\([\\\n\r\t\b\f\{\}\"\'])/g,placeables:/\{\{\s*([^\s]*?)\s*\}\}/,};},parse:function(ctx,source){if(!this.patterns){this.init();}
var ast=[];this.entryIds=Object.create(null);var entries=source.match(this.patterns.entries);if(!entries){return ast;}
for(var i=0;i<entries.length;i++){var line=entries[i];if(this.patterns.comment.test(line)){continue;}
while(this.patterns.multiline.test(line)&&i<entries.length){line=line.slice(0,-1)+entries[++i].trim();}
var entityMatch=line.match(this.patterns.entity);if(entityMatch){try{this.parseEntity(entityMatch[1],entityMatch[2],ast);}catch(e){if(ctx){ctx._emitter.emit('parseerror',e);}else{throw e;}}}}
return ast;},parseEntity:function(id,value,ast){var name,key;var pos=id.indexOf('[');if(pos!==-1){name=id.substr(0,pos);key=id.substring(pos+1,id.length-1);}else{name=id;key=null;}
var nameElements=name.split('.');if(nameElements.length>2){throw new L10nError('Error in ID: "'+name+'".'+' Nested attributes are not supported.');}
var attr;if(nameElements.length>1){name=nameElements[0];attr=nameElements[1];if(attr[0]==='$'){throw new L10nError('Attribute can\'t start with "$"',id);}}else{attr=null;}
this.setEntityValue(name,attr,key,this.unescapeString(value),ast);},setEntityValue:function(id,attr,key,rawValue,ast){var pos,v;var value=rawValue.indexOf('{{')>-1?this.parseString(rawValue):rawValue;if(attr){pos=this.entryIds[id];if(pos===undefined){v={$i:id};if(key){v[attr]={};v[attr][key]=value;}else{v[attr]=value;}
ast.push(v);this.entryIds[id]=ast.length-1;return;}
if(key){if(typeof(ast[pos][attr])==='string'){ast[pos][attr]={$x:this.parseIndex(ast[pos][attr]),$v:{}};}
ast[pos][attr].$v[key]=value;return;}
ast[pos][attr]=value;return;}
if(key){pos=this.entryIds[id];if(pos===undefined){v={};v[key]=value;ast.push({$i:id,$v:v});this.entryIds[id]=ast.length-1;return;}
if(typeof(ast[pos].$v)==='string'){ast[pos].$x=this.parseIndex(ast[pos].$v);ast[pos].$v={};}
ast[pos].$v[key]=value;return;}
ast.push({$i:id,$v:value});this.entryIds[id]=ast.length-1;},parseString:function(str){var chunks=str.split(this.patterns.placeables);var complexStr=[];var len=chunks.length;var placeablesCount=(len-1)/2;if(placeablesCount>=MAX_PLACEABLES){throw new L10nError('Too many placeables ('+placeablesCount+', max allowed is '+MAX_PLACEABLES+')');}
for(var i=0;i<chunks.length;i++){if(chunks[i].length===0){continue;}
if(i%2===1){complexStr.push({t:'idOrVar',v:chunks[i]});}else{complexStr.push(chunks[i]);}}
return complexStr;},unescapeString:function(str){if(str.lastIndexOf('\\')!==-1){str=str.replace(this.patterns.controlChars,'$1');}
return str.replace(this.patterns.unicode,function(match,token){return unescape('%u'+'0000'.slice(token.length)+token);});},parseIndex:function(str){var match=str.match(this.patterns.index);if(!match){throw new L10nError('Malformed index');}
if(match[2]){return[{t:'idOrVar',v:match[1]},match[2]];}else{return[{t:'idOrVar',v:match[1]}];}}};var KNOWN_MACROS=['plural'];var MAX_PLACEABLE_LENGTH=2500;var rePlaceables=/\{\{\s*(.+?)\s*\}\}/g;var nonLatin1=/[^\x01-\xFF]/;var FSI='\u2068';var PDI='\u2069';function createEntry(node,env){var keys=Object.keys(node);if(typeof node.$v==='string'&&keys.length===2){return node.$v;}
var attrs;for(var i=0,key;key=keys[i];i++){if(key[0]==='$'){continue;}
if(!attrs){attrs=Object.create(null);}
attrs[key]=createAttribute(node[key],env,node.$i+'.'+key);}
return{id:node.$i,value:node.$v!==undefined?node.$v:null,index:node.$x||null,attrs:attrs||null,env:env,dirty:false};}
function createAttribute(node,env,id){if(typeof node==='string'){return node;}
return{id:id,value:node.$v||(node!==undefined?node:null),index:node.$x||null,env:env,dirty:false};}
function format(args,entity){if(typeof entity==='string'){return[{},entity];}
if(entity.dirty){throw new L10nError('Cyclic reference detected: '+entity.id);}
entity.dirty=true;var rv;try{rv=resolveValue({},args,entity.env,entity.value,entity.index);}finally{entity.dirty=false;}
return rv;}
function resolveIdentifier(args,env,id){if(KNOWN_MACROS.indexOf(id)>-1){return[{},env['__'+id]];}
if(args&&args.hasOwnProperty(id)){if(typeof args[id]==='string'||(typeof args[id]==='number'&&!isNaN(args[id]))){return[{},args[id]];}else{throw new L10nError('Arg must be a string or a number: '+id);}}
if(id in env&&id!=='__proto__'){return format(args,env[id]);}
throw new L10nError('Unknown reference: '+id);}
function subPlaceable(locals,args,env,id){var res;try{res=resolveIdentifier(args,env,id);}catch(err){return[{error:err},'{{ '+id+' }}'];}
var value=res[1];if(typeof value==='number'){return res;}
if(typeof value==='string'){if(value.length>=MAX_PLACEABLE_LENGTH){throw new L10nError('Too many characters in placeable ('+
value.length+', max allowed is '+
MAX_PLACEABLE_LENGTH+')');}
if(locals.contextIsNonLatin1||value.match(nonLatin1)){res[1]=FSI+value+PDI;}
return res;}
return[{},'{{ '+id+' }}'];}
function interpolate(locals,args,env,arr){return arr.reduce(function(prev,cur){if(typeof cur==='string'){return[prev[0],prev[1]+cur];}else if(cur.t==='idOrVar'){var placeable=subPlaceable(locals,args,env,cur.v);return[prev[0],prev[1]+placeable[1]];}},[locals,'']);}
function resolveSelector(args,env,expr,index){var selectorName=index[0].v;var selector=resolveIdentifier(args,env,selectorName)[1];if(typeof selector!=='function'){return selector;}
var argValue=index[1]?resolveIdentifier(args,env,index[1])[1]:undefined;if(selector===env.__plural){if(argValue===0&&'zero'in expr){return'zero';}
if(argValue===1&&'one'in expr){return'one';}
if(argValue===2&&'two'in expr){return'two';}}
return selector(argValue);}
function resolveValue(locals,args,env,expr,index){if(!expr){return[locals,expr];}
if(typeof expr==='string'||typeof expr==='boolean'||typeof expr==='number'){return[locals,expr];}
if(Array.isArray(expr)){locals.contextIsNonLatin1=expr.some(function($_){return typeof($_)==='string'&&$_.match(nonLatin1);});return interpolate(locals,args,env,expr);}
if(index){var selector=resolveSelector(args,env,expr,index);if(expr.hasOwnProperty(selector)){return resolveValue(locals,args,env,expr[selector]);}}
if('other'in expr){return resolveValue(locals,args,env,expr.other);}
throw new L10nError('Unresolvable value');}
var Resolver={createEntry:createEntry,format:format,rePlaceables:rePlaceables};function walkContent(node,fn){if(typeof node==='string'){return fn(node);}
if(node.t==='idOrVar'){return node;}
var rv=Array.isArray(node)?[]:{};var keys=Object.keys(node);for(var i=0,key;(key=keys[i]);i++){if(key==='$i'||key==='$x'){rv[key]=node[key];}else{rv[key]=walkContent(node[key],fn);}}
return rv;}
var reAlphas=/[a-zA-Z]/g;var reVowels=/[aeiouAEIOU]/g;var ACCENTED_MAP='\u0226\u0181\u0187\u1E12\u1E16\u0191\u0193\u0126\u012A'+'\u0134\u0136\u013F\u1E3E\u0220\u01FE\u01A4\u024A\u0158'+'\u015E\u0166\u016C\u1E7C\u1E86\u1E8A\u1E8E\u1E90'+'[\\]^_`'+'\u0227\u0180\u0188\u1E13\u1E17\u0192\u0260\u0127\u012B'+'\u0135\u0137\u0140\u1E3F\u019E\u01FF\u01A5\u024B\u0159'+'\u015F\u0167\u016D\u1E7D\u1E87\u1E8B\u1E8F\u1E91';var FLIPPED_MAP='\u2200\u0510\u2183p\u018E\u025F\u05E4HI\u017F'+'\u04FC\u02E5WNO\u0500\xD2\u1D1AS\u22A5\u2229\u0245'+'\uFF2DX\u028EZ'+'[\\]\u1D65_,'+'\u0250q\u0254p\u01DD\u025F\u0183\u0265\u0131\u027E'+'\u029E\u0285\u026Fuodb\u0279s\u0287n\u028C\u028Dx\u028Ez';function makeLonger(val){return val.replace(reVowels,function(match){return match+match.toLowerCase();});}
function replaceChars(map,val){return val.replace(reAlphas,function(match){return map.charAt(match.charCodeAt(0)-65);});}
var reWords=/[^\W0-9_]+/g;function makeRTL(val){return val.replace(reWords,function(match){return'\u202e'+match+'\u202c';});}
var reExcluded=/(%[EO]?\w|\{\s*.+?\s*\}|&[#\w]+;|<\s*.+?\s*>)/;function mapContent(fn,val){if(!val){return val;}
var parts=val.split(reExcluded);var modified=parts.map(function(part){if(reExcluded.test(part)){return part;}
return fn(part);});return modified.join('');}
function Pseudo(id,name,charMap,modFn){this.id=id;this.translate=mapContent.bind(null,function(val){return replaceChars(charMap,modFn(val));});this.name=this.translate(name);}
var PSEUDO={'fr-x-psaccent':new Pseudo('fr-x-psaccent','Runtime Accented',ACCENTED_MAP,makeLonger),'ar-x-psbidi':new Pseudo('ar-x-psbidi','Runtime Bidi',FLIPPED_MAP,makeRTL)};function Locale(id,ctx){this.id=id;this.ctx=ctx;this.isReady=false;this.entries=Object.create(null);this.entries.__plural=getPluralRule(this.isPseudo()?this.ctx.defaultLocale:id);}
Locale.prototype.isPseudo=function(){return this.ctx.qps.indexOf(this.id)!==-1;};var bindingsIO={extra:function(id,ver,path,type,callback,errback){if(type==='properties'){type='text';}
navigator.mozApps.getLocalizationResource(id,ver,path,type).then(callback.bind(null,null),errback);},app:function(id,ver,path,type,callback,errback,sync){switch(type){case'properties':io.load(path,callback,sync);break;case'json':io.loadJSON(path,callback,sync);break;}},};Locale.prototype.build=function L_build(callback){var sync=!callback;var ctx=this.ctx;var self=this;var l10nLoads=ctx.resLinks.length;function onL10nLoaded(err){if(err){ctx._emitter.emit('fetcherror',err);}
if(--l10nLoads<=0){self.isReady=true;if(callback){callback();}}}
if(l10nLoads===0){onL10nLoaded();return;}
function onJSONLoaded(err,json){if(!err&&json){self.addAST(json);}
onL10nLoaded(err);}
function onPropLoaded(err,source){if(!err&&source){var ast=PropertiesParser.parse(ctx,source);self.addAST(ast);}
onL10nLoaded(err);}
var idToFetch=this.isPseudo()?ctx.defaultLocale:this.id;var appVersion=null;var source='app';if(typeof(navigator)!=='undefined'){source=navigator.mozL10n._config.localeSources[this.id]||'app';appVersion=navigator.mozL10n._config.appVersion;}
for(var i=0;i<ctx.resLinks.length;i++){var resLink=decodeURI(ctx.resLinks[i]);var path=resLink.replace('{locale}',idToFetch);var type=path.substr(path.lastIndexOf('.')+1);var cb;switch(type){case'json':cb=onJSONLoaded;break;case'properties':cb=onPropLoaded;break;}
bindingsIO[source](this.id,appVersion,path,type,cb,onL10nLoaded,sync);}};function createPseudoEntry(node,entries){return Resolver.createEntry(walkContent(node,PSEUDO[this.id].translate),entries);}
Locale.prototype.addAST=function(ast){var createEntry=this.isPseudo()?createPseudoEntry.bind(this):Resolver.createEntry;for(var i=0;i<ast.length;i++){this.entries[ast[i].$i]=createEntry(ast[i],this.entries);}};function Context(id){this.id=id;this.isReady=false;this.isLoading=false;this.defaultLocale='en-US';this.availableLocales=[];this.supportedLocales=[];this.qps=[];this.resLinks=[];this.locales={};this._emitter=new EventEmitter();this._ready=new Promise(this.once.bind(this));}
function reportMissing(id,err){this._emitter.emit('notfounderror',err);return id;}
function getWithFallback(id){var cur=0;var loc;var locale;while(loc=this.supportedLocales[cur]){locale=this.getLocale(loc);if(!locale.isReady){locale.build(null);}
var entry=locale.entries[id];if(entry===undefined){cur++;reportMissing.call(this,id,new L10nError('"'+id+'"'+' not found in '+loc+' in '+this.id,id,loc));continue;}
return entry;}
throw new L10nError('"'+id+'"'+' missing from all supported locales in '+this.id,id);}
function formatTuple(args,entity){try{return Resolver.format(args,entity);}catch(err){this._emitter.emit('resolveerror',err);var locals={error:err};return[locals,entity.id];}}
function formatValue(args,entity){if(typeof entity==='string'){return entity;}
return formatTuple.call(this,args,entity)[1];}
function formatEntity(args,entity){var entityTuple=formatTuple.call(this,args,entity);var value=entityTuple[1];var formatted={value:value,attrs:null,};if(entity.attrs){formatted.attrs=Object.create(null);}
for(var key in entity.attrs){var attrTuple=formatTuple.call(this,args,entity.attrs[key]);formatted.attrs[key]=attrTuple[1];}
return formatted;}
function formatAsync(fn,id,args){return this._ready.then(getWithFallback.bind(this,id)).then(fn.bind(this,args),reportMissing.bind(this,id));}
Context.prototype.formatValue=function(id,args){return formatAsync.call(this,formatValue,id,args);};Context.prototype.formatEntity=function(id,args){return formatAsync.call(this,formatEntity,id,args);};function legacyGet(fn,id,args){if(!this.isReady){throw new L10nError('Context not ready');}
var entry;try{entry=getWithFallback.call(this,id);}catch(err){if(err.loc){throw err;}
reportMissing.call(this,id,err);return'';}
return fn.call(this,args,entry);}
Context.prototype.get=function(id,args){return legacyGet.call(this,formatValue,id,args);};Context.prototype.getEntity=function(id,args){return legacyGet.call(this,formatEntity,id,args);};Context.prototype.getLocale=function getLocale(code){var locales=this.locales;if(locales[code]){return locales[code];}
return locales[code]=new Locale(code,this);};function negotiate(available,requested,defaultLocale){var supportedLocale;for(var i=0;i<requested.length;i++){var locale=requested[i];if(available.indexOf(locale)!==-1){supportedLocale=locale;break;}}
if(!supportedLocale||supportedLocale===defaultLocale){return[defaultLocale];}
return[supportedLocale,defaultLocale];}
function freeze(supported){var locale=this.getLocale(supported[0]);if(locale.isReady){setReady.call(this,supported);}else{locale.build(setReady.bind(this,supported));}}
function setReady(supported){this.supportedLocales=supported;this.isReady=true;this._emitter.emit('ready');}
Context.prototype.registerLocales=function(defLocale,available){if(defLocale){this.defaultLocale=defLocale;}
this.availableLocales=[this.defaultLocale];this.qps=Object.keys(PSEUDO);if(available){for(var i=0,loc;loc=available[i];i++){if(this.availableLocales.indexOf(loc)===-1){this.availableLocales.push(loc);var pos=this.qps.indexOf(loc);if(pos!==-1){this.qps.splice(pos,1);}}}}};Context.prototype.requestLocales=function requestLocales(){if(this.isLoading&&!this.isReady){throw new L10nError('Context not ready');}
this.isLoading=true;var requested=Array.prototype.slice.call(arguments);if(requested.length===0){throw new L10nError('No locales requested');}
var supported=negotiate(this.availableLocales.concat(this.qps),requested,this.defaultLocale);if(this.supportedLocales[0]!==supported[0]){freeze.call(this,supported);}};Context.prototype.addEventListener=function(type,listener){this._emitter.addEventListener(type,listener);};Context.prototype.removeEventListener=function(type,listener){this._emitter.removeEventListener(type,listener);};Context.prototype.ready=function(callback){if(this.isReady){setTimeout(callback);}
this.addEventListener('ready',callback);};Context.prototype.once=function(callback){if(this.isReady){setTimeout(callback);return;}
var callAndRemove=(function(){this.removeEventListener('ready',callAndRemove);callback();}).bind(this);this.addEventListener('ready',callAndRemove);};var allowed={elements:['a','em','strong','small','s','cite','q','dfn','abbr','data','time','code','var','samp','kbd','sub','sup','i','b','u','mark','ruby','rt','rp','bdi','bdo','span','br','wbr'],attributes:{global:['title','aria-label','aria-valuetext','aria-moz-hint'],a:['download'],area:['download','alt'],input:['alt','placeholder'],menuitem:['label'],menu:['label'],optgroup:['label'],option:['label'],track:['label'],img:['alt'],textarea:['placeholder'],th:['abbr']}};var rtlList=['ar','he','fa','ps','ar-x-psbidi','ur'];var nodeObserver=null;var pendingElements=null;var moConfig={attributes:true,characterData:false,childList:true,subtree:true,attributeFilter:['data-l10n-id','data-l10n-args']};navigator.mozL10n={ctx:null,get:function get(id,ctxdata){return navigator.mozL10n.ctx.get(id,ctxdata);},formatValue:function(id,ctxdata){return navigator.mozL10n.ctx.formatValue(id,ctxdata);},formatEntity:function(id,ctxdata){return navigator.mozL10n.ctx.formatEntity(id,ctxdata);},translateFragment:function(fragment){return translateFragment.call(navigator.mozL10n,fragment);},setAttributes:setL10nAttributes,getAttributes:getL10nAttributes,ready:function ready(callback){return navigator.mozL10n.ctx.ready(callback);},once:function once(callback){return navigator.mozL10n.ctx.once(callback);},get readyState(){return navigator.mozL10n.ctx.isReady?'complete':'loading';},language:{set code(lang){navigator.mozL10n.ctx.requestLocales(lang);},get code(){return navigator.mozL10n.ctx.supportedLocales[0];},get direction(){return getDirection(navigator.mozL10n.ctx.supportedLocales[0]);}},qps:PSEUDO,_config:{appVersion:null,localeSources:Object.create(null),isPretranslated:false,},_getInternalAPI:function(){return{Error:L10nError,Context:Context,Locale:Locale,Resolver:Resolver,getPluralRule:getPluralRule,rePlaceables:rePlaceables,translateDocument:translateDocument,onMetaInjected:onMetaInjected,PropertiesParser:PropertiesParser,walkContent:walkContent,buildLocaleList:buildLocaleList};}};function getDirection(lang){return(rtlList.indexOf(lang)>=0)?'rtl':'ltr';}
var readyStates={loading:0,interactive:1,complete:2};function whenInteractive(callback){if(readyStates[document.readyState]>=readyStates.interactive){callback();return;}
document.addEventListener('readystatechange',function l10n_onrsc(){if(readyStates[document.readyState]>=readyStates.interactive){document.removeEventListener('readystatechange',l10n_onrsc);callback();}});}
function initObserver(){nodeObserver=new MutationObserver(onMutations.bind(navigator.mozL10n));nodeObserver.observe(document,moConfig);}
function init(pretranslate){if(!pretranslate){initObserver();}
initResources.call(navigator.mozL10n);}
function initResources(){var meta={};var nodes=document.head.querySelectorAll('link[rel="localization"],'+'meta[name="availableLanguages"],'+'meta[name="defaultLanguage"],'+'meta[name="appVersion"],'+'script[type="application/l10n"]');for(var i=0,node;node=nodes[i];i++){var type=node.getAttribute('rel')||node.nodeName.toLowerCase();switch(type){case'localization':this.ctx.resLinks.push(node.getAttribute('href'));break;case'meta':onMetaInjected.call(this,node,meta);break;case'script':onScriptInjected.call(this,node);break;}}
var additionalLanguagesPromise;if(navigator.mozApps&&navigator.mozApps.getAdditionalLanguages){additionalLanguagesPromise=navigator.mozApps.getAdditionalLanguages().catch(function(e){console.error('Error while loading getAdditionalLanguages',e);});document.addEventListener('additionallanguageschange',function(evt){registerLocales.call(this,meta,evt.detail);this.ctx.requestLocales.apply(this.ctx,navigator.languages||[navigator.language]);}.bind(this));}else{additionalLanguagesPromise=Promise.resolve();}
additionalLanguagesPromise.then(function(extraLangs){registerLocales.call(this,meta,extraLangs);initLocale.call(this);}.bind(this));}
function registerLocales(meta,extraLangs){var locales=buildLocaleList.call(this,meta,extraLangs);navigator.mozL10n._config.localeSources=locales[1];this.ctx.registerLocales(locales[0],Object.keys(locales[1]));}
function getMatchingLangpack(appVersion,langpacks){for(var i=0,langpack;(langpack=langpacks[i]);i++){if(langpack.target===appVersion){return langpack;}}
return null;}
function buildLocaleList(meta,extraLangs){var loc,lp;var localeSources=Object.create(null);var defaultLocale=meta.defaultLanguage||this.ctx.defaultLocale;if(meta.availableLanguages){for(loc in meta.availableLanguages){localeSources[loc]='app';}}
if(extraLangs){for(loc in extraLangs){lp=getMatchingLangpack(this._config.appVersion,extraLangs[loc]);if(!lp){continue;}
if(!(loc in localeSources)||!meta.availableLanguages[loc]||parseInt(lp.revision)>meta.availableLanguages[loc]){localeSources[loc]='extra';}}}
if(!(defaultLocale in localeSources)){localeSources[defaultLocale]='app';}
return[defaultLocale,localeSources];}
function splitAvailableLanguagesString(str){var langs={};str.split(',').forEach(function(lang){lang=lang.trim().split(':');langs[lang[0]]=parseInt(lang[1]);});return langs;}
function onMetaInjected(node,meta){switch(node.getAttribute('name')){case'availableLanguages':meta.availableLanguages=splitAvailableLanguagesString(node.getAttribute('content'));break;case'defaultLanguage':meta.defaultLanguage=node.getAttribute('content');break;case'appVersion':navigator.mozL10n._config.appVersion=node.getAttribute('content');break;}}
function onScriptInjected(node){var lang=node.getAttribute('lang');var locale=this.ctx.getLocale(lang);locale.addAST(JSON.parse(node.textContent));}
function initLocale(){this.ctx.requestLocales.apply(this.ctx,navigator.languages||[navigator.language]);window.addEventListener('languagechange',function l10n_langchange(){this.ctx.requestLocales.apply(this.ctx,navigator.languages||[navigator.language]);}.bind(this));}
function localizeMutations(mutations){var mutation;var targets=new Set();for(var i=0;i<mutations.length;i++){mutation=mutations[i];if(mutation.type==='childList'){var addedNode;for(var j=0;j<mutation.addedNodes.length;j++){addedNode=mutation.addedNodes[j];if(addedNode.nodeType!==Node.ELEMENT_NODE){continue;}
targets.add(addedNode);}}
if(mutation.type==='attributes'){targets.add(mutation.target);}}
targets.forEach(function(target){if(target.childElementCount){translateFragment.call(this,target);}else if(target.hasAttribute('data-l10n-id')){translateElement.call(this,target);}},this);}
function onMutations(mutations,self){self.disconnect();localizeMutations.call(this,mutations);self.observe(document,moConfig);}
function onReady(){if(!navigator.mozL10n._config.isPretranslated){translateDocument.call(this);}
navigator.mozL10n._config.isPretranslated=false;if(pendingElements){for(var i=0,element;element=pendingElements[i];i++){translateElement.call(this,element);}
pendingElements=null;}
if(!nodeObserver){initObserver();}
fireLocalizedEvent.call(this);}
function fireLocalizedEvent(){var event=new CustomEvent('localized',{'bubbles':false,'cancelable':false,'detail':{'language':this.ctx.supportedLocales[0]}});window.dispatchEvent(event);}
var reOverlay=/<|&#?\w+;/;var reHtml=/[&<>]/g;var htmlEntities={'&':'&amp;','<':'&lt;','>':'&gt;',};function translateDocument(){document.documentElement.lang=this.language.code;document.documentElement.dir=this.language.direction;translateFragment.call(this,document.documentElement);}
function translateFragment(element){if(typeof element.hasAttribute==='function'&&element.hasAttribute('data-l10n-id')){translateElement.call(this,element);}
var nodes=getTranslatableChildren(element);for(var i=0;i<nodes.length;i++){translateElement.call(this,nodes[i]);}}
function setL10nAttributes(element,id,args){element.setAttribute('data-l10n-id',id);if(args){element.setAttribute('data-l10n-args',JSON.stringify(args));}}
function getL10nAttributes(element){return{id:element.getAttribute('data-l10n-id'),args:JSON.parse(element.getAttribute('data-l10n-args'))};}
function getTranslatableChildren(element){return element?element.querySelectorAll('*[data-l10n-id]'):[];}
function camelCaseToDashed(string){if(string==='ariaValueText'){return'aria-valuetext';}
return string.replace(/[A-Z]/g,function(match){return'-'+match.toLowerCase();}).replace(/^-/,'');}
function escapeL10nArgs(match){return htmlEntities[match];}
function translateElement(element){if(!this.ctx.isReady){if(!pendingElements){pendingElements=[];}
pendingElements.push(element);return;}
var l10nId=element.getAttribute('data-l10n-id');if(!l10nId){return false;}
var l10nArgs=element.getAttribute('data-l10n-args');var entity=this.ctx.getEntity(l10nId,l10nArgs?JSON.parse(l10nArgs.replace(reHtml,escapeL10nArgs)):undefined);var value=entity.value;if(typeof value==='string'){if(!reOverlay.test(value)){element.textContent=value;}else{var translation=element.ownerDocument.createElement('template');translation.innerHTML=value;overlayElement(element,translation.content);}}
for(var key in entity.attrs){var attrName=camelCaseToDashed(key);if(isAttrAllowed({name:attrName},element)){element.setAttribute(attrName,entity.attrs[key]);}}}
function overlayElement(sourceElement,translationElement){var result=translationElement.ownerDocument.createDocumentFragment();var k,attr;var childElement;while((childElement=translationElement.childNodes[0])){translationElement.removeChild(childElement);if(childElement.nodeType===Node.TEXT_NODE){result.appendChild(childElement);continue;}
var index=getIndexOfType(childElement);var sourceChild=getNthElementOfType(sourceElement,childElement,index);if(sourceChild){overlayElement(sourceChild,childElement);result.appendChild(sourceChild);continue;}
if(isElementAllowed(childElement)){var sanitizedChild=childElement.ownerDocument.createElement(childElement.nodeName);overlayElement(sanitizedChild,childElement);result.appendChild(sanitizedChild);continue;}
result.appendChild(document.createTextNode(childElement.textContent));}
sourceElement.textContent='';sourceElement.appendChild(result);if(translationElement.attributes){for(k=0,attr;(attr=translationElement.attributes[k]);k++){if(isAttrAllowed(attr,sourceElement)){sourceElement.setAttribute(attr.name,attr.value);}}}}
function isElementAllowed(element){return allowed.elements.indexOf(element.tagName.toLowerCase())!==-1;}
function isAttrAllowed(attr,element){var attrName=attr.name.toLowerCase();var tagName=element.tagName.toLowerCase();if(allowed.attributes.global.indexOf(attrName)!==-1){return true;}
if(!allowed.attributes[tagName]){return false;}
if(allowed.attributes[tagName].indexOf(attrName)!==-1){return true;}
if(tagName==='input'&&attrName==='value'){var type=element.type.toLowerCase();if(type==='submit'||type==='button'||type==='reset'){return true;}}
return false;}
function getNthElementOfType(context,element,index){var nthOfType=0;for(var i=0,child;child=context.children[i];i++){if(child.nodeType===Node.ELEMENT_NODE&&child.tagName===element.tagName){if(nthOfType===index){return child;}
nthOfType++;}}
return null;}
function getIndexOfType(element){var index=0;var child;while((child=element.previousElementSibling)){if(child.tagName===element.tagName){index++;}}
return index;}
var DEBUG=false;navigator.mozL10n.ctx=new Context(window.document?document.URL:null);navigator.mozL10n.ctx.ready(onReady.bind(navigator.mozL10n));navigator.mozL10n.ctx.addEventListener('notfounderror',function reportMissingEntity(e){if(DEBUG||e.loc==='en-US'){console.warn(e.toString());}});if(DEBUG){navigator.mozL10n.ctx.addEventListener('fetcherror',console.error.bind(console));navigator.mozL10n.ctx.addEventListener('parseerror',console.error.bind(console));navigator.mozL10n.ctx.addEventListener('resolveerror',console.error.bind(console));}
if(window.document){navigator.mozL10n._config.isPretranslated=document.documentElement.lang===navigator.language;var forcePretranslate=!navigator.mozL10n._config.isPretranslated;whenInteractive(init.bind(navigator.mozL10n,forcePretranslate));}
document.l10n={setAttributes:navigator.mozL10n.setAttributes,getAttributes:navigator.mozL10n.getAttributes,formatValue:function(id,args){return navigator.mozL10n.formatValue(id,args);},translateFragment:function(frag){return Promise.resolve(navigator.mozL10n.translateFragment(frag));},ready:new Promise(function(resolve){navigator.mozL10n.once(resolve);}),formatValues:function(){var keys=arguments;var resp=keys.map(function(key){if(Array.isArray(key)){return navigator.mozL10n.formatValue(key[0],key[1]);}
return navigator.mozL10n.formatValue(key);});return Promise.all(resp);},requestLanguages:function(langs){navigator.mozL10n.ctx.requestLocales.apply(navigator.mozL10n.ctx,langs);},pseudo:{'fr-x-psaccent':{getName:function(){return Promise.resolve(navigator.mozL10n.qps['fr-x-psaccent'].name);},processString:function(s){return Promise.resolve(navigator.mozL10n.qps['fr-x-psaccent'].translate(s));}},'ar-x-psbidi':{getName:function(){return Promise.resolve(navigator.mozL10n.qps['ar-x-psbidi'].name);},processString:function(s){return Promise.resolve(navigator.mozL10n.qps['ar-x-psbidi'].translate(s));}}},};navigator.mozL10n.ready(function(){document.documentElement.setAttribute('langs',navigator.mozL10n.ctx.supportedLocales.join(' '));});navigator.mozL10n.once(function(){window.addEventListener('localized',function(){document.dispatchEvent(new CustomEvent('DOMRetranslated',{bubbles:false,cancelable:false}));});});})(this);

View file

@ -0,0 +1,11 @@
;'use strict';var LazyLoader=(function(){function LazyLoader(){this._loaded={};this._isLoading={};}
LazyLoader.prototype={_js:function(file,callback){var script=document.createElement('script');script.src=file;script.async=false;script.addEventListener('load',callback);document.head.appendChild(script);this._isLoading[file]=script;},_css:function(file,callback){var style=document.createElement('link');style.type='text/css';style.rel='stylesheet';style.href=file;document.head.appendChild(style);callback();},_html:function(domNode,callback){if(domNode.getAttribute('is')){this.load(['/shared/js/html_imports.js'],function(){HtmlImports.populate(callback);}.bind(this));return;}
for(var i=0;i<domNode.childNodes.length;i++){if(domNode.childNodes[i].nodeType==document.COMMENT_NODE){domNode.innerHTML=domNode.childNodes[i].nodeValue;break;}}
window.dispatchEvent(new CustomEvent('lazyload',{detail:domNode}));callback();},getJSON:function(file,mozSystem){return new Promise(function(resolve,reject){var xhr;if(mozSystem){xhr=new XMLHttpRequest({mozSystem:true});}else{xhr=new XMLHttpRequest();}
xhr.open('GET',file,true);xhr.responseType='json';xhr.onerror=function(error){reject(error);};xhr.onload=function(){if(xhr.response!==null){resolve(xhr.response);}else{reject(new Error('No valid JSON object was found ('+
xhr.status+' '+xhr.statusText+')'));}};xhr.send();});},load:function(files,callback){var deferred={};deferred.promise=new Promise(resolve=>{deferred.resolve=resolve;});if(!Array.isArray(files)){files=[files];}
var loadsRemaining=files.length,self=this;function perFileCallback(file){if(self._isLoading[file]){delete self._isLoading[file];}
self._loaded[file]=true;if(--loadsRemaining===0){deferred.resolve();if(callback){callback();}}}
for(var i=0;i<files.length;i++){var file=files[i];if(this._loaded[file.id||file]){perFileCallback(file);}else if(this._isLoading[file]){this._isLoading[file].addEventListener('load',perFileCallback.bind(null,file));}else{var method,idx;if(typeof file==='string'){method=file.match(/\.([^.]+)$/)[1];idx=file;}else{method='html';idx=file.id;}
this['_'+method](file,perFileCallback.bind(null,idx));}}
return deferred.promise;}};return new LazyLoader();}());

View file

@ -0,0 +1,16 @@
;'use strict';(function(exports){var _lockedStateMsgMap={'unknown':'emergencyCallsOnly-unknownSIMState','pinRequired':'emergencyCallsOnly-pinRequired','pukRequired':'emergencyCallsOnly-pukRequired','networkLocked':'emergencyCallsOnly-networkLocked','serviceProviderLocked':'emergencyCallsOnly-serviceProviderLocked','corporateLocked':'emergencyCallsOnly-corporateLocked','network1Locked':'emergencyCallsOnly-network1Locked','network2Locked':'emergencyCallsOnly-network2Locked','hrpdNetworkLocked':'emergencyCallsOnly-hrpdNetworkLocked','ruimCorporateLocked':'emergencyCallsOnly-ruimCorporateLocked','ruimServiceProviderLocked':'emergencyCallsOnly-ruimServiceProviderLocked'};var _NETWORKS_2G=['gsm','gprs','edge'];var LockScreenConnInfoManager=function(root){if(root){this._initialize(root);}};var LockScreenConnInfoManagerPrototype={_connStates:null,_settings:null,_cellbroadcastLabel:null,_telephonyDefaultServiceId:0,_airplaneMode:false};LockScreenConnInfoManagerPrototype._initialize=function lscs_initialize(root){this._connStates=root;this._settings=navigator.mozSettings;this._connStates.hidden=false;SIMSlotManager.getSlots().forEach(function(simslot,index){this._connStates.appendChild(this._createConnStateElement());simslot.conn.addEventListener('voicechange',(function(index){this.updateConnState(simslot);}).bind(this));},this);this.simSlotCardStateChangeListener=(function(evt){this.updateConnState(evt.detail);}).bind(this);window.addEventListener('simslot-cardstatechange',this.simSlotCardStateChangeListener);this.simSlotIccInfoChangeListener=(function(evt){this.updateConnState(evt.detail);}).bind(this);window.addEventListener('simslot-iccinfochange',this.simSlotIccInfoChangeListener);this.cellBroadcastMsgChangedListener=(function(evt){this._cellbroadcastLabel=evt.detail;this.updateConnStates();}).bind(this);window.addEventListener('cellbroadcastmsgchanged',this.cellBroadcastMsgChangedListener);this._settings.addObserver('ril.radio.disabled',(function(evt){this._airplaneMode=evt.settingValue;this.updateConnStates();}).bind(this));this._settings.addObserver('ril.telephony.defaultServiceId',(function(evt){this._telephonyDefaultServiceId=evt.settingValue;this.updateConnStates();}).bind(this));var req=SettingsListener.getSettingsLock().get('ril.radio.disabled');req.onsuccess=(function(){this._airplaneMode=!!req.result['ril.radio.disabled'];var req2=SettingsListener.getSettingsLock().get('ril.telephony.defaultServiceId');req2.onsuccess=(function(){this._telephonyDefaultServiceId=req2.result['ril.telephony.defaultServiceId']||0;this.updateConnStates();}).bind(this);}).bind(this);this.updateConnStates();};LockScreenConnInfoManagerPrototype.teardown=function lscs_teardown(){window.removeEventListener('simslot-cardstatechange',this.simSlotCardStateChangeListener);window.removeEventListener('simslot-iccinfochange',this.simSlotIccInfoChangeListener);window.removeEventListener('cellbroadcastmsgchanged',this.cellBroadcastMsgChangedListener);};LockScreenConnInfoManagerPrototype._createConnStateElement=function lscs_createConnStateElement(){var div=document.createElement('div');var span=document.createElement('span');var line1=document.createElement('span');var line2=document.createElement('span');line1.className=line2.className='connstate-line';div.appendChild(span);div.appendChild(line1);div.appendChild(line2);return div;};LockScreenConnInfoManagerPrototype.updateConnStates=function lscs_updateConnStates(){SIMSlotManager.getSlots().forEach((function(simslot){this.updateConnState(simslot);}).bind(this));};function lineText(node,l10nId,l10nArgs,text){if(!l10nId&&!text){node.setAttribute('data-content',true);}else{node.removeAttribute('data-content');}
if(l10nId){navigator.mozL10n.setAttributes(node,l10nId,l10nArgs);}else{node.removeAttribute('data-l10n-id');if(text){node.textContent=text;}else{node.textContent='';}}}
LockScreenConnInfoManagerPrototype.updateConnState=function lscs_updateConnState(simslot){var conn=simslot.conn;var index=simslot.index;var connstate=this._connStates.children[index];var simIDLine=connstate.children[0];var connstateLines=Array.prototype.slice.call(connstate.querySelectorAll('.connstate-line'));var iccObj=simslot.simCard;var voice=conn.voice;connstate.hidden=false;if(SIMSlotManager.isMultiSIM()){simIDLine.hidden=false;lineText(simIDLine,'lockscreen-sim-id',{n:(index+1)});}else{simIDLine.hidden=true;}
connstateLines.forEach(function(line){lineText(line);});var nextLine=function(){for(var i=0;i<connstateLines.length;i++){var line=connstateLines[i];if(line.hasAttribute('data-content')){return line;}}
return connstateLines[connstateLines.length-1];};if(this._airplaneMode){if(index===0){lineText(nextLine(),'airplaneMode');}else{connstate.hidden=true;}
simIDLine.hidden=true;return;}
if(SIMSlotManager.noSIMCardOnDevice()){if(index===0){if(voice.emergencyCallsOnly){lineText(nextLine(),'emergencyCallsOnly');lineText(nextLine(),'emergencyCallsOnly-noSIM');}else{lineText(nextLine(),'emergencyCallsOnly-noSIM');}}
simIDLine.hidden=true;return;}else if(SIMSlotManager.noSIMCardConnectedToNetwork()){if(index===0){lineText(nextLine(),'emergencyCallsOnly');}
simIDLine.hidden=true;return;}
if(SIMSlotManager.isMultiSIM()&&navigator.mozIccManager.iccIds.length==1&&simslot.isAbsent()){connstate.hidden=true;return;}
if(voice&&'state'in voice&&voice.state=='notSearching'){lineText(nextLine(),'noNetwork');return;}
if(!voice.connected&&!voice.emergencyCallsOnly){lineText(nextLine(),'searching');return;}
if(voice.emergencyCallsOnly){if(this._telephonyDefaultServiceId==index){lineText(nextLine(),'emergencyCallsOnly');lineText(nextLine(),_lockedStateMsgMap[iccObj.cardState]);}else{connstate.hidden=true;}
return;}
var operatorInfos=MobileOperator.userFacingInfo(conn);var operator=operatorInfos.operator;var is2G=_NETWORKS_2G.some(function checkConnectionType(elem){return(conn.voice.type==elem);});var l10nArgs;if(voice.roaming){l10nArgs={operator:operator};lineText(nextLine(),'roaming',l10nArgs);}else{lineText(nextLine(),null,null,operator);}
if(this._cellbroadcastLabel&&is2G){lineText(nextLine(),null,null,this._cellbroadcastLabel);}else if(operatorInfos.carrier){l10nArgs={carrier:operatorInfos.carrier,region:operatorInfos.region};lineText(nextLine(),'operator-info',l10nArgs);}};LockScreenConnInfoManager.prototype=LockScreenConnInfoManagerPrototype;exports.LockScreenConnInfoManager=LockScreenConnInfoManager;})(window);

View file

@ -0,0 +1,37 @@
;'use strict';(function(exports){var LockScreenSlide=function(opts){this.initialize(opts);};var LockScreenSlidePrototype={stopped:false,canvas:null,layout:'',useNewStyle:false,track:{length:{tiny:'280',large:'410'},color:'rgba(255, 255, 255, 0.4)',backgroundColor:'rgba(0, 0, 0, 0)',from:0,to:0,radius:0,width:0},trackNew:{length:{tiny:'276',large:'406'},strokeColorTop:'rgba(0, 0, 0, 0.2)',strokeColorBottom:'rgba(0, 0, 0, 0)',fillColorTop:'rgba(0, 0, 0, 0.2)',fillColorBottom:'rgba(0, 0, 0, 0)',backColor:'rgba(51, 51, 51, 0.15)',from:0,to:0,radius:0,width:0},arrows:{left:null,right:null,ldraw:{x:null,y:null},rdraw:{x:null,y:null}},iconBG:{radius:20,left:{color:'rgba(255, 255, 255, 0.25)'},right:{color:'rgba(255, 255, 255, 0.25)'}},slides:{left:null,right:null},areas:{left:null,right:null},area:null,overlay:null,width:0,height:80,center:{x:null,y:null},handle:{autoExpand:{accState:'normal',accFactor:1.02,sentinelOffset:40,sentinelWidth:0},bounceBackTime:200,radius:28,lineWidth:1.6,maxWidth:0,touchedColor:'0, 170, 204',touchedColorStop:'178, 229, 239',color:'255, 255, 255',backgroundColor:'255, 255, 255',backgroundAlpha:0},handleNew:{autoExpand:{accState:'normal',accFactor:1.02,sentinelOffset:40,sentinelWidth:0},bounceBackTime:200,radius:30,innerRadius:15,outerColor:'rgba(255, 255, 255, 0.9)',innerColor:'rgba(0, 0, 0, 0.05)',lineWidth:1.6,maxWidth:0,towardLeft:false,touchedColor:'0, 170, 204',touchedColorStop:'178, 229, 239'},colors:{left:{touchedColor:'255, 255, 255',touchedColorStop:'255, 255, 255'},right:{touchedColor:'255, 255, 255',touchedColorStop:'255, 255, 255'}},states:{initialized:false,sliding:false,slideReachEnd:false,slidingColorful:false,slidingColorGradientEnd:false,touch:{id:'',touched:false,initX:-1,pageX:-1,pageY:-1,tx:-1,prevX:-1,deltaX:0}},IDs:{overlay:'lockscreen',area:'lockscreen-area',canvas:'lockscreen-canvas',areas:{left:'lockscreen-area-camera',right:'lockscreen-area-unlock'}},resources:{larrow:'/lockscreen/style/images/larrow.png',rarrow:'/lockscreen/style/images/rarrow.png'},resourcesNew:{larrow:'/lockscreen/style/images/lockscreen_toggle_arrow_left.png',rarrow:'/lockscreen/style/images/lockscreen_toggle_arrow_right.png'}};LockScreenSlidePrototype.initialize=function(opts){if(opts){this._overwriteSettings(opts);}
if(opts.useNewStyle){this.track=this.trackNew;this.handle=this.handleNew;this.resources=this.resourcesNew;}
this._initializeCanvas();this.publish('lockscreenslide-unlocker-initializer');this.states.initialized=true;};LockScreenSlidePrototype.reset=function lss_reset(){this._clearCanvas();this._drawTrack();this._resetHandle();this._resetArrows();this._drawIconBG();};LockScreenSlidePrototype._overwriteSettings=function(options){var iterate=function _iterate(opts,settings){for(var property in opts){if(opts.hasOwnProperty(property)){if('object'===typeof opts[property]){iterate(opts[property],settings[property]);}
else{settings[property]=opts[property];}}}};iterate(options,this);};LockScreenSlidePrototype.handleEvent=function(evt){switch(evt.type){case'screenchange':if(evt.detail.screenOffBy=='proximity'){break;}
this._clearCanvas();this._drawTrack();this._resetHandle();this._resetArrows();this._drawIconBG();break;case'touchstart':evt.preventDefault();if(evt.target!==this.area||evt.touches.length>1){return;}
this.states.touch.id=evt.touches[0].identifier;this._onSlideBegin(this._dpx(evt.touches[0].pageX));window.addEventListener('touchend',this);window.addEventListener('touchmove',this);break;case'touchmove':if(evt.touches.length>1){this._endGesture();return;}
this._onTouchMove(this._dpx(evt.touches[0].pageX),this._dpx(evt.touches[0].pageY));if(this.states.sliding){this._onSliding(this._dpx(evt.touches[0].pageX));}
break;case'touchend':if(evt.changedTouches[0].identifier!==this.states.touch.id){return;}
this._endGesture();break;case'click':if(evt.mozInputSource===0){evt.preventDefault();if(this.areas.left===evt.target){this.publish('lockscreenslide-activate-left');}else if(this.areas.right===evt.target){this.publish('lockscreenslide-activate-right');}}
break;}};LockScreenSlidePrototype._initializeCanvas=function lss_initializeCanvas(){this.overlay=document.getElementById(this.IDs.overlay);this.area=document.getElementById(this.IDs.area);this.canvas=document.getElementById(this.IDs.canvas);this.areas.left=document.getElementById(this.IDs.areas.left);this.areas.right=document.getElementById(this.IDs.areas.right);this.area.addEventListener('touchstart',this);this.areas.left.addEventListener('click',this);this.areas.right.addEventListener('click',this);this.layout=(ScreenLayout&&ScreenLayout.getCurrentLayout&&ScreenLayout.getCurrentLayout())?ScreenLayout.getCurrentLayout():'tiny';var center=this.center;this.arrows.left=new Image();this.arrows.right=new Image();var larrow=this.arrows.left;var rarrow=this.arrows.right;larrow.src=this.resources.larrow;rarrow.src=this.resources.rarrow;larrow.onload=(function(){var offset=this.useNewStyle?(this.arrows.left.width+this.handle.radius):(this.arrows.left.width<<1);this.arrows.ldraw.x=center.x-offset;this.arrows.ldraw.y=center.y-(this.arrows.left.height>>1);var ctx=this.canvas.getContext('2d');ctx.drawImage(this.arrows.left,this.arrows.ldraw.x,this.arrows.ldraw.y,this.arrows.left.width,this.arrows.left.height);}).bind(this);rarrow.onload=(function(){var offset=this.useNewStyle?this.handle.radius:this.arrows.right.width;this.arrows.rdraw.x=center.x+offset;this.arrows.rdraw.y=center.y-(this.arrows.right.height>>1);var ctx=this.canvas.getContext('2d');ctx.drawImage(this.arrows.right,this.arrows.rdraw.x,this.arrows.rdraw.y,this.arrows.right.width,this.arrows.right.height);}).bind(this);this.width=this._dpx(window.innerWidth);this.height=this._dpx(80);this.canvas.width=this.width;this.canvas.height=this.height;this.canvas.style.width=window.innerWidth+'px';this.canvas.style.height=80+'px';this.center.x=this.canvas.offsetLeft+this.canvas.width>>1;this.center.y=this.canvas.offsetTop+this.canvas.height>>1;this.handle.radius=this._dpx(this.handle.radius);if(this.useNewStyle){this.handle.innerRadius=this._dpx(this.handle.innerRadius);}
this.track.radius=this.handle.radius+this._dpx(this.useNewStyle?2:1);this.handle.lineWidth=this._dpx(this.handle.lineWidth);this.handle.autoExpand.sentinelOffset=this._dpx(this.handle.autoExpand.sentinelOffset);this.iconBG.radius=this._dpx(this.iconBG.radius);this.canvas.getContext('2d').save();this.canvas.getContext('2d',this.handle.radius<<1,0);var trackLength='tiny'===this.layout?this.track.length.tiny:this.track.length.large;trackLength=this._dpx(trackLength);var maxWidth=(trackLength-
(this.handle.radius<<1))>>1;maxWidth-=2;this.handle.maxWidth=maxWidth;this.handle.autoExpand.sentinelWidth=maxWidth-this.handle.autoExpand.sentinelOffset;this.track.width=trackLength;this.track.from=this.center.x-maxWidth;this.track.to=this.center.x+maxWidth;this.track.y=this.center.y;this._drawTrack();this._drawIconBG();this._resetHandle();this._resetTouchStates();};LockScreenSlidePrototype._finalizeCanvas=function lss_finalizeCanvas(){this.states.slidingColorful=false;this.states.slidingColorGradientEnd=false,this._clearCanvas();};LockScreenSlidePrototype._onSliding=function lss_onSliding(tx){var mtx=this._mapCoord(tx,0)[0];var isLeft=tx-this.center.x<0;var prevState;var currentState;this._clearCanvas();var expandSentinelR=this.center.x+
this.handle.autoExpand.sentinelWidth;var expandSentinelL=this.center.x-
this.handle.autoExpand.sentinelWidth;if(tx>expandSentinelR||tx<expandSentinelL){prevState=this.handle.autoExpand.accState;this.handle.autoExpand.accState='accelerating';currentState=this.handle.autoExpand.accState;var slow=false;if(isLeft){slow=this.states.touch.deltaX>0;if(prevState!==currentState){this.publish('lockscreenslide-near-left',{'currentState':currentState,'prevState':prevState});}}else{slow=this.states.touch.deltaX<0;if(prevState!==currentState){this.publish('lockscreenslide-near-right',{'currentState':currentState,'prevState':prevState});}}}else{prevState=this.handle.autoExpand.accState;this.handle.autoExpand.accState='normal';currentState=this.handle.autoExpand.accState;if(prevState!==currentState){if(isLeft){if(prevState!==currentState){this.publish('lockscreenslide-near-left',{'currentState':currentState,'prevState':prevState});}}else{if(prevState!==currentState){this.publish('lockscreenslide-near-right',{'currentState':currentState,'prevState':prevState});}}}}
mtx=this._accelerateSlide(tx);this._drawTrack();this._drawArrowsTo(mtx);this._drawIconBG();this._drawSlideTo(mtx);};LockScreenSlidePrototype._onSlideBegin=function lss_onSlideBegin(tx){var center=this.center;var boundaryR=center.x+this.handle.radius;var boundaryL=center.x-this.handle.radius;if(tx>boundaryR||tx<boundaryL){this.states.sliding=false;return;}
this.publish('lockscreenslide-unlocking-start');this.states.touch.initX=tx;this.states.sliding=true;this._lightIcons();};LockScreenSlidePrototype._endGesture=function lss_endGesture(){window.removeEventListener('touchmove',this);window.removeEventListener('touchend',this);this.states.sliding=false;this._onSlideEnd();this._resetTouchStates();this.overlay.classList.remove('touched');this.states.slideReachEnd=false;};LockScreenSlidePrototype._stop=function lss_stop(){if(this._stopped){return;}
window.removeEventListener('touchmove',this);window.removeEventListener('touchend',this);this.area.removeEventListener('touchstart',this);this._stopped=true;};LockScreenSlidePrototype._start=function lss_stop(){if(!this._stopped){return;}
window.addEventListener('touchmove',this);window.addEventListener('touchend',this);this.area.addEventListener('touchstart',this);this._stopped=false;};LockScreenSlidePrototype._onSlideEnd=function lss_onSlideEnd(){var isLeft=this.states.touch.pageX-this.center.x<0;if(false===this.states.slideReachEnd){this._bounceBack(this.states.touch.pageX);}else{var intention=isLeft?'lockscreenslide-activate-left':'lockscreenslide-activate-right';this.publish(intention);}
this.publish('lockscreenslide-unlocking-stop');this._darkIcons();};LockScreenSlidePrototype._onTouchMove=function ls_handleMove(pageX,pageY){var touch=this.states.touch;if(!touch.touched){if(!this.states.sliding){return;}
touch.touched=true;touch.initX=pageX;var overlay=this.overlay;overlay.classList.add('touched');}
touch.tx=pageX-touch.initX;touch.pageX=pageX;if(-1!==touch.pageX){touch.deltaX=pageX-touch.prevX;}
touch.prevX=pageX;};LockScreenSlidePrototype._accelerateSlide=function lss_accelerateSlide(tx){var isLeft=tx-this.center.x<0;var dx=Math.abs(tx-this.center.x);var accFactor=this.handle.autoExpand.accFactor;var acc=Math.pow(dx,accFactor);var accTx=tx+acc;if(isLeft){accTx=tx-acc;}
if(accTx<0){accTx=0;}
return accTx;};LockScreenSlidePrototype._clearCanvas=function lss_clearCanvas(){var canvas=this.canvas;var ctx=canvas.getContext('2d');ctx.clearRect(0,0,canvas.width,canvas.height);};LockScreenSlidePrototype._bounceBack=function lss_bounceBack(tx,cb){var duration=this.handle.bounceBackTime;var center=this.center;var nextTx=tx;var tsBegin=null;var mspf=0;var interval=1;var isLeft=tx-center.x<0;var drawIt=(function _drawIt(ts){if(null===tsBegin){tsBegin=ts;}
if(ts-tsBegin<duration){if(0===mspf){mspf=ts-tsBegin;}
interval=Math.abs(center.x-tx)/(duration/mspf);nextTx=isLeft?nextTx+interval:nextTx-interval;if((isLeft&&nextTx<center.x)||(!isLeft&&nextTx>=center.x)){this._clearCanvas();this._drawTrack();this._drawArrowsTo(nextTx);this._drawIconBG();this._drawSlideTo(nextTx);}
requestAnimationFrame(drawIt);}else{this._clearCanvas();this._drawTrack();this._drawArrowsTo(center.x);this._drawIconBG();this._drawSlideTo(center.x);if(cb){cb();}}}).bind(this);requestAnimationFrame(drawIt);};LockScreenSlidePrototype._darkIcons=function lss_darkIcons(){this.areas.left.classList.add('dark');this.areas.right.classList.add('dark');};LockScreenSlidePrototype._drawArrowsTo=function lss_drawArrows(tx){var canvas=this.canvas;var ctx=canvas.getContext('2d');var center=this.center;var offset=tx-center.x;var isLeft=offset<0;var alpha=1-Math.min(1,Math.abs(offset)/this._dpx(30));var position;var oldAlpha;if(this.handle.maxWidth<Math.abs(offset)){this.states.slideReachEnd=true;return;}
this.states.slideReachEnd=false;if(isLeft){position=this.useNewStyle?(tx-this.arrows.left.width-this.handle.radius):(tx-(this.arrows.left.width<<1));oldAlpha=ctx.globalAlpha;ctx.globalAlpha=alpha;ctx.drawImage(this.arrows.left,position,this.arrows.ldraw.y,this.arrows.left.width,this.arrows.left.height);ctx.globalAlpha=oldAlpha;ctx.drawImage(this.arrows.right,this.arrows.rdraw.x,this.arrows.rdraw.y,this.arrows.right.width,this.arrows.right.height);}else{position=this.useNewStyle?(tx+this.handle.radius):(tx+this.arrows.right.width);oldAlpha=ctx.globalAlpha;ctx.globalAlpha=alpha;ctx.drawImage(this.arrows.right,position,this.arrows.rdraw.y,this.arrows.right.width,this.arrows.right.height);ctx.globalAlpha=oldAlpha;ctx.drawImage(this.arrows.left,this.arrows.ldraw.x,this.arrows.ldraw.y,this.arrows.left.width,this.arrows.left.height);}};LockScreenSlidePrototype._drawTrack=function lss_drawTrack(){var canvas=this.canvas;var ctx=canvas.getContext('2d');var radius=this.track.radius;var startAngle;var endAngle;if(this.useNewStyle){startAngle=1.5*Math.PI;endAngle=0.5*Math.PI;var draw=(function(fillStyle,strokeStyle){ctx.beginPath();ctx.fillStyle=fillStyle;ctx.strokeStyle=strokeStyle;ctx.lineWidth=this.handle.lineWidth;ctx.moveTo(this.track.from,this.track.y-radius);ctx.lineTo(this.track.to,this.track.y-radius);ctx.arc(this.track.to,this.track.y,radius,startAngle,endAngle,false);ctx.lineTo(this.track.from,this.track.y+radius);ctx.arc(this.track.from,this.track.y,radius,endAngle,startAngle,false);ctx.fill();ctx.closePath();ctx.stroke();}).bind(this);draw(this.track.backColor,'transparent');var gradientStroke=ctx.createLinearGradient(this.track.from-radius,this.track.y-radius,this.track.from-radius,this.track.y+radius);var gradientFill=ctx.createLinearGradient(this.track.from-radius,this.track.y-radius,this.track.from-radius,this.track.y+radius);gradientStroke.addColorStop(0,this.track.strokeColorTop);gradientStroke.addColorStop(1,this.track.strokeColorBottom);gradientFill.addColorStop(0,this.track.fillColorTop);gradientFill.addColorStop(1,this.track.fillColorBottom);draw(gradientFill,gradientStroke);}else{startAngle=1.5*Math.PI;endAngle=0.5*Math.PI;var strokeStyle=this.track.color;ctx.fillStyle=this.track.backgroundColor;ctx.lineWidth=this.handle.lineWidth;ctx.strokeStyle=strokeStyle;ctx.beginPath();ctx.arc(this.track.from,this.track.y,radius,endAngle,startAngle,false);ctx.lineTo(this.track.from,this.track.y-radius);ctx.lineTo(this.track.to,this.track.y-radius);ctx.arc(this.track.to,this.track.y,radius,startAngle,endAngle,false);ctx.lineTo(this.track.from,this.track.y+radius);ctx.fill();ctx.stroke();ctx.closePath();}};LockScreenSlidePrototype._drawSlideTo=function lss_drawSlideTo(tx){var canvas=this.canvas;var ctx=canvas.getContext('2d');var maxWidth=this.handle.maxWidth;var offset=tx;var radius=this.handle.radius;var center=this.center;var rw=offset-center.x;var urw=Math.abs(rw);if(this.handle.maxWidth<urw){offset=rw>0?center.x+maxWidth:center.x-maxWidth;}
var counterclock=false;if(offset-center.x<0){counterclock=true;}
var isLeft=counterclock;var isRight=offset-center.x>0;if(isLeft){this.handle.touchedColor=this.colors.left.touchedColor;this.handle.touchedColorStop=this.colors.left.touchedColorStop;}else if(isRight){this.handle.touchedColor=this.colors.right.touchedColor;this.handle.touchedColorStop=this.colors.right.touchedColorStop;}
var startAngle=1.5*Math.PI;var endAngle=0.5*Math.PI;var fillAlpha=0.0;var strokeStyle='white';const GRADIENT_LENGTH=50;if(this.useNewStyle){if(0===urw){ctx.beginPath();ctx.arc(center.x,center.y,radius,0,2*Math.PI,false);ctx.fillStyle=this.handle.outerColor;ctx.closePath();ctx.fill();ctx.beginPath();ctx.arc(center.x,center.y,this.handle.innerRadius,0,2*Math.PI,false);ctx.fillStyle=this.handle.innerColor;ctx.closePath();ctx.fill();}else{fillAlpha=0.9-Math.min(0.7,(urw/this.handle.maxWidth)*0.7);strokeStyle='transparent';ctx.fillStyle='rgba('+this.handle.touchedColor+', '+
fillAlpha+')';ctx.strokeStyle=strokeStyle;ctx.beginPath();ctx.arc(center.x,center.y,radius,endAngle,startAngle,counterclock);ctx.lineTo(center.x,center.y-radius);ctx.lineTo(center.x+(offset-center.x),center.y-radius);ctx.arc(offset,center.y,radius,startAngle,endAngle,counterclock);ctx.lineTo(center.x,center.y+radius);ctx.fill();ctx.stroke();ctx.closePath();}}else{var fillColor;var strokeColor;var borderAlpha;if(urw>15&&true!==this.states.slidingColorful){fillAlpha=(urw-15)/GRADIENT_LENGTH;if(fillAlpha>1.0){fillAlpha=1.0;this.states.slidingColorGradientEnd=true;}
borderAlpha=1.0-fillAlpha;strokeStyle='rgba('+this.handle.touchedColorStop+','+borderAlpha+')';this.states.slidingColorful=true;}else{if(0===urw){fillAlpha=this.handle.backgroundAlpha;strokeColor=this.handle.color;fillColor=this.handle.backgroundColor;}else{fillAlpha=(urw-15)/GRADIENT_LENGTH;if(fillAlpha>1.0){fillAlpha=1.0;}
strokeColor=this.handle.touchedColorStop;fillColor=this.handle.touchedColor;}
borderAlpha=1.0-fillAlpha;strokeStyle='rgba('+strokeColor+','+borderAlpha+')';}
ctx.fillStyle='rgba('+fillColor+','+fillAlpha+')';ctx.lineWidth=this.handle.lineWidth;ctx.strokeStyle=strokeStyle;ctx.beginPath();ctx.arc(center.x,center.y,radius,endAngle,startAngle,counterclock);ctx.lineTo(center.x,center.y-radius);ctx.lineTo(center.x+(offset-center.x),center.y-radius);ctx.arc(offset,center.y,radius,startAngle,endAngle,counterclock);ctx.lineTo(center.x,center.y+radius);ctx.fill();ctx.stroke();ctx.closePath();}};LockScreenSlidePrototype._drawIconBG=function lss_dibg(){if(!this.useNewStyle){return;}
var canvas=this.canvas;var ctx=canvas.getContext('2d');ctx.fillStyle=this.iconBG.left.color;ctx.strokeStyle='transparent';ctx.beginPath();ctx.arc(this.track.from,this.track.y,this.iconBG.radius,0,2*Math.PI,false);ctx.stroke();ctx.closePath();ctx.fill();ctx.fillStyle=this.iconBG.right.color;ctx.beginPath();ctx.arc(this.track.to,this.track.y,this.iconBG.radius,0,2*Math.PI,false);ctx.fill();ctx.stroke();ctx.closePath();};LockScreenSlidePrototype._dpx=function lss_dpx(px){return px*window.devicePixelRatio;};LockScreenSlidePrototype._lightIcons=function lss_lightIcons(){this.areas.left.classList.remove('dark');this.areas.right.classList.remove('dark');};LockScreenSlidePrototype._mapCoord=function lss_mapCoord(x,y){var cw=this.canvas.clientWidth;var ch=this.canvas.clientHeight;return[cw*x/window.innerWidth,ch*y/window.innerHeight];};LockScreenSlidePrototype._resetArrows=function lss_restoreArrows(){var canvas=this.canvas;var ctx=canvas.getContext('2d');ctx.drawImage(this.arrows.left,this.arrows.ldraw.x,this.arrows.ldraw.y,this.arrows.left.width,this.arrows.left.height);ctx.drawImage(this.arrows.right,this.arrows.rdraw.x,this.arrows.rdraw.y,this.arrows.right.width,this.arrows.right.height);};LockScreenSlidePrototype._resetHandle=function lss_resetHandle(){this.states.slidingColorful=false;this.states.slidingColorGradientEnd=false;var centerx=this.center.x;this._drawSlideTo(centerx);};LockScreenSlidePrototype._resetTouchStates=function lss_resetTouchStates(){this.states.touch={id:null,touched:false,initX:this.center.x,pageX:this.center.x,pageY:this.center.y,tx:0,prevX:this.center.x,deltaX:0};};LockScreenSlidePrototype.publish=function lss_publish(type,detail){window.dispatchEvent(new CustomEvent(type,{'detail':detail}));};LockScreenSlide.prototype=LockScreenSlidePrototype;exports.LockScreenSlide=LockScreenSlide;})(window);

View file

@ -0,0 +1,3 @@
;'use strict';var MobileInfo={brazil:{carriers:{'00':'NEXTEL','02':'TIM','03':'TIM','04':'TIM','05':'CLARO','06':'VIVO','07':'CTBC','08':'TIM','10':'VIVO','11':'VIVO','15':'SERCOMTEL','16':'OI','23':'VIVO','24':'OI','31':'OI','32':'CTBC','33':'CTBC','34':'CTBC','37':'AEIOU'},regions:{'11':'SP','12':'SP','13':'SP','14':'SP','15':'SP','16':'SP','17':'SP','18':'SP','19':'SP','21':'RJ','22':'RJ','24':'RJ','27':'ES','28':'ES','31':'MG','32':'MG','33':'MG','34':'MG','35':'MG','37':'MG','38':'MG','41':'PR','42':'PR','43':'PR','44':'PR','45':'PR','46':'PR','47':'SC','48':'SC','49':'SC','51':'RS','53':'RS','54':'RS','55':'RS','61':'DF','62':'GO','63':'TO','64':'GO','65':'MT','66':'MT','67':'MS','68':'AC','69':'RO','71':'BA','73':'BA','74':'BA','75':'BA','77':'BA','79':'SE','81':'PE','82':'AL','83':'PB','84':'RN','85':'CE','86':'PI','87':'PE','88':'CE','89':'PI','91':'PA','92':'AM','93':'PA','94':'PA','95':'RR','96':'AP','97':'AM','98':'MA','99':'MA'}}};var MobileOperator={BRAZIL_MCC:'724',BRAZIL_CELLBROADCAST_CHANNEL:50,userFacingInfo:function mo_userFacingInfo(mobileConnection){var network=mobileConnection.voice.network;var iccid=mobileConnection.iccId;var iccObj=navigator.mozIccManager.getIccById(iccid);var iccInfo=iccObj?iccObj.iccInfo:null;var operator=network?(network.shortName||network.longName):null;if(operator&&iccInfo&&iccInfo.isDisplaySpnRequired&&iccInfo.spn){if(iccInfo.isDisplayNetworkNameRequired&&operator!==iccInfo.spn){operator=operator+' '+iccInfo.spn;}else{operator=iccInfo.spn;}}
var carrier,region;if(this.isBrazil(mobileConnection)){var lac=mobileConnection.voice.cell.gsmLocationAreaCode%100;var carriers=MobileInfo.brazil.carriers;var regions=MobileInfo.brazil.regions;carrier=carriers[network.mnc]||(this.BRAZIL_MCC+network.mnc);region=(regions[lac]?regions[lac]+' '+lac:'');}
return{'operator':operator,'carrier':carrier,'region':region};},isBrazil:function mo_isBrazil(mobileConnection){var cell=mobileConnection.voice.cell;var net=mobileConnection.voice.network;return net?(net.mcc===this.BRAZIL_MCC&&cell&&cell.gsmLocationAreaCode):null;}};

View file

@ -0,0 +1,35 @@
;(function(global){'use strict';global.mozIntl={formatList:function(list){return navigator.mozL10n.formatValue('listSeparator_middle').then(sep=>list.join(sep));},DateTimeFormat:function(locales,options){const resolvedOptions=Object.assign({},options);if(resolvedOptions.dayperiod){if(resolvedOptions.hour===undefined){resolvedOptions.hour='numeric';}}
if(resolvedOptions.hour!==undefined&&resolvedOptions.hour12===undefined){resolvedOptions.hour12=navigator.mozHour12;}
if(resolvedOptions.dayperiod===undefined&&resolvedOptions.hour12===true){resolvedOptions.dayperiod=true;}
var intlFormat=new Intl.DateTimeFormat(locales,resolvedOptions);resolvedOptions.locale=intlFormat.resolvedOptions().locale;resolvedOptions.hour12=intlFormat.resolvedOptions().hour12;var hourFormatter;if(resolvedOptions.dayperiod!==undefined&&resolvedOptions.hour12===true){hourFormatter=Intl.DateTimeFormat(locales,{hour:'numeric',hour12:false});}
return{resolvedOptions(){return resolvedOptions;},format:function(date,tokenFormats){var dayPeriod;var string=intlFormat.format(date);if(resolvedOptions.dayperiod===false&&resolvedOptions.hour12===true){dayPeriod=getDayPeriodTokenForDate(date,hourFormatter);string=string.replace(dayPeriod,'').trim();}else if(resolvedOptions.dayperiod===true&&options.hour===undefined){dayPeriod=getDayPeriodTokenForDate(date,hourFormatter);const hour=date.toLocaleString(navigator.languages,{hour12:true,hour:'numeric'}).replace(dayPeriod,'').trim();string=string.replace(hour,'').trim();}
for(var token in tokenFormats){if(token==='dayperiod'&&resolvedOptions.hour12===false){continue;}
const localOptions={[token]:resolvedOptions[token],};var formatter=global.mozIntl.DateTimeFormat(navigator.languages,localOptions);var tokenString=formatter.format(date);string=string.replace(tokenString,tokenFormats[token]);}
return string;},};},calendarInfo:function(token){switch(token){case'firstDayOfTheWeek':return navigator.mozL10n.formatValue('firstDayOfTheWeek').then(firstDayOfTheWeek=>parseInt(firstDayOfTheWeek)%7);default:throw new Error('Unknown token: '+token);}},DurationFormat:function(locales=navigator.languages,options={}){const resolvedOptions=Object.assign({locale:locales[0],maxUnit:'hour',minUnit:'second',},options);const numFormatter=Intl.NumberFormat(locales,{style:'decimal',useGrouping:false,minimumIntegerDigits:2});const maxUnitIdx=getDurationUnitIdx(resolvedOptions.maxUnit,0);const minUnitIdx=getDurationUnitIdx(resolvedOptions.minUnit,durationFormatOrder.length-1);return navigator.mozL10n.formatValue('durationPattern').then(fmt=>({resolvedOptions:function(){return resolvedOptions;},format:function(input){const minValue=durationFormatElements[resolvedOptions.minUnit].value;input=Math.round(input/minValue)*minValue;const duration=splitIntoTimeUnits(input,maxUnitIdx,minUnitIdx);var string=trimDurationPattern(fmt,resolvedOptions.maxUnit,resolvedOptions.minUnit);for(var unit in duration){const token=durationFormatElements[unit].token;string=string.replace(token,numFormatter.format(duration[unit]));}
if(input<0){return'-'+string;}
return string;}}));},RelativeTimeFormat:function(locales,options){return{resolvedOptions:function(){return options;},format:function(x){const{unit,value}=relativeTimeFormatId(x,options);return navigator.mozL10n.formatValue(unit,{value});},};},UnitFormat:function(locales,options){const unitGroup=getUnitFormatGroupName(options.unit);if(unitGroup===undefined){throw new RangeError(`invalid value ${options.unit} for option unit`);}
if(!unitFormatGroups[unitGroup].styles.includes(options.style)){throw new RangeError(`invalid value ${options.style} for option style`);}
const unit=`${unitGroup}-${options.unit}-${options.style}`;return{format:function(x){return document.l10n.formatValue(unit,{value:x});},};},_gaia:{relativePart:function(milliseconds){const units=computeTimeUnits(milliseconds);const unit=getBestMatchUnit(units);return{unit:unit+'s',value:Math.abs(units[unit])};},RelativeDate:function(locales,options){const style=options&&options.style||'long';const maxFormatter=Intl.DateTimeFormat(locales,{year:'numeric',month:'numeric',day:'numeric'});const relativeFmtOptions={unit:'bestFit',style:style,minUnit:'minute',};return{format:function(time,maxDiff){maxDiff=maxDiff||86400*10;const secDiff=(Date.now()-time)/1000;if(isNaN(secDiff)){return navigator.mozL10n.formatValue('incorrectDate');}
if(secDiff>maxDiff){return Promise.resolve(maxFormatter.format(time));}
const{unit,value}=relativeTimeFormatId(time,relativeFmtOptions);return navigator.mozL10n.formatValue(unit,{value});},formatElement:function(element,time,maxDiff){maxDiff=maxDiff||86400*10;const secDiff=(Date.now()-time)/1000;if(isNaN(secDiff)){element.setAttribute('data-l10n-id','incorrectDate');}
element.removeAttribute('data-l10n-id');if(secDiff>maxDiff){element.textContent=maxFormatter.format(time);}
const{unit,value}=relativeTimeFormatId(time,relativeFmtOptions);navigator.mozL10n.setAttributes(element,unit,{value});},};},getFormattedUnit:function(type,style,v){if(!unitFormatData.hasOwnProperty(type)){throw new RangeError(`invalid type ${type}`);}
if(!unitFormatGroups[type].styles.includes(style)){throw new RangeError(`invalid style ${style} for type ${type}`);}
var units=unitFormatData[type];var scale=0;for(let i=1;i<units.length;i++){if(v<units[i].value*unitFormatGroups[type].rounding){scale=i-1;break;}else if(i===units.length-1){scale=i;}}
var value=Math.round(v/units[scale].value*100)/100;return global.mozIntl.UnitFormat(navigator.languages,{unit:units[scale].name,style:style}).format(value);},}};const durationFormatOrder=['hour','minute','second','millisecond'];const durationFormatElements={'hour':{value:3600000,token:'hh'},'minute':{value:60000,token:'mm'},'second':{value:1000,token:'ss'},'millisecond':{value:10,token:'SS'}};const unitFormatData={'duration':[{'name':'second','value':1},{'name':'minute','value':60},{'name':'hour','value':60*60},{'name':'day','value':24*60*60},{'name':'month','value':30*24*60*60},],'digital':[{'name':'byte','value':1},{'name':'kilobyte','value':1024},{'name':'megabyte','value':1024*1024},{'name':'gigabyte','value':1024*1024*1024},{'name':'terabyte','value':1024*1024*1024*1024},],};const unitFormatGroups={'duration':{'units':['second','minute','hour','day','month'],'styles':['narrow'],'rounding':1},'digital':{'units':['byte','kilobyte','megabyte','gigabyte','terabyte'],'styles':['short'],'rounding':0.8}};function getDurationUnitIdx(name,defaultValue){if(!name){return defaultValue;}
const pos=durationFormatOrder.indexOf(name);if(pos===-1){throw new Error('Unknown unit type: '+name);}
return pos;}
function splitIntoTimeUnits(v,maxUnitIdx,minUnitIdx){const units={};var input=Math.abs(v);for(var i=maxUnitIdx;i<=minUnitIdx;i++){const key=durationFormatOrder[i];const{value}=durationFormatElements[key];units[key]=i==minUnitIdx?Math.round(input/value):Math.floor(input/value);input-=units[key]*value;}
return units;}
function trimDurationPattern(string,maxUnit,minUnit){const maxToken=durationFormatElements[maxUnit].token;const minToken=durationFormatElements[minUnit].token;string=string.substring(string.indexOf(maxToken),string.indexOf(minToken)+minToken.length);return string;}
function getDayPeriodTokenForDate(date,hourFormatter){const hourToken=hourFormatter.format(date);const newDate=new Date(date);newDate.setHours(parseInt(hourToken));return new Intl.DateTimeFormat(navigator.language, {hour:'numeric', hour12:true}).formatToParts(newDate).find(part => part.type === 'dayPeriod').value;}
function computeTimeUnits(v){const units={};const millisecond=Math.round(v);const second=Math.round(millisecond/1000);const minute=Math.round(second/60);const hour=Math.round(minute/60);const day=Math.round(hour/24);const rawYear=day*400/146097;units.millisecond=millisecond;units.second=second;units.minute=minute;units.hour=hour;units.day=day;units.week=Math.round(day/7);units.month=Math.round(rawYear*12);units.quarter=Math.round(rawYear*4);units.year=Math.round(rawYear);return units;}
function getBestMatchUnit(units){if(Math.abs(units.minute)<45){return'minute';}
if(Math.abs(units.hour)<22){return'hour';}
if(Math.abs(units.day)<7){return'day';}
if(Math.abs(units.week)<4){return'week';}
if(Math.abs(units.month)<11){return'month';}
return'year';}
function relativeTimeFormatId(x,options){const ms=x-Date.now();const units=computeTimeUnits(ms);const unit=options.unit==='bestFit'?getBestMatchUnit(units):options.unit;const v=units[unit];const tl=v<0?'-ago':'-until';const style=options.style||'long';const entry=unit+'s'+tl+'-'+style;return{unit:entry,value:Math.abs(v)};}
function getUnitFormatGroupName(unitName){for(let groupName in unitFormatGroups){if(unitFormatGroups[groupName].units.includes(unitName)){return groupName;}}
return undefined;}})(this);

View file

@ -0,0 +1,8 @@
;'use strict';var ScreenLayout={defaultQueries:{tiny:'(max-width: 767px)',small:'(min-width: 768px) and (max-width: 991px)',medium:'(min-width: 992px) and (max-width: 1200px)',large:'(min-width: 1201px)',hardwareHomeButton:window.VulpesCompat?'(min-width: 0px)':'(-moz-physical-home-button)'},init:function sl_init(){this.queries=(function(qs){var result={};for(var key in qs){result[key]=window.matchMedia(qs[key]);}
return result;})(this.defaultQueries);},_isOnRealDevice:undefined,isOnRealDevice:function sl_isOnRealDevice(){if(typeof(this._isOnRealDevice)!=='undefined'){return this._isOnRealDevice;}
if(window.innerWidth===screen.availWidth){this._isOnRealDevice=true;}else{this._isOnRealDevice=false;}
return this._isOnRealDevice;},getCurrentLayout:function sl_getCurrentLayout(type){if(type===undefined){for(var name in this.defaultQueries){if(this.queries[name]&&this.queries[name].matches){return name;}}}
if(typeof this.queries[type]!=='undefined'){return this.queries[type].matches;}
return false;},watch:function sl_watch(name,media){var mediaString=media||this.queries[name].media;if(!mediaString){return;}
this.unwatch(name);this.queries[name]=window.matchMedia(mediaString);this.boundHandleChange=this.handleChange.bind(this);this.queries[name].addListener(this.boundHandleChange);},unwatch:function sl_unwatch(name){if(this.queries[name]){this.queries[name].removeListener(this.boundHandleChange);}},handleChange:function sl_handleChange(evt){for(var key in this.queries){if(this.queries[key].media!==evt.media){continue;}
window.dispatchEvent(new CustomEvent('screenlayoutchange',{detail:{name:key,status:evt.matches}}));}}};ScreenLayout.init();

View file

@ -0,0 +1,4 @@
;;'use strict';var SettingsListener={_lock:null,_observers:[],getSettingsLock:function sl_getSettingsLock(){if(this._lock&&!this._lock.closed){return this._lock;}
var settings=window.navigator.mozSettings;return(this._lock=settings.createLock());},observe:function sl_observe(name,defaultValue,callback){var settings=window.navigator.mozSettings;if(!settings){window.setTimeout(function(){callback(defaultValue);});return;}
var req;try{req=this.getSettingsLock().get(name);}catch(e){console.warn('Stale lock in settings_listener.js.','See https://bugzilla.mozilla.org/show_bug.cgi?id=793239');this._lock=null;req=this.getSettingsLock().get(name);}
req.addEventListener('success',(function onsuccess(){callback(typeof(req.result[name])!='undefined'?req.result[name]:defaultValue);}));var settingChanged=function settingChanged(evt){callback(evt.settingValue);};settings.addObserver(name,settingChanged);this._observers.push({name:name,callback:callback,observer:settingChanged});},unobserve:function sl_unobserve(name,callback){var settings=window.navigator.mozSettings;var that=this;this._observers.forEach(function(value,index){if(value.name===name&&value.callback===callback){settings.removeObserver(name,value.observer);that._observers.splice(index,1);}});}};

View file

@ -0,0 +1,4 @@
;'use strict';function SettingsURL(){this._url=null;this._isBlob=false;}
SettingsURL.prototype={set:function(value){if(this._isBlob){window.URL.revokeObjectURL(this._url);}
if(value instanceof Blob){this._isBlob=true;this._url=window.URL.createObjectURL(value);}else{this._isBlob=false;this._url=value;}
return this._url;},get:function(){return this._url;}};

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,5 @@
;'use strict';(function(window){var _start=Date.now();var DEBUG=false;window.SIMSlot=function SIMSlot(conn,index,card){this.index=index;this.conn=conn;if(card){this.update(card);}
this.publish('created');};SIMSlot.EVENTS=['cardstatechange','iccinfochange','stkcommand','stksessionend'];SIMSlot.METHODS=['sendStkResponse','sendStkMenuSelection','sendStkTimerExpiration','sendStkEventDownload'];SIMSlot.DOM_REQUEST_METHODS=['getCardLock','unlockCardLock','setCardLock','getCardLockRetryCount','readContacts','updateContact','iccOpenChannel','iccExchangeAPDU','iccCloseChannel'];SIMSlot.ABSENT_TYPES=['permanentBlocked'];SIMSlot.LOCK_TYPES=['pinRequired','pukRequired','networkLocked','corporateLocked','serviceProviderLocked','network1Locked','network2Locked','hrpdNetworkLocked','ruimCorporateLocked','ruimServiceProviderLocked'];SIMSlot.prototype.update=function ss_update(iccObj){this.simCard=iccObj;this.constructor.EVENTS.forEach(function iterater(evt){iccObj.addEventListener(evt,this);},this);this.constructor.DOM_REQUEST_METHODS.forEach(function iterator(domRequest){this[domRequest]=function(){return iccObj[domRequest].apply(iccObj,arguments);};},this);this.constructor.METHODS.forEach(function iterator(method){this[method]=function(){return iccObj[method].apply(iccObj,arguments);};},this);this.publish('updated');};SIMSlot.prototype.EVENT_PREFIX='simslot-';SIMSlot.prototype.CLASS_NAME='SIMSLOT';SIMSlot.prototype.publish=function ss_publish(eventName){this.debug(' publish: '+eventName);window.dispatchEvent(new CustomEvent(this.EVENT_PREFIX+eventName,{detail:this}));};SIMSlot.prototype.handleEvent=function ss_handleEvent(evt){switch(evt.type){default:this.publish(evt.type);if(this.simCard){this.debug(this.simCard.cardState);}
break;}};SIMSlot.prototype.debug=function(){if(DEBUG){console.log('['+this.CLASS_NAME+']'+'['+(this.index)+']'+'['+(new Date().getTime()/1000-_start).toFixed(3)+']'+
Array.slice(arguments).concat());}};SIMSlot.prototype.isAbsent=function ss_isAbsent(){return(!this.simCard||this.constructor.ABSENT_TYPES.indexOf(this.simCard.cardState)>=0||this.simCard&&this.simCard.iccInfo&&this.simCard.iccInfo.iccid===null);};SIMSlot.prototype.getSmsc=function ss_getSmsc(cb){var mobileMessage=window.navigator.mozMobileMessage;if(!mobileMessage){console.error('can\'t access mozMobileMessage');cb(null);}else{mobileMessage.getSmscAddress(this.index).then((result)=>{var smsc;if(typeof result==='string'||result instanceof String){smsc=result.split(',')[0].replace(/"/g,'');}else{smsc=result.address;}
cb(smsc);},(error)=>{console.error(error);cb(null);});}};SIMSlot.prototype.isUnknownState=function ss_isUnknownState(){var empty=(this.simCard.cardState==='');var unknown=(this.simCard.cardState==='unknown');return!this.simCard.cardState||unknown||empty;};SIMSlot.prototype.isLocked=function ss_isLocked(){return this.constructor.LOCK_TYPES.indexOf(this.simCard.cardState)>=0;};SIMSlot.prototype.getCardState=function ss_getCardState(){return this.simCard.cardState;};}(window));

View file

@ -0,0 +1,9 @@
;'use strict';(function(window){var IccManager=navigator.mozIccManager;window.SIMSlotManager={length:0,_instances:[],TIMEOUT_FOR_SIM2:2000,_timerForSIM2:null,ready:false,init:function ssm_init(){if(!IccManager){return;}
this._conns=Array.prototype.slice.call(navigator.mozMobileConnections);this.length=this._conns.length;if(this._conns.length===0){return;}
var allSIMCardDetected=true;this._conns.forEach(function iterator(conn,index){var slot=new SIMSlot(conn,index,IccManager.getIccById(conn.iccId));this._instances.push(slot);if(slot.isAbsent()){allSIMCardDetected=false;}},this);if(allSIMCardDetected){this.publishSIMSlotIsReady();}else if(this.isMultiSIM()&&this.hasOnlyOneSIMCardDetected()){this.waitForSecondSIM();}
IccManager.addEventListener('iccdetected',this);window.dispatchEvent(new CustomEvent('simslotmanagerstarted'));},isMultiSIM:function(){return(this.length>1);},isSIMCardAbsent:function ssm_isSIMCardAbsent(index){var slot=this.get(index);if(slot){return slot.isAbsent();}else{return true;}},hasOnlyOneSIMCardDetected:function(){var sim0Absent=this.isSIMCardAbsent(0);var sim1Absent=this.isSIMCardAbsent(1);var hasOneSim=(sim0Absent&&!sim1Absent)||(!sim0Absent&&sim1Absent);return hasOneSim;},noSIMCardOnDevice:function ssm_noSIMCardOnDevice(){if(!IccManager||!IccManager.iccIds){return true;}
return(IccManager.iccIds.length===0);},noSIMCardConnectedToNetwork:function ssm_noSIMCardConnectedToNetwork(){if(!IccManager||!IccManager.iccIds){return true;}
return this._instances.every(function iterator(instance){return instance.conn.voice&&instance.conn.voice.emergencyCallsOnly;});},get:function ssm_get(index){if(index>this.length-1){return null;}
return this._instances[index];},getMobileConnection:function ssm_getMobileConnection(index){if(index>this.length-1){return null;}
return this._instances[index].conn;},getSlots:function ssm_getSlots(){return this._instances;},getSlotByIccId:function ssm_getSlotByIccId(iccId){var found=null;this._instances.some(function iterator(slot,index){if(slot.conn.iccId&&slot.conn.iccId===iccId){found=slot;return true;}else{return false;}},this);return found;},waitForSecondSIM:function(){var self=this;this._timerForSIM2=setTimeout(function(){clearTimeout(self._timerForSIM2);self.publishSIMSlotIsReady();},this.TIMEOUT_FOR_SIM2);},publishSIMSlotIsReady:function(){if(!this.ready){this.ready=true;window.dispatchEvent(new CustomEvent('simslotready'));}},handleEvent:function ssm_handleEvent(evt){switch(evt.type){case'iccdetected':var slot=this.getSlotByIccId(evt.iccId);if(slot){slot.update(IccManager.getIccById(evt.iccId));if(!this.isMultiSIM()){this.publishSIMSlotIsReady();}else{if(this.hasOnlyOneSIMCardDetected()){this.waitForSecondSIM();}else{clearTimeout(this._timerForSIM2);this.publishSIMSlotIsReady();}}}
break;}}};SIMSlotManager.init();}(window));

View file

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

View file

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Action menu</title>
<meta name="description" content="Presenting a list of actions related to the App content">
<link rel="stylesheet" href="../action_menu.css">
<!--
- This <style> element is only used for the example code;
- it is not required for the real use case.
-->
<style type="text/css">
html, body {
font-family: sans-serif;
margin: 0;
padding: 0;
font-size: 10px;
background-color: #fff;
}
body {
background: none;
}
</style>
</head>
<body role="application">
<p dir="ltr">
<label>
<input type="checkbox"
onchange="document.documentElement.dir = this.checked ? 'rtl' : 'ltr'">
RTL mode
</label>
</p>
<form role="dialog" data-type="action">
<header>
<button><span class="icon icon-close">close</span></button>
<menu type="toolbar">
<button>done</button>
</menu>
<h1>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</h1>
</header>
<section>
<p>Curabitur condimentum diam mollis lacus hendrerit congue. Phasellus porttitor orci elit, ac consequat est mollis ut. Ut consequat ipsum a ullamcorper aliquam.</p>
</section>
</form>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

View file

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html dir="ltr">
<head>
<meta charset="utf-8">
<title>Action menu</title>
<meta name="description" content="Presenting a list of actions related to the App content">
<link rel="stylesheet" href="../action_menu.css">
<!--
- These <style> and <script> elements are only used for the example code;
- they are not required for the real use case.
-->
<style type="text/css">
html, body {
font-family: sans-serif;
margin: 0;
padding: 0;
font-size: 10px;
background-color: #fff;
}
body {
background: none;
}
</style>
<script>
window.onkeypress = event => {
var dir = document.documentElement.dir;
document.documentElement.dir = (dir === 'ltr') ? 'rtl' : 'ltr';
};
</script>
</head>
<body role="application">
<form role="dialog" data-type="action">
<header><span class="icon icon-back"></span>Title</header> <!-- this header is optional -->
<menu type="toolbar">
<button>Action 1</button>
<button disabled> Action 2 (disabled) </button>
<button> Action 3. </button>
<button> الولايات 4</button>
<button disabled> Action 5 (disabled) </button>
<button> Action 6 </button>
<button> Action 7 </button>
<button disabled> Action 8 (disabled) </button>
<button> Action 9 </button>
<button> Cancel </button>
</menu>
</form>
</body>
</html>

View file

@ -0,0 +1,370 @@
/*
* The code is being shared between system/emergency-call/js/keypad.js
* and dialer/js/keypad.js. Be sure to update both files when you commit!
*
* BiDi note: keypads are always displayed in LTR (hardware legacy).
* This stylesheet must *NOT* be mirrored for RTL.
*/
.reset-button {
border: 0;
background: none;
}
.reset-button::-moz-focus-inner {
border: 0;
outline: none;
}
#phone-number-view-container {
width: 100%;
height: 28%;
background: var(--header-background);
text-align: center;
display: flex;
font-weight: 300;
overflow: hidden;
}
#phone-number-view-container .phone-number-view-wrapper-input {
width: 100%;
margin-bottom: 4.5rem;
display: flex;
align-items: center;
padding: 0 1rem 0 2rem;
}
#phone-number-view-container.keypad-visible {
height: calc(100% - 34.5rem);
visibility: hidden;
}
#phone-number-view {
font-size: 4.1rem;
width: 100%;
border: 0;
margin: 0;
background: transparent;
color: var(--header-color);
text-align: left;
cursor: none;
padding: 0;
pointer-events: auto;
-moz-user-select: text;
}
#fake-phone-number-view {
position: absolute;
left: 2rem;
line-height: 0;
visibility: hidden;
}
#keypad-delete {
margin-bottom: 4.5rem;
padding: 0 2.5rem 0 0;
visibility: hidden;
text-align: right;
}
#keypad-delete::before {
content: "";
background: url('keypad/images/keypad/actionicon_dialer_delete.png') no-repeat;
width: 3rem;
height: 2rem;
display: inline-block;
background-size: 100%;
}
#keypad-delete:active {
opacity: 0.6;
}
#keyboard-container {
height: 72%;
padding: 0 1rem;
}
#keypad {
width: 100%;
height: 80%;
display: table;
table-layout: fixed;
}
.keypad-row {
display: table-row;
}
.keypad-key {
display: table-cell;
padding: 1.3rem 0 0 2rem;
box-sizing: border-box;
height: 20%;
vertical-align: middle;
color: #333;
font-weight: 300;
font-size: 5rem;
line-height: 1rem;
overflow: hidden;
text-align: left;
}
.keypad-key span {
width: 1.5rem;
display: inline-block;
overflow: visible;
}
.keypad-key em {
display: inline-block;
font-weight: 300;
font-size: 1.5rem;
color: #038282;
font-style: normal;
width: 4.5rem;
overflow: visible;
text-align: left;
}
.keypad-key.active {
background: #94eee9;
color: #fff;
}
.keypad-key * {
pointer-events: none;
}
#keypad-delete * {
pointer-events: none;
}
.keypad-key .font-size-plus {
font-size: 2rem;
}
.keypad-subicon {
background-repeat: no-repeat;
background-position: center bottom;
-moz-user-select: none;
pointer-events: none;
display: inline-block;
width: 3rem;
height: 2rem;
}
.voicemail {
background-image: url('keypad/images/keypad/actionicon_dialer_voicemail.png');
background-size: 3rem;
background-position: -0.4rem -0.1rem;
}
.asterisk {
width: 4rem;
margin-top: 1rem;
margin-left: 0.2rem;
overflow: visible;
}
.sharp {
font-size: 4.5rem;
width: 4rem;
line-height: 0;
margin-top: -0.5rem;
margin-left: 0.2rem;
overflow: visible;
}
#keypad-callbar {
height: 20%;
display: flex;
flex-direction: row;
align-items: center;
width: 100%;
border-bottom: 0;
border-left: 0;
box-sizing: border-box;
}
.keypad-callbar-button {
position: relative;
width: 9rem;
background: #e7e7e7;
background-size: auto 100%;
border-radius: 2rem;
overflow: hidden;
height: 4rem;
text-align: center;
}
.keypad-callbar-button.cancel {
background: #575757;
line-height: 4rem;
font-size: 1.8rem;
font-style: italic;
}
.keypad-callbar-button.cancel:active {
background: #9ef2e7;
}
#keypad-callbar-call-action {
display: flex;
position: relative;
flex-grow: 1;
align-items: center;
flex-direction: row-reverse;
background-image: url("keypad/images/keypad/actionicon_activecall_pickup.png");
background-color: #00adad;
background-repeat: no-repeat;
background-position: center;
background-size: 4rem 4rem;
border-radius: 2rem;
margin-inline-start: 1rem;
height: 4rem;
}
#keypad-callbar-call-action:active {
background-color: #94eee9;
}
.icon-add-contact::before {
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-image: url("keypad/images/keypad/actionicon_activecall_addcontact_40x80.png");
background-repeat: no-repeat;
background-position: top center;
background-size: 4rem 8rem;
}
/* we won't do anything on click but this prevents fluffing/rendering issues */
.icon-add-contact:disabled {
pointer-events: all;
}
.icon-add-contact:disabled::before {
opacity: 0.4;
}
.icon-add-contact:not(:disabled):active::before {
background-position: center -4rem;
}
.js-sim-indication {
display: none;
font-size: 1.3rem;
text-align: right;
margin-right: 0.6rem;
color: #fff;
}
.has-preferred-sim .js-sim-indication {
display: initial;
}
.has-preferred-sim #keypad-callbar-call-action:after {
content: "";
position: absolute;
width: 1.4rem;
height: 1rem;
bottom: 0;
right: 1.7rem;
background-image: url("/shared/elements/gaia_sim_picker/images/long-tap-indicator.png");
background-repeat: no-repeat;
background-size: 1.4rem 1rem;
}
#keypad-hidebar {
border: 0;
box-sizing: border-box;
display: flex;
justify-content: space-around;
height: 7.5rem;
}
.kh__button {
width: 5rem;
height: 5rem;
background: #ded9d6;
border: none;
border-radius: 100%;
margin-top: 1rem;
position: relative;
}
.kh__button::before {
content: "";
position: absolute;
top: .5rem;
left: .5rem;
width: 4rem;
height: 4rem;
background-repeat: no-repeat;
background-position: 0 0;
background-size: cover;
}
.kh__button:active::before {
background-position: 0 -4rem;
}
.kh__button:active {
background-color: #9ef2e7;
}
.kh__button.active-state::before {
background-position: 0 -8rem;
}
.kh__button--mute::before {
background-image: url('keypad/images/keypad/actionicon_activecall_mute.png');
}
.kh__button--hide::before {
background-image: url('keypad/images/keypad/actionicon_activecall_dismisskeyboard.png');
}
.kh__call-end-button {
width: 6.5rem;
height: 6.5rem;
background: #e00;
border: none;
border-radius: 100%;
position: relative;
}
.kh__call-end-button::before {
content: "";
position: absolute;
top: 1.1rem;
left: 1.2rem;
width: 4rem;
height: 4rem;
background-image: url('keypad/images/actionicon_activecall_hangup.png');
background-repeat: no-repeat;
background-position: 0 0;
background-size: cover;
}
.kh__call-end-button:active::before {
background-position: 1.2rem 6rem;
}
.phone-number-font {
color: #fff;
}
.full-height {
height: 100%;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

View file

@ -0,0 +1,59 @@
/*
* Extend action menu as an overlay
*/
form.overlay {
font-size: 1.5rem;
opacity: 1;
visibility: hidden;
transform: translateY(-100%);
transition: transform var(--transition-duration) ease-in-out,
visibility var(--transition-duration);
}
form.overlay > menu {
height: 100%;
}
form.overlay.display {
transform: translateY(0%);
visibility: visible;
}
form.overlay menu ul {
height: calc(100% - 13rem);
overflow: auto;
margin-top: 5rem;
padding: 0;
line-height: 2.4rem;
list-style: none outside none;
}
form.overlay menu ul > li,
form.overlay menu ul > section {
height: 4.5rem;
padding: 1rem 2rem;
font-size: 1.7rem;
position: relative;
}
form.overlay menu ul > li:after,
form.overlay menu ul > section:after {
content: ' ';
border-bottom: 0.1rem solid #666;
display: block;
position: absolute;
left: 1rem;
bottom: 0;
right: 1rem;
}
form.overlay menu ul > li:last-child:after,
form.overlay menu ul > section:last-child:after {
display: none;
}
form.overlay menu ul > li:active,
form.overlay menu ul > section:active {
background-color: #00ABCC;
transition: background-color 0.2s ease;
}

View file

@ -0,0 +1,31 @@
/* ----------------------------------
* Status
* ---------------------------------- */
html[dir="ltr"] section[role="status"] [dir] { text-align: left; }
html[dir="rtl"] section[role="status"] [dir] { text-align: right; }
section[role="status"] {
background-color: #4d4d4d;
overflow: hidden;
position: absolute;
z-index: 100;
left: 0;
right: 0;
bottom: 0;
color: #fff;
}
html[dir="ltr"] section[role="status"] { background-position: left top; }
html[dir="rtl"] section[role="status"] { background-position: right top; }
section[role="status"] p {
font-size: 1.8rem;
font-weight: normal;
line-height: 2.2rem;
margin: 1rem 3rem;
padding: 0;
}
section[role="status"] p strong {
font-weight: 500;
}

View file

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html dir="ltr">
<head>
<meta charset="utf-8">
<title>Status</title>
<meta name="description" content="Most common used after Multi-Select edit, to confirm user action, and optional provide 'Undo' input">
<link rel="stylesheet" href="../status.css">
<!--
This <style>, <script> and <link> are only used for the example code,
they are not needed for the real use case
-->
<style>
html, body {
margin: 0;
padding: 0;
font-size: 10px;
background-color: #fff;
}
body {
background: none;
}
</style>
<script>
window.onload = function(){
document.getElementById('dir').checked = false;
};
</script>
</head>
<body role="application">
<p dir="ltr">
<label>
<input id="dir" type="checkbox"
onchange="document.documentElement.dir = this.checked ? 'rtl' : 'ltr'">
RTL mode
</label>
</p>
<section role="status">
<p>The Alarm is set for <strong>7 hours</strong> and <strong>14 minutes</strong> from now</p>
</section>
</body>
</html>

View file

@ -0,0 +1,93 @@
#group-call-details-list > section .additionalContactInfo {
height: 1.5rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 0 10.0rem 2rem;
padding-inline-start: 0;
font-size: 1.6rem;
line-height: 2rem;
}
#group-call-details-list .duration {
display: none;
}
#group-call-details-list .number bdi {
font-size: 1.7rem;
line-height: 2.4rem;
white-space: nowrap;
display: block;
overflow: hidden;
text-overflow: ellipsis;
font-weight: bold;
}
html[dir="ltr"] #group-call-details-list .number bdi {
text-align: left;
padding-right: 10.0rem;
}
html[dir="rtl"] #group-call-details-list .number bdi {
text-align: right;
padding-left: 10.0rem;
}
#group-call-details-list > section:not(.additionalInfo) .number {
line-height: 4.5rem;
}
#group-call-details {
z-index: 750;
}
.hangup-button {
visibility: hidden;
}
#group-call-details .hangup-button {
position: absolute;
background: url('images/handled_call/actionicon_activecall_hangup.png') no-repeat scroll transparent;
background-size: 4rem auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
visibility: visible;
}
html[dir="ltr"] #group-call-details .hangup-button {
background-position: right 1.8rem center;
}
html[dir="rtl"] #group-call-details .hangup-button {
background-position: left 1.8rem center;
}
#group-call-details section.ended > .hangup-button {
background-image: none;
}
#group-call-details section.ended > .duration {
display: block;
position: absolute;
top: 1rem;
offset-inline-end: 1.5rem;
}
#group-call-details section.ended > .duration > span {
font-weight: normal;
}
#group-call-details section.ended > .duration > .total-duration {
font-weight: 300;
line-height: 1.7rem;
}
html[dir="ltr"] #group-call-details section.ended > .duration > .total-duration {
text-align: right;
}
html[dir="rtl"] #group-call-details section.ended > .duration > .total-duration {
text-align: left;
}
#group-call-details-list .sim {
display: none;
color: #ffffff;
font-weight: normal;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

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