Skip to content

Commit

Permalink
Add support for the alarms Web Extension API.
Browse files Browse the repository at this point in the history
https://webkit.org/b/259950
rdar://problem/113592049

Reviewed by Brian Weinstein.

Implements the browser.alarms namespace and added API tests for all the supported methods.
Documentation: https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/alarms

* Source/WebKit/DerivedSources-input.xcfilelist: Added alarm files.
* Source/WebKit/DerivedSources-output.xcfilelist: Ditto.
* Source/WebKit/DerivedSources.make: Added WebExtensionAPIAlarms interface.
* Source/WebKit/Shared/Extensions/WebExtensionAlarmParameters.h: Added.
* Source/WebKit/Shared/Extensions/WebExtensionAlarmParameters.serialization.in: Added.
* Source/WebKit/Sources.txt: Added alarm files.
* Source/WebKit/UIProcess/Extensions/Cocoa/API/WebExtensionContextAPIAlarmsCocoa.mm: Added.
(WebKit::WebExtensionContext::alarmsCreate):
(WebKit::WebExtensionContext::alarmsGet):
(WebKit::WebExtensionContext::alarmsClear):
(WebKit::WebExtensionContext::alarmsGetAll):
(WebKit::WebExtensionContext::alarmsClearAll):
(WebKit::WebExtensionContext::fireAlarmsEventIfNeeded):
* Source/WebKit/UIProcess/Extensions/WebExtensionAlarm.cpp: Added.
(WebKit::WebExtensionAlarm::schedule):
(WebKit::WebExtensionAlarm::fire):
* Source/WebKit/UIProcess/Extensions/WebExtensionAlarm.h: Added.
(WebKit::WebExtensionAlarm::create):
(WebKit::WebExtensionAlarm::WebExtensionAlarm):
(WebKit::WebExtensionAlarm::parameters const):
(WebKit::WebExtensionAlarm::name const):
(WebKit::WebExtensionAlarm::initialInterval const):
(WebKit::WebExtensionAlarm::repeatInterval const):
(WebKit::WebExtensionAlarm::nextScheduledTime const):
* Source/WebKit/UIProcess/Extensions/WebExtensionContext.h:
* Source/WebKit/UIProcess/Extensions/WebExtensionContext.messages.in: Added alarm messages.
* Source/WebKit/UIProcess/Extensions/WebExtensionController.cpp:
* Source/WebKit/WebKit.xcodeproj/project.pbxproj: Added new files.
* Source/WebKit/WebProcess/Extensions/API/Cocoa/WebExtensionAPIAlarmsCocoa.mm: Added.
(WebKit::toAPI):
(WebKit::WebExtensionAPIAlarms::createAlarm):
(WebKit::WebExtensionAPIAlarms::get):
(WebKit::WebExtensionAPIAlarms::getAll):
(WebKit::WebExtensionAPIAlarms::clear):
(WebKit::WebExtensionAPIAlarms::clearAll):
(WebKit::WebExtensionAPIAlarms::onAlarm):
(WebKit::WebExtensionContextProxy::dispatchAlarmEvent):
* Source/WebKit/WebProcess/Extensions/API/Cocoa/WebExtensionAPINamespaceCocoa.mm:
(WebKit::WebExtensionAPINamespace::isPropertyAllowed): Added FIXME and check permissions for alarms too.
(WebKit::WebExtensionAPINamespace::alarms): Added.
* Source/WebKit/WebProcess/Extensions/API/WebExtensionAPIAlarms.h: Added.
* Source/WebKit/WebProcess/Extensions/API/WebExtensionAPINamespace.h:
* Source/WebKit/WebProcess/Extensions/Interfaces/WebExtensionAPIAlarms.idl: Added.
* Source/WebKit/WebProcess/Extensions/Interfaces/WebExtensionAPINamespace.idl: Added alarms.
* Source/WebKit/WebProcess/Extensions/WebExtensionContextProxy.h:
* Source/WebKit/WebProcess/Extensions/WebExtensionContextProxy.messages.in: Added alarm messages.
* Tools/TestWebKitAPI/SourcesCocoa.txt:
* Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtensionAPIAlarms.mm: Added.
* Tools/TestWebKitAPI/cocoa/WebExtensionUtilities.h:
(TestWebKitAPI::Util::constructScript): Stop adding semicolons, it can cause mysterious errors.
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewGetContents.mm: Use "UIKitSPI.h" since it was conflicting
with <pal/spi/ios/UIKitSPI.h> due to unified sources shifting around.
* Tools/TestWebKitAPI/ios/UIKitSPI.h: Add missing interfaces needed by WKWebViewGetContents.mm.

Canonical link: https://commits.webkit.org/266742@main
  • Loading branch information
