Skip to content

Commit

Permalink
Merge inbound to m-c a=merge
Browse files Browse the repository at this point in the history
--HG--
extra : commitid : 8FO2ow49CX2
  • Loading branch information
KWierso committed Nov 17, 2015
2 parents 234f7ca + 9d1f194 commit c4f40f5
Show file tree
Hide file tree
Showing 533 changed files with 8,158 additions and 4,592 deletions.
15 changes: 9 additions & 6 deletions accessible/tests/mochitest/textattrs/test_general.html
Original file line number Diff line number Diff line change
Expand Up @@ -478,14 +478,17 @@
attrs = { "font-family": kAbsentFontFamily };
testTextAttrs(ID, 18, attrs, defAttrs, 18, 22);

attrs = { };
testTextAttrs(ID, 22, attrs, defAttrs, 22, 27);
// bug 1224498 - this fails with 'cursive' fontconfig lookup
if (!LINUX) {
attrs = { };
testTextAttrs(ID, 22, attrs, defAttrs, 22, 27);

attrs = { "font-family": kCursiveFontFamily };
testTextAttrs(ID, 27, attrs, defAttrs, 27, 31);
attrs = { "font-family": kCursiveFontFamily };
testTextAttrs(ID, 27, attrs, defAttrs, 27, 31);

attrs = { };
testTextAttrs(ID, 31, attrs, defAttrs, 31, 44);
attrs = { };
testTextAttrs(ID, 31, attrs, defAttrs, 31, 44);
}

//////////////////////////////////////////////////////////////////////////
// area17, "text-decoration" tests
Expand Down
19 changes: 18 additions & 1 deletion devtools/shared/webconsole/test/helper_serviceworker.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,19 @@
console.log('script evaluation');

console.log("Hello from serviceworker");
addEventListener('install', function(evt) {
console.log('install event');
});

addEventListener('activate', function(evt) {
console.log('activate event');
});

addEventListener('fetch', function(evt) {
console.log('fetch event: ' + evt.request.url);
evt.respondWith(new Response('Hello world'));
});

addEventListener('message', function(evt) {
console.log('message event: ' + evt.data.message);
evt.source.postMessage({ type: 'PONG' });
});
207 changes: 168 additions & 39 deletions devtools/shared/webconsole/test/test_console_serviceworker.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,40 @@
<script class="testbody" type="text/javascript;version=1.8">
SimpleTest.waitForExplicitFinish();

let SERVICE_WORKER_URL = "https://example.com/chrome/devtools/shared/webconsole/test/helper_serviceworker.js";
let FRAME_URL = "https://example.com/chrome/devtools/shared/webconsole/test/sandboxed_iframe.html";
let BASE_URL = "https://example.com/chrome/devtools/shared/webconsole/test/";
let SERVICE_WORKER_URL = BASE_URL + "helper_serviceworker.js";
let SCOPE = BASE_URL + "foo/";
let NONSCOPE_FRAME_URL = BASE_URL + "sandboxed_iframe.html";
let SCOPE_FRAME_URL = SCOPE + "fake.html";
let SCOPE_FRAME_URL2 = SCOPE + "whatsit.html";
let MESSAGE = 'Tic Tock';

let swClosed = new Promise(() => {});
let expectedConsoleCalls = [
{
level: "log",
filename: /helper_serviceworker/,
arguments: ["Hello from serviceworker"],
}
arguments: ['script evaluation'],
},
{
level: "log",
filename: /helper_serviceworker/,
arguments: ['install event'],
},
{
level: "log",
filename: /helper_serviceworker/,
arguments: ['activate event'],
},
{
level: "log",
filename: /helper_serviceworker/,
arguments: ['fetch event: ' + SCOPE_FRAME_URL],
},
{
level: "log",
filename: /helper_serviceworker/,
arguments: ['fetch event: ' + SCOPE_FRAME_URL2],
},
];
let consoleCalls = [];

Expand All @@ -40,55 +64,160 @@
});
addEventListener("load", startTest);

function onAttach(state, response) {
onConsoleAPICall = onConsoleAPICall.bind(null, state);
state.dbgClient.addListener("consoleAPICall", onConsoleAPICall);

info("Loading a ServiceWorker that will use console API");
swClosed = new Promise(resolve => {
function withFrame(url) {
return new Promise(resolve => {
let iframe = document.createElement("iframe");
iframe.onload = function() {
let win = iframe.contentWindow;
info("Registering the service worker");
win.navigator.serviceWorker.register(SERVICE_WORKER_URL).then(swr => {

info("Service worker registered. Unregistering");
swr.unregister().then(() => {
resolve();
});
}, error => {
info("Error registering service worker: " + error);
});
resolve(iframe);
};
iframe.src = FRAME_URL;

iframe.src = url;
document.body.appendChild(iframe);
});
}

function onConsoleAPICall(state, type, packet) {
info("received message level: " + packet.message.level);
is(packet.from, state.actor, "console API call actor");
function navigateFrame(iframe, url) {
return new Promise(resolve => {
iframe.onload = function() {
resolve(iframe);
};
iframe.src = url;
});
}

consoleCalls.push(packet.message);
if (consoleCalls.length != expectedConsoleCalls.length) {
return;
}
function forceReloadFrame(iframe) {
return new Promise(resolve => {
iframe.onload = function() {
resolve(iframe);
};
iframe.contentWindow.location.reload(true);
});
}

state.dbgClient.removeListener("consoleAPICall", onConsoleAPICall);
function withActiveServiceWorker(win, url, scope) {
return win.navigator.serviceWorker.register(url, { scope: scope }).then(swr => {
if (swr.active) {
return swr;
}

// Unfortunately we can't just use navigator.serviceWorker.ready promise
// here. If the service worker is for a scope that does not cover the window
// then the ready promise will never resolve. Instead monitor the service
// workers state change events to determine when its activated.
return new Promise(resolve => {
let sw = swr.waiting || swr.installing;
sw.addEventListener('statechange', function stateHandler(evt) {
if (sw.state === 'activated') {
sw.removeEventListener('statechange', stateHandler);
resolve(swr);
}
});
});
});
}

function messageServiceWorker(win, scope, message) {
return win.navigator.serviceWorker.getRegistration(scope).then(swr => {
return new Promise(resolve => {
win.navigator.serviceWorker.onmessage = evt => {
resolve();
};
let sw = swr.active || swr.waiting || swr.installing;
sw.postMessage({ type: 'PING', message: message });
});
})
}

expectedConsoleCalls.forEach(function(aMessage, aIndex) {
info("checking received console call #" + aIndex);
checkConsoleAPICall(consoleCalls[aIndex], expectedConsoleCalls[aIndex]);
function unregisterServiceWorker(win) {
return win.navigator.serviceWorker.ready.then(swr => {
return swr.unregister();
});
}

consoleCalls = [];
let onAttach = Task.async(function*(state, response) {
onConsoleAPICall = onConsoleAPICall.bind(null, state);
state.dbgClient.addListener("consoleAPICall", onConsoleAPICall);

closeDebugger(state, function() {
swClosed.then(() => {
let currentFrame;
try {
// First, we need a frame from which to register our script. This
// will not trigger any console calls.
info("Loading a non-scope frame from which to register a service worker.");
currentFrame = yield withFrame(NONSCOPE_FRAME_URL);

// Now register the service worker and wait for it to become
// activate. This should trigger 3 console calls; 1 for script
// evaluation, 1 for the install event, and 1 for the activate
// event. These console calls are received because we called
// register(), not because we are in scope for the worker.
info("Registering the service worker");
yield withActiveServiceWorker(currentFrame.contentWindow,
SERVICE_WORKER_URL, SCOPE);
ok(!currentFrame.contentWindow.navigator.serviceWorker.controller,
'current frame should not be controlled');

// Now that the service worker is activate, lets navigate our frame.
// This will trigger 1 more console call for the fetch event.
info("Service worker registered. Navigating frame.");
yield navigateFrame(currentFrame, SCOPE_FRAME_URL);
ok(currentFrame.contentWindow.navigator.serviceWorker.controller,
'navigated frame should be controlled');

// We now have a controlled frame. Lets perform a non-navigation fetch.
// This should produce another console call for the fetch event.
info("Frame navigated. Calling fetch().");
yield currentFrame.contentWindow.fetch(SCOPE_FRAME_URL2);

// Now force refresh our controlled frame. This will cause the frame
// to bypass the service worker and become an uncontrolled frame. It
// also happens to make the frame display a 404 message because the URL
// does not resolve to a real resource. This is ok, as we really only
// care about the frame being non-controlled, but still having a location
// that matches our service worker scope so we can provide its not
// incorrectly getting console calls.
info("Completed fetch(). Force refreshing to get uncontrolled frame.");
yield forceReloadFrame(currentFrame);
ok(!currentFrame.contentWindow.navigator.serviceWorker.controller,
'current frame should not be controlled after force refresh');
is(currentFrame.contentWindow.location.toString(), SCOPE_FRAME_URL,
'current frame should still have in-scope location URL even though it got 404');

// Now postMessage() the service worker to trigger its message event
// handler. This will generate 1 or 2 to console.log() statements
// depending on if the worker thread needs to spin up again. In either
// case, though, we should not get any console calls because we don't
// have a controlled or registering document.
info("Completed force refresh. Messaging service worker.");
yield messageServiceWorker(currentFrame.contentWindow, SCOPE, MESSAGE);

info("Done messaging service worker. Unregistering service worker.");
yield unregisterServiceWorker(currentFrame.contentWindow);

info('Service worker unregistered. Checking console calls.');
state.dbgClient.removeListener("consoleAPICall", onConsoleAPICall);
is(consoleCalls.length, expectedConsoleCalls.length,
'received correct number of console calls');
expectedConsoleCalls.forEach(function(aMessage, aIndex) {
info("checking received console call #" + aIndex);
checkConsoleAPICall(consoleCalls[aIndex], expectedConsoleCalls[aIndex]);
});
} catch(error) {
ok(false, 'unexpected error: ' + error);
} finally {
if (currentFrame) {
currentFrame.remove();
currentFrame = null;
}
consoleCalls = [];
closeDebugger(state, function() {
SimpleTest.finish();
});
});
}
});

function onConsoleAPICall(state, type, packet) {
info("received message level: " + packet.message.level);
is(packet.from, state.actor, "console API call actor");
consoleCalls.push(packet.message);
}
</script>
</body>
Expand Down
31 changes: 6 additions & 25 deletions devtools/shared/webconsole/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ loader.lazyImporter(this, "Services", "resource://gre/modules/Services.jsm");
loader.lazyImporter(this, "VariablesView", "resource://devtools/client/shared/widgets/VariablesView.jsm");
const DevToolsUtils = require("devtools/shared/DevToolsUtils");

XPCOMUtils.defineLazyServiceGetter(this,
"swm",
"@mozilla.org/serviceworkers/manager;1",
"nsIServiceWorkerManager");

// Match the function name from the result of toString() or toSource().
//
// Examples:
Expand Down Expand Up @@ -126,29 +131,6 @@ var WebConsoleUtils = {
aTo.style.fontStyle = style.getPropertyCSSValue("font-style").cssText;
},

/**
* Recursively gather a list of window locations given
* a top level window.
*
* @param nsIDOMWindow aWindow
* @return Array
* list of window locations as strings
*/
getLocationsForFrames: function(aWindow)
{
let location = aWindow.location.toString();
let locations = [location];

if (aWindow.frames) {
for (let i = 0; i < aWindow.frames.length; i++) {
let frame = aWindow.frames[i];
locations = locations.concat(this.getLocationsForFrames(frame));
}
}

return locations;
},

/**
* Gets the ID of the inner window of this DOM window.
*
Expand Down Expand Up @@ -994,9 +976,8 @@ ConsoleAPIListener.prototype =
// scope, which can be used to determine whether it's controlling
// a window.
let scope = message.ID;
let locations = WebConsoleUtils.getLocationsForFrames(this.window);

if (!locations.some(loc => loc.startsWith(scope))) {
if (!swm.shouldReportToWindow(this.window, scope)) {
return false;
}
}
Expand Down
10 changes: 10 additions & 0 deletions docshell/base/nsDocShell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13714,6 +13714,13 @@ nsDocShell::SetIsBrowserInsideApp(uint32_t aContainingAppId)
return NS_OK;
}

NS_IMETHODIMP
nsDocShell::SetIsSignedPackage(const nsAString& aSignedPkg)
{
mSignedPkg = aSignedPkg;
return NS_OK;
}

/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsBrowserElement(bool* aIsBrowser)
{
Expand Down Expand Up @@ -13821,6 +13828,9 @@ nsDocShell::GetOriginAttributes()
attrs.mInBrowser = true;
}

// Bug 1209162 will address the inheritance of each attributes.
attrs.mSignedPkg = mSignedPkg;

return attrs;
}

Expand Down
4 changes: 4 additions & 0 deletions docshell/base/nsDocShell.h
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,10 @@ class nsDocShell final

nsString GetInheritedPaymentRequestId();

// The packageId for a signed packaged iff this docShell is created
// for a signed package.
nsString mSignedPkg;

private:
nsCString mForcedCharset;
nsCString mParentCharset;
Expand Down
8 changes: 7 additions & 1 deletion docshell/base/nsIDocShell.idl
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ interface nsITabParent;

typedef unsigned long nsLoadFlags;

[scriptable, builtinclass, uuid(41b1cf17-b37b-4a62-9df8-5f67cfecab3f)]
[scriptable, builtinclass, uuid(63adb599-6dc9-4746-972e-c22e9018020b)]
interface nsIDocShell : nsIDocShellTreeItem
{
/**
Expand Down Expand Up @@ -824,6 +824,12 @@ interface nsIDocShell : nsIDocShellTreeItem
*/
void setIsBrowserInsideApp(in unsigned long containingAppId);

/**
* Indicate that this docshell corresponds to a signed package with
* the given packageId.
*/
void setIsSignedPackage(in AString packageId);

/**
* Returns the id of the app associated with this docshell. If this docshell
* is an <iframe mozbrowser> inside an <iframe mozapp>, we return the app's
Expand Down
Loading

0 comments on commit c4f40f5

Please sign in to comment.