Merge mozilla-central to mozilla-inbound

This commit is contained in:
Carsten "Tomcat" Book 2015-09-09 14:08:42 +02:00
commit 5ad0e1dabd
52 changed files with 704 additions and 420 deletions

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e935894ef5f27e2f04b9e929a45a958e6288a223">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e69f2c86b931b723dd405115e33a1d02e6c5f5e6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="60e212543329ee48f2921e0cd92aaca4b4ce2f6a"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e935894ef5f27e2f04b9e929a45a958e6288a223">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e69f2c86b931b723dd405115e33a1d02e6c5f5e6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="60e212543329ee48f2921e0cd92aaca4b4ce2f6a"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e69f2c86b931b723dd405115e33a1d02e6c5f5e6"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="60e212543329ee48f2921e0cd92aaca4b4ce2f6a"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e69f2c86b931b723dd405115e33a1d02e6c5f5e6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="60e212543329ee48f2921e0cd92aaca4b4ce2f6a"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="c6cace53426b5be7e56c0fd202118009689bc707"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e935894ef5f27e2f04b9e929a45a958e6288a223">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e69f2c86b931b723dd405115e33a1d02e6c5f5e6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="60e212543329ee48f2921e0cd92aaca4b4ce2f6a"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e69f2c86b931b723dd405115e33a1d02e6c5f5e6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="60e212543329ee48f2921e0cd92aaca4b4ce2f6a"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e69f2c86b931b723dd405115e33a1d02e6c5f5e6"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="60e212543329ee48f2921e0cd92aaca4b4ce2f6a"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e935894ef5f27e2f04b9e929a45a958e6288a223">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e69f2c86b931b723dd405115e33a1d02e6c5f5e6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="60e212543329ee48f2921e0cd92aaca4b4ce2f6a"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "e69f2c86b931b723dd405115e33a1d02e6c5f5e6",
"git_revision": "60e212543329ee48f2921e0cd92aaca4b4ce2f6a",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "410ec98908ee38c636b018d3ba92e17fb338db79",
"revision": "8aa25dda878ebc1b075933633b69967b930b0726",
"repo_path": "integration/gaia-central"
}

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e69f2c86b931b723dd405115e33a1d02e6c5f5e6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="60e212543329ee48f2921e0cd92aaca4b4ce2f6a"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="c6cace53426b5be7e56c0fd202118009689bc707"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e69f2c86b931b723dd405115e33a1d02e6c5f5e6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="60e212543329ee48f2921e0cd92aaca4b4ce2f6a"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -637,9 +637,6 @@ pref("accessibility.typeaheadfind.timeout", 5000);
pref("accessibility.typeaheadfind.linksonly", false);
pref("accessibility.typeaheadfind.flashBar", 1);
// plugin finder service url
pref("pfs.datasource.url", "https://pfs.mozilla.org/plugins/PluginFinderService.php?mimetype=%PLUGIN_MIMETYPE%&appID=%APP_ID%&appVersion=%APP_VERSION%&clientOS=%CLIENT_OS%&chromeLocale=%CHROME_LOCALE%&appRelease=%APP_RELEASE%");
pref("plugins.update.url", "https://www.mozilla.org/%LOCALE%/plugincheck/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=plugincheck-update");
pref("plugins.update.notifyUser", false);
@ -1935,7 +1932,12 @@ pref("browser.pocket.oAuthConsumerKey", "40249-e88c401e1b1f2242d9e441c4");
pref("browser.pocket.useLocaleList", true);
pref("browser.pocket.enabledLocales", "cs de en-GB en-US en-ZA es-ES es-MX fr hu it ja ja-JP-mac ko nl pl pt-BR pt-PT ru zh-CN zh-TW");
// View source tabs are only enabled by default for Dev. Ed and Nightly.
#ifdef RELEASE_BUILD
pref("view_source.tab", false);
#else
pref("view_source.tab", true);
#endif
// Enable ServiceWorkers for Push API consumers.
// Interception is still disabled.

View File

@ -96,7 +96,7 @@ var FullScreen = {
TabsInTitlebar.updateAppearance(true);
}
if (enterFS) {
if (enterFS && !document.mozFullScreen) {
Services.telemetry.getHistogramById("FX_BROWSER_FULLSCREEN_USED")
.add(1);
}

View File

@ -154,7 +154,10 @@ let LoopUI;
}
this.PanelFrame.showPopup(window, event ? event.target : this.toolbarButton.node,
"loop", null, "about:looppanel", null, callback);
"loop", null, "about:looppanel",
// Loop wants a fixed size for the panel. This also stops it dynamically resizing.
{ width: 330, height: 410 },
callback);
});
});
},

View File

