mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1209162 - Create OriginAttributes subtypes. IGNORE IDL r=sicking. (c2cbe04ef3) - Bug 1220570 - Potential cookie lost while downgrading from Aurora 44 to 43. r=jduell (1a0111c842) - Bug 1217456: Add a security flag for controlling redirects. Use this flag in fetch() implementation. r=bkelly,jduell (79d449e479) - Bug 1112040 - Add a mochitest. r=bholley (566a05f720) - Bug 1171215 - Compute third-partyness in the loadinfo instead of nsIHttpChannelInternal so that other protocols correctly respect the third-party cookie pref. r=sicking/ckerschb (06f7a10a83) - better backport of Bug 485941 - Stack overflow using overly-deep XML tree (DoS). r=bzbarsky (ac43feeffa) - Bug 1182546 - Use channel->Open2() in parser/htmlparser/nsExpatDriver.cpp (r=bz) (42768f373a) - Bug 1163435 part 1 - [css-grid][css-flexbox] Propagate an explicit CB width/height to the reflow state to resolve percentage lengths for grid items properly. Resolve percent against the size in the same axis for abs.pos. children too. r=dholbert (a55463fb05) - Bug 1163435 part 2 - tests. (bb683c5fc6) - Bug 1223282 - Make NS_AUTOMARGIN be a different value than NS_UNCONSTRAINEDSIZE to avoid having clamped huge margin values be interpreted as auto margins. r=roc (4cdfe0f277) - Bug 1224230 - Explicitly store the lineContainer's writing mode in InlineIntrinsicISizeData. r=dbaron (6474515223) - Bug 1221043. Revert to including trailing whitespace for accessibility APIs. r=marcoz,mats (406018c163) - Bug 1227113 - Fix some indentation issues in ServiceWorkerManager, r=janv (2b343bde09) - Bug 1223116 P1 Expose nsIServiceWorkerManager.shouldReportToWindow(). r=catalinb (02899e429d) - Bug 1226441 - Part 1: Add wpt test verifying fetch event waits for activate to complete; r=catalinb (e8eb3e6e7a) - Bug 1209865 - Add gecko profiler marker when mark() of User Timing API is called. r=baku (f48d76e395) - Bug 1169068 - Performance.translateTime(), r=bz (38cd1c31b2) - Bug 1226441 - Part 2: Delay functional event dispatch until service worker is activated; r=catalinb (778cd3dd24) - Bug 1178233 - [non-e10s] The update process doesn't work within about:serviceworkers in non-e10s mode. Test. r=baku (4f8b6f53f8) - Bug 1188545 - Disable unstable test: test_aboutserviceworkers.html. a=testonly (4bbe106693) - Bug 1219255 - We should be able to attach to a service worker;r=amarchesini (0d6b71b4ec) - Bug 1222464 - Part 2: Implement FetchEvent.clientId; r=jdm (9c8abd62dd) - Bug 1218150 - Mark the members of Clients as NewObject; r=bzbarsky (b6b00a586c) - Bug 1222464 - Part 3: Implement Clients.get(); r=jdm (f5ca60d801) - Bug 1222464 - Part 1: Save a client ID for top-level navigations on the docshell and assign it as the document ID when we start loading the document; r=jdm (7dcb5ce2b6) - Bug 1218141 - Add some SameObject and NewObject annotations to ServiceWorkerGlobalScope; r=bzbarsky (5019f58c7a) - Bug 1218190 - Add a pref to enable Clients.openWindow, r=catalinb (dbb6d007dd) - Bug 1218142 - Remove ServiceWorkerGlobalScope.onbeforeevicted/onevicted; r=bzbarsky (029de6f8ec) - Bug 1218146 - Move WindowClient.frameType to Client.frameType; r=bzbarsky (00f0211276) - Bug 1218147 - Make WindowClient.focus() NewObject; r=bzbarsky (3c6aea4b67) - Bug 1189659 - Part 1 - Continue service worker job queue when life cycle events expire. r=bkelly (aa09cd9c60) - Bug 1227932 - Fix Service Workers SoftUpdate and registration.update code paths. r=ehsan (24567b23c0) - Bug 1189659 - Part 2 - Remove set of scopes being updated from ServiceWorkerManager. r=bkelly (ce581b095c) - Bug 1189659 - Part 3 - Use separate synchronization queues for service worker register jobs and install jobs. r=bkelly (9c408a22ed) - Bug 1189659 - Part 4 - Fix race in test_install_event.html. r=bkelly (3186ffb808) - Bug 1189659 - Part 5 - Fix race in skip-waiting.https.html and add some logging for SkipWaitingFlag in ServiceWorkerManager. r=ehsan (4e5ddda6f3) - Bug 1229056 - Implement ClientQueryOptions.includeUncontrolled; r=jdm (dbe56aa60d) - namespace (3b0863d42d) - Bug 1201127 - Return the same ServiceWorkerRegistration object from service worker APIs dealing with the same underlying registration object; r=jdm (c542688ae0) - Bug 1171583 - Remove mutable warning from |nsSimpleURI::SetUserPass|. r=bz (73934deaad) - Bug 1206199 - Extend channelwrapper to mediate OnStartRequest, OnStopRequest, OnDataAvailable (r=sicking) (758a7ec65c) - Bug 1186783 (part 4) - Replace nsBaseHashtable::EnumerateRead() calls in netwerk/ with iterators. r=valentin. (681bdba278) - Bug 1186783 (part 3) - Replace nsBaseHashtable::EnumerateRead() calls in netwerk/ with iterators. r=valentin. (76b8b7191e) - Bug 1186783 (part 2) - Replace nsBaseHashtable::EnumerateRead() calls in netwerk/ with iterators. r=valentin. (5c0743ac49) - Bug 1186783 (part 1) - Replace nsBaseHashtable::EnumerateRead() calls in netwerk/ with iterators. r=valentin. (952cc720cc) - Bug 1186783 (part 5) - Replace nsBaseHashtable::EnumerateRead() calls in netwerk/ with iterators. r=valentin. (25b9735c52) - Bug 1186783 (part 1) - Replace nsBaseHashtable::EnumerateRead() calls in netwerk/. r=michal. (ae52425809) - Bug 1186783 (follow-up) - Bustage fix for Gonk. (d4a1b769bd) - add back some hotfix stuff, even if unused (fe32076c5b) - Bug 1068087: Switch about:plugins to run remotely. r=mconley (bc4316dd03) - Bug 1214058: Part 1 - Add a simplified JSON-based add-on update protocol. r=Mossop (a3198884d5) - Bug 1214058: Part 2 - Run add-on update tests against comparable JSON and RDF manifests. r=Mossop (aa6a796e6f) - Bug 1152977 - Enable by default DEAA for desktop platforms that use OpenGL compositor. r=jmuizelaar (bfa9efd5c8)
This commit is contained in:
@@ -230,7 +230,9 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
||||
nsIContent* containerElm = containerNode->IsElement() ?
|
||||
containerNode->AsElement() : nullptr;
|
||||
|
||||
nsIFrame::RenderedText text = textFrame->GetRenderedText();
|
||||
nsIFrame::RenderedText text = textFrame->GetRenderedText(0,
|
||||
UINT32_MAX, nsIFrame::TextOffsetType::OFFSETS_IN_CONTENT_TEXT,
|
||||
nsIFrame::TrailingWhitespace::DONT_TRIM_TRAILING_WHITESPACE);
|
||||
|
||||
// Remove text accessible if rendered text is empty.
|
||||
if (textAcc) {
|
||||
|
||||
@@ -1091,7 +1091,9 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
||||
|
||||
// Create accessible for visible text frames.
|
||||
if (content->IsNodeOfType(nsINode::eTEXT)) {
|
||||
nsIFrame::RenderedText text = frame->GetRenderedText();
|
||||
nsIFrame::RenderedText text = frame->GetRenderedText(0,
|
||||
UINT32_MAX, nsIFrame::TextOffsetType::OFFSETS_IN_CONTENT_TEXT,
|
||||
nsIFrame::TrailingWhitespace::DONT_TRIM_TRAILING_WHITESPACE);
|
||||
// Ignore not rendered text nodes and whitespace text nodes between table
|
||||
// cells.
|
||||
if (text.mString.IsEmpty() ||
|
||||
|
||||
@@ -139,7 +139,9 @@ nsTextEquivUtils::AppendTextEquivFromTextContent(nsIContent *aContent,
|
||||
if (aContent->TextLength() > 0) {
|
||||
nsIFrame *frame = aContent->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
nsIFrame::RenderedText text = frame->GetRenderedText();
|
||||
nsIFrame::RenderedText text = frame->GetRenderedText(0,
|
||||
UINT32_MAX, nsIFrame::TextOffsetType::OFFSETS_IN_CONTENT_TEXT,
|
||||
nsIFrame::TrailingWhitespace::DONT_TRIM_TRAILING_WHITESPACE);
|
||||
aString->Append(text.mString);
|
||||
} else {
|
||||
// If aContent is an object that is display: none, we have no a frame.
|
||||
|
||||
@@ -394,7 +394,9 @@ Accessible::VisibilityState()
|
||||
if (frame->GetType() == nsGkAtoms::textFrame &&
|
||||
!(frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
|
||||
frame->GetRect().IsEmpty()) {
|
||||
nsIFrame::RenderedText text = frame->GetRenderedText();
|
||||
nsIFrame::RenderedText text = frame->GetRenderedText(0,
|
||||
UINT32_MAX, nsIFrame::TextOffsetType::OFFSETS_IN_CONTENT_TEXT,
|
||||
nsIFrame::TrailingWhitespace::DONT_TRIM_TRAILING_WHITESPACE);
|
||||
if (text.mString.IsEmpty()) {
|
||||
return states::INVISIBLE;
|
||||
}
|
||||
|
||||
@@ -1985,7 +1985,8 @@ HyperTextAccessible::ContentToRenderedOffset(nsIFrame* aFrame, int32_t aContentO
|
||||
"Call on primary frame only");
|
||||
|
||||
nsIFrame::RenderedText text = aFrame->GetRenderedText(aContentOffset,
|
||||
aContentOffset + 1);
|
||||
aContentOffset + 1, nsIFrame::TextOffsetType::OFFSETS_IN_CONTENT_TEXT,
|
||||
nsIFrame::TrailingWhitespace::DONT_TRIM_TRAILING_WHITESPACE);
|
||||
*aRenderedOffset = text.mOffsetWithinNodeRenderedText;
|
||||
|
||||
return NS_OK;
|
||||
@@ -2009,7 +2010,8 @@ HyperTextAccessible::RenderedToContentOffset(nsIFrame* aFrame, uint32_t aRendere
|
||||
"Call on primary frame only");
|
||||
|
||||
nsIFrame::RenderedText text = aFrame->GetRenderedText(aRenderedOffset,
|
||||
aRenderedOffset + 1, nsIFrame::TextOffsetType::OFFSETS_IN_RENDERED_TEXT);
|
||||
aRenderedOffset + 1, nsIFrame::TextOffsetType::OFFSETS_IN_RENDERED_TEXT,
|
||||
nsIFrame::TrailingWhitespace::DONT_TRIM_TRAILING_WHITESPACE);
|
||||
*aContentOffset = text.mOffsetWithinNodeText;
|
||||
|
||||
return NS_OK;
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
'A esoteric weapon wielded by only the most ' +
|
||||
'formidable warriors, for its unrelenting strict' +
|
||||
' power is unfathomable.',
|
||||
'• Lists of Programming Languages', 'Lisp',
|
||||
'• Lists of Programming Languages', 'Lisp ',
|
||||
'1. Scheme', '2. Racket', '3. Clojure',
|
||||
'4. Standard Lisp', 'link-0', ' Lisp',
|
||||
'checkbox-1-5', ' LeLisp', '• JavaScript',
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
gQueue, docAcc, ObjectTraversalRule, null,
|
||||
['Main Title', 'Lorem ipsum ',
|
||||
'dolor', ' sit amet. Integer vitae urna leo, id ',
|
||||
'semper', ' nulla.', 'Second Section Title',
|
||||
'semper', ' nulla. ', 'Second Section Title',
|
||||
'Sed accumsan luctus lacus, vitae mollis arcu tristique vulputate.',
|
||||
'An ', 'embedded', ' document.', 'Hide me', 'Link 1', 'Link 2',
|
||||
'Link 3', 'Hello', 'World']);
|
||||
@@ -90,7 +90,7 @@
|
||||
gQueue, docAcc, ObjectTraversalRule,
|
||||
getAccessible(doc.getElementById('paragraph-1')),
|
||||
['Lorem ipsum ', 'dolor', ' sit amet. Integer vitae urna leo, id ',
|
||||
'semper', ' nulla.']);
|
||||
'semper', ' nulla. ']);
|
||||
|
||||
gQueue.push(new setModalRootInvoker(docAcc, docAcc.parent,
|
||||
NS_ERROR_INVALID_ARG));
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
function doTest()
|
||||
{
|
||||
var iframeDoc = [ getNode("iframe").contentDocument ];
|
||||
testCharacterCount(iframeDoc, 13);
|
||||
testText(iframeDoc, 0, 13, "outbodyinbody");
|
||||
testCharacterCount(iframeDoc, 15);
|
||||
testText(iframeDoc, 0, 15, "outbody inbody ");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// getTextAtOffset line boundary
|
||||
|
||||
testTextAtOffset(0, BOUNDARY_LINE_START, "line", 0, 4,
|
||||
testTextAtOffset(0, BOUNDARY_LINE_START, "line ", 0, 5,
|
||||
"hypertext3", kOk, kOk, kOk);
|
||||
|
||||
// XXX: see bug 634202.
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
function doTest()
|
||||
{
|
||||
testTextAtOffset("line_test_1", BOUNDARY_LINE_START,
|
||||
[[0, 6, "Line 1", 0, 6],
|
||||
[6, 6, "", 6, 6],
|
||||
[7, 13, "Line 3", 7, 13]]);
|
||||
[[0, 6, "Line 1 ", 0, 7],
|
||||
[7, 7, "", 7, 7],
|
||||
[8, 15, "Line 3 ", 8, 15]]);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// __h__e__l__l__o__ __m__y__ __f__r__i__e__n__d__
|
||||
@@ -114,10 +114,10 @@
|
||||
[ [ 0, 3, "foo\n", 0, 4 ], [ 4, 4, "", 4, 4 ] ]);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// 'Hello world'
|
||||
// 'Hello world ' (\n is rendered as space)
|
||||
|
||||
testTextAtOffset([ "ht_4" ], BOUNDARY_LINE_START,
|
||||
[ [ 0, 11, "Hello world", 0, 11 ] ]);
|
||||
[ [ 0, 12, "Hello world ", 0, 12 ] ]);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// list items
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"color": gComputedStyle.color,
|
||||
"background-color": gComputedStyle.backgroundColor};
|
||||
testTextAttrs(ID, 27, attrs, defAttrs, 27, 49);
|
||||
testTextAttrs(ID, 27, attrs, defAttrs, 27, 50);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// area4
|
||||
@@ -110,7 +110,7 @@
|
||||
tempElem = tempElem.parentNode;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"color": gComputedStyle.color};
|
||||
testTextAttrs(ID, 34, attrs, defAttrs, 33, 45);
|
||||
testTextAttrs(ID, 34, attrs, defAttrs, 33, 46);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// area5: "Green!*!RedNormal"
|
||||
@@ -144,7 +144,7 @@
|
||||
|
||||
// Normal
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 11, attrs, defAttrs, 11, 17);
|
||||
testTextAttrs(ID, 11, attrs, defAttrs, 11, 18);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// area6 (CSS vertical-align property, refer to bug 445938 for details
|
||||
@@ -323,7 +323,7 @@
|
||||
testTextAttrs(ID, 152, attrs, defAttrs, 151, 164);
|
||||
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 165, attrs, defAttrs, 164, 171);
|
||||
testTextAttrs(ID, 165, attrs, defAttrs, 164, 172);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// area10, different single style spans in non-styled paragraph
|
||||
@@ -383,7 +383,7 @@
|
||||
testTextAttrs(ID, 111, attrs, defAttrs, 110, 123);
|
||||
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 124, attrs, defAttrs, 123, 130);
|
||||
testTextAttrs(ID, 124, attrs, defAttrs, 123, 131);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// area11, "font-weight" tests
|
||||
@@ -410,7 +410,7 @@
|
||||
testTextAttrs(ID, 51, attrs, defAttrs, 51, 57);
|
||||
|
||||
attrs = { };
|
||||
testTextAttrs(ID, 57, attrs, defAttrs, 57, 96);
|
||||
testTextAttrs(ID, 57, attrs, defAttrs, 57, 97);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// test out of range offset
|
||||
@@ -485,7 +485,7 @@
|
||||
testTextAttrs(ID, 27, attrs, defAttrs, 27, 31);
|
||||
|
||||
attrs = { };
|
||||
testTextAttrs(ID, 31, attrs, defAttrs, 31, 44);
|
||||
testTextAttrs(ID, 31, attrs, defAttrs, 31, 45);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// area17, "text-decoration" tests
|
||||
@@ -527,7 +527,7 @@
|
||||
"text-line-through-style": "wavy",
|
||||
"text-line-through-color": "rgb(0, 0, 0)",
|
||||
};
|
||||
testTextAttrs(ID, 39, attrs, defAttrs, 39, 43);
|
||||
testTextAttrs(ID, 39, attrs, defAttrs, 39, 44);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// area18, "auto-generation text" tests
|
||||
@@ -557,7 +557,7 @@
|
||||
testTextAttrs(ID, 11, attrs, defAttrs, 10, 17);
|
||||
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 18, attrs, defAttrs, 17, 27);
|
||||
testTextAttrs(ID, 18, attrs, defAttrs, 17, 28);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// area20, "aOffset as -1 (Mozilla Bug 789621)" test
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
turnCaretBrowsing(true);
|
||||
|
||||
// test caret offsets
|
||||
testCaretOffset(document, 15);
|
||||
testCaretOffset(document, 16);
|
||||
testCaretOffset("textbox", -1);
|
||||
testCaretOffset("textarea", -1);
|
||||
testCaretOffset("p", -1);
|
||||
|
||||
@@ -49,14 +49,14 @@
|
||||
},
|
||||
{
|
||||
role: ROLE_TEXT_LEAF,
|
||||
name: "Hello3"
|
||||
name: "Hello3 "
|
||||
},
|
||||
{
|
||||
role: ROLE_PARAGRAPH,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_TEXT_LEAF,
|
||||
name: "Hello4"
|
||||
name: "Hello4 "
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -71,7 +71,7 @@
|
||||
children: [
|
||||
{
|
||||
role: ROLE_TEXT_LEAF,
|
||||
name: "helllo"
|
||||
name: "helllo "
|
||||
},
|
||||
{
|
||||
role: ROLE_PARAGRAPH,
|
||||
@@ -84,7 +84,7 @@
|
||||
},
|
||||
{
|
||||
role: ROLE_TEXT_LEAF,
|
||||
name: "hello"
|
||||
name: "hello "
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@@ -1270,6 +1270,8 @@ pref("view_source.tab", false);
|
||||
// Interception is still disabled.
|
||||
pref("dom.serviceWorkers.enabled", true);
|
||||
|
||||
pref("dom.serviceWorkers.openWindow.enabled", true);
|
||||
|
||||
// Enable Push API.
|
||||
pref("dom.push.enabled", true);
|
||||
|
||||
|
||||
+64
-16
@@ -28,26 +28,74 @@ namespace mozilla {
|
||||
|
||||
using dom::URLParams;
|
||||
|
||||
void OriginAttributes::InheritFromDocShellParent(const OriginAttributes& aParent)
|
||||
void
|
||||
PrincipalOriginAttributes::InheritFromDocShellToDoc(const DocShellOriginAttributes& aAttrs,
|
||||
const nsIURI* aURI)
|
||||
{
|
||||
mAppId = aParent.mAppId;
|
||||
mInBrowser = aParent.mInBrowser;
|
||||
mUserContextId = aParent.mUserContextId;
|
||||
mSignedPkg = aParent.mSignedPkg;
|
||||
mAppId = aAttrs.mAppId;
|
||||
mInBrowser = aAttrs.mInBrowser;
|
||||
|
||||
// addonId is computed from the principal URI and never propagated
|
||||
mUserContextId = aAttrs.mUserContextId;
|
||||
|
||||
// TODO:
|
||||
// Bug 1225349 - PrincipalOriginAttributes should inherit mSignedPkg
|
||||
// accordingly by URI
|
||||
mSignedPkg = aAttrs.mSignedPkg;
|
||||
}
|
||||
|
||||
bool OriginAttributes::CopyFromLoadContext(nsILoadContext* aLoadContext)
|
||||
void
|
||||
PrincipalOriginAttributes::InheritFromNecko(const NeckoOriginAttributes& aAttrs)
|
||||
{
|
||||
OriginAttributes attrs;
|
||||
bool result = aLoadContext->GetOriginAttributes(attrs);
|
||||
NS_ENSURE_TRUE(result, false);
|
||||
mAppId = aAttrs.mAppId;
|
||||
mInBrowser = aAttrs.mInBrowser;
|
||||
|
||||
mAppId = attrs.mAppId;
|
||||
mInBrowser = attrs.mInBrowser;
|
||||
mAddonId = attrs.mAddonId;
|
||||
mUserContextId = attrs.mUserContextId;
|
||||
mSignedPkg = attrs.mSignedPkg;
|
||||
return true;
|
||||
// addonId is computed from the principal URI and never propagated
|
||||
mUserContextId = aAttrs.mUserContextId;
|
||||
mSignedPkg = aAttrs.mSignedPkg;
|
||||
}
|
||||
|
||||
void
|
||||
DocShellOriginAttributes::InheritFromDocToChildDocShell(const PrincipalOriginAttributes& aAttrs)
|
||||
{
|
||||
mAppId = aAttrs.mAppId;
|
||||
mInBrowser = aAttrs.mInBrowser;
|
||||
|
||||
// addonId is computed from the principal URI and never propagated
|
||||
mUserContextId = aAttrs.mUserContextId;
|
||||
|
||||
// TODO:
|
||||
// Bug 1225353 - DocShell/NeckoOriginAttributes should inherit
|
||||
// mSignedPkg accordingly by mSignedPkgInBrowser
|
||||
mSignedPkg = aAttrs.mSignedPkg;
|
||||
}
|
||||
|
||||
void
|
||||
NeckoOriginAttributes::InheritFromDocToNecko(const PrincipalOriginAttributes& aAttrs)
|
||||
{
|
||||
mAppId = aAttrs.mAppId;
|
||||
mInBrowser = aAttrs.mInBrowser;
|
||||
|
||||
// addonId is computed from the principal URI and never propagated
|
||||
mUserContextId = aAttrs.mUserContextId;
|
||||
|
||||
// TODO:
|
||||
// Bug 1225353 - DocShell/NeckoOriginAttributes should inherit
|
||||
// mSignedPkg accordingly by mSignedPkgInBrowser
|
||||
}
|
||||
|
||||
void
|
||||
NeckoOriginAttributes::InheritFromDocShellToNecko(const DocShellOriginAttributes& aAttrs)
|
||||
{
|
||||
mAppId = aAttrs.mAppId;
|
||||
mInBrowser = aAttrs.mInBrowser;
|
||||
|
||||
// addonId is computed from the principal URI and never propagated
|
||||
mUserContextId = aAttrs.mUserContextId;
|
||||
|
||||
// TODO:
|
||||
// Bug 1225353 - DocShell/NeckoOriginAttributes should inherit
|
||||
// mSignedPkg accordingly by mSignedPkgInBrowser
|
||||
}
|
||||
|
||||
void
|
||||
@@ -442,7 +490,7 @@ BasePrincipal::GetUnknownAppId(bool* aUnknownAppId)
|
||||
}
|
||||
|
||||
already_AddRefed<BasePrincipal>
|
||||
BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI, const OriginAttributes& aAttrs)
|
||||
BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI, const PrincipalOriginAttributes& aAttrs)
|
||||
{
|
||||
// If the URI is supposed to inherit the security context of whoever loads it,
|
||||
// we shouldn't make a codebase principal for it.
|
||||
|
||||
+92
-35
@@ -14,26 +14,19 @@
|
||||
#include "mozilla/dom/ChromeUtilsBinding.h"
|
||||
|
||||
class nsIContentSecurityPolicy;
|
||||
class nsILoadContext;
|
||||
class nsIObjectOutputStream;
|
||||
class nsIObjectInputStream;
|
||||
class nsIURI;
|
||||
|
||||
class nsExpandedPrincipal;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// Base OriginAttributes class. This has several subclass flavors, and is not
|
||||
// directly constructable itself.
|
||||
class OriginAttributes : public dom::OriginAttributesDictionary
|
||||
{
|
||||
public:
|
||||
OriginAttributes() {}
|
||||
OriginAttributes(uint32_t aAppId, bool aInBrowser)
|
||||
{
|
||||
mAppId = aAppId;
|
||||
mInBrowser = aInBrowser;
|
||||
}
|
||||
explicit OriginAttributes(const OriginAttributesDictionary& aOther)
|
||||
: OriginAttributesDictionary(aOther) {}
|
||||
|
||||
bool operator==(const OriginAttributes& aOther) const
|
||||
{
|
||||
return mAppId == aOther.mAppId &&
|
||||
@@ -47,28 +40,6 @@ public:
|
||||
return !(*this == aOther);
|
||||
}
|
||||
|
||||
// The docshell often influences the origin attributes of content loaded
|
||||
// inside of it, and in some cases also influences the origin attributes of
|
||||
// content loaded in child docshells. We say that a given attribute "lives on
|
||||
// the docshell" to indicate that this attribute is specified by the docshell
|
||||
// (if any) associated with a given content document.
|
||||
//
|
||||
// In practice, this usually means that we need to store a copy of those
|
||||
// attributes on each docshell, or provide methods on the docshell to compute
|
||||
// them on-demand.
|
||||
// We could track each of these attributes individually, but since the
|
||||
// majority of the existing origin attributes currently live on the docshell,
|
||||
// it's cleaner to simply store an entire OriginAttributes struct on each
|
||||
// docshell, and selectively copy them to child docshells and content
|
||||
// principals in a manner that implements our desired semantics.
|
||||
//
|
||||
// This method is used to propagate attributes from parent to child
|
||||
// docshells.
|
||||
void InheritFromDocShellParent(const OriginAttributes& aParent);
|
||||
|
||||
// Copy from the origin attributes of the nsILoadContext.
|
||||
bool CopyFromLoadContext(nsILoadContext* aLoadContext);
|
||||
|
||||
// Serializes/Deserializes non-default values into the suffix format, i.e.
|
||||
// |!key1=value1&key2=value2|. If there are no non-default attributes, this
|
||||
// returns an empty string.
|
||||
@@ -79,6 +50,92 @@ public:
|
||||
// |uri!key1=value1&key2=value2| and returns the uri without the suffix.
|
||||
bool PopulateFromOrigin(const nsACString& aOrigin,
|
||||
nsACString& aOriginNoSuffix);
|
||||
|
||||
protected:
|
||||
OriginAttributes() {}
|
||||
explicit OriginAttributes(const OriginAttributesDictionary& aOther)
|
||||
: OriginAttributesDictionary(aOther) {}
|
||||
};
|
||||
|
||||
class PrincipalOriginAttributes;
|
||||
class DocShellOriginAttributes;
|
||||
class NeckoOriginAttributes;
|
||||
|
||||
// Various classes in Gecko contain OriginAttributes members, and those
|
||||
// OriginAttributes get propagated to other classes according to certain rules.
|
||||
// For example, the OriginAttributes on the docshell affect the OriginAttributes
|
||||
// for the principal of a document loaded inside it, whose OriginAttributes in
|
||||
// turn affect those of network loads and child docshells. To codify and
|
||||
// centralize these rules, we introduce separate subclasses for the different
|
||||
// flavors, and a variety of InheritFrom* methods to implement the transfer
|
||||
// behavior.
|
||||
|
||||
// For OriginAttributes stored on principals.
|
||||
class PrincipalOriginAttributes : public OriginAttributes
|
||||
{
|
||||
public:
|
||||
PrincipalOriginAttributes() {}
|
||||
PrincipalOriginAttributes(uint32_t aAppId, bool aInBrowser)
|
||||
{
|
||||
mAppId = aAppId;
|
||||
mInBrowser = aInBrowser;
|
||||
}
|
||||
|
||||
// Inheriting OriginAttributes from docshell to document when user navigates.
|
||||
//
|
||||
// @param aAttrs Origin Attributes of the docshell.
|
||||
// @param aURI The URI of the document.
|
||||
void InheritFromDocShellToDoc(const DocShellOriginAttributes& aAttrs,
|
||||
const nsIURI* aURI);
|
||||
|
||||
// Inherit OriginAttributes from Necko.
|
||||
void InheritFromNecko(const NeckoOriginAttributes& aAttrs);
|
||||
};
|
||||
|
||||
// For OriginAttributes stored on docshells / loadcontexts / browsing contexts.
|
||||
class DocShellOriginAttributes : public OriginAttributes
|
||||
{
|
||||
public:
|
||||
DocShellOriginAttributes() {}
|
||||
DocShellOriginAttributes(uint32_t aAppId, bool aInBrowser)
|
||||
{
|
||||
mAppId = aAppId;
|
||||
mInBrowser = aInBrowser;
|
||||
}
|
||||
|
||||
// Inheriting OriginAttributes from document to child docshell when an
|
||||
// <iframe> is created.
|
||||
//
|
||||
// @param aAttrs Origin Attributes of the document.
|
||||
void
|
||||
InheritFromDocToChildDocShell(const PrincipalOriginAttributes& aAttrs);
|
||||
};
|
||||
|
||||
// For OriginAttributes stored on Necko.
|
||||
class NeckoOriginAttributes : public OriginAttributes
|
||||
{
|
||||
public:
|
||||
NeckoOriginAttributes() {}
|
||||
NeckoOriginAttributes(uint32_t aAppId, bool aInBrowser)
|
||||
{
|
||||
mAppId = aAppId;
|
||||
mInBrowser = aInBrowser;
|
||||
}
|
||||
|
||||
// Inheriting OriginAttributes from document to necko when a network request
|
||||
// is made.
|
||||
void InheritFromDocToNecko(const PrincipalOriginAttributes& aAttrs);
|
||||
|
||||
void InheritFromDocShellToNecko(const DocShellOriginAttributes& aAttrs);
|
||||
};
|
||||
|
||||
// For operating on OriginAttributes not associated with any data structure.
|
||||
class GenericOriginAttributes : public OriginAttributes
|
||||
{
|
||||
public:
|
||||
GenericOriginAttributes() {}
|
||||
explicit GenericOriginAttributes(const OriginAttributesDictionary& aOther)
|
||||
: OriginAttributes(aOther) {}
|
||||
};
|
||||
|
||||
class OriginAttributesPattern : public dom::OriginAttributesPatternDictionary
|
||||
@@ -167,9 +224,9 @@ public:
|
||||
|
||||
static BasePrincipal* Cast(nsIPrincipal* aPrin) { return static_cast<BasePrincipal*>(aPrin); }
|
||||
static already_AddRefed<BasePrincipal>
|
||||
CreateCodebasePrincipal(nsIURI* aURI, const OriginAttributes& aAttrs);
|
||||
CreateCodebasePrincipal(nsIURI* aURI, const PrincipalOriginAttributes& aAttrs);
|
||||
|
||||
const OriginAttributes& OriginAttributesRef() { return mOriginAttributes; }
|
||||
const PrincipalOriginAttributes& OriginAttributesRef() { return mOriginAttributes; }
|
||||
uint32_t AppId() const { return mOriginAttributes.mAppId; }
|
||||
uint32_t UserContextId() const { return mOriginAttributes.mUserContextId; }
|
||||
bool IsInBrowserElement() const { return mOriginAttributes.mInBrowser; }
|
||||
@@ -201,7 +258,7 @@ protected:
|
||||
|
||||
nsCOMPtr<nsIContentSecurityPolicy> mCSP;
|
||||
nsCOMPtr<nsIContentSecurityPolicy> mPreloadCSP;
|
||||
OriginAttributes mOriginAttributes;
|
||||
PrincipalOriginAttributes mOriginAttributes;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -160,7 +160,7 @@ nsJSPrincipals::ReadKnownPrincipalType(JSContext* aCx,
|
||||
return false;
|
||||
}
|
||||
|
||||
OriginAttributes attrs;
|
||||
PrincipalOriginAttributes attrs;
|
||||
attrs.PopulateFromSuffix(suffix);
|
||||
info = ContentPrincipalInfo(attrs, spec);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ nsNullPrincipal::CreateWithInheritedAttributes(nsIPrincipal* aInheritFrom)
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<nsNullPrincipal>
|
||||
nsNullPrincipal::Create(const OriginAttributes& aOriginAttributes)
|
||||
nsNullPrincipal::Create(const PrincipalOriginAttributes& aOriginAttributes)
|
||||
{
|
||||
RefPtr<nsNullPrincipal> nullPrin = new nsNullPrincipal();
|
||||
nsresult rv = nullPrin->Init(aOriginAttributes);
|
||||
@@ -54,7 +54,7 @@ nsNullPrincipal::Create(const OriginAttributes& aOriginAttributes)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNullPrincipal::Init(const OriginAttributes& aOriginAttributes)
|
||||
nsNullPrincipal::Init(const PrincipalOriginAttributes& aOriginAttributes)
|
||||
{
|
||||
mOriginAttributes = aOriginAttributes;
|
||||
|
||||
|
||||
@@ -52,9 +52,9 @@ public:
|
||||
|
||||
// Returns null on failure.
|
||||
static already_AddRefed<nsNullPrincipal>
|
||||
Create(const mozilla::OriginAttributes& aOriginAttributes = mozilla::OriginAttributes());
|
||||
Create(const mozilla::PrincipalOriginAttributes& aOriginAttributes = mozilla::PrincipalOriginAttributes());
|
||||
|
||||
nsresult Init(const mozilla::OriginAttributes& aOriginAttributes = mozilla::OriginAttributes());
|
||||
nsresult Init(const mozilla::PrincipalOriginAttributes& aOriginAttributes = mozilla::PrincipalOriginAttributes());
|
||||
|
||||
virtual void GetScriptLocation(nsACString &aStr) override;
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ nsPrincipal::~nsPrincipal()
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPrincipal::Init(nsIURI *aCodebase, const OriginAttributes& aOriginAttributes)
|
||||
nsPrincipal::Init(nsIURI *aCodebase, const PrincipalOriginAttributes& aOriginAttributes)
|
||||
{
|
||||
NS_ENSURE_STATE(!mInitialized);
|
||||
NS_ENSURE_ARG(aCodebase);
|
||||
@@ -391,7 +391,7 @@ nsPrincipal::Read(nsIObjectInputStream* aStream)
|
||||
rv = aStream->ReadCString(suffix);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
OriginAttributes attrs;
|
||||
PrincipalOriginAttributes attrs;
|
||||
bool ok = attrs.PopulateFromSuffix(suffix);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
|
||||
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ public:
|
||||
nsPrincipal();
|
||||
|
||||
// Init() must be called before the principal is in a usable state.
|
||||
nsresult Init(nsIURI* aCodebase, const mozilla::OriginAttributes& aOriginAttributes);
|
||||
nsresult Init(nsIURI* aCodebase, const mozilla::PrincipalOriginAttributes& aOriginAttributes);
|
||||
|
||||
virtual void GetScriptLocation(nsACString& aStr) override;
|
||||
void SetURI(nsIURI* aURI);
|
||||
|
||||
@@ -290,7 +290,7 @@ nsScriptSecurityManager::AppStatusForPrincipal(nsIPrincipal *aPrin)
|
||||
// The app could contain a cross-origin iframe - make sure that the content
|
||||
// is actually same-origin with the app.
|
||||
MOZ_ASSERT(inMozBrowser == false, "Checked this above");
|
||||
OriginAttributes attrs(appId, false);
|
||||
PrincipalOriginAttributes attrs(appId, false);
|
||||
nsCOMPtr<nsIPrincipal> appPrin = BasePrincipal::CreateCodebasePrincipal(appURI, attrs);
|
||||
NS_ENSURE_TRUE(appPrin, nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
||||
return aPrin->Equals(appPrin) ? status
|
||||
@@ -361,7 +361,7 @@ nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScriptSecurityManager::MaybeSetAddonIdFromURI(OriginAttributes& aAttrs, nsIURI* aURI)
|
||||
nsScriptSecurityManager::MaybeSetAddonIdFromURI(PrincipalOriginAttributes& aAttrs, nsIURI* aURI)
|
||||
{
|
||||
nsAutoCString scheme;
|
||||
nsresult rv = aURI->GetScheme(scheme);
|
||||
@@ -404,7 +404,8 @@ nsScriptSecurityManager::GetChannelURIPrincipal(nsIChannel* aChannel,
|
||||
return GetLoadContextCodebasePrincipal(uri, loadContext, aPrincipal);
|
||||
}
|
||||
|
||||
OriginAttributes attrs(UNKNOWN_APP_ID, false);
|
||||
//TODO: Bug 1211590. inherit Origin Attributes from LoadInfo.
|
||||
PrincipalOriginAttributes attrs(UNKNOWN_APP_ID, false);
|
||||
rv = MaybeSetAddonIdFromURI(attrs, uri);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(uri, attrs);
|
||||
@@ -1017,7 +1018,7 @@ NS_IMETHODIMP
|
||||
nsScriptSecurityManager::GetSimpleCodebasePrincipal(nsIURI* aURI,
|
||||
nsIPrincipal** aPrincipal)
|
||||
{
|
||||
OriginAttributes attrs(UNKNOWN_APP_ID, false);
|
||||
PrincipalOriginAttributes attrs(UNKNOWN_APP_ID, false);
|
||||
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(aURI, attrs);
|
||||
prin.forget(aPrincipal);
|
||||
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
|
||||
@@ -1027,7 +1028,7 @@ NS_IMETHODIMP
|
||||
nsScriptSecurityManager::GetNoAppCodebasePrincipal(nsIURI* aURI,
|
||||
nsIPrincipal** aPrincipal)
|
||||
{
|
||||
OriginAttributes attrs(NO_APP_ID, false);
|
||||
PrincipalOriginAttributes attrs(NO_APP_ID, false);
|
||||
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(aURI, attrs);
|
||||
prin.forget(aPrincipal);
|
||||
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
|
||||
@@ -1044,7 +1045,7 @@ NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, JS::Handle<JS::Value> aOriginAttributes,
|
||||
JSContext* aCx, nsIPrincipal** aPrincipal)
|
||||
{
|
||||
OriginAttributes attrs;
|
||||
PrincipalOriginAttributes attrs;
|
||||
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
@@ -1057,7 +1058,7 @@ NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CreateNullPrincipal(JS::Handle<JS::Value> aOriginAttributes,
|
||||
JSContext* aCx, nsIPrincipal** aPrincipal)
|
||||
{
|
||||
OriginAttributes attrs;
|
||||
PrincipalOriginAttributes attrs;
|
||||
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
@@ -1091,7 +1092,7 @@ nsScriptSecurityManager::GetAppCodebasePrincipal(nsIURI* aURI,
|
||||
NS_ENSURE_TRUE(aAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID,
|
||||
NS_ERROR_INVALID_ARG);
|
||||
|
||||
OriginAttributes attrs(aAppId, aInMozBrowser);
|
||||
PrincipalOriginAttributes attrs(aAppId, aInMozBrowser);
|
||||
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(aURI, attrs);
|
||||
prin.forget(aPrincipal);
|
||||
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
|
||||
@@ -1103,10 +1104,13 @@ nsScriptSecurityManager::
|
||||
nsILoadContext* aLoadContext,
|
||||
nsIPrincipal** aPrincipal)
|
||||
{
|
||||
OriginAttributes attrs;
|
||||
bool result = attrs.CopyFromLoadContext(aLoadContext);
|
||||
DocShellOriginAttributes docShellAttrs;
|
||||
bool result = aLoadContext->GetOriginAttributes(docShellAttrs);;
|
||||
NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
|
||||
|
||||
PrincipalOriginAttributes attrs;
|
||||
attrs.InheritFromDocShellToDoc(docShellAttrs, aURI);
|
||||
|
||||
nsresult rv = MaybeSetAddonIdFromURI(attrs, aURI);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(aURI, attrs);
|
||||
@@ -1119,10 +1123,8 @@ nsScriptSecurityManager::GetDocShellCodebasePrincipal(nsIURI* aURI,
|
||||
nsIDocShell* aDocShell,
|
||||
nsIPrincipal** aPrincipal)
|
||||
{
|
||||
OriginAttributes attrs;
|
||||
nsDocShell* docShell= nsDocShell::Cast(aDocShell);
|
||||
bool result = attrs.CopyFromLoadContext(docShell);
|
||||
NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
|
||||
PrincipalOriginAttributes attrs;
|
||||
attrs.InheritFromDocShellToDoc(nsDocShell::Cast(aDocShell)->GetOriginAttributes(), aURI);
|
||||
|
||||
nsresult rv = MaybeSetAddonIdFromURI(attrs, aURI);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@@ -28,7 +28,7 @@ class nsIStringBundle;
|
||||
class nsSystemPrincipal;
|
||||
|
||||
namespace mozilla {
|
||||
class OriginAttributes;
|
||||
class PrincipalOriginAttributes;
|
||||
} // namespace mozilla
|
||||
|
||||
/////////////////////////////
|
||||
@@ -121,7 +121,7 @@ private:
|
||||
AddSitesToFileURIWhitelist(const nsCString& aSiteList);
|
||||
|
||||
// If aURI is a moz-extension:// URI, set mAddonId to the associated addon.
|
||||
nsresult MaybeSetAddonIdFromURI(mozilla::OriginAttributes& aAttrs, nsIURI* aURI);
|
||||
nsresult MaybeSetAddonIdFromURI(mozilla::PrincipalOriginAttributes& aAttrs, nsIURI* aURI);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> mSystemPrincipal;
|
||||
bool mPrefInitialized;
|
||||
|
||||
@@ -4,34 +4,34 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
|
||||
using mozilla::OriginAttributes;
|
||||
using mozilla::PrincipalOriginAttributes;
|
||||
|
||||
static void
|
||||
TestSuffix(const OriginAttributes& attrs)
|
||||
TestSuffix(const PrincipalOriginAttributes& attrs)
|
||||
{
|
||||
nsAutoCString suffix;
|
||||
attrs.CreateSuffix(suffix);
|
||||
|
||||
OriginAttributes attrsFromSuffix;
|
||||
PrincipalOriginAttributes attrsFromSuffix;
|
||||
attrsFromSuffix.PopulateFromSuffix(suffix);
|
||||
|
||||
EXPECT_EQ(attrs, attrsFromSuffix);
|
||||
}
|
||||
|
||||
TEST(OriginAttributes, Suffix_default)
|
||||
TEST(PrincipalOriginAttributes, Suffix_default)
|
||||
{
|
||||
OriginAttributes attrs;
|
||||
PrincipalOriginAttributes attrs;
|
||||
TestSuffix(attrs);
|
||||
}
|
||||
|
||||
TEST(OriginAttributes, Suffix_appId_inBrowser)
|
||||
TEST(PrincipalOriginAttributes, Suffix_appId_inBrowser)
|
||||
{
|
||||
OriginAttributes attrs(1, true);
|
||||
PrincipalOriginAttributes attrs(1, true);
|
||||
TestSuffix(attrs);
|
||||
}
|
||||
|
||||
TEST(OriginAttributes, Suffix_maxAppId_inBrowser)
|
||||
TEST(PrincipalOriginAttributes, Suffix_maxAppId_inBrowser)
|
||||
{
|
||||
OriginAttributes attrs(4294967295, true);
|
||||
PrincipalOriginAttributes attrs(4294967295, true);
|
||||
TestSuffix(attrs);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,8 @@ LoadContext::LoadContext(nsIPrincipal* aPrincipal,
|
||||
, mIsNotNull(true)
|
||||
#endif
|
||||
{
|
||||
mOriginAttributes = BasePrincipal::Cast(aPrincipal)->OriginAttributesRef();
|
||||
PrincipalOriginAttributes poa = BasePrincipal::Cast(aPrincipal)->OriginAttributesRef();
|
||||
mOriginAttributes = DocShellOriginAttributes(poa.mAppId, poa.mInBrowser);
|
||||
|
||||
if (!aOptionalBase) {
|
||||
return;
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
// by child process.
|
||||
LoadContext(const IPC::SerializedLoadContext& aToCopy,
|
||||
dom::Element* aTopFrameElement,
|
||||
OriginAttributes& aAttrs)
|
||||
DocShellOriginAttributes& aAttrs)
|
||||
: mTopFrameElement(do_GetWeakReference(aTopFrameElement))
|
||||
, mNestedFrameId(0)
|
||||
, mIsContent(aToCopy.mIsContent)
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
// by child process.
|
||||
LoadContext(const IPC::SerializedLoadContext& aToCopy,
|
||||
uint64_t aNestedFrameId,
|
||||
OriginAttributes& aAttrs)
|
||||
DocShellOriginAttributes& aAttrs)
|
||||
: mTopFrameElement(nullptr)
|
||||
, mNestedFrameId(aNestedFrameId)
|
||||
, mIsContent(aToCopy.mIsContent)
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
bool aIsContent,
|
||||
bool aUsePrivateBrowsing,
|
||||
bool aUseRemoteTabs,
|
||||
const OriginAttributes& aAttrs)
|
||||
const DocShellOriginAttributes& aAttrs)
|
||||
: mTopFrameElement(do_GetWeakReference(aTopFrameElement))
|
||||
, mNestedFrameId(0)
|
||||
, mIsContent(aIsContent)
|
||||
@@ -117,7 +117,7 @@ private:
|
||||
bool mIsContent;
|
||||
bool mUsePrivateBrowsing;
|
||||
bool mUseRemoteTabs;
|
||||
OriginAttributes mOriginAttributes;
|
||||
DocShellOriginAttributes mOriginAttributes;
|
||||
#ifdef DEBUG
|
||||
bool mIsNotNull;
|
||||
#endif
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
bool mIsContent;
|
||||
bool mUsePrivateBrowsing;
|
||||
bool mUseRemoteTabs;
|
||||
mozilla::OriginAttributes mOriginAttributes;
|
||||
mozilla::DocShellOriginAttributes mOriginAttributes;
|
||||
};
|
||||
|
||||
// Function to serialize over IPDL
|
||||
|
||||
@@ -9446,7 +9446,8 @@ nsresult
|
||||
nsDocShell::CreatePrincipalFromReferrer(nsIURI* aReferrer,
|
||||
nsIPrincipal** aResult)
|
||||
{
|
||||
OriginAttributes attrs = GetOriginAttributes();
|
||||
PrincipalOriginAttributes attrs;
|
||||
attrs.InheritFromDocShellToDoc(GetOriginAttributes(), aReferrer);
|
||||
nsCOMPtr<nsIPrincipal> prin =
|
||||
BasePrincipal::CreateCodebasePrincipal(aReferrer, attrs);
|
||||
prin.forget(aResult);
|
||||
@@ -13890,13 +13891,19 @@ nsDocShell::GetAppId(uint32_t* aAppId)
|
||||
return parent->GetAppId(aAppId);
|
||||
}
|
||||
|
||||
OriginAttributes
|
||||
DocShellOriginAttributes
|
||||
nsDocShell::GetOriginAttributes()
|
||||
{
|
||||
OriginAttributes attrs;
|
||||
DocShellOriginAttributes attrs;
|
||||
RefPtr<nsDocShell> parent = GetParentDocshell();
|
||||
if (parent) {
|
||||
attrs.InheritFromDocShellParent(parent->GetOriginAttributes());
|
||||
nsCOMPtr<nsIPrincipal> parentPrin = parent->GetDocument()->NodePrincipal();
|
||||
PrincipalOriginAttributes poa = BasePrincipal::Cast(parentPrin)->OriginAttributesRef();
|
||||
attrs.InheritFromDocToChildDocShell(poa);
|
||||
} else {
|
||||
// This is the topmost docshell, so we get the mSignedPkg attribute if it is
|
||||
// set before.
|
||||
attrs.mSignedPkg = mSignedPkg;
|
||||
}
|
||||
|
||||
if (mOwnOrContainingAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
|
||||
@@ -13907,9 +13914,6 @@ nsDocShell::GetOriginAttributes()
|
||||
attrs.mInBrowser = true;
|
||||
}
|
||||
|
||||
// Bug 1209162 will address the inheritance of each attributes.
|
||||
attrs.mSignedPkg = mSignedPkg;
|
||||
|
||||
return attrs;
|
||||
}
|
||||
|
||||
@@ -13919,8 +13923,7 @@ nsDocShell::GetOriginAttributes(JS::MutableHandle<JS::Value> aVal)
|
||||
JSContext* cx = nsContentUtils::GetCurrentJSContext();
|
||||
MOZ_ASSERT(cx);
|
||||
|
||||
OriginAttributes attrs = GetOriginAttributes();
|
||||
bool ok = ToJSValue(cx, attrs, aVal);
|
||||
bool ok = ToJSValue(cx, GetOriginAttributes(), aVal);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -14119,7 +14122,8 @@ nsDocShell::ShouldPrepareForIntercept(nsIURI* aURI, bool aIsNonSubresourceReques
|
||||
}
|
||||
|
||||
if (aIsNonSubresourceRequest) {
|
||||
OriginAttributes attrs(GetAppId(), GetIsInBrowserElement());
|
||||
PrincipalOriginAttributes attrs;
|
||||
attrs.InheritFromDocShellToDoc(GetOriginAttributes(), aURI);
|
||||
*aShouldIntercept = swm->IsAvailable(attrs, aURI);
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -14206,15 +14210,26 @@ nsDocShell::ChannelIntercepted(nsIInterceptedChannel* aChannel,
|
||||
if (!doc) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
} else {
|
||||
// For top-level navigations, save a document ID which will be passed to
|
||||
// the FetchEvent as the clientId later on.
|
||||
rv = nsIDocument::GenerateDocumentId(mInterceptedDocumentId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
bool isReload = mLoadType & LOAD_CMD_RELOAD;
|
||||
|
||||
OriginAttributes attrs(GetAppId(), GetIsInBrowserElement());
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = channel->GetURI(getter_AddRefs(uri));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PrincipalOriginAttributes attrs;
|
||||
attrs.InheritFromDocShellToDoc(GetOriginAttributes(), uri);
|
||||
|
||||
ErrorResult error;
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
swm->PrepareFetchEvent(attrs, doc, aChannel, isReload, isSubresourceLoad, error);
|
||||
swm->PrepareFetchEvent(attrs, doc, mInterceptedDocumentId, aChannel,
|
||||
isReload, isSubresourceLoad, error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
}
|
||||
|
||||
@@ -268,14 +268,19 @@ public:
|
||||
// is no longer applied
|
||||
void NotifyAsyncPanZoomStopped();
|
||||
|
||||
mozilla::OriginAttributes GetOriginAttributes();
|
||||
|
||||
void SetInFrameSwap(bool aInSwap)
|
||||
{
|
||||
mInFrameSwap = aInSwap;
|
||||
}
|
||||
bool InFrameSwap();
|
||||
|
||||
mozilla::DocShellOriginAttributes GetOriginAttributes();
|
||||
|
||||
void GetInterceptedDocumentId(nsAString& aId)
|
||||
{
|
||||
aId = mInterceptedDocumentId;
|
||||
}
|
||||
|
||||
private:
|
||||
// An observed docshell wrapper is created when recording markers is enabled.
|
||||
mozilla::UniquePtr<mozilla::ObservedDocShell> mObserved;
|
||||
@@ -1014,6 +1019,8 @@ protected:
|
||||
// for a signed package.
|
||||
nsString mSignedPkg;
|
||||
|
||||
nsString mInterceptedDocumentId;
|
||||
|
||||
private:
|
||||
nsCString mForcedCharset;
|
||||
nsCString mParentCharset;
|
||||
|
||||
@@ -11,7 +11,7 @@ interface nsIDOMElement;
|
||||
|
||||
%{C++
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
#include "mozilla/BasePrincipal.h" // for OriginAttributes
|
||||
#include "mozilla/BasePrincipal.h" // for DocShellOriginAttributes
|
||||
#include "mozilla/dom/ScriptSettings.h" // for AutoJSAPI
|
||||
#include "xpcpublic.h" // for PrivilegedJunkScope
|
||||
#include "nsContentUtils.h" // for IsSystemPrincipal
|
||||
@@ -140,7 +140,7 @@ interface nsILoadContext : nsISupports
|
||||
/**
|
||||
* The C++ getter for origin attributes.
|
||||
*/
|
||||
bool GetOriginAttributes(mozilla::OriginAttributes& aAttrs)
|
||||
bool GetOriginAttributes(mozilla::DocShellOriginAttributes& aAttrs)
|
||||
{
|
||||
mozilla::dom::AutoJSAPI jsapi;
|
||||
bool ok = jsapi.Init(xpc::PrivilegedJunkScope());
|
||||
@@ -156,12 +156,13 @@ interface nsILoadContext : nsISupports
|
||||
MOZ_ASSERT(nsContentUtils::IsSystemPrincipal(nsContentUtils::ObjectPrincipal(obj)));
|
||||
JSAutoCompartment ac(jsapi.cx(), obj);
|
||||
|
||||
mozilla::OriginAttributes attrs;
|
||||
mozilla::DocShellOriginAttributes attrs;
|
||||
ok = attrs.Init(jsapi.cx(), v);
|
||||
NS_ENSURE_TRUE(ok, false);
|
||||
aAttrs = attrs;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
%}
|
||||
};
|
||||
|
||||
@@ -56,7 +56,7 @@ ChromeUtils::OriginAttributesToSuffix(dom::GlobalObject& aGlobal,
|
||||
nsCString& aSuffix)
|
||||
|
||||
{
|
||||
OriginAttributes attrs(aAttrs);
|
||||
GenericOriginAttributes attrs(aAttrs);
|
||||
attrs.CreateSuffix(aSuffix);
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ ChromeUtils::OriginAttributesMatchPattern(dom::GlobalObject& aGlobal,
|
||||
const dom::OriginAttributesDictionary& aAttrs,
|
||||
const dom::OriginAttributesPatternDictionary& aPattern)
|
||||
{
|
||||
OriginAttributes attrs(aAttrs);
|
||||
GenericOriginAttributes attrs(aAttrs);
|
||||
OriginAttributesPattern pattern(aPattern);
|
||||
return pattern.Matches(attrs);
|
||||
}
|
||||
|
||||
@@ -500,16 +500,20 @@ private:
|
||||
frame = *mCallData->mTopStackFrame;
|
||||
}
|
||||
|
||||
nsString id;
|
||||
nsString id = frame.mFilename;
|
||||
nsString innerID;
|
||||
if (mWorkerPrivate->IsSharedWorker()) {
|
||||
id = NS_LITERAL_STRING("SharedWorker");
|
||||
innerID = NS_LITERAL_STRING("SharedWorker");
|
||||
} else if (mWorkerPrivate->IsServiceWorker()) {
|
||||
id = NS_LITERAL_STRING("ServiceWorker");
|
||||
innerID = NS_LITERAL_STRING("ServiceWorker");
|
||||
// Use scope as ID so the webconsole can decide if the message should
|
||||
// show up per tab
|
||||
id.AssignWithConversion(mWorkerPrivate->WorkerName());
|
||||
} else {
|
||||
id = NS_LITERAL_STRING("Worker");
|
||||
innerID = NS_LITERAL_STRING("Worker");
|
||||
}
|
||||
|
||||
mCallData->SetIDs(frame.mFilename, id);
|
||||
mCallData->SetIDs(id, innerID);
|
||||
}
|
||||
|
||||
// Now we could have the correct window (if we are not window-less).
|
||||
|
||||
+27
-88
@@ -187,8 +187,6 @@ ThirdPartyUtil::IsThirdPartyChannel(nsIChannel* aChannel,
|
||||
|
||||
nsresult rv;
|
||||
bool doForce = false;
|
||||
bool checkWindowChain = true;
|
||||
bool parentIsThird = false;
|
||||
nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal =
|
||||
do_QueryInterface(aChannel);
|
||||
if (httpChannelInternal) {
|
||||
@@ -206,109 +204,50 @@ ThirdPartyUtil::IsThirdPartyChannel(nsIChannel* aChannel,
|
||||
*aResult = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (flags & nsIHttpChannelInternal::THIRD_PARTY_PARENT_IS_THIRD_PARTY) {
|
||||
// Check that the two PARENT_IS_{THIRD,SAME}_PARTY are mutually exclusive.
|
||||
MOZ_ASSERT(!(flags & nsIHttpChannelInternal::THIRD_PARTY_PARENT_IS_SAME_PARTY));
|
||||
|
||||
// If we're not forcing and we know that the window chain of the channel
|
||||
// is third party, then we know now that we're third party.
|
||||
if (!doForce) {
|
||||
*aResult = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
checkWindowChain = false;
|
||||
parentIsThird = true;
|
||||
} else {
|
||||
// In e10s, we can't check the parent chain in the parent, so we do so
|
||||
// in the child and send the result to the parent.
|
||||
// Note that we only check the window chain if neither
|
||||
// THIRD_PARTY_PARENT_IS_* flag is set.
|
||||
checkWindowChain = !(flags & nsIHttpChannelInternal::THIRD_PARTY_PARENT_IS_SAME_PARTY);
|
||||
parentIsThird = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool parentIsThird = false;
|
||||
|
||||
// Obtain the URI from the channel, and its base domain.
|
||||
nsCOMPtr<nsIURI> channelURI;
|
||||
aChannel->GetURI(getter_AddRefs(channelURI));
|
||||
NS_ENSURE_TRUE(channelURI, NS_ERROR_INVALID_ARG);
|
||||
rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(channelURI));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCString channelDomain;
|
||||
rv = GetBaseDomain(channelURI, channelDomain);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (aURI) {
|
||||
// Determine whether aURI is foreign with respect to channelURI.
|
||||
bool result;
|
||||
rv = IsThirdPartyInternal(channelDomain, aURI, &result);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// If it's foreign, or we're forcing, we're done.
|
||||
if (result || doForce) {
|
||||
*aResult = result;
|
||||
return NS_OK;
|
||||
if (!doForce) {
|
||||
if (nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo()) {
|
||||
parentIsThird = loadInfo->GetIsInThirdPartyContext();
|
||||
if (!parentIsThird &&
|
||||
loadInfo->GetExternalContentPolicyType() != nsIContentPolicy::TYPE_DOCUMENT) {
|
||||
// Check if the channel itself is third-party to its own requestor.
|
||||
// Unforunately, we have to go through the loading principal.
|
||||
nsCOMPtr<nsIURI> parentURI;
|
||||
loadInfo->LoadingPrincipal()->GetURI(getter_AddRefs(parentURI));
|
||||
rv = IsThirdPartyInternal(channelDomain, parentURI, &parentIsThird);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
} else {
|
||||
NS_WARNING("Found channel with no loadinfo, assuming third-party request");
|
||||
parentIsThird = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If we've already computed this in the child process, we're done.
|
||||
if (!checkWindowChain) {
|
||||
// If we're not comparing to a URI, we have our answer. Otherwise, if
|
||||
// parentIsThird, we're not forcing and we know that we're a third-party
|
||||
// request.
|
||||
if (!aURI || parentIsThird) {
|
||||
*aResult = parentIsThird;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Find the associated window and its parent window.
|
||||
nsCOMPtr<nsILoadContext> ctx;
|
||||
NS_QueryNotificationCallbacks(aChannel, ctx);
|
||||
if (!ctx) return NS_ERROR_INVALID_ARG;
|
||||
|
||||
// If there is no window, the consumer kicking off the load didn't provide one
|
||||
// to the channel. This is limited to loads of certain types of resources. If
|
||||
// those loads require cookies, the forceAllowThirdPartyCookie property should
|
||||
// be set on the channel.
|
||||
nsCOMPtr<nsIDOMWindow> ourWin, parentWin;
|
||||
ctx->GetAssociatedWindow(getter_AddRefs(ourWin));
|
||||
if (!ourWin) return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> piOurWin = do_QueryInterface(ourWin);
|
||||
MOZ_ASSERT(piOurWin);
|
||||
|
||||
// We use GetScriptableParent rather than GetParent because we consider
|
||||
// <iframe mozbrowser/mozapp> to be a top-level frame.
|
||||
parentWin = piOurWin->GetScriptableParent();
|
||||
NS_ENSURE_TRUE(parentWin, NS_ERROR_INVALID_ARG);
|
||||
|
||||
// Check whether this is the document channel for this window (representing a
|
||||
// load of a new page). In that situation we want to avoid comparing
|
||||
// channelURI to ourWin, since what's in ourWin right now will be replaced as
|
||||
// the channel loads. This covers the case of a freshly kicked-off load
|
||||
// (e.g. the user typing something in the location bar, or clicking on a
|
||||
// bookmark), where the window's URI hasn't yet been set, and will be bogus.
|
||||
// It also covers situations where a subframe is navigated to someting that
|
||||
// is same-origin with all its ancestors. This is a bit of a nasty hack, but
|
||||
// we will hopefully flag these channels better later.
|
||||
nsLoadFlags flags;
|
||||
rv = aChannel->GetLoadFlags(&flags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (flags & nsIChannel::LOAD_DOCUMENT_URI) {
|
||||
if (SameCOMIdentity(ourWin, parentWin)) {
|
||||
// We only need to compare aURI to the channel URI -- the window's will be
|
||||
// bogus. We already know the answer.
|
||||
*aResult = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Make sure to still compare to ourWin's ancestors
|
||||
ourWin = parentWin;
|
||||
}
|
||||
|
||||
// Check the window hierarchy. This covers most cases for an ordinary page
|
||||
// load from the location bar.
|
||||
return IsThirdPartyWindow(ourWin, channelURI, aResult);
|
||||
// Determine whether aURI is foreign with respect to channelURI.
|
||||
return IsThirdPartyInternal(channelDomain, aURI, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
||||
+60
-18
@@ -240,6 +240,7 @@
|
||||
#include "mozilla/dom/BoxObject.h"
|
||||
#include "gfxVR.h"
|
||||
#include "gfxPrefs.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
||||
#include "nsISpeculativeConnect.h"
|
||||
|
||||
@@ -1663,6 +1664,11 @@ nsDocument::~nsDocument()
|
||||
mImageTracker.Clear();
|
||||
|
||||
mPlugins.Clear();
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os) {
|
||||
os->RemoveObserver(this, "service-worker-get-client");
|
||||
}
|
||||
}
|
||||
|
||||
NS_INTERFACE_TABLE_HEAD(nsDocument)
|
||||
@@ -2064,6 +2070,11 @@ nsDocument::Init()
|
||||
|
||||
mozilla::HoldJSObjects(this);
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os) {
|
||||
os->AddObserver(this, "service-worker-get-client", /* ownsWeak */ true);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -4702,7 +4713,10 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
|
||||
|
||||
nsCOMPtr<nsIServiceWorkerManager> swm = mozilla::services::GetServiceWorkerManager();
|
||||
if (swm) {
|
||||
swm->MaybeStartControlling(this);
|
||||
nsAutoString documentId;
|
||||
static_cast<nsDocShell*>(docShell.get())->GetInterceptedDocumentId(documentId);
|
||||
|
||||
swm->MaybeStartControlling(this, documentId);
|
||||
mMaybeServiceWorkerControlled = true;
|
||||
}
|
||||
}
|
||||
@@ -12269,6 +12283,16 @@ nsDocument::Observe(nsISupports *aSubject,
|
||||
// We don't want to style the chrome window, only app ones.
|
||||
OnAppThemeChanged();
|
||||
}
|
||||
} else if (strcmp("service-worker-get-client", aTopic) == 0) {
|
||||
nsAutoString clientId;
|
||||
GetOrCreateId(clientId);
|
||||
if (!clientId.IsEmpty() && clientId.Equals(aData)) {
|
||||
nsCOMPtr<nsISupportsInterfacePointer> ifptr = do_QueryInterface(aSubject);
|
||||
if (ifptr) {
|
||||
ifptr->SetData(static_cast<nsIDocument*>(this));
|
||||
ifptr->SetDataIID(&NS_GET_IID(nsIDocument));
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -13113,35 +13137,53 @@ nsIDocument::CreateHTMLElement(nsIAtom* aTag)
|
||||
return element.forget();
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
nsIDocument::GetId(nsAString& aId)
|
||||
nsIDocument::GenerateDocumentId(nsAString& aId)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIUUIDGenerator> uuidgen = do_GetService("@mozilla.org/uuid-generator;1", &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsID id;
|
||||
rv = uuidgen->GenerateUUIDInPlace(&id);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Build a string in {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} format
|
||||
char buffer[NSID_LENGTH];
|
||||
id.ToProvidedString(buffer);
|
||||
NS_ConvertASCIItoUTF16 uuid(buffer);
|
||||
|
||||
// Remove {} and the null terminator
|
||||
aId.Assign(Substring(uuid, 1, NSID_LENGTH - 3));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsIDocument::GetOrCreateId(nsAString& aId)
|
||||
{
|
||||
if (mId.IsEmpty()) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIUUIDGenerator> uuidgen = do_GetService("@mozilla.org/uuid-generator;1", &rv);
|
||||
nsresult rv = GenerateDocumentId(mId);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsID id;
|
||||
rv = uuidgen->GenerateUUIDInPlace(&id);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Build a string in {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} format
|
||||
char buffer[NSID_LENGTH];
|
||||
id.ToProvidedString(buffer);
|
||||
NS_ConvertASCIItoUTF16 uuid(buffer);
|
||||
|
||||
// Remove {} and the null terminator
|
||||
mId.Assign(Substring(uuid, 1, NSID_LENGTH - 3));
|
||||
}
|
||||
|
||||
aId = mId;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsIDocument::SetId(const nsAString& aId)
|
||||
{
|
||||
MOZ_ASSERT(mId.IsEmpty(), "Cannot set the document ID after we have one");
|
||||
mId = aId;
|
||||
}
|
||||
|
||||
bool
|
||||
MarkDocumentTreeToBeInSyncOperation(nsIDocument* aDoc, void* aData)
|
||||
{
|
||||
|
||||
+13
-14
@@ -280,18 +280,10 @@ nsFrameLoader::LoadURI(nsIURI* aURI)
|
||||
NS_IMETHODIMP
|
||||
nsFrameLoader::SwitchProcessAndLoadURI(nsIURI* aURI, const nsACString& aPackageId)
|
||||
{
|
||||
nsCOMPtr<nsIURI> URIToLoad = aURI;
|
||||
RefPtr<TabParent> tp = nullptr;
|
||||
|
||||
nsCString signedPkgOrigin;
|
||||
if (!aPackageId.IsEmpty()) {
|
||||
// Only when aPackageId is not empty would signed package origin
|
||||
// be meaningful.
|
||||
nsPrincipal::GetOriginForURI(aURI, signedPkgOrigin);
|
||||
}
|
||||
|
||||
MutableTabContext context;
|
||||
nsresult rv = GetNewTabContext(&context, signedPkgOrigin, aPackageId);
|
||||
nsresult rv = GetNewTabContext(&context, aURI, aPackageId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<Element> ownerElement = mOwnerContent;
|
||||
@@ -305,7 +297,7 @@ nsFrameLoader::SwitchProcessAndLoadURI(nsIURI* aURI, const nsACString& aPackageI
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
LoadURI(URIToLoad);
|
||||
LoadURI(aURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -3015,14 +3007,21 @@ nsFrameLoader::MaybeUpdatePrimaryTabParent(TabParentChange aChange)
|
||||
|
||||
nsresult
|
||||
nsFrameLoader::GetNewTabContext(MutableTabContext* aTabContext,
|
||||
const nsACString& aSignedPkgOriginNoSuffix,
|
||||
nsIURI* aURI,
|
||||
const nsACString& aPackageId)
|
||||
{
|
||||
nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
|
||||
nsCOMPtr<mozIApplication> containingApp = GetContainingApp();
|
||||
OriginAttributes attrs = OriginAttributes();
|
||||
DocShellOriginAttributes attrs;
|
||||
attrs.mInBrowser = OwnerIsBrowserFrame();
|
||||
|
||||
nsCString signedPkgOrigin;
|
||||
if (!aPackageId.IsEmpty()) {
|
||||
// Only when aPackageId is not empty would signed package origin
|
||||
// be meaningful.
|
||||
nsPrincipal::GetOriginForURI(aURI, signedPkgOrigin);
|
||||
}
|
||||
|
||||
// Get the AppId from ownApp
|
||||
uint32_t appId = nsIScriptSecurityManager::NO_APP_ID;
|
||||
if (ownApp) {
|
||||
@@ -3039,8 +3038,8 @@ nsFrameLoader::GetNewTabContext(MutableTabContext* aTabContext,
|
||||
// Populate packageId to signedPkg.
|
||||
attrs.mSignedPkg = NS_ConvertUTF8toUTF16(aPackageId);
|
||||
|
||||
bool tabContextUpdated = aTabContext->SetTabContext(ownApp, containingApp,
|
||||
attrs, aSignedPkgOriginNoSuffix);
|
||||
bool tabContextUpdated =
|
||||
aTabContext->SetTabContext(ownApp, containingApp, attrs, signedPkgOrigin);
|
||||
NS_ENSURE_STATE(tabContextUpdated);
|
||||
|
||||
return NS_OK;
|
||||
|
||||
@@ -317,7 +317,7 @@ private:
|
||||
void InitializeBrowserAPI();
|
||||
|
||||
nsresult GetNewTabContext(mozilla::dom::MutableTabContext* aTabContext,
|
||||
const nsACString& aSignedPkgNoSuffix = EmptyCString(),
|
||||
nsIURI* aURI = nullptr,
|
||||
const nsACString& aPackageId = EmptyCString());
|
||||
|
||||
enum TabParentChange {
|
||||
|
||||
@@ -226,6 +226,7 @@
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/NavigatorBinding.h"
|
||||
#include "mozilla/dom/ImageBitmap.h"
|
||||
#include "mozilla/dom/ServiceWorkerRegistration.h"
|
||||
#ifdef HAVE_SIDEBAR
|
||||
#include "mozilla/dom/ExternalBinding.h"
|
||||
#endif
|
||||
@@ -264,7 +265,7 @@ using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::dom::ipc;
|
||||
using mozilla::BasePrincipal;
|
||||
using mozilla::OriginAttributes;
|
||||
using mozilla::PrincipalOriginAttributes;
|
||||
using mozilla::TimeStamp;
|
||||
using mozilla::TimeDuration;
|
||||
using mozilla::dom::cache::CacheStorage;
|
||||
@@ -1580,6 +1581,8 @@ nsGlobalWindow::CleanUp()
|
||||
}
|
||||
|
||||
DisableTimeChangeNotifications();
|
||||
|
||||
mServiceWorkerRegistrationTable.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1794,6 +1797,8 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPerformance)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mServiceWorkerRegistrationTable)
|
||||
|
||||
#ifdef MOZ_WEBSPEECH
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSpeechSynthesis)
|
||||
#endif
|
||||
@@ -1865,6 +1870,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPerformance)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mServiceWorkerRegistrationTable)
|
||||
|
||||
#ifdef MOZ_WEBSPEECH
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSpeechSynthesis)
|
||||
#endif
|
||||
@@ -8358,7 +8365,7 @@ nsGlobalWindow::PostMessageMozOuter(JSContext* aCx, JS::Handle<JS::Value> aMessa
|
||||
nsCOMPtr<nsIPrincipal> principal = nsContentUtils::SubjectPrincipal();
|
||||
MOZ_ASSERT(principal);
|
||||
|
||||
OriginAttributes attrs = BasePrincipal::Cast(principal)->OriginAttributesRef();
|
||||
PrincipalOriginAttributes attrs = BasePrincipal::Cast(principal)->OriginAttributesRef();
|
||||
// Create a nsIPrincipal inheriting the app/browser attributes from the
|
||||
// caller.
|
||||
providedPrincipal = BasePrincipal::CreateCodebasePrincipal(originURI, attrs);
|
||||
@@ -10852,6 +10859,24 @@ nsGlobalWindow::GetCaches(ErrorResult& aRv)
|
||||
return ref.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ServiceWorkerRegistrationMainThread>
|
||||
nsPIDOMWindow::GetServiceWorkerRegistration(const nsAString& aScope)
|
||||
{
|
||||
RefPtr<ServiceWorkerRegistrationMainThread> registration;
|
||||
if (!mServiceWorkerRegistrationTable.Get(aScope,
|
||||
getter_AddRefs(registration))) {
|
||||
registration = new ServiceWorkerRegistrationMainThread(this, aScope);
|
||||
mServiceWorkerRegistrationTable.Put(aScope, registration);
|
||||
}
|
||||
return registration.forget();
|
||||
}
|
||||
|
||||
void
|
||||
nsPIDOMWindow::InvalidateServiceWorkerRegistration(const nsAString& aScope)
|
||||
{
|
||||
mServiceWorkerRegistrationTable.Remove(aScope);
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::FireOfflineStatusEventIfChanged()
|
||||
{
|
||||
|
||||
@@ -818,7 +818,9 @@ public:
|
||||
return mAnonymousContents;
|
||||
}
|
||||
|
||||
nsresult GetId(nsAString& aId);
|
||||
static nsresult GenerateDocumentId(nsAString& aId);
|
||||
nsresult GetOrCreateId(nsAString& aId);
|
||||
void SetId(const nsAString& aId);
|
||||
|
||||
protected:
|
||||
virtual Element *GetRootElementInternal() const = 0;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/dom/EventTarget.h"
|
||||
#include "js/TypeDecls.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
|
||||
#define DOM_WINDOW_DESTROYED_TOPIC "dom-window-destroyed"
|
||||
#define DOM_WINDOW_FROZEN_TOPIC "dom-window-frozen"
|
||||
@@ -37,6 +38,7 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
class AudioContext;
|
||||
class Element;
|
||||
class ServiceWorkerRegistrationMainThread;
|
||||
} // namespace dom
|
||||
namespace gfx {
|
||||
class VRHMDInfo;
|
||||
@@ -218,6 +220,10 @@ public:
|
||||
return mServiceWorkersTestingEnabled;
|
||||
}
|
||||
|
||||
already_AddRefed<mozilla::dom::ServiceWorkerRegistrationMainThread>
|
||||
GetServiceWorkerRegistration(const nsAString& aScope);
|
||||
void InvalidateServiceWorkerRegistration(const nsAString& aScope);
|
||||
|
||||
protected:
|
||||
// Lazily instantiate an about:blank document if necessary, and if
|
||||
// we have what it takes to do so.
|
||||
@@ -810,6 +816,11 @@ protected:
|
||||
// mPerformance is only used on inner windows.
|
||||
RefPtr<nsPerformance> mPerformance;
|
||||
|
||||
typedef nsRefPtrHashtable<nsStringHashKey,
|
||||
mozilla::dom::ServiceWorkerRegistrationMainThread>
|
||||
ServiceWorkerRegistrationTable;
|
||||
ServiceWorkerRegistrationTable mServiceWorkerRegistrationTable;
|
||||
|
||||
uint32_t mModalStateDepth;
|
||||
|
||||
// These variables are only used on inner windows.
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "nsDOMNavigationTiming.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsILoadInfo.h"
|
||||
#include "nsIURI.h"
|
||||
@@ -29,7 +30,10 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "SharedWorker.h"
|
||||
#include "ServiceWorker.h"
|
||||
#include "js/HeapAPI.h"
|
||||
#include "GeckoProfiler.h"
|
||||
#include "WorkerPrivate.h"
|
||||
#include "WorkerRunnable.h"
|
||||
|
||||
@@ -798,15 +802,16 @@ nsPerformance::InsertUserEntry(PerformanceEntry* aEntry)
|
||||
PerformanceBase::InsertUserEntry(aEntry);
|
||||
}
|
||||
|
||||
DOMHighResTimeStamp
|
||||
nsPerformance::DeltaFromNavigationStart(DOMHighResTimeStamp aTime)
|
||||
TimeStamp
|
||||
nsPerformance::CreationTimeStamp() const
|
||||
{
|
||||
// If the time we're trying to convert is equal to zero, it hasn't been set
|
||||
// yet so just return 0.
|
||||
if (aTime == 0) {
|
||||
return 0;
|
||||
}
|
||||
return aTime - GetDOMTiming()->GetNavigationStart();
|
||||
return GetDOMTiming()->GetNavigationStartTimeStamp();
|
||||
}
|
||||
|
||||
DOMHighResTimeStamp
|
||||
nsPerformance::CreationTime() const
|
||||
{
|
||||
return GetDOMTiming()->GetNavigationStart();
|
||||
}
|
||||
|
||||
// PerformanceBase
|
||||
@@ -918,6 +923,48 @@ PerformanceBase::ClearResourceTimings()
|
||||
mResourceEntries.Clear();
|
||||
}
|
||||
|
||||
DOMHighResTimeStamp
|
||||
PerformanceBase::TranslateTime(DOMHighResTimeStamp aTime,
|
||||
const WindowOrWorkerOrSharedWorkerOrServiceWorker& aTimeSource,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
TimeStamp otherCreationTimeStamp;
|
||||
|
||||
if (aTimeSource.IsWindow()) {
|
||||
RefPtr<nsPerformance> performance = aTimeSource.GetAsWindow().GetPerformance();
|
||||
if (NS_WARN_IF(!performance)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
}
|
||||
otherCreationTimeStamp = performance->CreationTimeStamp();
|
||||
} else if (aTimeSource.IsWorker()) {
|
||||
otherCreationTimeStamp = aTimeSource.GetAsWorker().CreationTimeStamp();
|
||||
} else if (aTimeSource.IsSharedWorker()) {
|
||||
SharedWorker& sharedWorker = aTimeSource.GetAsSharedWorker();
|
||||
WorkerPrivate* workerPrivate = sharedWorker.GetWorkerPrivate();
|
||||
otherCreationTimeStamp = workerPrivate->CreationTimeStamp();
|
||||
} else if (aTimeSource.IsServiceWorker()) {
|
||||
ServiceWorker& serviceWorker = aTimeSource.GetAsServiceWorker();
|
||||
WorkerPrivate* workerPrivate = serviceWorker.GetWorkerPrivate();
|
||||
otherCreationTimeStamp = workerPrivate->CreationTimeStamp();
|
||||
} else {
|
||||
MOZ_CRASH("This should not be possible.");
|
||||
}
|
||||
|
||||
return RoundTime(
|
||||
aTime + (otherCreationTimeStamp - CreationTimeStamp()).ToMilliseconds());
|
||||
}
|
||||
|
||||
DOMHighResTimeStamp
|
||||
PerformanceBase::RoundTime(double aTime) const
|
||||
{
|
||||
// Round down to the nearest 5us, because if the timer is too accurate people
|
||||
// can do nasty timing attacks with it. See similar code in the worker
|
||||
// Performance implementation.
|
||||
const double maxResolutionMs = 0.005;
|
||||
return floor(aTime / maxResolutionMs) * maxResolutionMs;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PerformanceBase::Mark(const nsAString& aName, ErrorResult& aRv)
|
||||
{
|
||||
@@ -934,6 +981,10 @@ PerformanceBase::Mark(const nsAString& aName, ErrorResult& aRv)
|
||||
RefPtr<PerformanceMark> performanceMark =
|
||||
new PerformanceMark(GetAsISupports(), aName, Now());
|
||||
InsertUserEntry(performanceMark);
|
||||
|
||||
if (profiler_is_active()) {
|
||||
PROFILER_MARKER(NS_ConvertUTF16toUTF8(aName).get());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -968,7 +1019,7 @@ PerformanceBase::ResolveTimestampFromName(const nsAString& aName,
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DeltaFromNavigationStart(ts);
|
||||
return ts - CreationTime();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -23,10 +23,15 @@ class nsPerformance;
|
||||
class nsIHttpChannel;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class ErrorResult;
|
||||
|
||||
namespace dom {
|
||||
class PerformanceEntry;
|
||||
class PerformanceObserver;
|
||||
|
||||
class PerformanceEntry;
|
||||
class PerformanceObserver;
|
||||
class WindowOrWorkerOrSharedWorkerOrServiceWorker;
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -313,6 +318,11 @@ public:
|
||||
|
||||
virtual DOMHighResTimeStamp Now() const = 0;
|
||||
|
||||
DOMHighResTimeStamp
|
||||
TranslateTime(DOMHighResTimeStamp aTime,
|
||||
const mozilla::dom::WindowOrWorkerOrSharedWorkerOrServiceWorker& aTimeSource,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
void Mark(const nsAString& aName, mozilla::ErrorResult& aRv);
|
||||
void ClearMarks(const mozilla::dom::Optional<nsAString>& aName);
|
||||
void Measure(const nsAString& aName,
|
||||
@@ -344,8 +354,9 @@ protected:
|
||||
|
||||
virtual void DispatchBufferFullEvent() = 0;
|
||||
|
||||
virtual DOMHighResTimeStamp
|
||||
DeltaFromNavigationStart(DOMHighResTimeStamp aTime) = 0;
|
||||
virtual mozilla::TimeStamp CreationTimeStamp() const = 0;
|
||||
|
||||
virtual DOMHighResTimeStamp CreationTime() const = 0;
|
||||
|
||||
virtual bool IsPerformanceTimingAttribute(const nsAString& aName) = 0;
|
||||
|
||||
@@ -363,6 +374,8 @@ protected:
|
||||
void RunNotificationObserversTask();
|
||||
void QueueEntry(PerformanceEntry* aEntry);
|
||||
|
||||
DOMHighResTimeStamp RoundTime(double aTime) const;
|
||||
|
||||
nsTObserverArray<PerformanceObserver*> mObservers;
|
||||
|
||||
private:
|
||||
@@ -433,7 +446,11 @@ public:
|
||||
|
||||
IMPL_EVENT_HANDLER(resourcetimingbufferfull)
|
||||
|
||||
private:
|
||||
mozilla::TimeStamp CreationTimeStamp() const override;
|
||||
|
||||
DOMHighResTimeStamp CreationTime() const override;
|
||||
|
||||
protected:
|
||||
~nsPerformance();
|
||||
|
||||
nsISupports* GetAsISupports() override
|
||||
@@ -445,9 +462,6 @@ private:
|
||||
|
||||
bool IsPerformanceTimingAttribute(const nsAString& aName) override;
|
||||
|
||||
DOMHighResTimeStamp
|
||||
DeltaFromNavigationStart(DOMHighResTimeStamp aTime) override;
|
||||
|
||||
DOMHighResTimeStamp
|
||||
GetPerformanceTimingFromString(const nsAString& aTimingName) override;
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/* nothing here */
|
||||
@@ -256,6 +256,7 @@ support-files =
|
||||
file_explicit_user_agent.sjs
|
||||
referrer_change_server.sjs
|
||||
file_change_policy_redirect.html
|
||||
empty_worker.js
|
||||
|
||||
[test_anonymousContent_api.html]
|
||||
[test_anonymousContent_append_after_reflow.html]
|
||||
@@ -842,3 +843,4 @@ skip-if = e10s || os != 'linux' || buildapp != 'browser'
|
||||
[test_change_policy.html]
|
||||
skip-if = buildapp == 'b2g' #no ssl support
|
||||
[test_document.all_iteration.html]
|
||||
[test_performance_translate.html]
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for performance.translate()</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="test_performance_user_timing.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
function testBasic() {
|
||||
ok("translateTime" in performance, "Performance.translateTime exists.");
|
||||
try {
|
||||
performance.translateTime(0, null);
|
||||
ok(false, "Wrong use of performance.translateTime.");
|
||||
} catch(e) {
|
||||
ok(true, "Wrong use of performance.translateTime.");
|
||||
}
|
||||
|
||||
next();
|
||||
}
|
||||
|
||||
function testWindow() {
|
||||
is(performance.translateTime(42, this), 42, "translating time with the same window.");
|
||||
|
||||
var now = performance.now();
|
||||
|
||||
var ifr = document.createElement('iframe');
|
||||
ifr.src = 'file_empty.html';
|
||||
document.body.appendChild(ifr);
|
||||
|
||||
ifr.onload = function() {
|
||||
var a = performance.translateTime(0, ifr.contentWindow);
|
||||
ok (a >= now, "Time has been translated from a window that started loading later than we did");
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
||||
function testWorker() {
|
||||
var now = performance.now();
|
||||
|
||||
var w = new Worker('empty_worker.js');
|
||||
var a = performance.translateTime(0, w);
|
||||
// bug 1226147
|
||||
ok (a >= now, "Time has been translated from a Worker that started loading later than we did");
|
||||
next();
|
||||
}
|
||||
|
||||
function testSharedWorker() {
|
||||
var now = performance.now();
|
||||
|
||||
var w = new SharedWorker('empty_worker.js');
|
||||
var a = performance.translateTime(0, w);
|
||||
ok (a >= now, "Time has been translated from a SharedWorker that started loading later than we did");
|
||||
next();
|
||||
}
|
||||
|
||||
var tests = [ testBasic, testWindow, testWorker, testSharedWorker ];
|
||||
function next() {
|
||||
if (!tests.length) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var test = tests.shift();
|
||||
test();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(next);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
@@ -67,17 +67,17 @@ function run_test() {
|
||||
NS_ERROR_INVALID_ARG);
|
||||
|
||||
// We can't test isThirdPartyWindow since we can't really set up a window
|
||||
// heirarchy. We leave that to mochitests.
|
||||
// hierarchy. We leave that to mochitests.
|
||||
|
||||
// Test isThirdPartyChannel. As above, we can't test the bits that require
|
||||
// a load context or window heirarchy.
|
||||
// a load context or window heirarchy. Because of that, the code assumes
|
||||
// that these are all third-party loads.
|
||||
do_check_throws(function() { util.isThirdPartyChannel(null); },
|
||||
NS_ERROR_INVALID_ARG);
|
||||
do_check_throws(function() { util.isThirdPartyChannel(channel1); },
|
||||
NS_ERROR_INVALID_ARG);
|
||||
do_check_throws(function() { util.isThirdPartyChannel(channel1, uri1); },
|
||||
NS_ERROR_INVALID_ARG);
|
||||
do_check_true(util.isThirdPartyChannel(channel1));
|
||||
do_check_true(util.isThirdPartyChannel(channel1, uri1));
|
||||
do_check_true(util.isThirdPartyChannel(channel1, uri2));
|
||||
|
||||
let httpchannel1 = channel1.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
httpchannel1.forceAllowThirdPartyCookie = true;
|
||||
do_check_false(util.isThirdPartyChannel(channel1));
|
||||
|
||||
Vendored
+1
-1
@@ -1933,7 +1933,7 @@ ReadResponse(mozIStorageConnection* aConn, EntryId aEntryId,
|
||||
aSavedResponseOut->mValue.principalInfo() = void_t();
|
||||
if (!serializedInfo.IsEmpty()) {
|
||||
nsAutoCString originNoSuffix;
|
||||
OriginAttributes attrs;
|
||||
PrincipalOriginAttributes attrs;
|
||||
if (!attrs.PopulateFromOrigin(serializedInfo, originNoSuffix)) {
|
||||
NS_WARNING("Something went wrong parsing a serialized principal!");
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
}
|
||||
|
||||
using mozilla::BasePrincipal;
|
||||
using mozilla::OriginAttributes;
|
||||
using mozilla::PrincipalOriginAttributes;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@@ -211,7 +211,7 @@ ResetPermission(uint32_t aAppId, const nsAString& aOriginURL,
|
||||
return rv;
|
||||
}
|
||||
|
||||
OriginAttributes attrs(aAppId, false);
|
||||
PrincipalOriginAttributes attrs(aAppId, false);
|
||||
nsCOMPtr<nsIPrincipal> principal =
|
||||
BasePrincipal::CreateCodebasePrincipal(uri, attrs);
|
||||
NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE);
|
||||
|
||||
@@ -1131,7 +1131,7 @@ Event::TimeStamp() const
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
|
||||
TimeDuration duration =
|
||||
mEvent->timeStamp - workerPrivate->NowBaseTimeStamp();
|
||||
mEvent->timeStamp - workerPrivate->CreationTimeStamp();
|
||||
return duration.ToMilliseconds();
|
||||
}
|
||||
|
||||
|
||||
@@ -74,8 +74,9 @@ function testWorkerEvents() {
|
||||
var worker = new Worker(window.URL.createObjectURL(blob));
|
||||
worker.onmessage = function(evt) {
|
||||
var timeAfterEvent = window.performance.now();
|
||||
ok(evt.data > timeBeforeEvent &&
|
||||
evt.data < timeAfterEvent,
|
||||
var time = window.performance.translateTime(evt.data, worker);
|
||||
ok(time >= timeBeforeEvent &&
|
||||
time <= timeAfterEvent,
|
||||
"Event timestamp in dedicated worker (" + evt.data +
|
||||
") is in expected range: (" +
|
||||
timeBeforeEvent + ", " + timeAfterEvent + ")");
|
||||
|
||||
+31
-29
@@ -29,6 +29,7 @@
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "nsHttpChannel.h"
|
||||
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/workers/Workers.h"
|
||||
@@ -51,7 +52,6 @@ FetchDriver::FetchDriver(InternalRequest* aRequest, nsIPrincipal* aPrincipal,
|
||||
, mLoadGroup(aLoadGroup)
|
||||
, mRequest(aRequest)
|
||||
, mHasBeenCrossSite(false)
|
||||
, mFoundOpaqueRedirect(false)
|
||||
, mResponseAvailableCalled(false)
|
||||
, mFetchCalled(false)
|
||||
{
|
||||
@@ -236,6 +236,10 @@ FetchDriver::HttpFetch()
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
if (mRequest->GetRedirectMode() != RequestRedirect::Follow) {
|
||||
secFlags |= nsILoadInfo::SEC_DONT_FOLLOW_REDIRECTS;
|
||||
}
|
||||
|
||||
// From here on we create a channel and set its properties with the
|
||||
// information from the InternalRequest. This is an implementation detail.
|
||||
MOZ_ASSERT(mLoadGroup);
|
||||
@@ -443,7 +447,9 @@ FetchDriver::IsUnsafeRequest()
|
||||
}
|
||||
|
||||
already_AddRefed<InternalResponse>
|
||||
FetchDriver::BeginAndGetFilteredResponse(InternalResponse* aResponse, nsIURI* aFinalURI)
|
||||
FetchDriver::BeginAndGetFilteredResponse(InternalResponse* aResponse,
|
||||
nsIURI* aFinalURI,
|
||||
bool aFoundOpaqueRedirect)
|
||||
{
|
||||
MOZ_ASSERT(aResponse);
|
||||
nsAutoCString reqURL;
|
||||
@@ -456,7 +462,7 @@ FetchDriver::BeginAndGetFilteredResponse(InternalResponse* aResponse, nsIURI* aF
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
RefPtr<InternalResponse> filteredResponse;
|
||||
if (mFoundOpaqueRedirect) {
|
||||
if (aFoundOpaqueRedirect) {
|
||||
filteredResponse = aResponse->OpaqueRedirectResponse();
|
||||
} else {
|
||||
switch (mRequest->GetResponseTainting()) {
|
||||
@@ -553,10 +559,22 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest,
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest);
|
||||
nsCOMPtr<nsIJARChannel> jarChannel = do_QueryInterface(aRequest);
|
||||
|
||||
bool foundOpaqueRedirect = false;
|
||||
|
||||
if (httpChannel) {
|
||||
uint32_t responseStatus;
|
||||
httpChannel->GetResponseStatus(&responseStatus);
|
||||
|
||||
if (mozilla::net::nsHttpChannel::IsRedirectStatus(responseStatus)) {
|
||||
if (mRequest->GetRedirectMode() == RequestRedirect::Error) {
|
||||
FailWithNetworkError();
|
||||
return NS_BINDING_FAILED;
|
||||
}
|
||||
if (mRequest->GetRedirectMode() == RequestRedirect::Manual) {
|
||||
foundOpaqueRedirect = true;
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoCString statusText;
|
||||
httpChannel->GetResponseStatusText(statusText);
|
||||
|
||||
@@ -662,7 +680,8 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest,
|
||||
|
||||
// Resolves fetch() promise which may trigger code running in a worker. Make
|
||||
// sure the Response is fully initialized before calling this.
|
||||
mResponse = BeginAndGetFilteredResponse(response, channelURI);
|
||||
mResponse = BeginAndGetFilteredResponse(response, channelURI,
|
||||
foundOpaqueRedirect);
|
||||
|
||||
nsCOMPtr<nsIEventTarget> sts = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
@@ -745,6 +764,12 @@ FetchDriver::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We should only ever get here if we use a "follow" redirect policy,
|
||||
// or if if we set an "error" policy as a result of a CORS policy.
|
||||
MOZ_ASSERT(mRequest->GetRedirectMode() == RequestRedirect::Follow ||
|
||||
(mRequest->GetRedirectMode() == RequestRedirect::Error &&
|
||||
IsUnsafeRequest()));
|
||||
|
||||
// HTTP Fetch step 5, "redirect status", step 1
|
||||
if (NS_WARN_IF(mRequest->GetRedirectMode() == RequestRedirect::Error)) {
|
||||
aOldChannel->Cancel(NS_BINDING_FAILED);
|
||||
@@ -765,33 +790,10 @@ FetchDriver::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
|
||||
// HTTP Fetch step 5, "redirect status", step 10 requires us to halt the
|
||||
// redirect, but successfully return an opaqueredirect Response to the
|
||||
// initiating Fetch.
|
||||
if (mRequest->GetRedirectMode() == RequestRedirect::Manual) {
|
||||
// Ideally we would simply not cancel the old channel and allow it to
|
||||
// be processed as normal. Unfortunately this is quite fragile and
|
||||
// other redirect handlers can easily break it for certain use cases.
|
||||
//
|
||||
// For example, nsCORSListenerProxy cancels vetoed redirect channels.
|
||||
// The HTTP cache will also error on vetoed redirects when the
|
||||
// redirect has been previously cached.
|
||||
//
|
||||
// Therefore simulate the completion of the channel to produce the
|
||||
// opaqueredirect Response and then cancel the original channel. This
|
||||
// will result in OnStartRequest() getting called twice, but the second
|
||||
// time will be with an error response (from the Cancel) which will
|
||||
// be ignored.
|
||||
MOZ_ASSERT(!mFoundOpaqueRedirect);
|
||||
mFoundOpaqueRedirect = true;
|
||||
Unused << OnStartRequest(aOldChannel, nullptr);
|
||||
Unused << OnStopRequest(aOldChannel, nullptr, NS_OK);
|
||||
|
||||
aOldChannel->Cancel(NS_BINDING_FAILED);
|
||||
|
||||
return NS_BINDING_FAILED;
|
||||
}
|
||||
|
||||
// The following steps are from HTTP Fetch step 5, "redirect status", step 11
|
||||
// which requires the RequestRedirect to be "follow".
|
||||
MOZ_ASSERT(mRequest->GetRedirectMode() == RequestRedirect::Follow);
|
||||
// which requires the RequestRedirect to be "follow". We asserted that we're
|
||||
// in either "follow" or "error" mode here.
|
||||
|
||||
// HTTP Fetch step 5, "redirect status", steps 11.1 and 11.2 block redirecting
|
||||
// to a URL with credentials in CORS mode. This is implemented in
|
||||
|
||||
@@ -83,7 +83,6 @@ private:
|
||||
RefPtr<FetchDriverObserver> mObserver;
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
bool mHasBeenCrossSite;
|
||||
bool mFoundOpaqueRedirect;
|
||||
|
||||
DebugOnly<bool> mResponseAvailableCalled;
|
||||
DebugOnly<bool> mFetchCalled;
|
||||
@@ -100,7 +99,8 @@ private:
|
||||
// Returns the filtered response sent to the observer.
|
||||
// Callers who don't have access to a channel can pass null for aFinalURI.
|
||||
already_AddRefed<InternalResponse>
|
||||
BeginAndGetFilteredResponse(InternalResponse* aResponse, nsIURI* aFinalURI);
|
||||
BeginAndGetFilteredResponse(InternalResponse* aResponse, nsIURI* aFinalURI,
|
||||
bool aFoundOpaqueRedirect);
|
||||
// Utility since not all cases need to do any post processing of the filtered
|
||||
// response.
|
||||
nsresult FailWithNetworkError();
|
||||
|
||||
@@ -21,11 +21,19 @@ interface nsIServiceWorkerUnregisterCallback : nsISupports
|
||||
void unregisterFailed();
|
||||
};
|
||||
|
||||
[scriptable, builtinclass, uuid(1a1e71dd-0f78-4e2e-a2db-a946fe02cddf)]
|
||||
interface nsIWorkerDebugger;
|
||||
|
||||
[scriptable, builtinclass, uuid(76e357ed-208d-4e4c-9165-1c4059707879)]
|
||||
interface nsIServiceWorkerInfo : nsISupports
|
||||
{
|
||||
readonly attribute DOMString scriptSpec;
|
||||
readonly attribute DOMString cacheName;
|
||||
|
||||
readonly attribute nsIWorkerDebugger debugger;
|
||||
|
||||
void attachDebugger();
|
||||
|
||||
void detachDebugger();
|
||||
};
|
||||
|
||||
[scriptable, uuid(87e63548-d440-4b8a-b158-65ad1de0211E)]
|
||||
@@ -59,7 +67,7 @@ interface nsIServiceWorkerManagerListener : nsISupports
|
||||
void onUnregister(in nsIServiceWorkerRegistrationInfo aInfo);
|
||||
};
|
||||
|
||||
[scriptable, builtinclass, uuid(2f61820a-1e9a-4c16-bf1c-ce182c5f5d6d)]
|
||||
[scriptable, builtinclass, uuid(a03f2b64-7aaf-423a-97b0-e1f733cce0f6)]
|
||||
interface nsIServiceWorkerManager : nsISupports
|
||||
{
|
||||
/**
|
||||
@@ -98,7 +106,7 @@ interface nsIServiceWorkerManager : nsISupports
|
||||
*
|
||||
* This MUST only be called once per document!
|
||||
*/
|
||||
[notxpcom,nostdcall] void MaybeStartControlling(in nsIDocument aDoc);
|
||||
[notxpcom,nostdcall] void MaybeStartControlling(in nsIDocument aDoc, in DOMString aDocumentId);
|
||||
|
||||
/**
|
||||
* Documents that have called MaybeStartControlling() should call this when
|
||||
@@ -174,6 +182,8 @@ interface nsIServiceWorkerManager : nsISupports
|
||||
void addListener(in nsIServiceWorkerManagerListener aListener);
|
||||
|
||||
void removeListener(in nsIServiceWorkerManagerListener aListener);
|
||||
|
||||
bool shouldReportToWindow(in nsIDOMWindow aWindow, in ACString aScope);
|
||||
};
|
||||
|
||||
%{ C++
|
||||
|
||||
@@ -154,7 +154,7 @@ AssertAppProcess(TabContext& aContext,
|
||||
AssertAppProcessType aType,
|
||||
const char* aCapability)
|
||||
{
|
||||
const mozilla::OriginAttributes& attr = aContext.OriginAttributesRef();
|
||||
const mozilla::DocShellOriginAttributes& attr = aContext.OriginAttributesRef();
|
||||
nsCString suffix;
|
||||
attr.CreateSuffix(suffix);
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ TabContext::SetTabContext(const TabContext& aContext)
|
||||
return true;
|
||||
}
|
||||
|
||||
const OriginAttributes&
|
||||
const DocShellOriginAttributes&
|
||||
TabContext::OriginAttributesRef() const
|
||||
{
|
||||
return mOriginAttributes;
|
||||
@@ -167,7 +167,7 @@ TabContext::SignedPkgOriginNoSuffix() const
|
||||
bool
|
||||
TabContext::SetTabContext(mozIApplication* aOwnApp,
|
||||
mozIApplication* aAppFrameOwnerApp,
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
const DocShellOriginAttributes& aOriginAttributes,
|
||||
const nsACString& aSignedPkgOriginNoSuffix)
|
||||
{
|
||||
NS_ENSURE_FALSE(mInitialized, false);
|
||||
@@ -228,7 +228,7 @@ MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
|
||||
: mInvalidReason(nullptr)
|
||||
{
|
||||
uint32_t containingAppId = NO_APP_ID;
|
||||
OriginAttributes originAttributes = OriginAttributes();
|
||||
DocShellOriginAttributes originAttributes;
|
||||
nsAutoCString originSuffix;
|
||||
nsAutoCString signedPkgOriginNoSuffix;
|
||||
|
||||
@@ -269,9 +269,6 @@ MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
|
||||
//
|
||||
// Otherwise, we're a new app window and we inherit from our
|
||||
// opener app.
|
||||
|
||||
// FIXME bug 1212250 - use InheritFromDocToChildDocshell instead
|
||||
// of copying attributes directly.
|
||||
originAttributes = context->mOriginAttributes;
|
||||
if (ipcContext.isBrowserElement()) {
|
||||
containingAppId = context->OwnOrContainingAppId();
|
||||
|
||||
@@ -104,11 +104,11 @@ public:
|
||||
bool HasOwnOrContainingApp() const;
|
||||
|
||||
/**
|
||||
* OriginAttributesRef() returns the OriginAttributes of this frame to the
|
||||
* OriginAttributesRef() returns the DocShellOriginAttributes of this frame to the
|
||||
* caller. This is used to store any attribute associated with the frame's
|
||||
* docshell, such as the AppId.
|
||||
*/
|
||||
const OriginAttributes& OriginAttributesRef() const;
|
||||
const DocShellOriginAttributes& OriginAttributesRef() const;
|
||||
|
||||
/**
|
||||
* Returns the origin associated with the tab (w/o suffix) if this tab owns
|
||||
@@ -142,7 +142,7 @@ protected:
|
||||
*/
|
||||
bool SetTabContext(mozIApplication* aOwnApp,
|
||||
mozIApplication* aAppFrameOwnerApp,
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
const DocShellOriginAttributes& aOriginAttributes,
|
||||
const nsACString& aSignedPkgOriginNoSuffix);
|
||||
|
||||
private:
|
||||
@@ -170,9 +170,9 @@ private:
|
||||
uint32_t mContainingAppId;
|
||||
|
||||
/**
|
||||
* OriginAttributes of the top level tab docShell
|
||||
* DocShellOriginAttributes of the top level tab docShell
|
||||
*/
|
||||
OriginAttributes mOriginAttributes;
|
||||
DocShellOriginAttributes mOriginAttributes;
|
||||
|
||||
/**
|
||||
* The signed package origin without suffix. Since the signed packaged
|
||||
@@ -198,7 +198,7 @@ public:
|
||||
|
||||
bool SetTabContext(mozIApplication* aOwnApp,
|
||||
mozIApplication* aAppFrameOwnerApp,
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
const DocShellOriginAttributes& aOriginAttributes,
|
||||
const nsACString& aSignedPkgOriginNoSuffix = EmptyCString())
|
||||
{
|
||||
return TabContext::SetTabContext(aOwnApp,
|
||||
|
||||
@@ -5261,7 +5261,7 @@ StorageDirectoryHelper::RunOnMainThread()
|
||||
rv = secMan->GetSimpleCodebasePrincipal(uri,
|
||||
getter_AddRefs(principal));
|
||||
} else {
|
||||
OriginAttributes attrs(originProps.mAppId, originProps.mInMozBrowser);
|
||||
PrincipalOriginAttributes attrs(originProps.mAppId, originProps.mInMozBrowser);
|
||||
principal = BasePrincipal::CreateCodebasePrincipal(uri, attrs);
|
||||
rv = principal ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@@ -225,7 +225,15 @@ DoContentSecurityChecks(nsIURI* aURI, nsILoadInfo* aLoadInfo)
|
||||
break;
|
||||
}
|
||||
|
||||
case nsIContentPolicy::TYPE_DTD:
|
||||
case nsIContentPolicy::TYPE_DTD: {
|
||||
mimeTypeGuess = EmptyCString();
|
||||
requestingContext = aLoadInfo->LoadingNode();
|
||||
MOZ_ASSERT(!requestingContext ||
|
||||
requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
|
||||
"type_dtd requires requestingContext of type Document");
|
||||
break;
|
||||
}
|
||||
|
||||
case nsIContentPolicy::TYPE_FONT: {
|
||||
MOZ_ASSERT(false, "contentPolicyType not supported yet");
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
- http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset=UTF-8>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
parent.postMessage(document.cookie, "*");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
- http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset=UTF-8>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
document.cookie = "b=c";
|
||||
parent.postMessage("done", "*");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
/* vim: set ft=javascript: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
function handleRequest(request, response) {
|
||||
response.setHeader("Content-type", "text/html", false);
|
||||
response.setStatusLine(request.httpVersion, "302", "Found");
|
||||
response.setHeader("Location", request.queryString, false);
|
||||
response.write("<!DOCTYPE html><html><body>Look away!</body></html>");
|
||||
}
|
||||
@@ -34,6 +34,9 @@ support-files =
|
||||
utils_bug743615.js
|
||||
worker_bug743615.js
|
||||
file_bug927901.html
|
||||
file_cookieOutputter.html
|
||||
file_redirector.sjs
|
||||
file_prime_cookie.html
|
||||
|
||||
[test_DOMWindowCreated_chromeonly.html]
|
||||
[test_bug132255.html]
|
||||
@@ -167,3 +170,5 @@ skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e1
|
||||
[test_window_bar.html]
|
||||
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e10s
|
||||
[test_bug1022869.html]
|
||||
[test_bug1112040.html]
|
||||
[test_bug1171215.html]
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1112040
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1112040</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<base href="http://mochi.test:8888/tests/dom/tests/mochitest/">
|
||||
<meta charset="UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1112040">Mozilla Bug 1112040</a>
|
||||
<p id="display">
|
||||
</p>
|
||||
<div id="content">
|
||||
<input id="i" type="text" pattern="^.**$">
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 1112040 **/
|
||||
SimpleTest.runTestExpectingConsoleMessages(
|
||||
function() { $('i').value = "42"; },
|
||||
[{ errorMessage: "SyntaxError: nothing to repeat" }]
|
||||
);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,89 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1022869
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1022869</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<iframe src="about:blank"></iframe>
|
||||
<script type="text/javascript; version=1.8">
|
||||
|
||||
var f = document.getElementsByTagName("iframe")[0];
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
/** Test for Bug 1022869 **/
|
||||
function startTest() {
|
||||
// Initialize our cookie.
|
||||
document.cookie = "a=b";
|
||||
|
||||
// Set a cookie in example.org so we can test that we can't read it in
|
||||
// third-party cases.
|
||||
f.contentWindow.location =
|
||||
"http://example.org/tests/dom/tests/mochitest/bugs/file_prime_cookie.html";
|
||||
waitForLoad().then(function() {
|
||||
// Cookies are set up, disallow third-party cookies and start the test.
|
||||
SpecialPowers.pushPrefEnv({ set: [[ 'network.cookie.cookieBehavior', 1 ]] },
|
||||
() => { spawn_task(continueTest); });
|
||||
}).catch((e) => { ok(false, `Got exception: ${e}`) });
|
||||
}
|
||||
|
||||
function waitForLoad() {
|
||||
return new Promise((resolve) => {
|
||||
window.addEventListener("message", function received(msg) {
|
||||
window.removeEventListener("message", received);
|
||||
info(`got message ${msg.data}`);
|
||||
resolve(msg.data);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function* continueTest() {
|
||||
var sameOrigin = "http://mochi.test:8888";
|
||||
var thirdParty = "http://example.org";
|
||||
var page = "tests/dom/tests/mochitest/bugs/file_cookieOutputter.html"
|
||||
var redirect = "tests/dom/tests/mochitest/bugs/file_redirector.sjs";
|
||||
|
||||
function createRedirect(firstOrigin, secondOrigin) {
|
||||
return `${firstOrigin}/${redirect}?${secondOrigin}/${page}`;
|
||||
}
|
||||
|
||||
info("starting test");
|
||||
|
||||
// Same origin to same origin.
|
||||
f.contentWindow.location = createRedirect(sameOrigin, sameOrigin);
|
||||
let cookie = yield waitForLoad();
|
||||
is(cookie, "a=b", "got the cookie");
|
||||
|
||||
// Cross origin to cross origin.
|
||||
f.contentWindow.location = createRedirect(thirdParty, thirdParty);
|
||||
cookie = yield waitForLoad();
|
||||
is(cookie, "", "no third-party cookies");
|
||||
|
||||
// Same origin to cross origin.
|
||||
f.contentWindow.location = createRedirect(sameOrigin, thirdParty);
|
||||
cookie = yield waitForLoad();
|
||||
is(cookie, "", "no third-party cookies");
|
||||
|
||||
// Cross origin to same origin
|
||||
f.contentWindow.location = createRedirect(thirdParty, sameOrigin);
|
||||
cookie = yield waitForLoad();
|
||||
is(cookie, "a=b", "got the cookie");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="startTest()">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1022869">Mozilla Bug 1022869</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
@@ -39,7 +39,7 @@ interface ChromeUtils : ThreadSafeChromeUtils {
|
||||
* IMPORTANT: If you add any members here, you need to do the following:
|
||||
* (1) Add them to both dictionaries.
|
||||
* (2) Update the methods on mozilla::OriginAttributes, including equality,
|
||||
* serialization, and deserialization.
|
||||
* serialization, deserialization, and inheritance.
|
||||
* (3) Update the methods on mozilla::OriginAttributesPattern, including matching.
|
||||
*/
|
||||
dictionary OriginAttributesDictionary {
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
|
||||
[Exposed=ServiceWorker]
|
||||
interface Client {
|
||||
readonly attribute DOMString id;
|
||||
readonly attribute USVString url;
|
||||
readonly attribute FrameType frameType;
|
||||
readonly attribute DOMString id;
|
||||
|
||||
[Throws]
|
||||
void postMessage(any message, optional sequence<Transferable> transfer);
|
||||
@@ -21,9 +22,8 @@ interface Client {
|
||||
interface WindowClient : Client {
|
||||
readonly attribute VisibilityState visibilityState;
|
||||
readonly attribute boolean focused;
|
||||
readonly attribute FrameType frameType;
|
||||
|
||||
[Throws]
|
||||
[Throws, NewObject]
|
||||
Promise<WindowClient> focus();
|
||||
};
|
||||
|
||||
|
||||
@@ -11,11 +11,14 @@
|
||||
[Exposed=ServiceWorker]
|
||||
interface Clients {
|
||||
// The objects returned will be new instances every time
|
||||
[Throws]
|
||||
[NewObject]
|
||||
Promise<any> get(DOMString id);
|
||||
[NewObject]
|
||||
Promise<sequence<Client>?> matchAll(optional ClientQueryOptions options);
|
||||
[Throws]
|
||||
[NewObject,
|
||||
Func="mozilla::dom::workers::ServiceWorkerGlobalScope::OpenWindowEnabled"]
|
||||
Promise<WindowClient> openWindow(USVString url);
|
||||
[Throws]
|
||||
[NewObject]
|
||||
Promise<void> claim();
|
||||
};
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
Exposed=(ServiceWorker)]
|
||||
interface FetchEvent : ExtendableEvent {
|
||||
[SameObject] readonly attribute Request? request;
|
||||
readonly attribute DOMString? clientId;
|
||||
readonly attribute boolean isReload;
|
||||
|
||||
[Throws]
|
||||
@@ -20,5 +21,6 @@ interface FetchEvent : ExtendableEvent {
|
||||
|
||||
dictionary FetchEventInit : EventInit {
|
||||
Request request;
|
||||
DOMString? clientId = null;
|
||||
boolean isReload = false;
|
||||
};
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* http://www.w3.org/TR/hr-time/
|
||||
* http://w3c.github.io/hr-time/
|
||||
*
|
||||
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
||||
* liability, trademark and document use rules apply.
|
||||
* Copyright © 2015 W3C® (MIT, ERCIM, Keio, Beihang).
|
||||
* W3C liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
typedef double DOMHighResTimeStamp;
|
||||
@@ -17,6 +17,9 @@ typedef sequence <PerformanceEntry> PerformanceEntryList;
|
||||
interface Performance {
|
||||
[DependsOn=DeviceState, Affects=Nothing]
|
||||
DOMHighResTimeStamp now();
|
||||
|
||||
[Throws]
|
||||
DOMHighResTimeStamp translateTime(DOMHighResTimeStamp time, (Window or Worker or SharedWorker or ServiceWorker) timeSource);
|
||||
};
|
||||
|
||||
[Exposed=Window]
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
[Global=(Worker,ServiceWorker),
|
||||
Exposed=ServiceWorker]
|
||||
interface ServiceWorkerGlobalScope : WorkerGlobalScope {
|
||||
readonly attribute Clients clients;
|
||||
readonly attribute ServiceWorkerRegistration registration;
|
||||
[SameObject] readonly attribute Clients clients;
|
||||
[SameObject] readonly attribute ServiceWorkerRegistration registration;
|
||||
|
||||
[Throws]
|
||||
[Throws, NewObject]
|
||||
Promise<boolean> skipWaiting();
|
||||
|
||||
attribute EventHandler oninstall;
|
||||
@@ -24,8 +24,6 @@ interface ServiceWorkerGlobalScope : WorkerGlobalScope {
|
||||
|
||||
[Func="mozilla::dom::workers::ServiceWorkerGlobalScope::InterceptionEnabled"]
|
||||
attribute EventHandler onfetch;
|
||||
attribute EventHandler onbeforeevicted;
|
||||
attribute EventHandler onevicted;
|
||||
|
||||
// The event.source of these MessageEvents are instances of Client
|
||||
attribute EventHandler onmessage;
|
||||
|
||||
@@ -7,7 +7,7 @@ include protocol PBackground;
|
||||
include PBackgroundSharedTypes;
|
||||
include ServiceWorkerRegistrarTypes;
|
||||
|
||||
using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h";
|
||||
using mozilla::PrincipalOriginAttributes from "mozilla/ipc/BackgroundUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@@ -21,7 +21,7 @@ parent:
|
||||
|
||||
Unregister(PrincipalInfo principalInfo, nsString scope);
|
||||
|
||||
PropagateSoftUpdate(OriginAttributes originAttributes,
|
||||
PropagateSoftUpdate(PrincipalOriginAttributes originAttributes,
|
||||
nsString scope);
|
||||
PropagateUnregister(PrincipalInfo principalInfo, nsString scope);
|
||||
|
||||
@@ -33,7 +33,7 @@ parent:
|
||||
|
||||
child:
|
||||
NotifyRegister(ServiceWorkerRegistrationData data);
|
||||
NotifySoftUpdate(OriginAttributes originAttributes, nsString scope);
|
||||
NotifySoftUpdate(PrincipalOriginAttributes originAttributes, nsString scope);
|
||||
NotifyUnregister(PrincipalInfo principalInfo, nsString scope);
|
||||
NotifyRemove(nsCString host);
|
||||
NotifyRemoveAll();
|
||||
|
||||
@@ -32,7 +32,7 @@ DOMHighResTimeStamp
|
||||
Performance::Now() const
|
||||
{
|
||||
TimeDuration duration =
|
||||
TimeStamp::Now() - mWorkerPrivate->NowBaseTimeStamp();
|
||||
TimeStamp::Now() - mWorkerPrivate->CreationTimeStamp();
|
||||
double nowTime = duration.ToMilliseconds();
|
||||
// Round down to the nearest 20us, because if the timer is too accurate people
|
||||
// can do nasty timing attacks with it. See similar code in the non-worker
|
||||
@@ -57,7 +57,7 @@ Performance::GetPerformanceTimingFromString(const nsAString& aProperty)
|
||||
}
|
||||
|
||||
if (aProperty.EqualsLiteral("navigationStart")) {
|
||||
return mWorkerPrivate->NowBaseTimeHighRes();
|
||||
return mWorkerPrivate->CreationTime();
|
||||
}
|
||||
|
||||
MOZ_CRASH("IsPerformanceTimingAttribute and GetPerformanceTimingFromString are out of sync");
|
||||
@@ -74,14 +74,16 @@ Performance::InsertUserEntry(PerformanceEntry* aEntry)
|
||||
PerformanceBase::InsertUserEntry(aEntry);
|
||||
}
|
||||
|
||||
DOMHighResTimeStamp
|
||||
Performance::DeltaFromNavigationStart(DOMHighResTimeStamp aTime)
|
||||
TimeStamp
|
||||
Performance::CreationTimeStamp() const
|
||||
{
|
||||
if (aTime == 0) {
|
||||
return 0;
|
||||
}
|
||||
return mWorkerPrivate->CreationTimeStamp();
|
||||
}
|
||||
|
||||
return aTime - mWorkerPrivate->NowBaseTimeHighRes();
|
||||
DOMHighResTimeStamp
|
||||
Performance::CreationTime() const
|
||||
{
|
||||
return mWorkerPrivate->CreationTime();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -55,8 +55,9 @@ private:
|
||||
DOMHighResTimeStamp
|
||||
GetPerformanceTimingFromString(const nsAString& aTimingName) override;
|
||||
|
||||
DOMHighResTimeStamp
|
||||
DeltaFromNavigationStart(DOMHighResTimeStamp aTime) override;
|
||||
TimeStamp CreationTimeStamp() const override;
|
||||
|
||||
DOMHighResTimeStamp CreationTime() const override;
|
||||
};
|
||||
|
||||
END_WORKERS_NAMESPACE
|
||||
|
||||
@@ -168,6 +168,7 @@ static_assert(MAX_WORKERS_PER_DOMAIN >= 1,
|
||||
#define PREF_SERVICEWORKERS_TESTING_ENABLED "dom.serviceWorkers.testing.enabled"
|
||||
#define PREF_INTERCEPTION_ENABLED "dom.serviceWorkers.interception.enabled"
|
||||
#define PREF_INTERCEPTION_OPAQUE_ENABLED "dom.serviceWorkers.interception.opaque.enabled"
|
||||
#define PREF_OPEN_WINDOW_ENABLED "dom.serviceWorkers.openWindow.enabled"
|
||||
#define PREF_PUSH_ENABLED "dom.push.enabled"
|
||||
#define PREF_REQUESTCONTEXT_ENABLED "dom.requestcontext.enabled"
|
||||
#define PREF_OFFSCREENCANVAS_ENABLED "gfx.offscreencanvas.enabled"
|
||||
@@ -1924,6 +1925,10 @@ RuntimeService::Init()
|
||||
WorkerPrefChanged,
|
||||
PREF_INTERCEPTION_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_INTERCEPTION_ENABLED))) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_OPEN_WINDOW_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_OPEN_WINDOW_ENABLED))) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_INTERCEPTION_OPAQUE_ENABLED,
|
||||
@@ -2167,6 +2172,10 @@ RuntimeService::Cleanup()
|
||||
WorkerPrefChanged,
|
||||
PREF_INTERCEPTION_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_INTERCEPTION_ENABLED))) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_OPEN_WINDOW_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_OPEN_WINDOW_ENABLED))) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_SERVICEWORKERS_ENABLED,
|
||||
@@ -2711,6 +2720,7 @@ RuntimeService::WorkerPrefChanged(const char* aPrefName, void* aClosure)
|
||||
#endif
|
||||
case WORKERPREF_INTERCEPTION_ENABLED:
|
||||
case WORKERPREF_INTERCEPTION_OPAQUE_ENABLED:
|
||||
case WORKERPREF_OPEN_WINDOW_ENABLED:
|
||||
case WORKERPREF_SERVICEWORKERS:
|
||||
case WORKERPREF_SERVICEWORKERS_TESTING:
|
||||
case WORKERPREF_PUSH:
|
||||
|
||||
@@ -101,6 +101,13 @@ ServiceWorker::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
aRv = workerPrivate->SendMessageEvent(aCx, aMessage, aTransferable, Move(clientInfo));
|
||||
}
|
||||
|
||||
WorkerPrivate*
|
||||
ServiceWorker::GetWorkerPrivate() const
|
||||
{
|
||||
ServiceWorkerPrivate* workerPrivate = mInfo->WorkerPrivate();
|
||||
return workerPrivate->GetWorkerPrivate();
|
||||
}
|
||||
|
||||
} // namespace workers
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -67,6 +67,9 @@ public:
|
||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
||||
ErrorResult& aRv);
|
||||
|
||||
WorkerPrivate*
|
||||
GetWorkerPrivate() const;
|
||||
|
||||
private:
|
||||
// This class can only be created from the ServiceWorkerManager.
|
||||
ServiceWorker(nsPIDOMWindow* aWindow, ServiceWorkerInfo* aInfo);
|
||||
|
||||
@@ -34,7 +34,7 @@ ServiceWorkerClientInfo::ServiceWorkerClientInfo(nsIDocument* aDoc)
|
||||
: mWindowId(0)
|
||||
{
|
||||
MOZ_ASSERT(aDoc);
|
||||
nsresult rv = aDoc->GetId(mClientId);
|
||||
nsresult rv = aDoc->GetOrCreateId(mClientId);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to get the UUID of the document.");
|
||||
}
|
||||
|
||||
@@ -33,6 +33,11 @@ class ServiceWorkerClientInfo final
|
||||
public:
|
||||
explicit ServiceWorkerClientInfo(nsIDocument* aDoc);
|
||||
|
||||
const nsString& ClientId() const
|
||||
{
|
||||
return mClientId;
|
||||
}
|
||||
|
||||
private:
|
||||
nsString mClientId;
|
||||
uint64_t mWindowId;
|
||||
@@ -57,6 +62,7 @@ public:
|
||||
, mId(aClientInfo.mClientId)
|
||||
, mUrl(aClientInfo.mUrl)
|
||||
, mWindowId(aClientInfo.mWindowId)
|
||||
, mFrameType(aClientInfo.mFrameType)
|
||||
{
|
||||
MOZ_ASSERT(aOwner);
|
||||
}
|
||||
@@ -78,6 +84,12 @@ public:
|
||||
aUrl.Assign(mUrl);
|
||||
}
|
||||
|
||||
mozilla::dom::FrameType
|
||||
FrameType() const
|
||||
{
|
||||
return mFrameType;
|
||||
}
|
||||
|
||||
void
|
||||
PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
||||
@@ -97,6 +109,7 @@ private:
|
||||
|
||||
protected:
|
||||
uint64_t mWindowId;
|
||||
mozilla::dom::FrameType mFrameType;
|
||||
};
|
||||
|
||||
} // namespace workers
|
||||
|
||||
@@ -55,53 +55,140 @@ ServiceWorkerClients::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenPro
|
||||
|
||||
namespace {
|
||||
|
||||
class ResolvePromiseWorkerRunnable final : public WorkerRunnable
|
||||
class GetRunnable final : public nsRunnable
|
||||
{
|
||||
RefPtr<PromiseWorkerProxy> mPromiseProxy;
|
||||
nsTArray<ServiceWorkerClientInfo> mValue;
|
||||
|
||||
public:
|
||||
ResolvePromiseWorkerRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
PromiseWorkerProxy* aPromiseProxy,
|
||||
nsTArray<ServiceWorkerClientInfo>& aValue)
|
||||
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount),
|
||||
mPromiseProxy(aPromiseProxy)
|
||||
class ResolvePromiseWorkerRunnable final : public WorkerRunnable
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
mValue.SwapElements(aValue);
|
||||
}
|
||||
RefPtr<PromiseWorkerProxy> mPromiseProxy;
|
||||
UniquePtr<ServiceWorkerClientInfo> mValue;
|
||||
nsresult mRv;
|
||||
|
||||
bool
|
||||
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||
{
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
Promise* promise = mPromiseProxy->WorkerPromise();
|
||||
MOZ_ASSERT(promise);
|
||||
|
||||
nsTArray<RefPtr<ServiceWorkerClient>> ret;
|
||||
for (size_t i = 0; i < mValue.Length(); i++) {
|
||||
ret.AppendElement(RefPtr<ServiceWorkerClient>(
|
||||
new ServiceWorkerWindowClient(promise->GetParentObject(),
|
||||
mValue.ElementAt(i))));
|
||||
public:
|
||||
ResolvePromiseWorkerRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
PromiseWorkerProxy* aPromiseProxy,
|
||||
UniquePtr<ServiceWorkerClientInfo>&& aValue,
|
||||
nsresult aRv)
|
||||
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount),
|
||||
mPromiseProxy(aPromiseProxy),
|
||||
mValue(Move(aValue)),
|
||||
mRv(Move(aRv))
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
}
|
||||
|
||||
promise->MaybeResolve(ret);
|
||||
mPromiseProxy->CleanUp(aCx);
|
||||
return true;
|
||||
bool
|
||||
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||
{
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
Promise* promise = mPromiseProxy->WorkerPromise();
|
||||
MOZ_ASSERT(promise);
|
||||
|
||||
if (NS_FAILED(mRv)) {
|
||||
promise->MaybeReject(mRv);
|
||||
} else if (mValue) {
|
||||
RefPtr<ServiceWorkerWindowClient> windowClient =
|
||||
new ServiceWorkerWindowClient(promise->GetParentObject(), *mValue);
|
||||
promise->MaybeResolve(windowClient.get());
|
||||
} else {
|
||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
}
|
||||
mPromiseProxy->CleanUp(aCx);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
RefPtr<PromiseWorkerProxy> mPromiseProxy;
|
||||
nsString mClientId;
|
||||
public:
|
||||
GetRunnable(PromiseWorkerProxy* aPromiseProxy,
|
||||
const nsAString& aClientId)
|
||||
: mPromiseProxy(aPromiseProxy),
|
||||
mClientId(aClientId)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
MutexAutoLock lock(mPromiseProxy->Lock());
|
||||
if (mPromiseProxy->CleanedUp()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
WorkerPrivate* workerPrivate = mPromiseProxy->GetWorkerPrivate();
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
ErrorResult rv;
|
||||
UniquePtr<ServiceWorkerClientInfo> result = swm->GetClient(workerPrivate->GetPrincipal(),
|
||||
mClientId, rv);
|
||||
RefPtr<ResolvePromiseWorkerRunnable> r =
|
||||
new ResolvePromiseWorkerRunnable(mPromiseProxy->GetWorkerPrivate(),
|
||||
mPromiseProxy, Move(result),
|
||||
rv.StealNSResult());
|
||||
rv.SuppressException();
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
r->Dispatch(jsapi.cx());
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
class MatchAllRunnable final : public nsRunnable
|
||||
{
|
||||
class ResolvePromiseWorkerRunnable final : public WorkerRunnable
|
||||
{
|
||||
RefPtr<PromiseWorkerProxy> mPromiseProxy;
|
||||
nsTArray<ServiceWorkerClientInfo> mValue;
|
||||
|
||||
public:
|
||||
ResolvePromiseWorkerRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
PromiseWorkerProxy* aPromiseProxy,
|
||||
nsTArray<ServiceWorkerClientInfo>& aValue)
|
||||
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount),
|
||||
mPromiseProxy(aPromiseProxy)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
mValue.SwapElements(aValue);
|
||||
}
|
||||
|
||||
bool
|
||||
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||
{
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
Promise* promise = mPromiseProxy->WorkerPromise();
|
||||
MOZ_ASSERT(promise);
|
||||
|
||||
nsTArray<RefPtr<ServiceWorkerClient>> ret;
|
||||
for (size_t i = 0; i < mValue.Length(); i++) {
|
||||
ret.AppendElement(RefPtr<ServiceWorkerClient>(
|
||||
new ServiceWorkerWindowClient(promise->GetParentObject(),
|
||||
mValue.ElementAt(i))));
|
||||
}
|
||||
|
||||
promise->MaybeResolve(ret);
|
||||
mPromiseProxy->CleanUp(aCx);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
RefPtr<PromiseWorkerProxy> mPromiseProxy;
|
||||
nsCString mScope;
|
||||
bool mIncludeUncontrolled;
|
||||
public:
|
||||
MatchAllRunnable(PromiseWorkerProxy* aPromiseProxy,
|
||||
const nsCString& aScope)
|
||||
const nsCString& aScope,
|
||||
bool aIncludeUncontrolled)
|
||||
: mPromiseProxy(aPromiseProxy),
|
||||
mScope(aScope)
|
||||
mScope(aScope),
|
||||
mIncludeUncontrolled(aIncludeUncontrolled)
|
||||
{
|
||||
MOZ_ASSERT(mPromiseProxy);
|
||||
}
|
||||
@@ -119,7 +206,8 @@ public:
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
nsTArray<ServiceWorkerClientInfo> result;
|
||||
|
||||
swm->GetAllClients(mPromiseProxy->GetWorkerPrivate()->GetPrincipal(), mScope, result);
|
||||
swm->GetAllClients(mPromiseProxy->GetWorkerPrivate()->GetPrincipal(), mScope,
|
||||
mIncludeUncontrolled, result);
|
||||
RefPtr<ResolvePromiseWorkerRunnable> r =
|
||||
new ResolvePromiseWorkerRunnable(mPromiseProxy->GetWorkerPrivate(),
|
||||
mPromiseProxy, result);
|
||||
@@ -569,6 +657,31 @@ private:
|
||||
|
||||
} // namespace
|
||||
|
||||
already_AddRefed<Promise>
|
||||
ServiceWorkerClients::Get(const nsAString& aClientId, ErrorResult& aRv)
|
||||
{
|
||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
workerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
RefPtr<Promise> promise = Promise::Create(mWorkerScope, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<PromiseWorkerProxy> promiseProxy =
|
||||
PromiseWorkerProxy::Create(workerPrivate, promise);
|
||||
if (!promiseProxy) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
RefPtr<GetRunnable> r =
|
||||
new GetRunnable(promiseProxy, aClientId);
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(r)));
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
ServiceWorkerClients::MatchAll(const ClientQueryOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
@@ -580,7 +693,7 @@ ServiceWorkerClients::MatchAll(const ClientQueryOptions& aOptions,
|
||||
nsString scope;
|
||||
mWorkerScope->GetScope(scope);
|
||||
|
||||
if (aOptions.mIncludeUncontrolled || aOptions.mType != ClientType::Window) {
|
||||
if (aOptions.mType != ClientType::Window) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
@@ -599,7 +712,8 @@ ServiceWorkerClients::MatchAll(const ClientQueryOptions& aOptions,
|
||||
|
||||
RefPtr<MatchAllRunnable> r =
|
||||
new MatchAllRunnable(promiseProxy,
|
||||
NS_ConvertUTF16toUTF8(scope));
|
||||
NS_ConvertUTF16toUTF8(scope),
|
||||
aOptions.mIncludeUncontrolled);
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(r)));
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@ public:
|
||||
|
||||
explicit ServiceWorkerClients(ServiceWorkerGlobalScope* aWorkerScope);
|
||||
|
||||
already_AddRefed<Promise>
|
||||
Get(const nsAString& aClientId, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<Promise>
|
||||
MatchAll(const ClientQueryOptions& aOptions, ErrorResult& aRv);
|
||||
|
||||
|
||||
@@ -102,6 +102,7 @@ FetchEvent::Constructor(const GlobalObject& aGlobal,
|
||||
e->SetTrusted(trusted);
|
||||
e->mRequest = aOptions.mRequest.WasPassed() ?
|
||||
&aOptions.mRequest.Value() : nullptr;
|
||||
e->mClientId = aOptions.mClientId;
|
||||
e->mIsReload = aOptions.mIsReload;
|
||||
return e.forget();
|
||||
}
|
||||
|
||||
@@ -107,6 +107,7 @@ class FetchEvent final : public ExtendableEvent
|
||||
RefPtr<Request> mRequest;
|
||||
nsCString mScriptSpec;
|
||||
nsCString mPreventDefaultScriptSpec;
|
||||
nsString mClientId;
|
||||
uint32_t mPreventDefaultLineNumber;
|
||||
uint32_t mPreventDefaultColumnNumber;
|
||||
bool mIsReload;
|
||||
@@ -149,6 +150,12 @@ public:
|
||||
return mRequest;
|
||||
}
|
||||
|
||||
void
|
||||
GetClientId(nsAString& aClientId) const
|
||||
{
|
||||
aClientId = mClientId;
|
||||
}
|
||||
|
||||
bool
|
||||
IsReload() const
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,7 @@
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/TypedEnumBits.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
@@ -24,9 +25,9 @@
|
||||
#include "mozilla/dom/ServiceWorkerRegistrar.h"
|
||||
#include "mozilla/dom/ServiceWorkerRegistrarTypes.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "nsIIPCBackgroundChildCreateCallback.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsIIPCBackgroundChildCreateCallback.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsTArrayForwardDeclare.h"
|
||||
#include "nsTObserverArray.h"
|
||||
@@ -35,7 +36,7 @@ class mozIApplicationClearPrivateDataParams;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class OriginAttributes;
|
||||
class PrincipalOriginAttributes;
|
||||
|
||||
namespace dom {
|
||||
|
||||
@@ -47,13 +48,12 @@ class ServiceWorker;
|
||||
class ServiceWorkerClientInfo;
|
||||
class ServiceWorkerInfo;
|
||||
class ServiceWorkerJob;
|
||||
class ServiceWorkerRegisterJob;
|
||||
class ServiceWorkerJobQueue;
|
||||
class ServiceWorkerManagerChild;
|
||||
class ServiceWorkerPrivate;
|
||||
class ServiceWorkerUpdateFinishCallback;
|
||||
|
||||
class ServiceWorkerRegistrationInfo final : public nsIServiceWorkerRegistrationInfo
|
||||
class ServiceWorkerRegistrationInfo final
|
||||
: public nsIServiceWorkerRegistrationInfo
|
||||
{
|
||||
uint32_t mControlledDocumentsCounter;
|
||||
|
||||
@@ -78,7 +78,11 @@ public:
|
||||
|
||||
uint64_t mLastUpdateCheckTime;
|
||||
|
||||
RefPtr<ServiceWorkerRegisterJob> mUpdateJob;
|
||||
// According to the spec, Soft Update shouldn't queue an update job
|
||||
// if the registration queue is not empty. Because our job queue
|
||||
// works slightly different, we use a flag to determine if the registration
|
||||
// is already updating.
|
||||
bool mUpdating;
|
||||
|
||||
// When unregister() is called on a registration, it is not immediately
|
||||
// removed since documents may be controlled. It is marked as
|
||||
@@ -115,13 +119,14 @@ public:
|
||||
void
|
||||
StopControllingADocument()
|
||||
{
|
||||
MOZ_ASSERT(mControlledDocumentsCounter);
|
||||
--mControlledDocumentsCounter;
|
||||
}
|
||||
|
||||
bool
|
||||
IsControllingDocuments() const
|
||||
{
|
||||
return mActiveWorker && mControlledDocumentsCounter > 0;
|
||||
return mActiveWorker && mControlledDocumentsCounter;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -147,19 +152,13 @@ public:
|
||||
|
||||
void
|
||||
NotifyListenersOnChange();
|
||||
|
||||
bool
|
||||
IsUpdating() const;
|
||||
|
||||
void
|
||||
AppendUpdateCallback(ServiceWorkerUpdateFinishCallback* aCallback);
|
||||
};
|
||||
|
||||
class ServiceWorkerUpdateFinishCallback
|
||||
{
|
||||
protected:
|
||||
virtual ~ServiceWorkerUpdateFinishCallback()
|
||||
{ }
|
||||
{}
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(ServiceWorkerUpdateFinishCallback)
|
||||
@@ -281,6 +280,7 @@ public:
|
||||
void
|
||||
SetActivateStateUncheckedWithoutEvent(ServiceWorkerState aState)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
mState = aState;
|
||||
}
|
||||
|
||||
@@ -313,7 +313,9 @@ class ServiceWorkerManager final
|
||||
friend class GetRegistrationsRunnable;
|
||||
friend class GetRegistrationRunnable;
|
||||
friend class ServiceWorkerJobQueue;
|
||||
friend class ServiceWorkerInstallJob;
|
||||
friend class ServiceWorkerRegisterJob;
|
||||
friend class ServiceWorkerJobBase;
|
||||
friend class ServiceWorkerRegistrationInfo;
|
||||
friend class ServiceWorkerUnregisterJob;
|
||||
|
||||
@@ -351,17 +353,18 @@ public:
|
||||
nsClassHashtable<nsCStringHashKey, InterceptionList> mNavigationInterceptions;
|
||||
|
||||
bool
|
||||
IsAvailable(const OriginAttributes& aOriginAttributes, nsIURI* aURI);
|
||||
IsAvailable(const PrincipalOriginAttributes& aOriginAttributes, nsIURI* aURI);
|
||||
|
||||
bool
|
||||
IsControlled(nsIDocument* aDocument, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<nsIRunnable>
|
||||
PrepareFetchEvent(const OriginAttributes& aOriginAttributes,
|
||||
PrepareFetchEvent(const PrincipalOriginAttributes& aOriginAttributes,
|
||||
nsIDocument* aDoc,
|
||||
const nsAString& aDocumentIdForTopLevelNavigation,
|
||||
nsIInterceptedChannel* aChannel,
|
||||
bool aIsReload,
|
||||
bool aIsSubresourceLoad,
|
||||
bool aIsSubresourceLoad,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void
|
||||
@@ -370,17 +373,16 @@ public:
|
||||
ErrorResult& aRv);
|
||||
|
||||
void
|
||||
SoftUpdate(nsIPrincipal* aPrincipal,
|
||||
const nsACString& aScope,
|
||||
ServiceWorkerUpdateFinishCallback* aCallback = nullptr);
|
||||
Update(nsIPrincipal* aPrincipal,
|
||||
const nsACString& aScope,
|
||||
ServiceWorkerUpdateFinishCallback* aCallback);
|
||||
|
||||
void
|
||||
SoftUpdate(const OriginAttributes& aOriginAttributes,
|
||||
const nsACString& aScope,
|
||||
ServiceWorkerUpdateFinishCallback* aCallback = nullptr);
|
||||
const nsACString& aScope);
|
||||
|
||||
void
|
||||
PropagateSoftUpdate(const OriginAttributes& aOriginAttributes,
|
||||
PropagateSoftUpdate(const PrincipalOriginAttributes& aOriginAttributes,
|
||||
const nsAString& aScope);
|
||||
|
||||
void
|
||||
@@ -434,10 +436,16 @@ public:
|
||||
uint32_t aFlags,
|
||||
JSExnType aExnType);
|
||||
|
||||
UniquePtr<ServiceWorkerClientInfo>
|
||||
GetClient(nsIPrincipal* aPrincipal,
|
||||
const nsAString& aClientId,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void
|
||||
GetAllClients(nsIPrincipal* aPrincipal,
|
||||
const nsCString& aScope,
|
||||
nsTArray<ServiceWorkerClientInfo>& aControlledDocuments);
|
||||
bool aIncludeUncontrolled,
|
||||
nsTArray<ServiceWorkerClientInfo>& aDocuments);
|
||||
|
||||
void
|
||||
MaybeClaimClient(nsIDocument* aDocument,
|
||||
@@ -486,11 +494,6 @@ private:
|
||||
void
|
||||
MaybeRemoveRegistrationInfo(const nsACString& aScopeKey);
|
||||
|
||||
void
|
||||
SoftUpdate(const nsACString& aScopeKey,
|
||||
const nsACString& aScope,
|
||||
ServiceWorkerUpdateFinishCallback* aCallback = nullptr);
|
||||
|
||||
already_AddRefed<ServiceWorkerRegistrationInfo>
|
||||
GetRegistration(const nsACString& aScopeKey,
|
||||
const nsACString& aScope) const;
|
||||
@@ -502,7 +505,8 @@ private:
|
||||
Update(ServiceWorkerRegistrationInfo* aRegistration);
|
||||
|
||||
nsresult
|
||||
GetDocumentRegistration(nsIDocument* aDoc, ServiceWorkerRegistrationInfo** aRegistrationInfo);
|
||||
GetDocumentRegistration(nsIDocument* aDoc,
|
||||
ServiceWorkerRegistrationInfo** aRegistrationInfo);
|
||||
|
||||
NS_IMETHODIMP
|
||||
GetServiceWorkerForScope(nsIDOMWindow* aWindow,
|
||||
@@ -511,7 +515,7 @@ private:
|
||||
nsISupports** aServiceWorker);
|
||||
|
||||
ServiceWorkerInfo*
|
||||
GetActiveWorkerInfoForScope(const OriginAttributes& aOriginAttributes,
|
||||
GetActiveWorkerInfoForScope(const PrincipalOriginAttributes& aOriginAttributes,
|
||||
const nsACString& aScope);
|
||||
|
||||
ServiceWorkerInfo*
|
||||
@@ -521,9 +525,13 @@ private:
|
||||
InvalidateServiceWorkerRegistrationWorker(ServiceWorkerRegistrationInfo* aRegistration,
|
||||
WhichServiceWorker aWhichOnes);
|
||||
|
||||
void
|
||||
NotifyServiceWorkerRegistrationRemoved(ServiceWorkerRegistrationInfo* aRegistration);
|
||||
|
||||
void
|
||||
StartControllingADocument(ServiceWorkerRegistrationInfo* aRegistration,
|
||||
nsIDocument* aDoc);
|
||||
nsIDocument* aDoc,
|
||||
const nsAString& aDocumentId);
|
||||
|
||||
void
|
||||
StopControllingADocument(ServiceWorkerRegistrationInfo* aRegistration);
|
||||
@@ -538,7 +546,7 @@ private:
|
||||
GetServiceWorkerRegistrationInfo(nsIPrincipal* aPrincipal, nsIURI* aURI);
|
||||
|
||||
already_AddRefed<ServiceWorkerRegistrationInfo>
|
||||
GetServiceWorkerRegistrationInfo(const OriginAttributes& aOriginAttributes,
|
||||
GetServiceWorkerRegistrationInfo(const PrincipalOriginAttributes& aOriginAttributes,
|
||||
nsIURI* aURI);
|
||||
|
||||
already_AddRefed<ServiceWorkerRegistrationInfo>
|
||||
@@ -577,7 +585,8 @@ private:
|
||||
FireControllerChange(ServiceWorkerRegistrationInfo* aRegistration);
|
||||
|
||||
void
|
||||
StorePendingReadyPromise(nsPIDOMWindow* aWindow, nsIURI* aURI, Promise* aPromise);
|
||||
StorePendingReadyPromise(nsPIDOMWindow* aWindow, nsIURI* aURI,
|
||||
Promise* aPromise);
|
||||
|
||||
void
|
||||
CheckPendingReadyPromises();
|
||||
@@ -585,11 +594,11 @@ private:
|
||||
bool
|
||||
CheckReadyPromise(nsPIDOMWindow* aWindow, nsIURI* aURI, Promise* aPromise);
|
||||
|
||||
struct PendingReadyPromise
|
||||
struct PendingReadyPromise final
|
||||
{
|
||||
PendingReadyPromise(nsIURI* aURI, Promise* aPromise)
|
||||
: mURI(aURI), mPromise(aPromise)
|
||||
{ }
|
||||
{}
|
||||
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
RefPtr<Promise> mPromise;
|
||||
@@ -620,7 +629,7 @@ private:
|
||||
// Removes all service worker registrations that matches the given
|
||||
// mozIApplicationClearPrivateDataParams.
|
||||
void
|
||||
RemoveAllRegistrations(OriginAttributes* aParams);
|
||||
RemoveAllRegistrations(PrincipalOriginAttributes* aParams);
|
||||
|
||||
RefPtr<ServiceWorkerManagerChild> mActor;
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ ServiceWorkerManagerChild::RecvNotifyRegister(
|
||||
|
||||
bool
|
||||
ServiceWorkerManagerChild::RecvNotifySoftUpdate(
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
const PrincipalOriginAttributes& aOriginAttributes,
|
||||
const nsString& aScope)
|
||||
{
|
||||
if (mShuttingDown) {
|
||||
@@ -42,7 +42,7 @@ ServiceWorkerManagerChild::RecvNotifySoftUpdate(
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
MOZ_ASSERT(swm);
|
||||
|
||||
swm->SoftUpdate(aOriginAttributes, NS_ConvertUTF16toUTF8(aScope), nullptr);
|
||||
swm->SoftUpdate(aOriginAttributes, NS_ConvertUTF16toUTF8(aScope));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class OriginAttributes;
|
||||
class PrincipalOriginAttributes;
|
||||
|
||||
namespace ipc {
|
||||
class BackgroundChildImpl;
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
virtual bool RecvNotifyRegister(const ServiceWorkerRegistrationData& aData)
|
||||
override;
|
||||
|
||||
virtual bool RecvNotifySoftUpdate(const OriginAttributes& aOriginAttributes,
|
||||
virtual bool RecvNotifySoftUpdate(const PrincipalOriginAttributes& aOriginAttributes,
|
||||
const nsString& aScope) override;
|
||||
|
||||
virtual bool RecvNotifyUnregister(const PrincipalInfo& aPrincipalInfo,
|
||||
|
||||
@@ -232,7 +232,7 @@ ServiceWorkerManagerParent::RecvUnregister(const PrincipalInfo& aPrincipalInfo,
|
||||
}
|
||||
|
||||
bool
|
||||
ServiceWorkerManagerParent::RecvPropagateSoftUpdate(const OriginAttributes& aOriginAttributes,
|
||||
ServiceWorkerManagerParent::RecvPropagateSoftUpdate(const PrincipalOriginAttributes& aOriginAttributes,
|
||||
const nsString& aScope)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class OriginAttributes;
|
||||
class PrincipalOriginAttributes;
|
||||
|
||||
namespace ipc {
|
||||
class BackgroundParentImpl;
|
||||
}
|
||||
} // namespace ipc
|
||||
|
||||
namespace dom {
|
||||
namespace workers {
|
||||
@@ -42,7 +42,7 @@ private:
|
||||
virtual bool RecvUnregister(const PrincipalInfo& aPrincipalInfo,
|
||||
const nsString& aScope) override;
|
||||
|
||||
virtual bool RecvPropagateSoftUpdate(const OriginAttributes& aOriginAttributes,
|
||||
virtual bool RecvPropagateSoftUpdate(const PrincipalOriginAttributes& aOriginAttributes,
|
||||
const nsString& aScope) override;
|
||||
|
||||
virtual bool RecvPropagateUnregister(const PrincipalInfo& aPrincipalInfo,
|
||||
@@ -63,8 +63,8 @@ private:
|
||||
uint64_t mID;
|
||||
};
|
||||
|
||||
} // workers namespace
|
||||
} // dom namespace
|
||||
} // mozilla namespace
|
||||
} // namespace workers
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_ServiceWorkerManagerParent_h
|
||||
|
||||
@@ -111,7 +111,7 @@ ServiceWorkerManagerService::PropagateRegistration(
|
||||
void
|
||||
ServiceWorkerManagerService::PropagateSoftUpdate(
|
||||
uint64_t aParentID,
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
const PrincipalOriginAttributes& aOriginAttributes,
|
||||
const nsAString& aScope)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class OriginAttributes;
|
||||
class PrincipalOriginAttributes;
|
||||
|
||||
namespace ipc {
|
||||
class PrincipalInfo;
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
ServiceWorkerRegistrationData& aData);
|
||||
|
||||
void PropagateSoftUpdate(uint64_t aParentID,
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
const PrincipalOriginAttributes& aOriginAttributes,
|
||||
const nsAString& aScope);
|
||||
|
||||
void PropagateUnregister(uint64_t aParentID,
|
||||
|
||||
@@ -61,6 +61,7 @@ NS_IMPL_ISUPPORTS0(KeepAliveToken)
|
||||
ServiceWorkerPrivate::ServiceWorkerPrivate(ServiceWorkerInfo* aInfo)
|
||||
: mInfo(aInfo)
|
||||
, mIsPushWorker(false)
|
||||
, mDebuggerCount(0)
|
||||
, mTokenCount(0)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
@@ -103,46 +104,64 @@ namespace {
|
||||
class CheckScriptEvaluationWithCallback final : public WorkerRunnable
|
||||
{
|
||||
nsMainThreadPtrHandle<KeepAliveToken> mKeepAliveToken;
|
||||
RefPtr<nsRunnable> mCallback;
|
||||
RefPtr<LifeCycleEventCallback> mCallback;
|
||||
DebugOnly<bool> mDone;
|
||||
|
||||
public:
|
||||
CheckScriptEvaluationWithCallback(WorkerPrivate* aWorkerPrivate,
|
||||
KeepAliveToken* aKeepAliveToken,
|
||||
nsRunnable* aCallback)
|
||||
LifeCycleEventCallback* aCallback)
|
||||
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
|
||||
, mKeepAliveToken(new nsMainThreadPtrHolder<KeepAliveToken>(aKeepAliveToken))
|
||||
, mCallback(aCallback)
|
||||
, mDone(false)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
}
|
||||
|
||||
~CheckScriptEvaluationWithCallback()
|
||||
{
|
||||
MOZ_ASSERT(mDone);
|
||||
}
|
||||
|
||||
bool
|
||||
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
|
||||
{
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
if (aWorkerPrivate->WorkerScriptExecutedSuccessfully()) {
|
||||
nsresult rv = NS_DispatchToMainThread(mCallback);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to dispatch CheckScriptEvaluation callback.");
|
||||
}
|
||||
}
|
||||
Done(aWorkerPrivate->WorkerScriptExecutedSuccessfully());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Cancel() override
|
||||
{
|
||||
Done(false);
|
||||
return WorkerRunnable::Cancel();
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
Done(bool aResult)
|
||||
{
|
||||
mDone = true;
|
||||
mCallback->SetResult(aResult);
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(mCallback)));
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
nsresult
|
||||
ServiceWorkerPrivate::ContinueOnSuccessfulScriptEvaluation(nsRunnable* aCallback)
|
||||
ServiceWorkerPrivate::CheckScriptEvaluation(LifeCycleEventCallback* aCallback)
|
||||
{
|
||||
nsresult rv = SpawnWorkerIfNeeded(LifeCycleEvent, nullptr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
MOZ_ASSERT(mKeepAliveToken);
|
||||
RefPtr<WorkerRunnable> r = new CheckScriptEvaluationWithCallback(mWorkerPrivate,
|
||||
mKeepAliveToken,
|
||||
aCallback);
|
||||
mKeepAliveToken,
|
||||
aCallback);
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
if (NS_WARN_IF(!r->Dispatch(jsapi.cx()))) {
|
||||
@@ -211,7 +230,7 @@ public:
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
MOZ_ASSERT(swm);
|
||||
|
||||
OriginAttributes attrs =
|
||||
PrincipalOriginAttributes attrs =
|
||||
mozilla::BasePrincipal::Cast(mRegistration->mPrincipal)->OriginAttributesRef();
|
||||
|
||||
swm->PropagateSoftUpdate(attrs,
|
||||
@@ -352,6 +371,15 @@ public:
|
||||
return DispatchLifecycleEvent(aCx, aWorkerPrivate);
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Cancel() override
|
||||
{
|
||||
mCallback->SetResult(false);
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(mCallback)));
|
||||
|
||||
return WorkerRunnable::Cancel();
|
||||
}
|
||||
|
||||
private:
|
||||
bool
|
||||
DispatchLifecycleEvent(JSContext* aCx, WorkerPrivate* aWorkerPrivate);
|
||||
@@ -359,52 +387,116 @@ private:
|
||||
};
|
||||
|
||||
/*
|
||||
* Used to handle ExtendableEvent::waitUntil() and proceed with
|
||||
* installation/activation.
|
||||
* Used to handle ExtendableEvent::waitUntil() and catch abnormal worker
|
||||
* termination during the execution of life cycle events. It is responsible
|
||||
* with advancing the job queue for install/activate tasks.
|
||||
*/
|
||||
class LifecycleEventPromiseHandler final : public PromiseNativeHandler
|
||||
class LifeCycleEventWatcher final : public PromiseNativeHandler,
|
||||
public WorkerFeature
|
||||
{
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
RefPtr<LifeCycleEventCallback> mCallback;
|
||||
bool mDone;
|
||||
|
||||
virtual
|
||||
~LifecycleEventPromiseHandler()
|
||||
{ }
|
||||
~LifeCycleEventWatcher()
|
||||
{
|
||||
if (mDone) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(GetCurrentThreadWorkerPrivate() == mWorkerPrivate);
|
||||
// XXXcatalinb: If all the promises passed to waitUntil go out of scope,
|
||||
// the resulting Promise.all will be cycle collected and it will drop its
|
||||
// native handlers (including this object). Instead of waiting for a timeout
|
||||
// we report the failure now.
|
||||
JSContext* cx = mWorkerPrivate->GetJSContext();
|
||||
ReportResult(cx, false);
|
||||
}
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
explicit LifecycleEventPromiseHandler(LifeCycleEventCallback* aCallback)
|
||||
: mCallback(aCallback)
|
||||
LifeCycleEventWatcher(WorkerPrivate* aWorkerPrivate,
|
||||
LifeCycleEventCallback* aCallback)
|
||||
: mWorkerPrivate(aWorkerPrivate)
|
||||
, mCallback(aCallback)
|
||||
, mDone(false)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
|
||||
bool
|
||||
Init()
|
||||
{
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
JSContext* cx = mWorkerPrivate->GetJSContext();
|
||||
|
||||
// We need to listen for worker termination in case the event handler
|
||||
// never completes or never resolves the waitUntil promise. There are
|
||||
// two possible scenarios:
|
||||
// 1. The keepAlive token expires and the worker is terminated, in which
|
||||
// case the registration/update promise will be rejected
|
||||
// 2. A new service worker is registered which will terminate the current
|
||||
// installing worker.
|
||||
if (NS_WARN_IF(!mWorkerPrivate->AddFeature(cx, this))) {
|
||||
NS_WARNING("LifeCycleEventWatcher failed to add feature.");
|
||||
ReportResult(cx, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Notify(JSContext* aCx, Status aStatus) override
|
||||
{
|
||||
if (aStatus < Terminating) {
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(GetCurrentThreadWorkerPrivate() == mWorkerPrivate);
|
||||
ReportResult(aCx, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ReportResult(JSContext* aCx, bool aResult)
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
if (mDone) {
|
||||
return;
|
||||
}
|
||||
mDone = true;
|
||||
|
||||
mCallback->SetResult(aResult);
|
||||
nsresult rv = NS_DispatchToMainThread(mCallback);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
NS_RUNTIMEABORT("Failed to dispatch life cycle event handler.");
|
||||
}
|
||||
|
||||
mWorkerPrivate->RemoveFeature(aCx, this);
|
||||
}
|
||||
|
||||
void
|
||||
ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override
|
||||
{
|
||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
workerPrivate->AssertIsOnWorkerThread();
|
||||
MOZ_ASSERT(GetCurrentThreadWorkerPrivate() == mWorkerPrivate);
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
mCallback->SetResult(true);
|
||||
nsresult rv = NS_DispatchToMainThread(mCallback);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
NS_RUNTIMEABORT("Failed to dispatch life cycle event handler.");
|
||||
}
|
||||
ReportResult(aCx, true);
|
||||
}
|
||||
|
||||
void
|
||||
RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override
|
||||
{
|
||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
workerPrivate->AssertIsOnWorkerThread();
|
||||
MOZ_ASSERT(GetCurrentThreadWorkerPrivate() == mWorkerPrivate);
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
mCallback->SetResult(false);
|
||||
nsresult rv = NS_DispatchToMainThread(mCallback);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
NS_RUNTIMEABORT("Failed to dispatch life cycle event handler.");
|
||||
}
|
||||
ReportResult(aCx, false);
|
||||
|
||||
// Note, all WaitUntil() rejections are reported to client consoles
|
||||
// by the WaitUntilHandler in ServiceWorkerEvents. This ensures that
|
||||
@@ -413,7 +505,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS0(LifecycleEventPromiseHandler)
|
||||
NS_IMPL_ISUPPORTS0(LifeCycleEventWatcher)
|
||||
|
||||
bool
|
||||
LifecycleEventWorkerRunnable::DispatchLifecycleEvent(JSContext* aCx,
|
||||
@@ -436,16 +528,23 @@ LifecycleEventWorkerRunnable::DispatchLifecycleEvent(JSContext* aCx,
|
||||
|
||||
event->SetTrusted(true);
|
||||
|
||||
// It is important to initialize the watcher before actually dispatching
|
||||
// the event in order to catch worker termination while the event handler
|
||||
// is still executing. This can happen with infinite loops, for example.
|
||||
RefPtr<LifeCycleEventWatcher> watcher =
|
||||
new LifeCycleEventWatcher(aWorkerPrivate, mCallback);
|
||||
|
||||
if (!watcher->Init()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
RefPtr<Promise> waitUntil;
|
||||
DispatchExtendableEventOnWorkerScope(aCx, aWorkerPrivate->GlobalScope(),
|
||||
event, getter_AddRefs(waitUntil));
|
||||
if (waitUntil) {
|
||||
RefPtr<LifecycleEventPromiseHandler> handler =
|
||||
new LifecycleEventPromiseHandler(mCallback);
|
||||
waitUntil->AppendNativeHandler(handler);
|
||||
waitUntil->AppendNativeHandler(watcher);
|
||||
} else {
|
||||
mCallback->SetResult(false);
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(mCallback)));
|
||||
watcher->ReportResult(aCx, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -590,6 +689,14 @@ ServiceWorkerPrivate::SendPushEvent(const Maybe<nsTArray<uint8_t>>& aData,
|
||||
mKeepAliveToken,
|
||||
aData,
|
||||
regInfo);
|
||||
|
||||
if (mInfo->State() == ServiceWorkerState::Activating) {
|
||||
mPendingFunctionalEvents.AppendElement(r.forget());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mInfo->State() == ServiceWorkerState::Activated);
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
if (NS_WARN_IF(!r->Dispatch(jsapi.cx()))) {
|
||||
@@ -909,6 +1016,7 @@ class FetchEventRunnable : public ExtendableFunctionalEventWorkerRunnable
|
||||
nsTArray<nsCString> mHeaderValues;
|
||||
nsCString mSpec;
|
||||
nsCString mMethod;
|
||||
nsString mClientId;
|
||||
bool mIsReload;
|
||||
DebugOnly<bool> mIsHttpChannel;
|
||||
RequestMode mRequestMode;
|
||||
@@ -925,12 +1033,13 @@ public:
|
||||
// later on.
|
||||
const nsACString& aScriptSpec,
|
||||
nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo>& aRegistration,
|
||||
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo,
|
||||
const nsAString& aDocumentId,
|
||||
bool aIsReload)
|
||||
: ExtendableFunctionalEventWorkerRunnable(
|
||||
aWorkerPrivate, aKeepAliveToken, aRegistration)
|
||||
, mInterceptedChannel(aChannel)
|
||||
, mScriptSpec(aScriptSpec)
|
||||
, mClientId(aDocumentId)
|
||||
, mIsReload(aIsReload)
|
||||
, mIsHttpChannel(false)
|
||||
, mRequestMode(RequestMode::No_cors)
|
||||
@@ -1057,6 +1166,17 @@ public:
|
||||
return DispatchFetchEvent(aCx, aWorkerPrivate);
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Cancel() override
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> runnable = new ResumeRequest(mInterceptedChannel);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
|
||||
NS_WARNING("Failed to resume channel on FetchEventRunnable::Cancel()!\n");
|
||||
}
|
||||
WorkerRunnable::Cancel();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~FetchEventRunnable() {}
|
||||
|
||||
@@ -1143,6 +1263,7 @@ private:
|
||||
init.mRequest.Value() = request;
|
||||
init.mBubbles = false;
|
||||
init.mCancelable = true;
|
||||
init.mClientId = mClientId;
|
||||
init.mIsReload = mIsReload;
|
||||
RefPtr<FetchEvent> event =
|
||||
FetchEvent::Constructor(globalObj, NS_LITERAL_STRING("fetch"), init, result);
|
||||
@@ -1243,9 +1364,11 @@ NS_IMPL_ISUPPORTS_INHERITED(FetchEventRunnable, WorkerRunnable, nsIHttpHeaderVis
|
||||
nsresult
|
||||
ServiceWorkerPrivate::SendFetchEvent(nsIInterceptedChannel* aChannel,
|
||||
nsILoadGroup* aLoadGroup,
|
||||
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo,
|
||||
const nsAString& aDocumentId,
|
||||
bool aIsReload)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
// if the ServiceWorker script fails to load for some reason, just resume
|
||||
// the original channel.
|
||||
nsCOMPtr<nsIRunnable> failRunnable =
|
||||
@@ -1273,12 +1396,19 @@ ServiceWorkerPrivate::SendFetchEvent(nsIInterceptedChannel* aChannel,
|
||||
RefPtr<FetchEventRunnable> r =
|
||||
new FetchEventRunnable(mWorkerPrivate, mKeepAliveToken, handle,
|
||||
mInfo->ScriptSpec(), regInfo,
|
||||
Move(aClientInfo), aIsReload);
|
||||
aDocumentId, aIsReload);
|
||||
rv = r->Init();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (mInfo->State() == ServiceWorkerState::Activating) {
|
||||
mPendingFunctionalEvents.AppendElement(r.forget());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mInfo->State() == ServiceWorkerState::Activated);
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
if (NS_WARN_IF(!r->Dispatch(jsapi.cx()))) {
|
||||
@@ -1303,7 +1433,7 @@ ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy,
|
||||
|
||||
if (mWorkerPrivate) {
|
||||
mWorkerPrivate->UpdateOverridenLoadGroup(aLoadGroup);
|
||||
ResetIdleTimeout(aWhy);
|
||||
RenewKeepAliveToken(aWhy);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -1383,7 +1513,7 @@ ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy,
|
||||
}
|
||||
|
||||
mIsPushWorker = false;
|
||||
ResetIdleTimeout(aWhy);
|
||||
RenewKeepAliveToken(aWhy);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -1425,6 +1555,15 @@ ServiceWorkerPrivate::TerminateWorker()
|
||||
NS_WARN_IF(!mWorkerPrivate->Terminate(jsapi.cx()));
|
||||
mWorkerPrivate = nullptr;
|
||||
mSupportsArray.Clear();
|
||||
|
||||
// Any pending events are never going to fire on this worker. Cancel
|
||||
// them so that intercepted channels can be reset and other resources
|
||||
// cleaned up.
|
||||
nsTArray<RefPtr<WorkerRunnable>> pendingEvents;
|
||||
mPendingFunctionalEvents.SwapElements(pendingEvents);
|
||||
for (uint32_t i = 0; i < pendingEvents.Length(); ++i) {
|
||||
pendingEvents[i]->Cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1440,13 +1579,98 @@ void
|
||||
ServiceWorkerPrivate::NoteStoppedControllingDocuments()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
if (mIsPushWorker) {
|
||||
if (mIsPushWorker || mDebuggerCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
TerminateWorker();
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerPrivate::Activated()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
// If we had to queue up events due to the worker activating, that means
|
||||
// the worker must be currently running. We should be called synchronously
|
||||
// when the worker becomes activated.
|
||||
MOZ_ASSERT_IF(!mPendingFunctionalEvents.IsEmpty(), mWorkerPrivate);
|
||||
|
||||
nsTArray<RefPtr<WorkerRunnable>> pendingEvents;
|
||||
mPendingFunctionalEvents.SwapElements(pendingEvents);
|
||||
|
||||
for (uint32_t i = 0; i < pendingEvents.Length(); ++i) {
|
||||
RefPtr<WorkerRunnable> r = pendingEvents[i].forget();
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
if (NS_WARN_IF(!r->Dispatch(jsapi.cx()))) {
|
||||
NS_WARNING("Failed to dispatch pending functional event!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
ServiceWorkerPrivate::GetDebugger(nsIWorkerDebugger** aResult)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aResult);
|
||||
|
||||
if (!mDebuggerCount) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
|
||||
nsCOMPtr<nsIWorkerDebugger> debugger = do_QueryInterface(mWorkerPrivate->Debugger());
|
||||
debugger.forget(aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
ServiceWorkerPrivate::AttachDebugger()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
// When the first debugger attaches to a worker, we spawn a worker if needed,
|
||||
// and cancel the idle timeout. The idle timeout should not be reset until
|
||||
// the last debugger detached from the worker.
|
||||
if (!mDebuggerCount) {
|
||||
nsresult rv = SpawnWorkerIfNeeded(AttachEvent, nullptr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mIdleWorkerTimer->Cancel();
|
||||
}
|
||||
|
||||
++mDebuggerCount;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
ServiceWorkerPrivate::DetachDebugger()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (!mDebuggerCount) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
--mDebuggerCount;
|
||||
|
||||
// When the last debugger detaches from a worker, we either reset the idle
|
||||
// timeout, or terminate the worker if there are no more active tokens.
|
||||
if (!mDebuggerCount) {
|
||||
if (mTokenCount) {
|
||||
ResetIdleTimeout();
|
||||
} else {
|
||||
TerminateWorker();
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
ServiceWorkerPrivate::NoteIdleWorkerCallback(nsITimer* aTimer, void* aPrivate)
|
||||
{
|
||||
@@ -1490,24 +1714,36 @@ ServiceWorkerPrivate::TerminateWorkerCallback(nsITimer* aTimer, void *aPrivate)
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerPrivate::ResetIdleTimeout(WakeUpReason aWhy)
|
||||
ServiceWorkerPrivate::RenewKeepAliveToken(WakeUpReason aWhy)
|
||||
{
|
||||
// We should have an active worker if we're reseting the idle timeout
|
||||
// We should have an active worker if we're renewing the keep alive token.
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
|
||||
if (aWhy == PushEvent || aWhy == PushSubscriptionChangeEvent) {
|
||||
mIsPushWorker = true;
|
||||
}
|
||||
|
||||
// If there is at least one debugger attached to the worker, the idle worker
|
||||
// timeout was canceled when the first debugger attached to the worker. It
|
||||
// should not be reset until the last debugger detaches from the worker.
|
||||
if (!mDebuggerCount) {
|
||||
ResetIdleTimeout();
|
||||
}
|
||||
|
||||
if (!mKeepAliveToken) {
|
||||
mKeepAliveToken = new KeepAliveToken(this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerPrivate::ResetIdleTimeout()
|
||||
{
|
||||
uint32_t timeout = Preferences::GetInt("dom.serviceWorkers.idle_timeout");
|
||||
DebugOnly<nsresult> rv =
|
||||
mIdleWorkerTimer->InitWithFuncCallback(ServiceWorkerPrivate::NoteIdleWorkerCallback,
|
||||
this, timeout,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
if (!mKeepAliveToken) {
|
||||
mKeepAliveToken = new KeepAliveToken(this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -72,11 +72,9 @@ public:
|
||||
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo);
|
||||
|
||||
// This is used to validate the worker script and continue the installation
|
||||
// process. Note that the callback is dispatched to the main thread
|
||||
// ONLY if the evaluation was successful. Failure is handled by the JS
|
||||
// exception handler which will call ServiceWorkerManager::HandleError.
|
||||
// process.
|
||||
nsresult
|
||||
ContinueOnSuccessfulScriptEvaluation(nsRunnable* aCallback);
|
||||
CheckScriptEvaluation(LifeCycleEventCallback* aCallback);
|
||||
|
||||
nsresult
|
||||
SendLifeCycleEvent(const nsAString& aEventType,
|
||||
@@ -105,7 +103,7 @@ public:
|
||||
nsresult
|
||||
SendFetchEvent(nsIInterceptedChannel* aChannel,
|
||||
nsILoadGroup* aLoadGroup,
|
||||
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo,
|
||||
const nsAString& aDocumentId,
|
||||
bool aIsReload);
|
||||
|
||||
void
|
||||
@@ -128,6 +126,24 @@ public:
|
||||
void
|
||||
NoteStoppedControllingDocuments();
|
||||
|
||||
WorkerPrivate*
|
||||
GetWorkerPrivate() const
|
||||
{
|
||||
return mWorkerPrivate;
|
||||
}
|
||||
|
||||
void
|
||||
Activated();
|
||||
|
||||
nsresult
|
||||
GetDebugger(nsIWorkerDebugger** aResult);
|
||||
|
||||
nsresult
|
||||
AttachDebugger();
|
||||
|
||||
nsresult
|
||||
DetachDebugger();
|
||||
|
||||
private:
|
||||
enum WakeUpReason {
|
||||
FetchEvent = 0,
|
||||
@@ -135,7 +151,8 @@ private:
|
||||
PushSubscriptionChangeEvent,
|
||||
MessageEvent,
|
||||
NotificationClickEvent,
|
||||
LifeCycleEvent
|
||||
LifeCycleEvent,
|
||||
AttachEvent
|
||||
};
|
||||
|
||||
// Timer callbacks
|
||||
@@ -146,7 +163,10 @@ private:
|
||||
TerminateWorkerCallback(nsITimer* aTimer, void *aPrivate);
|
||||
|
||||
void
|
||||
ResetIdleTimeout(WakeUpReason aWhy);
|
||||
RenewKeepAliveToken(WakeUpReason aWhy);
|
||||
|
||||
void
|
||||
ResetIdleTimeout();
|
||||
|
||||
void
|
||||
AddToken();
|
||||
@@ -184,6 +204,8 @@ private:
|
||||
// worker a grace period after each event.
|
||||
RefPtr<KeepAliveToken> mKeepAliveToken;
|
||||
|
||||
uint64_t mDebuggerCount;
|
||||
|
||||
uint64_t mTokenCount;
|
||||
|
||||
// Meant for keeping objects alive while handling requests from the worker
|
||||
@@ -191,6 +213,10 @@ private:
|
||||
// |StoreISupports| and |RemoveISupports|. Note that the array is also
|
||||
// cleared whenever the worker is terminated.
|
||||
nsTArray<nsCOMPtr<nsISupports>> mSupportsArray;
|
||||
|
||||
// Array of function event worker runnables that are pending due to
|
||||
// the worker activating. Main thread only.
|
||||
nsTArray<RefPtr<WorkerRunnable>> mPendingFunctionalEvents;
|
||||
};
|
||||
|
||||
} // namespace workers
|
||||
|
||||
@@ -326,7 +326,7 @@ ServiceWorkerRegistrar::ReadData()
|
||||
nsAutoCString suffix;
|
||||
GET_LINE(suffix);
|
||||
|
||||
OriginAttributes attrs;
|
||||
PrincipalOriginAttributes attrs;
|
||||
if (!attrs.PopulateFromSuffix(suffix)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
@@ -250,6 +250,19 @@ ServiceWorkerRegistrationMainThread::InvalidateWorkers(WhichServiceWorker aWhich
|
||||
if (aWhichOnes & WhichServiceWorker::ACTIVE_WORKER) {
|
||||
mActiveWorker = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerRegistrationMainThread::RegistrationRemoved()
|
||||
{
|
||||
// If the registration is being removed completely, remove it from the
|
||||
// window registration hash table so that a new registration would get a new
|
||||
// wrapper JS object.
|
||||
nsCOMPtr<nsPIDOMWindow> window = GetOwner();
|
||||
if (window) {
|
||||
window->InvalidateServiceWorkerRegistration(mScope);
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -266,8 +279,7 @@ UpdateInternal(nsIPrincipal* aPrincipal,
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
MOZ_ASSERT(swm);
|
||||
|
||||
// The spec defines ServiceWorkerRegistration.update() exactly as Soft Update.
|
||||
swm->SoftUpdate(aPrincipal, NS_ConvertUTF16toUTF8(aScope), aCallback);
|
||||
swm->Update(aPrincipal, NS_ConvertUTF16toUTF8(aScope), aCallback);
|
||||
}
|
||||
|
||||
class MainThreadUpdateCallback final : public ServiceWorkerUpdateFinishCallback
|
||||
@@ -393,14 +405,22 @@ public:
|
||||
AssertIsOnMainThread();
|
||||
ErrorResult result;
|
||||
|
||||
MutexAutoLock lock(mPromiseProxy->Lock());
|
||||
if (mPromiseProxy->CleanedUp()) {
|
||||
return NS_OK;
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
// UpdateInternal may try to reject the promise synchronously leading
|
||||
// to a deadlock.
|
||||
{
|
||||
MutexAutoLock lock(mPromiseProxy->Lock());
|
||||
if (mPromiseProxy->CleanedUp()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
principal = mPromiseProxy->GetWorkerPrivate()->GetPrincipal();
|
||||
}
|
||||
MOZ_ASSERT(principal);
|
||||
|
||||
RefPtr<WorkerThreadUpdateCallback> cb =
|
||||
new WorkerThreadUpdateCallback(mPromiseProxy);
|
||||
UpdateInternal(mPromiseProxy->GetWorkerPrivate()->GetPrincipal(), mScope, cb);
|
||||
UpdateInternal(principal, mScope, cb);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -857,6 +877,12 @@ public:
|
||||
// FIXME(nsm);
|
||||
}
|
||||
|
||||
void
|
||||
RegistrationRemoved() override
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
}
|
||||
|
||||
void
|
||||
GetScope(nsAString& aScope) const override
|
||||
{
|
||||
|
||||
@@ -65,6 +65,9 @@ public:
|
||||
virtual void
|
||||
InvalidateWorkers(WhichServiceWorker aWhichOnes) = 0;
|
||||
|
||||
virtual void
|
||||
RegistrationRemoved() = 0;
|
||||
|
||||
virtual void
|
||||
GetScope(nsAString& aScope) const = 0;
|
||||
};
|
||||
@@ -106,9 +109,6 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerRegistrationMainThread,
|
||||
ServiceWorkerRegistrationBase)
|
||||
|
||||
ServiceWorkerRegistrationMainThread(nsPIDOMWindow* aWindow,
|
||||
const nsAString& aScope);
|
||||
|
||||
already_AddRefed<Promise>
|
||||
Update(ErrorResult& aRv);
|
||||
|
||||
@@ -154,6 +154,9 @@ public:
|
||||
void
|
||||
InvalidateWorkers(WhichServiceWorker aWhichOnes) override;
|
||||
|
||||
void
|
||||
RegistrationRemoved() override;
|
||||
|
||||
void
|
||||
GetScope(nsAString& aScope) const override
|
||||
{
|
||||
@@ -161,6 +164,9 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
friend nsPIDOMWindow;
|
||||
ServiceWorkerRegistrationMainThread(nsPIDOMWindow* aWindow,
|
||||
const nsAString& aScope);
|
||||
~ServiceWorkerRegistrationMainThread();
|
||||
|
||||
already_AddRefed<workers::ServiceWorker>
|
||||
|
||||
@@ -24,8 +24,7 @@ public:
|
||||
const ServiceWorkerClientInfo& aClientInfo)
|
||||
: ServiceWorkerClient(aOwner, aClientInfo),
|
||||
mVisibilityState(aClientInfo.mVisibilityState),
|
||||
mFocused(aClientInfo.mFocused),
|
||||
mFrameType(aClientInfo.mFrameType)
|
||||
mFocused(aClientInfo.mFocused)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -44,12 +43,6 @@ public:
|
||||
return mFocused;
|
||||
}
|
||||
|
||||
mozilla::dom::FrameType
|
||||
FrameType() const
|
||||
{
|
||||
return mFrameType;
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
Focus(ErrorResult& aRv) const;
|
||||
|
||||
@@ -59,7 +52,6 @@ private:
|
||||
|
||||
mozilla::dom::VisibilityState mVisibilityState;
|
||||
bool mFocused;
|
||||
mozilla::dom::FrameType mFrameType;
|
||||
};
|
||||
|
||||
} // namespace workers
|
||||
|
||||
@@ -2190,24 +2190,11 @@ WorkerPrivateParent<Derived>::WorkerPrivateParent(
|
||||
aParent->CopyJSSettings(mJSSettings);
|
||||
|
||||
MOZ_ASSERT(IsDedicatedWorker());
|
||||
mNowBaseTimeStamp = aParent->NowBaseTimeStamp();
|
||||
mNowBaseTimeHighRes = aParent->NowBaseTimeHighRes();
|
||||
}
|
||||
else {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
RuntimeService::GetDefaultJSSettings(mJSSettings);
|
||||
|
||||
if (IsDedicatedWorker() && mLoadInfo.mWindow &&
|
||||
mLoadInfo.mWindow->GetPerformance()) {
|
||||
mNowBaseTimeStamp = mLoadInfo.mWindow->GetPerformance()->GetDOMTiming()->
|
||||
GetNavigationStartTimeStamp();
|
||||
mNowBaseTimeHighRes = mLoadInfo.mWindow->GetPerformance()->GetDOMTiming()->
|
||||
GetNavigationStartHighRes();
|
||||
} else {
|
||||
mNowBaseTimeStamp = CreationTimeStamp();
|
||||
mNowBaseTimeHighRes = CreationTimeHighRes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -191,8 +191,6 @@ private:
|
||||
WorkerType mWorkerType;
|
||||
TimeStamp mCreationTimeStamp;
|
||||
DOMHighResTimeStamp mCreationTimeHighRes;
|
||||
TimeStamp mNowBaseTimeStamp;
|
||||
DOMHighResTimeStamp mNowBaseTimeHighRes;
|
||||
|
||||
protected:
|
||||
// The worker is owned by its thread, which is represented here. This is set
|
||||
@@ -549,21 +547,11 @@ public:
|
||||
return mCreationTimeStamp;
|
||||
}
|
||||
|
||||
DOMHighResTimeStamp CreationTimeHighRes() const
|
||||
DOMHighResTimeStamp CreationTime() const
|
||||
{
|
||||
return mCreationTimeHighRes;
|
||||
}
|
||||
|
||||
TimeStamp NowBaseTimeStamp() const
|
||||
{
|
||||
return mNowBaseTimeStamp;
|
||||
}
|
||||
|
||||
DOMHighResTimeStamp NowBaseTimeHighRes() const
|
||||
{
|
||||
return mNowBaseTimeHighRes;
|
||||
}
|
||||
|
||||
nsIPrincipal*
|
||||
GetPrincipal() const
|
||||
{
|
||||
@@ -1278,6 +1266,13 @@ public:
|
||||
return mPreferences[WORKERPREF_INTERCEPTION_ENABLED];
|
||||
}
|
||||
|
||||
bool
|
||||
OpenWindowEnabled() const
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
return mPreferences[WORKERPREF_OPEN_WINDOW_ENABLED];
|
||||
}
|
||||
|
||||
bool
|
||||
OpaqueInterceptionEnabled() const
|
||||
{
|
||||
|
||||
@@ -591,7 +591,9 @@ public:
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
runnable->Dispatch(jsapi.cx());
|
||||
if (!runnable->Dispatch(jsapi.cx())) {
|
||||
NS_WARNING("Failed to dispatch SkipWaitingResultRunnable to the worker.");
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
@@ -634,6 +636,15 @@ ServiceWorkerGlobalScope::InterceptionEnabled(JSContext* aCx, JSObject* aObj)
|
||||
return worker->InterceptionEnabled();
|
||||
}
|
||||
|
||||
bool
|
||||
ServiceWorkerGlobalScope::OpenWindowEnabled(JSContext* aCx, JSObject* aObj)
|
||||
{
|
||||
WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
|
||||
MOZ_ASSERT(worker);
|
||||
worker->AssertIsOnWorkerThread();
|
||||
return worker->OpenWindowEnabled();
|
||||
}
|
||||
|
||||
WorkerDebuggerGlobalScope::WorkerDebuggerGlobalScope(
|
||||
WorkerPrivate* aWorkerPrivate)
|
||||
: mWorkerPrivate(aWorkerPrivate)
|
||||
|
||||
@@ -249,6 +249,9 @@ public:
|
||||
static bool
|
||||
InterceptionEnabled(JSContext* aCx, JSObject* aObj);
|
||||
|
||||
static bool
|
||||
OpenWindowEnabled(JSContext* aCx, JSObject* aObj);
|
||||
|
||||
void
|
||||
GetScope(nsString& aScope) const
|
||||
{
|
||||
@@ -265,8 +268,6 @@ public:
|
||||
SkipWaiting(ErrorResult& aRv);
|
||||
|
||||
IMPL_EVENT_HANDLER(activate)
|
||||
IMPL_EVENT_HANDLER(beforeevicted)
|
||||
IMPL_EVENT_HANDLER(evicted)
|
||||
IMPL_EVENT_HANDLER(fetch)
|
||||
IMPL_EVENT_HANDLER(install)
|
||||
IMPL_EVENT_HANDLER(message)
|
||||
|
||||
@@ -201,6 +201,7 @@ enum WorkerPreference
|
||||
WORKERPREF_DOM_CACHES, // dom.caches.enabled
|
||||
WORKERPREF_SERVICEWORKERS, // dom.serviceWorkers.enabled
|
||||
WORKERPREF_INTERCEPTION_ENABLED, // dom.serviceWorkers.interception.enabled
|
||||
WORKERPREF_OPEN_WINDOW_ENABLED, // dom.serviceWorkers.openWindow.enabled
|
||||
WORKERPREF_DOM_WORKERNOTIFICATION, // dom.webnotifications.workers.enabled
|
||||
WORKERPREF_DOM_SERVICEWORKERNOTIFICATION, // dom.webnotifications.serviceworker.enabled
|
||||
WORKERPREF_DOM_CACHES_TESTING, // dom.caches.testing.enabled
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user