From 4e05fa12a2cb11d0702eb604e6c37a95e9b1d376 Mon Sep 17 00:00:00 2001 From: Arun Joseph Date: Wed, 22 Jul 2020 22:43:13 +0530 Subject: [PATCH] Cherry pick GTK WebKit 2.28.3 changes --- .../Source/JavaScriptCore/dfg/DFGClobberize.h | 4 +- .../JavaScriptCore/heap/GCMemoryOperations.h | 6 +- .../JavaScriptCore/runtime/StructureInlines.h | 6 +- .../main/native/Source/WTF/wtf/DataMutex.h | 88 +++++++++++++++++-- .../main/native/Source/WebCore/SourcesWPE.txt | 2 + .../bindings/js/JSDOMWindowProperties.h | 2 +- .../WebCore/bindings/js/ScriptController.cpp | 13 ++- .../bindings/scripts/CodeGeneratorJS.pm | 9 +- .../Source/WebCore/loader/FrameLoader.cpp | 11 ++- .../scrolling/ScrollingTreeScrollingNode.cpp | 3 + .../scrolling/ScrollingTreeScrollingNode.h | 4 + ...ScrollingTreeFrameScrollingNodeNicosia.cpp | 43 +++++++++ .../ScrollingTreeFrameScrollingNodeNicosia.h | 7 ++ ...ollingTreeOverflowScrollingNodeNicosia.cpp | 41 +++++++++ ...crollingTreeOverflowScrollingNodeNicosia.h | 7 ++ .../WebCore/platform/MIMETypeRegistry.cpp | 6 ++ .../WebCore/platform/MIMETypeRegistry.h | 3 + .../platform/ScrollAnimationKinetic.cpp | 59 +++++++++++-- .../WebCore/platform/ScrollAnimationKinetic.h | 29 ++++-- .../generic/ScrollAnimatorGeneric.cpp | 58 ++++-------- .../platform/generic/ScrollAnimatorGeneric.h | 6 +- .../platform/graphics/PlatformDisplay.cpp | 12 +-- .../graphics/PlatformMediaResourceLoader.h | 4 +- .../Source/WebCore/rendering/RenderBlock.cpp | 1 + .../Source/WebCore/rendering/RenderLayer.cpp | 23 ++--- .../Source/WebCore/rendering/RenderLayer.h | 1 - .../WebCore/rendering/RenderLayerFilters.cpp | 6 +- .../svg/RenderSVGResourceClipper.cpp | 56 ++++++------ .../rendering/svg/RenderSVGResourceClipper.h | 29 ++++-- .../svg/RenderSVGResourceContainer.cpp | 27 ++++-- .../updating/RenderTreeBuilderFirstLetter.cpp | 4 +- .../Source/WebCore/svg/SVGClipPathElement.cpp | 1 + .../native/Source/WebCore/svg/SVGTransform.h | 14 +++ .../WebCore/svg/properties/SVGProperty.h | 11 ++- .../service/context/ServiceWorkerFetch.cpp | 1 + .../xml/parser/XMLDocumentParserLibxml2.cpp | 22 +++++ 36 files changed, 467 insertions(+), 152 deletions(-) diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/dfg/DFGClobberize.h b/modules/javafx.web/src/main/native/Source/JavaScriptCore/dfg/DFGClobberize.h index f2b75cf01d1..a62b90f3fbc 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/dfg/DFGClobberize.h +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/dfg/DFGClobberize.h @@ -228,7 +228,7 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu case ArithAbs: if (node->child1().useKind() == Int32Use || node->child1().useKind() == DoubleRepUse) - def(PureValue(node)); + def(PureValue(node, node->arithMode())); else { read(World); write(Heap); @@ -248,7 +248,7 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu if (node->child1().useKind() == Int32Use || node->child1().useKind() == DoubleRepUse || node->child1().useKind() == Int52RepUse) - def(PureValue(node)); + def(PureValue(node, node->arithMode())); else { read(World); write(Heap); diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/heap/GCMemoryOperations.h b/modules/javafx.web/src/main/native/Source/JavaScriptCore/heap/GCMemoryOperations.h index f42539ac797..9795383b18c 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/heap/GCMemoryOperations.h +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/heap/GCMemoryOperations.h @@ -53,7 +53,7 @@ ALWAYS_INLINE void gcSafeMemcpy(T* dst, T* src, size_t bytes) bitwise_cast(dst)[i] = bitwise_cast(src)[i]; }; -#if COMPILER(GCC_COMPATIBLE) && USE(JSVALUE64) +#if COMPILER(GCC_COMPATIBLE) && (CPU(X86_64) || CPU(ARM64)) if (bytes <= smallCutoff) slowPathForwardMemcpy(); else if (isARM64() || bytes <= mediumCutoff) { @@ -121,8 +121,6 @@ ALWAYS_INLINE void gcSafeMemcpy(T* dst, T* src, size_t bytes) : : "d0", "d1", "memory" ); -#else - slowPathForwardMemcpy(); #endif // CPU(X86_64) } else { RELEASE_ASSERT(isX86_64()); @@ -139,7 +137,7 @@ ALWAYS_INLINE void gcSafeMemcpy(T* dst, T* src, size_t bytes) } #else slowPathForwardMemcpy(); -#endif // COMPILER(GCC_COMPATIBLE) +#endif // COMPILER(GCC_COMPATIBLE) && (CPU(X86_64) || CPU(ARM64)) #else memcpy(dst, src, bytes); #endif // USE(JSVALUE64) diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/StructureInlines.h b/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/StructureInlines.h index 4198f0ba79b..8284da7fd95 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/StructureInlines.h +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/StructureInlines.h @@ -36,16 +36,16 @@ namespace JSC { -inline Structure* Structure::create(VM& vm, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType, unsigned inlineCapacity) +inline Structure* Structure::create(VM& vm, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingModeIncludingHistory, unsigned inlineCapacity) { ASSERT(vm.structureStructure); ASSERT(classInfo); if (auto* object = prototype.getObject()) { - ASSERT(!object->anyObjectInChainMayInterceptIndexedAccesses(vm) || hasSlowPutArrayStorage(indexingType) || !hasIndexedProperties(indexingType)); + ASSERT(!object->anyObjectInChainMayInterceptIndexedAccesses(vm) || hasSlowPutArrayStorage(indexingModeIncludingHistory) || !hasIndexedProperties(indexingModeIncludingHistory)); object->didBecomePrototype(); } - Structure* structure = new (NotNull, allocateCell(vm.heap)) Structure(vm, globalObject, prototype, typeInfo, classInfo, indexingType, inlineCapacity); + Structure* structure = new (NotNull, allocateCell(vm.heap)) Structure(vm, globalObject, prototype, typeInfo, classInfo, indexingModeIncludingHistory, inlineCapacity); structure->finishCreation(vm); return structure; } diff --git a/modules/javafx.web/src/main/native/Source/WTF/wtf/DataMutex.h b/modules/javafx.web/src/main/native/Source/WTF/wtf/DataMutex.h index 8a5c5ec7193..60f15370e05 100644 --- a/modules/javafx.web/src/main/native/Source/WTF/wtf/DataMutex.h +++ b/modules/javafx.web/src/main/native/Source/WTF/wtf/DataMutex.h @@ -21,10 +21,74 @@ #pragma once #include +#include namespace WTF { -template +// By default invalid access checks are only done in Debug builds. +#if !defined(ENABLE_DATA_MUTEX_CHECKS) +#if defined(NDEBUG) +#define ENABLE_DATA_MUTEX_CHECKS 0 +#else +#define ENABLE_DATA_MUTEX_CHECKS 1 +#endif +#endif + +#if ENABLE_DATA_MUTEX_CHECKS +#define DATA_MUTEX_CHECK(expr) RELEASE_ASSERT(expr) +#else +#define DATA_MUTEX_CHECK(expr) +#endif + +template +class OwnerAwareLockAdapter { +public: + void lock() + { + DATA_MUTEX_CHECK(m_owner != &Thread::current()); // Thread attempted recursive lock (unsupported). + m_lock.lock(); +#if ENABLE_DATA_MUTEX_CHECKS + ASSERT(!m_owner); + m_owner = &Thread::current(); +#endif + } + + void unlock() + { +#if ENABLE_DATA_MUTEX_CHECKS + m_owner = nullptr; +#endif + m_lock.unlock(); + } + + bool tryLock() + { + DATA_MUTEX_CHECK(m_owner != &Thread::current()); // Thread attempted recursive lock (unsupported). + if (!m_lock.tryLock()) + return false; + +#if ENABLE_DATA_MUTEX_CHECKS + ASSERT(!m_owner); + m_owner = &Thread::current(); +#endif + return true; + } + + bool isLocked() const + { + return m_lock.isLocked(); + } + +private: +#if ENABLE_DATA_MUTEX_CHECKS + Thread* m_owner { nullptr }; // Use Thread* instead of RefPtr since m_owner thread is always alive while m_owner is set. +#endif + LockType m_lock; +}; + +using OwnerAwareLock = OwnerAwareLockAdapter; + +template class DataMutex { WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(DataMutex); @@ -44,32 +108,44 @@ class DataMutex { T* operator->() { + DATA_MUTEX_CHECK(m_mutex.isLocked()); return &m_data; } T& operator*() { + DATA_MUTEX_CHECK(m_mutex.isLocked()); return m_data; } - Lock& mutex() + LockType& mutex() { return m_mutex; } - LockHolder& lockHolder() + Locker& lockHolder() { return m_lockHolder; } + // Used to avoid excessive brace scoping when only small parts of the code need to be run unlocked. + // Please be mindful that accessing the wrapped data from the callback is unsafe and will fail on assertions. + // It's helpful to use a minimal lambda capture to be conscious of what data you're having access to in these sections. + void runUnlocked(WTF::Function callback) + { + m_mutex.unlock(); + callback(); + m_mutex.lock(); + } + private: - Lock& m_mutex; - LockHolder m_lockHolder; + LockType& m_mutex; + Locker m_lockHolder; T& m_data; }; private: - Lock m_mutex; + LockType m_mutex; T m_data; }; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/SourcesWPE.txt b/modules/javafx.web/src/main/native/Source/WebCore/SourcesWPE.txt index b5c89150887..7e18e797af4 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/SourcesWPE.txt +++ b/modules/javafx.web/src/main/native/Source/WebCore/SourcesWPE.txt @@ -59,6 +59,8 @@ page/scrolling/nicosia/ScrollingTreeStickyNode.cpp page/scrolling/generic/ScrollingThreadGeneric.cpp +platform/ScrollAnimationKinetic.cpp + platform/UserAgentQuirks.cpp platform/graphics/GLContext.cpp diff --git a/modules/javafx.web/src/main/native/Source/WebCore/bindings/js/JSDOMWindowProperties.h b/modules/javafx.web/src/main/native/Source/WebCore/bindings/js/JSDOMWindowProperties.h index ff186eb7dad..318c6607cfe 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/bindings/js/JSDOMWindowProperties.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/bindings/js/JSDOMWindowProperties.h @@ -51,7 +51,7 @@ class JSDOMWindowProperties final : public JSDOMObject { static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) { - return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::MayHaveIndexedAccessors); } static bool getOwnPropertySlot(JSC::JSObject*, JSC::JSGlobalObject*, JSC::PropertyName, JSC::PropertySlot&); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/bindings/js/ScriptController.cpp b/modules/javafx.web/src/main/native/Source/WebCore/bindings/js/ScriptController.cpp index d64f7a0fbbc..92317ee3b02 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/bindings/js/ScriptController.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/bindings/js/ScriptController.cpp @@ -811,16 +811,27 @@ bool ScriptController::executeIfJavaScriptURL(const URL& url, RefPtrvm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + String decodedURL = decodeURLEscapeSequences(url.string()); auto result = executeScriptIgnoringException(decodedURL.substring(javascriptSchemeLength)); + RELEASE_ASSERT(&vm == &jsWindowProxy(mainThreadNormalWorld()).window()->vm()); // If executing script caused this frame to be removed from the page, we // don't want to try to replace its document! if (!m_frame.page()) return true; + if (!result) + return true; + String scriptResult; - if (!result || !result.getString(jsWindowProxy(mainThreadNormalWorld()).window(), scriptResult)) + bool isString = result.getString(globalObject, scriptResult); + RETURN_IF_EXCEPTION(throwScope, true); + + if (!isString) return true; // FIXME: We should always replace the document, but doing so diff --git a/modules/javafx.web/src/main/native/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm b/modules/javafx.web/src/main/native/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm index 2f5277abf57..2fa8372c139 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm +++ b/modules/javafx.web/src/main/native/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm @@ -2741,15 +2741,16 @@ sub GenerateHeader # Structure ID push(@headerContent, " static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)\n"); push(@headerContent, " {\n"); + my $indexingModeIncludingHistory = InstanceOverridesGetOwnPropertySlot($interface) ? "JSC::MayHaveIndexedAccessors" : "JSC::NonArray"; if (IsDOMGlobalObject($interface)) { - push(@headerContent, " return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::GlobalObjectType, StructureFlags), info());\n"); + push(@headerContent, " return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::GlobalObjectType, StructureFlags), info(), $indexingModeIncludingHistory);\n"); } elsif ($codeGenerator->InheritsInterface($interface, "Node")) { my $type = GetJSTypeForNode($interface); - push(@headerContent, " return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSType($type), StructureFlags), info());\n"); + push(@headerContent, " return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSType($type), StructureFlags), info(), $indexingModeIncludingHistory);\n"); } elsif ($codeGenerator->InheritsInterface($interface, "Event")) { - push(@headerContent, " return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSType(JSEventType), StructureFlags), info());\n"); + push(@headerContent, " return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSType(JSEventType), StructureFlags), info(), $indexingModeIncludingHistory);\n"); } else { - push(@headerContent, " return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());\n"); + push(@headerContent, " return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), $indexingModeIncludingHistory);\n"); } push(@headerContent, " }\n\n"); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/loader/FrameLoader.cpp b/modules/javafx.web/src/main/native/Source/WebCore/loader/FrameLoader.cpp index 1842f78926b..50fca0cd06e 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/loader/FrameLoader.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/loader/FrameLoader.cpp @@ -4169,12 +4169,21 @@ RefPtr createWindow(Frame& openerFrame, Frame& lookupFrame, FrameLoadRequ windowRect.setX(*features.x); if (features.y) windowRect.setY(*features.y); - // Zero width and height mean using default size, not minumum one. + // Zero width and height mean using default size, not minimum one. if (features.width && *features.width) windowRect.setWidth(*features.width + (windowRect.width() - viewportSize.width())); if (features.height && *features.height) windowRect.setHeight(*features.height + (windowRect.height() - viewportSize.height())); +#if PLATFORM(GTK) + FloatRect oldWindowRect = oldPage->chrome().windowRect(); + // Use the size of the previous window if there is no default size. + if (!windowRect.width()) + windowRect.setWidth(oldWindowRect.width()); + if (!windowRect.height()) + windowRect.setHeight(oldWindowRect.height()); +#endif + // Ensure non-NaN values, minimum size as well as being within valid screen area. FloatRect newWindowRect = DOMWindow::adjustWindowRect(*page, windowRect); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp b/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp index 5c851cf26a2..76d5f830cad 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp @@ -164,6 +164,9 @@ void ScrollingTreeScrollingNode::scrollTo(const FloatPoint& position, ScrollType if (position == m_currentScrollPosition) return; + if (scrollType == ScrollType::Programmatic) + stopScrollAnimations(); + scrollingTree().setIsHandlingProgrammaticScroll(scrollType == ScrollType::Programmatic); m_currentScrollPosition = adjustedScrollPosition(position, clamp); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h b/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h index d8c446365d3..656de710cec 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h @@ -63,6 +63,8 @@ class WEBCORE_EXPORT ScrollingTreeScrollingNode : public ScrollingTreeNode { void scrollTo(const FloatPoint&, ScrollType = ScrollType::User, ScrollClamping = ScrollClamping::Clamped); void scrollBy(const FloatSize&, ScrollClamping = ScrollClamping::Clamped); + virtual void stopScrollAnimations() { }; + void wasScrolledByDelegatedScrolling(const FloatPoint& position, Optional overrideLayoutViewport = { }, ScrollingLayerPositionAction = ScrollingLayerPositionAction::Sync); const FloatSize& scrollableAreaSize() const { return m_scrollableAreaSize; } @@ -70,6 +72,8 @@ class WEBCORE_EXPORT ScrollingTreeScrollingNode : public ScrollingTreeNode { bool horizontalScrollbarHiddenByStyle() const { return m_scrollableAreaParameters.horizontalScrollbarHiddenByStyle; } bool verticalScrollbarHiddenByStyle() const { return m_scrollableAreaParameters.verticalScrollbarHiddenByStyle; } + bool canHaveHorizontalScrollbar() const { return m_scrollableAreaParameters.horizontalScrollbarMode != ScrollbarAlwaysOff; } + bool canHaveVerticalScrollbar() const { return m_scrollableAreaParameters.verticalScrollbarMode != ScrollbarAlwaysOff; } bool canHaveScrollbars() const { return m_scrollableAreaParameters.horizontalScrollbarMode != ScrollbarAlwaysOff || m_scrollableAreaParameters.verticalScrollbarMode != ScrollbarAlwaysOff; } #if ENABLE(CSS_SCROLL_SNAP) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp b/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp index b797b004f29..bbc816836d3 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp @@ -37,6 +37,10 @@ #include "ScrollingStateFrameScrollingNode.h" #include "ScrollingTree.h" +#if ENABLE(KINETIC_SCROLLING) +#include "ScrollAnimationKinetic.h" +#endif + namespace WebCore { Ref ScrollingTreeFrameScrollingNodeNicosia::create(ScrollingTree& scrollingTree, ScrollingNodeType nodeType, ScrollingNodeID nodeID) @@ -47,6 +51,20 @@ Ref ScrollingTreeFrameScrollingNodeNicosia::cre ScrollingTreeFrameScrollingNodeNicosia::ScrollingTreeFrameScrollingNodeNicosia(ScrollingTree& scrollingTree, ScrollingNodeType nodeType, ScrollingNodeID nodeID) : ScrollingTreeFrameScrollingNode(scrollingTree, nodeType, nodeID) { +#if ENABLE(KINETIC_SCROLLING) + m_kineticAnimation = makeUnique( + [this]() -> ScrollAnimationKinetic::ScrollExtents { + return { IntPoint(minimumScrollPosition()), IntPoint(maximumScrollPosition()) }; + }, + [this](FloatPoint&& position) { + auto* scrollLayer = static_cast(scrolledContentsLayer()); + ASSERT(scrollLayer); + auto& compositionLayer = downcast(*scrollLayer); + + auto updateScope = compositionLayer.createUpdateScope(); + scrollTo(position); + }); +#endif } ScrollingTreeFrameScrollingNodeNicosia::~ScrollingTreeFrameScrollingNodeNicosia() = default; @@ -108,7 +126,24 @@ ScrollingEventResult ScrollingTreeFrameScrollingNodeNicosia::handleWheelEvent(co auto updateScope = compositionLayer.createUpdateScope(); scrollBy({ -wheelEvent.deltaX(), -wheelEvent.deltaY() }); + + } + +#if ENABLE(KINETIC_SCROLLING) + m_kineticAnimation->appendToScrollHistory(wheelEvent); +#endif + +#if ENABLE(KINETIC_SCROLLING) + m_kineticAnimation->stop(); + if (wheelEvent.isEndOfNonMomentumScroll()) { + m_kineticAnimation->start(currentScrollPosition(), m_kineticAnimation->computeVelocity(), canHaveHorizontalScrollbar(), canHaveVerticalScrollbar()); + m_kineticAnimation->clearScrollHistory(); + } + if (wheelEvent.isTransitioningToMomentumScroll()) { + m_kineticAnimation->start(currentScrollPosition(), wheelEvent.swipeVelocity(), canHaveHorizontalScrollbar(), canHaveVerticalScrollbar()); + m_kineticAnimation->clearScrollHistory(); } +#endif scrollingTree().setOrClearLatchedNode(wheelEvent, scrollingNodeID()); @@ -116,6 +151,14 @@ ScrollingEventResult ScrollingTreeFrameScrollingNodeNicosia::handleWheelEvent(co return ScrollingEventResult::DidHandleEvent; } +void ScrollingTreeFrameScrollingNodeNicosia::stopScrollAnimations() +{ +#if ENABLE(KINETIC_SCROLLING) + m_kineticAnimation->stop(); + m_kineticAnimation->clearScrollHistory(); +#endif +} + FloatPoint ScrollingTreeFrameScrollingNodeNicosia::adjustedScrollPosition(const FloatPoint& position, ScrollClamping clamping) const { FloatPoint scrollPosition(roundf(position.x()), roundf(position.y())); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.h b/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.h index 171687db82a..dad1acdd763 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.h @@ -39,6 +39,7 @@ class CompositionLayer; } namespace WebCore { +class ScrollAnimationKinetic; class ScrollingTreeFrameScrollingNodeNicosia final : public ScrollingTreeFrameScrollingNode { public: @@ -53,6 +54,8 @@ class ScrollingTreeFrameScrollingNodeNicosia final : public ScrollingTreeFrameSc ScrollingEventResult handleWheelEvent(const PlatformWheelEvent&) override; + void stopScrollAnimations() override; + FloatPoint adjustedScrollPosition(const FloatPoint&, ScrollClamping) const override; void currentScrollPositionChanged() override; @@ -66,6 +69,10 @@ class ScrollingTreeFrameScrollingNodeNicosia final : public ScrollingTreeFrameSc RefPtr m_contentShadowLayer; RefPtr m_headerLayer; RefPtr m_footerLayer; + +#if ENABLE(KINETIC_SCROLLING) + std::unique_ptr m_kineticAnimation; +#endif }; } // namespace WebCore diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.cpp b/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.cpp index 70f041414a8..0e189b581be 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.cpp @@ -32,6 +32,9 @@ #if ENABLE(ASYNC_SCROLLING) && USE(NICOSIA) #include "NicosiaPlatformLayer.h" +#if ENABLE(KINETIC_SCROLLING) +#include "ScrollAnimationKinetic.h" +#endif #include "ScrollingStateOverflowScrollingNode.h" #include "ScrollingTree.h" @@ -45,6 +48,20 @@ Ref ScrollingTreeOverflowScrollingNodeNicosi ScrollingTreeOverflowScrollingNodeNicosia::ScrollingTreeOverflowScrollingNodeNicosia(ScrollingTree& scrollingTree, ScrollingNodeID nodeID) : ScrollingTreeOverflowScrollingNode(scrollingTree, nodeID) { +#if ENABLE(KINETIC_SCROLLING) + m_kineticAnimation = makeUnique( + [this]() -> ScrollAnimationKinetic::ScrollExtents { + return { IntPoint(minimumScrollPosition()), IntPoint(maximumScrollPosition()) }; + }, + [this](FloatPoint&& position) { + auto* scrollLayer = static_cast(scrolledContentsLayer()); + ASSERT(scrollLayer); + auto& compositionLayer = downcast(*scrollLayer); + + auto updateScope = compositionLayer.createUpdateScope(); + scrollTo(position); + }); +#endif } ScrollingTreeOverflowScrollingNodeNicosia::~ScrollingTreeOverflowScrollingNodeNicosia() = default; @@ -96,11 +113,35 @@ ScrollingEventResult ScrollingTreeOverflowScrollingNodeNicosia::handleWheelEvent scrollBy({ -wheelEvent.deltaX(), -wheelEvent.deltaY() }); } +#if ENABLE(KINETIC_SCROLLING) + m_kineticAnimation->appendToScrollHistory(wheelEvent); +#endif + +#if ENABLE(KINETIC_SCROLLING) + m_kineticAnimation->stop(); + if (wheelEvent.isEndOfNonMomentumScroll()) { + m_kineticAnimation->start(currentScrollPosition(), m_kineticAnimation->computeVelocity(), canHaveHorizontalScrollbar(), canHaveVerticalScrollbar()); + m_kineticAnimation->clearScrollHistory(); + } + if (wheelEvent.isTransitioningToMomentumScroll()) { + m_kineticAnimation->start(currentScrollPosition(), wheelEvent.swipeVelocity(), canHaveHorizontalScrollbar(), canHaveVerticalScrollbar()); + m_kineticAnimation->clearScrollHistory(); + } +#endif + scrollingTree().setOrClearLatchedNode(wheelEvent, scrollingNodeID()); return ScrollingEventResult::DidHandleEvent; } +void ScrollingTreeOverflowScrollingNodeNicosia::stopScrollAnimations() +{ +#if ENABLE(KINETIC_SCROLLING) + m_kineticAnimation->stop(); + m_kineticAnimation->clearScrollHistory(); +#endif +} + } // namespace WebCore #endif // ENABLE(ASYNC_SCROLLING) && USE(NICOSIA) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.h b/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.h index a1f9c812e68..e6f461a9f6e 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.h @@ -33,6 +33,7 @@ #include "ScrollingTreeOverflowScrollingNode.h" namespace WebCore { +class ScrollAnimationKinetic; class ScrollingTreeOverflowScrollingNodeNicosia final : public ScrollingTreeOverflowScrollingNode { public: @@ -49,6 +50,12 @@ class ScrollingTreeOverflowScrollingNodeNicosia final : public ScrollingTreeOver void repositionScrollingLayers() override; ScrollingEventResult handleWheelEvent(const PlatformWheelEvent&) override; + + void stopScrollAnimations() override; + +#if ENABLE(KINETIC_SCROLLING) + std::unique_ptr m_kineticAnimation; +#endif }; } // namespace WebCore diff --git a/modules/javafx.web/src/main/native/Source/WebCore/platform/MIMETypeRegistry.cpp b/modules/javafx.web/src/main/native/Source/WebCore/platform/MIMETypeRegistry.cpp index aacfb74b8b2..3d492af30ef 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/platform/MIMETypeRegistry.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/MIMETypeRegistry.cpp @@ -639,6 +639,12 @@ bool MIMETypeRegistry::isXMLMIMEType(const String& mimeType) return true; } +bool MIMETypeRegistry::isXMLEntityMIMEType(StringView mimeType) +{ + return equalLettersIgnoringASCIICase(mimeType, "text/xml-external-parsed-entity") + || equalLettersIgnoringASCIICase(mimeType, "application/xml-external-parsed-entity"); +} + bool MIMETypeRegistry::isJavaAppletMIMEType(const String& mimeType) { // Since this set is very limited and is likely to remain so we won't bother with the overhead diff --git a/modules/javafx.web/src/main/native/Source/WebCore/platform/MIMETypeRegistry.h b/modules/javafx.web/src/main/native/Source/WebCore/platform/MIMETypeRegistry.h index c9c40ba3a6f..af626bd7f68 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/platform/MIMETypeRegistry.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/MIMETypeRegistry.h @@ -126,6 +126,9 @@ class MIMETypeRegistry { // rather than an HTML document. WEBCORE_EXPORT static bool isXMLMIMEType(const String& mimeType); + // Check to see if a MIME type is for an XML external entity resource. + WEBCORE_EXPORT static bool isXMLEntityMIMEType(StringView mimeType); + // Used in page load algorithm to decide whether to display as a text // document in a frame. Not a good idea to use elsewhere, because that code // makes this test is after many other tests are done on the MIME type. diff --git a/modules/javafx.web/src/main/native/Source/WebCore/platform/ScrollAnimationKinetic.cpp b/modules/javafx.web/src/main/native/Source/WebCore/platform/ScrollAnimationKinetic.cpp index ac9f2f0f37f..3ce55a1851e 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/platform/ScrollAnimationKinetic.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/ScrollAnimationKinetic.cpp @@ -26,7 +26,11 @@ #include "config.h" #include "ScrollAnimationKinetic.h" -#include "ScrollableArea.h" +#include "PlatformWheelEvent.h" + +#if USE(GLIB) +#include +#endif /* * PerAxisData is a port of GtkKineticScrolling as of GTK+ 3.20, @@ -65,6 +69,7 @@ static const double decelFriction = 4; static const double frameRate = 60; static const Seconds tickTime = 1_s / frameRate; static const Seconds minimumTimerInterval { 1_ms }; +static const Seconds scrollCaptureThreshold { 150_ms }; namespace WebCore { @@ -104,11 +109,14 @@ bool ScrollAnimationKinetic::PerAxisData::animateScroll(Seconds timeDelta) return m_velocity; } -ScrollAnimationKinetic::ScrollAnimationKinetic(ScrollableArea& scrollableArea, std::function&& notifyPositionChangedFunction) - : ScrollAnimation(scrollableArea) +ScrollAnimationKinetic::ScrollAnimationKinetic(ScrollExtentsCallback&& scrollExtentsFunction, NotifyPositionChangedCallback&& notifyPositionChangedFunction) + : m_scrollExtentsFunction(WTFMove(scrollExtentsFunction)) , m_notifyPositionChangedFunction(WTFMove(notifyPositionChangedFunction)) - , m_animationTimer(*this, &ScrollAnimationKinetic::animationTimerFired) + , m_animationTimer(RunLoop::current(), this, &ScrollAnimationKinetic::animationTimerFired) { +#if USE(GLIB) + m_animationTimer.setPriority(WTF::RunLoopSourcePriority::DisplayRefreshMonitorTimer); +#endif } ScrollAnimationKinetic::~ScrollAnimationKinetic() = default; @@ -120,6 +128,40 @@ void ScrollAnimationKinetic::stop() m_verticalData = WTF::nullopt; } +void ScrollAnimationKinetic::appendToScrollHistory(const PlatformWheelEvent& event) +{ + m_scrollHistory.removeAllMatching([&event] (PlatformWheelEvent& otherEvent) -> bool { + return (event.timestamp() - otherEvent.timestamp()) > scrollCaptureThreshold; + }); + + m_scrollHistory.append(event); +} + +void ScrollAnimationKinetic::clearScrollHistory() +{ + m_scrollHistory.clear(); +} + +FloatPoint ScrollAnimationKinetic::computeVelocity() +{ + if (m_scrollHistory.isEmpty()) + return { }; + + auto first = m_scrollHistory[0].timestamp(); + auto last = m_scrollHistory.rbegin()->timestamp(); + + if (last == first) + return { }; + + FloatPoint accumDelta; + for (const auto& scrollEvent : m_scrollHistory) + accumDelta += FloatPoint(scrollEvent.deltaX(), scrollEvent.deltaY()); + + m_scrollHistory.clear(); + + return FloatPoint(accumDelta.x() * -1 / (last - first).value(), accumDelta.y() * -1 / (last - first).value()); +} + void ScrollAnimationKinetic::start(const FloatPoint& initialPosition, const FloatPoint& velocity, bool mayHScroll, bool mayVScroll) { stop(); @@ -129,14 +171,15 @@ void ScrollAnimationKinetic::start(const FloatPoint& initialPosition, const Floa if (!velocity.x() && !velocity.y()) return; + auto extents = m_scrollExtentsFunction(); if (mayHScroll) { - m_horizontalData = PerAxisData(m_scrollableArea.minimumScrollPosition().x(), - m_scrollableArea.maximumScrollPosition().x(), + m_horizontalData = PerAxisData(extents.minimumScrollPosition.x(), + extents.maximumScrollPosition.x(), initialPosition.x(), velocity.x()); } if (mayVScroll) { - m_verticalData = PerAxisData(m_scrollableArea.minimumScrollPosition().y(), - m_scrollableArea.maximumScrollPosition().y(), + m_verticalData = PerAxisData(extents.minimumScrollPosition.y(), + extents.maximumScrollPosition.y(), initialPosition.y(), velocity.y()); } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/platform/ScrollAnimationKinetic.h b/modules/javafx.web/src/main/native/Source/WebCore/platform/ScrollAnimationKinetic.h index cfd33ce5b49..cf25e798cd5 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/platform/ScrollAnimationKinetic.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/ScrollAnimationKinetic.h @@ -27,15 +27,16 @@ #include "FloatPoint.h" #include "ScrollAnimation.h" -#include "Timer.h" #include +#include namespace WebCore { -class ScrollableArea; +class PlatformWheelEvent; -class ScrollAnimationKinetic final: public ScrollAnimation { +class ScrollAnimationKinetic final { + WTF_MAKE_FAST_ALLOCATED; private: class PerAxisData { public: @@ -58,23 +59,37 @@ class ScrollAnimationKinetic final: public ScrollAnimation { }; public: - ScrollAnimationKinetic(ScrollableArea&, std::function&& notifyPositionChangedFunction); + struct ScrollExtents { + IntPoint minimumScrollPosition; + IntPoint maximumScrollPosition; + }; + + using ScrollExtentsCallback = WTF::Function; + using NotifyPositionChangedCallback = WTF::Function; + + ScrollAnimationKinetic(ScrollExtentsCallback&&, NotifyPositionChangedCallback&&); virtual ~ScrollAnimationKinetic(); + void appendToScrollHistory(const PlatformWheelEvent&); + void clearScrollHistory(); + FloatPoint computeVelocity(); + void start(const FloatPoint& initialPosition, const FloatPoint& velocity, bool mayHScroll, bool mayVScroll); + void stop(); private: - void stop() override; void animationTimerFired(); - std::function m_notifyPositionChangedFunction; + ScrollExtentsCallback m_scrollExtentsFunction; + NotifyPositionChangedCallback m_notifyPositionChangedFunction; Optional m_horizontalData; Optional m_verticalData; MonotonicTime m_startTime; - Timer m_animationTimer; + RunLoop::Timer m_animationTimer; FloatPoint m_position; + Vector m_scrollHistory; }; } // namespace WebCore diff --git a/modules/javafx.web/src/main/native/Source/WebCore/platform/generic/ScrollAnimatorGeneric.cpp b/modules/javafx.web/src/main/native/Source/WebCore/platform/generic/ScrollAnimatorGeneric.cpp index 208af7b8479..6a3350e3d16 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/platform/generic/ScrollAnimatorGeneric.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/generic/ScrollAnimatorGeneric.cpp @@ -40,7 +40,6 @@ namespace WebCore { static const Seconds overflowScrollbarsAnimationDuration { 1_s }; static const Seconds overflowScrollbarsAnimationHideDelay { 2_s }; -static const Seconds scrollCaptureThreshold { 150_ms }; std::unique_ptr ScrollAnimator::create(ScrollableArea& scrollableArea) { @@ -51,13 +50,17 @@ ScrollAnimatorGeneric::ScrollAnimatorGeneric(ScrollableArea& scrollableArea) : ScrollAnimator(scrollableArea) , m_overlayScrollbarAnimationTimer(*this, &ScrollAnimatorGeneric::overlayScrollbarAnimationTimerFired) { - m_kineticAnimation = makeUnique(m_scrollableArea, [this](FloatPoint&& position) { + m_kineticAnimation = makeUnique( + [this]() -> ScrollAnimationKinetic::ScrollExtents { + return { m_scrollableArea.minimumScrollPosition(), m_scrollableArea.maximumScrollPosition() }; + }, + [this](FloatPoint&& position) { #if ENABLE(SMOOTH_SCROLLING) - if (m_smoothAnimation) - m_smoothAnimation->setCurrentPosition(position); + if (m_smoothAnimation) + m_smoothAnimation->setCurrentPosition(position); #endif - updatePosition(WTFMove(position)); - }); + updatePosition(WTFMove(position)); + }); #if ENABLE(SMOOTH_SCROLLING) if (scrollableArea.scrollAnimatorEnabled()) @@ -94,7 +97,7 @@ void ScrollAnimatorGeneric::scrollToOffsetWithoutAnimation(const FloatPoint& off { FloatPoint position = ScrollableArea::scrollPositionFromOffset(offset, toFloatSize(m_scrollableArea.scrollOrigin())); m_kineticAnimation->stop(); - m_scrollHistory.clear(); + m_kineticAnimation->clearScrollHistory(); #if ENABLE(SMOOTH_SCROLLING) if (m_smoothAnimation) @@ -104,56 +107,29 @@ void ScrollAnimatorGeneric::scrollToOffsetWithoutAnimation(const FloatPoint& off updatePosition(WTFMove(position)); } -FloatPoint ScrollAnimatorGeneric::computeVelocity() -{ - if (m_scrollHistory.isEmpty()) - return { }; - - auto first = m_scrollHistory[0].timestamp(); - auto last = m_scrollHistory.rbegin()->timestamp(); - - if (last == first) - return { }; - - FloatPoint accumDelta; - for (const auto& scrollEvent : m_scrollHistory) - accumDelta += FloatPoint(scrollEvent.deltaX(), scrollEvent.deltaY()); - - m_scrollHistory.clear(); - - return FloatPoint(accumDelta.x() * -1 / (last - first).value(), accumDelta.y() * -1 / (last - first).value()); -} - bool ScrollAnimatorGeneric::handleWheelEvent(const PlatformWheelEvent& event) { m_kineticAnimation->stop(); - m_scrollHistory.removeAllMatching([&event] (PlatformWheelEvent& otherEvent) -> bool { - return (event.timestamp() - otherEvent.timestamp()) > scrollCaptureThreshold; - }); - #if ENABLE(KINETIC_SCROLLING) + m_kineticAnimation->appendToScrollHistory(event); + if (event.isEndOfNonMomentumScroll()) { - // We don't need to add the event to the history as its delta will be (0, 0). - static_cast(m_kineticAnimation.get())->start(m_currentPosition, computeVelocity(), m_scrollableArea.horizontalScrollbar(), m_scrollableArea.verticalScrollbar()); + m_kineticAnimation->start(m_currentPosition, m_kineticAnimation->computeVelocity(), m_scrollableArea.horizontalScrollbar(), m_scrollableArea.verticalScrollbar()); return true; } if (event.isTransitioningToMomentumScroll()) { - m_scrollHistory.clear(); - static_cast(m_kineticAnimation.get())->start(m_currentPosition, event.swipeVelocity(), m_scrollableArea.horizontalScrollbar(), m_scrollableArea.verticalScrollbar()); + m_kineticAnimation->clearScrollHistory(); + m_kineticAnimation->start(m_currentPosition, event.swipeVelocity(), m_scrollableArea.horizontalScrollbar(), m_scrollableArea.verticalScrollbar()); return true; } #endif - m_scrollHistory.append(event); - return ScrollAnimator::handleWheelEvent(event); } void ScrollAnimatorGeneric::willEndLiveResize() { - m_kineticAnimation->updateVisibleLengths(); - #if ENABLE(SMOOTH_SCROLLING) if (m_smoothAnimation) m_smoothAnimation->updateVisibleLengths(); @@ -169,8 +145,6 @@ void ScrollAnimatorGeneric::updatePosition(FloatPoint&& position) void ScrollAnimatorGeneric::didAddVerticalScrollbar(Scrollbar* scrollbar) { - m_kineticAnimation->updateVisibleLengths(); - #if ENABLE(SMOOTH_SCROLLING) if (m_smoothAnimation) m_smoothAnimation->updateVisibleLengths(); @@ -186,8 +160,6 @@ void ScrollAnimatorGeneric::didAddVerticalScrollbar(Scrollbar* scrollbar) void ScrollAnimatorGeneric::didAddHorizontalScrollbar(Scrollbar* scrollbar) { - m_kineticAnimation->updateVisibleLengths(); - #if ENABLE(SMOOTH_SCROLLING) if (m_smoothAnimation) m_smoothAnimation->updateVisibleLengths(); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/platform/generic/ScrollAnimatorGeneric.h b/modules/javafx.web/src/main/native/Source/WebCore/platform/generic/ScrollAnimatorGeneric.h index f9fca86f375..6a895389d24 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/platform/generic/ScrollAnimatorGeneric.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/generic/ScrollAnimatorGeneric.h @@ -36,6 +36,7 @@ namespace WebCore { class ScrollAnimation; +class ScrollAnimationKinetic; class ScrollAnimatorGeneric final : public ScrollAnimator { public: @@ -71,15 +72,12 @@ class ScrollAnimatorGeneric final : public ScrollAnimator { void hideOverlayScrollbars(); void updateOverlayScrollbarsOpacity(); - FloatPoint computeVelocity(); - #if ENABLE(SMOOTH_SCROLLING) void ensureSmoothScrollingAnimation(); std::unique_ptr m_smoothAnimation; #endif - std::unique_ptr m_kineticAnimation; - Vector m_scrollHistory; + std::unique_ptr m_kineticAnimation; Scrollbar* m_horizontalOverlayScrollbar { nullptr }; Scrollbar* m_verticalOverlayScrollbar { nullptr }; bool m_overlayScrollbarsLocked { false }; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/PlatformDisplay.cpp b/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/PlatformDisplay.cpp index 156e5aa2b73..62bc146f136 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/PlatformDisplay.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/PlatformDisplay.cpp @@ -90,12 +90,6 @@ std::unique_ptr PlatformDisplay::createPlatformDisplay() } #endif // PLATFORM(GTK) -#if USE(WPE_RENDERER) - return PlatformDisplayLibWPE::create(); -#elif PLATFORM(WIN) - return PlatformDisplayWin::create(); -#endif - #if PLATFORM(WAYLAND) if (auto platformDisplay = PlatformDisplayWayland::create()) return platformDisplay; @@ -113,6 +107,12 @@ std::unique_ptr PlatformDisplay::createPlatformDisplay() return PlatformDisplayX11::create(nullptr); #endif +#if USE(WPE_RENDERER) + return PlatformDisplayLibWPE::create(); +#elif PLATFORM(WIN) + return PlatformDisplayWin::create(); +#endif + RELEASE_ASSERT_NOT_REACHED(); } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/PlatformMediaResourceLoader.h b/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/PlatformMediaResourceLoader.h index a145f163c64..2963652a338 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/PlatformMediaResourceLoader.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/PlatformMediaResourceLoader.h @@ -54,7 +54,7 @@ class PlatformMediaResourceClient { virtual void loadFinished(PlatformMediaResource&) { } }; -class PlatformMediaResourceLoader : public ThreadSafeRefCounted { +class PlatformMediaResourceLoader : public ThreadSafeRefCounted { WTF_MAKE_NONCOPYABLE(PlatformMediaResourceLoader); WTF_MAKE_FAST_ALLOCATED; public: enum LoadOption { @@ -71,7 +71,7 @@ class PlatformMediaResourceLoader : public ThreadSafeRefCounted { +class PlatformMediaResource : public ThreadSafeRefCounted { WTF_MAKE_NONCOPYABLE(PlatformMediaResource); WTF_MAKE_FAST_ALLOCATED; public: PlatformMediaResource() = default; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderBlock.cpp b/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderBlock.cpp index c0229ce9f28..d37299f9101 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderBlock.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderBlock.cpp @@ -37,6 +37,7 @@ #include "HTMLNames.h" #include "HitTestLocation.h" #include "HitTestResult.h" +#include "ImageBuffer.h" #include "InlineElementBox.h" #include "InlineIterator.h" #include "InlineTextBox.h" diff --git a/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderLayer.cpp b/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderLayer.cpp index c4098034291..a0c6f188f5a 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderLayer.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderLayer.cpp @@ -4414,7 +4414,7 @@ Path RenderLayer::computeClipPath(const LayoutSize& offsetFromRoot, LayoutRect& bool RenderLayer::setupClipPath(GraphicsContext& context, const LayerPaintingInfo& paintingInfo, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed) { - if (!renderer().hasClipPath() || context.paintingDisabled()) + if (!renderer().hasClipPath() || context.paintingDisabled() || paintingInfo.paintDirtyRect.isEmpty()) return false; if (!rootRelativeBoundsComputed) { @@ -4442,13 +4442,12 @@ bool RenderLayer::setupClipPath(GraphicsContext& context, const LayerPaintingInf Element* element = renderer().document().getElementById(referenceClipPathOperation->fragment()); if (element && element->renderer() && is(element->renderer())) { context.save(); - float deviceSaleFactor = renderer().document().deviceScaleFactor(); - FloatRect referenceBox = snapRectToDevicePixels(computeReferenceBox(renderer(), CSSBoxType::ContentBox, paintingOffsetFromRoot, rootRelativeBounds), deviceSaleFactor); - FloatPoint offset {referenceBox.location()}; + auto referenceBox = snapRectToDevicePixels(rootRelativeBounds, renderer().document().deviceScaleFactor()); + auto offset = referenceBox.location(); context.translate(offset); - FloatRect svgReferenceBox {FloatPoint(), referenceBox.size()}; - downcast(*element->renderer()).applyClippingToContext(renderer(), svgReferenceBox, paintingInfo.paintDirtyRect, context); - context.translate(FloatPoint(-offset.x(), -offset.y())); + FloatRect svgReferenceBox { {}, referenceBox.size() }; + downcast(*element->renderer()).applyClippingToContext(renderer(), svgReferenceBox, context); + context.translate(-offset); return true; } } @@ -6911,16 +6910,6 @@ void RenderLayer::updateFilterPaintingStrategy() m_filters->buildFilter(renderer(), page().deviceScaleFactor(), renderer().settings().acceleratedFiltersEnabled() ? RenderingMode::Accelerated : RenderingMode::Unaccelerated); } -void RenderLayer::filterNeedsRepaint() -{ - // We use the enclosing element so that we recalculate style for the ancestor of an anonymous object. - if (Element* element = enclosingElement()) { - // FIXME: This really shouldn't have to invalidate layer composition, but tests like css3/filters/effect-reference-delete.html fail if that doesn't happen. - element->invalidateStyleAndLayerComposition(); - } - renderer().repaint(); -} - IntOutsets RenderLayer::filterOutsets() const { if (m_filters) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderLayer.h b/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderLayer.h index 5ee7322d50a..083bbd1e64b 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderLayer.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderLayer.h @@ -796,7 +796,6 @@ class RenderLayer final : public ScrollableArea { bool has3DTransform() const { return m_transform && !m_transform->isAffine(); } bool hasTransformedAncestor() const { return m_hasTransformedAncestor; } - void filterNeedsRepaint(); bool hasFilter() const { return renderer().hasFilter(); } bool hasFilterOutsets() const { return !filterOutsets().isZero(); } IntOutsets filterOutsets() const; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderLayerFilters.cpp b/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderLayerFilters.cpp index 4c8101ff959..4d0a27d6122 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderLayerFilters.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderLayerFilters.cpp @@ -67,7 +67,11 @@ bool RenderLayerFilters::hasFilterThatShouldBeRestrictedBySecurityOrigin() const void RenderLayerFilters::notifyFinished(CachedResource&) { - m_layer.filterNeedsRepaint(); + // FIXME: This really shouldn't have to invalidate layer composition, + // but tests like css3/filters/effect-reference-delete.html fail if that doesn't happen. + if (auto* enclosingElement = m_layer.enclosingElement()) + enclosingElement->invalidateStyleAndLayerComposition(); + m_layer.renderer().repaint(); } void RenderLayerFilters::updateReferenceFilterClients(const FilterOperations& operations) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp b/modules/javafx.web/src/main/native/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp index 5ad580726fc..6ffc8ff1d42 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp @@ -30,6 +30,7 @@ #include "HitTestResult.h" #include "IntRect.h" #include "RenderObject.h" +#include "Logging.h" #include "RenderStyle.h" #include "RenderView.h" #include "SVGNames.h" @@ -38,6 +39,7 @@ #include "SVGResourcesCache.h" #include "SVGUseElement.h" #include +#include namespace WebCore { @@ -52,7 +54,7 @@ RenderSVGResourceClipper::~RenderSVGResourceClipper() = default; void RenderSVGResourceClipper::removeAllClientsFromCache(bool markForInvalidation) { - m_clipBoundaries = FloatRect(); + m_clipBoundaries = { }; m_clipper.clear(); markAllClientsForInvalidation(markForInvalidation ? LayoutAndBoundariesInvalidation : ParentOnlyInvalidation); @@ -70,7 +72,11 @@ bool RenderSVGResourceClipper::applyResource(RenderElement& renderer, const Rend ASSERT(context); ASSERT_UNUSED(resourceMode, !resourceMode); - return applyClippingToContext(renderer, renderer.objectBoundingBox(), renderer.repaintRectInLocalCoordinates(), *context); + auto repaintRect = renderer.repaintRectInLocalCoordinates(); + if (repaintRect.isEmpty()) + return true; + + return applyClippingToContext(renderer, renderer.objectBoundingBox(), *context); } bool RenderSVGResourceClipper::pathOnlyClipping(GraphicsContext& context, const AffineTransform& animatedLocalTransform, const FloatRect& objectBoundingBox) @@ -128,25 +134,27 @@ bool RenderSVGResourceClipper::pathOnlyClipping(GraphicsContext& context, const return true; } -bool RenderSVGResourceClipper::applyClippingToContext(RenderElement& renderer, const FloatRect& objectBoundingBox, const FloatRect& repaintRect, GraphicsContext& context) +bool RenderSVGResourceClipper::applyClippingToContext(RenderElement& renderer, const FloatRect& objectBoundingBox, GraphicsContext& context) { - ClipperMaskImage& clipperMaskImage = addRendererToClipper(renderer); - bool shouldCreateClipperMaskImage = !clipperMaskImage; + ClipperData& clipperData = addRendererToClipper(renderer); + + LOG_WITH_STREAM(SVG, stream << "RenderSVGResourceClipper " << this << " applyClippingToContext: renderer " << &renderer << " objectBoundingBox " << objectBoundingBox << " (existing image buffer " << clipperData.imageBuffer.get() << ")"); AffineTransform animatedLocalTransform = clipPathElement().animatedLocalTransform(); - if (shouldCreateClipperMaskImage && pathOnlyClipping(context, animatedLocalTransform, objectBoundingBox)) + if (!clipperData.imageBuffer && pathOnlyClipping(context, animatedLocalTransform, objectBoundingBox)) return true; AffineTransform absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer); - - if (shouldCreateClipperMaskImage && !repaintRect.isEmpty()) { + if (!clipperData.isValidForGeometry(objectBoundingBox, absoluteTransform)) { // FIXME (149469): This image buffer should not be unconditionally unaccelerated. Making it match the context breaks nested clipping, though. - clipperMaskImage = SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, ColorSpace::SRGB, RenderingMode::Unaccelerated, &context); - if (!clipperMaskImage) + auto maskImage = SVGRenderingContext::createImageBuffer(objectBoundingBox, absoluteTransform, ColorSpace::SRGB, RenderingMode::Unaccelerated, &context); + if (!maskImage) return false; - GraphicsContext& maskContext = clipperMaskImage->context(); + clipperData = { WTFMove(maskImage), objectBoundingBox, absoluteTransform }; + + GraphicsContext& maskContext = clipperData.imageBuffer->context(); maskContext.concatCTM(animatedLocalTransform); // clipPath can also be clipped by another clipPath. @@ -156,30 +164,28 @@ bool RenderSVGResourceClipper::applyClippingToContext(RenderElement& renderer, c if (resources && (clipper = resources->clipper())) { GraphicsContextStateSaver stateSaver(maskContext); - if (!clipper->applyClippingToContext(*this, objectBoundingBox, repaintRect, maskContext)) + if (!clipper->applyClippingToContext(*this, objectBoundingBox, maskContext)) return false; - succeeded = drawContentIntoMaskImage(clipperMaskImage, objectBoundingBox); + succeeded = drawContentIntoMaskImage(*clipperData.imageBuffer, objectBoundingBox); // The context restore applies the clipping on non-CG platforms. } else - succeeded = drawContentIntoMaskImage(clipperMaskImage, objectBoundingBox); + succeeded = drawContentIntoMaskImage(*clipperData.imageBuffer, objectBoundingBox); if (!succeeded) - clipperMaskImage.reset(); + clipperData = { }; } - if (!clipperMaskImage) + if (!clipperData.imageBuffer) return false; - SVGRenderingContext::clipToImageBuffer(context, absoluteTransform, repaintRect, clipperMaskImage, shouldCreateClipperMaskImage); + SVGRenderingContext::clipToImageBuffer(context, absoluteTransform, objectBoundingBox, clipperData.imageBuffer, true); return true; } -bool RenderSVGResourceClipper::drawContentIntoMaskImage(const ClipperMaskImage& clipperMaskImage, const FloatRect& objectBoundingBox) +bool RenderSVGResourceClipper::drawContentIntoMaskImage(ImageBuffer& maskImageBuffer, const FloatRect& objectBoundingBox) { - ASSERT(clipperMaskImage); - - GraphicsContext& maskContext = clipperMaskImage->context(); + GraphicsContext& maskContext = maskImageBuffer.context(); AffineTransform maskContentTransformation; if (clipPathElement().clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { @@ -229,7 +235,7 @@ bool RenderSVGResourceClipper::drawContentIntoMaskImage(const ClipperMaskImage& // In the case of a element, we obtained its renderere above, to retrieve its clipRule. // We have to pass the renderer itself to renderSubtreeToImageBuffer() to apply it's x/y/transform/etc. values when rendering. // So if isUseElement is true, refetch the childNode->renderer(), as renderer got overridden above. - SVGRenderingContext::renderSubtreeToImageBuffer(clipperMaskImage.get(), isUseElement ? *child.renderer() : *renderer, maskContentTransformation); + SVGRenderingContext::renderSubtreeToImageBuffer(&maskImageBuffer, isUseElement ? *child.renderer() : *renderer, maskContentTransformation); } view().frameView().setPaintBehavior(oldBehavior); @@ -253,9 +259,9 @@ void RenderSVGResourceClipper::calculateClipContentRepaintRect() m_clipBoundaries = clipPathElement().animatedLocalTransform().mapRect(m_clipBoundaries); } -ClipperMaskImage& RenderSVGResourceClipper::addRendererToClipper(const RenderObject& object) +RenderSVGResourceClipper::ClipperData& RenderSVGResourceClipper::addRendererToClipper(const RenderObject& object) { - return m_clipper.add(&object, ClipperMaskImage()).iterator->value; + return m_clipper.add(&object, ClipperData()).iterator->value; } bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundingBox, const FloatPoint& nodeAtPoint) @@ -302,7 +308,7 @@ FloatRect RenderSVGResourceClipper::resourceBoundingBox(const RenderObject& obje { // Resource was not layouted yet. Give back the boundingBox of the object. if (selfNeedsLayout()) { - addRendererToClipper(object); + addRendererToClipper(object); // For selfNeedsClientInvalidation(). return object.objectBoundingBox(); } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h b/modules/javafx.web/src/main/native/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h index 57b73f4096b..79a55808146 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h @@ -30,8 +30,6 @@ namespace WebCore { class GraphicsContext; class ImageBuffer; -typedef std::unique_ptr ClipperMaskImage; - class RenderSVGResourceClipper final : public RenderSVGResourceContainer { WTF_MAKE_ISO_ALLOCATED(RenderSVGResourceClipper); public: @@ -47,7 +45,7 @@ class RenderSVGResourceClipper final : public RenderSVGResourceContainer { // clipPath can be clipped too, but don't have a boundingBox or repaintRect. So we can't call // applyResource directly and use the rects from the object, since they are empty for RenderSVGResources // FIXME: We made applyClippingToContext public because we cannot call applyResource on HTML elements (it asserts on RenderObject::objectBoundingBox) - bool applyClippingToContext(RenderElement&, const FloatRect&, const FloatRect&, GraphicsContext&); + bool applyClippingToContext(RenderElement&, const FloatRect&, GraphicsContext&); FloatRect resourceBoundingBox(const RenderObject&) override; RenderSVGResourceType resourceType() const override { return ClipperResourceType; } @@ -60,18 +58,37 @@ class RenderSVGResourceClipper final : public RenderSVGResourceContainer { bool selfNeedsClientInvalidation() const override { return (everHadLayout() || m_clipper.size()) && selfNeedsLayout(); } private: + struct ClipperData { + FloatRect objectBoundingBox; + AffineTransform absoluteTransform; + std::unique_ptr imageBuffer; + + ClipperData() = default; + ClipperData(std::unique_ptr&& buffer, const FloatRect& boundingBox, const AffineTransform& transform) + : objectBoundingBox(boundingBox) + , absoluteTransform(transform) + , imageBuffer(WTFMove(buffer)) + { + } + + bool isValidForGeometry(const FloatRect& boundingBox, const AffineTransform& transform) const + { + return imageBuffer && objectBoundingBox == boundingBox && absoluteTransform == transform; + } + }; + void element() const = delete; const char* renderName() const override { return "RenderSVGResourceClipper"; } bool isSVGResourceClipper() const override { return true; } bool pathOnlyClipping(GraphicsContext&, const AffineTransform&, const FloatRect&); - bool drawContentIntoMaskImage(const ClipperMaskImage&, const FloatRect& objectBoundingBox); + bool drawContentIntoMaskImage(ImageBuffer&, const FloatRect& objectBoundingBox); void calculateClipContentRepaintRect(); - ClipperMaskImage& addRendererToClipper(const RenderObject&); + ClipperData& addRendererToClipper(const RenderObject&); FloatRect m_clipBoundaries; - HashMap m_clipper; + HashMap m_clipper; }; } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp b/modules/javafx.web/src/main/native/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp index cddc375a780..39fa73fb11e 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp @@ -26,6 +26,7 @@ #include "SVGRenderingContext.h" #include "SVGResourcesCache.h" #include +#include #include namespace WebCore { @@ -91,10 +92,13 @@ void RenderSVGResourceContainer::idChanged() void RenderSVGResourceContainer::markAllClientsForInvalidation(InvalidationMode mode) { + // FIXME: Style invalidation should either be a pre-layout task or this function + // should never get called while in layout. See webkit.org/b/208903. if ((m_clients.isEmpty() && m_clientLayers.isEmpty()) || m_isInvalidating) return; - m_isInvalidating = true; + SetForScope isInvalidating(m_isInvalidating, true); + bool needsLayout = mode == LayoutAndBoundariesInvalidation; bool markForInvalidation = mode != ParentOnlyInvalidation; auto* root = SVGRenderSupport::findTreeRootObject(*this); @@ -116,18 +120,29 @@ void RenderSVGResourceContainer::markAllClientsForInvalidation(InvalidationMode } markAllClientLayersForInvalidation(); - - m_isInvalidating = false; } void RenderSVGResourceContainer::markAllClientLayersForInvalidation() { if (m_clientLayers.isEmpty()) return; - if ((*m_clientLayers.begin())->renderer().renderTreeBeingDestroyed()) + + auto& document = (*m_clientLayers.begin())->renderer().document(); + if (!document.view() || document.renderTreeBeingDestroyed()) return; - for (auto* clientLayer : m_clientLayers) - clientLayer->filterNeedsRepaint(); + + auto inLayout = document.view()->layoutContext().isInLayout(); + for (auto* clientLayer : m_clientLayers) { + // FIXME: We should not get here while in layout. See webkit.org/b/208903. + // Repaint should also be triggered through some other means. + if (inLayout) { + clientLayer->renderer().repaint(); + continue; + } + if (auto* enclosingElement = clientLayer->enclosingElement()) + enclosingElement->invalidateStyleAndLayerComposition(); + clientLayer->renderer().repaint(); + } } void RenderSVGResourceContainer::markClientForInvalidation(RenderObject& client, InvalidationMode mode) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/rendering/updating/RenderTreeBuilderFirstLetter.cpp b/modules/javafx.web/src/main/native/Source/WebCore/rendering/updating/RenderTreeBuilderFirstLetter.cpp index 3b16636c24f..e0e1806d0fb 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/rendering/updating/RenderTreeBuilderFirstLetter.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/rendering/updating/RenderTreeBuilderFirstLetter.cpp @@ -251,7 +251,7 @@ void RenderTreeBuilder::FirstLetter::createRenderers(RenderBlock& firstLetterBlo } auto* textNode = currentTextChild.textNode(); - auto* beforeChild = currentTextChild.nextSibling(); + auto beforeChild = makeWeakPtr(currentTextChild.nextSibling()); auto inlineWrapperForDisplayContents = makeWeakPtr(currentTextChild.inlineWrapperForDisplayContents()); auto hasInlineWrapperForDisplayContents = inlineWrapperForDisplayContents.get(); m_builder.destroy(currentTextChild); @@ -268,7 +268,7 @@ void RenderTreeBuilder::FirstLetter::createRenderers(RenderBlock& firstLetterBlo RenderTextFragment& remainingText = *newRemainingText; ASSERT_UNUSED(hasInlineWrapperForDisplayContents, hasInlineWrapperForDisplayContents == inlineWrapperForDisplayContents.get()); remainingText.setInlineWrapperForDisplayContents(inlineWrapperForDisplayContents.get()); - m_builder.attach(*textContentParent, WTFMove(newRemainingText), beforeChild); + m_builder.attach(*textContentParent, WTFMove(newRemainingText), beforeChild.get()); // FIXME: Make attach the final step so that we don't need to keep firstLetter around. auto& firstLetter = *newFirstLetter; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/svg/SVGClipPathElement.cpp b/modules/javafx.web/src/main/native/Source/WebCore/svg/SVGClipPathElement.cpp index 9a8dc8d18c3..a716143b80f 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/svg/SVGClipPathElement.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/svg/SVGClipPathElement.cpp @@ -24,6 +24,7 @@ #include "SVGClipPathElement.h" #include "Document.h" +#include "ImageBuffer.h" #include "RenderSVGResourceClipper.h" #include "SVGNames.h" #include "StyleResolver.h" diff --git a/modules/javafx.web/src/main/native/Source/WebCore/svg/SVGTransform.h b/modules/javafx.web/src/main/native/Source/WebCore/svg/SVGTransform.h index 38fdd783183..90cc2a574ae 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/svg/SVGTransform.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/svg/SVGTransform.h @@ -144,6 +144,20 @@ class SVGTransform : public SVGValueProperty, public SVGPrope return { }; } + void attach(SVGPropertyOwner* owner, SVGPropertyAccess access) override + { + Base::attach(owner, access); + // Reattach the SVGMatrix to the SVGTransformValue with the new SVGPropertyAccess. + m_value.matrix()->reattach(this, access); + } + + void detach() override + { + Base::detach(); + // Reattach the SVGMatrix to the SVGTransformValue with the SVGPropertyAccess::ReadWrite. + m_value.matrix()->reattach(this, access()); + } + private: using Base = SVGValueProperty; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/svg/properties/SVGProperty.h b/modules/javafx.web/src/main/native/Source/WebCore/svg/properties/SVGProperty.h index ce65cb110d1..4043ff44f20 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/svg/properties/SVGProperty.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/svg/properties/SVGProperty.h @@ -36,7 +36,7 @@ class SVGProperty : public RefCounted { // Managing the relationship with the owner. bool isAttached() const { return m_owner; } - void attach(SVGPropertyOwner* owner, SVGPropertyAccess access) + virtual void attach(SVGPropertyOwner* owner, SVGPropertyAccess access) { ASSERT(!m_owner); ASSERT(m_state == SVGPropertyState::Clean); @@ -44,13 +44,20 @@ class SVGProperty : public RefCounted { m_access = access; } - void detach() + virtual void detach() { m_owner = nullptr; m_access = SVGPropertyAccess::ReadWrite; m_state = SVGPropertyState::Clean; } + void reattach(SVGPropertyOwner* owner, SVGPropertyAccess access) + { + ASSERT_UNUSED(owner, owner == m_owner); + m_access = access; + m_state = SVGPropertyState::Clean; + } + const SVGElement* contextElement() const { if (!m_owner) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp b/modules/javafx.web/src/main/native/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp index 8c566096a36..3a80c6212cb 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp @@ -39,6 +39,7 @@ #include "ServiceWorker.h" #include "ServiceWorkerClientIdentifier.h" #include "ServiceWorkerGlobalScope.h" +#include "ServiceWorkerThread.h" #include "WorkerGlobalScope.h" namespace WebCore { diff --git a/modules/javafx.web/src/main/native/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp b/modules/javafx.web/src/main/native/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp index 204ae2c05b7..d17f8457a2c 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp @@ -39,7 +39,11 @@ #include "HTMLEntityParser.h" #include "HTMLHtmlElement.h" #include "HTMLTemplateElement.h" +#include "HTTPParsers.h" #include "InlineClassicScript.h" +#include "MIMETypeRegistry.h" +#include "Page.h" +#include "PageConsoleClient.h" #include "PendingScript.h" #include "ProcessingInstruction.h" #include "ResourceError.h" @@ -375,6 +379,19 @@ class OffsetBuffer { unsigned m_currentOffset; }; +static bool externalEntityMimeTypeAllowedByNosniff(const ResourceResponse& response) +{ + ContentTypeOptionsDisposition contentTypeOption = parseContentTypeOptionsHeader(response.httpHeaderField(HTTPHeaderName::XContentTypeOptions)); + if (contentTypeOption != ContentTypeOptionsNosniff) { + // Allow any MIME type without 'X-Content-Type-Options: nosniff' HTTP header. + return true; + } + String mimeType = extractMIMETypeFromMediaType(response.httpHeaderField(HTTPHeaderName::ContentType)); + if (MIMETypeRegistry::isXMLMIMEType(mimeType) || MIMETypeRegistry::isXMLEntityMIMEType(mimeType)) + return true; + return false; +} + static inline void setAttributes(Element* element, Vector& attributeVector, ParserContentPolicy parserContentPolicy) { if (!scriptingContentIsAllowed(parserContentPolicy)) @@ -455,6 +472,11 @@ static void* openFunc(const char* uri) options.mode = FetchOptions::Mode::SameOrigin; options.credentials = FetchOptions::Credentials::Include; cachedResourceLoader->frame()->loader().loadResourceSynchronously(url, ClientCredentialPolicy::MayAskClientForCredentials, options, { }, error, response, data); + if (!externalEntityMimeTypeAllowedByNosniff(response)) { + data = nullptr; + if (Page* page = cachedResourceLoader->document()->page()) + page->console().addMessage(MessageSource::Security, MessageLevel::Error, makeString("Did not parse external entity resource at '", url.stringCenterEllipsizedToLength(), "' because non XML External Entity MIME types are not allowed when 'X-Content-Type-Options: nosniff' is given.")); + } } }