xeenon committed Aug 9, 2023
1 parent f0bb878 commit de4ab2c
Show file tree
Hide file tree
Showing 27 changed files with 1,050 additions and 13 deletions.
2 changes: 2 additions & 0 deletions Source/WebKit/DerivedSources-input.xcfilelist
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ $(PROJECT_DIR)/Shared/Cocoa/WebCoreArgumentCodersCocoa.serialization.in
$(PROJECT_DIR)/Shared/Databases/IndexedDB/WebIDBResult.serialization.in
$(PROJECT_DIR)/Shared/DisplayListArgumentCoders.serialization.in
$(PROJECT_DIR)/Shared/EditorState.serialization.in
$(PROJECT_DIR)/Shared/Extensions/WebExtensionAlarmParameters.serialization.in
$(PROJECT_DIR)/Shared/Extensions/WebExtensionContextParameters.serialization.in
$(PROJECT_DIR)/Shared/Extensions/WebExtensionControllerParameters.serialization.in
$(PROJECT_DIR)/Shared/Extensions/WebExtensionEventListenerType.serialization.in
Expand Down Expand Up @@ -368,6 +369,7 @@ $(PROJECT_DIR)/WebProcess/Cache/WebCacheStorageConnection.messages.in
$(PROJECT_DIR)/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.messages.in
$(PROJECT_DIR)/WebProcess/Extensions/Bindings/Scripts/CodeGeneratorExtensions.pm
$(PROJECT_DIR)/WebProcess/Extensions/Bindings/Scripts/IDLAttributes.json
$(PROJECT_DIR)/WebProcess/Extensions/Interfaces/WebExtensionAPIAlarms.idl
$(PROJECT_DIR)/WebProcess/Extensions/Interfaces/WebExtensionAPIEvent.idl
$(PROJECT_DIR)/WebProcess/Extensions/Interfaces/WebExtensionAPIExtension.idl
$(PROJECT_DIR)/WebProcess/Extensions/Interfaces/WebExtensionAPINamespace.idl
Expand Down
2 changes: 2 additions & 0 deletions Source/WebKit/DerivedSources-output.xcfilelist
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/IPCTesterMessages.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/IPCTesterReceiverMessageReceiver.cpp
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/IPCTesterReceiverMessages.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/IPCTesterReceiverMessagesReplies.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/JSWebExtensionAPIAlarms.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/JSWebExtensionAPIAlarms.mm
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/JSWebExtensionAPIEvent.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/JSWebExtensionAPIEvent.mm
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/JSWebExtensionAPIExtension.h
Expand Down
2 changes: 2 additions & 0 deletions Source/WebKit/DerivedSources.make
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ SERIALIZATION_DESCRIPTION_FILES = \
Shared/BackgroundFetchState.serialization.in \
Shared/DisplayListArgumentCoders.serialization.in \
Shared/EditorState.serialization.in \
Shared/Extensions/WebExtensionAlarmParameters.serialization.in \
Shared/Extensions/WebExtensionContextParameters.serialization.in \
Shared/Extensions/WebExtensionControllerParameters.serialization.in \
Shared/Extensions/WebExtensionEventListenerType.serialization.in \
Expand Down Expand Up @@ -641,6 +642,7 @@ BINDINGS_SCRIPTS = \
#

EXTENSION_INTERFACES = \
WebExtensionAPIAlarms \
WebExtensionAPIEvent \
WebExtensionAPIExtension \
WebExtensionAPINamespace \
Expand Down
44 changes: 44 additions & 0 deletions Source/WebKit/Shared/Extensions/WebExtensionAlarmParameters.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2023 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#pragma once

#if ENABLE(WK_WEB_EXTENSIONS)

#include <wtf/Forward.h>
#include <wtf/MonotonicTime.h>

namespace WebKit {

struct WebExtensionAlarmParameters {
String name;
Seconds initialInterval;
Seconds repeatInterval;
MonotonicTime nextScheduledTime;
};

} // namespace WebKit

#endif // ENABLE(WK_WEB_EXTENSIONS)
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright (C) 2023 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#if ENABLE(WK_WEB_EXTENSIONS)

struct WebKit::WebExtensionAlarmParameters {
String name;
Seconds initialInterval;
Seconds repeatInterval;
MonotonicTime nextScheduledTime;
}

#endif
1 change: 1 addition & 0 deletions Source/WebKit/Sources.txt
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,7 @@ UIProcess/Automation/WebAutomationSession.cpp @no-unify
UIProcess/Downloads/DownloadProxy.cpp
UIProcess/Downloads/DownloadProxyMap.cpp

UIProcess/Extensions/WebExtensionAlarm.cpp
UIProcess/Extensions/WebExtensionContext.cpp
UIProcess/Extensions/WebExtensionController.cpp
UIProcess/Extensions/WebExtensionControllerConfiguration.cpp
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright (C) 2023 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#if !__has_feature(objc_arc)
#error This file requires ARC. Add the "-fobjc-arc" compiler flag for this file.
#endif

#import "config.h"
#import "WebExtensionContext.h"

#if ENABLE(WK_WEB_EXTENSIONS)

#import "WebExtensionAlarm.h"
#import "WebExtensionContextProxy.h"
#import "WebExtensionContextProxyMessages.h"

