Bug 1133601 - Implement about:serviceworkers, r=ehsan

This commit is contained in:
Andrea Marchesini 2015-04-10 09:50:06 +01:00
parent 590d964eff
commit 81daef00e3
15 changed files with 376 additions and 1 deletions

View File

@ -103,6 +103,10 @@ static RedirEntry kRedirMap[] = {
"webrtc", "chrome://global/content/aboutwebrtc/aboutWebrtc.xhtml",
nsIAboutModule::ALLOW_SCRIPT
},
{
"serviceworkers", "chrome://global/content/aboutServiceWorkers.xhtml",
nsIAboutModule::ALLOW_SCRIPT
},
// about:srcdoc is unresolvable by specification. It is included here
// because the security manager would disallow srcdoc iframes otherwise.
{

View File

@ -175,6 +175,7 @@ const mozilla::Module::ContractIDEntry kDocShellContracts[] = {
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "networking", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "webrtc", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "srcdoc", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "serviceworkers", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_URI_LOADER_CONTRACTID, &kNS_URI_LOADER_CID },
{ NS_DOCUMENTLOADER_SERVICE_CONTRACTID, &kNS_DOCUMENTLOADER_SERVICE_CID },
{ NS_EXTERNALHELPERAPPSERVICE_CONTRACTID, &kNS_EXTERNALHELPERAPPSERVICE_CID },

View File

@ -5,6 +5,7 @@
#include "domstubs.idl"
interface nsIArray;
interface nsIDocument;
interface nsIInterceptedChannel;
interface nsIPrincipal;
@ -19,7 +20,20 @@ interface nsIServiceWorkerUnregisterCallback : nsISupports
[noscript] void UnregisterFailed();
};
[builtinclass, uuid(e4c8baa5-237a-4bf6-82d4-ea06eb4b76ba)]
[scriptable, builtinclass, uuid(8ce0d197-5740-4ddf-aa4a-e5a63e611d03)]
interface nsIServiceWorkerInfo : nsISupports
{
readonly attribute nsIPrincipal principal;
readonly attribute DOMString scope;
readonly attribute DOMString scriptSpec;
readonly attribute DOMString currentWorkerURL;
readonly attribute DOMString activeCacheName;
readonly attribute DOMString waitingCacheName;
};
[scriptable, builtinclass, uuid(861b55e9-d6ac-47cf-a528-8590e9b44de6)]
interface nsIServiceWorkerManager : nsISupports
{
/**
@ -103,6 +117,10 @@ interface nsIServiceWorkerManager : nsISupports
// Testing
DOMString getScopeForUrl(in DOMString path);
// This is meant to be used only by about:serviceworkers. It returns an array
// of nsIServiceWorkerInfo.
nsIArray getAllRegistrations();
};
%{ C++

View File

@ -13,6 +13,7 @@
#include "nsIHttpChannelInternal.h"
#include "nsIHttpHeaderVisitor.h"
#include "nsINetworkInterceptController.h"
#include "nsIMutableArray.h"
#include "nsPIDOMWindow.h"
#include "nsScriptLoader.h"
#include "nsDebug.h"
@ -2819,6 +2820,130 @@ ServiceWorkerManager::RemoveRegistration(ServiceWorkerRegistrationInfo* aRegistr
mActor->SendUnregisterServiceWorker(principalInfo, NS_ConvertUTF8toUTF16(reg->mScope));
}
class ServiceWorkerDataInfo final : public nsIServiceWorkerInfo
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISERVICEWORKERINFO
static already_AddRefed<ServiceWorkerDataInfo>
Create(const ServiceWorkerRegistrationData& aData);
private:
ServiceWorkerDataInfo()
{}
~ServiceWorkerDataInfo()
{}
nsCOMPtr<nsIPrincipal> mPrincipal;
nsString mScope;
nsString mScriptSpec;
nsString mCurrentWorkerURL;
nsString mActiveCacheName;
nsString mWaitingCacheName;
};
NS_IMPL_ISUPPORTS(ServiceWorkerDataInfo, nsIServiceWorkerInfo)
/* static */ already_AddRefed<ServiceWorkerDataInfo>
ServiceWorkerDataInfo::Create(const ServiceWorkerRegistrationData& aData)
{
AssertIsOnMainThread();
nsRefPtr<ServiceWorkerDataInfo> info = new ServiceWorkerDataInfo();
info->mPrincipal = PrincipalInfoToPrincipal(aData.principal());
if (!info->mPrincipal) {
return nullptr;
}
CopyUTF8toUTF16(aData.scope(), info->mScope);
CopyUTF8toUTF16(aData.scriptSpec(), info->mScriptSpec);
CopyUTF8toUTF16(aData.currentWorkerURL(), info->mCurrentWorkerURL);
info->mActiveCacheName = aData.activeCacheName();
info->mWaitingCacheName = aData.waitingCacheName();
return info.forget();
}
NS_IMETHODIMP
ServiceWorkerDataInfo::GetPrincipal(nsIPrincipal** aPrincipal)
{
AssertIsOnMainThread();
NS_ADDREF(*aPrincipal = mPrincipal);
return NS_OK;
}
NS_IMETHODIMP
ServiceWorkerDataInfo::GetScope(nsAString& aScope)
{
AssertIsOnMainThread();
aScope = mScope;
return NS_OK;
}
NS_IMETHODIMP
ServiceWorkerDataInfo::GetScriptSpec(nsAString& aScriptSpec)
{
AssertIsOnMainThread();
aScriptSpec = mScriptSpec;
return NS_OK;
}
NS_IMETHODIMP
ServiceWorkerDataInfo::GetCurrentWorkerURL(nsAString& aCurrentWorkerURL)
{
AssertIsOnMainThread();
aCurrentWorkerURL = mCurrentWorkerURL;
return NS_OK;
}
NS_IMETHODIMP
ServiceWorkerDataInfo::GetActiveCacheName(nsAString& aActiveCacheName)
{
AssertIsOnMainThread();
aActiveCacheName = mActiveCacheName;
return NS_OK;
}
NS_IMETHODIMP
ServiceWorkerDataInfo::GetWaitingCacheName(nsAString& aWaitingCacheName)
{
AssertIsOnMainThread();
aWaitingCacheName = mWaitingCacheName;
return NS_OK;
}
NS_IMETHODIMP
ServiceWorkerManager::GetAllRegistrations(nsIArray** aResult)
{
AssertIsOnMainThread();
nsRefPtr<ServiceWorkerRegistrar> swr = ServiceWorkerRegistrar::Get();
MOZ_ASSERT(swr);
nsTArray<ServiceWorkerRegistrationData> data;
swr->GetRegistrations(data);
nsCOMPtr<nsIMutableArray> array(do_CreateInstance(NS_ARRAY_CONTRACTID));
if (!array) {
return NS_ERROR_OUT_OF_MEMORY;
}
for (uint32_t i = 0, len = data.Length(); i < len; ++i) {
nsCOMPtr<nsIServiceWorkerInfo> info = ServiceWorkerDataInfo::Create(data[i]);
if (!info) {
return NS_ERROR_FAILURE;
}
array->AppendElement(info, false);
}
array.forget(aResult);
return NS_OK;
}
void
ServiceWorkerInfo::AppendWorker(ServiceWorker* aWorker)
{

View File

@ -0,0 +1,99 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/Services.jsm");
const bundle = Services.strings.createBundle(
"chrome://global/locale/aboutServiceWorkers.properties");
function init() {
let enabled = Services.prefs.getBoolPref("dom.serviceWorkers.enabled");
if (!enabled) {
let div = document.getElementById("warning_not_enabled");
div.classList.add("active");
return;
}
let swm = Cc["@mozilla.org/serviceworkers/manager;1"]
.getService(Ci.nsIServiceWorkerManager);
if (!swm) {
dump("AboutServiceWorkers: Failed to get the ServiceWorkerManager service!\n");
return;
}
let data = swm.getAllRegistrations();
if (!data) {
dump("AboutServiceWorkers: Failed to retrieve the registrations.\n");
return;
}
let length = data.length;
if (!length) {
let div = document.getElementById("warning_no_serviceworkers");
div.classList.add("active");
return;
}
for (let i = 0; i < length; ++i) {
let info = data.queryElementAt(i, Ci.nsIServiceWorkerInfo);
if (!info) {
dump("AboutServiceWorkers: Invalid nsIServiceWorkerInfo interface.\n");
continue;
}
display(info);
}
}
function display(info) {
let parent = document.getElementById("serviceworkers");
let div = document.createElement('div');
parent.appendChild(div);
let title = document.createElement('h2');
let titleStr = bundle.formatStringFromName('title', [info.principal.origin], 1);
title.appendChild(document.createTextNode(titleStr));
div.appendChild(title);
if (info.principal.appId) {
let b2gtitle = document.createElement('h3');
let trueFalse = bundle.GetStringFromName(info.principal.isInBrowserElement ? 'true' : 'false');
let b2gtitleStr = bundle.formatStringFromName('b2gtitle', [info.principal.appId, trueFalse], 2);
b2gtitle.appendChild(document.createTextNode(b2gtitleStr));
div.appendChild(b2gtitle);
}
let list = document.createElement('ul');
div.appendChild(list);
function createItem(title, value) {
let item = document.createElement('li');
list.appendChild(item);
let bold = document.createElement('strong');
bold.appendChild(document.createTextNode(title + " "));
item.appendChild(bold);
item.appendChild(document.createTextNode(value));
}
createItem(bundle.GetStringFromName('scope'), info.scope);
createItem(bundle.GetStringFromName('scriptSpec'), info.scriptSpec);
createItem(bundle.GetStringFromName('currentWorkerURL'), info.currentWorkerURL);
createItem(bundle.GetStringFromName('activeCacheName'), info.activeCacheName);
createItem(bundle.GetStringFromName('waitingCacheName'), info.waitingCacheName);
let sep = document.createElement('hr');
div.appendChild(sep);
}
window.addEventListener("DOMContentLoaded", function load() {
window.removeEventListener("DOMContentLoaded", load);
init();
});

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE html [
<!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> %htmlDTD;
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd"> %globalDTD;
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> %brandDTD;
<!ENTITY % serviceworkersDTD SYSTEM "chrome://global/locale/aboutServiceWorkers.dtd"> %serviceworkersDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>&aboutServiceWorkers.title;</title>
<link rel="stylesheet" href="chrome://global/skin/about.css" type="text/css" />
<link rel="stylesheet" href="chrome://mozapps/skin/aboutServiceWorkers.css" type="text/css" />
<script type="application/javascript;version=1.7" src="chrome://global/content/aboutServiceWorkers.js" />
</head>
<body id="body">
<div id="warning_not_enabled" class="warningBackground">
<div class="warningMessage">&aboutServiceWorkers.warning_not_enabled;</div>
</div>
<div id="warning_no_serviceworkers" class="warningBackground">
<div class="warningMessage">&aboutServiceWorkers.warning_no_serviceworkers;</div>
</div>
<div id="serviceworkers" class="tab active">
<h1>&aboutServiceWorkers.maintitle;</h1>
</div>
</body>
</html>

View File

@ -186,6 +186,16 @@
</td>
</tr>
<tr class="no-copy">
<th class="column">
&aboutSupport.appBasicsServiceWorkers;
</th>
<td>
<a href="about:serviceworkers">about:serviceworkers</a>
</td>
</tr>
<tr>
<th class="column">
&aboutSupport.appBasicsMultiProcessSupport;

View File

@ -20,6 +20,8 @@ toolkit.jar:
content/global/aboutRights-unbranded.xhtml (aboutRights-unbranded.xhtml)
content/global/aboutNetworking.js
content/global/aboutNetworking.xhtml
content/global/aboutServiceWorkers.js
content/global/aboutServiceWorkers.xhtml
content/global/aboutwebrtc/aboutWebrtc.css (aboutwebrtc/aboutWebrtc.css)
content/global/aboutwebrtc/aboutWebrtc.js (aboutwebrtc/aboutWebrtc.js)
content/global/aboutwebrtc/aboutWebrtc.xhtml (aboutwebrtc/aboutWebrtc.xhtml)

View File

@ -0,0 +1,12 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!-- LOCALIZATION NOTE the term "Service Workers" should not be translated. -->
<!ENTITY aboutServiceWorkers.title "About Service Workers">
<!-- LOCALIZATION NOTE the term "Service Workers" should not be translated. -->
<!ENTITY aboutServiceWorkers.maintitle "Registered Service Workers">
<!-- LOCALIZATION NOTE the term "Service Workers" should not be translated. -->
<!ENTITY aboutServiceWorkers.warning_not_enabled "Service Workers are not enabled.">
<!-- LOCALIZATION NOTE the term "Service Workers" should not be translated. -->
<!ENTITY aboutServiceWorkers.warning_no_serviceworkers "No Service Workers registered.">

View File

@ -0,0 +1,25 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
title = Origin: %S
# LOCALIZATION NOTE the terms "AppId" and "InBrowserElement" should not be translated.
b2gtitle = Firefox OS AppID %S - InBrowserElement %S
scope = Scope:
scriptSpec = Script Spec:
# LOCALIZATION NOTE the term "Worker" should not be translated.
currentWorkerURL = Current Worker URL:
# LOCALIZATION NOTE the term "Cache" should not be translated.
activeCacheName = Active Cache Name:
# LOCALIZATION NOTE the term "Cache" should not be translated.
waitingCacheName = Waiting Cache Name:
true = true
false = false

View File

@ -55,6 +55,7 @@ Windows/Mac use the term "Folder" instead of "Directory" -->
<!ENTITY aboutSupport.appBasicsBuildConfig "Build Configuration">
<!ENTITY aboutSupport.appBasicsUserAgent "User Agent">
<!ENTITY aboutSupport.appBasicsMemoryUse "Memory Use">
<!ENTITY aboutSupport.appBasicsServiceWorkers "Registered ServiceWorkers">
<!ENTITY aboutSupport.appBasicsMultiProcessSupport "Multiprocess Windows">

View File

@ -11,6 +11,8 @@
locale/@AB_CD@/global/aboutReader.properties (%chrome/global/aboutReader.properties)
locale/@AB_CD@/global/aboutRights.dtd (%chrome/global/aboutRights.dtd)
locale/@AB_CD@/global/aboutNetworking.dtd (%chrome/global/aboutNetworking.dtd)
locale/@AB_CD@/global/aboutServiceWorkers.dtd (%chrome/global/aboutServiceWorkers.dtd)
locale/@AB_CD@/global/aboutServiceWorkers.properties (%chrome/global/aboutServiceWorkers.properties)
locale/@AB_CD@/global/aboutSupport.dtd (%chrome/global/aboutSupport.dtd)
locale/@AB_CD@/global/aboutSupport.properties (%chrome/global/aboutSupport.properties)
locale/@AB_CD@/global/aboutTelemetry.dtd (%chrome/global/aboutTelemetry.dtd)

View File

@ -56,6 +56,7 @@ toolkit.jar:
skin/classic/mozapps/formautofill/requestAutocomplete.css (../../shared/formautofill/requestAutocomplete.css)
skin/classic/mozapps/plugins/pluginProblem.css (../../shared/plugins/pluginProblem.css)
skin/classic/mozapps/aboutNetworking.css (../../shared/aboutNetworking.css)
skin/classic/mozapps/aboutServiceWorkers.css (../../shared/aboutServiceWorkers.css)
skin/classic/mozapps/plugins/contentPluginActivate.png (../../shared/plugins/contentPluginActivate.png)
skin/classic/mozapps/plugins/contentPluginBlocked.png (../../shared/plugins/contentPluginBlocked.png)
skin/classic/mozapps/plugins/contentPluginClose.png (../../shared/plugins/contentPluginClose.png)

View File

@ -0,0 +1,40 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
body {
min-width: 330px;
max-width: 100%;
min-height: 330px;
max-height: 100%;
}
.warningBackground {
display: none;
background: -moz-Dialog;
width:100%;
height:100%;
z-index:10;
top:0;
left:0;
position:fixed;
}
.warningMessage {
color: -moz-FieldText;
position: relative;
min-width: 330px;
max-width: 50em;
margin: 4em auto;
border: 1px solid ThreeDShadow;
border-radius: 10px;
padding: 3em;
-moz-padding-start: 30px;
background: -moz-Field;
margin-left: auto;
text-align: center;
}
.active {
display: block;
}

View File

@ -55,6 +55,7 @@ toolkit.jar:
skin/classic/mozapps/formautofill/requestAutocomplete.css (../../shared/formautofill/requestAutocomplete.css)
skin/classic/mozapps/plugins/pluginProblem.css (../../shared/plugins/pluginProblem.css)
skin/classic/mozapps/aboutNetworking.css (../../shared/aboutNetworking.css)
skin/classic/mozapps/aboutServiceWorkers.css (../../shared/aboutServiceWorkers.css)
skin/classic/mozapps/plugins/contentPluginActivate.png (../../shared/plugins/contentPluginActivate.png)
skin/classic/mozapps/plugins/contentPluginBlocked.png (../../shared/plugins/contentPluginBlocked.png)
skin/classic/mozapps/plugins/contentPluginClose.png (../../shared/plugins/contentPluginClose.png)