Release Vulpes OS 2.7-preview.24
This commit is contained in:
parent
49572b6b45
commit
97ef99f827
135 changed files with 7717 additions and 2524 deletions
|
|
@ -475,20 +475,25 @@
|
|||
}
|
||||
}
|
||||
|
||||
// Set the .icon property before saving for
|
||||
// backwards compatibility with verticalhome
|
||||
// Set the .icon property before saving for backwards compatibility with
|
||||
// verticalhome. A missing favicon must not prevent pinning the site.
|
||||
var saveSite = function(icon) {
|
||||
siteObject.icon = icon || '';
|
||||
BookmarksDatabase.put(siteObject, siteObject.id)
|
||||
.then(() => {
|
||||
this.app.debug('pinSite: ' + siteObject.id);
|
||||
this.systemBanner.show('site-pinned-to-home-screen');
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('pinSite, Failed to pin site: ' + error);
|
||||
});
|
||||
}.bind(this);
|
||||
|
||||
IconsHelper.getIcon(siteObject.url, null,
|
||||
{icons: this.app.favicons}, siteObject).then(icon => {
|
||||
siteObject.icon = icon;
|
||||
BookmarksDatabase.put(siteObject, siteObject.id)
|
||||
.then(() => {
|
||||
this.app.debug('pinSite: ' + siteObject.id);
|
||||
this.systemBanner.show('site-pinned-to-home-screen');
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('pinSite, Failed to pin site: ' + error);
|
||||
});
|
||||
});
|
||||
{icons: this.app.favicons}, siteObject).then(saveSite, function(error) {
|
||||
this.app.debug('pinSite: using no favicon: ' + error);
|
||||
saveSite('');
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -986,12 +991,14 @@
|
|||
return;
|
||||
}
|
||||
|
||||
// Enable/disable the bookmark option
|
||||
BookmarksDatabase.get(this._currentURL).then(function resolve(result) {
|
||||
// start_url is the bookmark key for installed web apps, while _currentURL
|
||||
// may be a later page in the app. Check the canonical key first.
|
||||
var siteUrl = this.getSiteUrl();
|
||||
BookmarksDatabase.get(siteUrl).then(function resolve(result) {
|
||||
this.addToHomeButton.hidden = !!result;
|
||||
}.bind(this),
|
||||
function reject() {
|
||||
this.addToHomeButton.hidden = true;
|
||||
this.addToHomeButton.hidden = false;
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -242,76 +242,29 @@
|
|||
div.dataset.zIndexLevel = 'poweroff-splash';
|
||||
div.id = 'poweroff-splash';
|
||||
|
||||
this.poweroffLogoLoader = new LogoLoader(this._poweroff);
|
||||
// Vulpes uses Gaia's three-ring shutdown animation without a carrier
|
||||
// image or video layered over it.
|
||||
var inner;
|
||||
for (var i = 1; i <= 3; i++) {
|
||||
var outer = document.createElement('span');
|
||||
outer.className = 'poweroff-ring';
|
||||
outer.id = 'poweroff-ring-' + i;
|
||||
div.appendChild(outer);
|
||||
inner = document.createElement('span');
|
||||
outer.appendChild(inner);
|
||||
}
|
||||
|
||||
this.poweroffLogoLoader.onload = function(elem) {
|
||||
// Perform customized animation.
|
||||
div.appendChild(elem);
|
||||
div.className = 'step1';
|
||||
|
||||
if (elem.tagName.toLowerCase() == 'video' && !elem.ended) {
|
||||
elem.onended = function() {
|
||||
elem.classList.add('hide');
|
||||
// XXX workaround of bug 831747
|
||||
// Unload the video. This releases the video decoding hardware
|
||||
// so other apps can use it.
|
||||
elem.removeAttribute('src');
|
||||
elem.load();
|
||||
};
|
||||
elem.play();
|
||||
} else {
|
||||
div.addEventListener('animationend', function() {
|
||||
elem.classList.add('hide');
|
||||
if (elem.tagName.toLowerCase() == 'video') {
|
||||
// XXX workaround of bug 831747
|
||||
// Unload the video. This releases the video decoding hardware
|
||||
// so other apps can use it.
|
||||
elem.removeAttribute('src');
|
||||
elem.load();
|
||||
}
|
||||
});
|
||||
div.className = 'step1';
|
||||
var nextAnimation = function nextAnimation(e) {
|
||||
if (e.target == div) {
|
||||
div.className = 'step2';
|
||||
}
|
||||
|
||||
elem.addEventListener('transitionend', function() {
|
||||
if (e.target == inner) {
|
||||
self._actualPowerOff(reboot);
|
||||
});
|
||||
document.getElementById('screen').appendChild(div);
|
||||
};
|
||||
|
||||
this.poweroffLogoLoader.onnotfound = function() {
|
||||
// - Perform OS default animation.
|
||||
|
||||
// The overall animation ends when the inner span of the bottom ring
|
||||
// is animated, so we store it for detecting.
|
||||
var inner;
|
||||
|
||||
for (var i = 1; i <= 3; i++) {
|
||||
var outer = document.createElement('span');
|
||||
outer.className = 'poweroff-ring';
|
||||
outer.id = 'poweroff-ring-' + i;
|
||||
div.appendChild(outer);
|
||||
|
||||
inner = document.createElement('span');
|
||||
outer.appendChild(inner);
|
||||
}
|
||||
|
||||
div.className = 'step1';
|
||||
var nextAnimation = function nextAnimation(e) {
|
||||
// Switch to next class
|
||||
if (e.target == div) {
|
||||
div.className = 'step2';
|
||||
}
|
||||
|
||||
if (e.target != inner) {
|
||||
return;
|
||||
}
|
||||
|
||||
self._actualPowerOff(reboot);
|
||||
};
|
||||
div.addEventListener('animationend', nextAnimation);
|
||||
|
||||
document.getElementById('screen').appendChild(div);
|
||||
};
|
||||
div.addEventListener('animationend', nextAnimation);
|
||||
document.getElementById('screen').appendChild(div);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -265,7 +265,8 @@
|
|||
// until it works. It may fail at the moment the screenchange
|
||||
// event has been fired, so we may need to try it several times.
|
||||
var tryLockOrientation = () => {
|
||||
if (screen.mozLockOrientation('portrait-primary')) {
|
||||
// Allow the lock screen to follow the physical display orientation.
|
||||
if (screen.mozLockOrientation('any')) {
|
||||
if (!this.orientationLockID) {
|
||||
throw new Error('No orientation ID. This function should only' +
|
||||
'be invoked as a interval callback');
|
||||
|
|
|
|||
|
|
@ -346,13 +346,26 @@
|
|||
|
||||
case this.fullApp:
|
||||
// XXX: This should be replaced probably by Web Activities
|
||||
var host = document.location.host;
|
||||
var domain = host.replace(/(^[\w\d]+\.)?([\w\d]+\.[a-z]+)/, '$2');
|
||||
var protocol = document.location.protocol + '//';
|
||||
applications.getByManifestURL(protocol + 'settings.' +
|
||||
domain + '/manifest.webapp').launch();
|
||||
|
||||
UtilityTray.hide();
|
||||
var settingsURL = new URL(document.location.href);
|
||||
if (settingsURL.hostname.indexOf('system.') !== 0) {
|
||||
console.error('Quick settings: cannot resolve Settings app host');
|
||||
return;
|
||||
}
|
||||
settingsURL.hostname = 'settings.' +
|
||||
settingsURL.hostname.slice('system.'.length);
|
||||
settingsURL.pathname = '/manifest.webapp';
|
||||
settingsURL.search = '';
|
||||
settingsURL.hash = '';
|
||||
applications.waitForReady().then(function() {
|
||||
var settingsApp = applications.getByManifestURL(
|
||||
settingsURL.href);
|
||||
if (!settingsApp) {
|
||||
console.error('Quick settings: Settings app is not installed');
|
||||
return;
|
||||
}
|
||||
settingsApp.launch();
|
||||
UtilityTray.hide();
|
||||
});
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -187,6 +187,15 @@
|
|||
},
|
||||
|
||||
hasPermission: function wf_hasPermission(app, permission) {
|
||||
// The embedded Gaia browser is the trusted system web client. Newer
|
||||
// Gecko builds no longer expose mozPermissionSettings to this code, so
|
||||
// honour its declared window permission and keep popup navigation in
|
||||
// Gaia instead of letting Gecko open a desktop browser window.
|
||||
if (app && app.manifest && app.manifest.role === 'search' &&
|
||||
permission === 'open-remote-window' && app.manifest.permissions &&
|
||||
app.manifest.permissions['open-remote-window']) {
|
||||
return true;
|
||||
}
|
||||
var mozPerms = navigator.mozPermissionSettings;
|
||||
if (!mozPerms) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@
|
|||
text-overflow: ellipsis;
|
||||
}
|
||||
#app-install-dialog p {
|
||||
font-size: 1.6rem;
|
||||
font-size: 1.4rem;
|
||||
font-weight: 400;
|
||||
line-height: normal;
|
||||
border-top: none;
|
||||
|
|
@ -79,7 +79,7 @@
|
|||
margin-top: 0;
|
||||
}
|
||||
#app-install-dialog span {
|
||||
font-size: 1.6rem;
|
||||
font-size: 1.4rem;
|
||||
font-weight: 400;
|
||||
line-height: normal;
|
||||
color: inherit;
|
||||
|
|
|
|||
|
|
@ -57,6 +57,6 @@
|
|||
#os-logo { background:#071d35; display:flex; flex-direction:column; align-items:center; justify-content:center; }
|
||||
#os-logo::before { content:""; width:min(42vw,190px); aspect-ratio:1; flex:none; background:url('/shared/resources/branding/vulpes-symbol.png') center / contain no-repeat; animation:vulpes-boot 2s ease-in-out infinite alternate; }
|
||||
#os-logo::after { content:"VULPES\A Firefox OS Community Project"; white-space:pre-line; padding:12px 22px; color:#f5f8fa; font:500 20px/1.8 FiraSans,sans-serif; text-align:center; }
|
||||
#poweroff-splash { background:#071d35 url('/shared/resources/branding/vulpes-symbol.png') center / 190px 190px no-repeat; }
|
||||
#poweroff-splash { background:#071d35; }
|
||||
@keyframes vulpes-boot { from {opacity:.75} to {opacity:1} }
|
||||
@media (prefers-reduced-motion: reduce) { #os-logo::before {animation:none} }
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ requireApp('system/shared/test/unit/mocks/mock_navigator_moz_settings.js');
|
|||
requireApp('system/shared/test/unit/mocks/mock_navigator_moz_power.js');
|
||||
|
||||
suite('CoverScreen >', function() {
|
||||
var settingsCore, realSettings, subject, realMozPower;
|
||||
var settingsCore, realSettings, subject, realMozPower, fakeScreen;
|
||||
const DEFAULT_VIDEO_ON = '/resources/power/carrier_power_on.mp4';
|
||||
const DEFAULT_VIDEO_OFF = '/resources/power/carrier_power_off.mp4';
|
||||
const DEFAULT_IMAGE_ON = '/resources/power/carrier_power_on.png';
|
||||
|
|
@ -113,6 +113,9 @@ suite('CoverScreen >', function() {
|
|||
var fakeElement = document.createElement('div');
|
||||
if (id === 'poweroff-splash') {
|
||||
return null;
|
||||
} else if (id === 'screen') {
|
||||
fakeScreen = fakeElement;
|
||||
return fakeScreen;
|
||||
} else {
|
||||
return fakeElement.cloneNode(true);
|
||||
}
|
||||
|
|
@ -135,10 +138,9 @@ suite('CoverScreen >', function() {
|
|||
test('restart requested', function() {
|
||||
var stub = this.sinon.stub(navigator.mozPower, 'reboot');
|
||||
subject.poweroff(true);
|
||||
var element = document.createElement('div');
|
||||
var transitionStub = this.sinon.stub(element, 'addEventListener');
|
||||
subject.poweroffLogoLoader.onload(element);
|
||||
transitionStub.getCall(0).args[1]();
|
||||
fakeScreen.lastChild.dispatchEvent(new Event('animationend'));
|
||||
fakeScreen.lastChild.querySelector('#poweroff-ring-3 > span')
|
||||
.dispatchEvent(new Event('animationend', { bubbles: true }));
|
||||
assert.ok(stub.calledOnce);
|
||||
});
|
||||
|
||||
|
|
@ -151,11 +153,9 @@ suite('CoverScreen >', function() {
|
|||
test('poweroff requested', function() {
|
||||
var stub = this.sinon.stub(navigator.mozPower, 'powerOff');
|
||||
subject.poweroff(false);
|
||||
|
||||
var element = document.createElement('div');
|
||||
var transitionStub = this.sinon.stub(element, 'addEventListener');
|
||||
subject.poweroffLogoLoader.onload(element);
|
||||
transitionStub.getCall(0).args[1]();
|
||||
fakeScreen.lastChild.dispatchEvent(new Event('animationend'));
|
||||
fakeScreen.lastChild.querySelector('#poweroff-ring-3 > span')
|
||||
.dispatchEvent(new Event('animationend', { bubbles: true }));
|
||||
assert.ok(stub.calledOnce);
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue