mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Merge inbound to central, a=merge
MozReview-Commit-ID: 5Ytu9rQ8iD5
This commit is contained in:
commit
cc2a84852b
@ -231,7 +231,6 @@ window:not([chromehidden~="toolbar"]) #urlbar-wrapper {
|
||||
}
|
||||
|
||||
/* No extra vertical padding for nav bar */
|
||||
#nav-bar-customization-target,
|
||||
#nav-bar {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
|
@ -98,7 +98,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media not all and (-moz-windows-default-theme) {
|
||||
@media (-moz-windows-default-theme: 0) {
|
||||
#main-window {
|
||||
background-color: transparent;
|
||||
}
|
||||
@ -225,7 +225,7 @@
|
||||
background-color: hsl(355, 82%, 69%);
|
||||
}
|
||||
}
|
||||
@media not all and (-moz-windows-default-theme) {
|
||||
@media (-moz-windows-default-theme: 0) {
|
||||
.titlebar-button {
|
||||
background-color: -moz-field;
|
||||
}
|
||||
@ -444,7 +444,7 @@
|
||||
}
|
||||
|
||||
/* Aero Basic */
|
||||
@media not all and (-moz-windows-compositor) {
|
||||
@media (-moz-windows-compositor: 0) {
|
||||
@media (-moz-windows-default-theme) {
|
||||
#main-window {
|
||||
background-color: rgb(185,209,234);
|
||||
|
@ -187,8 +187,8 @@ toolbar:-moz-lwtheme {
|
||||
transition: min-height 170ms ease-out, max-height 170ms ease-out, visibility 170ms linear;
|
||||
}
|
||||
|
||||
@media not all and (-moz-windows-compositor),
|
||||
not all and (-moz-windows-default-theme) {
|
||||
@media (-moz-windows-compositor: 0),
|
||||
(-moz-windows-default-theme: 0) {
|
||||
/* Please keep the menu text colors in this media block in sync with
|
||||
* devedition.css, minus the :not(:-moz-lwtheme) condition - see Bug 1165718.
|
||||
*/
|
||||
@ -203,7 +203,7 @@ toolbar:-moz-lwtheme {
|
||||
}
|
||||
}
|
||||
|
||||
@media not all and (-moz-windows-compositor) {
|
||||
@media (-moz-windows-compositor: 0) {
|
||||
#main-window[tabsintitlebar] #titlebar:-moz-lwtheme {
|
||||
visibility: hidden;
|
||||
}
|
||||
@ -383,7 +383,7 @@ toolbar:-moz-lwtheme {
|
||||
border-top: 1px solid @toolbarShadowColor@ !important;
|
||||
box-shadow: 0 1px 0 @toolbarHighlight@ inset;
|
||||
}
|
||||
@media not all and (-moz-windows-compositor) {
|
||||
@media (-moz-windows-compositor: 0) {
|
||||
#TabsToolbar[collapsed="true"] + #nav-bar {
|
||||
border-top-style: none !important;
|
||||
}
|
||||
@ -1614,7 +1614,7 @@ html|span.ac-emphasize-text-url {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@media not all and (-moz-windows-default-theme) {
|
||||
@media (-moz-windows-default-theme: 0) {
|
||||
.autocomplete-richlistitem[selected=true] {
|
||||
background-color: Highlight;
|
||||
}
|
||||
@ -2560,7 +2560,7 @@ notification.pluginVulnerable > .notification-inner > .messageCloseButton {
|
||||
* window caption buttons, and therefore needs to be special-cased.
|
||||
*/
|
||||
@media (-moz-windows-default-theme) {
|
||||
@media not all and (-moz-windows-compositor) {
|
||||
@media (-moz-windows-compositor: 0) {
|
||||
#main-window[sizemode="normal"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
|
||||
background-image: url("chrome://browser/skin/privatebrowsing-mask-titlebar-XPVista7-tall.png");
|
||||
height: 28px;
|
||||
|
@ -120,7 +120,7 @@ menu[disabled="true"].subviewbutton > .menu-right {
|
||||
list-style-image: url(chrome://browser/skin/customizableui/menu-arrow.svg#arrow-disabled);
|
||||
}
|
||||
|
||||
@media not all and (-moz-windows-default-theme) {
|
||||
@media (-moz-windows-default-theme: 0) {
|
||||
menu[_moz-menuactive].subviewbutton > .menu-right {
|
||||
list-style-image: url(chrome://browser/skin/customizableui/menu-arrow.svg#arrow-hover);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
(Win XP or 7 in classic / basic theme), or else dragging and focus become
|
||||
broken. So instead just show the normal titlebar in that case, and override
|
||||
the window color as transparent when the compositor is available. */
|
||||
@media not all and (-moz-windows-compositor) {
|
||||
@media (-moz-windows-compositor: 0) {
|
||||
#main-window[tabsintitlebar] #titlebar:-moz-lwtheme {
|
||||
visibility: visible;
|
||||
}
|
||||
@ -191,8 +191,8 @@
|
||||
}
|
||||
|
||||
/* Use proper menu text styling in Win7 classic mode (copied from browser.css) */
|
||||
@media not all and (-moz-windows-compositor),
|
||||
not all and (-moz-windows-default-theme) {
|
||||
@media (-moz-windows-compositor: 0),
|
||||
(-moz-windows-default-theme: 0) {
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) #toolbar-menubar,
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) #TabsToolbar {
|
||||
color: CaptionText;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
%include ../../../shared/incontentprefs/preferences.inc.css
|
||||
|
||||
@media not all and (-moz-windows-default-theme) {
|
||||
@media (-moz-windows-default-theme: 0) {
|
||||
#category-general > .category-icon {
|
||||
list-style-image: url("chrome://browser/skin/preferences/in-content/icons.svg#general-native");
|
||||
}
|
||||
|
@ -3570,6 +3570,11 @@ nsresult nsContentUtils::FormatLocalizedString(PropertiesFile aFile,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsIStringBundle *bundle = sStringBundles[aFile];
|
||||
|
||||
if (!aParams || !aParamsLength) {
|
||||
return bundle->GetStringFromName(NS_ConvertASCIItoUTF16(aKey).get(),
|
||||
getter_Copies(aResult));
|
||||
}
|
||||
|
||||
return bundle->FormatStringFromName(NS_ConvertASCIItoUTF16(aKey).get(),
|
||||
aParams, aParamsLength,
|
||||
getter_Copies(aResult));
|
||||
|
@ -568,6 +568,34 @@ Event::SetEventType(const nsAString& aEventTypeArg)
|
||||
mEvent->SetDefaultComposedInNativeAnonymousContent();
|
||||
}
|
||||
|
||||
already_AddRefed<EventTarget>
|
||||
Event::EnsureWebAccessibleRelatedTarget(EventTarget* aRelatedTarget)
|
||||
{
|
||||
nsCOMPtr<EventTarget> relatedTarget = aRelatedTarget;
|
||||
if (relatedTarget) {
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(relatedTarget);
|
||||
nsCOMPtr<nsIContent> currentTarget =
|
||||
do_QueryInterface(mEvent->mCurrentTarget);
|
||||
|
||||
if (content && content->ChromeOnlyAccess() &&
|
||||
!nsContentUtils::CanAccessNativeAnon()) {
|
||||
content = content->FindFirstNonChromeOnlyAccessContent();
|
||||
relatedTarget = do_QueryInterface(content);
|
||||
}
|
||||
|
||||
nsIContent* shadowRelatedTarget =
|
||||
GetShadowRelatedTarget(currentTarget, content);
|
||||
if (shadowRelatedTarget) {
|
||||
relatedTarget = shadowRelatedTarget;
|
||||
}
|
||||
|
||||
if (relatedTarget) {
|
||||
relatedTarget = relatedTarget->GetTargetForDOMEvent();
|
||||
}
|
||||
}
|
||||
return relatedTarget.forget();
|
||||
}
|
||||
|
||||
void
|
||||
Event::InitEvent(const nsAString& aEventTypeArg,
|
||||
bool aCanBubbleArg,
|
||||
|
@ -284,6 +284,9 @@ protected:
|
||||
mEvent->SetComposed(aComposed);
|
||||
}
|
||||
|
||||
already_AddRefed<EventTarget>
|
||||
EnsureWebAccessibleRelatedTarget(EventTarget* aRelatedTarget);
|
||||
|
||||
mozilla::WidgetEvent* mEvent;
|
||||
RefPtr<nsPresContext> mPresContext;
|
||||
nsCOMPtr<EventTarget> mExplicitOriginalTarget;
|
||||
|
@ -31,14 +31,15 @@ NS_IMETHODIMP
|
||||
FocusEvent::GetRelatedTarget(nsIDOMEventTarget** aRelatedTarget)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRelatedTarget);
|
||||
NS_IF_ADDREF(*aRelatedTarget = GetRelatedTarget());
|
||||
*aRelatedTarget = GetRelatedTarget().take();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
EventTarget*
|
||||
already_AddRefed<EventTarget>
|
||||
FocusEvent::GetRelatedTarget()
|
||||
{
|
||||
return mEvent->AsFocusEvent()->mRelatedTarget;
|
||||
return
|
||||
EnsureWebAccessibleRelatedTarget(mEvent->AsFocusEvent()->mRelatedTarget);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
nsPresContext* aPresContext,
|
||||
InternalFocusEvent* aEvent);
|
||||
|
||||
EventTarget* GetRelatedTarget();
|
||||
already_AddRefed<EventTarget> GetRelatedTarget();
|
||||
|
||||
static already_AddRefed<FocusEvent> Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aType,
|
||||
|
@ -302,27 +302,7 @@ MouseEvent::GetRelatedTarget()
|
||||
break;
|
||||
}
|
||||
|
||||
if (relatedTarget) {
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(relatedTarget);
|
||||
nsCOMPtr<nsIContent> currentTarget =
|
||||
do_QueryInterface(mEvent->mCurrentTarget);
|
||||
|
||||
nsIContent* shadowRelatedTarget = GetShadowRelatedTarget(currentTarget, content);
|
||||
if (shadowRelatedTarget) {
|
||||
relatedTarget = shadowRelatedTarget;
|
||||
}
|
||||
|
||||
if (content && content->ChromeOnlyAccess() &&
|
||||
!nsContentUtils::CanAccessNativeAnon()) {
|
||||
relatedTarget = do_QueryInterface(content->FindFirstNonChromeOnlyAccessContent());
|
||||
}
|
||||
|
||||
if (relatedTarget) {
|
||||
relatedTarget = relatedTarget->GetTargetForDOMEvent();
|
||||
}
|
||||
return relatedTarget.forget();
|
||||
}
|
||||
return nullptr;
|
||||
return EnsureWebAccessibleRelatedTarget(relatedTarget);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -423,6 +423,7 @@ support-files =
|
||||
[test_bug1146116.html]
|
||||
[test_bug1264157.html]
|
||||
[test_bug1287321.html]
|
||||
[test_bug1323815.html]
|
||||
[test_change_crossorigin.html]
|
||||
[test_checked.html]
|
||||
[test_dir_attributes_reflection.html]
|
||||
|
50
dom/html/test/test_bug1323815.html
Normal file
50
dom/html/test/test_bug1323815.html
Normal file
@ -0,0 +1,50 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1323815
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1323815</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 1323815 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
function test() {
|
||||
var n = document.getElementById("number");
|
||||
var t = document.getElementById("text");
|
||||
t.focus();
|
||||
var gotBlur = false;
|
||||
t.onblur = function(e) {
|
||||
try {
|
||||
is(e.relatedTarget.localName, "input");
|
||||
} catch(ex) {
|
||||
ok(false, "Accessing properties on the relatedTarget shouldn't throw! " + ex);
|
||||
}
|
||||
gotBlur = true;
|
||||
}
|
||||
|
||||
n.focus();
|
||||
ok(gotBlur);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForFocus(test);
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1323815">Mozilla Bug 1323815</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<input type="number" id="number"><input type="text" id="text">
|
||||
</body>
|
||||
</html>
|
@ -229,6 +229,8 @@ ServiceWorkerRegisterNetworkError=Failed to register/update a ServiceWorker for
|
||||
ServiceWorkerRegisterMimeTypeError=Failed to register/update a ServiceWorker for scope ‘%1$S’: Bad Content-Type of ‘%2$S’ received for script ‘%3$S’. Must be ‘text/javascript’, ‘application/x-javascript’, or ‘application/javascript’.
|
||||
# LOCALIZATION NOTE: Do not translate "ServiceWorker". %1$S is a URL representing the scope of the ServiceWorker.
|
||||
ServiceWorkerGraceTimeoutTermination=Terminating ServiceWorker for scope ‘%1$S’ with pending waitUntil/respondWith promises because of grace timeout.
|
||||
# LOCALIZATION NOTE (ServiceWorkerNoFetchHandler): Do not translate "Fetch".
|
||||
ServiceWorkerNoFetchHandler=Fetch event handlers must be added during the worker script’s initial evaluation.
|
||||
ExecCommandCutCopyDeniedNotInputDriven=document.execCommand(‘cut’/‘copy’) was denied because it was not called from inside a short running user-generated event handler.
|
||||
ManifestShouldBeObject=Manifest should be an object.
|
||||
ManifestScopeURLInvalid=The scope URL is invalid.
|
||||
|
@ -118,7 +118,7 @@ WidevineAdapter::GMPGetAPI(const char* aAPIName,
|
||||
return GMPGenericErr;
|
||||
}
|
||||
Log("cdm: 0x%x", cdm);
|
||||
RefPtr<CDMWrapper> wrapper(new CDMWrapper(cdm));
|
||||
RefPtr<CDMWrapper> wrapper(new CDMWrapper(cdm, decryptor));
|
||||
decryptor->SetCDM(wrapper, aDecryptorId);
|
||||
*aPluginAPI = decryptor;
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WidevineUtils.h"
|
||||
#include "WidevineDecryptor.h"
|
||||
|
||||
#include "gmp-api/gmp-errors.h"
|
||||
#include <stdarg.h>
|
||||
@ -76,4 +77,19 @@ void InitInputBuffer(const GMPEncryptedBufferMetadata* aCrypto,
|
||||
aInputBuffer.timestamp = aTimestamp;
|
||||
}
|
||||
|
||||
CDMWrapper::CDMWrapper(cdm::ContentDecryptionModule_8* aCDM,
|
||||
WidevineDecryptor* aDecryptor)
|
||||
: mCDM(aCDM)
|
||||
, mDecryptor(aDecryptor)
|
||||
{
|
||||
MOZ_ASSERT(mCDM);
|
||||
}
|
||||
|
||||
CDMWrapper::~CDMWrapper()
|
||||
{
|
||||
Log("CDMWrapper destroying CDM=%p", mCDM);
|
||||
mCDM->Destroy();
|
||||
mCDM = nullptr;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -42,23 +42,19 @@ Log(const char* aFormat, ...);
|
||||
GMPErr
|
||||
ToGMPErr(cdm::Status aStatus);
|
||||
|
||||
class WidevineDecryptor;
|
||||
|
||||
class CDMWrapper {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CDMWrapper)
|
||||
|
||||
explicit CDMWrapper(cdm::ContentDecryptionModule_8* aCDM)
|
||||
: mCDM(aCDM)
|
||||
{
|
||||
MOZ_ASSERT(mCDM);
|
||||
}
|
||||
explicit CDMWrapper(cdm::ContentDecryptionModule_8* aCDM,
|
||||
WidevineDecryptor* aDecryptor);
|
||||
cdm::ContentDecryptionModule_8* GetCDM() const { return mCDM; }
|
||||
private:
|
||||
~CDMWrapper();
|
||||
cdm::ContentDecryptionModule_8* mCDM;
|
||||
~CDMWrapper() {
|
||||
Log("CDMWrapper destroying CDM=%p", mCDM);
|
||||
mCDM->Destroy();
|
||||
mCDM = nullptr;
|
||||
}
|
||||
RefPtr<WidevineDecryptor> mDecryptor;
|
||||
};
|
||||
|
||||
void InitInputBuffer(const GMPEncryptedBufferMetadata* aCrypto,
|
||||
|
@ -180,6 +180,7 @@ ServiceWorkerInfo::ServiceWorkerInfo(nsIPrincipal* aPrincipal,
|
||||
, mServiceWorkerID(GetNextID())
|
||||
, mServiceWorkerPrivate(new ServiceWorkerPrivate(this))
|
||||
, mSkipWaitingFlag(false)
|
||||
, mHandlesFetch(Unknown)
|
||||
{
|
||||
MOZ_ASSERT(mPrincipal);
|
||||
// cache origin attributes so we can use them off main thread
|
||||
|
@ -46,6 +46,12 @@ private:
|
||||
RefPtr<ServiceWorkerPrivate> mServiceWorkerPrivate;
|
||||
bool mSkipWaitingFlag;
|
||||
|
||||
enum {
|
||||
Unknown,
|
||||
Enabled,
|
||||
Disabled
|
||||
} mHandlesFetch;
|
||||
|
||||
~ServiceWorkerInfo();
|
||||
|
||||
// Generates a unique id for the service worker, with zero being treated as
|
||||
@ -134,6 +140,22 @@ public:
|
||||
mState = aState;
|
||||
}
|
||||
|
||||
void
|
||||
SetHandlesFetch(bool aHandlesFetch)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_DIAGNOSTIC_ASSERT(mHandlesFetch == Unknown);
|
||||
mHandlesFetch = aHandlesFetch ? Enabled : Disabled;
|
||||
}
|
||||
|
||||
bool
|
||||
HandlesFetch() const
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_DIAGNOSTIC_ASSERT(mHandlesFetch != Unknown);
|
||||
return mHandlesFetch != Disabled;
|
||||
}
|
||||
|
||||
void
|
||||
AppendWorker(ServiceWorker* aWorker);
|
||||
|
||||
|
@ -184,6 +184,7 @@ PopulateRegistrationData(nsIPrincipal* aPrincipal,
|
||||
if (aRegistration->GetActive()) {
|
||||
aData.currentWorkerURL() = aRegistration->GetActive()->ScriptSpec();
|
||||
aData.cacheName() = aRegistration->GetActive()->CacheName();
|
||||
aData.currentWorkerHandlesFetch() = aRegistration->GetActive()->HandlesFetch();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -1697,6 +1698,8 @@ ServiceWorkerManager::LoadRegistration(
|
||||
registration->SetActive(
|
||||
new ServiceWorkerInfo(registration->mPrincipal, registration->mScope,
|
||||
currentWorkerURL, aRegistration.cacheName()));
|
||||
|
||||
registration->GetActive()->SetHandlesFetch(aRegistration.currentWorkerHandlesFetch());
|
||||
registration->GetActive()->SetActivateStateUncheckedWithoutEvent(ServiceWorkerState::Activated);
|
||||
}
|
||||
}
|
||||
|
@ -107,19 +107,26 @@ namespace {
|
||||
|
||||
class CheckScriptEvaluationWithCallback final : public WorkerRunnable
|
||||
{
|
||||
nsMainThreadPtrHandle<ServiceWorkerPrivate> mServiceWorkerPrivate;
|
||||
nsMainThreadPtrHandle<KeepAliveToken> mKeepAliveToken;
|
||||
RefPtr<LifeCycleEventCallback> mCallback;
|
||||
|
||||
// The script evaluation result must be reported even if the runnable
|
||||
// is cancelled.
|
||||
RefPtr<LifeCycleEventCallback> mScriptEvaluationCallback;
|
||||
|
||||
#ifdef DEBUG
|
||||
bool mDone;
|
||||
#endif
|
||||
|
||||
public:
|
||||
CheckScriptEvaluationWithCallback(WorkerPrivate* aWorkerPrivate,
|
||||
ServiceWorkerPrivate* aServiceWorkerPrivate,
|
||||
KeepAliveToken* aKeepAliveToken,
|
||||
LifeCycleEventCallback* aCallback)
|
||||
LifeCycleEventCallback* aScriptEvaluationCallback)
|
||||
: WorkerRunnable(aWorkerPrivate)
|
||||
, mServiceWorkerPrivate(new nsMainThreadPtrHolder<ServiceWorkerPrivate>(aServiceWorkerPrivate))
|
||||
, mKeepAliveToken(new nsMainThreadPtrHolder<KeepAliveToken>(aKeepAliveToken))
|
||||
, mCallback(aCallback)
|
||||
, mScriptEvaluationCallback(aScriptEvaluationCallback)
|
||||
#ifdef DEBUG
|
||||
, mDone(false)
|
||||
#endif
|
||||
@ -136,42 +143,55 @@ public:
|
||||
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
|
||||
{
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
Done(aWorkerPrivate->WorkerScriptExecutedSuccessfully());
|
||||
|
||||
bool fetchHandlerWasAdded = aWorkerPrivate->FetchHandlerWasAdded();
|
||||
nsCOMPtr<nsIRunnable> runnable = NewRunnableMethod<bool>(this,
|
||||
&CheckScriptEvaluationWithCallback::ReportFetchFlag, fetchHandlerWasAdded);
|
||||
aWorkerPrivate->DispatchToMainThread(runnable.forget());
|
||||
|
||||
ReportScriptEvaluationResult(aWorkerPrivate->WorkerScriptExecutedSuccessfully());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ReportFetchFlag(bool aFetchHandlerWasAdded)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
mServiceWorkerPrivate->SetHandlesFetch(aFetchHandlerWasAdded);
|
||||
}
|
||||
|
||||
nsresult
|
||||
Cancel() override
|
||||
{
|
||||
Done(false);
|
||||
ReportScriptEvaluationResult(false);
|
||||
return WorkerRunnable::Cancel();
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
Done(bool aResult)
|
||||
ReportScriptEvaluationResult(bool aScriptEvaluationResult)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
mDone = true;
|
||||
#endif
|
||||
mCallback->SetResult(aResult);
|
||||
MOZ_ALWAYS_SUCCEEDS(mWorkerPrivate->DispatchToMainThread(mCallback));
|
||||
mScriptEvaluationCallback->SetResult(aScriptEvaluationResult);
|
||||
MOZ_ALWAYS_SUCCEEDS(mWorkerPrivate->DispatchToMainThread(mScriptEvaluationCallback));
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
nsresult
|
||||
ServiceWorkerPrivate::CheckScriptEvaluation(LifeCycleEventCallback* aCallback)
|
||||
ServiceWorkerPrivate::CheckScriptEvaluation(LifeCycleEventCallback* aScriptEvaluationCallback)
|
||||
{
|
||||
nsresult rv = SpawnWorkerIfNeeded(LifeCycleEvent, nullptr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
RefPtr<KeepAliveToken> token = CreateEventKeepAliveToken();
|
||||
RefPtr<WorkerRunnable> r = new CheckScriptEvaluationWithCallback(mWorkerPrivate,
|
||||
token,
|
||||
aCallback);
|
||||
this, token,
|
||||
aScriptEvaluationCallback);
|
||||
if (NS_WARN_IF(!r->Dispatch())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -1682,6 +1702,28 @@ ServiceWorkerPrivate::SendFetchEvent(nsIInterceptedChannel* aChannel,
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (NS_WARN_IF(!mInfo)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
MOZ_ASSERT(swm);
|
||||
|
||||
RefPtr<ServiceWorkerRegistrationInfo> registration =
|
||||
swm->GetRegistration(mInfo->GetPrincipal(), mInfo->Scope());
|
||||
|
||||
// Handle Fetch algorithm - step 16. If the service worker didn't register
|
||||
// any fetch event handlers, then abort the interception and maybe trigger
|
||||
// the soft update algorithm.
|
||||
if (!mInfo->HandlesFetch()) {
|
||||
aChannel->ResetInterception();
|
||||
|
||||
// Trigger soft updates if necessary.
|
||||
registration->MaybeScheduleTimeCheckAndUpdate();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// if the ServiceWorker script fails to load for some reason, just resume
|
||||
// the original channel.
|
||||
nsCOMPtr<nsIRunnable> failRunnable =
|
||||
@ -1693,16 +1735,6 @@ ServiceWorkerPrivate::SendFetchEvent(nsIInterceptedChannel* aChannel,
|
||||
nsMainThreadPtrHandle<nsIInterceptedChannel> handle(
|
||||
new nsMainThreadPtrHolder<nsIInterceptedChannel>(aChannel, false));
|
||||
|
||||
if (NS_WARN_IF(!mInfo)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
MOZ_ASSERT(swm);
|
||||
|
||||
RefPtr<ServiceWorkerRegistrationInfo> registration =
|
||||
swm->GetRegistration(mInfo->GetPrincipal(), mInfo->Scope());
|
||||
|
||||
nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> regInfo(
|
||||
new nsMainThreadPtrHolder<ServiceWorkerRegistrationInfo>(registration, false));
|
||||
|
||||
@ -2120,4 +2152,16 @@ ServiceWorkerPrivate::Observe(nsISupports* aSubject, const char* aTopic, const c
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerPrivate::SetHandlesFetch(bool aValue)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (NS_WARN_IF(!mInfo)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mInfo->SetHandlesFetch(aValue);
|
||||
}
|
||||
|
||||
END_WORKERS_NAMESPACE
|
||||
|
@ -153,6 +153,9 @@ public:
|
||||
void
|
||||
AddPendingWindow(Runnable* aPendingWindow);
|
||||
|
||||
void
|
||||
SetHandlesFetch(bool aValue);
|
||||
|
||||
private:
|
||||
enum WakeUpReason {
|
||||
FetchEvent = 0,
|
||||
|
@ -41,6 +41,7 @@ namespace {
|
||||
|
||||
static const char* gSupportedRegistrarVersions[] = {
|
||||
SERVICEWORKERREGISTRAR_VERSION,
|
||||
"4",
|
||||
"3",
|
||||
"2"
|
||||
};
|
||||
@ -351,6 +352,40 @@ ServiceWorkerRegistrar::ReadData()
|
||||
|
||||
GET_LINE(entry->currentWorkerURL());
|
||||
|
||||
nsAutoCString fetchFlag;
|
||||
GET_LINE(fetchFlag);
|
||||
if (!fetchFlag.EqualsLiteral(SERVICEWORKERREGISTRAR_TRUE) &&
|
||||
!fetchFlag.EqualsLiteral(SERVICEWORKERREGISTRAR_FALSE)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
entry->currentWorkerHandlesFetch() =
|
||||
fetchFlag.EqualsLiteral(SERVICEWORKERREGISTRAR_TRUE);
|
||||
|
||||
nsAutoCString cacheName;
|
||||
GET_LINE(cacheName);
|
||||
CopyUTF8toUTF16(cacheName, entry->cacheName());
|
||||
} else if (version.EqualsLiteral("4")) {
|
||||
overwrite = true;
|
||||
dedupe = true;
|
||||
|
||||
nsAutoCString suffix;
|
||||
GET_LINE(suffix);
|
||||
|
||||
PrincipalOriginAttributes attrs;
|
||||
if (!attrs.PopulateFromSuffix(suffix)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
GET_LINE(entry->scope());
|
||||
|
||||
entry->principal() =
|
||||
mozilla::ipc::ContentPrincipalInfo(attrs, entry->scope());
|
||||
|
||||
GET_LINE(entry->currentWorkerURL());
|
||||
|
||||
// default handlesFetch flag to Enabled
|
||||
entry->currentWorkerHandlesFetch() = true;
|
||||
|
||||
nsAutoCString cacheName;
|
||||
GET_LINE(cacheName);
|
||||
CopyUTF8toUTF16(cacheName, entry->cacheName());
|
||||
@ -376,6 +411,9 @@ ServiceWorkerRegistrar::ReadData()
|
||||
|
||||
GET_LINE(entry->currentWorkerURL());
|
||||
|
||||
// default handlesFetch flag to Enabled
|
||||
entry->currentWorkerHandlesFetch() = true;
|
||||
|
||||
nsAutoCString cacheName;
|
||||
GET_LINE(cacheName);
|
||||
CopyUTF8toUTF16(cacheName, entry->cacheName());
|
||||
@ -404,6 +442,9 @@ ServiceWorkerRegistrar::ReadData()
|
||||
|
||||
GET_LINE(entry->currentWorkerURL());
|
||||
|
||||
// default handlesFetch flag to Enabled
|
||||
entry->currentWorkerHandlesFetch() = true;
|
||||
|
||||
nsAutoCString cacheName;
|
||||
GET_LINE(cacheName);
|
||||
CopyUTF8toUTF16(cacheName, entry->cacheName());
|
||||
@ -699,6 +740,10 @@ ServiceWorkerRegistrar::WriteData()
|
||||
buffer.Append(data[i].currentWorkerURL());
|
||||
buffer.Append('\n');
|
||||
|
||||
buffer.Append(data[i].currentWorkerHandlesFetch() ?
|
||||
SERVICEWORKERREGISTRAR_TRUE : SERVICEWORKERREGISTRAR_FALSE);
|
||||
buffer.Append('\n');
|
||||
|
||||
buffer.Append(NS_ConvertUTF16toUTF8(data[i].cacheName()));
|
||||
buffer.Append('\n');
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "nsTArray.h"
|
||||
|
||||
#define SERVICEWORKERREGISTRAR_FILE "serviceworker.txt"
|
||||
#define SERVICEWORKERREGISTRAR_VERSION "4"
|
||||
#define SERVICEWORKERREGISTRAR_VERSION "5"
|
||||
#define SERVICEWORKERREGISTRAR_TERMINATOR "#"
|
||||
#define SERVICEWORKERREGISTRAR_TRUE "true"
|
||||
#define SERVICEWORKERREGISTRAR_FALSE "false"
|
||||
|
@ -13,6 +13,7 @@ struct ServiceWorkerRegistrationData
|
||||
{
|
||||
nsCString scope;
|
||||
nsCString currentWorkerURL;
|
||||
bool currentWorkerHandlesFetch;
|
||||
|
||||
nsString cacheName;
|
||||
|
||||
|
@ -4019,6 +4019,7 @@ WorkerPrivate::WorkerPrivate(WorkerPrivate* aParent,
|
||||
, mPeriodicGCTimerRunning(false)
|
||||
, mIdleGCTimerRunning(false)
|
||||
, mWorkerScriptExecutedSuccessfully(false)
|
||||
, mFetchHandlerWasAdded(false)
|
||||
, mOnLine(false)
|
||||
{
|
||||
MOZ_ASSERT_IF(!IsDedicatedWorker(), !aWorkerName.IsVoid());
|
||||
|
@ -973,6 +973,7 @@ class WorkerPrivate : public WorkerPrivateParent<WorkerPrivate>
|
||||
bool mPeriodicGCTimerRunning;
|
||||
bool mIdleGCTimerRunning;
|
||||
bool mWorkerScriptExecutedSuccessfully;
|
||||
bool mFetchHandlerWasAdded;
|
||||
bool mPreferences[WORKERPREF_COUNT];
|
||||
bool mOnLine;
|
||||
|
||||
@ -1211,6 +1212,22 @@ public:
|
||||
void
|
||||
MemoryPressureInternal();
|
||||
|
||||
void
|
||||
SetFetchHandlerWasAdded()
|
||||
{
|
||||
MOZ_ASSERT(IsServiceWorker());
|
||||
AssertIsOnWorkerThread();
|
||||
mFetchHandlerWasAdded = true;
|
||||
}
|
||||
|
||||
bool
|
||||
FetchHandlerWasAdded() const
|
||||
{
|
||||
MOZ_ASSERT(IsServiceWorker());
|
||||
AssertIsOnWorkerThread();
|
||||
return mFetchHandlerWasAdded;
|
||||
}
|
||||
|
||||
JSContext*
|
||||
GetJSContext() const
|
||||
{
|
||||
|
@ -611,6 +611,89 @@ ServiceWorkerGlobalScope::Registration()
|
||||
return mRegistration;
|
||||
}
|
||||
|
||||
EventHandlerNonNull*
|
||||
ServiceWorkerGlobalScope::GetOnfetch()
|
||||
{
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
return GetEventHandler(nullptr, NS_LITERAL_STRING("fetch"));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class ReportFetchListenerWarningRunnable final : public Runnable
|
||||
{
|
||||
const nsCString mScope;
|
||||
nsCString mSourceSpec;
|
||||
uint32_t mLine;
|
||||
uint32_t mColumn;
|
||||
|
||||
public:
|
||||
explicit ReportFetchListenerWarningRunnable(const nsString& aScope)
|
||||
: mScope(NS_ConvertUTF16toUTF8(aScope))
|
||||
{
|
||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
JSContext* cx = workerPrivate->GetJSContext();
|
||||
MOZ_ASSERT(cx);
|
||||
|
||||
nsJSUtils::GetCallingLocation(cx, mSourceSpec, &mLine, &mColumn);
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
ServiceWorkerManager::LocalizeAndReportToAllClients(mScope, "ServiceWorkerNoFetchHandler",
|
||||
nsTArray<nsString>{}, nsIScriptError::warningFlag, NS_ConvertUTF8toUTF16(mSourceSpec),
|
||||
EmptyString(), mLine, mColumn);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void
|
||||
ServiceWorkerGlobalScope::SetOnfetch(mozilla::dom::EventHandlerNonNull* aCallback)
|
||||
{
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
if (aCallback) {
|
||||
if (mWorkerPrivate->WorkerScriptExecutedSuccessfully()) {
|
||||
RefPtr<Runnable> r = new ReportFetchListenerWarningRunnable(mScope);
|
||||
mWorkerPrivate->DispatchToMainThread(r.forget());
|
||||
}
|
||||
mWorkerPrivate->SetFetchHandlerWasAdded();
|
||||
}
|
||||
SetEventHandler(nullptr, NS_LITERAL_STRING("fetch"), aCallback);
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerGlobalScope::AddEventListener(
|
||||
const nsAString& aType,
|
||||
dom::EventListener* aListener,
|
||||
const dom::AddEventListenerOptionsOrBoolean& aOptions,
|
||||
const dom::Nullable<bool>& aWantsUntrusted,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
if (mWorkerPrivate->WorkerScriptExecutedSuccessfully()) {
|
||||
RefPtr<Runnable> r = new ReportFetchListenerWarningRunnable(mScope);
|
||||
mWorkerPrivate->DispatchToMainThread(r.forget());
|
||||
}
|
||||
DOMEventTargetHelper::AddEventListener(aType, aListener, aOptions,
|
||||
aWantsUntrusted, aRv);
|
||||
if (!aRv.Failed()) {
|
||||
mWorkerPrivate->SetFetchHandlerWasAdded();
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class SkipWaitingResultRunnable final : public WorkerRunnable
|
||||
|
@ -281,13 +281,25 @@ public:
|
||||
SkipWaiting(ErrorResult& aRv);
|
||||
|
||||
IMPL_EVENT_HANDLER(activate)
|
||||
IMPL_EVENT_HANDLER(fetch)
|
||||
IMPL_EVENT_HANDLER(install)
|
||||
IMPL_EVENT_HANDLER(message)
|
||||
|
||||
IMPL_EVENT_HANDLER(push)
|
||||
IMPL_EVENT_HANDLER(pushsubscriptionchange)
|
||||
|
||||
EventHandlerNonNull*
|
||||
GetOnfetch();
|
||||
|
||||
void
|
||||
SetOnfetch(mozilla::dom::EventHandlerNonNull* aCallback);
|
||||
|
||||
using DOMEventTargetHelper::AddEventListener;
|
||||
virtual void
|
||||
AddEventListener(const nsAString& aType,
|
||||
dom::EventListener* aListener,
|
||||
const dom::AddEventListenerOptionsOrBoolean& aOptions,
|
||||
const dom::Nullable<bool>& aWantsUntrusted,
|
||||
ErrorResult& aRv) override;
|
||||
};
|
||||
|
||||
class WorkerDebuggerGlobalScope final : public DOMEventTargetHelper,
|
||||
|
@ -148,11 +148,15 @@ TEST(ServiceWorkerRegistrar, TestReadData)
|
||||
nsAutoCString buffer(SERVICEWORKERREGISTRAR_VERSION "\n");
|
||||
|
||||
buffer.Append("^appId=123&inBrowser=1\n");
|
||||
buffer.Append("scope 0\ncurrentWorkerURL 0\ncacheName 0\n");
|
||||
buffer.Append("scope 0\ncurrentWorkerURL 0\n");
|
||||
buffer.Append(SERVICEWORKERREGISTRAR_TRUE "\n");
|
||||
buffer.Append("cacheName 0\n");
|
||||
buffer.Append(SERVICEWORKERREGISTRAR_TERMINATOR "\n");
|
||||
|
||||
buffer.Append("\n");
|
||||
buffer.Append("scope 1\ncurrentWorkerURL 1\ncacheName 1\n");
|
||||
buffer.Append("scope 1\ncurrentWorkerURL 1\n");
|
||||
buffer.Append(SERVICEWORKERREGISTRAR_FALSE "\n");
|
||||
buffer.Append("cacheName 1\n");
|
||||
buffer.Append(SERVICEWORKERREGISTRAR_TERMINATOR "\n");
|
||||
|
||||
ASSERT_TRUE(CreateFile(buffer)) << "CreateFile should not fail";
|
||||
@ -176,6 +180,7 @@ TEST(ServiceWorkerRegistrar, TestReadData)
|
||||
ASSERT_STREQ("scope 0", cInfo0.spec().get());
|
||||
ASSERT_STREQ("scope 0", data[0].scope().get());
|
||||
ASSERT_STREQ("currentWorkerURL 0", data[0].currentWorkerURL().get());
|
||||
ASSERT_TRUE(data[0].currentWorkerHandlesFetch());
|
||||
ASSERT_STREQ("cacheName 0", NS_ConvertUTF16toUTF8(data[0].cacheName()).get());
|
||||
|
||||
const mozilla::ipc::PrincipalInfo& info1 = data[1].principal();
|
||||
@ -189,6 +194,7 @@ TEST(ServiceWorkerRegistrar, TestReadData)
|
||||
ASSERT_STREQ("scope 1", cInfo1.spec().get());
|
||||
ASSERT_STREQ("scope 1", data[1].scope().get());
|
||||
ASSERT_STREQ("currentWorkerURL 1", data[1].currentWorkerURL().get());
|
||||
ASSERT_FALSE(data[1].currentWorkerHandlesFetch());
|
||||
ASSERT_STREQ("cacheName 1", NS_ConvertUTF16toUTF8(data[1].cacheName()).get());
|
||||
}
|
||||
|
||||
@ -370,6 +376,59 @@ TEST(ServiceWorkerRegistrar, TestVersion3Migration)
|
||||
ASSERT_STREQ("cacheName 1", NS_ConvertUTF16toUTF8(data[1].cacheName()).get());
|
||||
}
|
||||
|
||||
TEST(ServiceWorkerRegistrar, TestVersion4Migration)
|
||||
{
|
||||
nsAutoCString buffer("4" "\n");
|
||||
|
||||
buffer.Append("^appId=123&inBrowser=1\n");
|
||||
buffer.Append("scope 0\ncurrentWorkerURL 0\ncacheName 0\n");
|
||||
buffer.Append(SERVICEWORKERREGISTRAR_TERMINATOR "\n");
|
||||
|
||||
buffer.Append("\n");
|
||||
buffer.Append("scope 1\ncurrentWorkerURL 1\ncacheName 1\n");
|
||||
buffer.Append(SERVICEWORKERREGISTRAR_TERMINATOR "\n");
|
||||
|
||||
ASSERT_TRUE(CreateFile(buffer)) << "CreateFile should not fail";
|
||||
|
||||
RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest;
|
||||
|
||||
nsresult rv = swr->TestReadData();
|
||||
ASSERT_EQ(NS_OK, rv) << "ReadData() should not fail";
|
||||
|
||||
const nsTArray<ServiceWorkerRegistrationData>& data = swr->TestGetData();
|
||||
ASSERT_EQ((uint32_t)2, data.Length()) << "2 entries should be found";
|
||||
|
||||
const mozilla::ipc::PrincipalInfo& info0 = data[0].principal();
|
||||
ASSERT_EQ(info0.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) << "First principal must be content";
|
||||
const mozilla::ipc::ContentPrincipalInfo& cInfo0 = data[0].principal();
|
||||
|
||||
nsAutoCString suffix0;
|
||||
cInfo0.attrs().CreateSuffix(suffix0);
|
||||
|
||||
ASSERT_STREQ("^appId=123&inBrowser=1", suffix0.get());
|
||||
ASSERT_STREQ("scope 0", cInfo0.spec().get());
|
||||
ASSERT_STREQ("scope 0", data[0].scope().get());
|
||||
ASSERT_STREQ("currentWorkerURL 0", data[0].currentWorkerURL().get());
|
||||
// default is true
|
||||
ASSERT_EQ(true, data[1].currentWorkerHandlesFetch());
|
||||
ASSERT_STREQ("cacheName 0", NS_ConvertUTF16toUTF8(data[0].cacheName()).get());
|
||||
|
||||
const mozilla::ipc::PrincipalInfo& info1 = data[1].principal();
|
||||
ASSERT_EQ(info1.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) << "First principal must be content";
|
||||
const mozilla::ipc::ContentPrincipalInfo& cInfo1 = data[1].principal();
|
||||
|
||||
nsAutoCString suffix1;
|
||||
cInfo1.attrs().CreateSuffix(suffix1);
|
||||
|
||||
ASSERT_STREQ("", suffix1.get());
|
||||
ASSERT_STREQ("scope 1", cInfo1.spec().get());
|
||||
ASSERT_STREQ("scope 1", data[1].scope().get());
|
||||
ASSERT_STREQ("currentWorkerURL 1", data[1].currentWorkerURL().get());
|
||||
// default is true
|
||||
ASSERT_EQ(true, data[1].currentWorkerHandlesFetch());
|
||||
ASSERT_STREQ("cacheName 1", NS_ConvertUTF16toUTF8(data[1].cacheName()).get());
|
||||
}
|
||||
|
||||
TEST(ServiceWorkerRegistrar, TestDedupeRead)
|
||||
{
|
||||
nsAutoCString buffer("3" "\n");
|
||||
|
@ -214,6 +214,7 @@ support-files =
|
||||
sharedWorker_fetch.js
|
||||
async_waituntil_worker.js
|
||||
lazy_worker.js
|
||||
nofetch_handler_worker.js
|
||||
|
||||
[test_bug1151916.html]
|
||||
[test_bug1240436.html]
|
||||
@ -319,3 +320,4 @@ tags = openwindow
|
||||
[test_xslt.html]
|
||||
[test_async_waituntil.html]
|
||||
[test_worker_reference_gc_timeout.html]
|
||||
[test_nofetch_handler.html]
|
||||
|
@ -0,0 +1,8 @@
|
||||
function handleFetch(event) {
|
||||
event.respondWith(new Response('intercepted'));
|
||||
}
|
||||
|
||||
self.oninstall = function(event) {
|
||||
addEventListener('fetch', handleFetch);
|
||||
self.onfetch = handleFetch;
|
||||
}
|
65
dom/workers/test/serviceworkers/test_nofetch_handler.html
Normal file
65
dom/workers/test/serviceworkers/test_nofetch_handler.html
Normal file
@ -0,0 +1,65 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 1181127</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script src="/tests/SimpleTest/SpawnTask.js"></script>
|
||||
<script src="error_reporting_helpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
|
||||
</head>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1181127">Mozilla Bug 1181127</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
add_task(function setupPrefs() {
|
||||
return SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true],
|
||||
// Make sure the event handler during the install event persists. This ensures
|
||||
// the reason for which the interception doesn't occur is because of the
|
||||
// handlesFetch=false flag from ServiceWorkerInfo.
|
||||
["dom.serviceWorkers.idle_timeout", 299999],
|
||||
]});
|
||||
});
|
||||
|
||||
var iframeg;
|
||||
function create_iframe(url) {
|
||||
return new Promise(function(res) {
|
||||
iframe = document.createElement('iframe');
|
||||
iframe.src = url;
|
||||
iframe.onload = function() { res(iframe) }
|
||||
document.body.appendChild(iframe);
|
||||
iframeg = iframe;
|
||||
})
|
||||
}
|
||||
|
||||
add_task(function* test_nofetch_worker() {
|
||||
let registration = yield navigator.serviceWorker.register(
|
||||
"nofetch_handler_worker.js", { scope: "./nofetch_handler_worker/"} )
|
||||
.then(function(registration) {
|
||||
var worker = registration.installing;
|
||||
return new Promise(function(resolve) {
|
||||
worker.addEventListener('statechange', function() {
|
||||
if (worker.state === 'activated') {
|
||||
resolve(registration);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
let iframe = yield create_iframe("./nofetch_handler_worker/doesnt_exist.html");
|
||||
ok(!iframe.contentDocument.body.innerHTML.includes("intercepted"), "Request was not intercepted.");
|
||||
|
||||
yield SpecialPowers.popPrefEnv();
|
||||
yield registration.unregister();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -94,7 +94,7 @@ public:
|
||||
nsresult rv = GetShutdownBarrier()->AddBlocker(
|
||||
this, NS_LITERAL_STRING(__FILE__), __LINE__,
|
||||
NS_LITERAL_STRING("Minidump analysis"));
|
||||
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
|
||||
Unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() override
|
||||
|
@ -4518,6 +4518,12 @@ nsIPresShell::RestyleForCSSRuleChanges()
|
||||
}
|
||||
|
||||
RestyleManagerHandle restyleManager = mPresContext->RestyleManager();
|
||||
|
||||
if (mStyleSet->IsServo()) {
|
||||
// Tell Servo that the contents of style sheets have changed.
|
||||
mStyleSet->AsServo()->NoteStyleSheetsChanged();
|
||||
}
|
||||
|
||||
if (scopeRoots.IsEmpty()) {
|
||||
// If scopeRoots is empty, we know that mStylesHaveChanged was true at
|
||||
// the beginning of this function, and that we need to restyle the whole
|
||||
@ -4550,7 +4556,6 @@ PresShell::RecordStyleSheetChange(StyleSheet* aStyleSheet)
|
||||
}
|
||||
} else {
|
||||
NS_WARNING("stylo: ServoStyleSheets don't support <style scoped>");
|
||||
return;
|
||||
}
|
||||
|
||||
mStylesHaveChanged = true;
|
||||
|
@ -59,6 +59,16 @@ ServoRestyleManager::PostRestyleEvent(Element* aElement,
|
||||
aRestyleHint |= eRestyle_Self | eRestyle_Subtree;
|
||||
}
|
||||
|
||||
// XXX For now, convert eRestyle_Subtree into (eRestyle_Self |
|
||||
// eRestyle_SomeDescendants), which Servo will interpret as
|
||||
// RESTYLE_SELF | RESTYLE_DESCENDANTS, since this is a commonly
|
||||
// posted restyle hint that doesn't yet align with RestyleHint's
|
||||
// bits.
|
||||
if (aRestyleHint & eRestyle_Subtree) {
|
||||
aRestyleHint &= ~eRestyle_Subtree;
|
||||
aRestyleHint |= eRestyle_Self | eRestyle_SomeDescendants;
|
||||
}
|
||||
|
||||
if (aRestyleHint || aMinChangeHint) {
|
||||
Servo_NoteExplicitHints(aElement, aRestyleHint, aMinChangeHint);
|
||||
}
|
||||
|
@ -47,6 +47,8 @@ SERVO_BINDING_FUNC(Servo_StyleSet_RemoveStyleSheet, void,
|
||||
SERVO_BINDING_FUNC(Servo_StyleSet_InsertStyleSheetBefore, void,
|
||||
RawServoStyleSetBorrowed set, RawServoStyleSheetBorrowed sheet,
|
||||
RawServoStyleSheetBorrowed reference)
|
||||
SERVO_BINDING_FUNC(Servo_StyleSet_NoteStyleSheetsChanged, void,
|
||||
RawServoStyleSetBorrowed set)
|
||||
|
||||
// CSSRuleList
|
||||
SERVO_BINDING_FUNC(Servo_CssRules_ListTypes, void,
|
||||
|
@ -474,6 +474,12 @@ ServoStyleSet::StyleNewChildren(Element* aParent)
|
||||
TraversalRootBehavior::UnstyledChildrenOnly);
|
||||
}
|
||||
|
||||
void
|
||||
ServoStyleSet::NoteStyleSheetsChanged()
|
||||
{
|
||||
Servo_StyleSet_NoteStyleSheetsChanged(mRawSet.get());
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
ServoStyleSet::AssertTreeIsClean()
|
||||
|
@ -142,6 +142,13 @@ public:
|
||||
*/
|
||||
void StyleNewChildren(Element* aParent);
|
||||
|
||||
/**
|
||||
* Records that the contents of style sheets have changed since the last
|
||||
* restyle. Calling this will ensure that the Stylist rebuilds its
|
||||
* selector maps.
|
||||
*/
|
||||
void NoteStyleSheetsChanged();
|
||||
|
||||
#ifdef DEBUG
|
||||
void AssertTreeIsClean();
|
||||
#else
|
||||
|
@ -628,7 +628,11 @@ pref("media.decoder.recycle.enabled", true);
|
||||
pref("media.android-media-codec.enabled", true);
|
||||
pref("media.android-media-codec.preferred", true);
|
||||
// Run decoder in seperate process.
|
||||
#ifdef NIGHTLY_BUILD
|
||||
pref("media.android-remote-codec.enabled", true);
|
||||
#else
|
||||
pref("media.android-remote-codec.enabled", false);
|
||||
#endif
|
||||
|
||||
// Enable MSE
|
||||
pref("media.mediasource.enabled", true);
|
||||
|
@ -22,6 +22,9 @@ SPHINX_TREES['telemetry'] = 'docs'
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += ['-Wno-error=shadow']
|
||||
|
||||
if CONFIG['ENABLE_TESTS']:
|
||||
DIRS += ['tests/gtest']
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
|
||||
BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini']
|
||||
|
||||
|
65
toolkit/components/telemetry/tests/gtest/TelemetryFixture.h
Normal file
65
toolkit/components/telemetry/tests/gtest/TelemetryFixture.h
Normal file
@ -0,0 +1,65 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
#ifndef TelemetryFixture_h_
|
||||
#define TelemetryFixture_h_
|
||||
|
||||
#include "mozilla/CycleCollectedJSContext.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/SimpleGlobalObject.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
class TelemetryTestFixture: public ::testing::Test {
|
||||
protected:
|
||||
TelemetryTestFixture() : mCleanGlobal(nullptr) {}
|
||||
virtual void SetUp();
|
||||
|
||||
JSObject* mCleanGlobal;
|
||||
|
||||
nsCOMPtr<nsITelemetry> mTelemetry;
|
||||
};
|
||||
|
||||
void
|
||||
TelemetryTestFixture::SetUp()
|
||||
{
|
||||
mTelemetry = do_GetService("@mozilla.org/base/telemetry;1");
|
||||
|
||||
mCleanGlobal =
|
||||
dom::SimpleGlobalObject::Create(dom::SimpleGlobalObject::GlobalType::BindingDetail);
|
||||
|
||||
// The test must fail if we failed getting the global.
|
||||
ASSERT_NE(mCleanGlobal, nullptr) << "SimpleGlobalObject must return a valid global object.";
|
||||
}
|
||||
|
||||
|
||||
// AutoJSAPI is annotated with MOZ_STACK_CLASS and thus cannot be
|
||||
// used as a member of TelemetryTestFixture, since gtest instantiates
|
||||
// that on the heap. To work around the problem, use the following class
|
||||
// at the beginning of each Telemetry test.
|
||||
// Note: this is very similar to AutoJSContext, but it allows to pass a
|
||||
// global JS object in.
|
||||
class MOZ_RAII AutoJSContextWithGlobal {
|
||||
public:
|
||||
explicit AutoJSContextWithGlobal(JSObject* aGlobalObject);
|
||||
JSContext* GetJSContext() const;
|
||||
|
||||
protected:
|
||||
dom::AutoJSAPI mJsAPI;
|
||||
JSContext* mCx;
|
||||
};
|
||||
|
||||
AutoJSContextWithGlobal::AutoJSContextWithGlobal(JSObject* aGlobalObject)
|
||||
: mCx(nullptr)
|
||||
{
|
||||
// The JS API must initialize correctly.
|
||||
MOZ_ALWAYS_TRUE(mJsAPI.Init(aGlobalObject));
|
||||
}
|
||||
|
||||
JSContext* AutoJSContextWithGlobal::GetJSContext() const
|
||||
{
|
||||
return mJsAPI.cx();
|
||||
}
|
||||
|
||||
#endif //TelemetryFixture_h_
|
288
toolkit/components/telemetry/tests/gtest/TestScalars.cpp
Normal file
288
toolkit/components/telemetry/tests/gtest/TestScalars.cpp
Normal file
@ -0,0 +1,288 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "js/Conversions.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsJSUtils.h" // nsAutoJSString
|
||||
#include "nsITelemetry.h"
|
||||
#include "Telemetry.h"
|
||||
#include "TelemetryFixture.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
#define EXPECTED_STRING "Nice, expected and creative string."
|
||||
|
||||
namespace {
|
||||
|
||||
void
|
||||
CheckUintScalar(const char* aName, JSContext* aCx, JS::HandleValue aSnapshot, uint32_t expectedValue)
|
||||
{
|
||||
// Validate the value of the test scalar.
|
||||
JS::RootedValue value(aCx);
|
||||
JS::RootedObject scalarObj(aCx, &aSnapshot.toObject());
|
||||
ASSERT_TRUE(JS_GetProperty(aCx, scalarObj, aName, &value)) << "The test scalar must be reported.";
|
||||
ASSERT_TRUE(value.isInt32()) << "The scalar value must be of the correct type.";
|
||||
ASSERT_TRUE(value.toInt32() >= 0) << "The uint scalar type must contain a value >= 0.";
|
||||
ASSERT_EQ(static_cast<uint32_t>(value.toInt32()), expectedValue) << "The scalar value must match the expected value.";
|
||||
}
|
||||
|
||||
void
|
||||
CheckBoolScalar(const char* aName, JSContext* aCx, JS::HandleValue aSnapshot, bool expectedValue)
|
||||
{
|
||||
// Validate the value of the test scalar.
|
||||
JS::RootedValue value(aCx);
|
||||
JS::RootedObject scalarObj(aCx, &aSnapshot.toObject());
|
||||
ASSERT_TRUE(JS_GetProperty(aCx, scalarObj, aName, &value)) << "The test scalar must be reported.";
|
||||
ASSERT_TRUE(value.isBoolean()) << "The scalar value must be of the correct type.";
|
||||
ASSERT_EQ(static_cast<bool>(value.toBoolean()), expectedValue) << "The scalar value must match the expected value.";
|
||||
}
|
||||
|
||||
void
|
||||
CheckStringScalar(const char* aName, JSContext* aCx, JS::HandleValue aSnapshot, const char* expectedValue)
|
||||
{
|
||||
// Validate the value of the test scalar.
|
||||
JS::RootedValue value(aCx);
|
||||
JS::RootedObject scalarObj(aCx, &aSnapshot.toObject());
|
||||
ASSERT_TRUE(JS_GetProperty(aCx, scalarObj, aName, &value)) << "The test scalar must be reported.";
|
||||
ASSERT_TRUE(value.isString()) << "The scalar value must be of the correct type.";
|
||||
|
||||
bool sameString;
|
||||
ASSERT_TRUE(JS_StringEqualsAscii(aCx, value.toString(), expectedValue, &sameString)) << "JS String comparison failed";
|
||||
ASSERT_TRUE(sameString) << "The scalar value must match the expected string";
|
||||
}
|
||||
|
||||
void
|
||||
CheckKeyedUintScalar(const char* aName, const char* aKey, JSContext* aCx, JS::HandleValue aSnapshot,
|
||||
uint32_t expectedValue)
|
||||
{
|
||||
JS::RootedValue keyedScalar(aCx);
|
||||
JS::RootedObject scalarObj(aCx, &aSnapshot.toObject());
|
||||
// Get the aName keyed scalar object from the scalars snapshot.
|
||||
ASSERT_TRUE(JS_GetProperty(aCx, scalarObj, aName, &keyedScalar))
|
||||
<< "The keyed scalar must be reported.";
|
||||
|
||||
CheckUintScalar(aKey, aCx, keyedScalar, expectedValue);
|
||||
}
|
||||
|
||||
void
|
||||
CheckKeyedBoolScalar(const char* aName, const char* aKey, JSContext* aCx, JS::HandleValue aSnapshot,
|
||||
bool expectedValue)
|
||||
{
|
||||
JS::RootedValue keyedScalar(aCx);
|
||||
JS::RootedObject scalarObj(aCx, &aSnapshot.toObject());
|
||||
// Get the aName keyed scalar object from the scalars snapshot.
|
||||
ASSERT_TRUE(JS_GetProperty(aCx, scalarObj, aName, &keyedScalar))
|
||||
<< "The keyed scalar must be reported.";
|
||||
|
||||
CheckBoolScalar(aKey, aCx, keyedScalar, expectedValue);
|
||||
}
|
||||
|
||||
void
|
||||
CheckNumberOfProperties(const char* aName, JSContext* aCx, JS::HandleValue aSnapshot,
|
||||
uint32_t expectedNumProperties)
|
||||
{
|
||||
JS::RootedValue keyedScalar(aCx);
|
||||
JS::RootedObject scalarObj(aCx, &aSnapshot.toObject());
|
||||
// Get the aName keyed scalar object from the scalars snapshot.
|
||||
ASSERT_TRUE(JS_GetProperty(aCx, scalarObj, aName, &keyedScalar))
|
||||
<< "The keyed scalar must be reported.";
|
||||
|
||||
JS::RootedObject keyedScalarObj(aCx, &keyedScalar.toObject());
|
||||
JS::Rooted<JS::IdVector> ids(aCx, JS::IdVector(aCx));
|
||||
ASSERT_TRUE(JS_Enumerate(aCx, keyedScalarObj, &ids))
|
||||
<< "We must be able to get keyed scalar members.";
|
||||
|
||||
ASSERT_EQ(expectedNumProperties, ids.length())
|
||||
<< "The scalar must report the expected number of properties.";
|
||||
}
|
||||
|
||||
void
|
||||
GetScalarsSnapshot(bool aKeyed, JSContext* aCx, JS::MutableHandle<JS::Value> aResult)
|
||||
{
|
||||
nsCOMPtr<nsITelemetry> telemetry = do_GetService("@mozilla.org/base/telemetry;1");
|
||||
|
||||
// Get a snapshot of the scalars.
|
||||
JS::RootedValue scalarsSnapshot(aCx);
|
||||
nsresult rv;
|
||||
|
||||
if (aKeyed) {
|
||||
rv = telemetry->SnapshotKeyedScalars(nsITelemetry::DATASET_RELEASE_CHANNEL_OPTIN,
|
||||
false, aCx, 0, &scalarsSnapshot);
|
||||
} else {
|
||||
rv = telemetry->SnapshotScalars(nsITelemetry::DATASET_RELEASE_CHANNEL_OPTIN,
|
||||
false, aCx, 0, &scalarsSnapshot);
|
||||
}
|
||||
|
||||
// Validate the snapshot.
|
||||
ASSERT_EQ(rv, NS_OK) << "Creating a snapshot of the data must not fail.";
|
||||
ASSERT_TRUE(scalarsSnapshot.isObject()) << "The snapshot must be an object.";
|
||||
|
||||
aResult.set(scalarsSnapshot);
|
||||
}
|
||||
|
||||
} // Anonymous namespace.
|
||||
|
||||
// Test that we can properly write unsigned scalars using the C++ API.
|
||||
TEST_F(TelemetryTestFixture, ScalarUnsigned) {
|
||||
AutoJSContextWithGlobal cx(mCleanGlobal);
|
||||
|
||||
// Make sure we don't get scalars from other tests.
|
||||
Unused << mTelemetry->ClearScalars();
|
||||
|
||||
// Set the test scalar to a known value.
|
||||
const uint32_t kInitialValue = 1172015;
|
||||
const uint32_t kExpectedUint = 1172017;
|
||||
Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_UNSIGNED_INT_KIND, kInitialValue);
|
||||
Telemetry::ScalarAdd(Telemetry::ScalarID::TELEMETRY_TEST_UNSIGNED_INT_KIND, kExpectedUint - kInitialValue);
|
||||
|
||||
// Check the recorded value.
|
||||
JS::RootedValue scalarsSnapshot(cx.GetJSContext());
|
||||
GetScalarsSnapshot(false, cx.GetJSContext(), &scalarsSnapshot);
|
||||
CheckUintScalar("telemetry.test.unsigned_int_kind", cx.GetJSContext(), scalarsSnapshot, kExpectedUint);
|
||||
|
||||
// Try to use SetMaximum.
|
||||
const uint32_t kExpectedUintMaximum = kExpectedUint * 2;
|
||||
Telemetry::ScalarSetMaximum(Telemetry::ScalarID::TELEMETRY_TEST_UNSIGNED_INT_KIND, kExpectedUintMaximum);
|
||||
|
||||
// Make sure that calls of the unsupported type don't corrupt the stored value.
|
||||
// Don't run this part in debug builds as that intentionally asserts.
|
||||
#ifndef DEBUG
|
||||
Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_UNSIGNED_INT_KIND, false);
|
||||
Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_UNSIGNED_INT_KIND, NS_LITERAL_STRING("test"));
|
||||
#endif
|
||||
|
||||
// Check the recorded value.
|
||||
GetScalarsSnapshot(false, cx.GetJSContext(), &scalarsSnapshot);
|
||||
CheckUintScalar("telemetry.test.unsigned_int_kind", cx.GetJSContext(), scalarsSnapshot, kExpectedUintMaximum);
|
||||
}
|
||||
|
||||
// Test that we can properly write boolean scalars using the C++ API.
|
||||
TEST_F(TelemetryTestFixture, ScalarBoolean) {
|
||||
AutoJSContextWithGlobal cx(mCleanGlobal);
|
||||
|
||||
Unused << mTelemetry->ClearScalars();
|
||||
|
||||
// Set the test scalar to a known value.
|
||||
Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_BOOLEAN_KIND, true);
|
||||
|
||||
// Make sure that calls of the unsupported type don't corrupt the stored value.
|
||||
// Don't run this part in debug builds as that intentionally asserts.
|
||||
#ifndef DEBUG
|
||||
Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_BOOLEAN_KIND, static_cast<uint32_t>(12));
|
||||
Telemetry::ScalarSetMaximum(Telemetry::ScalarID::TELEMETRY_TEST_BOOLEAN_KIND, 20);
|
||||
Telemetry::ScalarAdd(Telemetry::ScalarID::TELEMETRY_TEST_BOOLEAN_KIND, 2);
|
||||
Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_BOOLEAN_KIND, NS_LITERAL_STRING("test"));
|
||||
#endif
|
||||
|
||||
// Check the recorded value.
|
||||
JS::RootedValue scalarsSnapshot(cx.GetJSContext());
|
||||
GetScalarsSnapshot(false, cx.GetJSContext(), &scalarsSnapshot);
|
||||
CheckBoolScalar("telemetry.test.boolean_kind", cx.GetJSContext(), scalarsSnapshot, true);
|
||||
}
|
||||
|
||||
// Test that we can properly write string scalars using the C++ API.
|
||||
TEST_F(TelemetryTestFixture, ScalarString) {
|
||||
AutoJSContextWithGlobal cx(mCleanGlobal);
|
||||
|
||||
Unused << mTelemetry->ClearScalars();
|
||||
|
||||
// Set the test scalar to a known value.
|
||||
Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_STRING_KIND, NS_LITERAL_STRING(EXPECTED_STRING));
|
||||
|
||||
// Make sure that calls of the unsupported type don't corrupt the stored value.
|
||||
// Don't run this part in debug builds as that intentionally asserts.
|
||||
#ifndef DEBUG
|
||||
Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_STRING_KIND, static_cast<uint32_t>(12));
|
||||
Telemetry::ScalarSetMaximum(Telemetry::ScalarID::TELEMETRY_TEST_STRING_KIND, 20);
|
||||
Telemetry::ScalarAdd(Telemetry::ScalarID::TELEMETRY_TEST_STRING_KIND, 2);
|
||||
Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_STRING_KIND, true);
|
||||
#endif
|
||||
|
||||
// Check the recorded value.
|
||||
JS::RootedValue scalarsSnapshot(cx.GetJSContext());
|
||||
GetScalarsSnapshot(false, cx.GetJSContext(), &scalarsSnapshot);
|
||||
CheckStringScalar("telemetry.test.string_kind", cx.GetJSContext(), scalarsSnapshot, EXPECTED_STRING);
|
||||
}
|
||||
|
||||
// Test that we can properly write keyed unsigned scalars using the C++ API.
|
||||
TEST_F(TelemetryTestFixture, KeyedScalarUnsigned) {
|
||||
AutoJSContextWithGlobal cx(mCleanGlobal);
|
||||
|
||||
Unused << mTelemetry->ClearScalars();
|
||||
|
||||
// Set the test scalar to a known value.
|
||||
const char* kScalarName = "telemetry.test.keyed_unsigned_int";
|
||||
const uint32_t kKey1Value = 1172015;
|
||||
const uint32_t kKey2Value = 1172017;
|
||||
Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_KEYED_UNSIGNED_INT,
|
||||
NS_LITERAL_STRING("key1"), kKey1Value);
|
||||
Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_KEYED_UNSIGNED_INT,
|
||||
NS_LITERAL_STRING("key2"), kKey1Value);
|
||||
Telemetry::ScalarAdd(Telemetry::ScalarID::TELEMETRY_TEST_KEYED_UNSIGNED_INT,
|
||||
NS_LITERAL_STRING("key2"), 2);
|
||||
|
||||
// Make sure that calls of the unsupported type don't corrupt the stored value.
|
||||
// Don't run this part in debug builds as that intentionally asserts.
|
||||
#ifndef DEBUG
|
||||
Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_KEYED_UNSIGNED_INT,
|
||||
NS_LITERAL_STRING("key1"), false);
|
||||
Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_KEYED_UNSIGNED_INT, NS_LITERAL_STRING("test"));
|
||||
#endif
|
||||
|
||||
// Check the recorded value.
|
||||
JS::RootedValue scalarsSnapshot(cx.GetJSContext());
|
||||
GetScalarsSnapshot(true, cx.GetJSContext(), &scalarsSnapshot);
|
||||
|
||||
// Check the keyed scalar we're interested in.
|
||||
CheckKeyedUintScalar(kScalarName, "key1", cx.GetJSContext(), scalarsSnapshot, kKey1Value);
|
||||
CheckKeyedUintScalar(kScalarName, "key2", cx.GetJSContext(), scalarsSnapshot, kKey2Value);
|
||||
CheckNumberOfProperties(kScalarName, cx.GetJSContext(), scalarsSnapshot, 2);
|
||||
|
||||
// Try to use SetMaximum.
|
||||
const uint32_t kExpectedUintMaximum = kKey1Value * 2;
|
||||
Telemetry::ScalarSetMaximum(Telemetry::ScalarID::TELEMETRY_TEST_KEYED_UNSIGNED_INT,
|
||||
NS_LITERAL_STRING("key1"), kExpectedUintMaximum);
|
||||
|
||||
GetScalarsSnapshot(true, cx.GetJSContext(), &scalarsSnapshot);
|
||||
// The first key should be different and te second is expected to be the same.
|
||||
CheckKeyedUintScalar(kScalarName, "key1", cx.GetJSContext(), scalarsSnapshot, kExpectedUintMaximum);
|
||||
CheckKeyedUintScalar(kScalarName, "key2", cx.GetJSContext(), scalarsSnapshot, kKey2Value);
|
||||
CheckNumberOfProperties(kScalarName, cx.GetJSContext(), scalarsSnapshot, 2);
|
||||
}
|
||||
|
||||
TEST_F(TelemetryTestFixture, KeyedScalarBoolean) {
|
||||
AutoJSContextWithGlobal cx(mCleanGlobal);
|
||||
|
||||
Unused << mTelemetry->ClearScalars();
|
||||
|
||||
// Set the test scalar to a known value.
|
||||
Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_KEYED_BOOLEAN_KIND,
|
||||
NS_LITERAL_STRING("key1"), false);
|
||||
Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_KEYED_BOOLEAN_KIND,
|
||||
NS_LITERAL_STRING("key2"), true);
|
||||
|
||||
// Make sure that calls of the unsupported type don't corrupt the stored value.
|
||||
// Don't run this part in debug builds as that intentionally asserts.
|
||||
#ifndef DEBUG
|
||||
Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_KEYED_BOOLEAN_KIND,
|
||||
NS_LITERAL_STRING("key1"), static_cast<uint32_t>(12));
|
||||
Telemetry::ScalarSetMaximum(Telemetry::ScalarID::TELEMETRY_TEST_KEYED_BOOLEAN_KIND,
|
||||
NS_LITERAL_STRING("key1"), 20);
|
||||
Telemetry::ScalarAdd(Telemetry::ScalarID::TELEMETRY_TEST_KEYED_BOOLEAN_KIND,
|
||||
NS_LITERAL_STRING("key1"), 2);
|
||||
#endif
|
||||
|
||||
// Check the recorded value.
|
||||
JS::RootedValue scalarsSnapshot(cx.GetJSContext());
|
||||
GetScalarsSnapshot(true, cx.GetJSContext(), &scalarsSnapshot);
|
||||
|
||||
// Make sure that the keys contain the expected values.
|
||||
const char* kScalarName = "telemetry.test.keyed_boolean_kind";
|
||||
CheckKeyedBoolScalar(kScalarName, "key1", cx.GetJSContext(), scalarsSnapshot, false);
|
||||
CheckKeyedBoolScalar(kScalarName, "key2", cx.GetJSContext(), scalarsSnapshot, true);
|
||||
CheckNumberOfProperties(kScalarName, cx.GetJSContext(), scalarsSnapshot, 2);
|
||||
}
|
17
toolkit/components/telemetry/tests/gtest/moz.build
Normal file
17
toolkit/components/telemetry/tests/gtest/moz.build
Normal file
@ -0,0 +1,17 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, you can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
Library('telemetrytest')
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'../..',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES = [
|
||||
'TestScalars.cpp',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul-gtest'
|
@ -59,7 +59,7 @@ button[default="true"] {
|
||||
-moz-border-left-colors: ThreeDDarkShadow ThreeDHighlight ThreeDLightShadow;
|
||||
}
|
||||
|
||||
@media not all and (-moz-windows-default-theme) {
|
||||
@media (-moz-windows-default-theme: 0) {
|
||||
@media (-moz-windows-compositor) {
|
||||
/* This is for high-contrast themes on Windows 8 and later */
|
||||
button[default="true"],
|
||||
|
@ -24,7 +24,7 @@ xul|checkbox {
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
|
||||
@media not all and (-moz-windows-default-theme) {
|
||||
@media (-moz-windows-default-theme: 0) {
|
||||
xul|*.checkbox-check {
|
||||
background-image: none !important;
|
||||
}
|
||||
@ -40,7 +40,7 @@ xul|radio {
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
|
||||
@media not all and (-moz-windows-default-theme) {
|
||||
@media (-moz-windows-default-theme: 0) {
|
||||
xul|*.radio-check {
|
||||
background-image: none;
|
||||
}
|
||||
@ -74,7 +74,7 @@ xul|checkbox:-moz-focusring > xul|*.checkbox-label-box {
|
||||
|
||||
/* Use a 2px border so that selected row highlight is still visible behind
|
||||
an existing high-contrast border that uses the background color */
|
||||
@media not all and (-moz-windows-default-theme) {
|
||||
@media (-moz-windows-default-theme: 0) {
|
||||
xul|treechildren::-moz-tree-row(selected),
|
||||
xul|listbox xul|listitem[selected="true"] {
|
||||
border: 2px dotted Highlight;
|
||||
|
@ -97,7 +97,7 @@ toolbarbutton[checked="true"]:not([disabled="true"]) {
|
||||
}
|
||||
}
|
||||
|
||||
@media not all and (-moz-windows-default-theme) {
|
||||
@media (-moz-windows-default-theme: 0) {
|
||||
toolbarbutton:-moz-lwtheme {
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
margin-inline-end: 16px;
|
||||
}
|
||||
|
||||
@media not all and (-moz-windows-default-theme) {
|
||||
@media (-moz-windows-default-theme: 0) {
|
||||
#header-utils-btn {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/utilities.svg#utilities-native");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user