namespace WebKit {

void WebExtensionContext::alarmsCreate(const String& name, Seconds initialInterval, Seconds repeatInterval)
{
m_alarmMap.set(name, WebExtensionAlarm::create(name, initialInterval, repeatInterval, [&](const WebExtensionAlarm& alarm) {
fireAlarmsEventIfNeeded(alarm);
}));
}

void WebExtensionContext::alarmsGet(const String& name, CompletionHandler<void(std::optional<WebExtensionAlarmParameters>)>&& completionHandler)
{
if (auto* alarm = m_alarmMap.get(name))
completionHandler(alarm->parameters());
else
completionHandler(std::nullopt);
}

void WebExtensionContext::alarmsClear(const String& name, CompletionHandler<void()>&& completionHandler)
{
m_alarmMap.remove(name);

completionHandler();
}

void WebExtensionContext::alarmsGetAll(CompletionHandler<void(Vector<WebExtensionAlarmParameters>&&)>&& completionHandler)
{
Vector<WebExtensionAlarmParameters> alarms;
alarms.reserveInitialCapacity(m_alarmMap.size());

for (auto& alarm : m_alarmMap.values())
alarms.uncheckedAppend(alarm->parameters());

completionHandler(WTFMove(alarms));
}

void WebExtensionContext::alarmsClearAll(CompletionHandler<void()>&& completionHandler)
{
m_alarmMap.clear();

completionHandler();
}

void WebExtensionContext::fireAlarmsEventIfNeeded(const WebExtensionAlarm& alarm)
{
auto type = WebExtensionEventListenerType::AlarmsOnAlarm;
wakeUpBackgroundContentIfNecessaryToFireEvents({ type }, [&] {
sendToProcessesForEvent(type, Messages::WebExtensionContextProxy::DispatchAlarmEvent(alarm.parameters()));
});
}

} // namespace WebKit

#endif // ENABLE(WK_WEB_EXTENSIONS)
62 changes: 62 additions & 0 deletions Source/WebKit/UIProcess/Extensions/WebExtensionAlarm.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright (C) 2023 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "config.h"
#include "WebExtensionAlarm.h"

#if ENABLE(WK_WEB_EXTENSIONS)

namespace WebKit {

using namespace WebCore;

void WebExtensionAlarm::schedule()
{
m_parameters.nextScheduledTime = MonotonicTime::now() + initialInterval();

RELEASE_LOG_INFO(Extensions, "Scheduled alarm; initial = %f seconds; repeat = %f seconds", initialInterval().seconds(), repeatInterval().seconds());

m_timer = makeUnique<Timer>(*this, &WebExtensionAlarm::fire);
m_timer->start(initialInterval(), repeatInterval());
}

void WebExtensionAlarm::fire()
{
// Calculate the next scheduled time now, so the handler's work time does not count against it.
auto nextScheduledTime = MonotonicTime::now() + repeatInterval();

m_handler(*this);

if (!repeatInterval()) {
m_timer = nullptr;
return;
}

m_parameters.nextScheduledTime = nextScheduledTime;
}

} // namespace WebKit

#endif // ENABLE(WK_WEB_EXTENSIONS)
78 changes: 78 additions & 0 deletions Source/WebKit/UIProcess/Extensions/WebExtensionAlarm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright (C) 2023 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#pragma once

#if ENABLE(WK_WEB_EXTENSIONS)

#include "WebExtensionAlarmParameters.h"
#include <WebCore/Timer.h>
#include <wtf/Forward.h>
#include <wtf/Function.h>
#include <wtf/RefCounted.h>

namespace WebKit {

class WebExtensionContext;

class WebExtensionAlarm : public RefCounted<WebExtensionAlarm> {
WTF_MAKE_NONCOPYABLE(WebExtensionAlarm);
WTF_MAKE_FAST_ALLOCATED;

public:
template<typename... Args>
static Ref<WebExtensionAlarm> create(Args&&... args)
{
return adoptRef(*new WebExtensionAlarm(std::forward<Args>(args)...));
}

explicit WebExtensionAlarm(String name, Seconds initialInterval, Seconds repeatInterval, Function<void(WebExtensionAlarm&)>&& handler = nullptr)
: m_parameters({ name, initialInterval, repeatInterval, MonotonicTime::nan() })
, m_handler(WTFMove(handler))
{
ASSERT(!name.isNull());
schedule();
}

const WebExtensionAlarmParameters& parameters() const { return m_parameters; }

const String& name() const { return m_parameters.name; }
Seconds initialInterval() const { return m_parameters.initialInterval; }
Seconds repeatInterval() const { return m_parameters.repeatInterval; }
MonotonicTime nextScheduledTime() const { return m_parameters.nextScheduledTime; }

private:
void schedule();
void fire();

WebExtensionAlarmParameters m_parameters;

Function<void(WebExtensionAlarm&)> m_handler;
std::unique_ptr<WebCore::Timer> m_timer;
};

} // namespace WebKit

#endif // ENABLE(WK_WEB_EXTENSIONS)
Loading

0 comments on commit de4ab2c

Please sign in to comment.