summaryrefslogtreecommitdiff
path: root/Source/WebCore/dom/Document.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-09-14 16:29:47 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-09-14 16:29:47 +0200
commitd0424a769059c84ae20beb3c217812792ea6726b (patch)
tree6f94a5c3db8c52c6694ee56498542a6c35417350 /Source/WebCore/dom/Document.cpp
parent88a04ac016f57c2d78e714682445dff2e7db4ade (diff)
downloadqtwebkit-d0424a769059c84ae20beb3c217812792ea6726b.tar.gz
Imported WebKit commit 37c5e5041d39a14ea0d429a77ebd352e4bd26516 (http://svn.webkit.org/repository/webkit/trunk@128608)
New snapshot that enables WebKit2 build on Windows (still some bugs) and allows for WebKit to be built with qmake && make
Diffstat (limited to 'Source/WebCore/dom/Document.cpp')
-rw-r--r--Source/WebCore/dom/Document.cpp144
1 files changed, 141 insertions, 3 deletions
diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp
index 9780f246d..3ac5d9ec0 100644
--- a/Source/WebCore/dom/Document.cpp
+++ b/Source/WebCore/dom/Document.cpp
@@ -105,6 +105,8 @@
#include "ImageLoader.h"
#include "InspectorCounters.h"
#include "InspectorInstrumentation.h"
+#include "Language.h"
+#include "Localizer.h"
#include "Logging.h"
#include "MediaQueryList.h"
#include "MediaQueryMatcher.h"
@@ -131,6 +133,7 @@
#include "RenderTextControl.h"
#include "RenderView.h"
#include "RenderWidget.h"
+#include "RuntimeEnabledFeatures.h"
#include "SchemeRegistry.h"
#include "ScopedEventQueue.h"
#include "ScriptCallStack.h"
@@ -1384,7 +1387,7 @@ String Document::suggestedMIMEType() const
// * making it receive a rect as parameter, i.e. nodesFromRect(x, y, w, h);
// * making it receive the expading size of each direction separately,
// i.e. nodesFromRect(x, y, topSize, rightSize, bottomSize, leftSize);
-PassRefPtr<NodeList> Document::nodesFromRect(int centerX, int centerY, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding, HitTestRequest::HitTestRequestType hitType) const
+PassRefPtr<NodeList> Document::nodesFromRect(int centerX, int centerY, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, bool allowChildFrameContent) const
{
// FIXME: Share code between this, elementFromPoint and caretRangeFromPoint.
if (!renderer())
@@ -1399,11 +1402,19 @@ PassRefPtr<NodeList> Document::nodesFromRect(int centerX, int centerY, unsigned
float zoomFactor = frame->pageZoomFactor();
LayoutPoint point = roundedLayoutPoint(FloatPoint(centerX * zoomFactor + view()->scrollX(), centerY * zoomFactor + view()->scrollY()));
- HitTestRequest request(hitType);
+ int type = HitTestRequest::ReadOnly | HitTestRequest::Active;
// When ignoreClipping is false, this method returns null for coordinates outside of the viewport.
- if (!request.ignoreClipping() && !frameView->visibleContentRect().intersects(HitTestResult::rectForPoint(point, topPadding, rightPadding, bottomPadding, leftPadding)))
+ if (ignoreClipping)
+ type |= HitTestRequest::IgnoreClipping;
+ else if (!frameView->visibleContentRect().intersects(HitTestResult::rectForPoint(point, topPadding, rightPadding, bottomPadding, leftPadding)))
return 0;
+ if (allowShadowContent)
+ type |= HitTestRequest::AllowShadowContent;
+ if (allowChildFrameContent)
+ type |= HitTestRequest::AllowChildFrameContent;
+
+ HitTestRequest request(type);
// Passing a zero padding will trigger a rect hit test, however for the purposes of nodesFromRect,
// we special handle this case in order to return a valid NodeList.
@@ -6112,6 +6123,121 @@ void Document::setContextFeatures(PassRefPtr<ContextFeatures> features)
m_contextFeatures = features;
}
+static RenderObject* nearestCommonHoverAncestor(RenderObject* obj1, RenderObject* obj2)
+{
+ if (!obj1 || !obj2)
+ return 0;
+
+ for (RenderObject* currObj1 = obj1; currObj1; currObj1 = currObj1->hoverAncestor()) {
+ for (RenderObject* currObj2 = obj2; currObj2; currObj2 = currObj2->hoverAncestor()) {
+ if (currObj1 == currObj2)
+ return currObj1;
+ }
+ }
+
+ return 0;
+}
+
+void Document::updateHoverActiveState(const HitTestRequest& request, HitTestResult& result)
+{
+ // We don't update :hover/:active state when the result is marked as readOnly.
+ if (request.readOnly())
+ return;
+
+ Node* innerNodeInDocument = result.innerNode();
+ while (innerNodeInDocument && innerNodeInDocument->document() != this)
+ innerNodeInDocument = innerNodeInDocument->document()->ownerElement();
+
+ Node* oldActiveNode = activeNode();
+ if (oldActiveNode && !request.active()) {
+ // We are clearing the :active chain because the mouse has been released.
+ for (RenderObject* curr = oldActiveNode->renderer(); curr; curr = curr->parent()) {
+ if (curr->node() && !curr->isText()) {
+ curr->node()->setActive(false);
+ curr->node()->clearInActiveChain();
+ }
+ }
+ setActiveNode(0);
+ } else {
+ Node* newActiveNode = innerNodeInDocument;
+ if (!oldActiveNode && newActiveNode && request.active() && !request.touchMove()) {
+ // We are setting the :active chain and freezing it. If future moves happen, they
+ // will need to reference this chain.
+ for (RenderObject* curr = newActiveNode->renderer(); curr; curr = curr->parent()) {
+ if (curr->node() && !curr->isText())
+ curr->node()->setInActiveChain();
+ }
+ setActiveNode(newActiveNode);
+ }
+ }
+ // If the mouse has just been pressed, set :active on the chain. Those (and only those)
+ // nodes should remain :active until the mouse is released.
+ bool allowActiveChanges = !oldActiveNode && activeNode();
+
+ // If the mouse is down and if this is a mouse move event, we want to restrict changes in
+ // :hover/:active to only apply to elements that are in the :active chain that we froze
+ // at the time the mouse went down.
+ bool mustBeInActiveChain = request.active() && request.move();
+
+ RefPtr<Node> oldHoverNode = hoverNode();
+ // Clear the :hover chain when the touch gesture is over.
+ if (request.touchRelease()) {
+ if (oldHoverNode) {
+ for (RenderObject* curr = oldHoverNode->renderer(); curr; curr = curr->hoverAncestor()) {
+ if (curr->node() && !curr->isText())
+ curr->node()->setHovered(false);
+ }
+ setHoverNode(0);
+ }
+ // A touch release can not set new hover or active target.
+ return;
+ }
+
+ // Check to see if the hovered node has changed.
+ // If it hasn't, we do not need to do anything.
+ Node* newHoverNode = innerNodeInDocument;
+ while (newHoverNode && !newHoverNode->renderer())
+ newHoverNode = newHoverNode->parentOrHostNode();
+
+ // Update our current hover node.
+ setHoverNode(newHoverNode);
+
+ // We have two different objects. Fetch their renderers.
+ RenderObject* oldHoverObj = oldHoverNode ? oldHoverNode->renderer() : 0;
+ RenderObject* newHoverObj = newHoverNode ? newHoverNode->renderer() : 0;
+
+ // Locate the common ancestor render object for the two renderers.
+ RenderObject* ancestor = nearestCommonHoverAncestor(oldHoverObj, newHoverObj);
+
+ Vector<RefPtr<Node>, 32> nodesToRemoveFromChain;
+ Vector<RefPtr<Node>, 32> nodesToAddToChain;
+
+ if (oldHoverObj != newHoverObj) {
+ // The old hover path only needs to be cleared up to (and not including) the common ancestor;
+ for (RenderObject* curr = oldHoverObj; curr && curr != ancestor; curr = curr->hoverAncestor()) {
+ if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr->node()->inActiveChain()))
+ nodesToRemoveFromChain.append(curr->node());
+ }
+ }
+
+ // Now set the hover state for our new object up to the root.
+ for (RenderObject* curr = newHoverObj; curr; curr = curr->hoverAncestor()) {
+ if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr->node()->inActiveChain()))
+ nodesToAddToChain.append(curr->node());
+ }
+
+ size_t removeCount = nodesToRemoveFromChain.size();
+ for (size_t i = 0; i < removeCount; ++i)
+ nodesToRemoveFromChain[i]->setHovered(false);
+
+ size_t addCount = nodesToAddToChain.size();
+ for (size_t i = 0; i < addCount; ++i) {
+ if (allowActiveChanges)
+ nodesToAddToChain[i]->setActive(true);
+ nodesToAddToChain[i]->setHovered(true);
+ }
+}
+
void Document::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
@@ -6170,6 +6296,7 @@ PassRefPtr<UndoManager> Document::undoManager()
#endif
class ImmutableAttributeDataCacheKey {
+ WTF_MAKE_FAST_ALLOCATED;
public:
ImmutableAttributeDataCacheKey()
: m_localName(0)
@@ -6238,4 +6365,15 @@ PassRefPtr<ElementAttributeData> Document::cachedImmutableAttributeData(const El
return attributeData.release();
}
+Localizer& Document::getLocalizer(const AtomicString& locale)
+{
+ AtomicString localeKey = locale;
+ if (locale.isEmpty() || !RuntimeEnabledFeatures::langAttributeAwareFormControlUIEnabled())
+ localeKey = defaultLanguage();
+ LocaleToLocalizerMap::AddResult result = m_localizerCache.add(localeKey, nullptr);
+ if (result.isNewEntry)
+ result.iterator->second = Localizer::create(localeKey);
+ return *(result.iterator->second);
+}
+
} // namespace WebCore