@ -84,8 +84,8 @@ function waitForProviderLoad(cb) {
waitForCondition(function() {
let sbrowser = document.getElementById("social-sidebar-browser");
let provider = SocialSidebar.provider;
let postActivation = provider && gBrowser.contentDocument &&
gBrowser.contentDocument.location.href == provider.origin + "/browser/browser/base/content/test/social/social_postActivation.html";
let postActivation = provider && gBrowser.currentURI &&
gBrowser.currentURI.spec == provider.origin + "/browser/browser/base/content/test/social/social_postActivation.html";
return postActivation && sbrowser.docShellIsActive;
}, function() {

View File

@ -7,6 +7,59 @@ html {
font-family: sans-serif; /* XXX will be changed to a system font in bug 1191398 */
}
.contacts-container {
flex: 1;
display: flex;
flex-flow: column nowrap;
overflow: auto;
}
.contact-list-container {
flex: 1;
display: flex;
flex-direction: column;
overflow: auto;
}
/* Don't show the Gravatar if we're showing a contacts list. */
.contact-list ~ .contacts-gravatar-promo {
display: none;
}
.contact-list-wrapper {
flex: 1;
overflow-x: hidden;
overflow-y: auto;
}
/* Don't show the empty contacts image if we're showing gravatar promo. */
.contacts-gravatar-promo ~ .contact-list-empty {
background-image: none;
padding-top: 0;
padding-bottom: 0;
margin-top: 2px;
}
.contact-list-empty-container {
flex: 1;
overflow-x: hidden;
overflow-y: auto;
}
.contact-list-empty,
.contact-search-list-empty {
margin-top: 4rem;
padding-top: 11.5rem;
padding-bottom: 0;
}
.contact-search-list-empty {
background-image: url("../shared/img/empty_search.svg");
}
.contact-list-empty {
background-image: url("../shared/img/empty_contacts.svg");
}
.contact-import-spinner {
display: none;
}
@ -35,8 +88,6 @@ html {
background-repeat: no-repeat;
color: #999;
font-size: 1.2rem;
flex: 2 1 auto;
align-self: stretch;
}
html[dir="rtl"] .contact-filter {
@ -65,21 +116,17 @@ html[dir="rtl"] .contact-filter {
}
.contact-list {
overflow-x: hidden;
overflow-y: auto;
/* Space for six contacts, not affected by filtering. This is enough space
to show the dropdown menu when there is only one contact. */
height: 306px;
/* Contact list title goes away when searching, needed for spacing. */
margin-top: 4px;
}
.contact-list-title {
padding: 0 1rem;
padding: 0.75rem 1rem;
color: #666;
font-weight: 500;
font-size: .9em;
margin-top: 1rem;
}
.contact,
@ -210,23 +257,6 @@ html[dir="rtl"] .contact-filter {
width: 100%;
}
.contact-list-empty,
.contact-search-list-empty {
background-image: url("../shared/img/empty_contacts.svg");
background-repeat: no-repeat;
background-position: top center;
background-size: 128px;
margin-top: 4rem;
padding-top: 12rem;
padding-bottom: 5rem;
text-align: center;
color: #4a4a4a;
}
.contact-search-list-empty {
background-image: url("../shared/img/empty_search.svg");
}
.panel-text-medium,
.panel-text-large {
margin: 3px;
@ -340,7 +370,10 @@ html[dir="rtl"] .contact > .dropdown-menu {
}
.contact-form {
padding: 14px; /* Override based on spacing in Mockup */
padding: 14px 15px 0 15px; /* Override based on spacing in Mockup */
flex: 1;
display: flex;
flex-direction: column;
}
/* This will effect the header displayed at the top of the contact details form
*/
@ -352,9 +385,8 @@ html[dir="rtl"] .contact > .dropdown-menu {
}
.contact-form .form-content-container {
height: 24.1rem; /* This height is needed to keep the panel height at 400px and
the bottom elements at the bottom of the panel
Can likely go away if we switched this pane to flexbox model */
/* flex is needed to fill and place the buttons above the footer */
flex: 1;
padding-top: 4px; /* Based on spacing in Mockup
replaced margin-top
See http://stackoverflow.com/questions/6204670/css-clean-solution-to-the-margin-collapse-issue-when-floating-an-element
@ -435,7 +467,9 @@ html[dir="rtl"] .contacts-gravatar-arrow {
}
.contact-controls {
padding: 0 16px;
padding-left: 15px;
padding-right: 15px;
border-top: 1px solid #D8D8D8;
}
.contact-controls > .button {

View File

@ -17,11 +17,23 @@ body {
overflow: hidden;
font: menu;
background-color: #fbfbfb;
height: 410px;
width: 330px;
}
/* Panel container flexbox */
.panel-content {
height: 410px;
width: 330px;
display: flex;
flex-flow: column nowrap;
align-items: flex-start;
}
/* Notifications displayed over tabs */
.panel .messages {
width: 100%;
margin: 0;
}
@ -67,10 +79,15 @@ body {
/* Tabs and tab selection buttons */
.tab-view-container {
width: 100%;
background-image: url("../shared/img/beta-ribbon.svg#beta-ribbon");
background-color: #fbfbfb;
background-size: 36px 36px;
background-repeat: no-repeat;
flex: 1;
display: flex;
flex-flow: column nowrap;
overflow: hidden;
}
.tab-view {
@ -179,7 +196,8 @@ html[dir="rtl"] .tab-view li:nth-child(2).selected ~ .slide-bar {
background-image: url("../shared/img/icons-14x14.svg#hello-hover");
}
.tab-view li:first-child:nth-last-child(2) ~ div {
.tab-view li:first-child:nth-last-child(2) ~ li {
/* hide the tab-slider when there is only one tab shown */
display: none;
}
@ -190,10 +208,13 @@ html[dir="rtl"] .tab-view li:nth-child(2).selected ~ .slide-bar {
.tab {
display: none;
flex: 1;
overflow: auto;
}
.tab.selected {
display: block;
display: flex;
flex-flow: column nowrap;
}
/* Content area and input fields */
@ -254,29 +275,25 @@ html[dir="rtl"] .tab-view li:nth-child(2).selected ~ .slide-bar {
/* Rooms and contacts shared CSS */
.contact-list-empty,
.room-list-empty {
background-image: url("../shared/img/empty_contacts.svg");
.contact-search-list-empty,
.no-conversations-message {
background-repeat: no-repeat;
background-position: top center;
padding-top: 19%;
padding-bottom: 3%;
text-align: center;
color: #4a4a4a;
font-weight: lighter;
}
/* Don't show the empty contacts image if we're showing gravatar promo. */
.contacts-gravatar-promo ~ .contact-list-empty {
background-image: none;
padding-top: 3%;
}
.contact-list-empty {
padding-top: 27%;
}
.room-list-empty {
margin: 5% 15px;
.no-conversations-message {
/* example of vertical aligning a container in an element
see: http://zerosixthree.se/vertical-align-anything-with-just-3-lines-of-css/ */
position: relative;
top: 50%;
transform: translateY(-50%);
padding-top: 75px;
padding-bottom: 10px;
background-image: url("../shared/img/empty_conversations.svg");
}
@ -296,6 +313,8 @@ html[dir="rtl"] .tab-view li:nth-child(2).selected ~ .slide-bar {
.room-list-loading {
margin: 5rem 15px;
text-align: center;
/* makes sure that buttons are anchored above footer */
flex: 1;
}
.room-list-loading > img {
@ -305,9 +324,9 @@ html[dir="rtl"] .tab-view li:nth-child(2).selected ~ .slide-bar {
/* Rooms */
.rooms {
min-height: 100px;
/* To hold the conversation dropdown menu. */
position: relative;
flex: 1;
display: flex;
flex-flow: column nowrap;
}
.rooms > h1 {
@ -323,6 +342,7 @@ html[dir="rtl"] .tab-view li:nth-child(2).selected ~ .slide-bar {
.new-room-view {
display: flex;
flex-direction: column;
border-top: 1px solid #d8d8d8;
}
.new-room-view > .context-checkbox-checked {
@ -332,8 +352,8 @@ html[dir="rtl"] .tab-view li:nth-child(2).selected ~ .slide-bar {
.new-room-view > .context {
border-top: 1px solid #ebebeb;
flex: 1;
margin: .5rem 0;
padding: .5rem 15px 1rem;
border-radius: 3px 3px 0 0;
padding: 6px 15px 8px;
}
.new-room-view > .context > .context-enabled {
@ -370,7 +390,7 @@ html[dir="rtl"] .tab-view li:nth-child(2).selected ~ .slide-bar {
height: 3rem;
display: block;
font-size: 1.2rem;
margin: 0 15px 1rem 15px;
margin: 7px 15px 0 15px;
padding: .5rem 1rem;
border-radius: 4px;
}
@ -382,14 +402,23 @@ html[dir="rtl"] .tab-view li:nth-child(2).selected ~ .slide-bar {
}
.room-list {
max-height: 335px; /* XXX better computation needed */
/* At least high enough to be able to contain the conversation menu. */
min-height: 100px;
overflow: auto;
/* xxx not sure why flex needs the 3 value setting
but setting flex to just 1, the whole tab including the new room is scrollable.
seems to not like the 0% of the default setting - may be FF bug */
flex: 1 1 0;
overflow-y: auto;
overflow-x: hidden;
display: flex;
flex-flow: column nowrap;
}
.room-list:empty {
.room-list-empty {
border-bottom-width: 0;
flex: 1;
/* the child no-conversations-message is vertical aligned inside this container
see: http://zerosixthree.se/vertical-align-anything-with-just-3-lines-of-css/
stops blurring from decimal pixels being rendered - pixel rounding */
transform-style: preserve-3d;
}
.room-list > .room-entry {
@ -404,8 +433,9 @@ html[dir="rtl"] .tab-view li:nth-child(2).selected ~ .slide-bar {
line-height: 2.4rem;
color: #000;
/* See .room-entry-context-item for the margin/size reductions.
* An extra 40px to make space for the call button and chevron. */
* An extra 40px to make space for the call button and chevron. */
width: calc(100% - 1rem - 56px);
}
.room-list > .room-entry.room-active > h2 {
@ -437,7 +467,7 @@ html[dir="rtl"] .tab-view li:nth-child(2).selected ~ .slide-bar {
@keyframes drop-and-fade-in {
0% {opacity: 0; top: -15px;}
25% {opacity: 0; top: -15px;}
100% {opacity: 1; top: 0px;}
100% {opacity: 1; top: 0;}
}
.room-list > .room-entry > h2 > button {
@ -475,7 +505,7 @@ html[dir="rtl"] .tab-view li:nth-child(2).selected ~ .slide-bar {
background: transparent url(../shared/img/icons-16x16.svg#checkmark);
animation: pulse .150s;
animation-timing-function: ease-in-out;
top: 0px;
top: 0;
}
/* keep the various room-entry row pieces aligned with each other */
@ -551,11 +581,11 @@ html[dir="rtl"] .room-entry-call-btn {
html[dir="rtl"] .room-entry-context-actions > .dropdown-menu {
right: auto;
left: 21px;
left: 45px;
}
.room-entry-context-actions > .dropdown-menu {
right: 21px;
right: 45px;
bottom: auto;
left: auto;
}
@ -980,9 +1010,10 @@ html[dir="rtl"] .settings-menu .dropdown-menu {
align-content: stretch;
align-items: center;
font-size: 1rem;
background-color: #fbfbfb;
color: #666666;
padding: .5rem 15px;
padding: 10px 15px 6px 15px;
width: 100%;
height: 42px;
}
.footer .signin-details {
@ -999,14 +1030,14 @@ html[dir="rtl"] .settings-menu .dropdown-menu {
/* First time use */
.fte-get-started-content {
/* Manual vertical centering */
flex: 1;
padding: 4.5rem 0 3.4rem;
padding: 7.5rem 0 0;
display: flex;
flex-direction: column;
}
.fte-title {
flex: 1;
margin: 0 44px;
}
@ -1022,19 +1053,14 @@ html[dir="rtl"] .settings-menu .dropdown-menu {
}
.fte-get-started-content + .powered-by-wrapper {
flex: 0;
width: 100%;
}
.fte-get-started-container {
height: 100%;
width: 100%;
min-height: 270px;
height: 410px;
width: 330px;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: space-between;
align-content: flex-start;
align-items: flex-start;
flex-flow: column nowrap;
background: #fbfbfb;
}

View File

@ -655,6 +655,9 @@ loop.contacts = (function(_, mozL10n) {
this.state.filter) {
return (
React.createElement("div", {className: "contact-search-list-empty"},
React.createElement("p", {className: "panel-text-large"},
mozL10n.get("no_search_results_message_heading")
),
React.createElement("p", {className: "panel-text-medium"},
mozL10n.get("contacts_no_search_results")
)
@ -666,35 +669,40 @@ loop.contacts = (function(_, mozL10n) {
if (!shownContacts.available && !shownContacts.blocked &&
!this.state.filter) {
return (
React.createElement("div", {className: "contact-list-empty"},
React.createElement("p", {className: "panel-text-medium"},
mozL10n.get("no_contacts_message_heading2")
),
React.createElement("p", {className: "panel-text-medium"},
mozL10n.get("no_contacts_import_or_add2")
React.createElement("div", {className: "contact-list-empty-container"},
this._renderGravatarPromoMessage(),
React.createElement("div", {className: "contact-list-empty"},
React.createElement("p", {className: "panel-text-large"},
mozL10n.get("no_contacts_message_heading2")
),
React.createElement("p", {className: "panel-text-medium"},
mozL10n.get("no_contacts_import_or_add2")
)
)
)
)
);
}
return (
React.createElement("div", null,
!this.state.filter ? React.createElement("div", {className: "contact-list-title"},
mozL10n.get("contact_list_title")
) : null,
this._renderGravatarPromoMessage(),
React.createElement("ul", {className: "contact-list"},
shownContacts.available ?
shownContacts.available.sort(this.sortContacts).map(viewForItem) :
null,
shownContacts.blocked && shownContacts.blocked.length > 0 ?
React.createElement("div", {className: "contact-separator"}, mozL10n.get("contacts_blocked_contacts")) :
null,
shownContacts.blocked ?
shownContacts.blocked.sort(this.sortContacts).map(viewForItem) :
null
React.createElement("div", {className: "contact-list-container"},
!this.state.filter ? React.createElement("div", {className: "contact-list-title"},
mozL10n.get("contact_list_title")
) : null,
React.createElement("div", {className: "contact-list-wrapper"},
this._renderGravatarPromoMessage(),
React.createElement("ul", {className: "contact-list"},
shownContacts.available ?
shownContacts.available.sort(this.sortContacts).map(viewForItem) :
null,
shownContacts.blocked && shownContacts.blocked.length > 0 ?
React.createElement("div", {className: "contact-separator"}, mozL10n.get("contacts_blocked_contacts")) :
null,
shownContacts.blocked ?
shownContacts.blocked.sort(this.sortContacts).map(viewForItem) :
null
)
)
)
)
);
},
@ -735,7 +743,7 @@ loop.contacts = (function(_, mozL10n) {
render: function() {
return (
React.createElement("div", null,
React.createElement("div", {className: "contacts-container"},
this._renderContactsFilter(),
this._renderContactsList(),
this._renderAddContactButtons()

View File

@ -655,6 +655,9 @@ loop.contacts = (function(_, mozL10n) {
this.state.filter) {
return (
<div className="contact-search-list-empty">
<p className="panel-text-large">
{mozL10n.get("no_search_results_message_heading")}
</p>
<p className="panel-text-medium">
{mozL10n.get("contacts_no_search_results")}
</p>
@ -666,35 +669,40 @@ loop.contacts = (function(_, mozL10n) {
if (!shownContacts.available && !shownContacts.blocked &&
!this.state.filter) {
return (
<div className="contact-list-empty">
<p className="panel-text-medium">
{mozL10n.get("no_contacts_message_heading2")}
</p>
<p className="panel-text-medium">
{mozL10n.get("no_contacts_import_or_add2")}
</p>
</div>
<div className="contact-list-empty-container">
{this._renderGravatarPromoMessage()}
<div className="contact-list-empty">
<p className="panel-text-large">
{mozL10n.get("no_contacts_message_heading2")}
</p>
<p className="panel-text-medium">
{mozL10n.get("no_contacts_import_or_add2")}
</p>
</div>
</div>
);
}
return (
<div>
{!this.state.filter ? <div className="contact-list-title">
{mozL10n.get("contact_list_title")}
</div> : null}
{this._renderGravatarPromoMessage()}
<ul className="contact-list">
{shownContacts.available ?
shownContacts.available.sort(this.sortContacts).map(viewForItem) :
null}
{shownContacts.blocked && shownContacts.blocked.length > 0 ?
<div className="contact-separator">{mozL10n.get("contacts_blocked_contacts")}</div> :
null}
{shownContacts.blocked ?
shownContacts.blocked.sort(this.sortContacts).map(viewForItem) :
null}
</ul>
</div>
<div className="contact-list-container">
{!this.state.filter ? <div className="contact-list-title">
{mozL10n.get("contact_list_title")}
</div> : null}
<div className="contact-list-wrapper">
{this._renderGravatarPromoMessage()}
<ul className="contact-list">
{shownContacts.available ?
shownContacts.available.sort(this.sortContacts).map(viewForItem) :
null}
{shownContacts.blocked && shownContacts.blocked.length > 0 ?
<div className="contact-separator">{mozL10n.get("contacts_blocked_contacts")}</div> :
null}
{shownContacts.blocked ?
shownContacts.blocked.sort(this.sortContacts).map(viewForItem) :
null}
</ul>
</div>
</div>
);
},
@ -735,7 +743,7 @@ loop.contacts = (function(_, mozL10n) {
render: function() {
return (
<div>
<div className="contacts-container">
{this._renderContactsFilter()}
{this._renderContactsList()}
{this._renderAddContactButtons()}

View File

@ -479,8 +479,6 @@ loop.conversationViews = (function(mozL10n) {
_getTitleMessage: function() {
switch (this.getStoreState().callStateReason) {
case WEBSOCKET_REASONS.REJECT:
case WEBSOCKET_REASONS.BUSY:
case FAILURE_DETAILS.USER_UNAVAILABLE:
var contactDisplayName = _getContactDisplayName(this.props.contact);
if (contactDisplayName.length) {

View File

@ -479,8 +479,6 @@ loop.conversationViews = (function(mozL10n) {
_getTitleMessage: function() {
switch (this.getStoreState().callStateReason) {
case WEBSOCKET_REASONS.REJECT:
case WEBSOCKET_REASONS.BUSY:
case FAILURE_DETAILS.USER_UNAVAILABLE:
var contactDisplayName = _getContactDisplayName(this.props.contact);
if (contactDisplayName.length) {

View File

@ -100,7 +100,7 @@ loop.panel = (function(_, mozL10n) {
React.createElement("div", {className: "tab-view-container"},
React.createElement("ul", {className: "tab-view"},
tabButtons,
React.createElement("div", {className: "slide-bar"})
React.createElement("li", {className: "slide-bar"})
),
tabs
)
@ -306,7 +306,7 @@ loop.panel = (function(_, mozL10n) {
});
return (
React.createElement("div", {id: "powered-by-wrapper"},
React.createElement("div", {className: "powered-by-wrapper", id: "powered-by-wrapper"},
React.createElement("p", {className: "powered-by", id: "powered-by"},
mozL10n.get("powered_by_beforeLogo"),
React.createElement("span", {className: locale, id: "powered-by-logo"}),
@ -826,13 +826,15 @@ loop.panel = (function(_, mozL10n) {
_renderNoRoomsView: function() {
return (
React.createElement("div", {className: "room-list"},
React.createElement("div", {className: "rooms"},
React.createElement("div", {className: "room-list-empty"},
React.createElement("p", {className: "panel-text-large"},
mozL10n.get("no_conversations_message_heading")
),
React.createElement("p", {className: "panel-text-medium"},
mozL10n.get("no_conversations_start_message")
React.createElement("div", {className: "no-conversations-message"},
React.createElement("p", {className: "panel-text-large"},
mozL10n.get("no_conversations_message_heading")
),
React.createElement("p", {className: "panel-text-medium"},
mozL10n.get("no_conversations_start_message")
)
)
),
this._renderNewRoomButton()
@ -1128,7 +1130,7 @@ loop.panel = (function(_, mozL10n) {
}
return (
React.createElement("div", null,
React.createElement("div", {className: "panel-content"},
React.createElement(NotificationListView, {
clearOnDocumentHidden: true,
notifications: this.props.notifications}),

View File

@ -100,7 +100,7 @@ loop.panel = (function(_, mozL10n) {
<div className="tab-view-container">
<ul className="tab-view">
{tabButtons}
<div className="slide-bar" />
<li className="slide-bar" />
</ul>
{tabs}
</div>
@ -306,7 +306,7 @@ loop.panel = (function(_, mozL10n) {
});
return (
<div id="powered-by-wrapper">
<div className="powered-by-wrapper" id="powered-by-wrapper">
<p className="powered-by" id="powered-by">
{mozL10n.get("powered_by_beforeLogo")}
<span className={locale} id="powered-by-logo"/>
@ -826,14 +826,16 @@ loop.panel = (function(_, mozL10n) {
_renderNoRoomsView: function() {
return (
<div className="room-list">
<div className="rooms">
<div className="room-list-empty">
<p className="panel-text-large">
{mozL10n.get("no_conversations_message_heading")}
</p>
<p className="panel-text-medium">
{mozL10n.get("no_conversations_start_message")}
</p>
<div className="no-conversations-message">
<p className="panel-text-large">
{mozL10n.get("no_conversations_message_heading")}
</p>
<p className="panel-text-medium">
{mozL10n.get("no_conversations_start_message")}
</p>
</div>
</div>
{this._renderNewRoomButton()}
</div>
@ -1128,7 +1130,7 @@ loop.panel = (function(_, mozL10n) {
}
return (
<div>
<div className="panel-content">
<NotificationListView
clearOnDocumentHidden={true}
notifications={this.props.notifications} />

View File

@ -426,7 +426,6 @@ loop.store = loop.store || {};
* Gather the list of all available rooms from the MozLoop API.
*/
getAllRooms: function() {
this.setStoreState({pendingInitialRetrieval: true});
this._mozLoop.rooms.getAll(null, function(err, rawRoomList) {
var action;

View File

@ -224,13 +224,13 @@ html[dir="rtl"] .conversation-toolbar-btn-box.btn-edit-entry {
background-image: url("../img/svg/sharing-hover.svg");
}
.btn-settings.muted,
.btn-screen-share.active {
opacity: 1;
background-image: url("../img/svg/sharing-active.svg");
}
.btn-screen-share.disabled {
background-image: url("../img/svg/sharing-mute.svg");
/* The screen share button is in its pending state when its disabled. */
background-image: url("../img/svg/sharing-pending.svg");
}
.fx-embedded .remote_wrapper {

View File

@ -0,0 +1 @@
<svg width="28" height="28" viewBox="0 0 28 28" xmlns="http://www.w3.org/2000/svg"><g fill="none"><rect opacity=".95" fill="#fff" x="2" y="2" width="24" height="24" rx="40"/><path d="M2 14c0 6.629 5.373 12 12 12 6.629 0 12-5.373 12-12 0-6.629-5.373-12-12-12-6.629 0-12 5.373-12 12zm-2 0c0-7.732 6.267-14 14-14 7.732 0 14 6.267 14 14 0 7.732-6.267 14-14 14-7.732 0-14-6.267-14-14z" fill-opacity=".2" fill="#000"/><rect fill="#00A9DC" x="11" y="12" width="9" height="7" rx="1"/><path d="M17 11v-.997c0-.565-.447-1.003-.998-1.003h-7.005c-.551 0-.998.449-.998 1.003v4.994c0 .565.447 1.003.998 1.003h1.002v-3.997c0-.554.446-1.003.998-1.003h6.002z" fill="#00A9DC"/></g></svg>

After

Width:  |  Height:  |  Size: 670 B

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="28px" height="28px" viewBox="0 0 28 28" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<rect id="Rectangle-1264-Copy" opacity="0.95" fill="#FFFFFF" x="2" y="2" width="24" height="24" rx="40"></rect>
<path d="M2,14 L2,14 C2,20.6288742 7.372583,26 14,26 L14,26 C20.6288742,26 26,20.627417 26,14 L26,14 C26,7.37112582 20.627417,2 14,2 L14,2 C7.37112582,2 2,7.372583 2,14 L2,14 Z M0,14 L0,14 C0,6.26754774 6.26702203,0 14,0 C21.7324523,0 28,6.26702203 28,14 C28,21.7324523 21.732978,28 14,28 C6.26754774,28 0,21.732978 0,14 L0,14 Z" id="Shape" fill-opacity="0.2" fill="#000000"></path>
<path d="M16.4994509,12 L11.9975446,12 C11.4463114,12 11,12.4490268 11,13.0029293 L11,17.491272 L16.4994509,12 Z M11.1367161,19.3689248 C11.1138915,19.40931 11.099976,19.4517095 11.099976,19.5009121 C11.099976,19.5708113 11.1280605,19.6269803 11.1698752,19.6831493 L11.8139462,20.3272204 C11.8701152,20.3696591 11.9262842,20.3971195 11.9961834,20.3971195 C12.0667067,20.3971195 12.1222516,20.3696591 12.1784205,20.3272204 L13.5056409,19 L19.0024554,19 C19.5536886,19 20,18.5509732 20,17.9970707 L20,13.0029293 C20,12.8551278 19.9694422,12.716027 19.9144529,12.591188 L21.8301248,10.6755161 C21.8719395,10.6337014 21.900024,10.5638022 21.900024,10.4932789 C21.900024,10.437734 21.8719395,10.3672108 21.8301248,10.3253961 L21.1860538,9.68132501 C21.1298848,9.62515602 21.0737158,9.59707153 21.0038166,9.59707153 C20.9339174,9.59707153 20.8777484,9.62515602 20.8215795,9.68132501 L19.8517551,10.6497071 C19.8450712,10.6591494 19.8378312,10.6678097 19.8301248,10.6755161 L11.1367161,19.3689248 Z M17.001,11 L17.001,10.003 C17.001,9.438 16.554,9 16.003,9 L8.998,9 C8.447,9 8,9.449 8,10.003 L8,14.997 C8,15.562 8.447,16 8.998,16 L10,16 L10,12.003 C10,11.449 10.446,11 10.998,11 L17,11 L17.001,11 Z" id="Shape-Copy-3" fill="#4A4A4A"></path>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1 @@
<svg width="28" height="28" viewBox="0 0 28 28" xmlns="http://www.w3.org/2000/svg"><g fill="none"><rect opacity=".95" fill="#999999" x="2" y="2" width="24" height="24" rx="40"/><path d="M2 14c0 6.629 5.373 12 12 12 6.629 0 12-5.373 12-12 0-6.629-5.373-12-12-12-6.629 0-12 5.373-12 12zm-2 0c0-7.732 6.267-14 14-14 7.732 0 14 6.267 14 14 0 7.732-6.267 14-14 14-7.732 0-14-6.267-14-14z" fill-opacity=".2" fill="#000"/><rect fill="#4A4A4A" x="11" y="12" width="9" height="7" rx="1"/><path d="M17 11v-.997c0-.565-.447-1.003-.998-1.003h-7.005c-.551 0-.998.449-.998 1.003v4.994c0 .565.447 1.003.998 1.003h1.002v-3.997c0-.554.446-1.003.998-1.003h6.002z" fill="#4A4A4A"/></g></svg>

After

Width:  |  Height:  |  Size: 673 B

View File

@ -12,6 +12,7 @@ loop.store = loop.store || {};
var CALL_TYPES = loop.shared.utils.CALL_TYPES;
var REST_ERRNOS = loop.shared.utils.REST_ERRNOS;
var FAILURE_DETAILS = loop.shared.utils.FAILURE_DETAILS;
var WEBSOCKET_REASONS = loop.shared.utils.WEBSOCKET_REASONS;
/**
* Websocket states taken from:
@ -616,8 +617,19 @@ loop.store = loop.store || {};
(previousState !== WS_STATES.INIT &&
previousState !== WS_STATES.ALERTING)) {
// For outgoing calls we can treat everything as connection failure.
// XXX We currently fallback to the websocket reason, but really these should
// be fully migrated to use FAILURE_DETAILS, so as not to expose websocket
// states outside of this store. Bug 1124384 should help to fix this.
var reason = progressData.reason;
if (reason === WEBSOCKET_REASONS.REJECT ||
reason === WEBSOCKET_REASONS.BUSY) {
reason = FAILURE_DETAILS.USER_UNAVAILABLE;
}
this.dispatcher.dispatch(new sharedActions.ConnectionFailure({
reason: progressData.reason
reason: reason
}));
return;
}

View File

@ -70,8 +70,9 @@ browser.jar:
content/browser/loop/shared/img/svg/settings.svg (content/shared/img/svg/settings.svg)
content/browser/loop/shared/img/svg/settings-hover.svg (content/shared/img/svg/settings-hover.svg)
content/browser/loop/shared/img/svg/sharing.svg (content/shared/img/svg/sharing.svg)
content/browser/loop/shared/img/svg/sharing-active.svg (content/shared/img/svg/sharing-active.svg)
content/browser/loop/shared/img/svg/sharing-pending.svg (content/shared/img/svg/sharing-pending.svg)
content/browser/loop/shared/img/svg/sharing-hover.svg (content/shared/img/svg/sharing-hover.svg)
content/browser/loop/shared/img/svg/sharing-mute.svg (content/shared/img/svg/sharing-mute.svg)
content/browser/loop/shared/img/svg/media-group.svg (content/shared/img/svg/media-group.svg)
content/browser/loop/shared/img/svg/media-group-left-hover.svg (content/shared/img/svg/media-group-left-hover.svg)
content/browser/loop/shared/img/svg/media-group-right-hover.svg (content/shared/img/svg/media-group-right-hover.svg)

View File

@ -406,30 +406,6 @@ describe("loop.conversationViews", function () {
sinon.assert.calledWith(document.mozL10n.get, "generic_failure_title");
});
it("should show 'contact unavailable' when the reason is WEBSOCKET_REASONS.REJECT",
function () {
conversationStore.setStoreState({callStateReason: WEBSOCKET_REASONS.REJECT});
view = mountTestComponent({contact: fakeContact});
sinon.assert.calledWithExactly(document.mozL10n.get,
"contact_unavailable_title",
{contactName: loop.conversationViews
._getContactDisplayName(fakeContact)});
});
it("should show 'contact unavailable' when the reason is WEBSOCKET_REASONS.BUSY",
function () {
conversationStore.setStoreState({callStateReason: WEBSOCKET_REASONS.BUSY});
view = mountTestComponent({contact: fakeContact});
sinon.assert.calledWithExactly(document.mozL10n.get,
"contact_unavailable_title",
{contactName: loop.conversationViews
._getContactDisplayName(fakeContact)});
});
it("should show 'something went wrong' when the reason is 'setup'",
function () {
conversationStore.setStoreState({callStateReason: "setup"});
@ -462,8 +438,10 @@ describe("loop.conversationViews", function () {
});
it("should display a generic contact unavailable msg when the reason is" +
" WEBSOCKET_REASONS.BUSY and no display name is available", function() {
conversationStore.setStoreState({callStateReason: WEBSOCKET_REASONS.BUSY});
" FAILURE_DETAILS.USER_UNAVAILABLE and no display name is available", function() {
conversationStore.setStoreState({
callStateReason: FAILURE_DETAILS.USER_UNAVAILABLE
});
var phoneOnlyContact = {
tel: [{"pref": true, type: "work", value: ""}]
};

View File

@ -38,7 +38,7 @@ add_task(function* test_LoopUI_getters() {
yield loadLoopPanel();
Assert.ok(LoopUI.browser, "Browser element should be there");
Assert.strictEqual(LoopUI.selectedTab, "rooms", "Initially the rooms tab should be selected");
let panelTabs = LoopUI.browser.contentDocument.querySelectorAll(".tab-view > li");
let panelTabs = LoopUI.browser.contentDocument.querySelectorAll(".tab-view > li:not(.slide-bar)");
Assert.strictEqual(panelTabs.length, 1, "Only one tab, 'rooms', should be visible");
// Hide the panel.
@ -52,7 +52,7 @@ add_task(function* test_LoopUI_getters() {
yield LoopUI.togglePanel();
Assert.strictEqual(LoopUI.selectedTab, "rooms", "Rooms tab should still be selected");
panelTabs = LoopUI.browser.contentDocument.querySelectorAll(".tab-view > li");
panelTabs = LoopUI.browser.contentDocument.querySelectorAll(".tab-view > li:not(.slide-bar)");
Assert.strictEqual(panelTabs.length, 2, "Two tabs should be visible");
yield LoopUI.togglePanel();

View File

@ -388,11 +388,10 @@ describe("loop.store.ConversationStore", function () {
connectPromise.then(function() {
checkFailures(done, function() {
sinon.assert.calledOnce(dispatcher.dispatch);
// Can't use instanceof here, as that matches any action
sinon.assert.calledWithMatch(dispatcher.dispatch,
sinon.match.hasOwn("name", "connectionProgress"));
sinon.assert.calledWithMatch(dispatcher.dispatch,
sinon.match.hasOwn("wsState", WS_STATES.INIT));
sinon.assert.calledWithExactly(dispatcher.dispatch,
new sharedActions.ConnectionProgress({
wsState: WS_STATES.INIT
}));
});
}, function() {
done(new Error("Promise should have been resolve, not rejected"));
@ -407,11 +406,10 @@ describe("loop.store.ConversationStore", function () {
}, function() {
checkFailures(done, function() {
sinon.assert.calledOnce(dispatcher.dispatch);
// Can't use instanceof here, as that matches any action
sinon.assert.calledWithMatch(dispatcher.dispatch,
sinon.match.hasOwn("name", "connectionFailure"));
sinon.assert.calledWithMatch(dispatcher.dispatch,
sinon.match.hasOwn("reason", "websocket-setup"));
sinon.assert.calledOnce(dispatcher.dispatch,
new sharedActions.ConnectionFailure({
reason: "websocket-setup"
}));
});
});
});
@ -1137,24 +1135,6 @@ describe("loop.store.ConversationStore", function () {
sandbox.stub(dispatcher, "dispatch");
});
it("should dispatch a connection failure action on 'terminate' for outgoing calls", function() {
store.setStoreState({
outgoing: true
});
store._websocket.trigger("progress", {
state: WS_STATES.TERMINATED,
reason: WEBSOCKET_REASONS.REJECT
});
sinon.assert.calledOnce(dispatcher.dispatch);
// Can't use instanceof here, as that matches any action
sinon.assert.calledWithMatch(dispatcher.dispatch,
sinon.match.hasOwn("name", "connectionFailure"));
sinon.assert.calledWithMatch(dispatcher.dispatch,
sinon.match.hasOwn("reason", WEBSOCKET_REASONS.REJECT));
});
it("should dispatch a connection failure action on 'terminate' for incoming calls if the previous state was not 'alerting' or 'init'", function() {
store.setStoreState({
outgoing: false
@ -1166,7 +1146,6 @@ describe("loop.store.ConversationStore", function () {
}, WS_STATES.CONNECTING);
sinon.assert.calledOnce(dispatcher.dispatch);
// Can't use instanceof here, as that matches any action
sinon.assert.calledWithExactly(dispatcher.dispatch,
new sharedActions.ConnectionFailure({
reason: WEBSOCKET_REASONS.CANCEL
@ -1184,7 +1163,6 @@ describe("loop.store.ConversationStore", function () {
}, WS_STATES.INIT);
sinon.assert.calledOnce(dispatcher.dispatch);
// Can't use instanceof here, as that matches any action
sinon.assert.calledWithExactly(dispatcher.dispatch,
new sharedActions.CancelCall({}));
});
@ -1200,7 +1178,6 @@ describe("loop.store.ConversationStore", function () {
}, WS_STATES.ALERTING);
sinon.assert.calledOnce(dispatcher.dispatch);
// Can't use instanceof here, as that matches any action
sinon.assert.calledWithExactly(dispatcher.dispatch,
new sharedActions.CancelCall({}));
});
@ -1209,11 +1186,57 @@ describe("loop.store.ConversationStore", function () {
store._websocket.trigger("progress", {state: WS_STATES.ALERTING});
sinon.assert.calledOnce(dispatcher.dispatch);
// Can't use instanceof here, as that matches any action
sinon.assert.calledWithMatch(dispatcher.dispatch,
sinon.match.hasOwn("name", "connectionProgress"));
sinon.assert.calledWithMatch(dispatcher.dispatch,
sinon.match.hasOwn("wsState", WS_STATES.ALERTING));
sinon.assert.calledWithExactly(dispatcher.dispatch,
new sharedActions.ConnectionProgress({
wsState: WS_STATES.ALERTING
}));
});
describe("Outgoing Calls, handling 'terminate'", function() {
beforeEach(function() {
store.setStoreState({
outgoing: true
});
});
it("should dispatch a connection failure action", function() {
store._websocket.trigger("progress", {
state: WS_STATES.TERMINATED,
reason: WEBSOCKET_REASONS.MEDIA_FAIL
});
sinon.assert.calledOnce(dispatcher.dispatch);
sinon.assert.calledWithExactly(dispatcher.dispatch,
new sharedActions.ConnectionFailure({
reason: WEBSOCKET_REASONS.MEDIA_FAIL
}));
});
it("should dispatch an action with user unavailable if the websocket reports busy", function() {
store._websocket.trigger("progress", {
state: WS_STATES.TERMINATED,
reason: WEBSOCKET_REASONS.BUSY
});
sinon.assert.calledOnce(dispatcher.dispatch);
sinon.assert.calledWithExactly(dispatcher.dispatch,
new sharedActions.ConnectionFailure({
reason: FAILURE_DETAILS.USER_UNAVAILABLE
}));
});
it("should dispatch an action with user unavailable if the websocket reports reject", function() {
store._websocket.trigger("progress", {
state: WS_STATES.TERMINATED,
reason: WEBSOCKET_REASONS.REJECT
});
sinon.assert.calledOnce(dispatcher.dispatch);
sinon.assert.calledWithExactly(dispatcher.dispatch,
new sharedActions.ConnectionFailure({
reason: FAILURE_DETAILS.USER_UNAVAILABLE
}));
});
});
});
});

View File

@ -48,6 +48,58 @@ var fakeRooms = [
{ "displayName": "Alexis", "account": "alexis@example.com", "roomConnectionId": "2a1787a6-4a73-43b5-ae3e-906ec1e763cb" },
{ "displayName": "Adam", "roomConnectionId": "781f012b-f1ea-4ce1-9105-7cfc36fb4ec7" }
]
},
{
"roomToken": "REJRFfkdfkf",
"decryptedContext": {
"roomName": "Third Room Name"
},
"roomUrl": "http://localhost:3000/rooms/REJRFfkdfkf",
"roomOwner": "Alexis",
"maxSize": 2,
"creationTime": 1405537485,
"ctime": 1405537485,
"expiresAt": 1405554180,
"participants": []
},
{
"roomToken": "fjdkreFJDer",
"decryptedContext": {
"roomName": "Forth Room Name"
},
"roomUrl": "http://localhost:3000/rooms/fjdkreFJDer",
"roomOwner": "Alexis",
"maxSize": 2,
"creationTime": 1405546564,
"ctime": 1405546564,
"expiresAt": 1405564180,
"participants": []
},
{
"roomToken": "preFDREJhdf",
"decryptedContext": {
"roomName": "Fifth Room Name"
},
"roomUrl": "http://localhost:3000/rooms/preFDREJhdf",
"roomOwner": "Alexis",
"maxSize": 2,
"creationTime": 1405566934,
"ctime": 1405566934,
"expiresAt": 1405584180,
"participants": []
},
{
"roomToken": "preFLighdf",
"decryptedContext": {
"roomName": "Sixth Room Name"
},
"roomUrl": "http://localhost:3000/rooms/preFLighdf",
"roomOwner": "Alexis",
"maxSize": 2,
"creationTime": 1405576934,
"ctime": 1405576934,
"expiresAt": 1405614180,
"participants": []
}
];

View File

@ -44,6 +44,7 @@
// Store constants
var ROOM_STATES = loop.store.ROOM_STATES;
var CALL_TYPES = loop.shared.utils.CALL_TYPES;
var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES;
// Local helpers
function returnTrue() {
@ -446,6 +447,12 @@
callback(null, []);
};
var mockMozLoopNoRoomsNoContext = _.cloneDeep(navigator.mozLoop);
mockMozLoopNoRoomsNoContext.getSelectedTabMetadata = function(){};
mockMozLoopNoRoomsNoContext.rooms.getAll = function(version, callback) {
callback(null, []);
};
var roomStoreNoRooms = new loop.store.RoomStore(new loop.Dispatcher(), {
mozLoop: mockMozLoopNoRooms,
activeRoomStore: new loop.store.ActiveRoomStore(new loop.Dispatcher(), {
@ -454,12 +461,29 @@
})
});
/* xxx this is asynchronous - if start seeing things pending then this is the culprit */
roomStoreNoRooms.setStoreState({
pendingInitialRetrieval: false
});
var roomStoreNoRoomsPending = new loop.store.RoomStore(new loop.Dispatcher(), {
mozLoop: mockMozLoopNoRooms,
activeRoomStore: new loop.store.ActiveRoomStore(new loop.Dispatcher(), {
mozLoop: mockMozLoopNoRooms,
sdkDriver: mockSDK
})
});
var mockMozLoopLoggedIn = _.cloneDeep(navigator.mozLoop);
mockMozLoopLoggedIn.userProfile = {
email: "text@example.com",
uid: "0354b278a381d3cb408bb46ffc01266"
};
var mockMozLoopLoggedInNoContext = _.cloneDeep(navigator.mozLoop);
mockMozLoopLoggedInNoContext.getSelectedTabMetadata = function(){};
mockMozLoopLoggedInNoContext.userProfile = _.cloneDeep(mockMozLoopLoggedIn.userProfile);
var mockMozLoopLoggedInLongEmail = _.cloneDeep(navigator.mozLoop);
mockMozLoopLoggedInLongEmail.userProfile = {
email: "reallyreallylongtext@example.com",
@ -723,8 +747,8 @@
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
dashed: true,
height: 410,
summary: "Re-sign-in view",
width: 332},
summary: "First time experience view",
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
@ -749,7 +773,7 @@
dashed: true,
height: 410,
summary: "Room list tab",
width: 332},
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
@ -760,11 +784,26 @@
)
),
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
dashed: true,
height: 410,
summary: "Room list tab (No Context)",
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
mozLoop: mockMozLoopLoggedInNoContext,
notifications: notifications,
roomStore: roomStore,
selectedTab: "rooms"})
)
),
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
dashed: true,
height: 410,
summary: "Room list tab (no rooms)",
width: 332},
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
@ -775,11 +814,41 @@
)
),
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
dashed: true,
height: 410,
summary: "Room list tab (no rooms and no context)",
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
mozLoop: mockMozLoopNoRoomsNoContext,
notifications: notifications,
roomStore: roomStoreNoRooms,
selectedTab: "rooms"})
)
),
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
dashed: true,
height: 410,
summary: "Room list tab (loading view)",
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
mozLoop: mockMozLoopNoRoomsNoContext,
notifications: notifications,
roomStore: roomStoreNoRoomsPending,
selectedTab: "rooms"})
)
),
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
dashed: true,
height: 410,
summary: "Contact list tab",
width: 332},
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
@ -807,7 +876,7 @@
dashed: true,
height: 410,
summary: "Contact list tab long email",
width: 332},
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
@ -821,7 +890,7 @@
dashed: true,
height: 410,
summary: "Contact list tab (no contacts)",
width: 332},
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
@ -835,7 +904,7 @@
dashed: true,
height: 410,
summary: "Error Notification",
width: 332},
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
@ -848,7 +917,7 @@
dashed: true,
height: 410,
summary: "Error Notification - authenticated",
width: 332},
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
@ -861,7 +930,7 @@
dashed: true,
height: 410,
summary: "Contact import success",
width: 332},
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {dispatcher: dispatcher,
mozLoop: mockMozLoopLoggedIn,
@ -874,7 +943,7 @@
dashed: true,
height: 410,
summary: "Contact import error",
width: 332},
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {dispatcher: dispatcher,
mozLoop: mockMozLoopLoggedIn,
@ -887,7 +956,7 @@
dashed: true,
height: 410,
summary: "Contact Form - Add",
width: 332},
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
@ -901,14 +970,18 @@
),
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
dashed: true,
height: 321,
height: 410,
summary: "Contact Form - Edit",
width: 332},
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(ContactDetailsForm, {contactFormData: fakeManyContacts[1],
mode: "edit",
mozLoop: mockMozLoopLoggedIn,
switchToInitialView: noop})
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
initialSelectedTabComponent: "contactEdit",
mozLoop: mockMozLoopLoggedIn,
notifications: notifications,
roomStore: roomStore,
selectedTab: "contacts",
userProfile: {email: "test@example.com"}})
)
)
),
@ -941,9 +1014,9 @@
React.createElement(Section, {name: "ContactDetail"},
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
dashed: true,
height: 272,
height: 50,
summary: "ContactDetail",
width: 300},
width: 334},
React.createElement("div", {className: "panel force-menu-show"},
React.createElement(ContactDetail, {contact: fakeManyContacts[0],
handleContactAction: function() {}})
@ -1025,32 +1098,38 @@
width: 300},
React.createElement("div", {className: "fx-embedded"},
React.createElement(ConversationToolbar, {audio: { enabled: true, visible: true},
dispatcher: dispatcher,
hangup: noop,
publishStream: noop,
screenShare: { state: SCREEN_SHARE_STATES.INACTIVE, visible: true},
settingsMenuItems: [{ id: "feedback" }],
video: { enabled: true, visible: true}})
)
),
React.createElement(FramedExample, {dashed: true,
height: 56,
summary: "Video muted",
summary: "Video muted, Screen share pending",
width: 300},
React.createElement("div", {className: "fx-embedded"},
React.createElement(ConversationToolbar, {audio: { enabled: true, visible: true},
dispatcher: dispatcher,
hangup: noop,
publishStream: noop,
screenShare: { state: SCREEN_SHARE_STATES.PENDING, visible: true},
settingsMenuItems: [{ id: "feedback" }],
video: { enabled: false, visible: true}})
)
),
React.createElement(FramedExample, {dashed: true,
height: 56,
summary: "Audio muted",
summary: "Audio muted, Screen share active",
width: 300},
React.createElement("div", {className: "fx-embedded"},
React.createElement(ConversationToolbar, {audio: { enabled: false, visible: true},
dispatcher: dispatcher,
hangup: noop,
publishStream: noop,
screenShare: { state: SCREEN_SHARE_STATES.ACTIVE, visible: true},
settingsMenuItems: [{ id: "feedback" }],
video: { enabled: true, visible: true}})
)
@ -1662,7 +1741,7 @@
};
try {
React.renderComponent(React.createElement(App, null), document.getElementById("main"));
React.render(React.createElement(App, null), document.getElementById("main"));
for (var listener of visibilityListeners) {
listener({target: {hidden: false}});
@ -1683,7 +1762,7 @@
// This simulates the mocha layout for errors which means we can run
// this alongside our other unit tests but use the same harness.
var expectedWarningsCount = 10;
var expectedWarningsCount = 3;
var warningsMismatch = caughtWarnings.length !== expectedWarningsCount;
var resultsElement = document.querySelector("#results");
var divFailuresNode = document.createElement("div");

View File

@ -44,6 +44,7 @@
// Store constants
var ROOM_STATES = loop.store.ROOM_STATES;
var CALL_TYPES = loop.shared.utils.CALL_TYPES;
var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES;
// Local helpers
function returnTrue() {
@ -446,6 +447,12 @@
callback(null, []);
};
var mockMozLoopNoRoomsNoContext = _.cloneDeep(navigator.mozLoop);
mockMozLoopNoRoomsNoContext.getSelectedTabMetadata = function(){};
mockMozLoopNoRoomsNoContext.rooms.getAll = function(version, callback) {
callback(null, []);
};
var roomStoreNoRooms = new loop.store.RoomStore(new loop.Dispatcher(), {
mozLoop: mockMozLoopNoRooms,
activeRoomStore: new loop.store.ActiveRoomStore(new loop.Dispatcher(), {
@ -454,12 +461,29 @@
})
});
/* xxx this is asynchronous - if start seeing things pending then this is the culprit */
roomStoreNoRooms.setStoreState({
pendingInitialRetrieval: false
});
var roomStoreNoRoomsPending = new loop.store.RoomStore(new loop.Dispatcher(), {
mozLoop: mockMozLoopNoRooms,
activeRoomStore: new loop.store.ActiveRoomStore(new loop.Dispatcher(), {
mozLoop: mockMozLoopNoRooms,
sdkDriver: mockSDK
})
});
var mockMozLoopLoggedIn = _.cloneDeep(navigator.mozLoop);
mockMozLoopLoggedIn.userProfile = {
email: "text@example.com",
uid: "0354b278a381d3cb408bb46ffc01266"
};
var mockMozLoopLoggedInNoContext = _.cloneDeep(navigator.mozLoop);
mockMozLoopLoggedInNoContext.getSelectedTabMetadata = function(){};
mockMozLoopLoggedInNoContext.userProfile = _.cloneDeep(mockMozLoopLoggedIn.userProfile);
var mockMozLoopLoggedInLongEmail = _.cloneDeep(navigator.mozLoop);
mockMozLoopLoggedInLongEmail.userProfile = {
email: "reallyreallylongtext@example.com",
@ -723,8 +747,8 @@
<FramedExample cssClass="fx-embedded-panel"
dashed={true}
height={410}
summary="Re-sign-in view"
width={332}>
summary="First time experience view"
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
@ -749,7 +773,7 @@
dashed={true}
height={410}
summary="Room list tab"
width={332}>
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
@ -760,11 +784,26 @@
</div>
</FramedExample>
<FramedExample cssClass="fx-embedded-panel"
dashed={true}
height={410}
summary="Room list tab (No Context)"
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
mozLoop={mockMozLoopLoggedInNoContext}
notifications={notifications}
roomStore={roomStore}
selectedTab="rooms" />
</div>
</FramedExample>
<FramedExample cssClass="fx-embedded-panel"
dashed={true}
height={410}
summary="Room list tab (no rooms)"
width={332}>
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
@ -775,11 +814,41 @@
</div>
</FramedExample>
<FramedExample cssClass="fx-embedded-panel"
dashed={true}
height={410}
summary="Room list tab (no rooms and no context)"
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
mozLoop={mockMozLoopNoRoomsNoContext}
notifications={notifications}
roomStore={roomStoreNoRooms}
selectedTab="rooms" />
</div>
</FramedExample>
<FramedExample cssClass="fx-embedded-panel"
dashed={true}
height={410}
summary="Room list tab (loading view)"
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
mozLoop={mockMozLoopNoRoomsNoContext}
notifications={notifications}
roomStore={roomStoreNoRoomsPending}
selectedTab="rooms" />
</div>
</FramedExample>
<FramedExample cssClass="fx-embedded-panel"
dashed={true}
height={410}
summary="Contact list tab"
width={332}>
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
@ -807,7 +876,7 @@
dashed={true}
height={410}
summary="Contact list tab long email"
width={332}>
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
@ -821,7 +890,7 @@
dashed={true}
height={410}
summary="Contact list tab (no contacts)"
width={332}>
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
@ -835,7 +904,7 @@
dashed={true}
height={410}
summary="Error Notification"
width={332}>
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
@ -848,7 +917,7 @@
dashed={true}
height={410}
summary="Error Notification - authenticated"
width={332}>
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
@ -861,7 +930,7 @@
dashed={true}
height={410}
summary="Contact import success"
width={332}>
width={330}>
<div className="panel">
<PanelView dispatcher={dispatcher}
mozLoop={mockMozLoopLoggedIn}
@ -874,7 +943,7 @@
dashed={true}
height={410}
summary="Contact import error"
width={332}>
width={330}>
<div className="panel">
<PanelView dispatcher={dispatcher}
mozLoop={mockMozLoopLoggedIn}
@ -887,7 +956,7 @@
dashed={true}
height={410}
summary="Contact Form - Add"
width={332}>
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
@ -901,14 +970,18 @@
</FramedExample>
<FramedExample cssClass="fx-embedded-panel"
dashed={true}
height={321}
height={410}
summary="Contact Form - Edit"
width={332}>
width={330}>
<div className="panel">
<ContactDetailsForm contactFormData={fakeManyContacts[1]}
mode={"edit"}
mozLoop={mockMozLoopLoggedIn}
switchToInitialView={noop} />
<PanelView client={mockClient}
dispatcher={dispatcher}
initialSelectedTabComponent="contactEdit"
mozLoop={mockMozLoopLoggedIn}
notifications={notifications}
roomStore={roomStore}
selectedTab="contacts"
userProfile={{email: "test@example.com"}} />
</div>
</FramedExample>
</Section>
@ -941,9 +1014,9 @@
<Section name="ContactDetail">
<FramedExample cssClass="fx-embedded-panel"
dashed={true}
height={272}
height={50}
summary="ContactDetail"
width={300}>
width={334}>
<div className="panel force-menu-show">
<ContactDetail contact={fakeManyContacts[0]}
handleContactAction={function() {}} />
@ -1025,32 +1098,38 @@
width={300}>
<div className="fx-embedded">
<ConversationToolbar audio={{ enabled: true, visible: true }}
dispatcher={dispatcher}
hangup={noop}
publishStream={noop}
screenShare={{ state: SCREEN_SHARE_STATES.INACTIVE, visible: true }}
settingsMenuItems={[{ id: "feedback" }]}
video={{ enabled: true, visible: true }} />
</div>
</FramedExample>
<FramedExample dashed={true}
height={56}
summary="Video muted"
summary="Video muted, Screen share pending"
width={300}>
<div className="fx-embedded">
<ConversationToolbar audio={{ enabled: true, visible: true }}
dispatcher={dispatcher}
hangup={noop}
publishStream={noop}
screenShare={{ state: SCREEN_SHARE_STATES.PENDING, visible: true }}
settingsMenuItems={[{ id: "feedback" }]}
video={{ enabled: false, visible: true }} />
</div>
</FramedExample>
<FramedExample dashed={true}
height={56}
summary="Audio muted"
summary="Audio muted, Screen share active"
width={300}>
<div className="fx-embedded">
<ConversationToolbar audio={{ enabled: false, visible: true }}
dispatcher={dispatcher}
hangup={noop}
publishStream={noop}
screenShare={{ state: SCREEN_SHARE_STATES.ACTIVE, visible: true }}
settingsMenuItems={[{ id: "feedback" }]}
video={{ enabled: true, visible: true }} />
</div>
@ -1662,7 +1741,7 @@
};
try {
React.renderComponent(<App />, document.getElementById("main"));
React.render(<App />, document.getElementById("main"));
for (var listener of visibilityListeners) {
listener({target: {hidden: false}});
@ -1683,7 +1762,7 @@
// This simulates the mocha layout for errors which means we can run
// this alongside our other unit tests but use the same harness.
var expectedWarningsCount = 10;
var expectedWarningsCount = 3;
var warningsMismatch = caughtWarnings.length !== expectedWarningsCount;
var resultsElement = document.querySelector("#results");
var divFailuresNode = document.createElement("div");

View File

@ -56,7 +56,8 @@ nsEdgeReadingListExtractor::Extract(const nsAString& aDBPath, nsIArray** aItems)
// Check for the right page size and initialize with that
unsigned long pageSize;
err = JetGetDatabaseFileInfoW(aDBPath.BeginReading(), &pageSize, sizeof(pageSize), JET_DbInfoPageSize);
err = JetGetDatabaseFileInfoW(static_cast<char16ptr_t>(aDBPath.BeginReading()),
&pageSize, sizeof(pageSize), JET_DbInfoPageSize);
NS_HANDLE_JET_ERROR(err)
err = JetSetSystemParameter(&instance, NULL, JET_paramDatabasePageSize, pageSize, NULL);
NS_HANDLE_JET_ERROR(err)
@ -79,10 +80,12 @@ nsEdgeReadingListExtractor::Extract(const nsAString& aDBPath, nsIArray** aItems)
sessionCreated = true;
// Actually open the DB, and make sure to do so readonly:
err = JetAttachDatabaseW(sesid, aDBPath.BeginReading(), JET_bitDbReadOnly);
err = JetAttachDatabaseW(sesid, static_cast<char16ptr_t>(aDBPath.BeginReading()),
JET_bitDbReadOnly);
NS_HANDLE_JET_ERROR(err)
dbOpened = true;
err = JetOpenDatabaseW(sesid, aDBPath.BeginReading(), NULL, &dbid, JET_bitDbReadOnly);
err = JetOpenDatabaseW(sesid, static_cast<char16ptr_t>(aDBPath.BeginReading()),
NULL, &dbid, JET_bitDbReadOnly);
NS_HANDLE_JET_ERROR(err)
// Open the readinglist table and get information on the columns we are interested in:

View File

@ -43,6 +43,7 @@
label="&performanceUI.enableMemory;"
tooltiptext="&performanceUI.enableMemory.tooltiptext;"/>
<menuitem id="option-enable-allocations"
class="experimental-option"
type="checkbox"
data-pref="enable-allocations"
label="&performanceUI.enableAllocations;"

View File

@ -12,6 +12,7 @@
#include "BluetoothUuid.h"
#include "ObexBase.h"
#include "mozilla/dom/BluetoothPbapParametersBinding.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/RefPtr.h"
@ -527,29 +528,26 @@ BluetoothPbapManager::AppendBtNamedValueByTagId(
const AppParameterTag aTagId)
{
uint8_t buf[64];
if (!aHeader.GetAppParameter(aTagId, buf, 64)) {
return;
}
switch (aTagId) {
case AppParameterTag::Order: {
if (!aHeader.GetAppParameter(AppParameterTag::Order, buf, 64)) {
break;
}
static const nsString sOrderStr[] = {NS_LITERAL_STRING("alphanumeric"),
NS_LITERAL_STRING("indexed"),
NS_LITERAL_STRING("phonetical")};
uint8_t order = buf[0];
if (order < MOZ_ARRAY_LENGTH(sOrderStr)) {
BT_APPEND_NAMED_VALUE(aValues, "order", sOrderStr[order]);
} else {
BT_LOGR("Unexpected value %d of 'Order'", order);
}
using namespace mozilla::dom::vCardOrderTypeValues;
uint32_t order = buf[0] < ArrayLength(strings) ? (uint32_t) buf[0]
: 0; // default: indexed
BT_APPEND_NAMED_VALUE(aValues, "order", order);
break;
}
case AppParameterTag::SearchProperty: {
using namespace mozilla::dom::vCardSearchKeyTypeValues;
uint32_t searchKey = buf[0] < ArrayLength(strings) ? (uint32_t) buf[0]
: 0; // default: name
BT_APPEND_NAMED_VALUE(aValues, "searchKey", searchKey);
break;
}
case AppParameterTag::SearchValue: {
if (!aHeader.GetAppParameter(AppParameterTag::SearchValue, buf, 64)) {
break;
}
// Section 5.3.4.3 "SearchValue {<text string>}", PBAP 1.2
// The UTF-8 character set shall be used for <text string>.
@ -560,27 +558,7 @@ BluetoothPbapManager::AppendBtNamedValueByTagId(
BT_APPEND_NAMED_VALUE(aValues, "searchText", text);
break;
}
case AppParameterTag::SearchProperty: {
if (!aHeader.GetAppParameter(AppParameterTag::SearchProperty, buf, 64)) {
break;
}
static const nsString sSearchKeyStr[] = {NS_LITERAL_STRING("name"),
NS_LITERAL_STRING("number"),
NS_LITERAL_STRING("sound")};
uint8_t searchKey = buf[0];
if (searchKey < MOZ_ARRAY_LENGTH(sSearchKeyStr)) {
BT_APPEND_NAMED_VALUE(aValues, "searchKey", sSearchKeyStr[searchKey]);
} else {
BT_LOGR("Unexpected value %d of 'SearchProperty'", searchKey);
}
break;
}
case AppParameterTag::MaxListCount: {
if (!aHeader.GetAppParameter(AppParameterTag::MaxListCount, buf, 64)) {
break;
}
uint16_t maxListCount = *((uint16_t *)buf);
// convert big endian to little endian
@ -595,10 +573,6 @@ BluetoothPbapManager::AppendBtNamedValueByTagId(
break;
}
case AppParameterTag::ListStartOffset: {
if (!aHeader.GetAppParameter(AppParameterTag::ListStartOffset, buf, 64)) {
break;
}
uint16_t listStartOffset = *((uint16_t *)buf);
// convert big endian to little endian
@ -609,30 +583,17 @@ BluetoothPbapManager::AppendBtNamedValueByTagId(
break;
}
case AppParameterTag::PropertySelector: {
if (!aHeader.GetAppParameter(
AppParameterTag::PropertySelector, buf, 64)) {
break;
}
InfallibleTArray<uint32_t> props = PackPropertiesMask(buf, 64);
BT_APPEND_NAMED_VALUE(aValues, "propSelector", props);
break;
}
case AppParameterTag::Format: {
if (!aHeader.GetAppParameter(AppParameterTag::Format, buf, 64)) {
break;
}
bool usevCard3 = buf[0];
BT_APPEND_NAMED_VALUE(aValues, "format", usevCard3);
break;
}
case AppParameterTag::vCardSelector: {
if (!aHeader.GetAppParameter(AppParameterTag::vCardSelector, buf, 64)) {
break;
}
InfallibleTArray<uint32_t> props = PackPropertiesMask(buf, 64);
bool hasVCardSelectorOperator = aHeader.GetAppParameter(

View File

@ -1295,11 +1295,11 @@ BluetoothAdapter::HandlePullVCardListingReq(const BluetoothValue& aValue)
if (name.EqualsLiteral("name")) {
init.mName = value.get_nsString();
} else if (name.EqualsLiteral("order")) {
init.mOrder = ConvertStringToVCardOrderType(value.get_nsString());
init.mOrder = static_cast<vCardOrderType>(value.get_uint32_t());
} else if (name.EqualsLiteral("searchKey")) {
init.mSearchKey = static_cast<vCardSearchKeyType>(value.get_uint32_t());
} else if (name.EqualsLiteral("searchText")) {
init.mSearchValue = value.get_nsString();
} else if (name.EqualsLiteral("searchKey")) {
init.mSearchKey = ConvertStringToVCardSearchKeyType(value.get_nsString());
} else if (name.EqualsLiteral("maxListCount")) {
init.mMaxListCount = value.get_uint32_t();
} else if (name.EqualsLiteral("listStartOffset")) {
@ -1338,40 +1338,6 @@ BluetoothAdapter::getVCardProperties(const BluetoothValue &aValue)
return propSelector;
}
vCardOrderType
BluetoothAdapter::ConvertStringToVCardOrderType(const nsAString& aString)
{
using namespace mozilla::dom::vCardOrderTypeValues;
for (size_t index = 0; index < ArrayLength(strings) - 1; index++) {
if (aString.LowerCaseEqualsASCII(strings[index].value,
strings[index].length)) {
return static_cast<vCardOrderType>(index);
}
}
BT_WARNING("Treat the unexpected string '%s' as vCardOrderType::Indexed",
NS_ConvertUTF16toUTF8(aString).get());
return vCardOrderType::Indexed; // The default value is 'Indexed'.
}
vCardSearchKeyType
BluetoothAdapter::ConvertStringToVCardSearchKeyType(const nsAString& aString)
{
using namespace mozilla::dom::vCardSearchKeyTypeValues;
for (size_t index = 0; index < ArrayLength(strings) - 1; index++) {
if (aString.LowerCaseEqualsASCII(strings[index].value,
strings[index].length)) {
return static_cast<vCardSearchKeyType>(index);
}
}
BT_WARNING("Treat the unexpected string '%s' as vCardSearchKeyType::Name",
NS_ConvertUTF16toUTF8(aString).get());
return vCardSearchKeyType::Name; // The default value is 'Name'.
}
void
BluetoothAdapter::DispatchAttributeEvent(const Sequence<nsString>& aTypes)
{

View File

@ -342,21 +342,6 @@ private:
*/
Sequence<vCardProperties> getVCardProperties(const BluetoothValue &aValue);
/**
* Convert string to vCardOrderType.
*
* @param aString [in] String to convert
*/
vCardOrderType ConvertStringToVCardOrderType(const nsAString& aString);
/**
* Convert string to vCardSearchKeyType.
*
* @param aString [in] String to convert
*/
vCardSearchKeyType ConvertStringToVCardSearchKeyType(
const nsAString& aString);
/**
* Fire BluetoothAttributeEvent to trigger onattributechanged event handler.
*

View File

@ -49,8 +49,8 @@ enum vCardProperties
* objects.
*/
enum vCardOrderType {
"alphabetical",
"indexed", // default
"alphabetical",
"phonetical"
};

View File

@ -25,6 +25,7 @@ interface TreeColumn {
const short TYPE_TEXT = 1;
const short TYPE_CHECKBOX = 2;
const short TYPE_PROGRESSMETER = 3;
const short TYPE_PASSWORD = 4;
readonly attribute short type;
TreeColumn? getNext();

View File

@ -358,7 +358,12 @@ nsXULTooltipListener::CheckTreeBodyMove(nsIDOMMouseEvent* aMouseEvent)
// determine if we are going to need a titletip
// XXX check the disabletitletips attribute on the tree content
mNeedTitletip = false;
if (row >= 0 && obj.EqualsLiteral("text")) {
int16_t colType = -1;
if (col) {
col->GetType(&colType);
}
if (row >= 0 && obj.EqualsLiteral("text") &&
colType != nsITreeColumn::TYPE_PASSWORD) {
obx->IsCellCropped(row, col, &mNeedTitletip);
}

View File

@ -32,6 +32,7 @@ interface nsITreeColumn : nsISupports
const short TYPE_TEXT = 1;
const short TYPE_CHECKBOX = 2;
const short TYPE_PROGRESSMETER = 3;
const short TYPE_PASSWORD = 4;
readonly attribute short type;
nsITreeColumn getNext();

View File

@ -64,6 +64,7 @@
#include "nsIScriptableRegion.h"
#include <algorithm>
#include "ScrollbarActivity.h"
#include "../../editor/libeditor/nsTextEditRules.h"
#ifdef ACCESSIBILITY
#include "nsAccessibilityService.h"
@ -3309,6 +3310,7 @@ nsTreeBodyFrame::PaintCell(int32_t aRowIndex,
if (dirtyRect.IntersectRect(aDirtyRect, elementRect)) {
switch (aColumn->GetType()) {
case nsITreeColumn::TYPE_TEXT:
case nsITreeColumn::TYPE_PASSWORD:
PaintText(aRowIndex, aColumn, elementRect, aPresContext, aRenderingContext, aDirtyRect, currX);
break;
case nsITreeColumn::TYPE_CHECKBOX:
@ -3595,6 +3597,11 @@ nsTreeBodyFrame::PaintText(int32_t aRowIndex,
// Now obtain the text for our cell.
nsAutoString text;
mView->GetCellText(aRowIndex, aColumn, text);
if (aColumn->Type() == nsITreeColumn::TYPE_PASSWORD) {
nsTextEditRules::FillBufWithPWChars(&text, text.Length());
}
// We're going to paint this text so we need to ensure bidi is enabled if
// necessary
CheckTextForBidi(text);

View File

@ -321,11 +321,13 @@ nsTreeColumn::Invalidate()
// Figure out our column type. Default type is text.
mType = nsITreeColumn::TYPE_TEXT;
static nsIContent::AttrValuesArray typestrings[] =
{&nsGkAtoms::checkbox, &nsGkAtoms::progressmeter, nullptr};
{&nsGkAtoms::checkbox, &nsGkAtoms::progressmeter, &nsGkAtoms::password,
nullptr};
switch (mContent->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::type,
typestrings, eCaseMatters)) {
case 0: mType = nsITreeColumn::TYPE_CHECKBOX; break;
case 1: mType = nsITreeColumn::TYPE_PROGRESSMETER; break;
case 2: mType = nsITreeColumn::TYPE_PASSWORD; break;
}
// Fetch the crop style.

View File

@ -348,10 +348,15 @@ public class ShareDialog extends Locales.LocaleAwareActivity implements SendTabT
@Override
public void finish() {
super.finish();
finish(true);
}
// Don't perform an activity-dismiss animation.
overridePendingTransition(0, 0);
private void finish(final boolean shouldOverrideAnimations) {
super.finish();
if (shouldOverrideAnimations) {
// Don't perform an activity-dismiss animation.
overridePendingTransition(0, 0);
}
}
/*
@ -413,7 +418,8 @@ public class ShareDialog extends Locales.LocaleAwareActivity implements SendTabT
} catch (URISyntaxException e) {
// Nothing much we can do.
} finally {
slideOut();
// Since we're changing apps, users expect the default app switch animations.
finish(false);
}
}

View File

@ -23,7 +23,9 @@ import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.UUID;
import java.util.zip.CRC32;
import org.json.JSONException;
import org.json.JSONObject;
@ -188,8 +190,18 @@ public class SwitchBoard {
String device = Build.DEVICE;
String manufacturer = Build.MANUFACTURER;
String lang = Locale.getDefault().getISO3Language();
String country = Locale.getDefault().getISO3Country();
String lang = "unknown";
try {
lang = Locale.getDefault().getISO3Language();
} catch (MissingResourceException e) {
e.printStackTrace();
}
String country = "unknown";
try {
country = Locale.getDefault().getISO3Country();
} catch (MissingResourceException e) {
e.printStackTrace();
}
String packageName = c.getPackageName();
String versionName = "none";
try {
@ -218,7 +230,15 @@ public class SwitchBoard {
e.printStackTrace();
}
}
public static boolean isInBucket(Context c, int low, int high) {
int userBucket = getUserBucket(c);
if (userBucket >= low && userBucket < high)
return true;
else
return false;
}
/**
* Looks up in config if user is in certain experiment. Returns false as a default value when experiment
* does not exist.
@ -370,4 +390,18 @@ public class SwitchBoard {
return null;
}
/**
* Return the bucket number of the user. There are 100 possible buckets.
*/
private static int getUserBucket(Context c) {
//get uuid
DeviceUuidFactory df = new DeviceUuidFactory(c);
String uuid = df.getDeviceUuid().toString();
CRC32 crc = new CRC32();
crc.update(uuid.getBytes());
long checksum = crc.getValue();
return (int)(checksum % 100L);
}
}

View File

@ -4244,6 +4244,11 @@
"kind": "count",
"description": "Windows 10+ only: The number of times tablet-mode is used during a session"
},
"FX_TOUCH_USED": {
"expires_in_version": "46",
"kind": "count",
"description": "Windows only. Counts occurrences of touch events"
},
"FX_URLBAR_SELECTED_RESULT_INDEX": {
"expires_in_version": "45",
"kind": "enumerated",

View File

@ -341,8 +341,10 @@
return false;
if (row < 0 || row >= this.view.rowCount || !column)
return false;
if (column.type != Components.interfaces.nsITreeColumn.TYPE_TEXT ||
column.cycler || !this.view.isEditable(row, column))
if (column.type != Components.interfaces.nsITreeColumn.TYPE_TEXT &&
column.type != Components.interfaces.nsITreeColumn.TYPE_PASSWORD)
return false;
if (column.cycler || !this.view.isEditable(row, column))
return false;
// Beyond this point, we are going to edit the cell.

View File

@ -188,6 +188,8 @@
#include "mozilla/layers/InputAPZContext.h"
#include "InputData.h"
#include "mozilla/Telemetry.h"
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::gfx;
@ -4007,12 +4009,18 @@ nsWindow::DispatchMouseEvent(EventMessage aEventMessage, WPARAM wParam,
return result;
}
if (mTouchWindow && WinUtils::GetIsMouseFromTouch(aEventMessage)) {
// If mTouchWindow is true, then we must have APZ enabled and be
// feeding it raw touch events. In that case we don't need to
// send touch-generated mouse events to content.
MOZ_ASSERT(mAPZC);
return result;
if (WinUtils::GetIsMouseFromTouch(aEventMessage)) {
if (aEventMessage == eMouseDown) {
Telemetry::Accumulate(Telemetry::FX_TOUCH_USED, 1);
}
if (mTouchWindow) {
// If mTouchWindow is true, then we must have APZ enabled and be
// feeding it raw touch events. In that case we don't need to
// send touch-generated mouse events to content.
MOZ_ASSERT(mAPZC);
return result;
}
}
// Since it is unclear whether a user will use the digitizer,