Commit 60b0f2cb authored by Jay Harris's avatar Jay Harris Committed by Commit Bot

Changes the shape of the Badging API, per the decision on the spec.

ExperimentalBadge.set ==> navigator.setExperimentalAppBadge
ExperimentalBadge.clear ==> navigator.clearExperimentalAppBadge

Note: This also removes the (unused) scope parameter from the
IDL files and returns a Promise<void> from both APIs, in case
we ever want to promisify the API in future (see
https://github.com/WICG/badging/issues/55#issuecomment-535740159).

TPAC Discussion Summary:
https://github.com/WICG/badging/issues/55

Summary of IDL Changes:

interface ExperimentalBadge {
  static void set(optional unsigned long long contents);
  static void clear();
}

changed to:

partial interface Navigator {
  Promise<void> setExperimentalAppBadge(optional unsigned long long contents);
  Promise<void> clearExperimentalAppBadge();
}

Bug: 719176
Change-Id: Ied825cb1a58df674d5c7de59278cbf8b6e3b32f9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1816002
Commit-Queue: Jay Harris <harrisjay@chromium.org>
Reviewed-by: default avatarGiovanni Ortuño Urquidi <ortuno@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarMatt Giuca <mgiuca@chromium.org>
Cr-Commit-Position: refs/heads/master@{#704926}
parent 67f33767
......@@ -145,14 +145,14 @@ class WebAppBadgingBrowserTest : public WebAppControllerBrowserTest {
IN_PROC_BROWSER_TEST_P(WebAppBadgingBrowserTest,
CrossSiteFrameCannotChangeMainFrameBadge) {
// Clearing from cross site frame should affect only the cross site app.
ExecuteScriptAndWaitForBadgeChange("ExperimentalBadge.clear()",
ExecuteScriptAndWaitForBadgeChange("navigator.clearExperimentalAppBadge()",
cross_site_frame_);
ASSERT_TRUE(was_cleared_);
ASSERT_FALSE(was_flagged_);
ASSERT_EQ(cross_site_app_id(), changed_app_id_);
// Setting from cross site frame should affect only the cross site app.
ExecuteScriptAndWaitForBadgeChange("ExperimentalBadge.set(77)",
ExecuteScriptAndWaitForBadgeChange("navigator.setExperimentalAppBadge(77)",
cross_site_frame_);
ASSERT_FALSE(was_cleared_);
ASSERT_FALSE(was_flagged_);
......@@ -163,7 +163,8 @@ IN_PROC_BROWSER_TEST_P(WebAppBadgingBrowserTest,
// Tests that setting the badge to an integer will be propagated across
// processes.
IN_PROC_BROWSER_TEST_P(WebAppBadgingBrowserTest, BadgeCanBeSetToAnInteger) {
ExecuteScriptAndWaitForBadgeChange("ExperimentalBadge.set(99)", main_frame_);
ExecuteScriptAndWaitForBadgeChange("navigator.setExperimentalAppBadge(99)",
main_frame_);
ASSERT_FALSE(was_cleared_);
ASSERT_FALSE(was_flagged_);
ASSERT_EQ(main_app_id(), changed_app_id_);
......@@ -173,13 +174,15 @@ IN_PROC_BROWSER_TEST_P(WebAppBadgingBrowserTest, BadgeCanBeSetToAnInteger) {
// Tests that calls to |Badge.clear| are propagated across processes.
IN_PROC_BROWSER_TEST_P(WebAppBadgingBrowserTest,
BadgeCanBeClearedWithClearMethod) {
ExecuteScriptAndWaitForBadgeChange("ExperimentalBadge.set(55)", main_frame_);
ExecuteScriptAndWaitForBadgeChange("navigator.setExperimentalAppBadge(55)",
main_frame_);
ASSERT_FALSE(was_cleared_);
ASSERT_FALSE(was_flagged_);
ASSERT_EQ(main_app_id(), changed_app_id_);
ASSERT_EQ(base::Optional<uint64_t>(55u), last_badge_content_);
ExecuteScriptAndWaitForBadgeChange("ExperimentalBadge.clear()", main_frame_);
ExecuteScriptAndWaitForBadgeChange("navigator.clearExperimentalAppBadge()",
main_frame_);
ASSERT_TRUE(was_cleared_);
ASSERT_FALSE(was_flagged_);
ASSERT_EQ(main_app_id(), changed_app_id_);
......@@ -189,7 +192,8 @@ IN_PROC_BROWSER_TEST_P(WebAppBadgingBrowserTest,
// Tests that calling Badge.set(0) is equivalent to calling |Badge.clear| and
// that it propagates across processes.
IN_PROC_BROWSER_TEST_P(WebAppBadgingBrowserTest, BadgeCanBeClearedWithZero) {
ExecuteScriptAndWaitForBadgeChange("ExperimentalBadge.set(0)", main_frame_);
ExecuteScriptAndWaitForBadgeChange("navigator.setExperimentalAppBadge(0)",
main_frame_);
ASSERT_TRUE(was_cleared_);
ASSERT_FALSE(was_flagged_);
ASSERT_EQ(main_app_id(), changed_app_id_);
......@@ -198,7 +202,8 @@ IN_PROC_BROWSER_TEST_P(WebAppBadgingBrowserTest, BadgeCanBeClearedWithZero) {
// Tests that setting the badge without content is propagated across processes.
IN_PROC_BROWSER_TEST_P(WebAppBadgingBrowserTest, BadgeCanBeSetWithoutAValue) {
ExecuteScriptAndWaitForBadgeChange("ExperimentalBadge.set()", main_frame_);
ExecuteScriptAndWaitForBadgeChange("navigator.setExperimentalAppBadge()",
main_frame_);
ASSERT_FALSE(was_cleared_);
ASSERT_TRUE(was_flagged_);
ASSERT_EQ(main_app_id(), changed_app_id_);
......@@ -208,14 +213,14 @@ IN_PROC_BROWSER_TEST_P(WebAppBadgingBrowserTest, BadgeCanBeSetWithoutAValue) {
// Tests that the badge can be set and cleared from an in scope frame.
IN_PROC_BROWSER_TEST_P(WebAppBadgingBrowserTest,
BadgeCanBeSetAndClearedFromInScopeFrame) {
ExecuteScriptAndWaitForBadgeChange("ExperimentalBadge.set()",
ExecuteScriptAndWaitForBadgeChange("navigator.setExperimentalAppBadge()",
in_scope_frame_);
ASSERT_FALSE(was_cleared_);
ASSERT_TRUE(was_flagged_);
ASSERT_EQ(main_app_id(), changed_app_id_);
ASSERT_EQ(base::nullopt, last_badge_content_);
ExecuteScriptAndWaitForBadgeChange("ExperimentalBadge.clear()",
ExecuteScriptAndWaitForBadgeChange("navigator.clearExperimentalAppBadge()",
in_scope_frame_);
ASSERT_TRUE(was_cleared_);
ASSERT_FALSE(was_flagged_);
......@@ -232,10 +237,10 @@ IN_PROC_BROWSER_TEST_P(WebAppBadgingBrowserTest,
->GetActiveWebContents()
->GetMainFrame();
ASSERT_TRUE(
content::ExecuteScript(incognito_frame, "ExperimentalBadge.set()"));
ASSERT_TRUE(
content::ExecuteScript(incognito_frame, "ExperimentalBadge.clear()"));
ASSERT_TRUE(content::ExecuteScript(incognito_frame,
"navigator.setExperimentalAppBadge()"));
ASSERT_TRUE(content::ExecuteScript(incognito_frame,
"navigator.clearExperimentalAppBadge()"));
}
INSTANTIATE_TEST_SUITE_P(
......
......@@ -6,7 +6,7 @@ import("//third_party/blink/renderer/modules/modules.gni")
blink_modules_sources("badging") {
sources = [
"badge.cc",
"badge.h",
"navigator_badge.cc",
"navigator_badge.h",
]
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file
#include "third_party/blink/renderer/modules/badging/badge.h"
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/badging/badge_options.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
namespace blink {
const char Badge::kSupplementName[] = "Badge";
Badge::~Badge() = default;
// static
Badge* Badge::From(ExecutionContext* context) {
Badge* supplement = Supplement<ExecutionContext>::From<Badge>(context);
if (!supplement) {
supplement = MakeGarbageCollected<Badge>(context);
ProvideTo(*context, supplement);
}
return supplement;
}
// static
void Badge::set(ScriptState* script_state, ExceptionState& exception_state) {
Badge::set(script_state, BadgeOptions::Create(), exception_state);
}
// static
void Badge::set(ScriptState* script_state,
const BadgeOptions* options,
ExceptionState& exception_state) {
BadgeFromState(script_state)
->SetBadge(options->scope(), mojom::blink::BadgeValue::NewFlag(0),
exception_state);
}
// static
void Badge::set(ScriptState* script_state,
uint64_t content,
ExceptionState& exception_state) {
Badge::set(script_state, content, BadgeOptions::Create(), exception_state);
}
// static
void Badge::set(ScriptState* script_state,
uint64_t content,
const BadgeOptions* options,
ExceptionState& exception_state) {
if (content == 0) {
Badge::clear(script_state, options, exception_state);
} else {
BadgeFromState(script_state)
->SetBadge(options->scope(),
mojom::blink::BadgeValue::NewNumber(content),
exception_state);
}
}
// static
void Badge::clear(ScriptState* script_state,
const BadgeOptions* options,
ExceptionState& exception_state) {
BadgeFromState(script_state)->ClearBadge(options->scope(), exception_state);
}
void Badge::SetBadge(WTF::String scope,
mojom::blink::BadgeValuePtr value,
ExceptionState& exception_state) {
base::Optional<KURL> scope_url = ScopeStringToURL(scope, exception_state);
if (!scope_url)
return;
badge_service_->SetBadge(std::move(value));
}
void Badge::ClearBadge(WTF::String scope, ExceptionState& exception_state) {
base::Optional<KURL> scope_url = ScopeStringToURL(scope, exception_state);
if (!scope_url)
return;
badge_service_->ClearBadge();
}
void Badge::Trace(blink::Visitor* visitor) {
Supplement<ExecutionContext>::Trace(visitor);
ScriptWrappable::Trace(visitor);
visitor->Trace(execution_context_);
}
Badge::Badge(ExecutionContext* context) : execution_context_(context) {
context->GetBrowserInterfaceBroker().GetInterface(
badge_service_.BindNewPipeAndPassReceiver());
DCHECK(badge_service_);
}
// static
Badge* Badge::BadgeFromState(ScriptState* script_state) {
return Badge::From(ExecutionContext::From(script_state));
}
base::Optional<KURL> Badge::ScopeStringToURL(WTF::String& scope,
ExceptionState& exception_state) {
// Resolve |scope| against the URL of the current document/worker.
KURL scope_url = KURL(execution_context_->Url(), scope);
if (!scope_url.IsValid()) {
exception_state.ThrowTypeError("Invalid scope URL");
return base::nullopt;
}
// Same-origin check. Note that this is also checked in BadgeManager on the
// browser side for security, but it is also checked here to report the error.
scoped_refptr<SecurityOrigin> scope_origin =
SecurityOrigin::Create(scope_url);
if (!execution_context_->GetSecurityOrigin()->IsSameSchemeHostPort(
scope_origin.get())) {
exception_state.ThrowSecurityError(
"Scope URL is not in the current origin");
return base::nullopt;
}
return base::Optional<KURL>(scope_url);
}
} // namespace blink
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BADGING_BADGE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_BADGING_BADGE_H_
#include "base/optional.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/badging/badging.mojom-blink.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/supplementable.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
class BadgeOptions;
class ExceptionState;
class ExecutionContext;
class ScriptState;
class Badge final : public ScriptWrappable,
public Supplement<ExecutionContext> {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(Badge);
public:
static const char kSupplementName[];
static Badge* From(ExecutionContext*);
explicit Badge(ExecutionContext*);
~Badge() override;
// Badge IDL interface.
static void set(ScriptState*, const BadgeOptions*, ExceptionState&);
static void set(ScriptState*,
uint64_t content,
const BadgeOptions*,
ExceptionState&);
static void set(ScriptState*, ExceptionState&);
static void set(ScriptState*, uint64_t content, ExceptionState&);
static void clear(ScriptState*, const BadgeOptions*, ExceptionState&);
void SetBadge(WTF::String scope,
mojom::blink::BadgeValuePtr value,
ExceptionState&);
void ClearBadge(WTF::String scope, ExceptionState&);
void Trace(blink::Visitor*) override;
private:
static Badge* BadgeFromState(ScriptState* script_state);
// If the URL is invalid, sets an exception and returns nullopt, which callers
// should check for and stop doing work.
base::Optional<KURL> ScopeStringToURL(WTF::String& scope, ExceptionState&);
mojo::Remote<blink::mojom::blink::BadgeService> badge_service_;
Member<ExecutionContext> execution_context_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BADGING_BADGE_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// The options used to decide how to apply a badge.
// See the explainer https://github.com/WICG/badging/blob/master/explainer.md
dictionary BadgeOptions {
// The scope of the badge. This is resolved against the URL of the current
// page.
// https://github.com/WICG/badging/blob/master/explainer.md#badge-scope
DOMString scope = "/";
};
\ No newline at end of file
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// TODO(estevenson): Add link to spec once complete.
// https://github.com/WICG/badging/blob/master/explainer.md
[
RuntimeEnabled=Badging,
// TODO(estevenson): Expose the Badge interface to Worker.
Exposed=Window,
ImplementedAs=Badge
] interface ExperimentalBadge {
[CallWith=ScriptState, RaisesException, MeasureAs=BadgeSet]
static void set(optional [EnforceRange] unsigned long long contents, optional BadgeOptions options);
[CallWith=ScriptState, RaisesException, MeasureAs=BadgeClear] static void clear(optional BadgeOptions options);
};
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file
#include "third_party/blink/renderer/modules/badging/navigator_badge.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
namespace blink {
const char NavigatorBadge::kSupplementName[] = "NavigatorBadge";
// static
NavigatorBadge& NavigatorBadge::From(ScriptState* script_state) {
ExecutionContext* context = ExecutionContext::From(script_state);
NavigatorBadge* supplement =
Supplement<ExecutionContext>::From<NavigatorBadge>(context);
if (!supplement) {
supplement = MakeGarbageCollected<NavigatorBadge>(context);
ProvideTo(*context, supplement);
}
return *supplement;
}
NavigatorBadge::NavigatorBadge(ExecutionContext* context) {
context->GetBrowserInterfaceBroker().GetInterface(
badge_service_.BindNewPipeAndPassReceiver());
DCHECK(badge_service_);
}
// static
ScriptPromise NavigatorBadge::setAppBadge(ScriptState* script_state,
Navigator& /*navigator*/) {
From(script_state)
.badge_service_->SetBadge(mojom::blink::BadgeValue::NewFlag(0));
return ScriptPromise::CastUndefined(script_state);
}
// static
ScriptPromise NavigatorBadge::setAppBadge(ScriptState* script_state,
Navigator& navigator,
uint64_t content) {
if (content == 0)
return NavigatorBadge::clearAppBadge(script_state, navigator);
From(script_state)
.badge_service_->SetBadge(mojom::blink::BadgeValue::NewNumber(content));
return ScriptPromise::CastUndefined(script_state);
}
// static
ScriptPromise NavigatorBadge::clearAppBadge(ScriptState* script_state,
Navigator& /*navigator*/) {
From(script_state).badge_service_->ClearBadge();
return ScriptPromise::CastUndefined(script_state);
}
void NavigatorBadge::Trace(blink::Visitor* visitor) {
Supplement<ExecutionContext>::Trace(visitor);
}
} // namespace blink
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BADGING_NAVIGATOR_BADGE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_BADGING_NAVIGATOR_BADGE_H_
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/badging/badging.mojom-blink.h"
#include "third_party/blink/renderer/core/frame/navigator.h"
#include "third_party/blink/renderer/platform/supplementable.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
class ScriptPromise;
class NavigatorBadge final : public GarbageCollected<NavigatorBadge>,
public Supplement<ExecutionContext> {
USING_GARBAGE_COLLECTED_MIXIN(NavigatorBadge);
public:
static const char kSupplementName[];
static NavigatorBadge& From(ScriptState*);
explicit NavigatorBadge(ExecutionContext*);
// Badge IDL interface.
static ScriptPromise setAppBadge(ScriptState*, Navigator&);
static ScriptPromise setAppBadge(ScriptState*, Navigator&, uint64_t content);
static ScriptPromise clearAppBadge(ScriptState*, Navigator&);
void Trace(blink::Visitor*) override;
private:
mojo::Remote<blink::mojom::blink::BadgeService> badge_service_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BADGING_NAVIGATOR_BADGE_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// https://wicg.github.io/badging/
[
RuntimeEnabled=Badging,
ImplementedAs=NavigatorBadge
] partial interface Navigator {
[CallWith=ScriptState, MeasureAs=BadgeSet, ImplementedAs=setAppBadge]
Promise<void> setExperimentalAppBadge(optional [EnforceRange] unsigned long long contents);
[CallWith=ScriptState, MeasureAs=BadgeClear, ImplementedAs=clearAppBadge]
Promise<void> clearExperimentalAppBadge();
};
\ No newline at end of file
......@@ -74,7 +74,6 @@ modules_idl_files =
"background_sync/periodic_sync_event.idl",
"background_sync/periodic_sync_manager.idl",
"background_sync/sync_manager.idl",
"badging/experimental_badge.idl",
"battery/battery_manager.idl",
"bluetooth/bluetooth.idl",
"bluetooth/bluetooth_advertising_event.idl",
......@@ -575,7 +574,6 @@ modules_dictionary_idl_files =
"background_sync/background_sync_options.idl",
"background_sync/sync_event_init.idl",
"background_sync/periodic_sync_event_init.idl",
"badging/badge_options.idl",
"bluetooth/bluetooth_advertising_event_init.idl",
"bluetooth/bluetooth_le_scan_filter_init.idl",
"bluetooth/bluetooth_le_scan_options.idl",
......@@ -925,6 +923,7 @@ modules_dependency_idl_files =
"background_fetch/service_worker_registration_background_fetch.idl",
"background_sync/service_worker_global_scope_sync.idl",
"background_sync/service_worker_registration_sync.idl",
"badging/navigator_badge.idl",
"battery/navigator_battery.idl",
"beacon/navigator_beacon.idl",
"bluetooth/navigator_bluetooth.idl",
......
......@@ -12,21 +12,27 @@
<script>
// Negative value not allowed.
badge_test(() => { ExperimentalBadge.set(-1); }, undefined, 'TypeError');
badge_test(() => navigator.setExperimentalAppBadge(-1), undefined,
'TypeError');
// Value too large (2^53).
badge_test(() => { ExperimentalBadge.set(9007199254740992); },
badge_test(() => navigator.setExperimentalAppBadge(Number.MAX_SAFE_INTEGER + 1),
undefined,
'TypeError');
// Illegal numeric values.
badge_test(() => { ExperimentalBadge.set(Infinity); }, undefined, 'TypeError');
badge_test(() => { ExperimentalBadge.set(-Infinity); }, undefined, 'TypeError');
badge_test(() => { ExperimentalBadge.set(NaN); }, undefined, 'TypeError');
badge_test(() => navigator.setExperimentalAppBadge(Infinity), undefined,
'TypeError');
badge_test(() => navigator.setExperimentalAppBadge(-Infinity), undefined,
'TypeError');
badge_test(() => navigator.setExperimentalAppBadge(NaN), undefined,
'TypeError');
// Other values that can't convert to a long.
badge_test(() => { ExperimentalBadge.set("Foo"); }, undefined, 'TypeError');
badge_test(() => { ExperimentalBadge.set({}); }, undefined, 'TypeError');
badge_test(() => navigator.setExperimentalAppBadge("Foo"), undefined,
'TypeError');
badge_test(() => navigator.setExperimentalAppBadge({}), undefined,
'TypeError');
</script>
</body>
......
......@@ -11,29 +11,29 @@
<body>
<script>
badge_test(() => { ExperimentalBadge.set(); }, 'flag');
badge_test(() => navigator.setExperimentalAppBadge(), 'flag');
badge_test(() => { ExperimentalBadge.set(undefined); }, 'flag');
badge_test(() => navigator.setExperimentalAppBadge(undefined), 'flag');
badge_test(() => { ExperimentalBadge.set(1); }, 'number:1');
badge_test(() => navigator.setExperimentalAppBadge(1), 'number:1');
// Non-whole number should round down to nearest integer.
badge_test(() => { ExperimentalBadge.set(10.6); }, 'number:10');
badge_test(() => navigator.setExperimentalAppBadge(10.6), 'number:10');
// Maximum allowed value (2^53 - 1).
badge_test(() => { ExperimentalBadge.set(9007199254740991); },
'number:9007199254740991');
badge_test(() => navigator.setExperimentalAppBadge(Number.MAX_SAFE_INTEGER),
'number:' + Number.MAX_SAFE_INTEGER);
// Setting the Badge to 0 should be equivalent to clearing the badge.
badge_test(() => { ExperimentalBadge.set(0); }, 'clear');
badge_test(() => navigator.setExperimentalAppBadge(0), 'clear');
badge_test(() => { ExperimentalBadge.clear(); }, 'clear');
badge_test(() => navigator.clearExperimentalAppBadge(), 'clear');
// Non-numeric values that convert to integer.
badge_test(() => { ExperimentalBadge.set(null); }, 'clear');
badge_test(() => { ExperimentalBadge.set(false); }, 'clear');
badge_test(() => { ExperimentalBadge.set(true); }, 'number:1');
badge_test(() => { ExperimentalBadge.set('3'); }, 'number:3');
badge_test(() => navigator.setExperimentalAppBadge(null), 'clear');
badge_test(() => navigator.setExperimentalAppBadge(false), 'clear');
badge_test(() => navigator.setExperimentalAppBadge(true), 'number:1');
badge_test(() => navigator.setExperimentalAppBadge('3'), 'number:3');
</script>
</body>
......
......@@ -5,11 +5,10 @@
<script src="../resources/webidl2.js"></script>
<script src="../resources/idlharness.js"></script>
<script type="text/plain" id="tested">
interface ExperimentalBadge {
[CallWith=ScriptState, RaisesException]
static void set(optional [EnforceRange] unsigned long long contents, optional BadgeOptions options);
[CallWith=ScriptState] static void clear(optional BadgeOptions options);
};
interface Navigator {
Promise<void> setExperimentalAppBadge(optional [EnforceRange] unsigned long long contents);
Promise<void> clearExperimentalAppBadge();
};
</script>
<script>
"use strict";
......
......@@ -49,25 +49,16 @@ class MockBadgeService {
let mockBadgeService = new MockBadgeService();
function callAndObserveErrors(func, expectedErrorName) {
return new Promise((resolve, reject) => {
function badge_test(func, expectedAction, expectedError) {
promise_test(async () => {
let mockPromise = mockBadgeService.init_(expectedAction);
try {
func();
await func();
} catch (error) {
try {
assert_equals(error.name, expectedErrorName);
resolve();
} catch (reason) {
reject(reason);
}
return assert_equals(error.name, expectedError);
}
});
}
function badge_test(func, expectedAction, expectedError) {
promise_test(() => {
let mockPromise = mockBadgeService.init_(expectedAction);
return Promise.race(
[callAndObserveErrors(func, expectedError), mockPromise]);
await mockPromise;
});
}
......@@ -11,9 +11,12 @@ generate_token.py http://127.0.0.1:8000 Badging --expire-timestamp=2000000000
<script src="/resources/origin-trials-helper.js"></script>
<script>
function assert_function_on(object, function_name, explanation) {
assert_equals(typeof object[function_name], 'function', explanation);
}
test(t => {
assert_own_property(window, 'ExperimentalBadge', 'ExperimentalBadge is not defined on the window');
assert_own_property(window.ExperimentalBadge, 'set', 'Set is not defined on the ExperimentalBadge API');
assert_own_property(window.ExperimentalBadge, 'clear', 'Clear is not defined on the ExperimentalBadge API');
assert_function_on(navigator, 'setExperimentalAppBadge', 'setExperimentalAppBadge is not defined on navigator');
assert_function_on(navigator, 'clearExperimentalAppBadge', 'clearExperimentalAppBadge is not defined on navigator');
}, 'Badge API interfaces and properties in Origin-Trial enabled document.');
</script>
\ No newline at end of file
......@@ -2357,11 +2357,6 @@ interface EventTarget
method constructor
method dispatchEvent
method removeEventListener
interface ExperimentalBadge
static method clear
static method set
attribute @@toStringTag
method constructor
interface External
attribute @@toStringTag
method AddSearchProvider
......@@ -5215,6 +5210,7 @@ interface Navigator
getter webkitTemporaryStorage
getter xr
method canShare
method clearExperimentalAppBadge
method constructor
method getBattery
method getGamepads
......@@ -5227,6 +5223,7 @@ interface Navigator
method requestMIDIAccess
method requestMediaKeySystemAccess
method sendBeacon
method setExperimentalAppBadge
method share
method unregisterProtocolHandler
method vibrate
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment