summaryrefslogtreecommitdiffstats
path: root/WebCore/page
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-05 14:34:32 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-05 14:34:32 -0800
commit635860845790a19bf50bbc51ba8fb66a96dde068 (patch)
treeef6ad9ff73a5b57f65249d4232a202fa77e6a140 /WebCore/page
parent8e35f3cfc7fba1d1c829dc557ebad6409cbe16a2 (diff)
downloadexternal_webkit-635860845790a19bf50bbc51ba8fb66a96dde068.zip
external_webkit-635860845790a19bf50bbc51ba8fb66a96dde068.tar.gz
external_webkit-635860845790a19bf50bbc51ba8fb66a96dde068.tar.bz2
auto import from //depot/cupcake/@136594
Diffstat (limited to 'WebCore/page')
-rw-r--r--WebCore/page/AccessibilityListBox.cpp14
-rw-r--r--WebCore/page/AccessibilityListBox.h2
-rw-r--r--WebCore/page/AccessibilityObject.cpp53
-rw-r--r--WebCore/page/AccessibilityObject.h10
-rw-r--r--WebCore/page/AccessibilityRenderObject.cpp142
-rw-r--r--WebCore/page/AccessibilityRenderObject.h9
-rw-r--r--WebCore/page/AccessibilityTable.cpp6
-rw-r--r--WebCore/page/AccessibilityTableCell.cpp39
-rw-r--r--WebCore/page/AccessibilityTableCell.h4
-rw-r--r--WebCore/page/Chrome.cpp63
-rw-r--r--WebCore/page/Chrome.h3
-rw-r--r--WebCore/page/ChromeClient.h6
-rw-r--r--WebCore/page/Console.cpp332
-rw-r--r--WebCore/page/Console.h52
-rw-r--r--WebCore/page/Console.idl36
-rw-r--r--WebCore/page/ContextMenuController.cpp19
-rw-r--r--WebCore/page/DOMTimer.cpp177
-rw-r--r--WebCore/page/DOMTimer.h68
-rw-r--r--WebCore/page/DOMWindow.cpp24
-rw-r--r--WebCore/page/DOMWindow.idl17
-rw-r--r--WebCore/page/DragController.cpp40
-rw-r--r--WebCore/page/DragController.h24
-rw-r--r--WebCore/page/EditorClient.h1
-rw-r--r--WebCore/page/EventHandler.cpp123
-rw-r--r--WebCore/page/EventHandler.h7
-rw-r--r--WebCore/page/Frame.cpp500
-rw-r--r--WebCore/page/Frame.h95
-rw-r--r--WebCore/page/FrameLoadRequest.h9
-rw-r--r--WebCore/page/FramePrivate.h99
-rw-r--r--WebCore/page/FrameTree.h3
-rw-r--r--WebCore/page/FrameView.cpp602
-rw-r--r--WebCore/page/FrameView.h80
-rw-r--r--WebCore/page/Geolocation.cpp6
-rw-r--r--WebCore/page/MouseEventWithHitTestResults.cpp16
-rw-r--r--WebCore/page/Navigator.cpp76
-rw-r--r--WebCore/page/Navigator.h14
-rw-r--r--WebCore/page/NavigatorBase.cpp115
-rw-r--r--WebCore/page/NavigatorBase.h54
-rw-r--r--WebCore/page/Page.cpp60
-rw-r--r--WebCore/page/Page.h37
-rw-r--r--WebCore/page/PageGroup.cpp24
-rw-r--r--WebCore/page/PageGroup.h8
-rw-r--r--WebCore/page/PositionError.h9
-rw-r--r--WebCore/page/PositionError.idl7
-rw-r--r--WebCore/page/SecurityOrigin.cpp10
-rw-r--r--WebCore/page/Settings.cpp28
-rw-r--r--WebCore/page/Settings.h24
-rw-r--r--WebCore/page/WorkerNavigator.cpp51
-rw-r--r--WebCore/page/WorkerNavigator.h56
-rw-r--r--WebCore/page/WorkerNavigator.idl43
-rw-r--r--WebCore/page/android/DragControllerAndroid.cpp4
-rw-r--r--WebCore/page/android/EventHandlerAndroid.cpp7
-rw-r--r--WebCore/page/android/InspectorControllerAndroid.cpp14
-rw-r--r--WebCore/page/animation/AnimationBase.cpp439
-rw-r--r--WebCore/page/animation/AnimationBase.h109
-rw-r--r--WebCore/page/animation/AnimationController.cpp328
-rw-r--r--WebCore/page/animation/AnimationController.h27
-rw-r--r--WebCore/page/animation/CompositeAnimation.cpp466
-rw-r--r--WebCore/page/animation/CompositeAnimation.h34
-rw-r--r--WebCore/page/animation/ImplicitAnimation.cpp31
-rw-r--r--WebCore/page/animation/ImplicitAnimation.h2
-rw-r--r--WebCore/page/animation/KeyframeAnimation.cpp19
-rw-r--r--WebCore/page/animation/KeyframeAnimation.h3
-rw-r--r--WebCore/page/chromium/AXObjectCacheChromium.cpp58
-rw-r--r--WebCore/page/chromium/AccessibilityObjectChromium.cpp (renamed from WebCore/page/PositionOptions.idl)16
-rw-r--r--WebCore/page/chromium/AccessibilityObjectWrapper.h50
-rw-r--r--WebCore/page/chromium/ChromeClientChromium.h52
-rw-r--r--WebCore/page/chromium/DragControllerChromium.cpp77
-rw-r--r--WebCore/page/chromium/EventHandlerChromium.cpp154
-rw-r--r--WebCore/page/chromium/FrameChromium.cpp98
-rw-r--r--WebCore/page/chromium/FrameChromium.h39
-rw-r--r--WebCore/page/gtk/AccessibilityObjectAtk.cpp4
-rw-r--r--WebCore/page/gtk/AccessibilityObjectWrapperAtk.cpp4
-rw-r--r--WebCore/page/gtk/DragControllerGtk.cpp4
-rw-r--r--WebCore/page/gtk/EventHandlerGtk.cpp7
-rw-r--r--WebCore/page/mac/AXObjectCacheMac.mm4
-rw-r--r--WebCore/page/mac/AccessibilityObjectMac.mm4
-rw-r--r--WebCore/page/mac/AccessibilityObjectWrapper.mm120
-rw-r--r--WebCore/page/mac/DragControllerMac.mm9
-rw-r--r--WebCore/page/mac/EventHandlerMac.mm17
-rw-r--r--WebCore/page/mac/FrameMac.mm61
-rw-r--r--WebCore/page/mac/WebCoreViewFactory.h2
-rw-r--r--WebCore/page/mac/WebDashboardRegion.m41
-rw-r--r--WebCore/page/qt/AccessibilityObjectQt.cpp4
-rw-r--r--WebCore/page/qt/DragControllerQt.cpp4
-rw-r--r--WebCore/page/qt/EventHandlerQt.cpp7
-rw-r--r--WebCore/page/qt/FrameQt.cpp18
-rw-r--r--WebCore/page/win/AccessibilityObjectWin.cpp5
-rw-r--r--WebCore/page/win/DragControllerWin.cpp4
-rw-r--r--WebCore/page/win/EventHandlerWin.cpp7
-rw-r--r--WebCore/page/win/FrameCGWin.cpp41
-rw-r--r--WebCore/page/win/FrameCairoWin.cpp6
-rw-r--r--WebCore/page/win/FrameWin.cpp3
-rw-r--r--WebCore/page/wx/AccessibilityObjectWx.cpp4
-rw-r--r--WebCore/page/wx/DragControllerWx.cpp4
-rw-r--r--WebCore/page/wx/EventHandlerWx.cpp7
96 files changed, 3863 insertions, 1852 deletions
diff --git a/WebCore/page/AccessibilityListBox.cpp b/WebCore/page/AccessibilityListBox.cpp
index 912351e..b94ccef 100644
--- a/WebCore/page/AccessibilityListBox.cpp
+++ b/WebCore/page/AccessibilityListBox.cpp
@@ -150,30 +150,28 @@ AccessibilityObject* AccessibilityListBox::listBoxOptionAccessibilityObject(HTML
return listBoxObject;
}
-AccessibilityObject* AccessibilityListBox::doAccessibilityHitTest(const IntPoint& point)
+AccessibilityObject* AccessibilityListBox::doAccessibilityHitTest(const IntPoint& point) const
{
// the internal HTMLSelectElement methods for returning a listbox option at a point
// ignore optgroup elements.
if (!m_renderer)
return 0;
- Node *element = m_renderer->element();
+ Node* element = m_renderer->element();
if (!element)
return 0;
-
- if (!hasChildren())
- addChildren();
IntRect parentRect = boundingBoxRect();
- unsigned length = m_children.size();
+ const Vector<HTMLElement*>& listItems = static_cast<HTMLSelectElement*>(element)->listItems();
+ unsigned length = listItems.size();
for (unsigned i = 0; i < length; i++) {
IntRect rect = static_cast<RenderListBox*>(m_renderer)->itemBoundingBoxRect(parentRect.x(), parentRect.y(), i);
if (rect.contains(point))
- return m_children[i].get();
+ return listBoxOptionAccessibilityObject(listItems[i]);
}
- return this;
+ return axObjectCache()->get(m_renderer);
}
} // namespace WebCore
diff --git a/WebCore/page/AccessibilityListBox.h b/WebCore/page/AccessibilityListBox.h
index f95a921..3f3352d 100644
--- a/WebCore/page/AccessibilityListBox.h
+++ b/WebCore/page/AccessibilityListBox.h
@@ -42,7 +42,7 @@ public:
static PassRefPtr<AccessibilityListBox> create(RenderObject*);
virtual ~AccessibilityListBox();
- virtual AccessibilityObject* doAccessibilityHitTest(const IntPoint&);
+ virtual AccessibilityObject* doAccessibilityHitTest(const IntPoint&) const;
virtual bool isListBox() const { return true; };
virtual bool canSetFocusAttribute() const { return true; }
diff --git a/WebCore/page/AccessibilityObject.cpp b/WebCore/page/AccessibilityObject.cpp
index 6be8c1a..6d441d0 100644
--- a/WebCore/page/AccessibilityObject.cpp
+++ b/WebCore/page/AccessibilityObject.cpp
@@ -51,6 +51,7 @@
#include "TextIterator.h"
#include "htmlediting.h"
#include "visible_units.h"
+#include <wtf/StdLibExtras.h>
using namespace std;
@@ -256,7 +257,7 @@ void AccessibilityObject::setSelectedText(const String&)
notImplemented();
}
-void AccessibilityObject::setSelectedTextRange(const PlainTextRange& range)
+void AccessibilityObject::setSelectedTextRange(const PlainTextRange&)
{
}
@@ -271,11 +272,11 @@ KURL AccessibilityObject::url() const
return KURL();
}
-void AccessibilityObject::setFocused(bool on)
+void AccessibilityObject::setFocused(bool)
{
}
-void AccessibilityObject::setValue(const String& string)
+void AccessibilityObject::setValue(const String&)
{
}
@@ -326,17 +327,17 @@ VisiblePositionRange AccessibilityObject::visiblePositionRange() const
return VisiblePositionRange();
}
-VisiblePositionRange AccessibilityObject::visiblePositionRangeForLine(unsigned lineCount) const
+VisiblePositionRange AccessibilityObject::visiblePositionRangeForLine(unsigned) const
{
return VisiblePositionRange();
}
-VisiblePosition AccessibilityObject::visiblePositionForIndex(int index) const
+VisiblePosition AccessibilityObject::visiblePositionForIndex(int) const
{
return VisiblePosition();
}
-int AccessibilityObject::indexForVisiblePosition(const VisiblePosition& pos) const
+int AccessibilityObject::indexForVisiblePosition(const VisiblePosition&) const
{
return 0;
}
@@ -599,7 +600,7 @@ String AccessibilityObject::stringForVisiblePositionRange(const VisiblePositionR
return String::adopt(resultVector);
}
-IntRect AccessibilityObject::boundsForVisiblePositionRange(const VisiblePositionRange& visiblePositionRange) const
+IntRect AccessibilityObject::boundsForVisiblePositionRange(const VisiblePositionRange&) const
{
return IntRect();
}
@@ -635,7 +636,7 @@ void AccessibilityObject::setSelectedVisiblePositionRange(const VisiblePositionR
{
}
-VisiblePosition AccessibilityObject::visiblePositionForPoint(const IntPoint& point) const
+VisiblePosition AccessibilityObject::visiblePositionForPoint(const IntPoint&) const
{
return VisiblePosition();
}
@@ -738,7 +739,8 @@ VisiblePosition AccessibilityObject::nextSentenceEndPosition(const VisiblePositi
// an empty line is considered a sentence. If it's skipped, then the sentence parser will not
// see this empty line. Instead, return the end position of the empty line.
VisiblePosition endPosition;
- String lineString = plainText(makeRange(startOfLine(visiblePos), endOfLine(visiblePos)).get());
+
+ String lineString = plainText(makeRange(startOfLine(nextVisiblePos), endOfLine(nextVisiblePos)).get());
if (lineString.isEmpty())
endPosition = nextVisiblePos;
else
@@ -761,6 +763,7 @@ VisiblePosition AccessibilityObject::previousSentenceStartPosition(const Visible
// treat empty line as a separate sentence.
VisiblePosition startPosition;
+
String lineString = plainText(makeRange(startOfLine(previousVisiblePos), endOfLine(previousVisiblePos)).get());
if (lineString.isEmpty())
startPosition = previousVisiblePos;
@@ -797,7 +800,7 @@ VisiblePosition AccessibilityObject::previousParagraphStartPosition(const Visibl
}
// NOTE: Consider providing this utility method as AX API
-VisiblePosition AccessibilityObject::visiblePositionForIndex(unsigned indexValue, bool lastIndexOK) const
+VisiblePosition AccessibilityObject::visiblePositionForIndex(unsigned, bool) const
{
return VisiblePosition();
}
@@ -848,14 +851,14 @@ PlainTextRange AccessibilityObject::plainTextRangeForVisiblePositionRange(const
}
// NOTE: Consider providing this utility method as AX API
-int AccessibilityObject::index(const VisiblePosition& position) const
+int AccessibilityObject::index(const VisiblePosition&) const
{
return -1;
}
// Given a line number, the range of characters of the text associated with this accessibility
// object that contains the line number.
-PlainTextRange AccessibilityObject::doAXRangeForLine(unsigned lineNumber) const
+PlainTextRange AccessibilityObject::doAXRangeForLine(unsigned) const
{
return PlainTextRange();
}
@@ -878,7 +881,7 @@ PlainTextRange AccessibilityObject::doAXRangeForPosition(const IntPoint& point)
// The composed character range in the text associated with this accessibility object that
// is specified by the given index value. This parameterized attribute returns the complete
// range of characters (including surrogate pairs of multi-byte glyphs) at the given index.
-PlainTextRange AccessibilityObject::doAXRangeForIndex(unsigned index) const
+PlainTextRange AccessibilityObject::doAXRangeForIndex(unsigned) const
{
return PlainTextRange();
}
@@ -893,7 +896,7 @@ PlainTextRange AccessibilityObject::doAXStyleRangeForIndex(unsigned index) const
// A substring of the text associated with this accessibility object that is
// specified by the given character range.
-String AccessibilityObject::doAXStringForRange(const PlainTextRange& range) const
+String AccessibilityObject::doAXStringForRange(const PlainTextRange&) const
{
return String();
}
@@ -901,7 +904,7 @@ String AccessibilityObject::doAXStringForRange(const PlainTextRange& range) cons
// The bounding rectangle of the text associated with this accessibility object that is
// specified by the given range. This is the bounding rectangle a sighted user would see
// on the display screen, in pixels.
-IntRect AccessibilityObject::doAXBoundsForRange(const PlainTextRange& range) const
+IntRect AccessibilityObject::doAXBoundsForRange(const PlainTextRange&) const
{
return IntRect();
}
@@ -925,7 +928,7 @@ FrameView* AccessibilityObject::documentFrameView() const
return object->documentFrameView();
}
-AccessibilityObject* AccessibilityObject::doAccessibilityHitTest(const IntPoint& point) const
+AccessibilityObject* AccessibilityObject::doAccessibilityHitTest(const IntPoint&) const
{
return 0;
}
@@ -1001,13 +1004,13 @@ void AccessibilityObject::removeAXObjectID()
const String& AccessibilityObject::actionVerb() const
{
// FIXME: Need to add verbs for select elements.
- static const String buttonAction = AXButtonActionVerb();
- static const String textFieldAction = AXTextFieldActionVerb();
- static const String radioButtonAction = AXRadioButtonActionVerb();
- static const String checkedCheckBoxAction = AXCheckedCheckBoxActionVerb();
- static const String uncheckedCheckBoxAction = AXUncheckedCheckBoxActionVerb();
- static const String linkAction = AXLinkActionVerb();
- static const String noAction;
+ DEFINE_STATIC_LOCAL(const String, buttonAction, (AXButtonActionVerb()));
+ DEFINE_STATIC_LOCAL(const String, textFieldAction, (AXTextFieldActionVerb()));
+ DEFINE_STATIC_LOCAL(const String, radioButtonAction, (AXRadioButtonActionVerb()));
+ DEFINE_STATIC_LOCAL(const String, checkedCheckBoxAction, (AXCheckedCheckBoxActionVerb()));
+ DEFINE_STATIC_LOCAL(const String, uncheckedCheckBoxAction, (AXUncheckedCheckBoxActionVerb()));
+ DEFINE_STATIC_LOCAL(const String, linkAction, (AXLinkActionVerb()));
+ DEFINE_STATIC_LOCAL(const String, noAction, ());
switch (roleValue()) {
case ButtonRole:
@@ -1027,4 +1030,8 @@ const String& AccessibilityObject::actionVerb() const
}
}
+void AccessibilityObject::updateBackingStore()
+{
+}
+
} // namespace WebCore
diff --git a/WebCore/page/AccessibilityObject.h b/WebCore/page/AccessibilityObject.h
index 947757a..a751003 100644
--- a/WebCore/page/AccessibilityObject.h
+++ b/WebCore/page/AccessibilityObject.h
@@ -213,6 +213,7 @@ public:
virtual bool isMenuButton() const { return false; }
virtual bool isMenuItem() const { return false; }
virtual bool isFileUploadButton() const { return false; };
+ virtual bool isInputImage() const { return false; }
virtual bool isProgressIndicator() const { return false; };
virtual bool isSlider() const { return false; };
virtual bool isControl() const { return false; };
@@ -222,6 +223,7 @@ public:
virtual bool isTableColumn() const { return false; };
virtual bool isTableCell() const { return false; };
virtual bool isFieldset() const { return false; };
+ virtual bool isGroup() const { return false; };
virtual bool isChecked() const { return false; };
virtual bool isEnabled() const { return false; };
@@ -392,7 +394,15 @@ public:
#endif
// a platform-specific method for determining if an attachment is ignored
+#if HAVE(ACCESSIBILITY)
bool accessibilityIgnoreAttachment() const;
+#else
+ bool accessibilityIgnoreAttachment() const { return true; }
+#endif
+
+ // allows for an AccessibilityObject to update its render tree or perform
+ // other operations update type operations
+ virtual void updateBackingStore();
protected:
unsigned m_id;
diff --git a/WebCore/page/AccessibilityRenderObject.cpp b/WebCore/page/AccessibilityRenderObject.cpp
index 144aab0..5cdc7b4 100644
--- a/WebCore/page/AccessibilityRenderObject.cpp
+++ b/WebCore/page/AccessibilityRenderObject.cpp
@@ -61,6 +61,7 @@
#include "RenderListBox.h"
#include "RenderListMarker.h"
#include "RenderMenuList.h"
+#include "RenderText.h"
#include "RenderTextControl.h"
#include "RenderTheme.h"
#include "RenderView.h"
@@ -70,6 +71,7 @@
#include "TextIterator.h"
#include "htmlediting.h"
#include "visible_units.h"
+#include <wtf/StdLibExtras.h>
using namespace std;
@@ -246,6 +248,16 @@ bool AccessibilityRenderObject::isFileUploadButton() const
return false;
}
+
+bool AccessibilityRenderObject::isInputImage() const
+{
+ if (m_renderer && m_renderer->element() && m_renderer->element()->hasTagName(inputTag)) {
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(m_renderer->element());
+ return input->inputType() == HTMLInputElement::IMAGE;
+ }
+
+ return false;
+}
bool AccessibilityRenderObject::isProgressIndicator() const
{
@@ -341,6 +353,10 @@ bool AccessibilityRenderObject::isReadOnly() const
if (!document)
return true;
+ HTMLElement* body = document->body();
+ if (body && body->isContentEditable())
+ return false;
+
Frame* frame = document->frame();
if (!frame)
return true;
@@ -425,6 +441,11 @@ bool AccessibilityRenderObject::isFieldset() const
return m_renderer->isFieldset();
}
+
+bool AccessibilityRenderObject::isGroup() const
+{
+ return roleValue() == GroupRole;
+}
const AtomicString& AccessibilityRenderObject::getAttribute(const QualifiedName& attribute) const
{
@@ -449,8 +470,9 @@ Element* AccessibilityRenderObject::anchorElement() const
// Search up the render tree for a RenderObject with a DOM node. Defer to an earlier continuation, though.
for (currRenderer = m_renderer; currRenderer && !currRenderer->element(); currRenderer = currRenderer->parent()) {
- if (currRenderer->continuation())
- return cache->get(currRenderer->continuation())->anchorElement();
+ RenderFlow* continuation = currRenderer->virtualContinuation();
+ if (continuation)
+ return cache->get(continuation)->anchorElement();
}
// bail if none found
@@ -470,10 +492,17 @@ Element* AccessibilityRenderObject::anchorElement() const
Element* AccessibilityRenderObject::actionElement() const
{
- if (m_renderer->element() && m_renderer->element()->hasTagName(inputTag)) {
- HTMLInputElement* input = static_cast<HTMLInputElement*>(m_renderer->element());
- if (!input->disabled() && (isCheckboxOrRadio() || input->isTextButton()))
- return input;
+ if (!m_renderer)
+ return 0;
+
+ Node* node = m_renderer->element();
+ if (node) {
+ if (node->hasTagName(inputTag)) {
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(node);
+ if (!input->disabled() && (isCheckboxOrRadio() || input->isTextButton()))
+ return input;
+ } else if (node->hasTagName(buttonTag))
+ return static_cast<Element*>(node);
}
if (isFileUploadButton())
@@ -837,7 +866,7 @@ String AccessibilityRenderObject::title() const
if (isInputTag || AccessibilityObject::isARIAInput(ariaRole) || isControl()) {
HTMLLabelElement* label = labelForElement(static_cast<Element*>(node));
- if (label)
+ if (label && !titleUIElement())
return label->innerText();
}
@@ -920,9 +949,8 @@ IntRect AccessibilityRenderObject::boundingBoxRect() const
// FIXME: This doesn't work correctly with transforms.
Vector<IntRect> rects;
- int x, y;
- obj->absolutePosition(x, y);
- obj->absoluteRects(rects, x, y);
+ FloatPoint absPos = obj->localToAbsolute();
+ obj->absoluteRects(rects, absPos.x(), absPos.y());
const size_t n = rects.size();
for (size_t i = 0; i < n; ++i) {
IntRect r = rects[i];
@@ -985,12 +1013,9 @@ AccessibilityObject* AccessibilityRenderObject::internalLinkElement() const
if (m_renderer->document()->url() != linkURL)
return 0;
- Node* linkedNode = m_renderer->document()->getElementById(ref);
- if (!linkedNode) {
- linkedNode = m_renderer->document()->anchors()->namedItem(ref, !m_renderer->document()->inCompatMode());
- if (!linkedNode)
- return 0;
- }
+ Node* linkedNode = m_renderer->document()->findAnchor(ref);
+ if (!linkedNode)
+ return 0;
// the element we find may not be accessible, keep searching until we find a good one
AccessibilityObject* linkedAXElement = m_renderer->document()->axObjectCache()->get(linkedNode->renderer());
@@ -1118,7 +1143,7 @@ bool AccessibilityRenderObject::accessibilityIsIgnored() const
if (parentObjectUnignored()->ariaRoleAttribute() == MenuItemRole ||
parentObjectUnignored()->ariaRoleAttribute() == MenuButtonRole)
return true;
- return m_renderer->isBR() || !static_cast<RenderText*>(m_renderer)->firstTextBox();
+ return m_renderer->isBR() || !toRenderText(m_renderer)->firstTextBox();
}
if (isHeading())
@@ -1153,12 +1178,12 @@ bool AccessibilityRenderObject::accessibilityIsIgnored() const
}
// check for one-dimensional image
- if (m_renderer->height() <= 1 || m_renderer->width() <= 1)
+ RenderImage* image = static_cast<RenderImage*>(m_renderer);
+ if (image->height() <= 1 || image->width() <= 1)
return true;
// check whether rendered image was stretched from one-dimensional file image
if (isNativeImage()) {
- RenderImage* image = static_cast<RenderImage*>(m_renderer);
if (image->cachedImage()) {
IntSize imageSize = image->cachedImage()->imageSize(image->view()->zoomFactor());
return imageSize.height() <= 1 || imageSize.width() <= 1;
@@ -1337,6 +1362,9 @@ KURL AccessibilityRenderObject::url() const
if (isImage() && m_renderer->element() && m_renderer->element()->hasTagName(imgTag))
return static_cast<HTMLImageElement*>(m_renderer->element())->src();
+ if (isInputImage())
+ return static_cast<HTMLInputElement*>(m_renderer->element())->src();
+
return KURL();
}
@@ -1411,9 +1439,9 @@ bool AccessibilityRenderObject::isEnabled() const
return m_renderer->element() ? m_renderer->element()->isEnabled() : true;
}
-RenderObject* AccessibilityRenderObject::topRenderer() const
+RenderView* AccessibilityRenderObject::topRenderer() const
{
- return m_renderer->document()->topDocument()->renderer();
+ return m_renderer->document()->topDocument()->renderView();
}
Document* AccessibilityRenderObject::document() const
@@ -1621,19 +1649,19 @@ IntRect AccessibilityRenderObject::boundsForVisiblePositionRange(const VisiblePo
// Create a mutable VisiblePositionRange.
VisiblePositionRange range(visiblePositionRange);
- IntRect rect1 = range.start.caretRect();
- IntRect rect2 = range.end.caretRect();
+ IntRect rect1 = range.start.absoluteCaretBounds();
+ IntRect rect2 = range.end.absoluteCaretBounds();
// readjust for position at the edge of a line. This is to exclude line rect that doesn't need to be accounted in the range bounds
if (rect2.y() != rect1.y()) {
VisiblePosition endOfFirstLine = endOfLine(range.start);
if (range.start == endOfFirstLine) {
range.start.setAffinity(DOWNSTREAM);
- rect1 = range.start.caretRect();
+ rect1 = range.start.absoluteCaretBounds();
}
if (range.end == endOfFirstLine) {
range.end.setAffinity(UPSTREAM);
- rect2 = range.end.caretRect();
+ rect2 = range.end.absoluteCaretBounds();
}
}
@@ -1675,7 +1703,7 @@ VisiblePosition AccessibilityRenderObject::visiblePositionForPoint(const IntPoin
{
// convert absolute point to view coordinates
FrameView* frameView = m_renderer->document()->topDocument()->renderer()->view()->frameView();
- RenderObject* renderer = topRenderer();
+ RenderView* renderView = topRenderer();
Node* innerNode = 0;
// locate the node containing the point
@@ -1689,7 +1717,7 @@ VisiblePosition AccessibilityRenderObject::visiblePositionForPoint(const IntPoin
#endif
HitTestRequest request(true, true);
HitTestResult result(ourpoint);
- renderer->layer()->hitTest(request, result);
+ renderView->layer()->hitTest(request, result);
innerNode = result.innerNode();
if (!innerNode || !innerNode->renderer())
return VisiblePosition();
@@ -1697,7 +1725,7 @@ VisiblePosition AccessibilityRenderObject::visiblePositionForPoint(const IntPoin
pointResult = result.localPoint();
// done if hit something other than a widget
- renderer = innerNode->renderer();
+ RenderObject* renderer = innerNode->renderer();
if (!renderer->isWidget())
break;
@@ -1711,7 +1739,7 @@ VisiblePosition AccessibilityRenderObject::visiblePositionForPoint(const IntPoin
Document* document = frame->document();
if (!document)
break;
- renderer = document->renderer();
+ renderView = document->renderView();
frameView = static_cast<FrameView*>(widget);
}
@@ -1842,13 +1870,11 @@ IntRect AccessibilityRenderObject::doAXBoundsForRange(const PlainTextRange& rang
AccessibilityObject* AccessibilityRenderObject::doAccessibilityHitTest(const IntPoint& point) const
{
- if (!m_renderer)
- return 0;
-
- RenderLayer* layer = m_renderer->layer();
- if (!layer)
+ if (!m_renderer || !m_renderer->hasLayer())
return 0;
+ RenderLayer* layer = toRenderBox(m_renderer)->layer();
+
HitTestRequest request(true, true);
HitTestResult hitTestResult = HitTestResult(point);
layer->hitTest(request, hitTestResult);
@@ -1940,6 +1966,9 @@ AccessibilityObject* AccessibilityRenderObject::activeDescendant() const
return 0;
Element* target = renderer()->document()->getElementById(activeDescendantAttrStr);
+ if (!target)
+ return 0;
+
AccessibilityObject* obj = renderer()->document()->axObjectCache()->get(target->renderer());
if (obj->isAccessibilityRenderObject())
// an activedescendant is only useful if it has a renderer, because that's what's needed to post the notification
@@ -1982,7 +2011,7 @@ static const ARIARoleMap& createARIARoleMap()
AccessibilityRole webcoreRole;
};
- static const RoleEntry roles[] = {
+ const RoleEntry roles[] = {
{ "button", ButtonRole },
{ "checkbox", CheckBoxRole },
{ "group", GroupRole },
@@ -2185,12 +2214,20 @@ bool AccessibilityRenderObject::canSetTextRangeAttributes() const
void AccessibilityRenderObject::childrenChanged()
{
- clearChildren();
+ // this method is meant as a quick way of marking dirty
+ // a portion of the accessibility tree
- if (accessibilityIsIgnored()) {
- AccessibilityObject* parent = parentObject();
- if (parent)
- parent->childrenChanged();
+ markChildrenDirty();
+
+ // this object may not be accessible (and thus may not appear
+ // in the hierarchy), which means we need to go up the parent
+ // chain and mark the parent's dirty. Ideally, we would want
+ // to only access the next object that is not ignored, but
+ // asking an element if it's ignored can lead to an examination of the
+ // render tree which is dangerous.
+ for (AccessibilityObject* parent = parentObject(); parent; parent = parent->parentObject()) {
+ if (parent->isAccessibilityRenderObject())
+ static_cast<AccessibilityRenderObject *>(parent)->markChildrenDirty();
}
}
@@ -2214,6 +2251,11 @@ bool AccessibilityRenderObject::canHaveChildren() const
const AccessibilityObject::AccessibilityChildrenVector& AccessibilityRenderObject::children()
{
+ if (m_childrenDirty) {
+ clearChildren();
+ m_childrenDirty = false;
+ }
+
if (!m_haveChildren)
addChildren();
return m_children;
@@ -2348,13 +2390,13 @@ void AccessibilityRenderObject::removeAXObjectID()
const String& AccessibilityRenderObject::actionVerb() const
{
// FIXME: Need to add verbs for select elements.
- static const String buttonAction = AXButtonActionVerb();
- static const String textFieldAction = AXTextFieldActionVerb();
- static const String radioButtonAction = AXRadioButtonActionVerb();
- static const String checkedCheckBoxAction = AXCheckedCheckBoxActionVerb();
- static const String uncheckedCheckBoxAction = AXUncheckedCheckBoxActionVerb();
- static const String linkAction = AXLinkActionVerb();
- static const String noAction;
+ DEFINE_STATIC_LOCAL(const String, buttonAction, (AXButtonActionVerb()));
+ DEFINE_STATIC_LOCAL(const String, textFieldAction, (AXTextFieldActionVerb()));
+ DEFINE_STATIC_LOCAL(const String, radioButtonAction, (AXRadioButtonActionVerb()));
+ DEFINE_STATIC_LOCAL(const String, checkedCheckBoxAction, (AXCheckedCheckBoxActionVerb()));
+ DEFINE_STATIC_LOCAL(const String, uncheckedCheckBoxAction, (AXUncheckedCheckBoxActionVerb()));
+ DEFINE_STATIC_LOCAL(const String, linkAction, (AXLinkActionVerb()));
+ DEFINE_STATIC_LOCAL(const String, noAction, ());
switch (roleValue()) {
case ButtonRole:
@@ -2374,5 +2416,11 @@ const String& AccessibilityRenderObject::actionVerb() const
}
}
+void AccessibilityRenderObject::updateBackingStore()
+{
+ if (!m_renderer)
+ return;
+ m_renderer->view()->layoutIfNeeded();
+}
} // namespace WebCore
diff --git a/WebCore/page/AccessibilityRenderObject.h b/WebCore/page/AccessibilityRenderObject.h
index c859b5a..03ba1db 100644
--- a/WebCore/page/AccessibilityRenderObject.h
+++ b/WebCore/page/AccessibilityRenderObject.h
@@ -50,6 +50,7 @@ class Node;
class RenderObject;
class RenderListBox;
class RenderTextControl;
+class RenderView;
class Selection;
class String;
class Widget;
@@ -76,6 +77,7 @@ public:
virtual bool isWebArea() const;
virtual bool isCheckboxOrRadio() const;
virtual bool isFileUploadButton() const;
+ virtual bool isInputImage() const;
virtual bool isProgressIndicator() const;
virtual bool isSlider() const;
virtual bool isMenuRelated() const;
@@ -85,6 +87,7 @@ public:
virtual bool isMenuItem() const;
virtual bool isControl() const;
virtual bool isFieldset() const;
+ virtual bool isGroup() const;
virtual bool isEnabled() const;
virtual bool isSelected() const;
@@ -145,7 +148,7 @@ public:
void setRenderer(RenderObject* renderer) { m_renderer = renderer; }
RenderObject* renderer() const { return m_renderer; }
- RenderObject* topRenderer() const;
+ RenderView* topRenderer() const;
RenderTextControl* textControl() const;
Document* document() const;
FrameView* topDocumentFrameView() const;
@@ -207,9 +210,12 @@ public:
virtual String doAXStringForRange(const PlainTextRange&) const;
virtual IntRect doAXBoundsForRange(const PlainTextRange&) const;
+ virtual void updateBackingStore();
+
protected:
RenderObject* m_renderer;
AccessibilityRole m_ariaRole;
+ mutable bool m_childrenDirty;
void setRenderObject(RenderObject* renderer) { m_renderer = renderer; }
virtual void removeAXObjectID();
@@ -229,6 +235,7 @@ private:
AccessibilityObject* internalLinkElement() const;
AccessibilityObject* accessibilityParentForImageMap(HTMLMapElement* map) const;
+ void markChildrenDirty() const { m_childrenDirty = true; }
};
} // namespace WebCore
diff --git a/WebCore/page/AccessibilityTable.cpp b/WebCore/page/AccessibilityTable.cpp
index 11c36ef..9409283 100644
--- a/WebCore/page/AccessibilityTable.cpp
+++ b/WebCore/page/AccessibilityTable.cpp
@@ -53,13 +53,11 @@ AccessibilityTable::AccessibilityTable(RenderObject* renderer)
: AccessibilityRenderObject(renderer),
m_headerContainer(0)
{
- // AXTables should not appear in tiger or leopard, on the mac
-#if PLATFORM(MAC) && (defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD))
+#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD)
m_isAccessibilityTable = false;
-#else
+#else
m_isAccessibilityTable = isTableExposableThroughAccessibility();
#endif
-
}
AccessibilityTable::~AccessibilityTable()
diff --git a/WebCore/page/AccessibilityTableCell.cpp b/WebCore/page/AccessibilityTableCell.cpp
index 2062a88..ff82811 100644
--- a/WebCore/page/AccessibilityTableCell.cpp
+++ b/WebCore/page/AccessibilityTableCell.cpp
@@ -30,6 +30,7 @@
#include "AccessibilityTableCell.h"
#include "AXObjectCache.h"
+#include "HTMLNames.h"
#include "RenderObject.h"
#include "RenderTableCell.h"
@@ -37,6 +38,8 @@ using namespace std;
namespace WebCore {
+using namespace HTMLNames;
+
AccessibilityTableCell::AccessibilityTableCell(RenderObject* renderer)
: AccessibilityRenderObject(renderer)
{
@@ -84,7 +87,7 @@ void AccessibilityTableCell::rowIndexRange(pair<int, int>& rowRange)
if (!m_renderer)
return;
- RenderTableCell *renderCell = static_cast<RenderTableCell*>(m_renderer);
+ RenderTableCell* renderCell = static_cast<RenderTableCell*>(m_renderer);
rowRange.first = renderCell->row();
rowRange.second = renderCell->rowSpan();
@@ -114,9 +117,41 @@ void AccessibilityTableCell::columnIndexRange(pair<int, int>& columnRange)
if (!m_renderer)
return;
- RenderTableCell *renderCell = static_cast<RenderTableCell*>(m_renderer);
+ RenderTableCell* renderCell = static_cast<RenderTableCell*>(m_renderer);
columnRange.first = renderCell->col();
columnRange.second = renderCell->colSpan();
}
+AccessibilityObject* AccessibilityTableCell::titleUIElement() const
+{
+ // Try to find if the first cell in this row is a <th>. If it is,
+ // then it can act as the title ui element. (This is only in the
+ // case when the table is not appearing as an AXTable.)
+ if (!m_renderer || isTableCell())
+ return 0;
+
+ RenderTableCell* renderCell = static_cast<RenderTableCell*>(m_renderer);
+
+ // If this cell is in the first column, there is no need to continue.
+ int col = renderCell->col();
+ if (!col)
+ return 0;
+
+ int row = renderCell->row();
+
+ RenderTableSection* section = renderCell->section();
+ if (!section)
+ return 0;
+
+ RenderTableCell* headerCell = section->cellAt(row, 0).cell;
+ if (!headerCell || headerCell == renderCell)
+ return 0;
+
+ Node* cellElement = headerCell->element();
+ if (!cellElement || !cellElement->hasTagName(thTag))
+ return 0;
+
+ return axObjectCache()->get(headerCell);
+}
+
} // namespace WebCore
diff --git a/WebCore/page/AccessibilityTableCell.h b/WebCore/page/AccessibilityTableCell.h
index e77dfb2..8f8dd77 100644
--- a/WebCore/page/AccessibilityTableCell.h
+++ b/WebCore/page/AccessibilityTableCell.h
@@ -51,6 +51,10 @@ public:
// fills in the start location and column span of cell
void columnIndexRange(pair<int, int>& columnRange);
+ // if a table cell is not exposed as a table cell, a TH element can
+ // serve as its title ui element
+ AccessibilityObject* titleUIElement() const;
+
private:
int m_rowIndex;
diff --git a/WebCore/page/Chrome.cpp b/WebCore/page/Chrome.cpp
index c9b57f2..4698aa5 100644
--- a/WebCore/page/Chrome.cpp
+++ b/WebCore/page/Chrome.cpp
@@ -35,7 +35,6 @@
#include "InspectorController.h"
#include "Page.h"
#include "PageGroup.h"
-#include "PausedTimeouts.h"
#include "ResourceHandle.h"
#include "ScriptController.h"
#include "SecurityOrigin.h"
@@ -60,9 +59,6 @@ public:
~PageGroupLoadDeferrer();
private:
Vector<RefPtr<Frame>, 16> m_deferredFrames;
-#if !PLATFORM(MAC)
- Vector<pair<RefPtr<Frame>, PausedTimeouts*>, 16> m_pausedTimeouts;
-#endif
};
Chrome::Chrome(Page* page, ChromeClient* client)
@@ -102,6 +98,16 @@ PlatformWidget Chrome::platformWindow() const
return m_client->platformWindow();
}
+void Chrome::contentsSizeChanged(Frame* frame, const IntSize& size) const
+{
+ m_client->contentsSizeChanged(frame, size);
+}
+
+void Chrome::scrollRectIntoView(const IntRect& rect, const ScrollView* scrollView) const
+{
+ m_client->scrollRectIntoView(rect, scrollView);
+}
+
void Chrome::setWindowRect(const FloatRect& rect) const
{
m_client->setWindowRect(rect);
@@ -253,10 +259,7 @@ void Chrome::runJavaScriptAlert(Frame* frame, const String& message)
PageGroupLoadDeferrer deferrer(m_page, true);
ASSERT(frame);
- String text = message;
- text.replace('\\', frame->backslashAsCurrencySymbol());
-
- m_client->runJavaScriptAlert(frame, text);
+ m_client->runJavaScriptAlert(frame, frame->displayStringModifiedByEncoding(message));
}
bool Chrome::runJavaScriptConfirm(Frame* frame, const String& message)
@@ -266,10 +269,7 @@ bool Chrome::runJavaScriptConfirm(Frame* frame, const String& message)
PageGroupLoadDeferrer deferrer(m_page, true);
ASSERT(frame);
- String text = message;
- text.replace('\\', frame->backslashAsCurrencySymbol());
-
- return m_client->runJavaScriptConfirm(frame, text);
+ return m_client->runJavaScriptConfirm(frame, frame->displayStringModifiedByEncoding(message));
}
bool Chrome::runJavaScriptPrompt(Frame* frame, const String& prompt, const String& defaultValue, String& result)
@@ -279,15 +279,10 @@ bool Chrome::runJavaScriptPrompt(Frame* frame, const String& prompt, const Strin
PageGroupLoadDeferrer deferrer(m_page, true);
ASSERT(frame);
- String promptText = prompt;
- promptText.replace('\\', frame->backslashAsCurrencySymbol());
- String defaultValueText = defaultValue;
- defaultValueText.replace('\\', frame->backslashAsCurrencySymbol());
-
- bool ok = m_client->runJavaScriptPrompt(frame, promptText, defaultValueText, result);
+ bool ok = m_client->runJavaScriptPrompt(frame, frame->displayStringModifiedByEncoding(prompt), frame->displayStringModifiedByEncoding(defaultValue), result);
if (ok)
- result.replace(frame->backslashAsCurrencySymbol(), '\\');
+ result = frame->displayStringModifiedByEncoding(result);
return ok;
}
@@ -295,10 +290,7 @@ bool Chrome::runJavaScriptPrompt(Frame* frame, const String& prompt, const Strin
void Chrome::setStatusbarText(Frame* frame, const String& status)
{
ASSERT(frame);
- String text = status;
- text.replace('\\', frame->backslashAsCurrencySymbol());
-
- m_client->setStatusbarText(text);
+ m_client->setStatusbarText(frame->displayStringModifiedByEncoding(status));
}
bool Chrome::shouldInterruptJavaScript()
@@ -440,8 +432,8 @@ void ChromeClient::enableSuddenTermination()
}
bool ChromeClient::paintCustomScrollbar(GraphicsContext*, const FloatRect&, ScrollbarControlSize,
- ScrollbarControlState, ScrollbarPart, bool vertical,
- float value, float proportion, ScrollbarControlPartMask)
+ ScrollbarControlState, ScrollbarPart, bool,
+ float, float, ScrollbarControlPartMask)
{
return false;
}
@@ -466,10 +458,8 @@ PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf)
#if !PLATFORM(MAC)
for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
- OwnPtr<PausedTimeouts> timeouts;
- frame->script()->pauseTimeouts(timeouts);
- if (timeouts)
- m_pausedTimeouts.append(make_pair(RefPtr<Frame>(frame), timeouts.release()));
+ if (Document* document = frame->document())
+ document->suspendActiveDOMObjects();
}
#endif
}
@@ -483,17 +473,18 @@ PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf)
PageGroupLoadDeferrer::~PageGroupLoadDeferrer()
{
- for (size_t i = 0; i < m_deferredFrames.size(); ++i)
- if (Page* page = m_deferredFrames[i]->page())
+ for (size_t i = 0; i < m_deferredFrames.size(); ++i) {
+ if (Page* page = m_deferredFrames[i]->page()) {
page->setDefersLoading(false);
#if !PLATFORM(MAC)
- for (size_t i = 0; i < m_pausedTimeouts.size(); i++) {
- Frame* frame = m_pausedTimeouts[i].first.get();
- OwnPtr<PausedTimeouts> timeouts(m_pausedTimeouts[i].second);
- frame->script()->resumeTimeouts(timeouts);
- }
+ for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ if (Document* document = frame->document())
+ document->resumeActiveDOMObjects();
+ }
#endif
+ }
+ }
}
diff --git a/WebCore/page/Chrome.h b/WebCore/page/Chrome.h
index 0dd4013..47b912d 100644
--- a/WebCore/page/Chrome.h
+++ b/WebCore/page/Chrome.h
@@ -59,6 +59,9 @@ namespace WebCore {
virtual IntPoint screenToWindow(const IntPoint&) const;
virtual IntRect windowToScreen(const IntRect&) const;
virtual PlatformWidget platformWindow() const;
+ virtual void scrollRectIntoView(const IntRect&, const ScrollView*) const;
+
+ void contentsSizeChanged(Frame*, const IntSize&) const;
void setWindowRect(const FloatRect&) const;
FloatRect windowRect() const;
diff --git a/WebCore/page/ChromeClient.h b/WebCore/page/ChromeClient.h
index 7678dc2..5d90b2f 100644
--- a/WebCore/page/ChromeClient.h
+++ b/WebCore/page/ChromeClient.h
@@ -115,6 +115,8 @@ namespace WebCore {
virtual IntPoint screenToWindow(const IntPoint&) const = 0;
virtual IntRect windowToScreen(const IntRect&) const = 0;
virtual PlatformWidget platformWindow() const = 0;
+ virtual void contentsSizeChanged(Frame*, const IntSize&) const = 0;
+ virtual void scrollRectIntoView(const IntRect&, const ScrollView*) const {} // Platforms other than Mac can implement this if it ever becomes necessary for them to do so.
// End methods used by HostWindow.
virtual void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags) = 0;
@@ -148,6 +150,10 @@ namespace WebCore {
virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>) = 0;
+ // Notification that the given form element has changed. This function
+ // will be called frequently, so handling should be very fast.
+ virtual void formStateDidChange(const Node*) = 0;
+
#if PLATFORM(MAC)
virtual KeyboardUIMode keyboardUIMode() { return KeyboardAccessDefault; }
diff --git a/WebCore/page/Console.cpp b/WebCore/page/Console.cpp
index bfcc478..8755f0e 100644
--- a/WebCore/page/Console.cpp
+++ b/WebCore/page/Console.cpp
@@ -35,18 +35,16 @@
#include "FrameLoader.h"
#include "FrameTree.h"
#include "InspectorController.h"
-#include "JSDOMBinding.h"
#include "Page.h"
#include "PageGroup.h"
#include "PlatformString.h"
-#include <runtime/ArgList.h>
-#include <kjs/interpreter.h>
-#include <runtime/JSObject.h>
-#include <VM/Machine.h>
+
+#if USE(JSC)
#include <profiler/Profiler.h>
-#include <stdio.h>
+#endif
-using namespace JSC;
+#include "ScriptCallStack.h"
+#include <stdio.h>
namespace WebCore {
@@ -70,6 +68,18 @@ static void printSourceURLAndLine(const String& sourceURL, unsigned lineNumber)
}
}
+static bool getFirstArgumentAsString(const ScriptCallFrame& callFrame, String& result, bool checkForNullOrUndefined = false)
+{
+ if (!callFrame.argumentCount())
+ return false;
+
+ const ScriptValue& value = callFrame.argumentAt(0);
+ if (checkForNullOrUndefined && (value.isNull() || value.isUndefined()))
+ return false;
+
+ return value.getString(result);
+}
+
static void printMessageSourceAndLevelPrefix(MessageSource source, MessageLevel level)
{
const char* sourceString;
@@ -77,6 +87,9 @@ static void printMessageSourceAndLevelPrefix(MessageSource source, MessageLevel
case HTMLMessageSource:
sourceString = "HTML";
break;
+ case WMLMessageSource:
+ sourceString = "WML";
+ break;
case XMLMessageSource:
sourceString = "XML";
break;
@@ -116,8 +129,17 @@ static void printMessageSourceAndLevelPrefix(MessageSource source, MessageLevel
printf("%s %s:", sourceString, levelString);
}
-static void printToStandardOut(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber)
+void Console::addMessage(MessageSource source, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL)
{
+ Page* page = this->page();
+ if (!page)
+ return;
+
+ if (source == JSMessageSource || source == WMLMessageSource)
+ page->chrome()->client()->addMessageToConsole(message, lineNumber, sourceURL);
+
+ page->inspectorController()->addMessageToConsole(source, level, message, lineNumber, sourceURL);
+
if (!Console::shouldPrintExceptions())
return;
@@ -127,217 +149,124 @@ static void printToStandardOut(MessageSource source, MessageLevel level, const S
printf(" %s\n", message.utf8().data());
}
-static void printToStandardOut(MessageLevel level, ExecState* exec, const ArgList& args, const KURL& url)
-{
- if (!Console::shouldPrintExceptions())
+void Console::addMessage(MessageLevel level, ScriptCallStack* callStack, bool acceptNoArguments) {
+ Page* page = this->page();
+ if (!page)
return;
- printSourceURLAndLine(url.prettyURL(), 0);
- printMessageSourceAndLevelPrefix(JSMessageSource, level);
-
- for (size_t i = 0; i < args.size(); ++i) {
- UString argAsString = args.at(exec, i)->toString(exec);
- printf(" %s", argAsString.UTF8String().c_str());
- }
-
- printf("\n");
-}
+ const ScriptCallFrame& lastCaller = callStack->at(0);
-static inline void retrieveLastCaller(ExecState* exec, KURL& url, unsigned& lineNumber)
-{
- int signedLineNumber;
- intptr_t sourceID;
- UString urlString;
- JSValue* function;
+ if (!acceptNoArguments && !lastCaller.argumentCount())
+ return;
- exec->machine()->retrieveLastCaller(exec, signedLineNumber, sourceID, urlString, function);
+ String message;
+ if (getFirstArgumentAsString(lastCaller, message))
+ page->chrome()->client()->addMessageToConsole(message, lastCaller.lineNumber(), lastCaller.sourceURL().prettyURL());
- url = KURL(urlString);
- lineNumber = (signedLineNumber >= 0 ? signedLineNumber : 0);
-}
+ page->inspectorController()->addMessageToConsole(JSMessageSource, level, callStack);
-void Console::addMessage(MessageSource source, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL)
-{
- Page* page = this->page();
- if (!page)
+ if (!Console::shouldPrintExceptions())
return;
- if (source == JSMessageSource)
- page->chrome()->client()->addMessageToConsole(message, lineNumber, sourceURL);
-
- page->inspectorController()->addMessageToConsole(source, level, message, lineNumber, sourceURL);
+ printSourceURLAndLine(lastCaller.sourceURL().prettyURL(), 0);
+ printMessageSourceAndLevelPrefix(JSMessageSource, level);
- printToStandardOut(source, level, message, sourceURL, lineNumber);
+ for (unsigned i = 0; i < lastCaller.argumentCount(); ++i) {
+ String argAsString;
+ if (lastCaller.argumentAt(i).getString(argAsString))
+ printf(" %s", argAsString.utf8().data());
+ }
+ printf("\n");
}
-void Console::debug(ExecState* exec, const ArgList& args)
+void Console::debug(ScriptCallStack* callStack)
{
// In Firebug, console.debug has the same behavior as console.log. So we'll do the same.
- log(exec, args);
+ log(callStack);
}
-void Console::error(ExecState* exec, const ArgList& args)
+void Console::error(ScriptCallStack* callStack)
{
- if (args.isEmpty())
- return;
-
- Page* page = this->page();
- if (!page)
- return;
-
- String message = args.at(exec, 0)->toString(exec);
-
- KURL url;
- unsigned lineNumber;
- retrieveLastCaller(exec, url, lineNumber);
-
- page->chrome()->client()->addMessageToConsole(message, lineNumber, url.prettyURL());
- page->inspectorController()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, exec, args, lineNumber, url.string());
-
- printToStandardOut(ErrorMessageLevel, exec, args, url);
+ addMessage(ErrorMessageLevel, callStack);
}
-void Console::info(ExecState* exec, const ArgList& args)
+void Console::info(ScriptCallStack* callStack)
{
- if (args.isEmpty())
- return;
-
- Page* page = this->page();
- if (!page)
- return;
-
- String message = args.at(exec, 0)->toString(exec);
-
- KURL url;
- unsigned lineNumber;
- retrieveLastCaller(exec, url, lineNumber);
-
- page->chrome()->client()->addMessageToConsole(message, lineNumber, url.prettyURL());
- page->inspectorController()->addMessageToConsole(JSMessageSource, LogMessageLevel, exec, args, lineNumber, url.string());
-
- printToStandardOut(LogMessageLevel, exec, args, url);
+ log(callStack);
}
-void Console::log(ExecState* exec, const ArgList& args)
+void Console::log(ScriptCallStack* callStack)
{
- if (args.isEmpty())
- return;
-
- Page* page = this->page();
- if (!page)
- return;
-
- String message = args.at(exec, 0)->toString(exec);
-
- KURL url;
- unsigned lineNumber;
- retrieveLastCaller(exec, url, lineNumber);
-
- page->chrome()->client()->addMessageToConsole(message, lineNumber, url.prettyURL());
- page->inspectorController()->addMessageToConsole(JSMessageSource, LogMessageLevel, exec, args, lineNumber, url.string());
-
- printToStandardOut(LogMessageLevel, exec, args, url);
+ addMessage(LogMessageLevel, callStack);
}
-void Console::dir(ExecState* exec, const ArgList& args)
+void Console::dir(ScriptCallStack* callStack)
{
- if (args.isEmpty())
- return;
-
- Page* page = this->page();
- if (!page)
- return;
-
- page->inspectorController()->addMessageToConsole(JSMessageSource, ObjectMessageLevel, exec, args, 0, String());
+ addMessage(ObjectMessageLevel, callStack);
}
-void Console::dirxml(ExecState* exec, const ArgList& args)
+void Console::dirxml(ScriptCallStack* callStack)
{
- if (args.isEmpty())
- return;
-
- Page* page = this->page();
- if (!page)
- return;
-
- page->inspectorController()->addMessageToConsole(JSMessageSource, NodeMessageLevel, exec, args, 0, String());
+ addMessage(NodeMessageLevel, callStack);
}
-void Console::trace(ExecState* exec)
+void Console::trace(ScriptCallStack* callStack)
{
- Page* page = this->page();
- if (!page)
- return;
+ addMessage(TraceMessageLevel, callStack, true);
- int signedLineNumber;
- intptr_t sourceID;
- UString urlString;
- JSValue* func;
-
- exec->machine()->retrieveLastCaller(exec, signedLineNumber, sourceID, urlString, func);
+ if (!shouldPrintExceptions())
+ return;
- ArgList args;
- while (!func->isNull()) {
- args.append(func);
- func = exec->machine()->retrieveCaller(exec, asInternalFunction(func));
+ printf("Stack Trace\n");
+ for (unsigned i = 0; i < callStack->size(); ++i) {
+ String functionName = String(callStack->at(i).functionName());
+ printf("\t%s\n", functionName.utf8().data());
}
-
- page->inspectorController()->addMessageToConsole(JSMessageSource, TraceMessageLevel, exec, args, 0, String());
}
-void Console::assertCondition(bool condition, ExecState* exec, const ArgList& args)
+void Console::assertCondition(bool condition, ScriptCallStack* callStack)
{
if (condition)
return;
- Page* page = this->page();
- if (!page)
- return;
-
- KURL url;
- unsigned lineNumber;
- retrieveLastCaller(exec, url, lineNumber);
-
// FIXME: <https://bugs.webkit.org/show_bug.cgi?id=19135> It would be nice to prefix assertion failures with a message like "Assertion failed: ".
- // FIXME: <https://bugs.webkit.org/show_bug.cgi?id=19136> We should print a message even when args.isEmpty() is true.
-
- page->inspectorController()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, exec, args, lineNumber, url.string());
-
- printToStandardOut(ErrorMessageLevel, exec, args, url);
+ addMessage(ErrorMessageLevel, callStack, true);
}
-void Console::count(ExecState* exec, const ArgList& args)
+void Console::count(ScriptCallStack* callStack)
{
Page* page = this->page();
if (!page)
return;
- KURL url;
- unsigned lineNumber;
- retrieveLastCaller(exec, url, lineNumber);
+ const ScriptCallFrame& lastCaller = callStack->at(0);
+ // Follow Firebug's behavior of counting with null and undefined title in
+ // the same bucket as no argument
+ String title;
+ getFirstArgumentAsString(lastCaller, title);
- UString title;
- if (args.size() >= 1)
- title = valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, 0));
-
- page->inspectorController()->count(title, lineNumber, url.string());
+ page->inspectorController()->count(title, lastCaller.lineNumber(), lastCaller.sourceURL().string());
}
-void Console::profile(ExecState* exec, const ArgList& args)
+#if USE(JSC)
+
+void Console::profile(const JSC::UString& title, ScriptCallStack* callStack)
{
Page* page = this->page();
if (!page)
return;
+ if (title.isNull())
+ return;
+
// FIXME: log a console message when profiling is disabled.
if (!page->inspectorController()->profilerEnabled())
return;
- UString title = args.at(exec, 0)->toString(exec);
- Profiler::profiler()->startProfiling(exec, title);
+ JSC::Profiler::profiler()->startProfiling(callStack->state(), title);
}
-void Console::profileEnd(ExecState* exec, const ArgList& args)
+void Console::profileEnd(const JSC::UString& title, ScriptCallStack* callStack)
{
Page* page = this->page();
if (!page)
@@ -346,69 +275,62 @@ void Console::profileEnd(ExecState* exec, const ArgList& args)
if (!page->inspectorController()->profilerEnabled())
return;
- UString title;
- if (args.size() >= 1)
- title = valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, 0));
-
- RefPtr<Profile> profile = Profiler::profiler()->stopProfiling(exec, title);
+ RefPtr<JSC::Profile> profile = JSC::Profiler::profiler()->stopProfiling(callStack->state(), title);
if (!profile)
return;
m_profiles.append(profile);
if (Page* page = this->page()) {
- KURL url;
- unsigned lineNumber;
- retrieveLastCaller(exec, url, lineNumber);
-
- page->inspectorController()->addProfile(profile, lineNumber, url);
+ const ScriptCallFrame& lastCaller = callStack->at(0);
+ page->inspectorController()->addProfile(profile, lastCaller.lineNumber(), lastCaller.sourceURL());
}
}
-void Console::time(const UString& title)
-{
- if (title.isNull())
- return;
+#endif
+void Console::time(const String& title)
+{
Page* page = this->page();
if (!page)
return;
+
+ // Follow Firebug's behavior of requiring a title that is not null or
+ // undefined for timing functions
+ if (title.isNull())
+ return;
page->inspectorController()->startTiming(title);
}
-void Console::timeEnd(ExecState* exec, const ArgList& args)
+void Console::timeEnd(const String& title, ScriptCallStack* callStack)
{
- UString title;
- if (args.size() >= 1)
- title = valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, 0));
- if (title.isNull())
- return;
-
Page* page = this->page();
if (!page)
return;
+ // Follow Firebug's behavior of requiring a title that is not null or
+ // undefined for timing functions
+ if (title.isNull())
+ return;
+
double elapsed;
if (!page->inspectorController()->stopTiming(title, elapsed))
return;
- String message = String(title) + String::format(": %.0fms", elapsed);
+ String message = title + String::format(": %.0fms", elapsed);
- KURL url;
- unsigned lineNumber;
- retrieveLastCaller(exec, url, lineNumber);
-
- page->inspectorController()->addMessageToConsole(JSMessageSource, LogMessageLevel, message, lineNumber, url.string());
+ const ScriptCallFrame& lastCaller = callStack->at(0);
+ page->inspectorController()->addMessageToConsole(JSMessageSource, LogMessageLevel, message, lastCaller.lineNumber(), lastCaller.sourceURL().string());
}
-void Console::group(ExecState* exec, const ArgList& arguments)
+void Console::group(ScriptCallStack* callStack)
{
Page* page = this->page();
if (!page)
return;
- page->inspectorController()->startGroup(JSMessageSource, exec, arguments, 0, String());
+ page->inspectorController()->startGroup(JSMessageSource, callStack);
}
void Console::groupEnd()
@@ -420,43 +342,9 @@ void Console::groupEnd()
page->inspectorController()->endGroup(JSMessageSource, 0, String());
}
-void Console::warn(ExecState* exec, const ArgList& args)
-{
- if (args.isEmpty())
- return;
-
- Page* page = this->page();
- if (!page)
- return;
-
- String message = args.at(exec, 0)->toString(exec);
-
- KURL url;
- unsigned lineNumber;
- retrieveLastCaller(exec, url, lineNumber);
-
- page->chrome()->client()->addMessageToConsole(message, lineNumber, url.prettyURL());
- page->inspectorController()->addMessageToConsole(JSMessageSource, WarningMessageLevel, exec, args, lineNumber, url.string());
-
- printToStandardOut(WarningMessageLevel, exec, args, url);
-}
-
-void Console::reportException(ExecState* exec, JSValue* exception)
-{
- UString errorMessage = exception->toString(exec);
- JSObject* exceptionObject = exception->toObject(exec);
- int lineNumber = exceptionObject->get(exec, Identifier(exec, "line"))->toInt32(exec);
- UString exceptionSourceURL = exceptionObject->get(exec, Identifier(exec, "sourceURL"))->toString(exec);
- addMessage(JSMessageSource, ErrorMessageLevel, errorMessage, lineNumber, exceptionSourceURL);
- if (exec->hadException())
- exec->clearException();
-}
-
-void Console::reportCurrentException(ExecState* exec)
+void Console::warn(ScriptCallStack* callStack)
{
- JSValue* exception = exec->exception();
- exec->clearException();
- reportException(exec, exception);
+ addMessage(WarningMessageLevel, callStack);
}
static bool printExceptions = false;
diff --git a/WebCore/page/Console.h b/WebCore/page/Console.h
index 8f33e96..7301fc9 100644
--- a/WebCore/page/Console.h
+++ b/WebCore/page/Console.h
@@ -30,25 +30,29 @@
#define Console_h
#include "PlatformString.h"
+
+#if USE(JSC)
#include <profiler/Profile.h>
+#endif
+
#include <wtf/RefCounted.h>
#include <wtf/PassRefPtr.h>
-namespace JSC {
- class ExecState;
- class ArgList;
-}
-
namespace WebCore {
+#if USE(JSC)
typedef Vector<RefPtr<JSC::Profile> > ProfilesArray;
+#endif
class Frame;
class Page;
class String;
+ class ScriptCallStack;
+ // Keep in sync with inspector/front-end/Console.js
enum MessageSource {
HTMLMessageSource,
+ WMLMessageSource,
XMLMessageSource,
JSMessageSource,
CSSMessageSource,
@@ -75,40 +79,42 @@ namespace WebCore {
void addMessage(MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL);
+ void debug(ScriptCallStack*);
+ void error(ScriptCallStack*);
+ void info(ScriptCallStack*);
+ void log(ScriptCallStack*);
+ void warn(ScriptCallStack*);
+ void dir(ScriptCallStack*);
+ void dirxml(ScriptCallStack*);
+ void trace(ScriptCallStack*);
+ void assertCondition(bool condition, ScriptCallStack*);
+ void count(ScriptCallStack*);
#if USE(JSC)
- void debug(JSC::ExecState*, const JSC::ArgList&);
- void error(JSC::ExecState*, const JSC::ArgList&);
- void info(JSC::ExecState*, const JSC::ArgList&);
- void log(JSC::ExecState*, const JSC::ArgList&);
- void warn(JSC::ExecState*, const JSC::ArgList&);
- void dir(JSC::ExecState*, const JSC::ArgList&);
- void dirxml(JSC::ExecState*, const JSC::ArgList& arguments);
- void trace(JSC::ExecState*);
- void assertCondition(bool condition, JSC::ExecState*, const JSC::ArgList&);
- void count(JSC::ExecState*, const JSC::ArgList&);
- void profile(JSC::ExecState*, const JSC::ArgList&);
- void profileEnd(JSC::ExecState*, const JSC::ArgList&);
- void time(const JSC::UString& title);
- void timeEnd(JSC::ExecState*, const JSC::ArgList&);
- void group(JSC::ExecState*, const JSC::ArgList&);
+ void profile(const JSC::UString&, ScriptCallStack*);
+ void profileEnd(const JSC::UString&, ScriptCallStack*);
+#endif
+ void time(const String&);
+ void timeEnd(const String&, ScriptCallStack*);
+ void group(ScriptCallStack*);
void groupEnd();
- void reportException(JSC::ExecState*, JSC::JSValue*);
- void reportCurrentException(JSC::ExecState*);
-
static bool shouldPrintExceptions();
static void setShouldPrintExceptions(bool);
+#if USE(JSC)
const ProfilesArray& profiles() const { return m_profiles; }
#endif
private:
inline Page* page() const;
+ void addMessage(MessageLevel, ScriptCallStack*, bool acceptNoArguments = false);
Console(Frame*);
Frame* m_frame;
+#if USE(JSC)
ProfilesArray m_profiles;
+#endif
};
} // namespace WebCore
diff --git a/WebCore/page/Console.idl b/WebCore/page/Console.idl
index 9075963..fb7688d 100644
--- a/WebCore/page/Console.idl
+++ b/WebCore/page/Console.idl
@@ -29,24 +29,30 @@
module window {
interface Console {
- readonly attribute [CustomGetter] Array profiles;
+
+#if !defined(V8_BINDING)
+ readonly attribute [CustomGetter] Array profiles;
+#endif
- [Custom] void debug();
- [Custom] void error();
- [Custom] void info();
- [Custom] void log();
- [Custom] void warn();
- [Custom] void dir();
- [Custom] void dirxml();
- [Custom] void trace();
- [Custom, ImplementationFunction=assertCondition] void assert(in boolean condition);
- [Custom] void count();
+ [CustomArgumentHandling] void debug();
+ [CustomArgumentHandling] void error();
+ [CustomArgumentHandling] void info();
+ [CustomArgumentHandling] void log();
+ [CustomArgumentHandling] void warn();
+ [CustomArgumentHandling] void dir();
+ [CustomArgumentHandling] void dirxml();
+ [CustomArgumentHandling] void trace();
+ [CustomArgumentHandling, ImplementationFunction=assertCondition] void assert(in boolean condition);
+ [CustomArgumentHandling] void count();
+
+#if !defined(V8_BINDING)
+ [CustomArgumentHandling] void profile(in [ConvertUndefinedOrNullToNullString] DOMString title);
+ [CustomArgumentHandling] void profileEnd(in [ConvertUndefinedOrNullToNullString] DOMString title);
+#endif
- [Custom] void profile(in DOMString title);
- [Custom] void profileEnd();
void time(in [ConvertUndefinedOrNullToNullString] DOMString title);
- [Custom] void timeEnd();
- [Custom] void group();
+ [CustomArgumentHandling] void timeEnd(in [ConvertUndefinedOrNullToNullString] DOMString title);
+ [CustomArgumentHandling] void group();
void groupEnd();
};
diff --git a/WebCore/page/ContextMenuController.cpp b/WebCore/page/ContextMenuController.cpp
index 813f8e2..47a0663 100644
--- a/WebCore/page/ContextMenuController.cpp
+++ b/WebCore/page/ContextMenuController.cpp
@@ -86,9 +86,13 @@ void ContextMenuController::handleContextMenuEvent(Event* event)
IntPoint point = IntPoint(mouseEvent->pageX(), mouseEvent->pageY());
HitTestResult result(point);
- if (Frame* frame = event->target()->toNode()->document()->frame())
+ if (Frame* frame = event->target()->toNode()->document()->frame()) {
+ float zoomFactor = frame->pageZoomFactor();
+ point.setX(static_cast<int>(point.x() * zoomFactor));
+ point.setY(static_cast<int>(point.y() * zoomFactor));
result = frame->eventHandler()->hitTestResultAtPoint(point, false);
-
+ }
+
if (!result.innerNonSharedNode())
return;
@@ -215,7 +219,7 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
case ContextMenuItemTagOpenLink:
if (Frame* targetFrame = result.targetFrame())
targetFrame->loader()->loadFrameRequestWithFormAndValues(FrameLoadRequest(ResourceRequest(result.absoluteLinkURL(),
- frame->loader()->outgoingReferrer())), false, 0, 0, HashMap<String, String>());
+ frame->loader()->outgoingReferrer())), false, false, 0, 0, HashMap<String, String>());
else
openNewWindow(result.absoluteLinkURL(), frame);
break;
@@ -255,6 +259,15 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
case ContextMenuItemTagRightToLeft:
frame->editor()->setBaseWritingDirection(RightToLeftWritingDirection);
break;
+ case ContextMenuItemTagTextDirectionDefault:
+ frame->editor()->command("MakeTextWritingDirectionNatural").execute();
+ break;
+ case ContextMenuItemTagTextDirectionLeftToRight:
+ frame->editor()->command("MakeTextWritingDirectionLeftToRight").execute();
+ break;
+ case ContextMenuItemTagTextDirectionRightToLeft:
+ frame->editor()->command("MakeTextWritingDirectionRightToLeft").execute();
+ break;
#if PLATFORM(MAC)
case ContextMenuItemTagSearchInSpotlight:
m_client->searchWithSpotlight();
diff --git a/WebCore/page/DOMTimer.cpp b/WebCore/page/DOMTimer.cpp
new file mode 100644
index 0000000..911da71
--- /dev/null
+++ b/WebCore/page/DOMTimer.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2008 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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 "DOMTimer.h"
+
+#include "Document.h"
+#include "ScheduledAction.h"
+#include "ScriptExecutionContext.h"
+#include <wtf/HashSet.h>
+#include <wtf/StdLibExtras.h>
+
+using namespace std;
+
+namespace WebCore {
+
+static const int maxTimerNestingLevel = 5;
+static const double oneMillisecond = 0.001;
+static const double minTimerInterval = 0.010; // 10 milliseconds
+
+static int timerNestingLevel = 0;
+
+DOMTimer::DOMTimer(ScriptExecutionContext* context, ScheduledAction* action, int timeout, bool singleShot)
+ : ActiveDOMObject(context, this)
+ , m_action(action)
+ , m_nextFireInterval(0)
+ , m_repeatInterval(0)
+{
+ static int lastUsedTimeoutId = 0;
+ ++lastUsedTimeoutId;
+ // Avoid wraparound going negative on us.
+ if (lastUsedTimeoutId <= 0)
+ lastUsedTimeoutId = 1;
+ m_timeoutId = lastUsedTimeoutId;
+
+ m_nestingLevel = timerNestingLevel + 1;
+
+ // FIXME: Move the timeout map and API to ScriptExecutionContext to be able
+ // to create timeouts from Workers.
+ ASSERT(scriptExecutionContext() && scriptExecutionContext()->isDocument());
+ static_cast<Document*>(scriptExecutionContext())->addTimeout(m_timeoutId, this);
+
+ double intervalMilliseconds = max(oneMillisecond, timeout * oneMillisecond);
+
+ // Use a minimum interval of 10 ms to match other browsers, but only once we've
+ // nested enough to notice that we're repeating.
+ // Faster timers might be "better", but they're incompatible.
+ if (intervalMilliseconds < minTimerInterval && m_nestingLevel >= maxTimerNestingLevel)
+ intervalMilliseconds = minTimerInterval;
+ if (singleShot)
+ startOneShot(intervalMilliseconds);
+ else
+ startRepeating(intervalMilliseconds);
+}
+
+DOMTimer::~DOMTimer()
+{
+ if (scriptExecutionContext()) {
+ ASSERT(scriptExecutionContext()->isDocument());
+ static_cast<Document*>(scriptExecutionContext())->removeTimeout(m_timeoutId);
+ }
+}
+
+int DOMTimer::install(ScriptExecutionContext* context, ScheduledAction* action, int timeout, bool singleShot)
+{
+ // DOMTimer constructor links the new timer into a list of ActiveDOMObjects held by the 'context'.
+ // The timer is deleted when context is deleted (DOMTimer::contextDestroyed) or explicitly via DOMTimer::removeById(),
+ // or if it is a one-time timer and it has fired (DOMTimer::fired).
+ DOMTimer* timer = new DOMTimer(context, action, timeout, singleShot);
+ return timer->m_timeoutId;
+}
+
+void DOMTimer::removeById(ScriptExecutionContext* context, int timeoutId)
+{
+ // timeout IDs have to be positive, and 0 and -1 are unsafe to
+ // even look up since they are the empty and deleted value
+ // respectively
+ if (timeoutId <= 0)
+ return;
+ ASSERT(context && context->isDocument());
+ delete static_cast<Document*>(context)->findTimeout(timeoutId);
+}
+
+void DOMTimer::fired()
+{
+ ScriptExecutionContext* context = scriptExecutionContext();
+ timerNestingLevel = m_nestingLevel;
+
+ // Simple case for non-one-shot timers.
+ if (isActive()) {
+ if (repeatInterval() && repeatInterval() < minTimerInterval) {
+ m_nestingLevel++;
+ if (m_nestingLevel >= maxTimerNestingLevel)
+ augmentRepeatInterval(minTimerInterval - repeatInterval());
+ }
+
+ // No access to member variables after this point, it can delete the timer.
+ m_action->execute(context);
+ return;
+ }
+
+ // Delete timer before executing the action for one-shot timers.
+ ScheduledAction* action = m_action.release();
+
+ // No access to member variables after this point.
+ delete this;
+
+ action->execute(context);
+ delete action;
+ timerNestingLevel = 0;
+}
+
+bool DOMTimer::hasPendingActivity() const
+{
+ return isActive();
+}
+
+void DOMTimer::contextDestroyed()
+{
+ ActiveDOMObject::contextDestroyed();
+ delete this;
+}
+
+void DOMTimer::stop()
+{
+ TimerBase::stop();
+ // Need to release JS objects potentially protected by ScheduledAction
+ // because they can form circular references back to the ScriptExecutionContext
+ // which will cause a memory leak.
+ m_action.clear();
+}
+
+void DOMTimer::suspend()
+{
+ ASSERT(m_nextFireInterval == 0 && m_repeatInterval == 0);
+ m_nextFireInterval = nextFireInterval();
+ m_repeatInterval = repeatInterval();
+ TimerBase::stop();
+}
+
+void DOMTimer::resume()
+{
+ start(m_nextFireInterval, m_repeatInterval);
+ m_nextFireInterval = 0;
+ m_repeatInterval = 0;
+}
+
+
+bool DOMTimer::canSuspend() const
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/DOMTimer.h b/WebCore/page/DOMTimer.h
new file mode 100644
index 0000000..200b9b1
--- /dev/null
+++ b/WebCore/page/DOMTimer.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2008 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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.
+ *
+ */
+
+#ifndef DOMTimer_h
+#define DOMTimer_h
+
+#include "ActiveDOMObject.h"
+#include "Timer.h"
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+class ScheduledAction;
+
+class DOMTimer : public TimerBase, public ActiveDOMObject {
+public:
+ virtual ~DOMTimer();
+ // Creates a new timer owned by specified ScriptExecutionContext, starts it
+ // and returns its Id.
+ static int install(ScriptExecutionContext*, ScheduledAction*, int timeout, bool singleShot);
+ static void removeById(ScriptExecutionContext*, int timeoutId);
+
+ // ActiveDOMObject
+ virtual bool hasPendingActivity() const;
+ virtual void contextDestroyed();
+ virtual void stop();
+ virtual bool canSuspend() const;
+ virtual void suspend();
+ virtual void resume();
+
+private:
+ DOMTimer(ScriptExecutionContext*, ScheduledAction*, int timeout, bool singleShot);
+ virtual void fired();
+
+ int m_timeoutId;
+ int m_nestingLevel;
+ OwnPtr<ScheduledAction> m_action;
+ double m_nextFireInterval;
+ double m_repeatInterval;
+};
+
+} // namespace WebCore
+
+#endif // DOMTimer_h
+
diff --git a/WebCore/page/DOMWindow.cpp b/WebCore/page/DOMWindow.cpp
index 4ab69ca..70ee79e 100644
--- a/WebCore/page/DOMWindow.cpp
+++ b/WebCore/page/DOMWindow.cpp
@@ -55,6 +55,7 @@
#include "PlatformString.h"
#include "Screen.h"
#include "SecurityOrigin.h"
+#include "Settings.h"
#include <algorithm>
#include <wtf/MathExtras.h>
@@ -339,9 +340,13 @@ Storage* DOMWindow::localStorage() const
Page* page = document->page();
if (!page)
return 0;
-
+
+ Settings* settings = document->settings();
+ if (!settings || !settings->localStorageEnabled())
+ return 0;
+
LocalStorage* localStorage = page->group().localStorage();
- RefPtr<StorageArea> storageArea = localStorage ? localStorage->storageArea(m_frame, document->securityOrigin()) : 0;
+ RefPtr<StorageArea> storageArea = localStorage ? localStorage->storageArea(document->securityOrigin()) : 0;
if (storageArea)
m_localStorage = Storage::create(m_frame, storageArea.release());
@@ -358,7 +363,7 @@ void DOMWindow::postMessage(const String& message, MessagePort* messagePort, con
// to generate the SYNTAX_ERR exception correctly.
RefPtr<SecurityOrigin> target;
if (targetOrigin != "*") {
- target = SecurityOrigin::create(KURL(targetOrigin));
+ target = SecurityOrigin::createFromString(targetOrigin);
if (target->isEmpty()) {
ec = SYNTAX_ERR;
return;
@@ -367,7 +372,7 @@ void DOMWindow::postMessage(const String& message, MessagePort* messagePort, con
RefPtr<MessagePort> newMessagePort;
if (messagePort)
- newMessagePort = messagePort->clone(document(), ec);
+ newMessagePort = messagePort->clone(ec);
if (ec)
return;
@@ -400,6 +405,11 @@ void DOMWindow::postMessageTimerFired(PostMessageTimer* t)
}
}
+ MessagePort* messagePort = timer->event()->messagePort();
+ ASSERT(!messagePort || !messagePort->scriptExecutionContext());
+ if (messagePort)
+ messagePort->attachToContext(document());
+
document()->dispatchWindowEvent(timer->event());
}
@@ -520,7 +530,7 @@ String DOMWindow::prompt(const String& message, const String& defaultValue)
return String();
}
-bool DOMWindow::find(const String& string, bool caseSensitive, bool backwards, bool wrap, bool wholeWord, bool searchInFrames, bool showDialog) const
+bool DOMWindow::find(const String& string, bool caseSensitive, bool backwards, bool wrap, bool /*wholeWord*/, bool /*searchInFrames*/, bool /*showDialog*/) const
{
if (!m_frame)
return false;
@@ -808,6 +818,10 @@ PassRefPtr<Database> DOMWindow::openDatabase(const String& name, const String& v
if (!doc)
return 0;
+ Settings* settings = m_frame->settings();
+ if (!settings || !settings->databasesEnabled())
+ return 0;
+
return Database::openDatabase(doc, name, version, displayName, estimatedSize, ec);
}
#endif
diff --git a/WebCore/page/DOMWindow.idl b/WebCore/page/DOMWindow.idl
index ce519b5..78c780f 100644
--- a/WebCore/page/DOMWindow.idl
+++ b/WebCore/page/DOMWindow.idl
@@ -38,6 +38,7 @@ module window {
CustomMarkFunction,
CustomNativeConverter,
CustomPutFunction,
+ ExtendsDOMGlobalObject,
GenerateNativeConverter,
LegacyParent=JSDOMWindowBase
] DOMWindow {
@@ -226,6 +227,7 @@ module window {
attribute CSSValueConstructor CSSValue;
attribute CSSPrimitiveValueConstructor CSSPrimitiveValue;
attribute CSSValueListConstructor CSSValueList;
+ attribute WebKitCSSTransformValueConstructor WebKitCSSTransformValue;
attribute CSSRuleConstructor CSSRule;
attribute CSSCharsetRuleConstructor CSSCharsetRule;
@@ -247,7 +249,7 @@ module window {
// FIXME: Implement the commented-out global constructors for interfaces listed in DOM Level 3 Core specification.
attribute DOMCoreExceptionConstructor DOMException;
-// attribute DOMStringListConstructor DOMStringList;
+ attribute DOMStringListConstructor DOMStringList;
// attribute NameListConstructor NameList;
// attribute DOMImplementationListConstructor DOMImplementationList;
// attribute DOMImplementationSourceConstructor DOMImplementationSource;
@@ -348,6 +350,8 @@ module window {
attribute ProgressEventConstructor ProgressEvent;
attribute TextEventConstructor TextEvent;
attribute UIEventConstructor UIEvent;
+ attribute WebKitAnimationEventConstructor WebKitAnimationEvent;
+ attribute WebKitTransitionEventConstructor WebKitTransitionEvent;
attribute WheelEventConstructor WheelEvent;
attribute MessageEventConstructor MessageEvent;
attribute EventExceptionConstructor EventException;
@@ -355,7 +359,12 @@ module window {
attribute TouchEventConstructor TouchEvent;
#endif
+ attribute WebKitCSSKeyframeRuleConstructor WebKitCSSKeyframeRule;
+ attribute WebKitCSSKeyframesRuleConstructor WebKitCSSKeyframesRule;
+
+#if ENABLE_CHANNEL_MESSAGING
attribute MessagePortConstructor MessagePort;
+#endif
attribute ClipboardConstructor Clipboard;
@@ -376,6 +385,12 @@ module window {
attribute XMLHttpRequestUploadConstructor XMLHttpRequestUpload;
attribute XMLHttpRequestExceptionConstructor XMLHttpRequestException;
+ attribute PluginConstructor Plugin;
+ attribute PluginArrayConstructor PluginArray;
+
+ attribute MimeTypeConstructor MimeType;
+ attribute MimeTypeArrayConstructor MimeTypeArray;
+
#if ENABLE_DOM_STORAGE
attribute StorageConstructor Storage;
attribute StorageEventConstructor StorageEvent;
diff --git a/WebCore/page/DragController.cpp b/WebCore/page/DragController.cpp
index 268397e..9911f34 100644
--- a/WebCore/page/DragController.cpp
+++ b/WebCore/page/DragController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -57,10 +57,10 @@
#include "ResourceRequest.h"
#include "SelectionController.h"
#include "Settings.h"
-#include "SystemTime.h"
#include "Text.h"
#include "htmlediting.h"
#include "markup.h"
+#include <wtf/CurrentTime.h>
#include <wtf/RefPtr.h>
namespace WebCore {
@@ -126,11 +126,9 @@ static PassRefPtr<DocumentFragment> documentFragmentFromDragData(DragData* dragD
return 0;
}
-bool DragController::dragIsMove(SelectionController* selection, DragData* dragData)
+bool DragController::dragIsMove(SelectionController* selection)
{
- return m_document == m_dragInitiator
- && selection->isContentEditable()
- && !isCopyKeyDown();
+ return m_document == m_dragInitiator && selection->isContentEditable() && !isCopyKeyDown();
}
void DragController::cancelDrag()
@@ -191,7 +189,7 @@ bool DragController::performDrag(DragData* dragData)
return true;
}
- if ((m_dragDestinationAction & DragDestinationActionEdit) && concludeDrag(dragData, m_dragDestinationAction)) {
+ if ((m_dragDestinationAction & DragDestinationActionEdit) && concludeEditDrag(dragData)) {
m_document = 0;
return true;
}
@@ -202,7 +200,7 @@ bool DragController::performDrag(DragData* dragData)
return false;
m_client->willPerformDragDestinationAction(DragDestinationActionLoad, dragData);
- m_page->mainFrame()->loader()->load(ResourceRequest(dragData->asURL()));
+ m_page->mainFrame()->loader()->load(ResourceRequest(dragData->asURL()), false);
return true;
}
@@ -288,7 +286,7 @@ DragOperation DragController::tryDocumentDrag(DragData* dragData, DragDestinatio
m_page->dragCaretController()->setSelection(dragCaret);
}
- return dragIsMove(innerFrame->selection(), dragData) ? DragOperationMove : DragOperationCopy;
+ return dragIsMove(innerFrame->selection()) ? DragOperationMove : DragOperationCopy;
}
m_page->dragCaretController()->clear();
@@ -322,11 +320,10 @@ static bool setSelectionToDragCaret(Frame* frame, Selection& dragCaret, RefPtr<R
return !frame->selection()->isNone() && frame->selection()->isContentEditable();
}
-bool DragController::concludeDrag(DragData* dragData, DragDestinationAction actionMask)
+bool DragController::concludeEditDrag(DragData* dragData)
{
ASSERT(dragData);
ASSERT(!m_isHandlingDrag);
- ASSERT(actionMask & DragDestinationActionEdit);
if (!m_document)
return false;
@@ -394,7 +391,7 @@ bool DragController::concludeDrag(DragData* dragData, DragDestinationAction acti
return false;
DocLoader* loader = range->ownerDocument()->docLoader();
loader->setAllowStaleResources(true);
- if (dragIsMove(innerFrame->selection(), dragData) || dragCaret.isContentRichlyEditable()) {
+ if (dragIsMove(innerFrame->selection()) || dragCaret.isContentRichlyEditable()) {
bool chosePlainText = false;
RefPtr<DocumentFragment> fragment = documentFragmentFromDragData(dragData, range, true, chosePlainText);
if (!fragment || !innerFrame->editor()->shouldInsertFragment(fragment, range, EditorInsertActionDropped)) {
@@ -403,7 +400,7 @@ bool DragController::concludeDrag(DragData* dragData, DragDestinationAction acti
}
m_client->willPerformDragDestinationAction(DragDestinationActionEdit, dragData);
- if (dragIsMove(innerFrame->selection(), dragData)) {
+ if (dragIsMove(innerFrame->selection())) {
bool smartMove = innerFrame->selectionGranularity() == WordGranularity
&& innerFrame->editor()->smartInsertDeleteEnabled()
&& dragData->canSmartReplace();
@@ -579,7 +576,7 @@ static IntPoint dragLocForDHTMLDrag(const IntPoint& mouseDraggedPoint, const Int
static IntPoint dragLocForSelectionDrag(Frame* src)
{
- IntRect draggingRect = enclosingIntRect(src->selectionRect());
+ IntRect draggingRect = enclosingIntRect(src->selectionBounds());
int xpos = draggingRect.right();
xpos = draggingRect.x() < xpos ? draggingRect.x() : xpos;
int ypos = draggingRect.bottom();
@@ -629,9 +626,12 @@ bool DragController::startDrag(Frame* src, Clipboard* clipboard, DragOperation s
Node* node = dragSource.innerNonSharedNode();
- if (!imageURL.isEmpty() && node && node->isElementNode()
- && getImage(static_cast<Element*>(node))
+ Image* image = getImage(static_cast<Element*>(node));
+ if (!imageURL.isEmpty() && node && node->isElementNode() && image
&& (m_dragSourceAction & DragSourceActionImage)) {
+ // We shouldn't be starting a drag for an image that can't provide an extension.
+ // This is an early detection for problems encountered later upon drop.
+ ASSERT(!image->filenameExtension().isEmpty());
Element* element = static_cast<Element*>(node);
if (!clipboard->hasData()) {
m_draggingImageURL = imageURL;
@@ -698,7 +698,7 @@ bool DragController::startDrag(Frame* src, Clipboard* clipboard, DragOperation s
deleteDragImage(dragImage);
return startedDrag;
}
-
+
void DragController::doImageDrag(Element* element, const IntPoint& dragOrigin, const IntRect& rect, Clipboard* clipboard, Frame* frame, IntPoint& dragImageOffset)
{
IntPoint mouseDownPoint = dragOrigin;
@@ -750,11 +750,7 @@ void DragController::doSystemDrag(DragImageRef image, const IntPoint& dragLoc, c
m_client->startDrag(image, viewProtector->windowToContents(frame->view()->contentsToWindow(dragLoc)),
viewProtector->windowToContents(frame->view()->contentsToWindow(eventPos)), clipboard, frameProtector.get(), forLink);
- // Drag has ended, dragEnded *should* have been called, however it is possible
- // for the UIDelegate to take over the drag, and fail to send the appropriate
- // drag termination event. As dragEnded just resets drag variables, we just
- // call it anyway to be on the safe side
- dragEnded();
+ cleanupAfterSystemDrag();
}
// Manual drag caret manipulation
diff --git a/WebCore/page/DragController.h b/WebCore/page/DragController.h
index efa8292..3beff5a 100644
--- a/WebCore/page/DragController.h
+++ b/WebCore/page/DragController.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,7 +29,6 @@
#include "DragActions.h"
#include "DragImage.h"
#include "IntPoint.h"
-#include "IntRect.h"
#include "KURL.h"
namespace WebCore {
@@ -41,6 +40,7 @@ namespace WebCore {
class Element;
class Frame;
class Image;
+ class IntRect;
class Node;
class Page;
class PlatformMouseEvent;
@@ -58,8 +58,8 @@ namespace WebCore {
DragOperation dragUpdated(DragData*);
bool performDrag(DragData*);
- //FIXME: It should be possible to remove a number of these accessors once all
- //drag logic is in WebCore
+ // FIXME: It should be possible to remove a number of these accessors once all
+ // drag logic is in WebCore.
void setDidInitiateDrag(bool initiated) { m_didInitiateDrag = initiated; }
bool didInitiateDrag() const { return m_didInitiateDrag; }
void setIsHandlingDrag(bool handling) { m_isHandlingDrag = handling; }
@@ -73,7 +73,7 @@ namespace WebCore {
void setDragOffset(const IntPoint& offset) { m_dragOffset = offset; }
const IntPoint& dragOffset() const { return m_dragOffset; }
DragSourceAction dragSourceAction() const { return m_dragSourceAction; }
-
+
Document* document() const { return m_document; }
DragDestinationAction dragDestinationAction() const { return m_dragDestinationAction; }
DragSourceAction delegateDragSourceAction(const IntPoint& pagePoint);
@@ -91,30 +91,30 @@ namespace WebCore {
static const int DragIconRightInset;
static const int DragIconBottomInset;
static const float DragImageAlpha;
+
private:
bool canProcessDrag(DragData*);
- bool concludeDrag(DragData*, DragDestinationAction);
+ bool concludeEditDrag(DragData*);
DragOperation dragEnteredOrUpdated(DragData*);
DragOperation operationForLoad(DragData*);
DragOperation tryDocumentDrag(DragData*, DragDestinationAction);
DragOperation tryDHTMLDrag(DragData*);
DragOperation dragOperation(DragData*);
void cancelDrag();
- bool dragIsMove(SelectionController*, DragData*);
+ bool dragIsMove(SelectionController*);
bool isCopyKeyDown();
IntRect selectionDraggingRect(Frame*);
bool doDrag(Frame* src, Clipboard* clipboard, DragImageRef dragImage, const KURL& linkURL, const KURL& imageURL, Node* node, IntPoint& dragLoc, IntPoint& dragImageOffset);
void doImageDrag(Element*, const IntPoint&, const IntRect&, Clipboard*, Frame*, IntPoint&);
void doSystemDrag(DragImageRef, const IntPoint&, const IntPoint&, Clipboard*, Frame*, bool forLink);
+ void cleanupAfterSystemDrag();
+
Page* m_page;
DragClient* m_client;
- //The Document the mouse was last dragged over
- Document* m_document;
-
- //The Document (if any) that initiated the drag
- Document* m_dragInitiator;
+ Document* m_document; // The document the mouse was last dragged over.
+ Document* m_dragInitiator; // The Document (if any) that initiated the drag.
DragDestinationAction m_dragDestinationAction;
DragSourceAction m_dragSourceAction;
diff --git a/WebCore/page/EditorClient.h b/WebCore/page/EditorClient.h
index b36709f..56d0435 100644
--- a/WebCore/page/EditorClient.h
+++ b/WebCore/page/EditorClient.h
@@ -69,6 +69,7 @@ public:
virtual bool shouldDeleteRange(Range*) = 0;
virtual bool shouldShowDeleteInterface(HTMLElement*) = 0;
virtual bool smartInsertDeleteEnabled() = 0;
+ virtual bool isSelectTrailingWhitespaceEnabled() = 0;
virtual bool isContinuousSpellCheckingEnabled() = 0;
virtual void toggleContinuousSpellChecking() = 0;
virtual bool isGrammarCheckingEnabled() = 0;
diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp
index 3f45b92..32648cc 100644
--- a/WebCore/page/EventHandler.cpp
+++ b/WebCore/page/EventHandler.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
*
* Redistribution and use in source and binary forms, with or without
@@ -63,6 +63,7 @@
#include "SelectionController.h"
#include "Settings.h"
#include "TextEvent.h"
+#include <wtf/StdLibExtras.h>
#if ENABLE(SVG)
#include "SVGDocument.h"
@@ -106,15 +107,19 @@ static inline void scrollAndAcceptEvent(float delta, ScrollDirection positiveDir
{
if (!delta)
return;
+
+ // Find the nearest enclosing box.
+ RenderBox* enclosingBox = node->renderer()->enclosingBox();
+
if (e.granularity() == ScrollByPageWheelEvent) {
- if (node->renderer()->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPage, 1))
+ if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPage, 1))
e.accept();
return;
}
float pixelsToScroll = delta > 0 ? delta : -delta;
if (e.granularity() == ScrollByLineWheelEvent)
pixelsToScroll *= cMouseWheelPixelsPerLineStep;
- if (node->renderer()->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPixel, pixelsToScroll))
+ if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPixel, pixelsToScroll))
e.accept();
}
@@ -155,7 +160,7 @@ EventHandler::~EventHandler()
EventHandler::EventHandlerDragState& EventHandler::dragState()
{
- static EventHandlerDragState state;
+ DEFINE_STATIC_LOCAL(EventHandlerDragState, state, ());
return state;
}
@@ -199,6 +204,8 @@ void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestRe
if (newSelection.isRange()) {
m_frame->setSelectionGranularity(WordGranularity);
m_beganSelectingText = true;
+ if (result.event().clickCount() == 2 && m_frame->editor()->isSelectTrailingWhitespaceEnabled())
+ newSelection.appendTrailingWhitespace();
}
if (m_frame->shouldChangeSelection(newSelection))
@@ -381,8 +388,8 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve
swallowEvent = handleMousePressEventSingleClick(event);
}
- m_mouseDownMayStartAutoscroll = m_mouseDownMayStartSelect ||
- (m_mousePressNode && m_mousePressNode->renderer() && m_mousePressNode->renderer()->canBeProgramaticallyScrolled(true));
+ m_mouseDownMayStartAutoscroll = m_mouseDownMayStartSelect ||
+ (m_mousePressNode && m_mousePressNode->renderBox() && m_mousePressNode->renderBox()->canBeProgramaticallyScrolled(true));
return swallowEvent;
}
@@ -409,7 +416,7 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e
// If the selection is contained in a layer that can scroll, that layer should handle the autoscroll
// Otherwise, let the bridge handle it so the view can scroll itself.
RenderObject* renderer = targetNode->renderer();
- while (renderer && !renderer->canBeProgramaticallyScrolled(false)) {
+ while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeProgramaticallyScrolled(false))) {
if (!renderer->parent() && renderer->node() == renderer->document() && renderer->document()->ownerElement())
renderer = renderer->document()->ownerElement()->renderer();
else
@@ -456,7 +463,7 @@ void EventHandler::updateSelectionForMouseDrag()
FrameView* view = m_frame->view();
if (!view)
return;
- RenderObject* renderer = m_frame->contentRenderer();
+ RenderView* renderer = m_frame->contentRenderer();
if (!renderer)
return;
RenderLayer* layer = renderer->layer();
@@ -599,7 +606,7 @@ void EventHandler::handleAutoscroll(RenderObject* renderer)
void EventHandler::autoscrollTimerFired(Timer<EventHandler>*)
{
RenderObject* r = autoscrollRenderer();
- if (!r) {
+ if (!r || !r->isBox()) {
stopAutoscrollTimer();
return;
}
@@ -609,7 +616,7 @@ void EventHandler::autoscrollTimerFired(Timer<EventHandler>*)
stopAutoscrollTimer();
return;
}
- r->autoscroll();
+ toRenderBox(r)->autoscroll();
} else {
// we verify that the main frame hasn't received the order to stop the panScroll
if (!m_frame->page()->mainFrame()->eventHandler()->panScrollInProgress()) {
@@ -618,7 +625,7 @@ void EventHandler::autoscrollTimerFired(Timer<EventHandler>*)
}
#if ENABLE(PAN_SCROLLING)
setPanScrollCursor();
- r->panScroll(m_panScrollStartPos);
+ toRenderBox(r)->panScroll(m_panScrollStartPos);
#endif
}
}
@@ -670,7 +677,7 @@ void EventHandler::updateAutoscrollRenderer()
if (Node* nodeAtPoint = hitTest.innerNode())
m_autoscrollRenderer = nodeAtPoint->renderer();
- while (m_autoscrollRenderer && !m_autoscrollRenderer->canBeProgramaticallyScrolled(false))
+ while (m_autoscrollRenderer && (!m_autoscrollRenderer->isBox() || !toRenderBox(m_autoscrollRenderer)->canBeProgramaticallyScrolled(false)))
m_autoscrollRenderer = m_autoscrollRenderer->parent();
}
@@ -703,15 +710,16 @@ HitTestResult EventHandler::hitTestResultAtPoint(const IntPoint& point, bool all
Node* n = result.innerNode();
if (!result.isOverWidget() || !n || !n->renderer() || !n->renderer()->isWidget())
break;
- Widget* widget = static_cast<RenderWidget*>(n->renderer())->widget();
+ RenderWidget* renderWidget = static_cast<RenderWidget*>(n->renderer());
+ Widget* widget = renderWidget->widget();
if (!widget || !widget->isFrameView())
break;
Frame* frame = static_cast<HTMLFrameElementBase*>(n)->contentFrame();
if (!frame || !frame->contentRenderer())
break;
FrameView* view = static_cast<FrameView*>(widget);
- IntPoint widgetPoint(result.localPoint().x() + view->scrollX() - n->renderer()->borderLeft() - n->renderer()->paddingLeft(),
- result.localPoint().y() + view->scrollY() - n->renderer()->borderTop() - n->renderer()->paddingTop());
+ IntPoint widgetPoint(result.localPoint().x() + view->scrollX() - renderWidget->borderLeft() - renderWidget->paddingLeft(),
+ result.localPoint().y() + view->scrollY() - renderWidget->borderTop() - renderWidget->paddingTop());
HitTestResult widgetHitTestResult(widgetPoint);
frame->contentRenderer()->layer()->hitTest(HitTestRequest(true, true), widgetHitTestResult);
result = widgetHitTestResult;
@@ -751,7 +759,7 @@ void EventHandler::stopAutoscrollTimer(bool rendererIsBeingDestroyed)
if (autoscrollRenderer()) {
if (!rendererIsBeingDestroyed && (m_autoscrollInProgress || m_panScrollInProgress))
- autoscrollRenderer()->stopAutoscroll();
+ toRenderBox(autoscrollRenderer())->stopAutoscroll();
#if ENABLE(PAN_SCROLLING)
if (m_panScrollInProgress) {
m_frame->view()->removePanScrollIcon();
@@ -791,9 +799,9 @@ bool EventHandler::scrollOverflow(ScrollDirection direction, ScrollGranularity g
node = m_mousePressNode.get();
if (node) {
- RenderObject *r = node->renderer();
+ RenderObject* r = node->renderer();
if (r && !r->isListBox())
- return r->scroll(direction, granularity);
+ return r->enclosingBox()->scroll(direction, granularity);
}
return false;
@@ -1044,7 +1052,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
if (mouseEvent.button() == MiddleButton && !mev.isOverLink()) {
RenderObject* renderer = mev.targetNode()->renderer();
- while (renderer && !renderer->canBeProgramaticallyScrolled(false)) {
+ while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeProgramaticallyScrolled(false))) {
if (!renderer->parent() && renderer->node() == renderer->document() && renderer->document()->ownerElement())
renderer = renderer->document()->ownerElement()->renderer();
else
@@ -1524,7 +1532,7 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
}
}
-bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targetNode, bool cancelable, int clickCount, const PlatformMouseEvent& mouseEvent, bool setUnder)
+bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targetNode, bool /*cancelable*/, int clickCount, const PlatformMouseEvent& mouseEvent, bool setUnder)
{
updateMouseEventTargetNode(targetNode, mouseEvent, setUnder);
@@ -1584,12 +1592,14 @@ bool EventHandler::handleWheelEvent(PlatformWheelEvent& e)
RenderObject* docRenderer = doc->renderer();
if (!docRenderer)
return false;
+
+ RefPtr<FrameView> protector(m_frame->view());
IntPoint vPoint = m_frame->view()->windowToContents(e.pos());
HitTestRequest request(true, false);
HitTestResult result(vPoint);
- doc->renderer()->layer()->hitTest(request, result);
+ doc->renderView()->layer()->hitTest(request, result);
Node* node = result.innerNode();
if (node) {
@@ -1635,8 +1645,10 @@ bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
IntPoint viewportPos = v->windowToContents(event.pos());
MouseEventWithHitTestResults mev = doc->prepareMouseEvent(HitTestRequest(false, true), viewportPos, event);
- // Context menu events shouldn't select text in GTK+ applications.
-#if !PLATFORM(GTK)
+ // Context menu events shouldn't select text in GTK+ applications or in Chromium.
+ // FIXME: This should probably be configurable by embedders. Consider making it a WebPreferences setting.
+ // See: https://bugs.webkit.org/show_bug.cgi?id=15279
+#if !PLATFORM(GTK) && !PLATFORM(CHROMIUM)
if (!m_frame->selection()->contains(viewportPos) &&
// FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse.
// If the selection is non-editable, we do word selection to make it easier to use the contextual menu items
@@ -1705,7 +1717,7 @@ void EventHandler::hoverTimerFired(Timer<EventHandler>*)
ASSERT(m_frame);
ASSERT(m_frame->document());
- if (RenderObject* renderer = m_frame->contentRenderer()) {
+ if (RenderView* renderer = m_frame->contentRenderer()) {
HitTestResult result(m_frame->view()->windowToContents(m_currentMousePosition));
renderer->layer()->hitTest(HitTestRequest(false, false, true), result);
m_frame->document()->updateRendering();
@@ -1730,7 +1742,12 @@ static EventTargetNode* eventTargetNodeForDocument(Document* doc)
bool EventHandler::handleAccessKey(const PlatformKeyboardEvent& evt)
{
- if ((evt.modifiers() & s_accessKeyModifiers) != s_accessKeyModifiers)
+ // FIXME: Ignoring the state of Shift key is what neither IE nor Firefox do.
+ // IE matches lower and upper case access keys regardless of Shift key state - but if both upper and
+ // lower case variants are present in a document, the correct element is matched based on Shift key state.
+ // Firefox only matches an access key if Shift is not pressed, and does that case-insensitively.
+ ASSERT(!(accessKeyModifiers() & PlatformKeyboardEvent::ShiftKey));
+ if ((evt.modifiers() & ~PlatformKeyboardEvent::ShiftKey) != accessKeyModifiers())
return false;
String key = evt.unmodifiedText();
Element* elem = m_frame->document()->getElementByAccessKey(key.lower());
@@ -1888,6 +1905,8 @@ void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event)
m_frame->editor()->handleKeyboardEvent(event);
if (event->defaultHandled())
return;
+ if (event->charCode() == ' ')
+ defaultSpaceEventHandler(event);
}
}
@@ -2031,10 +2050,10 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event)
// Check to see if the is a DOM based drag, if it is get the DOM specified drag
// image and offset
if (dragState().m_dragSrcIsDHTML) {
- int srcX, srcY;
if (RenderObject* renderer = dragState().m_dragSrc->renderer()) {
- renderer->absolutePosition(srcX, srcY);
- IntSize delta = m_mouseDownPos - IntPoint(srcX, srcY);
+ // FIXME: This doesn't work correctly with transforms.
+ FloatPoint absPos = renderer->localToAbsolute();
+ IntSize delta = m_mouseDownPos - roundedIntPoint(absPos);
dragState().m_dragClipboard->setDragImageElement(dragState().m_dragSrc.get(), IntPoint() + delta);
} else {
// The renderer has disappeared, this can happen if the onStartDrag handler has hidden
@@ -2083,17 +2102,15 @@ cleanupDrag:
return true;
}
-bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEvent,
- bool isLineBreak, bool isBackTab)
+bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEvent, bool isLineBreak, bool isBackTab)
{
- if (!m_frame)
- return false;
-#ifndef NDEBUG
// Platforms should differentiate real commands like selectAll from text input in disguise (like insertNewline),
// and avoid dispatching text input events from keydown default handlers.
- if (underlyingEvent && underlyingEvent->isKeyboardEvent())
- ASSERT(static_cast<KeyboardEvent*>(underlyingEvent)->type() == eventNames().keypressEvent);
-#endif
+ ASSERT(!underlyingEvent || !underlyingEvent->isKeyboardEvent() || static_cast<KeyboardEvent*>(underlyingEvent)->type() == eventNames().keypressEvent);
+
+ if (!m_frame)
+ return false;
+
EventTarget* target;
if (underlyingEvent)
target = underlyingEvent->target();
@@ -2101,12 +2118,14 @@ bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEve
target = eventTargetNodeForDocument(m_frame->document());
if (!target)
return false;
+
RefPtr<TextEvent> event = TextEvent::create(m_frame->domWindow(), text);
event->setUnderlyingEvent(underlyingEvent);
event->setIsLineBreak(isLineBreak);
event->setIsBackTab(isBackTab);
ExceptionCode ec;
- return target->dispatchEvent(event.release(), ec);
+ target->dispatchEvent(event, ec);
+ return event->defaultHandled();
}
@@ -2146,6 +2165,36 @@ void EventHandler::defaultTextInputEventHandler(TextEvent* event)
}
}
+#if PLATFORM(QT) || PLATFORM(MAC)
+
+// These two platforms handle the space event in the platform-specific WebKit code.
+// Eventually it would be good to eliminate that and use the code here instead, but
+// the Qt version is inside an ifdef and the Mac version has some extra behavior
+// so we can't unify everything yet.
+void EventHandler::defaultSpaceEventHandler(KeyboardEvent*)
+{
+}
+
+#else
+
+void EventHandler::defaultSpaceEventHandler(KeyboardEvent* event)
+{
+ ScrollDirection direction = event->shiftKey() ? ScrollUp : ScrollDown;
+ if (scrollOverflow(direction, ScrollByPage)) {
+ event->setDefaultHandled();
+ return;
+ }
+
+ FrameView* view = m_frame->view();
+ if (!view)
+ return;
+
+ if (view->scroll(direction, ScrollByPage))
+ event->setDefaultHandled();
+}
+
+#endif
+
void EventHandler::defaultTabEventHandler(KeyboardEvent* event)
{
// We should only advance focus on tabs if no special modifier keys are held down.
diff --git a/WebCore/page/EventHandler.h b/WebCore/page/EventHandler.h
index 8035494..944bbd3 100644
--- a/WebCore/page/EventHandler.h
+++ b/WebCore/page/EventHandler.h
@@ -148,7 +148,7 @@ public:
bool needsKeyboardEventDisambiguationQuirks() const;
- static unsigned accessKeyModifiers() { return s_accessKeyModifiers; }
+ static unsigned accessKeyModifiers();
bool handleAccessKey(const PlatformKeyboardEvent&);
bool keyEvent(const PlatformKeyboardEvent&);
void defaultKeyboardEventHandler(KeyboardEvent*);
@@ -273,6 +273,7 @@ private:
bool passMouseDownEventToWidget(Widget*);
bool passWheelEventToWidget(PlatformWheelEvent&, Widget*);
+ void defaultSpaceEventHandler(KeyboardEvent*);
void defaultTabEventHandler(KeyboardEvent*);
void allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const;
@@ -339,14 +340,12 @@ private:
RefPtr<HTMLFrameSetElement> m_frameSetBeingResized;
- IntSize m_offsetFromResizeCorner;
+ IntSize m_offsetFromResizeCorner; // in the coords of m_resizeLayer
IntPoint m_currentMousePosition;
IntPoint m_mouseDownPos; // in our view's coords
double m_mouseDownTimestamp;
PlatformMouseEvent m_mouseDown;
-
- static unsigned s_accessKeyModifiers;
unsigned m_pendingFrameUnloadEventCount;
unsigned m_pendingFrameBeforeUnloadEventCount;
diff --git a/WebCore/page/Frame.cpp b/WebCore/page/Frame.cpp
index d474c3b..d4632e5 100644
--- a/WebCore/page/Frame.cpp
+++ b/WebCore/page/Frame.cpp
@@ -27,7 +27,6 @@
*/
#include "config.h"
#include "Frame.h"
-#include "FramePrivate.h"
#include "ApplyStyleCommand.h"
#include "BeforeUnloadEvent.h"
@@ -42,6 +41,7 @@
#include "EditorClient.h"
#include "EventNames.h"
#include "FocusController.h"
+#include "FloatQuad.h"
#include "FrameLoader.h"
#include "FrameView.h"
#include "GraphicsContext.h"
@@ -66,7 +66,6 @@
#include "RenderTheme.h"
#include "RenderView.h"
#include "Settings.h"
-#include "SystemTime.h"
#include "TextIterator.h"
#include "TextResourceDecoder.h"
#include "XMLNames.h"
@@ -75,6 +74,7 @@
#include "runtime_root.h"
#include "visible_units.h"
#include <wtf/RefCountedLeakCounter.h>
+#include <wtf/StdLibExtras.h>
#if FRAME_LOADS_USER_STYLESHEET
#include "UserStyleSheetLoader.h"
@@ -91,6 +91,10 @@
#include "WebViewCore.h"
#endif
+#if ENABLE(WML)
+#include "WMLNames.h"
+#endif
+
using namespace std;
namespace WebCore {
@@ -109,10 +113,33 @@ static inline Frame* parentFromOwnerElement(HTMLFrameOwnerElement* ownerElement)
}
Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* frameLoaderClient)
- : d(new FramePrivate(page, parentFromOwnerElement(ownerElement), this, ownerElement, frameLoaderClient))
+ : m_page(page)
+ , m_treeNode(this, parentFromOwnerElement(ownerElement))
+ , m_loader(this, frameLoaderClient)
+ , m_ownerElement(ownerElement)
+ , m_script(this)
+ , m_selectionGranularity(CharacterGranularity)
+ , m_selectionController(this)
+ , m_caretBlinkTimer(this, &Frame::caretBlinkTimerFired)
+ , m_editor(this)
+ , m_eventHandler(this)
+ , m_animationController(this)
+ , m_lifeSupportTimer(this, &Frame::lifeSupportTimerFired)
+ , m_caretVisible(false)
+ , m_caretPaint(true)
+ , m_highlightTextMatches(false)
+ , m_inViewSourceMode(false)
+ , m_needsReapplyStyles(false)
+ , m_isDisconnected(false)
+ , m_excludeFromTextSearch(false)
+#if FRAME_LOADS_USER_STYLESHEET
+ , m_userStyleSheetLoader(0)
+#endif
{
+ Frame* parent = parentFromOwnerElement(ownerElement);
+ m_zoomFactor = parent ? parent->m_zoomFactor : 1.0f;
+
AtomicString::init();
- EventNames::init();
HTMLNames::init();
QualifiedName::init();
MediaFeatureNames::init();
@@ -122,6 +149,10 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient*
XLinkNames::init();
#endif
+#if ENABLE(WML)
+ WMLNames::init();
+#endif
+
XMLNames::init();
if (!ownerElement)
@@ -146,76 +177,73 @@ Frame::~Frame()
// FIXME: We should not be doing all this work inside the destructor
- ASSERT(!d->m_lifeSupportTimer.isActive());
+ ASSERT(!m_lifeSupportTimer.isActive());
#ifndef NDEBUG
frameCounter.decrement();
#endif
- if (d->m_script.haveWindowShell())
- d->m_script.windowShell()->disconnectFrame();
+ if (m_script.haveWindowShell())
+ m_script.windowShell()->disconnectFrame();
disconnectOwnerElement();
- if (d->m_domWindow)
- d->m_domWindow->disconnectFrame();
+ if (m_domWindow)
+ m_domWindow->disconnectFrame();
- HashSet<DOMWindow*>::iterator end = d->m_liveFormerWindows.end();
- for (HashSet<DOMWindow*>::iterator it = d->m_liveFormerWindows.begin(); it != end; ++it)
+ HashSet<DOMWindow*>::iterator end = m_liveFormerWindows.end();
+ for (HashSet<DOMWindow*>::iterator it = m_liveFormerWindows.begin(); it != end; ++it)
(*it)->disconnectFrame();
- if (d->m_view) {
- d->m_view->hide();
- d->m_view->clearFrame();
+ if (m_view) {
+ m_view->hide();
+ m_view->clearFrame();
}
- ASSERT(!d->m_lifeSupportTimer.isActive());
+ ASSERT(!m_lifeSupportTimer.isActive());
#if FRAME_LOADS_USER_STYLESHEET
- delete d->m_userStyleSheetLoader;
+ delete m_userStyleSheetLoader;
#endif
-
- delete d;
- d = 0;
}
void Frame::init()
{
- d->m_loader.init();
+ m_loader.init();
}
FrameLoader* Frame::loader() const
{
- return &d->m_loader;
+ return &m_loader;
}
FrameView* Frame::view() const
{
- return d->m_view.get();
+ return m_view.get();
}
void Frame::setView(FrameView* view)
{
#if PLATFORM(ANDROID)
- if (!view && d->m_view) {
+ if (!view && m_view) {
// FIXME(for Cary): This is moved from FrameAndroid destructor. Do we
// need to call removeFrameGeneration per Frame or per FrameView?
- android::WebViewCore::getWebViewCore(d->m_view.get())->removeFrameGeneration(this);
+ android::WebViewCore::getWebViewCore(m_view.get())->removeFrameGeneration(this);
}
#endif
// Detach the document now, so any onUnload handlers get run - if
// we wait until the view is destroyed, then things won't be
// hooked up enough for some JavaScript calls to work.
- if (!view && d->m_doc && d->m_doc->attached() && !d->m_doc->inPageCache()) {
+ if (!view && m_doc && m_doc->attached() && !m_doc->inPageCache()) {
// FIXME: We don't call willRemove here. Why is that OK?
- d->m_doc->detach();
- if (d->m_view)
- d->m_view->unscheduleRelayout();
+ m_doc->detach();
+ if (m_view)
+ m_view->unscheduleRelayout();
}
eventHandler()->clear();
- d->m_view = view;
+ m_view = view;
// Only one form submission is allowed per view of a part.
// Since this part may be getting reused as a result of being
@@ -225,35 +253,35 @@ void Frame::setView(FrameView* view)
ScriptController* Frame::script()
{
- return &d->m_script;
+ return &m_script;
}
Document* Frame::document() const
{
- return d->m_doc.get();
+ return m_doc.get();
}
void Frame::setDocument(PassRefPtr<Document> newDoc)
{
- if (d->m_doc && d->m_doc->attached() && !d->m_doc->inPageCache()) {
+ if (m_doc && m_doc->attached() && !m_doc->inPageCache()) {
// FIXME: We don't call willRemove here. Why is that OK?
- d->m_doc->detach();
+ m_doc->detach();
}
- d->m_doc = newDoc;
- if (d->m_doc && selection()->isFocusedAndActive())
- setUseSecureKeyboardEntry(d->m_doc->useSecureKeyboardEntryWhenActive());
+ m_doc = newDoc;
+ if (m_doc && selection()->isFocusedAndActive())
+ setUseSecureKeyboardEntry(m_doc->useSecureKeyboardEntryWhenActive());
- if (d->m_doc && !d->m_doc->attached())
- d->m_doc->attach();
+ if (m_doc && !m_doc->attached())
+ m_doc->attach();
// Update the cached 'document' property, which is now stale.
- d->m_script.updateDocument();
+ m_script.updateDocument();
}
Settings* Frame::settings() const
{
- return d->m_page ? d->m_page->settings() : 0;
+ return m_page ? m_page->settings() : 0;
}
String Frame::selectedText() const
@@ -267,15 +295,24 @@ IntRect Frame::firstRectForRange(Range* range) const
ExceptionCode ec = 0;
ASSERT(range->startContainer(ec));
ASSERT(range->endContainer(ec));
+
InlineBox* startInlineBox;
int startCaretOffset;
range->startPosition().getInlineBoxAndOffset(DOWNSTREAM, startInlineBox, startCaretOffset);
- IntRect startCaretRect = range->startContainer(ec)->renderer()->caretRect(startInlineBox, startCaretOffset, &extraWidthToEndOfLine);
+
+ RenderObject* startRenderer = range->startContainer(ec)->renderer();
+ IntRect startCaretRect = startRenderer->localCaretRect(startInlineBox, startCaretOffset, &extraWidthToEndOfLine);
+ if (startCaretRect != IntRect())
+ startCaretRect = startRenderer->localToAbsoluteQuad(FloatRect(startCaretRect)).enclosingBoundingBox();
InlineBox* endInlineBox;
int endCaretOffset;
range->endPosition().getInlineBoxAndOffset(UPSTREAM, endInlineBox, endCaretOffset);
- IntRect endCaretRect = range->endContainer(ec)->renderer()->caretRect(endInlineBox, endCaretOffset);
+
+ RenderObject* endRenderer = range->endContainer(ec)->renderer();
+ IntRect endCaretRect = endRenderer->localCaretRect(endInlineBox, endCaretOffset);
+ if (endCaretRect != IntRect())
+ endCaretRect = endRenderer->localToAbsoluteQuad(FloatRect(endCaretRect)).enclosingBoundingBox();
if (startCaretRect.y() == endCaretRect.y()) {
// start and end are on the same line
@@ -294,33 +331,33 @@ IntRect Frame::firstRectForRange(Range* range) const
SelectionController* Frame::selection() const
{
- return &d->m_selectionController;
+ return &m_selectionController;
}
Editor* Frame::editor() const
{
- return &d->m_editor;
+ return &m_editor;
}
TextGranularity Frame::selectionGranularity() const
{
- return d->m_selectionGranularity;
+ return m_selectionGranularity;
}
-void Frame::setSelectionGranularity(TextGranularity granularity) const
+void Frame::setSelectionGranularity(TextGranularity granularity)
{
- d->m_selectionGranularity = granularity;
+ m_selectionGranularity = granularity;
}
SelectionController* Frame::dragCaretController() const
{
- return d->m_page->dragCaretController();
+ return m_page->dragCaretController();
}
AnimationController* Frame::animation() const
{
- return &d->m_animationController;
+ return &m_animationController;
}
static RegularExpression* createRegExpForLabels(const Vector<String>& labels)
@@ -328,7 +365,7 @@ static RegularExpression* createRegExpForLabels(const Vector<String>& labels)
// REVIEW- version of this call in FrameMac.mm caches based on the NSArray ptrs being
// the same across calls. We can't do that.
- static RegularExpression wordRegExp = RegularExpression("\\w");
+ DEFINE_STATIC_LOCAL(RegularExpression, wordRegExp, ("\\w", TextCaseSensitive));
String pattern("(");
unsigned int numLabels = labels.size();
unsigned int i;
@@ -338,8 +375,8 @@ static RegularExpression* createRegExpForLabels(const Vector<String>& labels)
bool startsWithWordChar = false;
bool endsWithWordChar = false;
if (label.length() != 0) {
- startsWithWordChar = wordRegExp.search(label.substring(0, 1)) >= 0;
- endsWithWordChar = wordRegExp.search(label.substring(label.length() - 1, 1)) >= 0;
+ startsWithWordChar = wordRegExp.match(label.substring(0, 1)) >= 0;
+ endsWithWordChar = wordRegExp.match(label.substring(label.length() - 1, 1)) >= 0;
}
if (i != 0)
@@ -356,7 +393,7 @@ static RegularExpression* createRegExpForLabels(const Vector<String>& labels)
}
}
pattern.append(")");
- return new RegularExpression(pattern, false);
+ return new RegularExpression(pattern, TextCaseInsensitive);
}
String Frame::searchForLabelsAboveCell(RegularExpression* regExp, HTMLTableCellElement* cell)
@@ -408,8 +445,7 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element
n = n->traversePreviousNode())
{
if (n->hasTagName(formTag)
- || (n->isHTMLElement()
- && static_cast<HTMLElement*>(n)->isGenericFormElement()))
+ || (n->isHTMLElement() && static_cast<Element*>(n)->isFormControlElement()))
{
// We hit another form element or the start of the form - bail out
break;
@@ -448,7 +484,7 @@ String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* e
return String();
// Make numbers and _'s in field names behave like word boundaries, e.g., "address2"
- replace(name, RegularExpression("\\d"), " ");
+ replace(name, RegularExpression("\\d", TextCaseSensitive), " ");
name.replace('_', ' ');
OwnPtr<RegularExpression> regExp(createRegExpForLabels(labels));
@@ -459,7 +495,7 @@ String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* e
int bestLength = -1;
int start = 0;
do {
- pos = regExp->search(name, start);
+ pos = regExp->match(name, start);
if (pos != -1) {
length = regExp->matchedLength();
if (length >= bestLength) {
@@ -477,7 +513,7 @@ String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* e
const Selection& Frame::mark() const
{
- return d->m_mark;
+ return m_mark;
}
void Frame::setMark(const Selection& s)
@@ -487,7 +523,7 @@ void Frame::setMark(const Selection& s)
ASSERT(!s.start().node() || s.start().node()->document() == document());
ASSERT(!s.end().node() || s.end().node()->document() == document());
- d->m_mark = s;
+ m_mark = s;
}
void Frame::notifyRendererOfSelectionChange(bool userTriggered)
@@ -509,18 +545,18 @@ void Frame::invalidateSelection()
void Frame::setCaretVisible(bool flag)
{
- if (d->m_caretVisible == flag)
+ if (m_caretVisible == flag)
return;
clearCaretRectIfNeeded();
- d->m_caretVisible = flag;
+ m_caretVisible = flag;
selectionLayoutChanged();
}
void Frame::clearCaretRectIfNeeded()
{
#if ENABLE(TEXT_CARET)
- if (d->m_caretPaint) {
- d->m_caretPaint = false;
+ if (m_caretPaint) {
+ m_caretPaint = false;
selection()->invalidateCaretRect();
}
#endif
@@ -571,21 +607,23 @@ void Frame::selectionLayoutChanged()
bool caretRectChanged = selection()->recomputeCaretRect();
#if ENABLE(TEXT_CARET)
- bool shouldBlink = d->m_caretVisible
+ bool shouldBlink = m_caretVisible
&& selection()->isCaret() && selection()->isContentEditable();
shouldBlink = false;
// If the caret moved, stop the blink timer so we can restart with a
// black caret in the new location.
if (caretRectChanged || !shouldBlink)
- d->m_caretBlinkTimer.stop();
+ m_caretBlinkTimer.stop();
// Start blinking with a black caret. Be sure not to restart if we're
// already blinking in the right location.
- if (shouldBlink && !d->m_caretBlinkTimer.isActive()) {
- d->m_caretBlinkTimer.startRepeating(theme()->caretBlinkFrequency());
- if (!d->m_caretPaint) {
- d->m_caretPaint = true;
+ if (shouldBlink && !m_caretBlinkTimer.isActive()) {
+ if (double blinkInterval = theme()->caretBlinkInterval())
+ m_caretBlinkTimer.startRepeating(blinkInterval);
+
+ if (!m_caretPaint) {
+ m_caretPaint = true;
selection()->invalidateCaretRect();
}
}
@@ -594,14 +632,14 @@ void Frame::selectionLayoutChanged()
return;
#endif
- RenderView* canvas = contentRenderer();
- if (!canvas)
+ RenderView* view = contentRenderer();
+ if (!view)
return;
Selection selection = this->selection()->selection();
if (!selection.isRange())
- canvas->clearSelection();
+ view->clearSelection();
else {
// Use the rightmost candidate for the start of the selection, and the leftmost candidate for the end of the selection.
// Example: foo <a>bar</a>. Imagine that a line wrap occurs after 'foo', and that 'bar' is selected. If we pass [foo, 3]
@@ -619,7 +657,7 @@ void Frame::selectionLayoutChanged()
if (startPos.isNotNull() && endPos.isNotNull() && selection.visibleStart() != selection.visibleEnd()) {
RenderObject *startRenderer = startPos.node()->renderer();
RenderObject *endRenderer = endPos.node()->renderer();
- canvas->setSelection(startRenderer, startPos.offset(), endRenderer, endPos.offset());
+ view->setSelection(startRenderer, startPos.offset(), endRenderer, endPos.offset());
}
}
}
@@ -627,50 +665,50 @@ void Frame::selectionLayoutChanged()
void Frame::caretBlinkTimerFired(Timer<Frame>*)
{
#if ENABLE(TEXT_CARET)
- ASSERT(d->m_caretVisible);
+ ASSERT(m_caretVisible);
ASSERT(selection()->isCaret());
- bool caretPaint = d->m_caretPaint;
+ bool caretPaint = m_caretPaint;
if (selection()->isCaretBlinkingSuspended() && caretPaint)
return;
- d->m_caretPaint = !caretPaint;
+ m_caretPaint = !caretPaint;
selection()->invalidateCaretRect();
#endif
}
-void Frame::paintCaret(GraphicsContext* p, const IntRect& rect) const
+void Frame::paintCaret(GraphicsContext* p, int tx, int ty, const IntRect& clipRect) const
{
#if ENABLE(TEXT_CARET)
- if (d->m_caretPaint && d->m_caretVisible)
- selection()->paintCaret(p, rect);
+ if (m_caretPaint && m_caretVisible)
+ selection()->paintCaret(p, tx, ty, clipRect);
#endif
}
-void Frame::paintDragCaret(GraphicsContext* p, const IntRect& rect) const
+void Frame::paintDragCaret(GraphicsContext* p, int tx, int ty, const IntRect& clipRect) const
{
#if ENABLE(TEXT_CARET)
- SelectionController* dragCaretController = d->m_page->dragCaretController();
+ SelectionController* dragCaretController = m_page->dragCaretController();
ASSERT(dragCaretController->selection().isCaret());
if (dragCaretController->selection().start().node()->document()->frame() == this)
- dragCaretController->paintCaret(p, rect);
+ dragCaretController->paintCaret(p, tx, ty, clipRect);
#endif
}
float Frame::zoomFactor() const
{
- return d->m_zoomFactor;
+ return m_zoomFactor;
}
bool Frame::isZoomFactorTextOnly() const
{
- return d->m_page->settings()->zoomsTextOnly();
+ return m_page->settings()->zoomsTextOnly();
}
bool Frame::shouldApplyTextZoom() const
{
- if (d->m_zoomFactor == 1.0f || !isZoomFactorTextOnly())
+ if (m_zoomFactor == 1.0f || !isZoomFactorTextOnly())
return false;
#if ENABLE(SVG)
- if (d->m_doc && d->m_doc->isSVGDocument())
+ if (m_doc && m_doc->isSVGDocument())
return false;
#endif
return true;
@@ -678,10 +716,10 @@ bool Frame::shouldApplyTextZoom() const
bool Frame::shouldApplyPageZoom() const
{
- if (d->m_zoomFactor == 1.0f || isZoomFactorTextOnly())
+ if (m_zoomFactor == 1.0f || isZoomFactorTextOnly())
return false;
#if ENABLE(SVG)
- if (d->m_doc && d->m_doc->isSVGDocument())
+ if (m_doc && m_doc->isSVGDocument())
return false;
#endif
return true;
@@ -689,44 +727,44 @@ bool Frame::shouldApplyPageZoom() const
void Frame::setZoomFactor(float percent, bool isTextOnly)
{
- if (d->m_zoomFactor == percent && isZoomFactorTextOnly())
+ if (m_zoomFactor == percent && isZoomFactorTextOnly() == isTextOnly)
return;
#if ENABLE(SVG)
// SVG doesn't care if the zoom factor is text only. It will always apply a
// zoom to the whole SVG.
- if (d->m_doc && d->m_doc->isSVGDocument()) {
- if (!static_cast<SVGDocument*>(d->m_doc.get())->zoomAndPanEnabled())
+ if (m_doc && m_doc->isSVGDocument()) {
+ if (!static_cast<SVGDocument*>(m_doc.get())->zoomAndPanEnabled())
return;
- d->m_zoomFactor = percent;
- d->m_page->settings()->setZoomsTextOnly(true); // We do this to avoid doing any scaling of CSS pixels, since the SVG has its own notion of zoom.
- if (d->m_doc->renderer())
- d->m_doc->renderer()->repaint();
+ m_zoomFactor = percent;
+ m_page->settings()->setZoomsTextOnly(true); // We do this to avoid doing any scaling of CSS pixels, since the SVG has its own notion of zoom.
+ if (m_doc->renderer())
+ m_doc->renderer()->repaint();
return;
}
#endif
- d->m_zoomFactor = percent;
- d->m_page->settings()->setZoomsTextOnly(isTextOnly);
+ m_zoomFactor = percent;
+ m_page->settings()->setZoomsTextOnly(isTextOnly);
- if (d->m_doc)
- d->m_doc->recalcStyle(Node::Force);
+ if (m_doc)
+ m_doc->recalcStyle(Node::Force);
for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
- child->setZoomFactor(d->m_zoomFactor, isTextOnly);
+ child->setZoomFactor(m_zoomFactor, isTextOnly);
- if (d->m_doc && d->m_doc->renderer() && d->m_doc->renderer()->needsLayout() && view()->didFirstLayout())
+ if (m_doc && m_doc->renderer() && m_doc->renderer()->needsLayout() && view()->didFirstLayout())
view()->layout();
}
void Frame::setPrinting(bool printing, float minPageWidth, float maxPageWidth, bool adjustViewSize)
{
- if (!d->m_doc)
+ if (!m_doc)
return;
- d->m_doc->setPrinting(printing);
+ m_doc->setPrinting(printing);
view()->setMediaType(printing ? "print" : "screen");
- d->m_doc->updateStyleSelector();
+ m_doc->updateStyleSelector();
forceLayoutWithPageWidthRange(minPageWidth, maxPageWidth, adjustViewSize);
for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
@@ -735,58 +773,58 @@ void Frame::setPrinting(bool printing, float minPageWidth, float maxPageWidth, b
void Frame::setJSStatusBarText(const String& text)
{
- d->m_kjsStatusBarText = text;
- if (d->m_page)
- d->m_page->chrome()->setStatusbarText(this, d->m_kjsStatusBarText);
+ m_kjsStatusBarText = text;
+ if (m_page)
+ m_page->chrome()->setStatusbarText(this, m_kjsStatusBarText);
}
void Frame::setJSDefaultStatusBarText(const String& text)
{
- d->m_kjsDefaultStatusBarText = text;
- if (d->m_page)
- d->m_page->chrome()->setStatusbarText(this, d->m_kjsDefaultStatusBarText);
+ m_kjsDefaultStatusBarText = text;
+ if (m_page)
+ m_page->chrome()->setStatusbarText(this, m_kjsDefaultStatusBarText);
}
String Frame::jsStatusBarText() const
{
- return d->m_kjsStatusBarText;
+ return m_kjsStatusBarText;
}
String Frame::jsDefaultStatusBarText() const
{
- return d->m_kjsDefaultStatusBarText;
+ return m_kjsDefaultStatusBarText;
}
void Frame::setNeedsReapplyStyles()
{
- if (d->m_needsReapplyStyles)
+ if (m_needsReapplyStyles)
return;
- d->m_needsReapplyStyles = true;
+ m_needsReapplyStyles = true;
- // Invalidate the FrameView so that FrameView::layout will get called,
- // which calls reapplyStyles.
+ // FrameView's "layout" timer includes reapplyStyles, so despite its
+ // name, it's what we want to call here.
if (view())
- view()->invalidate();
+ view()->scheduleRelayout();
}
bool Frame::needsReapplyStyles() const
{
- return d->m_needsReapplyStyles;
+ return m_needsReapplyStyles;
}
void Frame::reapplyStyles()
{
- d->m_needsReapplyStyles = false;
+ m_needsReapplyStyles = false;
// FIXME: This call doesn't really make sense in a method called
// "reapplyStyles". We should probably eventually move it into its own
// method.
- if (d->m_doc)
- d->m_doc->docLoader()->setAutoLoadImages(d->m_page && d->m_page->settings()->loadsImagesAutomatically());
+ if (m_doc)
+ m_doc->docLoader()->setAutoLoadImages(m_page && m_page->settings()->loadsImagesAutomatically());
#if FRAME_LOADS_USER_STYLESHEET
- const KURL userStyleSheetLocation = d->m_page ? d->m_page->settings()->userStyleSheetLocation() : KURL();
+ const KURL userStyleSheetLocation = m_page ? m_page->settings()->userStyleSheetLocation() : KURL();
if (!userStyleSheetLocation.isEmpty())
setUserStyleSheetLocation(userStyleSheetLocation);
else
@@ -797,8 +835,8 @@ void Frame::reapplyStyles()
// The document automatically does this as required when you set the style sheet.
// But we had problems when this code was removed. Details are in
// <http://bugs.webkit.org/show_bug.cgi?id=8079>.
- if (d->m_doc)
- d->m_doc->updateStyleSelector();
+ if (m_doc)
+ m_doc->updateStyleSelector();
}
bool Frame::shouldChangeSelection(const Selection& newSelection) const
@@ -819,11 +857,11 @@ bool Frame::shouldDeleteSelection(const Selection& selection) const
bool Frame::isContentEditable() const
{
- if (d->m_editor.clientIsEditable())
+ if (m_editor.clientIsEditable())
return true;
- if (!d->m_doc)
+ if (!m_doc)
return false;
- return d->m_doc->inDesignMode();
+ return m_doc->inDesignMode();
}
#if !PLATFORM(MAC)
@@ -837,22 +875,22 @@ void Frame::setUseSecureKeyboardEntry(bool)
void Frame::updateSecureKeyboardEntryIfActive()
{
if (selection()->isFocusedAndActive())
- setUseSecureKeyboardEntry(d->m_doc->useSecureKeyboardEntryWhenActive());
+ setUseSecureKeyboardEntry(m_doc->useSecureKeyboardEntryWhenActive());
}
CSSMutableStyleDeclaration *Frame::typingStyle() const
{
- return d->m_typingStyle.get();
+ return m_typingStyle.get();
}
void Frame::setTypingStyle(CSSMutableStyleDeclaration *style)
{
- d->m_typingStyle = style;
+ m_typingStyle = style;
}
void Frame::clearTypingStyle()
{
- d->m_typingStyle = 0;
+ m_typingStyle = 0;
}
void Frame::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction editingAction)
@@ -869,9 +907,25 @@ void Frame::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction edit
mutableStyle = typingStyle();
}
+ RefPtr<CSSValue> unicodeBidi;
+ RefPtr<CSSValue> direction;
+ if (editingAction == EditActionSetWritingDirection) {
+ unicodeBidi = mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
+ direction = mutableStyle->getPropertyCSSValue(CSSPropertyDirection);
+ }
+
Node* node = selection()->selection().visibleStart().deepEquivalent().node();
computedStyle(node)->diff(mutableStyle.get());
-
+
+ if (editingAction == EditActionSetWritingDirection && unicodeBidi) {
+ ASSERT(unicodeBidi->isPrimitiveValue());
+ mutableStyle->setProperty(CSSPropertyUnicodeBidi, static_cast<CSSPrimitiveValue*>(unicodeBidi.get())->getIdent());
+ if (direction) {
+ ASSERT(direction->isPrimitiveValue());
+ mutableStyle->setProperty(CSSPropertyDirection, static_cast<CSSPrimitiveValue*>(direction.get())->getIdent());
+ }
+ }
+
// Handle block styles, substracting these from the typing style.
RefPtr<CSSMutableStyleDeclaration> blockStyle = mutableStyle->copyBlockProperties();
blockStyle->diff(mutableStyle.get());
@@ -879,7 +933,7 @@ void Frame::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction edit
applyCommand(ApplyStyleCommand::create(document(), blockStyle.get(), editingAction));
// Set the remaining style as the typing style.
- d->m_typingStyle = mutableStyle.release();
+ m_typingStyle = mutableStyle.release();
}
String Frame::selectionStartStylePropertyValue(int stylePropertyID) const
@@ -920,11 +974,11 @@ PassRefPtr<CSSComputedStyleDeclaration> Frame::selectionComputedStyle(Node*& nod
RefPtr<Element> styleElement = elem;
ExceptionCode ec = 0;
- if (d->m_typingStyle) {
+ if (m_typingStyle) {
styleElement = document()->createElementNS(xhtmlNamespaceURI, "span", ec);
ASSERT(ec == 0);
- styleElement->setAttribute(styleAttr, d->m_typingStyle->cssText().impl(), ec);
+ styleElement->setAttribute(styleAttr, m_typingStyle->cssText().impl(), ec);
ASSERT(ec == 0);
styleElement->appendChild(document()->createEditingTextNode(""), ec);
@@ -990,10 +1044,10 @@ void Frame::textDidChangeInTextArea(Element* e)
void Frame::applyEditingStyleToBodyElement() const
{
- if (!d->m_doc)
+ if (!m_doc)
return;
- RefPtr<NodeList> list = d->m_doc->getElementsByTagName("body");
+ RefPtr<NodeList> list = m_doc->getElementsByTagName("body");
unsigned len = list->length();
for (unsigned i = 0; i < len; i++) {
applyEditingStyleToElement(static_cast<Element*>(list->item(i)));
@@ -1002,10 +1056,10 @@ void Frame::applyEditingStyleToBodyElement() const
void Frame::removeEditingStyleFromBodyElement() const
{
- if (!d->m_doc)
+ if (!m_doc)
return;
- RefPtr<NodeList> list = d->m_doc->getElementsByTagName("body");
+ RefPtr<NodeList> list = m_doc->getElementsByTagName("body");
unsigned len = list->length();
for (unsigned i = 0; i < len; i++) {
removeEditingStyleFromElement(static_cast<Element*>(list->item(i)));
@@ -1036,20 +1090,20 @@ void Frame::removeEditingStyleFromElement(Element*) const
#ifndef NDEBUG
static HashSet<Frame*>& keepAliveSet()
{
- static HashSet<Frame*> staticKeepAliveSet;
+ DEFINE_STATIC_LOCAL(HashSet<Frame*>, staticKeepAliveSet, ());
return staticKeepAliveSet;
}
#endif
void Frame::keepAlive()
{
- if (d->m_lifeSupportTimer.isActive())
+ if (m_lifeSupportTimer.isActive())
return;
#ifndef NDEBUG
keepAliveSet().add(this);
#endif
ref();
- d->m_lifeSupportTimer.startOneShot(0);
+ m_lifeSupportTimer.startOneShot(0);
}
#ifndef NDEBUG
@@ -1058,7 +1112,7 @@ void Frame::cancelAllKeepAlive()
HashSet<Frame*>::iterator end = keepAliveSet().end();
for (HashSet<Frame*>::iterator it = keepAliveSet().begin(); it != end; ++it) {
Frame* frame = *it;
- frame->d->m_lifeSupportTimer.stop();
+ frame->m_lifeSupportTimer.stop();
frame->deref();
}
keepAliveSet().clear();
@@ -1075,11 +1129,11 @@ void Frame::lifeSupportTimerFired(Timer<Frame>*)
void Frame::clearDOMWindow()
{
- if (d->m_domWindow) {
- d->m_liveFormerWindows.add(d->m_domWindow.get());
- d->m_domWindow->clear();
+ if (m_domWindow) {
+ m_liveFormerWindows.add(m_domWindow.get());
+ m_domWindow->clear();
}
- d->m_domWindow = 0;
+ m_domWindow = 0;
}
RenderView* Frame::contentRenderer() const
@@ -1096,12 +1150,12 @@ RenderView* Frame::contentRenderer() const
HTMLFrameOwnerElement* Frame::ownerElement() const
{
- return d->m_ownerElement;
+ return m_ownerElement;
}
RenderPart* Frame::ownerRenderer() const
{
- HTMLFrameOwnerElement* ownerElement = d->m_ownerElement;
+ HTMLFrameOwnerElement* ownerElement = m_ownerElement;
if (!ownerElement)
return 0;
RenderObject* object = ownerElement->renderer();
@@ -1109,7 +1163,7 @@ RenderPart* Frame::ownerRenderer() const
return 0;
// FIXME: If <object> is ever fixed to disassociate itself from frames
// that it has started but canceled, then this can turn into an ASSERT
- // since d->m_ownerElement would be 0 when the load is canceled.
+ // since m_ownerElement would be 0 when the load is canceled.
// https://bugs.webkit.org/show_bug.cgi?id=18585
if (!object->isRenderPart())
return 0;
@@ -1118,33 +1172,33 @@ RenderPart* Frame::ownerRenderer() const
bool Frame::isDisconnected() const
{
- return d->m_isDisconnected;
+ return m_isDisconnected;
}
void Frame::setIsDisconnected(bool isDisconnected)
{
- d->m_isDisconnected = isDisconnected;
+ m_isDisconnected = isDisconnected;
}
bool Frame::excludeFromTextSearch() const
{
- return d->m_excludeFromTextSearch;
+ return m_excludeFromTextSearch;
}
void Frame::setExcludeFromTextSearch(bool exclude)
{
- d->m_excludeFromTextSearch = exclude;
+ m_excludeFromTextSearch = exclude;
}
// returns FloatRect because going through IntRect would truncate any floats
-FloatRect Frame::selectionRect(bool clipToVisibleContent) const
+FloatRect Frame::selectionBounds(bool clipToVisibleContent) const
{
RenderView* root = contentRenderer();
- FrameView* view = d->m_view.get();
+ FrameView* view = m_view.get();
if (!root || !view)
return IntRect();
- IntRect selectionRect = root->selectionRect(clipToVisibleContent);
+ IntRect selectionRect = root->selectionBounds(clipToVisibleContent);
return clipToVisibleContent ? intersection(selectionRect, view->visibleContentRect()) : selectionRect;
}
@@ -1160,7 +1214,7 @@ void Frame::selectionTextRects(Vector<FloatRect>& rects, bool clipToVisibleConte
selectedRange->addLineBoxRects(intRects, true);
unsigned size = intRects.size();
- FloatRect visibleContentRect = d->m_view->visibleContentRect();
+ FloatRect visibleContentRect = m_view->visibleContentRect();
for (unsigned i = 0; i < size; ++i)
if (clipToVisibleContent)
rects.append(intersection(intRects[i], visibleContentRect));
@@ -1171,7 +1225,7 @@ void Frame::selectionTextRects(Vector<FloatRect>& rects, bool clipToVisibleConte
bool Frame::isFrameSet() const
{
- Document* document = d->m_doc.get();
+ Document* document = m_doc.get();
if (!document || !document->isHTMLDocument())
return false;
Node *body = static_cast<HTMLDocument*>(document)->body();
@@ -1185,7 +1239,7 @@ static HTMLFormElement *scanForForm(Node *start)
for (n = start; n; n = n->traverseNextNode()) {
if (n->hasTagName(formTag))
return static_cast<HTMLFormElement*>(n);
- else if (n->isHTMLElement() && static_cast<HTMLElement*>(n)->isGenericFormElement())
+ else if (n->isHTMLElement() && static_cast<Element*>(n)->isFormControlElement())
return static_cast<HTMLFormControlElement*>(n)->form();
else if (n->hasTagName(frameTag) || n->hasTagName(iframeTag)) {
Node *childDoc = static_cast<HTMLFrameElementBase*>(n)->contentDocument();
@@ -1200,7 +1254,7 @@ static HTMLFormElement *scanForForm(Node *start)
HTMLFormElement *Frame::currentForm() const
{
// start looking either at the active (first responder) node, or where the selection is
- Node *start = d->m_doc ? d->m_doc->focusedNode() : 0;
+ Node *start = m_doc ? m_doc->focusedNode() : 0;
if (!start)
start = selection()->start().node();
@@ -1209,8 +1263,7 @@ HTMLFormElement *Frame::currentForm() const
for (n = start; n; n = n->parentNode()) {
if (n->hasTagName(formTag))
return static_cast<HTMLFormElement*>(n);
- else if (n->isHTMLElement()
- && static_cast<HTMLElement*>(n)->isGenericFormElement())
+ else if (n->isHTMLElement() && static_cast<Element*>(n)->isFormControlElement())
return static_cast<HTMLFormControlElement*>(n)->form();
}
@@ -1228,11 +1281,11 @@ void Frame::revealSelection(const RenderLayer::ScrollAlignment& alignment) const
return;
case Selection::CARET:
- rect = selection()->caretRect();
+ rect = selection()->absoluteCaretBounds();
break;
case Selection::RANGE:
- rect = enclosingIntRect(selectionRect(false));
+ rect = enclosingIntRect(selectionBounds(false));
break;
}
@@ -1255,14 +1308,14 @@ void Frame::revealCaret(const RenderLayer::ScrollAlignment& alignment) const
Position extent = selection()->extent();
if (extent.node() && extent.node()->renderer()) {
- IntRect extentRect = VisiblePosition(extent).caretRect();
+ IntRect extentRect = VisiblePosition(extent).absoluteCaretBounds();
RenderLayer* layer = extent.node()->renderer()->enclosingLayer();
if (layer)
layer->scrollRectToVisible(extentRect, false, alignment, alignment);
}
}
-void Frame::adjustPageHeight(float *newBottom, float oldTop, float oldBottom, float bottomLimit)
+void Frame::adjustPageHeight(float* newBottom, float oldTop, float oldBottom, float /*bottomLimit*/)
{
RenderView* root = contentRenderer();
if (root) {
@@ -1294,7 +1347,7 @@ Frame* Frame::frameForWidget(const Widget* widget)
void Frame::forceLayout(bool allowSubtree)
{
- FrameView *v = d->m_view.get();
+ FrameView *v = m_view.get();
if (v) {
v->layout(allowSubtree);
// We cannot unschedule a pending relayout, since the force can be called with
@@ -1343,7 +1396,7 @@ void Frame::sendResizeEvent()
void Frame::sendScrollEvent()
{
- FrameView* v = d->m_view.get();
+ FrameView* v = m_view.get();
if (!v)
return;
v->setWasScrolledByUser(true);
@@ -1359,7 +1412,7 @@ void Frame::clearTimers(FrameView *view, Document *document)
view->unscheduleRelayout();
if (view->frame()) {
if (document && document->renderer() && document->renderer()->hasLayer())
- document->renderer()->layer()->suspendMarquees();
+ document->renderView()->layer()->suspendMarquees();
view->frame()->animation()->suspendAnimations(document);
view->frame()->eventHandler()->stopAutoscrollTimer();
}
@@ -1368,7 +1421,7 @@ void Frame::clearTimers(FrameView *view, Document *document)
void Frame::clearTimers()
{
- clearTimers(d->m_view.get(), document());
+ clearTimers(m_view.get(), document());
}
RenderStyle *Frame::styleForSelectionStart(Node *&nodeToRemove) const
@@ -1387,14 +1440,14 @@ RenderStyle *Frame::styleForSelectionStart(Node *&nodeToRemove) const
if (!node)
return 0;
- if (!d->m_typingStyle)
+ if (!m_typingStyle)
return node->renderer()->style();
ExceptionCode ec = 0;
RefPtr<Element> styleElement = document()->createElementNS(xhtmlNamespaceURI, "span", ec);
ASSERT(ec == 0);
- String styleText = d->m_typingStyle->cssText() + " display: inline";
+ String styleText = m_typingStyle->cssText() + " display: inline";
styleElement->setAttribute(styleAttr, styleText.impl(), ec);
ASSERT(ec == 0);
@@ -1425,24 +1478,12 @@ void Frame::setSelectionFromNone()
bool Frame::inViewSourceMode() const
{
- return d->m_inViewSourceMode;
+ return m_inViewSourceMode;
}
-void Frame::setInViewSourceMode(bool mode) const
+void Frame::setInViewSourceMode(bool mode)
{
- d->m_inViewSourceMode = mode;
-}
-
-UChar Frame::backslashAsCurrencySymbol() const
-{
- Document *doc = document();
- if (!doc)
- return '\\';
- TextResourceDecoder *decoder = doc->decoder();
- if (!decoder)
- return '\\';
-
- return decoder->encoding().backslashAsCurrencySymbol();
+ m_inViewSourceMode = mode;
}
// Searches from the beginning of the document if nothing is selected.
@@ -1577,13 +1618,13 @@ unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsig
// Do a "fake" paint in order to execute the code that computes the rendered rect for
// each text match.
Document* doc = document();
- if (doc && d->m_view && contentRenderer()) {
+ if (doc && m_view && contentRenderer()) {
doc->updateLayout(); // Ensure layout is up to date.
- IntRect visibleRect = d->m_view->visibleContentRect();
+ IntRect visibleRect = m_view->visibleContentRect();
if (!visibleRect.isEmpty()) {
GraphicsContext context((PlatformGraphicsContext*)0);
context.setPaintingDisabled(true);
- d->m_view->paintContents(&context, visibleRect);
+ m_view->paintContents(&context, visibleRect);
}
}
@@ -1592,44 +1633,53 @@ unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsig
bool Frame::markedTextMatchesAreHighlighted() const
{
- return d->m_highlightTextMatches;
+ return m_highlightTextMatches;
}
void Frame::setMarkedTextMatchesAreHighlighted(bool flag)
{
- if (flag == d->m_highlightTextMatches || !document())
+ if (flag == m_highlightTextMatches || !document())
return;
- d->m_highlightTextMatches = flag;
+ m_highlightTextMatches = flag;
document()->repaintMarkers(DocumentMarker::TextMatch);
}
FrameTree* Frame::tree() const
{
- return &d->m_treeNode;
+ return &m_treeNode;
+}
+
+void Frame::setDOMWindow(DOMWindow* domWindow)
+{
+ if (m_domWindow) {
+ m_liveFormerWindows.add(m_domWindow.get());
+ m_domWindow->clear();
+ }
+ m_domWindow = domWindow;
}
DOMWindow* Frame::domWindow() const
{
- if (!d->m_domWindow)
- d->m_domWindow = DOMWindow::create(const_cast<Frame*>(this));
+ if (!m_domWindow)
+ m_domWindow = DOMWindow::create(const_cast<Frame*>(this));
- return d->m_domWindow.get();
+ return m_domWindow.get();
}
void Frame::clearFormerDOMWindow(DOMWindow* window)
{
- d->m_liveFormerWindows.remove(window);
+ m_liveFormerWindows.remove(window);
}
Page* Frame::page() const
{
- return d->m_page;
+ return m_page;
}
EventHandler* Frame::eventHandler() const
{
- return &d->m_eventHandler;
+ return &m_eventHandler;
}
void Frame::pageDestroyed()
@@ -1649,20 +1699,21 @@ void Frame::pageDestroyed()
script()->windowShell()->disconnectFrame();
script()->clearScriptObjects();
+ script()->updatePlatformScriptObjects();
- d->m_page = 0;
+ m_page = 0;
}
void Frame::disconnectOwnerElement()
{
- if (d->m_ownerElement) {
+ if (m_ownerElement) {
if (Document* doc = document())
doc->clearAXObjectCache();
- d->m_ownerElement->m_contentFrame = 0;
- if (d->m_page)
- d->m_page->decrementFrameCount();
+ m_ownerElement->m_contentFrame = 0;
+ if (m_page)
+ m_page->decrementFrameCount();
}
- d->m_ownerElement = 0;
+ m_ownerElement = 0;
}
String Frame::documentTypeString() const
@@ -1719,8 +1770,7 @@ bool Frame::shouldClose()
if (beforeUnloadEvent->result().isNull())
return true;
- String text = beforeUnloadEvent->result();
- text.replace('\\', backslashAsCurrencySymbol());
+ String text = doc->displayStringModifiedByEncoding(beforeUnloadEvent->result());
return chrome->runBeforeUnloadConfirmPanel(text, this);
}
@@ -1811,37 +1861,5 @@ Document* Frame::documentAtPoint(const IntPoint& point)
result = eventHandler()->hitTestResultAtPoint(pt, false);
return result.innerNode() ? result.innerNode()->document() : 0;
}
-
-FramePrivate::FramePrivate(Page* page, Frame* parent, Frame* thisFrame, HTMLFrameOwnerElement* ownerElement,
- FrameLoaderClient* frameLoaderClient)
- : m_page(page)
- , m_treeNode(thisFrame, parent)
- , m_loader(thisFrame, frameLoaderClient)
- , m_ownerElement(ownerElement)
- , m_script(thisFrame)
- , m_zoomFactor(parent ? parent->d->m_zoomFactor : 1.0f)
- , m_selectionGranularity(CharacterGranularity)
- , m_selectionController(thisFrame)
- , m_caretBlinkTimer(thisFrame, &Frame::caretBlinkTimerFired)
- , m_editor(thisFrame)
- , m_eventHandler(thisFrame)
- , m_animationController(thisFrame)
- , m_lifeSupportTimer(thisFrame, &Frame::lifeSupportTimerFired)
- , m_caretVisible(false)
- , m_caretPaint(true)
- , m_highlightTextMatches(false)
- , m_inViewSourceMode(false)
- , m_needsReapplyStyles(false)
- , m_isDisconnected(false)
- , m_excludeFromTextSearch(false)
-#if FRAME_LOADS_USER_STYLESHEET
- , m_userStyleSheetLoader(0)
-#endif
-{
-}
-
-FramePrivate::~FramePrivate()
-{
-}
} // namespace WebCore
diff --git a/WebCore/page/Frame.h b/WebCore/page/Frame.h
index 8f50062..bebdc63 100644
--- a/WebCore/page/Frame.h
+++ b/WebCore/page/Frame.h
@@ -28,11 +28,23 @@
#ifndef Frame_h
#define Frame_h
+#include "AnimationController.h"
#include "DragImage.h"
#include "EditAction.h"
+#include "Editor.h"
+#include "EventHandler.h"
+#include "FrameLoader.h"
+#include "FrameTree.h"
+#include "Range.h"
#include "RenderLayer.h"
+#include "ScriptController.h"
+#include "SelectionController.h"
#include "TextGranularity.h"
+#if PLATFORM(WIN)
+#include "FrameWin.h"
+#endif
+
#if PLATFORM(MAC)
#ifndef __OBJC__
class NSArray;
@@ -43,6 +55,10 @@ typedef int NSWritingDirection;
#endif
#endif
+#if PLATFORM(WIN)
+typedef struct HBITMAP__* HBITMAP;
+#endif
+
namespace WebCore {
class Editor;
@@ -60,6 +76,10 @@ class Selection;
class SelectionController;
class Widget;
+#if FRAME_LOADS_USER_STYLESHEET
+ class UserStyleSheetLoader;
+#endif
+
template <typename T> class Timer;
class Frame : public RefCounted<Frame> {
@@ -82,8 +102,10 @@ public:
Document* document() const;
FrameView* view() const;
+ void setDOMWindow(DOMWindow*);
DOMWindow* domWindow() const;
void clearFormerDOMWindow(DOMWindow*);
+
Editor* editor() const;
EventHandler* eventHandler() const;
FrameLoader* loader() const;
@@ -104,8 +126,6 @@ public:
private:
Frame(Page*, HTMLFrameOwnerElement*, FrameLoaderClient*);
-
- FramePrivate* d;
// === undecided, would like to consider moving to another class
@@ -122,7 +142,7 @@ public:
void setPrinting(bool printing, float minPageWidth, float maxPageWidth, bool adjustViewSize);
bool inViewSourceMode() const;
- void setInViewSourceMode(bool = true) const;
+ void setInViewSourceMode(bool = true);
void keepAlive(); // Used to keep the frame alive when running a script that might destroy it.
#ifndef NDEBUG
@@ -134,9 +154,6 @@ public:
void clearTimers();
static void clearTimers(FrameView*, Document*);
- // Convenience, to avoid repeating the code to dig down to get this.
- UChar backslashAsCurrencySymbol() const;
-
void setNeedsReapplyStyles();
bool needsReapplyStyles() const;
void reapplyStyles();
@@ -147,6 +164,11 @@ public:
// should move onto ScriptController
void clearDOMWindow();
+ String displayStringModifiedByEncoding(const String& str) const
+ {
+ return document() ? document()->displayStringModifiedByEncoding(str) : str;
+ }
+
private:
void lifeSupportTimerFired(Timer<Frame>*);
@@ -232,7 +254,7 @@ public:
public:
TextGranularity selectionGranularity() const;
- void setSelectionGranularity(TextGranularity) const;
+ void setSelectionGranularity(TextGranularity);
bool shouldChangeSelection(const Selection&) const;
bool shouldDeleteSelection(const Selection&) const;
@@ -244,8 +266,8 @@ public:
void invalidateSelection();
void setCaretVisible(bool = true);
- void paintCaret(GraphicsContext*, const IntRect&) const;
- void paintDragCaret(GraphicsContext*, const IntRect&) const;
+ void paintCaret(GraphicsContext*, int tx, int ty, const IntRect& clipRect) const;
+ void paintDragCaret(GraphicsContext*, int tx, int ty, const IntRect& clipRect) const;
bool isContentEditable() const; // if true, everything in frame is editable
@@ -255,7 +277,7 @@ public:
void setTypingStyle(CSSMutableStyleDeclaration*);
void clearTypingStyle();
- FloatRect selectionRect(bool clipToVisibleContent = true) const;
+ FloatRect selectionBounds(bool clipToVisibleContent = true) const;
void selectionTextRects(Vector<FloatRect>&, bool clipToVisibleContent = true) const;
HTMLFormElement* currentForm() const;
@@ -307,6 +329,59 @@ public:
#endif
+#if PLATFORM(WIN)
+
+public:
+ // FIXME - We should have a single version of nodeImage instead of using platform types.
+ HBITMAP nodeImage(Node*) const;
+
+#endif
+
+private:
+ Page* m_page;
+ mutable FrameTree m_treeNode;
+ mutable FrameLoader m_loader;
+
+ mutable RefPtr<DOMWindow> m_domWindow;
+ HashSet<DOMWindow*> m_liveFormerWindows;
+
+ HTMLFrameOwnerElement* m_ownerElement;
+ RefPtr<FrameView> m_view;
+ RefPtr<Document> m_doc;
+
+ ScriptController m_script;
+
+ String m_kjsStatusBarText;
+ String m_kjsDefaultStatusBarText;
+
+ float m_zoomFactor;
+
+ TextGranularity m_selectionGranularity;
+
+ mutable SelectionController m_selectionController;
+ mutable Selection m_mark;
+ Timer<Frame> m_caretBlinkTimer;
+ mutable Editor m_editor;
+ mutable EventHandler m_eventHandler;
+ mutable AnimationController m_animationController;
+
+ RefPtr<CSSMutableStyleDeclaration> m_typingStyle;
+
+ Timer<Frame> m_lifeSupportTimer;
+
+ bool m_caretVisible;
+ bool m_caretPaint;
+
+ bool m_highlightTextMatches;
+ bool m_inViewSourceMode;
+ bool m_needsReapplyStyles;
+ bool m_isDisconnected;
+ bool m_excludeFromTextSearch;
+
+#if FRAME_LOADS_USER_STYLESHEET
+ UserStyleSheetLoader* m_userStyleSheetLoader;
+#endif
+
};
} // namespace WebCore
diff --git a/WebCore/page/FrameLoadRequest.h b/WebCore/page/FrameLoadRequest.h
index bfb750c..0f92c45 100644
--- a/WebCore/page/FrameLoadRequest.h
+++ b/WebCore/page/FrameLoadRequest.h
@@ -33,16 +33,14 @@ namespace WebCore {
struct FrameLoadRequest {
public:
FrameLoadRequest()
- : m_lockHistory(false)
#ifdef ANDROID_USER_GESTURE
- , m_wasUserGesture(true)
+ : m_wasUserGesture(true)
#endif
{
}
FrameLoadRequest(const ResourceRequest& resourceRequest)
: m_resourceRequest(resourceRequest)
- , m_lockHistory(false)
#ifdef ANDROID_USER_GESTURE
, m_wasUserGesture(true)
#endif
@@ -52,7 +50,6 @@ namespace WebCore {
FrameLoadRequest(const ResourceRequest& resourceRequest, const String& frameName)
: m_resourceRequest(resourceRequest)
, m_frameName(frameName)
- , m_lockHistory(false)
#ifdef ANDROID_USER_GESTURE
, m_wasUserGesture(true)
#endif
@@ -67,9 +64,6 @@ namespace WebCore {
const String& frameName() const { return m_frameName; }
void setFrameName(const String& frameName) { m_frameName = frameName; }
- bool lockHistory() const { return m_lockHistory; }
- void setLockHistory(bool lock) { m_lockHistory = lock; }
-
#ifdef ANDROID_USER_GESTURE
void setWasUserGesture(bool wasUserGesture) { m_wasUserGesture = wasUserGesture; }
bool wasUserGesture() const { return m_wasUserGesture; }
@@ -78,7 +72,6 @@ namespace WebCore {
private:
ResourceRequest m_resourceRequest;
String m_frameName;
- bool m_lockHistory;
#ifdef ANDROID_USER_GESTURE
bool m_wasUserGesture;
#endif
diff --git a/WebCore/page/FramePrivate.h b/WebCore/page/FramePrivate.h
deleted file mode 100644
index 2f7c59a..0000000
--- a/WebCore/page/FramePrivate.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
- * 1999-2001 Lars Knoll <knoll@kde.org>
- * 1999-2001 Antti Koivisto <koivisto@kde.org>
- * 2000-2001 Simon Hausmann <hausmann@kde.org>
- * 2000-2001 Dirk Mueller <mueller@kde.org>
- * 2000 Stefan Schimanski <1Stein@gmx.de>
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef FramePrivate_h
-#define FramePrivate_h
-
-#include "AnimationController.h"
-#include "Editor.h"
-#include "EventHandler.h"
-#include "FrameLoader.h"
-#include "FrameTree.h"
-#include "Range.h"
-#include "SelectionController.h"
-#include "StringHash.h"
-#include "ScriptController.h"
-
-#if PLATFORM(WIN)
-#include "FrameWin.h"
-#endif
-
-namespace WebCore {
-
-#if FRAME_LOADS_USER_STYLESHEET
- class UserStyleSheetLoader;
-#endif
-
- class FramePrivate {
- public:
- FramePrivate(Page*, Frame* parent, Frame* thisFrame, HTMLFrameOwnerElement*, FrameLoaderClient*);
- ~FramePrivate();
-
- Page* m_page;
- FrameTree m_treeNode;
- FrameLoader m_loader;
- RefPtr<DOMWindow> m_domWindow;
- HashSet<DOMWindow*> m_liveFormerWindows;
-
- HTMLFrameOwnerElement* m_ownerElement;
- RefPtr<FrameView> m_view;
- RefPtr<Document> m_doc;
-
- ScriptController m_script;
-
- String m_kjsStatusBarText;
- String m_kjsDefaultStatusBarText;
-
- float m_zoomFactor;
-
- TextGranularity m_selectionGranularity;
-
- SelectionController m_selectionController;
- Selection m_mark;
- Timer<Frame> m_caretBlinkTimer;
- Editor m_editor;
- EventHandler m_eventHandler;
- AnimationController m_animationController;
-
- RefPtr<CSSMutableStyleDeclaration> m_typingStyle;
-
- Timer<Frame> m_lifeSupportTimer;
-
- bool m_caretVisible;
- bool m_caretPaint;
-
- bool m_highlightTextMatches;
- bool m_inViewSourceMode;
- bool m_needsReapplyStyles;
- bool m_isDisconnected;
- bool m_excludeFromTextSearch;
-
-#if FRAME_LOADS_USER_STYLESHEET
- UserStyleSheetLoader* m_userStyleSheetLoader;
-#endif
- };
-}
-
-#endif
diff --git a/WebCore/page/FrameTree.h b/WebCore/page/FrameTree.h
index 0952dcd..3b74d5d 100644
--- a/WebCore/page/FrameTree.h
+++ b/WebCore/page/FrameTree.h
@@ -21,10 +21,11 @@
#define FrameTree_h
#include "AtomicString.h"
-#include "Frame.h"
namespace WebCore {
+ class Frame;
+
class FrameTree : Noncopyable {
public:
FrameTree(Frame* thisFrame, Frame* parentFrame)
diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp
index 1d5ef9f..2eefd6c 100644
--- a/WebCore/page/FrameView.cpp
+++ b/WebCore/page/FrameView.cpp
@@ -34,6 +34,7 @@
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
+#include "FrameTree.h"
#include "GraphicsContext.h"
#include "HTMLDocument.h"
#include "HTMLFrameElement.h"
@@ -43,10 +44,11 @@
#include "Page.h"
#include "RenderPart.h"
#include "RenderPartObject.h"
+#include "RenderScrollbar.h"
#include "RenderTheme.h"
#include "RenderView.h"
#include "Settings.h"
-#include "SystemTime.h"
+#include <wtf/CurrentTime.h>
#ifdef ANDROID_INSTRUMENT
#include "FrameTree.h"
@@ -64,110 +66,25 @@ struct ScheduledEvent {
RefPtr<EventTargetNode> m_eventTarget;
};
-class FrameViewPrivate {
-public:
- FrameViewPrivate(FrameView* view)
- : m_slowRepaintObjectCount(0)
- , m_layoutTimer(view, &FrameView::layoutTimerFired)
- , m_layoutRoot(0)
- , m_postLayoutTasksTimer(view, &FrameView::postLayoutTimerFired)
- , m_mediaType("screen")
- , m_enqueueEvents(0)
- , m_overflowStatusDirty(true)
- , m_viewportRenderer(0)
- , m_wasScrolledByUser(false)
- , m_inProgrammaticScroll(false)
- , m_shouldUpdateWhileOffscreen(true)
- {
- m_isTransparent = false;
- m_baseBackgroundColor = Color::white;
- m_vmode = m_hmode = ScrollbarAuto;
- m_needToInitScrollbars = true;
- reset();
- }
- void reset()
- {
- m_useSlowRepaints = false;
- m_borderX = 30;
- m_borderY = 30;
- m_layoutTimer.stop();
- m_layoutRoot = 0;
- m_delayedLayout = false;
- m_doFullRepaint = true;
- m_layoutSchedulingEnabled = true;
- m_midLayout = false;
- m_layoutCount = 0;
- m_nestedLayoutCount = 0;
- m_postLayoutTasksTimer.stop();
- m_firstLayout = true;
- m_firstLayoutCallbackPending = false;
- m_wasScrolledByUser = false;
- m_lastLayoutSize = IntSize();
- m_lastZoomFactor = 1.0f;
- m_deferringRepaints = 0;
- m_repaintCount = 0;
- m_repaintRect = IntRect();
- m_repaintRects.clear();
- m_paintRestriction = PaintRestrictionNone;
- m_isPainting = false;
- }
-
- bool m_doFullRepaint;
-
- ScrollbarMode m_vmode;
- ScrollbarMode m_hmode;
- bool m_useSlowRepaints;
- unsigned m_slowRepaintObjectCount;
-
- int m_borderX, m_borderY;
-
- Timer<FrameView> m_layoutTimer;
- bool m_delayedLayout;
- RenderObject* m_layoutRoot;
-
- bool m_layoutSchedulingEnabled;
- bool m_midLayout;
- int m_layoutCount;
- unsigned m_nestedLayoutCount;
- Timer<FrameView> m_postLayoutTasksTimer;
- bool m_firstLayoutCallbackPending;
-
- bool m_firstLayout;
- bool m_needToInitScrollbars;
- bool m_isTransparent;
- Color m_baseBackgroundColor;
- IntSize m_lastLayoutSize;
- float m_lastZoomFactor;
-
- String m_mediaType;
-
- unsigned m_enqueueEvents;
- Vector<ScheduledEvent*> m_scheduledEvents;
-
- bool m_overflowStatusDirty;
- bool m_horizontalOverflow;
- bool m_verticalOverflow;
- RenderObject* m_viewportRenderer;
-
- bool m_wasScrolledByUser;
- bool m_inProgrammaticScroll;
-
- unsigned m_deferringRepaints;
- unsigned m_repaintCount;
- IntRect m_repaintRect;
- Vector<IntRect> m_repaintRects;
-
- bool m_shouldUpdateWhileOffscreen;
-
- RefPtr<Node> m_nodeToDraw;
- PaintRestriction m_paintRestriction;
- bool m_isPainting;
-};
-
FrameView::FrameView(Frame* frame)
: m_refCount(1)
, m_frame(frame)
- , d(new FrameViewPrivate(this))
+ , m_vmode(ScrollbarAuto)
+ , m_hmode(ScrollbarAuto)
+ , m_slowRepaintObjectCount(0)
+ , m_layoutTimer(this, &FrameView::layoutTimerFired)
+ , m_layoutRoot(0)
+ , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired)
+ , m_needToInitScrollbars(true)
+ , m_isTransparent(false)
+ , m_baseBackgroundColor(Color::white)
+ , m_mediaType("screen")
+ , m_enqueueEvents(0)
+ , m_overflowStatusDirty(true)
+ , m_viewportRenderer(0)
+ , m_wasScrolledByUser(false)
+ , m_inProgrammaticScroll(false)
+ , m_shouldUpdateWhileOffscreen(true)
{
init();
show();
@@ -176,7 +93,22 @@ FrameView::FrameView(Frame* frame)
FrameView::FrameView(Frame* frame, const IntSize& initialSize)
: m_refCount(1)
, m_frame(frame)
- , d(new FrameViewPrivate(this))
+ , m_vmode(ScrollbarAuto)
+ , m_hmode(ScrollbarAuto)
+ , m_slowRepaintObjectCount(0)
+ , m_layoutTimer(this, &FrameView::layoutTimerFired)
+ , m_layoutRoot(0)
+ , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired)
+ , m_needToInitScrollbars(true)
+ , m_isTransparent(false)
+ , m_baseBackgroundColor(Color::white)
+ , m_mediaType("screen")
+ , m_enqueueEvents(0)
+ , m_overflowStatusDirty(true)
+ , m_viewportRenderer(0)
+ , m_wasScrolledByUser(false)
+ , m_inProgrammaticScroll(false)
+ , m_shouldUpdateWhileOffscreen(true)
{
init();
Widget::setFrameRect(IntRect(x(), y(), initialSize.width(), initialSize.height()));
@@ -185,10 +117,10 @@ FrameView::FrameView(Frame* frame, const IntSize& initialSize)
FrameView::~FrameView()
{
- if (d->m_postLayoutTasksTimer.isActive()) {
- d->m_postLayoutTasksTimer.stop();
- d->m_scheduledEvents.clear();
- d->m_enqueueEvents = 0;
+ if (m_postLayoutTasksTimer.isActive()) {
+ m_postLayoutTasksTimer.stop();
+ m_scheduledEvents.clear();
+ m_enqueueEvents = 0;
}
resetScrollbars();
@@ -196,8 +128,8 @@ FrameView::~FrameView()
setHasVerticalScrollbar(false);
ASSERT(m_refCount == 0);
- ASSERT(d->m_scheduledEvents.isEmpty());
- ASSERT(!d->m_enqueueEvents);
+ ASSERT(m_scheduledEvents.isEmpty());
+ ASSERT(!m_enqueueEvents);
if (m_frame) {
ASSERT(m_frame->view() != this || !m_frame->document() || !m_frame->contentRenderer());
@@ -205,9 +137,35 @@ FrameView::~FrameView()
if (renderer && renderer->widget() == this)
renderer->setWidget(0);
}
+}
- delete d;
- d = 0;
+void FrameView::reset()
+{
+ m_useSlowRepaints = false;
+ m_borderX = 30;
+ m_borderY = 30;
+ m_layoutTimer.stop();
+ m_layoutRoot = 0;
+ m_delayedLayout = false;
+ m_doFullRepaint = true;
+ m_layoutSchedulingEnabled = true;
+ m_midLayout = false;
+ m_layoutCount = 0;
+ m_nestedLayoutCount = 0;
+ m_postLayoutTasksTimer.stop();
+ m_firstLayout = true;
+ m_firstLayoutCallbackPending = false;
+ m_wasScrolledByUser = false;
+ m_lastLayoutSize = IntSize();
+ m_lastZoomFactor = 1.0f;
+ m_deferringRepaints = 0;
+ m_repaintCount = 0;
+ m_repaintRect = IntRect();
+ m_repaintRects.clear();
+ m_paintRestriction = PaintRestrictionNone;
+ m_isPainting = false;
+ m_isVisuallyNonEmpty = false;
+ m_firstVisuallyNonEmptyLayoutCallbackPending = true;
}
bool FrameView::isFrameView() const
@@ -223,14 +181,16 @@ void FrameView::clearFrame()
void FrameView::resetScrollbars()
{
// Reset the document's scrollbars back to our defaults before we yield the floor.
- d->m_firstLayout = true;
+ m_firstLayout = true;
setScrollbarsSuppressed(true);
- setScrollbarModes(d->m_hmode, d->m_vmode);
+ setScrollbarModes(m_hmode, m_vmode);
setScrollbarsSuppressed(false);
}
void FrameView::init()
{
+ reset();
+
m_margins = IntSize(-1, -1); // undefined
m_size = IntSize();
@@ -253,28 +213,34 @@ void FrameView::clear()
{
setCanBlitOnScroll(true);
- d->reset();
+ reset();
- if (m_frame)
+ if (m_frame) {
if (RenderPart* renderer = m_frame->ownerRenderer())
renderer->viewCleared();
+ }
setScrollbarsSuppressed(true);
}
bool FrameView::didFirstLayout() const
{
- return !d->m_firstLayout;
+ return !m_firstLayout;
}
void FrameView::initScrollbars()
{
- if (!d->m_needToInitScrollbars)
+ if (!m_needToInitScrollbars)
return;
- d->m_needToInitScrollbars = false;
- d->m_hmode = horizontalScrollbarMode();
- d->m_vmode = verticalScrollbarMode();
- setScrollbarModes(d->m_hmode, d->m_vmode);
+ m_needToInitScrollbars = false;
+ updateDefaultScrollbarState();
+}
+
+void FrameView::updateDefaultScrollbarState()
+{
+ m_hmode = horizontalScrollbarMode();
+ m_vmode = verticalScrollbarMode();
+ setScrollbarModes(m_hmode, m_vmode);
}
void FrameView::invalidateRect(const IntRect& rect)
@@ -313,7 +279,44 @@ void FrameView::setMarginHeight(int h)
void FrameView::setCanHaveScrollbars(bool canScroll)
{
ScrollView::setCanHaveScrollbars(canScroll);
- scrollbarModes(d->m_hmode, d->m_vmode);
+ scrollbarModes(m_hmode, m_vmode);
+}
+
+PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientation)
+{
+ // FIXME: We need to update the scrollbar dynamically as documents change (or as doc elements and bodies get discovered that have custom styles).
+ Document* doc = m_frame->document();
+ if (!doc)
+ return ScrollView::createScrollbar(orientation);
+
+ // Try the <body> element first as a scrollbar source.
+ Element* body = doc->body();
+ if (body && body->renderer() && body->renderer()->style()->hasPseudoStyle(RenderStyle::SCROLLBAR))
+ return RenderScrollbar::createCustomScrollbar(this, orientation, body->renderBox());
+
+ // If the <body> didn't have a custom style, then the root element might.
+ Element* docElement = doc->documentElement();
+ if (docElement && docElement->renderer() && docElement->renderer()->style()->hasPseudoStyle(RenderStyle::SCROLLBAR))
+ return RenderScrollbar::createCustomScrollbar(this, orientation, docElement->renderBox());
+
+ // If we have an owning iframe/frame element, then it can set the custom scrollbar also.
+ RenderPart* frameRenderer = m_frame->ownerRenderer();
+ if (frameRenderer && frameRenderer->style()->hasPseudoStyle(RenderStyle::SCROLLBAR))
+ return RenderScrollbar::createCustomScrollbar(this, orientation, frameRenderer);
+
+ // Nobody set a custom style, so we just use a native scrollbar.
+ return ScrollView::createScrollbar(orientation);
+}
+
+void FrameView::setContentsSize(const IntSize& size)
+{
+ ScrollView::setContentsSize(size);
+
+ Page* page = frame() ? frame()->page() : 0;
+ if (!page)
+ return;
+
+ page->chrome()->contentsSizeChanged(frame(), size); //notify only
}
void FrameView::adjustViewSize()
@@ -361,31 +364,21 @@ void FrameView::applyOverflowToViewport(RenderObject* o, ScrollbarMode& hMode, S
;
}
- d->m_viewportRenderer = o;
-}
-
-int FrameView::layoutCount() const
-{
- return d->m_layoutCount;
-}
-
-bool FrameView::needsFullRepaint() const
-{
- return d->m_doFullRepaint;
+ m_viewportRenderer = o;
}
RenderObject* FrameView::layoutRoot(bool onlyDuringLayout) const
{
- return onlyDuringLayout && layoutPending() ? 0 : d->m_layoutRoot;
+ return onlyDuringLayout && layoutPending() ? 0 : m_layoutRoot;
}
void FrameView::layout(bool allowSubtree)
{
- if (d->m_midLayout)
+ if (m_midLayout)
return;
- d->m_layoutTimer.stop();
- d->m_delayedLayout = false;
+ m_layoutTimer.stop();
+ m_delayedLayout = false;
// Protect the view from being deleted during layout (in recalcStyle)
RefPtr<FrameView> protector(this);
@@ -393,7 +386,7 @@ void FrameView::layout(bool allowSubtree)
if (!m_frame) {
// FIXME: Do we need to set m_size.width here?
// FIXME: Should we set m_size.height here too?
- m_size.setWidth(visibleWidth());
+ m_size.setWidth(layoutWidth());
return;
}
@@ -402,9 +395,9 @@ void FrameView::layout(bool allowSubtree)
if (isPainting())
return;
- if (!allowSubtree && d->m_layoutRoot) {
- d->m_layoutRoot->markContainingBlocksForLayout(false);
- d->m_layoutRoot = 0;
+ if (!allowSubtree && m_layoutRoot) {
+ m_layoutRoot->markContainingBlocksForLayout(false);
+ m_layoutRoot = 0;
}
ASSERT(m_frame->view() == this);
@@ -417,16 +410,16 @@ void FrameView::layout(bool allowSubtree)
Document* document = m_frame->document();
if (!document) {
// FIXME: Should we set m_size.height here too?
- m_size.setWidth(visibleWidth());
+ m_size.setWidth(layoutWidth());
return;
}
- d->m_layoutSchedulingEnabled = false;
+ m_layoutSchedulingEnabled = false;
- if (!d->m_nestedLayoutCount && d->m_postLayoutTasksTimer.isActive()) {
+ if (!m_nestedLayoutCount && m_postLayoutTasksTimer.isActive()) {
// This is a new top-level layout. If there are any remaining tasks from the previous
// layout, finish them now.
- d->m_postLayoutTasksTimer.stop();
+ m_postLayoutTasksTimer.stop();
performPostLayoutTasks();
}
@@ -442,17 +435,17 @@ void FrameView::layout(bool allowSubtree)
else if (document->hasChangedChild())
document->recalcStyle();
- bool subtree = d->m_layoutRoot;
+ bool subtree = m_layoutRoot;
// If there is only one ref to this view left, then its going to be destroyed as soon as we exit,
// so there's no point to continuing to layout
if (protector->hasOneRef())
return;
- RenderObject* root = subtree ? d->m_layoutRoot : document->renderer();
+ RenderObject* root = subtree ? m_layoutRoot : document->renderer();
if (!root) {
// FIXME: Do we need to set m_size here?
- d->m_layoutSchedulingEnabled = true;
+ m_layoutSchedulingEnabled = true;
return;
}
@@ -461,10 +454,10 @@ void FrameView::layout(bool allowSubtree)
android::TimeCounter::start(android::TimeCounter::LayoutTimeCounter);
#endif
- d->m_nestedLayoutCount++;
+ m_nestedLayoutCount++;
- ScrollbarMode hMode = d->m_hmode;
- ScrollbarMode vMode = d->m_vmode;
+ ScrollbarMode hMode = m_hmode;
+ ScrollbarMode vMode = m_vmode;
if (!subtree) {
RenderObject* rootRenderer = document->documentElement() ? document->documentElement()->renderer() : 0;
@@ -475,8 +468,8 @@ void FrameView::layout(bool allowSubtree)
vMode = ScrollbarAlwaysOff;
hMode = ScrollbarAlwaysOff;
} else if (body->hasTagName(bodyTag)) {
- if (!d->m_firstLayout && m_size.height() != visibleHeight()
- && static_cast<RenderBox*>(body->renderer())->stretchesToViewHeight())
+ if (!m_firstLayout && m_size.height() != layoutHeight()
+ && toRenderBox(body->renderer())->stretchesToViewHeight())
body->renderer()->setChildNeedsLayout(true);
// It's sufficient to just check the X overflow,
// since it's illegal to have visible in only one direction.
@@ -486,25 +479,25 @@ void FrameView::layout(bool allowSubtree)
} else if (rootRenderer)
applyOverflowToViewport(rootRenderer, hMode, vMode);
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
- if (d->m_firstLayout && !document->ownerElement())
+ if (m_firstLayout && !document->ownerElement())
printf("Elapsed time before first layout: %d\n", document->elapsedTime());
#endif
}
- d->m_doFullRepaint = !subtree && (d->m_firstLayout || static_cast<RenderView*>(root)->printing());
+ m_doFullRepaint = !subtree && (m_firstLayout || static_cast<RenderView*>(root)->printing());
if (!subtree) {
// Now set our scrollbar state for the layout.
ScrollbarMode currentHMode = horizontalScrollbarMode();
ScrollbarMode currentVMode = verticalScrollbarMode();
- if (d->m_firstLayout || (hMode != currentHMode || vMode != currentVMode)) {
+ if (m_firstLayout || (hMode != currentHMode || vMode != currentVMode)) {
setScrollbarsSuppressed(true);
- if (d->m_firstLayout) {
- d->m_firstLayout = false;
- d->m_firstLayoutCallbackPending = true;
- d->m_lastLayoutSize = IntSize(width(), height());
- d->m_lastZoomFactor = root->style()->zoom();
+ if (m_firstLayout) {
+ m_firstLayout = false;
+ m_firstLayoutCallbackPending = true;
+ m_lastLayoutSize = IntSize(width(), height());
+ m_lastZoomFactor = root->style()->zoom();
// Set the initial vMode to AlwaysOn if we're auto.
if (vMode == ScrollbarAuto)
@@ -519,12 +512,12 @@ void FrameView::layout(bool allowSubtree)
IntSize oldSize = m_size;
- m_size = IntSize(visibleWidth(), visibleHeight());
+ m_size = IntSize(layoutWidth(), layoutHeight());
if (oldSize != m_size)
- d->m_doFullRepaint = true;
+ m_doFullRepaint = true;
}
-
+
RenderLayer* layer = root->enclosingLayer();
pauseScheduledEvents();
@@ -532,29 +525,29 @@ void FrameView::layout(bool allowSubtree)
if (subtree)
root->view()->pushLayoutState(root);
- d->m_midLayout = true;
+ m_midLayout = true;
beginDeferredRepaints();
root->layout();
endDeferredRepaints();
- d->m_midLayout = false;
+ m_midLayout = false;
if (subtree)
root->view()->popLayoutState();
- d->m_layoutRoot = 0;
+ m_layoutRoot = 0;
m_frame->invalidateSelection();
- d->m_layoutSchedulingEnabled = true;
+ m_layoutSchedulingEnabled = true;
if (!subtree && !static_cast<RenderView*>(root)->printing())
adjustViewSize();
// Now update the positions of all layers.
beginDeferredRepaints();
- layer->updateLayerPositions(d->m_doFullRepaint);
+ layer->updateLayerPositions(m_doFullRepaint);
endDeferredRepaints();
- d->m_layoutCount++;
+ m_layoutCount++;
#if PLATFORM(MAC)
if (AXObjectCache::accessibilityEnabled())
@@ -573,10 +566,10 @@ void FrameView::layout(bool allowSubtree)
setCanBlitOnScroll(!useSlowRepaints());
if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
- updateOverflowStatus(visibleWidth() < contentsWidth(),
- visibleHeight() < contentsHeight());
+ updateOverflowStatus(layoutWidth() < contentsWidth(),
+ layoutHeight() < contentsHeight());
- if (!d->m_postLayoutTasksTimer.isActive()) {
+ if (!m_postLayoutTasksTimer.isActive()) {
// Calls resumeScheduledEvents()
performPostLayoutTasks();
@@ -584,16 +577,16 @@ void FrameView::layout(bool allowSubtree)
// Post-layout widget updates or an event handler made us need layout again.
// Lay out again, but this time defer widget updates and event dispatch until after
// we return.
- d->m_postLayoutTasksTimer.startOneShot(0);
+ m_postLayoutTasksTimer.startOneShot(0);
pauseScheduledEvents();
layout();
}
} else {
resumeScheduledEvents();
- ASSERT(d->m_enqueueEvents);
+ ASSERT(m_enqueueEvents);
}
- d->m_nestedLayoutCount--;
+ m_nestedLayoutCount--;
}
void FrameView::addWidgetToUpdate(RenderPartObject* object)
@@ -614,7 +607,7 @@ void FrameView::removeWidgetToUpdate(RenderPartObject* object)
void FrameView::setMediaType(const String& mediaType)
{
- d->m_mediaType = mediaType;
+ m_mediaType = mediaType;
}
String FrameView::mediaType() const
@@ -623,33 +616,33 @@ String FrameView::mediaType() const
String overrideType = m_frame->loader()->client()->overrideMediaType();
if (!overrideType.isNull())
return overrideType;
- return d->m_mediaType;
+ return m_mediaType;
}
bool FrameView::useSlowRepaints() const
{
- return d->m_useSlowRepaints || d->m_slowRepaintObjectCount > 0;
+ return m_useSlowRepaints || m_slowRepaintObjectCount > 0;
}
void FrameView::setUseSlowRepaints()
{
- d->m_useSlowRepaints = true;
+ m_useSlowRepaints = true;
setCanBlitOnScroll(false);
}
void FrameView::addSlowRepaintObject()
{
- if (!d->m_slowRepaintObjectCount)
+ if (!m_slowRepaintObjectCount)
setCanBlitOnScroll(false);
- d->m_slowRepaintObjectCount++;
+ m_slowRepaintObjectCount++;
}
void FrameView::removeSlowRepaintObject()
{
- ASSERT(d->m_slowRepaintObjectCount > 0);
- d->m_slowRepaintObjectCount--;
- if (!d->m_slowRepaintObjectCount)
- setCanBlitOnScroll(!d->m_useSlowRepaints);
+ ASSERT(m_slowRepaintObjectCount > 0);
+ m_slowRepaintObjectCount--;
+ if (!m_slowRepaintObjectCount)
+ setCanBlitOnScroll(!m_useSlowRepaints);
}
void FrameView::restoreScrollbar()
@@ -659,18 +652,18 @@ void FrameView::restoreScrollbar()
void FrameView::scrollRectIntoViewRecursively(const IntRect& r)
{
- bool wasInProgrammaticScroll = d->m_inProgrammaticScroll;
- d->m_inProgrammaticScroll = true;
+ bool wasInProgrammaticScroll = m_inProgrammaticScroll;
+ m_inProgrammaticScroll = true;
ScrollView::scrollRectIntoViewRecursively(r);
- d->m_inProgrammaticScroll = wasInProgrammaticScroll;
+ m_inProgrammaticScroll = wasInProgrammaticScroll;
}
void FrameView::setScrollPosition(const IntPoint& scrollPoint)
{
- bool wasInProgrammaticScroll = d->m_inProgrammaticScroll;
- d->m_inProgrammaticScroll = true;
+ bool wasInProgrammaticScroll = m_inProgrammaticScroll;
+ m_inProgrammaticScroll = true;
ScrollView::setScrollPosition(scrollPoint);
- d->m_inProgrammaticScroll = wasInProgrammaticScroll;
+ m_inProgrammaticScroll = wasInProgrammaticScroll;
}
HostWindow* FrameView::hostWindow() const
@@ -687,16 +680,16 @@ void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
{
ASSERT(!m_frame->document()->ownerElement());
- if (d->m_deferringRepaints && !immediate) {
+ if (m_deferringRepaints && !immediate) {
IntRect visibleContent = visibleContentRect();
visibleContent.intersect(r);
if (!visibleContent.isEmpty()) {
- d->m_repaintCount++;
- d->m_repaintRect.unite(r);
- if (d->m_repaintCount == cRepaintRectUnionThreshold)
- d->m_repaintRects.clear();
- else if (d->m_repaintCount < cRepaintRectUnionThreshold)
- d->m_repaintRects.append(r);
+ m_repaintCount++;
+ m_repaintRect.unite(r);
+ if (m_repaintCount == cRepaintRectUnionThreshold)
+ m_repaintRects.clear();
+ else if (m_repaintCount < cRepaintRectUnionThreshold)
+ m_repaintRects.append(r);
}
#ifdef ANDROID_CAPTURE_OFFSCREEN_PAINTS
else
@@ -717,13 +710,13 @@ void FrameView::beginDeferredRepaints()
if (page->mainFrame() != m_frame)
return page->mainFrame()->view()->beginDeferredRepaints();
- d->m_deferringRepaints++;
+ m_deferringRepaints++;
#ifdef ANDROID_FIX // This allows sub frames to accumulate deferred repaints
- if (d->m_deferringRepaints == 1) {
+ if (m_deferringRepaints == 1) {
#endif
- d->m_repaintCount = 0;
- d->m_repaintRect = IntRect();
- d->m_repaintRects.clear();
+ m_repaintCount = 0;
+ m_repaintRect = IntRect();
+ m_repaintRects.clear();
#ifdef ANDROID_FIX
}
#endif
@@ -736,15 +729,15 @@ void FrameView::endDeferredRepaints()
if (page->mainFrame() != m_frame)
return page->mainFrame()->view()->endDeferredRepaints();
- ASSERT(d->m_deferringRepaints > 0);
- if (--d->m_deferringRepaints == 0) {
- if (d->m_repaintCount >= cRepaintRectUnionThreshold)
- repaintContentRectangle(d->m_repaintRect, false);
+ ASSERT(m_deferringRepaints > 0);
+ if (--m_deferringRepaints == 0) {
+ if (m_repaintCount >= cRepaintRectUnionThreshold)
+ repaintContentRectangle(m_repaintRect, false);
else {
- unsigned size = d->m_repaintRects.size();
+ unsigned size = m_repaintRects.size();
for (unsigned i = 0; i < size; i++)
- repaintContentRectangle(d->m_repaintRects[i], false);
- d->m_repaintRects.clear();
+ repaintContentRectangle(m_repaintRects[i], false);
+ m_repaintRects.clear();
}
}
}
@@ -763,13 +756,14 @@ void FrameView::scheduleRelayout()
ASSERT(!m_frame->document() || !m_frame->document()->inPageCache());
ASSERT(m_frame->view() == this);
- if (d->m_layoutRoot) {
- d->m_layoutRoot->markContainingBlocksForLayout(false);
- d->m_layoutRoot = 0;
+ if (m_layoutRoot) {
+ m_layoutRoot->markContainingBlocksForLayout(false);
+ m_layoutRoot = 0;
}
- if (!d->m_layoutSchedulingEnabled)
+ if (!m_layoutSchedulingEnabled)
+ return;
+ if (!needsLayout())
return;
-
if (!m_frame->document() || !m_frame->document()->shouldScheduleLayout())
return;
@@ -783,19 +777,19 @@ void FrameView::scheduleRelayout()
#else
int delay = m_frame->document()->minimumLayoutDelay();
#endif
- if (d->m_layoutTimer.isActive() && d->m_delayedLayout && !delay)
+ if (m_layoutTimer.isActive() && m_delayedLayout && !delay)
unscheduleRelayout();
- if (d->m_layoutTimer.isActive())
+ if (m_layoutTimer.isActive())
return;
- d->m_delayedLayout = delay != 0;
+ m_delayedLayout = delay != 0;
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
if (!m_frame->document()->ownerElement())
printf("Scheduling layout for %d\n", delay);
#endif
- d->m_layoutTimer.startOneShot(delay * 0.001);
+ m_layoutTimer.startOneShot(delay * 0.001);
}
static bool isObjectAncestorContainerOf(RenderObject* ancestor, RenderObject* descendant)
@@ -811,7 +805,7 @@ void FrameView::scheduleRelayoutOfSubtree(RenderObject* relayoutRoot)
{
ASSERT(m_frame->view() == this);
- if (!d->m_layoutSchedulingEnabled || (m_frame->contentRenderer()
+ if (!m_layoutSchedulingEnabled || (m_frame->contentRenderer()
&& m_frame->contentRenderer()->needsLayout())) {
if (relayoutRoot)
relayoutRoot->markContainingBlocksForLayout(false);
@@ -819,19 +813,19 @@ void FrameView::scheduleRelayoutOfSubtree(RenderObject* relayoutRoot)
}
if (layoutPending()) {
- if (d->m_layoutRoot != relayoutRoot) {
- if (isObjectAncestorContainerOf(d->m_layoutRoot, relayoutRoot)) {
+ if (m_layoutRoot != relayoutRoot) {
+ if (isObjectAncestorContainerOf(m_layoutRoot, relayoutRoot)) {
// Keep the current root
- relayoutRoot->markContainingBlocksForLayout(false, d->m_layoutRoot);
- } else if (d->m_layoutRoot && isObjectAncestorContainerOf(relayoutRoot, d->m_layoutRoot)) {
+ relayoutRoot->markContainingBlocksForLayout(false, m_layoutRoot);
+ } else if (m_layoutRoot && isObjectAncestorContainerOf(relayoutRoot, m_layoutRoot)) {
// Re-root at relayoutRoot
- d->m_layoutRoot->markContainingBlocksForLayout(false, relayoutRoot);
- d->m_layoutRoot = relayoutRoot;
+ m_layoutRoot->markContainingBlocksForLayout(false, relayoutRoot);
+ m_layoutRoot = relayoutRoot;
} else {
// Just do a full relayout
- if (d->m_layoutRoot)
- d->m_layoutRoot->markContainingBlocksForLayout(false);
- d->m_layoutRoot = 0;
+ if (m_layoutRoot)
+ m_layoutRoot->markContainingBlocksForLayout(false);
+ m_layoutRoot = 0;
relayoutRoot->markContainingBlocksForLayout(false);
}
}
@@ -841,27 +835,31 @@ void FrameView::scheduleRelayoutOfSubtree(RenderObject* relayoutRoot)
#else
int delay = m_frame->document()->minimumLayoutDelay();
#endif
- d->m_layoutRoot = relayoutRoot;
- d->m_delayedLayout = delay != 0;
- d->m_layoutTimer.startOneShot(delay * 0.001);
+ m_layoutRoot = relayoutRoot;
+ m_delayedLayout = delay != 0;
+ m_layoutTimer.startOneShot(delay * 0.001);
}
}
bool FrameView::layoutPending() const
{
- return d->m_layoutTimer.isActive();
+ return m_layoutTimer.isActive();
}
bool FrameView::needsLayout() const
{
- // It is possible that our document will not have a body yet. If this is the case,
- // then we are not allowed to schedule layouts yet, so we won't be pending layout.
+ // This can return true in cases where the document does not have a body yet.
+ // Document::shouldScheduleLayout takes care of preventing us from scheduling
+ // layout in that case.
if (!m_frame)
return false;
RenderView* root = m_frame->contentRenderer();
- Document * doc = m_frame->document();
- // doc->hasChangedChild() condition can occur when using WebKit ObjC interface
- return layoutPending() || (root && root->needsLayout()) || d->m_layoutRoot || (doc && doc->hasChangedChild()) || m_frame->needsReapplyStyles();
+ Document* document = m_frame->document();
+ return layoutPending()
+ || (root && root->needsLayout())
+ || m_layoutRoot
+ || (document && document->hasChangedChild()) // can occur when using WebKit ObjC interface
+ || m_frame->needsReapplyStyles();
}
void FrameView::setNeedsLayout()
@@ -873,7 +871,7 @@ void FrameView::setNeedsLayout()
void FrameView::unscheduleRelayout()
{
- if (!d->m_layoutTimer.isActive())
+ if (!m_layoutTimer.isActive())
return;
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
@@ -881,45 +879,57 @@ void FrameView::unscheduleRelayout()
printf("Layout timer unscheduled at %d\n", m_frame->document()->elapsedTime());
#endif
- d->m_layoutTimer.stop();
- d->m_delayedLayout = false;
+ m_layoutTimer.stop();
+ m_delayedLayout = false;
}
bool FrameView::isTransparent() const
{
- return d->m_isTransparent;
+ return m_isTransparent;
}
void FrameView::setTransparent(bool isTransparent)
{
- d->m_isTransparent = isTransparent;
+ m_isTransparent = isTransparent;
}
Color FrameView::baseBackgroundColor() const
{
- return d->m_baseBackgroundColor;
+ return m_baseBackgroundColor;
}
void FrameView::setBaseBackgroundColor(Color bc)
{
if (!bc.isValid())
bc = Color::white;
- d->m_baseBackgroundColor = bc;
+ m_baseBackgroundColor = bc;
+}
+
+void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool transparent)
+{
+ for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
+ FrameView* view = frame->view();
+ if (!view)
+ continue;
+
+ view->setTransparent(transparent);
+ view->setBaseBackgroundColor(backgroundColor);
+ }
}
bool FrameView::shouldUpdateWhileOffscreen() const
{
- return d->m_shouldUpdateWhileOffscreen;
+ return m_shouldUpdateWhileOffscreen;
}
void FrameView::setShouldUpdateWhileOffscreen(bool shouldUpdateWhileOffscreen)
{
- d->m_shouldUpdateWhileOffscreen = shouldUpdateWhileOffscreen;
+ m_shouldUpdateWhileOffscreen = shouldUpdateWhileOffscreen;
}
void FrameView::scheduleEvent(PassRefPtr<Event> event, PassRefPtr<EventTargetNode> eventTarget)
{
- if (!d->m_enqueueEvents) {
+ if (!m_enqueueEvents) {
ExceptionCode ec = 0;
eventTarget->dispatchEvent(event, ec);
return;
@@ -928,34 +938,39 @@ void FrameView::scheduleEvent(PassRefPtr<Event> event, PassRefPtr<EventTargetNod
ScheduledEvent* scheduledEvent = new ScheduledEvent;
scheduledEvent->m_event = event;
scheduledEvent->m_eventTarget = eventTarget;
- d->m_scheduledEvents.append(scheduledEvent);
+ m_scheduledEvents.append(scheduledEvent);
}
void FrameView::pauseScheduledEvents()
{
- ASSERT(d->m_scheduledEvents.isEmpty() || d->m_enqueueEvents);
- d->m_enqueueEvents++;
+ ASSERT(m_scheduledEvents.isEmpty() || m_enqueueEvents);
+ m_enqueueEvents++;
}
void FrameView::resumeScheduledEvents()
{
- d->m_enqueueEvents--;
- if (!d->m_enqueueEvents)
+ m_enqueueEvents--;
+ if (!m_enqueueEvents)
dispatchScheduledEvents();
- ASSERT(d->m_scheduledEvents.isEmpty() || d->m_enqueueEvents);
+ ASSERT(m_scheduledEvents.isEmpty() || m_enqueueEvents);
}
void FrameView::performPostLayoutTasks()
{
- if (d->m_firstLayoutCallbackPending) {
- d->m_firstLayoutCallbackPending = false;
+ if (m_firstLayoutCallbackPending) {
+ m_firstLayoutCallbackPending = false;
m_frame->loader()->didFirstLayout();
}
-
+
+ if (m_isVisuallyNonEmpty && m_firstVisuallyNonEmptyLayoutCallbackPending) {
+ m_firstVisuallyNonEmptyLayoutCallbackPending = false;
+ m_frame->loader()->didFirstVisuallyNonEmptyLayout();
+ }
+
RenderView* root = m_frame->contentRenderer();
root->updateWidgetPositions();
- if (m_widgetUpdateSet && d->m_nestedLayoutCount <= 1) {
+ if (m_widgetUpdateSet && m_nestedLayoutCount <= 1) {
Vector<RenderPartObject*> objectVector;
copyToVector(*m_widgetUpdateSet, objectVector);
size_t size = objectVector.size();
@@ -976,9 +991,9 @@ void FrameView::performPostLayoutTasks()
if (!root->printing()) {
IntSize currentSize = IntSize(width(), height());
float currentZoomFactor = root->style()->zoom();
- bool resized = !d->m_firstLayout && (currentSize != d->m_lastLayoutSize || currentZoomFactor != d->m_lastZoomFactor);
- d->m_lastLayoutSize = currentSize;
- d->m_lastZoomFactor = currentZoomFactor;
+ bool resized = !m_firstLayout && (currentSize != m_lastLayoutSize || currentZoomFactor != m_lastZoomFactor);
+ m_lastLayoutSize = currentSize;
+ m_lastZoomFactor = currentZoomFactor;
if (resized)
m_frame->sendResizeEvent();
}
@@ -991,37 +1006,37 @@ void FrameView::postLayoutTimerFired(Timer<FrameView>*)
void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow)
{
- if (!d->m_viewportRenderer)
+ if (!m_viewportRenderer)
return;
- if (d->m_overflowStatusDirty) {
- d->m_horizontalOverflow = horizontalOverflow;
- d->m_verticalOverflow = verticalOverflow;
- d->m_overflowStatusDirty = false;
+ if (m_overflowStatusDirty) {
+ m_horizontalOverflow = horizontalOverflow;
+ m_verticalOverflow = verticalOverflow;
+ m_overflowStatusDirty = false;
return;
}
- bool horizontalOverflowChanged = (d->m_horizontalOverflow != horizontalOverflow);
- bool verticalOverflowChanged = (d->m_verticalOverflow != verticalOverflow);
+ bool horizontalOverflowChanged = (m_horizontalOverflow != horizontalOverflow);
+ bool verticalOverflowChanged = (m_verticalOverflow != verticalOverflow);
if (horizontalOverflowChanged || verticalOverflowChanged) {
- d->m_horizontalOverflow = horizontalOverflow;
- d->m_verticalOverflow = verticalOverflow;
+ m_horizontalOverflow = horizontalOverflow;
+ m_verticalOverflow = verticalOverflow;
scheduleEvent(OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow,
verticalOverflowChanged, verticalOverflow),
- EventTargetNodeCast(d->m_viewportRenderer->element()));
+ EventTargetNodeCast(m_viewportRenderer->element()));
}
}
void FrameView::dispatchScheduledEvents()
{
- if (d->m_scheduledEvents.isEmpty())
+ if (m_scheduledEvents.isEmpty())
return;
- Vector<ScheduledEvent*> scheduledEventsCopy = d->m_scheduledEvents;
- d->m_scheduledEvents.clear();
+ Vector<ScheduledEvent*> scheduledEventsCopy = m_scheduledEvents;
+ m_scheduledEvents.clear();
Vector<ScheduledEvent*>::iterator end = scheduledEventsCopy.end();
for (Vector<ScheduledEvent*>::iterator it = scheduledEventsCopy.begin(); it != end; ++it) {
@@ -1096,6 +1111,11 @@ void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rec
invalidateRect(dirtyRect);
}
+void FrameView::getTickmarks(Vector<IntRect>& tickmarks) const
+{
+ tickmarks = frame()->document()->renderedRectsForMarkers(DocumentMarker::TextMatch);
+}
+
IntRect FrameView::windowResizerRect() const
{
Page* page = frame() ? frame()->page() : 0;
@@ -1111,7 +1131,7 @@ void FrameView::updateDashboardRegions()
if (!document->hasDashboardRegions())
return;
Vector<DashboardRegionValue> newRegions;
- document->renderer()->collectDashboardRegions(newRegions);
+ document->renderBox()->collectDashboardRegions(newRegions);
if (newRegions == document->dashboardRegions())
return;
document->setDashboardRegions(newRegions);
@@ -1148,14 +1168,14 @@ void FrameView::updateControlTints()
bool FrameView::wasScrolledByUser() const
{
- return d->m_wasScrolledByUser;
+ return m_wasScrolledByUser;
}
void FrameView::setWasScrolledByUser(bool wasScrolledByUser)
{
- if (d->m_inProgrammaticScroll)
+ if (m_inProgrammaticScroll)
return;
- d->m_wasScrolledByUser = wasScrolledByUser;
+ m_wasScrolledByUser = wasScrolledByUser;
}
void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
@@ -1175,9 +1195,9 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
fillWithRed = false; // Subframe, don't fill with red.
else if (isTransparent())
fillWithRed = false; // Transparent, don't fill with red.
- else if (d->m_paintRestriction == PaintRestrictionSelectionOnly || d->m_paintRestriction == PaintRestrictionSelectionOnlyBlackText)
+ else if (m_paintRestriction == PaintRestrictionSelectionOnly || m_paintRestriction == PaintRestrictionSelectionOnlyBlackText)
fillWithRed = false; // Selections are transparent, don't fill with red.
- else if (d->m_nodeToDraw)
+ else if (m_nodeToDraw)
fillWithRed = false; // Element images are transparent, don't fill with red.
else
fillWithRed = true;
@@ -1197,17 +1217,17 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
}
ASSERT(!needsLayout());
- ASSERT(!d->m_isPainting);
+ ASSERT(!m_isPainting);
- d->m_isPainting = true;
+ m_isPainting = true;
// m_nodeToDraw is used to draw only one element (and its descendants)
- RenderObject* eltRenderer = d->m_nodeToDraw ? d->m_nodeToDraw->renderer() : 0;
- if (d->m_paintRestriction == PaintRestrictionNone)
+ RenderObject* eltRenderer = m_nodeToDraw ? m_nodeToDraw->renderer() : 0;
+ if (m_paintRestriction == PaintRestrictionNone)
document->invalidateRenderedRectsForMarkersInRect(rect);
- contentRenderer->layer()->paint(p, rect, d->m_paintRestriction, eltRenderer);
+ contentRenderer->layer()->paint(p, rect, m_paintRestriction, eltRenderer);
- d->m_isPainting = false;
+ m_isPainting = false;
#if ENABLE(DASHBOARD_SUPPORT)
// Regions may have changed as a result of the visibility/z-index of element changing.
@@ -1221,17 +1241,17 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
void FrameView::setPaintRestriction(PaintRestriction pr)
{
- d->m_paintRestriction = pr;
+ m_paintRestriction = pr;
}
bool FrameView::isPainting() const
{
- return d->m_isPainting;
+ return m_isPainting;
}
void FrameView::setNodeToDraw(Node* node)
{
- d->m_nodeToDraw = node;
+ m_nodeToDraw = node;
}
void FrameView::layoutIfNeededRecursive()
@@ -1255,4 +1275,4 @@ void FrameView::layoutIfNeededRecursive()
static_cast<FrameView*>(*current)->layoutIfNeededRecursive();
}
-}
+} // namespace WebCore
diff --git a/WebCore/page/FrameView.h b/WebCore/page/FrameView.h
index 84a829f..a1d514f 100644
--- a/WebCore/page/FrameView.h
+++ b/WebCore/page/FrameView.h
@@ -4,7 +4,7 @@
(C) 1998, 1999 Torben Weis (weis@kde.org)
(C) 1999 Lars Knoll (knoll@kde.org)
(C) 1999 Antti Koivisto (koivisto@kde.org)
- Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -39,11 +39,12 @@ class EventTargetNode;
class Frame;
class FrameViewPrivate;
class IntRect;
-class PlatformMouseEvent;
class Node;
+class PlatformMouseEvent;
class RenderLayer;
class RenderObject;
class RenderPartObject;
+class ScheduledEvent;
class String;
template <typename T> class Timer;
@@ -75,6 +76,10 @@ public:
virtual void setCanHaveScrollbars(bool);
+ virtual PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation);
+
+ virtual void setContentsSize(const IntSize&);
+
void layout(bool allowSubtree = true);
bool didFirstLayout() const;
void layoutTimerFired(Timer<FrameView>*);
@@ -84,13 +89,13 @@ public:
bool layoutPending() const;
RenderObject* layoutRoot(bool onlyDuringLayout = false) const;
- int layoutCount() const;
+ int layoutCount() const { return m_layoutCount; }
// These two helper functions just pass through to the RenderView.
bool needsLayout() const;
void setNeedsLayout();
- bool needsFullRepaint() const;
+ bool needsFullRepaint() const { return m_doFullRepaint; }
void resetScrollbars();
@@ -101,12 +106,14 @@ public:
Color baseBackgroundColor() const;
void setBaseBackgroundColor(Color);
+ void updateBackgroundRecursively(const Color&, bool);
bool shouldUpdateWhileOffscreen() const;
void setShouldUpdateWhileOffscreen(bool);
void adjustViewSize();
void initScrollbars();
+ void updateDefaultScrollbarState();
virtual IntRect windowClipRect(bool clipToContents = true) const;
IntRect windowClipRectForLayer(const RenderLayer*, bool clipToLayerContents) const;
@@ -114,7 +121,8 @@ public:
virtual bool isActive() const;
virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
virtual void valueChanged(Scrollbar*);
-
+ virtual void getTickmarks(Vector<IntRect>&) const;
+
virtual IntRect windowResizerRect() const;
virtual void scrollRectIntoViewRecursively(const IntRect&);
@@ -158,7 +166,10 @@ public:
void layoutIfNeededRecursive();
+ void setIsVisuallyNonEmpty() { m_isVisuallyNonEmpty = true; }
+
private:
+ void reset();
void init();
virtual bool isFrameView() const;
@@ -183,9 +194,62 @@ private:
IntSize m_margins;
OwnPtr<HashSet<RenderPartObject*> > m_widgetUpdateSet;
RefPtr<Frame> m_frame;
- FrameViewPrivate* d;
+
+ bool m_doFullRepaint;
+
+ ScrollbarMode m_vmode;
+ ScrollbarMode m_hmode;
+ bool m_useSlowRepaints;
+ unsigned m_slowRepaintObjectCount;
+
+ int m_borderX, m_borderY;
+
+ Timer<FrameView> m_layoutTimer;
+ bool m_delayedLayout;
+ RenderObject* m_layoutRoot;
+
+ bool m_layoutSchedulingEnabled;
+ bool m_midLayout;
+ int m_layoutCount;
+ unsigned m_nestedLayoutCount;
+ Timer<FrameView> m_postLayoutTasksTimer;
+ bool m_firstLayoutCallbackPending;
+
+ bool m_firstLayout;
+ bool m_needToInitScrollbars;
+ bool m_isTransparent;
+ Color m_baseBackgroundColor;
+ IntSize m_lastLayoutSize;
+ float m_lastZoomFactor;
+
+ String m_mediaType;
+
+ unsigned m_enqueueEvents;
+ Vector<ScheduledEvent*> m_scheduledEvents;
+
+ bool m_overflowStatusDirty;
+ bool m_horizontalOverflow;
+ bool m_verticalOverflow;
+ RenderObject* m_viewportRenderer;
+
+ bool m_wasScrolledByUser;
+ bool m_inProgrammaticScroll;
+
+ unsigned m_deferringRepaints;
+ unsigned m_repaintCount;
+ IntRect m_repaintRect;
+ Vector<IntRect> m_repaintRects;
+
+ bool m_shouldUpdateWhileOffscreen;
+
+ RefPtr<Node> m_nodeToDraw;
+ PaintRestriction m_paintRestriction;
+ bool m_isPainting;
+
+ bool m_isVisuallyNonEmpty;
+ bool m_firstVisuallyNonEmptyLayoutCallbackPending;
};
-}
+} // namespace WebCore
-#endif
+#endif // FrameView_h
diff --git a/WebCore/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp
index a0c9694..f82e95d 100644
--- a/WebCore/page/Geolocation.cpp
+++ b/WebCore/page/Geolocation.cpp
@@ -47,7 +47,7 @@ void Geolocation::GeoNotifier::timerFired(Timer<GeoNotifier>*)
m_timer.stop();
- RefPtr<PositionError> error = PositionError::create(PositionError::TIMEOUT_ERROR, "Timed out");
+ RefPtr<PositionError> error = PositionError::create(PositionError::TIMEOUT, "Timed out");
m_errorCallback->handleEvent(error.get());
}
@@ -73,7 +73,7 @@ void Geolocation::getCurrentPosition(PassRefPtr<PositionCallback> successCallbac
if (!m_service->startUpdating(options)) {
if (notifier->m_errorCallback) {
- RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_ERROR, "Unable to Start");
+ RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, "Unable to Start");
notifier->m_errorCallback->handleEvent(error.get());
}
return;
@@ -88,7 +88,7 @@ int Geolocation::watchPosition(PassRefPtr<PositionCallback> successCallback, Pas
if (!m_service->startUpdating(options)) {
if (notifier->m_errorCallback) {
- RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_ERROR, "Unable to Start");
+ RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, "Unable to Start");
notifier->m_errorCallback->handleEvent(error.get());
}
return 0;
diff --git a/WebCore/page/MouseEventWithHitTestResults.cpp b/WebCore/page/MouseEventWithHitTestResults.cpp
index 0fc8c17..042269c 100644
--- a/WebCore/page/MouseEventWithHitTestResults.cpp
+++ b/WebCore/page/MouseEventWithHitTestResults.cpp
@@ -27,16 +27,6 @@
namespace WebCore {
-static inline Element* targetElement(Node* node)
-{
- if (!node)
- return 0;
- Node* parent = node->parent();
- if (!parent || !parent->isElementNode())
- return 0;
- return static_cast<Element*>(parent);
-}
-
MouseEventWithHitTestResults::MouseEventWithHitTestResults(const PlatformMouseEvent& event, const HitTestResult& hitTestResult)
: m_event(event)
, m_hitTestResult(hitTestResult)
@@ -46,10 +36,12 @@ MouseEventWithHitTestResults::MouseEventWithHitTestResults(const PlatformMouseEv
Node* MouseEventWithHitTestResults::targetNode() const
{
Node* node = m_hitTestResult.innerNode();
- if (node && node->inDocument())
+ if (!node)
+ return 0;
+ if (node->inDocument())
return node;
- Element* element = targetElement(node);
+ Element* element = node->parentElement();
if (element && element->inDocument())
return element;
diff --git a/WebCore/page/Navigator.cpp b/WebCore/page/Navigator.cpp
index 6045062..429ec00 100644
--- a/WebCore/page/Navigator.cpp
+++ b/WebCore/page/Navigator.cpp
@@ -30,7 +30,6 @@
#include "Geolocation.h"
#include "Language.h"
#include "MimeTypeArray.h"
-#include "NetworkStateNotifier.h"
#include "Page.h"
#include "PlatformString.h"
#include "PluginArray.h"
@@ -38,37 +37,6 @@
#include "ScriptController.h"
#include "Settings.h"
-#ifndef WEBCORE_NAVIGATOR_PLATFORM
-#if PLATFORM(MAC) && PLATFORM(PPC)
-#define WEBCORE_NAVIGATOR_PLATFORM "MacPPC"
-#elif PLATFORM(MAC) && PLATFORM(X86)
-#define WEBCORE_NAVIGATOR_PLATFORM "MacIntel"
-#elif PLATFORM(WIN_OS)
-#define WEBCORE_NAVIGATOR_PLATFORM "Win32"
-#elif PLATFORM(ANDROID)
-#define WEBCORE_NAVIGATOR_PLATFORM "Android"
-#else
-#define WEBCORE_NAVIGATOR_PLATFORM ""
-#endif
-#endif // ifndef WEBCORE_NAVIGATOR_PLATFORM
-
-#ifndef WEBCORE_NAVIGATOR_PRODUCT
-#define WEBCORE_NAVIGATOR_PRODUCT "Gecko"
-#endif // ifndef WEBCORE_NAVIGATOR_PRODUCT
-
-#ifndef WEBCORE_NAVIGATOR_PRODUCT_SUB
-#define WEBCORE_NAVIGATOR_PRODUCT_SUB "20030107"
-#endif // ifndef WEBCORE_NAVIGATOR_PRODUCT_SUB
-
-#ifndef WEBCORE_NAVIGATOR_VENDOR
-#define WEBCORE_NAVIGATOR_VENDOR "Apple Computer, Inc."
-#endif // ifndef WEBCORE_NAVIGATOR_VENDOR
-
-#ifndef WEBCORE_NAVIGATOR_VENDOR_SUB
-#define WEBCORE_NAVIGATOR_VENDOR_SUB ""
-#endif // ifndef WEBCORE_NAVIGATOR_VENDOR_SUB
-
-
namespace WebCore {
Navigator::Navigator(Frame* frame)
@@ -98,16 +66,6 @@ void Navigator::disconnectFrame()
m_frame = 0;
}
-String Navigator::appCodeName() const
-{
- return "Mozilla";
-}
-
-String Navigator::appName() const
-{
- return "Netscape";
-}
-
// If this function returns true, we need to hide the substring "4." that would otherwise
// appear in the appVersion string. This is to avoid problems with old versions of a
// library called OpenCube QuickMenu, which as of this writing is still being used on
@@ -129,9 +87,7 @@ String Navigator::appVersion() const
{
if (!m_frame)
return String();
- // Version is everything in the user agent string past the "Mozilla/" prefix.
- const String& userAgent = m_frame->loader()->userAgent(m_frame->document() ? m_frame->document()->url() : KURL());
- String appVersion = userAgent.substring(userAgent.find('/') + 1);
+ String appVersion = NavigatorBase::appVersion();
if (shouldHideFourDot(m_frame))
appVersion.replace("4.", "4_");
return appVersion;
@@ -149,11 +105,6 @@ String Navigator::userAgent() const
return m_frame->loader()->userAgent(m_frame->document() ? m_frame->document()->url() : KURL());
}
-String Navigator::platform() const
-{
- return WEBCORE_NAVIGATOR_PLATFORM;
-}
-
PluginArray* Navigator::plugins() const
{
if (!m_plugins)
@@ -168,26 +119,6 @@ MimeTypeArray* Navigator::mimeTypes() const
return m_mimeTypes.get();
}
-String Navigator::product() const
-{
- return WEBCORE_NAVIGATOR_PRODUCT;
-}
-
-String Navigator::productSub() const
-{
- return WEBCORE_NAVIGATOR_PRODUCT_SUB;
-}
-
-String Navigator::vendor() const
-{
- return WEBCORE_NAVIGATOR_VENDOR;
-}
-
-String Navigator::vendorSub() const
-{
- return WEBCORE_NAVIGATOR_VENDOR_SUB;
-}
-
bool Navigator::cookieEnabled() const
{
if (m_frame->page() && !m_frame->page()->cookieEnabled())
@@ -202,11 +133,6 @@ bool Navigator::javaEnabled() const
return false;
return m_frame->settings()->isJavaEnabled();
}
-
-bool Navigator::onLine() const
-{
- return networkStateNotifier().onLine();
-}
Geolocation* Navigator::geolocation() const
{
diff --git a/WebCore/page/Navigator.h b/WebCore/page/Navigator.h
index ea5d780..d50721e 100644
--- a/WebCore/page/Navigator.h
+++ b/WebCore/page/Navigator.h
@@ -20,6 +20,7 @@
#ifndef Navigator_h
#define Navigator_h
+#include "NavigatorBase.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
@@ -33,7 +34,7 @@ namespace WebCore {
class PluginArray;
class String;
- class Navigator : public RefCounted<Navigator> {
+ class Navigator : public NavigatorBase, public RefCounted<Navigator> {
public:
static PassRefPtr<Navigator> create(Frame* frame) { return adoptRef(new Navigator(frame)); }
~Navigator();
@@ -41,22 +42,15 @@ namespace WebCore {
void disconnectFrame();
Frame* frame() const { return m_frame; }
- String appCodeName() const;
- String appName() const;
String appVersion() const;
String language() const;
- String userAgent() const;
- String platform() const;
PluginArray* plugins() const;
MimeTypeArray* mimeTypes() const;
- String product() const;
- String productSub() const;
- String vendor() const;
- String vendorSub() const;
bool cookieEnabled() const;
bool javaEnabled() const;
- bool onLine() const;
+ virtual String userAgent() const;
+
Geolocation* geolocation() const;
// This is used for GC marking.
Geolocation* optionalGeolocation() const { return m_geolocation.get(); }
diff --git a/WebCore/page/NavigatorBase.cpp b/WebCore/page/NavigatorBase.cpp
new file mode 100644
index 0000000..27c9fdd
--- /dev/null
+++ b/WebCore/page/NavigatorBase.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2008 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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 "NavigatorBase.h"
+
+#include "NetworkStateNotifier.h"
+#include "PlatformString.h"
+
+#ifndef WEBCORE_NAVIGATOR_PLATFORM
+#if PLATFORM(MAC) && PLATFORM(PPC)
+#define WEBCORE_NAVIGATOR_PLATFORM "MacPPC"
+#elif PLATFORM(MAC) && PLATFORM(X86)
+#define WEBCORE_NAVIGATOR_PLATFORM "MacIntel"
+#elif PLATFORM(WIN_OS)
+#define WEBCORE_NAVIGATOR_PLATFORM "Win32"
+#else
+#define WEBCORE_NAVIGATOR_PLATFORM ""
+#endif
+#endif // ifndef WEBCORE_NAVIGATOR_PLATFORM
+
+#ifndef WEBCORE_NAVIGATOR_PRODUCT
+#define WEBCORE_NAVIGATOR_PRODUCT "Gecko"
+#endif // ifndef WEBCORE_NAVIGATOR_PRODUCT
+
+#ifndef WEBCORE_NAVIGATOR_PRODUCT_SUB
+#define WEBCORE_NAVIGATOR_PRODUCT_SUB "20030107"
+#endif // ifndef WEBCORE_NAVIGATOR_PRODUCT_SUB
+
+#ifndef WEBCORE_NAVIGATOR_VENDOR
+#define WEBCORE_NAVIGATOR_VENDOR "Apple Computer, Inc."
+#endif // ifndef WEBCORE_NAVIGATOR_VENDOR
+
+#ifndef WEBCORE_NAVIGATOR_VENDOR_SUB
+#define WEBCORE_NAVIGATOR_VENDOR_SUB ""
+#endif // ifndef WEBCORE_NAVIGATOR_VENDOR_SUB
+
+
+namespace WebCore {
+
+NavigatorBase::~NavigatorBase()
+{
+}
+
+String NavigatorBase::appName() const
+{
+ return "Netscape";
+}
+
+String NavigatorBase::appVersion() const
+{
+ // Version is everything in the user agent string past the "Mozilla/" prefix.
+ const String& agent = userAgent();
+ return agent.substring(agent.find('/') + 1);
+}
+
+String NavigatorBase::platform() const
+{
+ return WEBCORE_NAVIGATOR_PLATFORM;
+}
+
+String NavigatorBase::appCodeName() const
+{
+ return "Mozilla";
+}
+
+String NavigatorBase::product() const
+{
+ return WEBCORE_NAVIGATOR_PRODUCT;
+}
+
+String NavigatorBase::productSub() const
+{
+ return WEBCORE_NAVIGATOR_PRODUCT_SUB;
+}
+
+String NavigatorBase::vendor() const
+{
+ return WEBCORE_NAVIGATOR_VENDOR;
+}
+
+String NavigatorBase::vendorSub() const
+{
+ return WEBCORE_NAVIGATOR_VENDOR_SUB;
+}
+
+bool NavigatorBase::onLine() const
+{
+ return networkStateNotifier().onLine();
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/NavigatorBase.h b/WebCore/page/NavigatorBase.h
new file mode 100644
index 0000000..4c09f47
--- /dev/null
+++ b/WebCore/page/NavigatorBase.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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.
+*/
+
+#ifndef NavigatorBase_h
+#define NavigatorBase_h
+
+namespace WebCore {
+
+ class String;
+
+ class NavigatorBase {
+ public:
+ String appName() const;
+ String appVersion() const;
+ virtual String userAgent() const = 0;
+ String platform() const;
+
+ String appCodeName() const;
+ String product() const;
+ String productSub() const;
+ String vendor() const;
+ String vendorSub() const;
+
+ bool onLine() const;
+
+ protected:
+ virtual ~NavigatorBase();
+ };
+
+} // namespace WebCore
+
+#endif // NavigatorBase_h
diff --git a/WebCore/page/Page.cpp b/WebCore/page/Page.cpp
index 3c573d6..460183a 100644
--- a/WebCore/page/Page.cpp
+++ b/WebCore/page/Page.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006, 2007, 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -50,10 +51,9 @@
#include "TextResourceDecoder.h"
#include "Widget.h"
#include "ScriptController.h"
-#include <kjs/collector.h>
-#include <runtime/JSLock.h>
#include <wtf/HashMap.h>
#include <wtf/RefCountedLeakCounter.h>
+#include <wtf/StdLibExtras.h>
#if ENABLE(DOM_STORAGE)
#include "LocalStorage.h"
@@ -65,6 +65,10 @@
#include "JavaScriptDebugServer.h"
#endif
+#if ENABLE(WML)
+#include "WMLPageState.h"
+#endif
+
namespace WebCore {
static HashSet<Page*>* allPages;
@@ -100,7 +104,7 @@ static void networkStateChanged()
eventTarget->dispatchEventForType(eventName, false, false);
}
}
-
+
Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, EditorClient* editorClient, DragClient* dragClient, InspectorClient* inspectorClient)
: m_chrome(new Chrome(this, chromeClient))
, m_dragCaretController(new SelectionController(0, true))
@@ -117,6 +121,8 @@ Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, Edi
, m_defersLoading(false)
, m_inLowQualityInterpolationMode(false)
, m_cookieEnabled(true)
+ , m_areMemoryCacheClientCallsEnabled(true)
+ , m_mediaVolume(1)
, m_parentInspectorController(0)
, m_didLoadUserStyleSheet(false)
, m_userStyleSheetModificationTime(0)
@@ -213,6 +219,11 @@ void Page::goToItem(HistoryItem* item, FrameLoadType type)
m_mainFrame->loader()->goToItem(item, type);
}
+void Page::setGlobalHistoryItem(HistoryItem* item)
+{
+ m_globalHistoryItem = item;
+}
+
void Page::setGroupName(const String& name)
{
if (m_group && !m_group->name().isEmpty()) {
@@ -232,7 +243,7 @@ void Page::setGroupName(const String& name)
const String& Page::groupName() const
{
- static String nullString;
+ DEFINE_STATIC_LOCAL(String, nullString, ());
return m_group ? m_group->name() : nullString;
}
@@ -281,6 +292,8 @@ void Page::refreshPlugins(bool reload)
PluginData* Page::pluginData() const
{
+ if (!settings()->arePluginsEnabled())
+ return 0;
if (!m_pluginData)
m_pluginData = PluginData::create(this);
return m_pluginData.get();
@@ -381,6 +394,21 @@ void Page::setInLowQualityImageInterpolationMode(bool mode)
m_inLowQualityInterpolationMode = mode;
}
+void Page::setMediaVolume(float volume)
+{
+ if (volume < 0 || volume > 1)
+ return;
+
+ if (m_mediaVolume == volume)
+ return;
+
+ m_mediaVolume = volume;
+ for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ if (frame->document())
+ frame->document()->mediaVolumeDidChange();
+ }
+}
+
void Page::userStyleSheetLocationChanged()
{
#if !FRAME_LOADS_USER_STYLESHEET
@@ -469,7 +497,7 @@ void Page::allVisitedStateChanged(PageGroup* group)
}
}
-void Page::visitedStateChanged(PageGroup* group, unsigned visitedLinkHash)
+void Page::visitedStateChanged(PageGroup* group, LinkHash visitedLinkHash)
{
ASSERT(group);
ASSERT(allPages);
@@ -561,6 +589,15 @@ void Page::changePendingBeforeUnloadEventCount(int delta)
return;
}
+#if ENABLE(WML)
+WMLPageState* Page::wmlPageState()
+{
+ if (!m_wmlPageState)
+ m_wmlPageState.set(new WMLPageState(this));
+ return m_wmlPageState.get();
+}
+#endif
+
void Page::setCustomHTMLTokenizerTimeDelay(double customHTMLTokenizerTimeDelay)
{
if (customHTMLTokenizerTimeDelay < 0) {
@@ -579,4 +616,17 @@ void Page::setCustomHTMLTokenizerChunkSize(int customHTMLTokenizerChunkSize)
m_customHTMLTokenizerChunkSize = customHTMLTokenizerChunkSize;
}
+void Page::setMemoryCacheClientCallsEnabled(bool enabled)
+{
+ if (m_areMemoryCacheClientCallsEnabled == enabled)
+ return;
+
+ m_areMemoryCacheClientCallsEnabled = enabled;
+ if (!enabled)
+ return;
+
+ for (RefPtr<Frame> frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
+ frame->loader()->tellClientAboutPastMemoryCacheLoads();
+}
+
} // namespace WebCore
diff --git a/WebCore/page/Page.h b/WebCore/page/Page.h
index 9c00ba7..aea16a2 100644
--- a/WebCore/page/Page.h
+++ b/WebCore/page/Page.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,12 +25,14 @@
#include "Chrome.h"
#include "ContextMenuController.h"
#include "FrameLoaderTypes.h"
+#include "LinkHash.h"
#include "PlatformString.h"
+#include <wtf/HashSet.h>
+#include <wtf/OwnPtr.h>
+
#if PLATFORM(MAC)
#include "SchedulePair.h"
#endif
-#include <wtf/HashSet.h>
-#include <wtf/OwnPtr.h>
#if PLATFORM(WIN) || (PLATFORM(WX) && PLATFORM(WIN_OS)) || (PLATFORM(QT) && defined(Q_WS_WIN))
typedef struct HINSTANCE__* HINSTANCE;
@@ -63,8 +66,10 @@ namespace WebCore {
class SessionStorage;
#endif
class Settings;
+#if ENABLE(WML)
+ class WMLPageState;
+#endif
- enum TextCaseSensitivity { TextCaseSensitive, TextCaseInsensitive };
enum FindDirection { FindDirectionForward, FindDirectionBackward };
class Page : Noncopyable {
@@ -91,7 +96,10 @@ namespace WebCore {
bool goBack();
bool goForward();
void goToItem(HistoryItem*, FrameLoadType);
-
+
+ HistoryItem* globalHistoryItem() const { return m_globalHistoryItem.get(); }
+ void setGlobalHistoryItem(HistoryItem*);
+
void setGroupName(const String&);
const String& groupName() const;
@@ -142,6 +150,9 @@ namespace WebCore {
bool cookieEnabled() const { return m_cookieEnabled; }
void setCookieEnabled(bool enabled) { m_cookieEnabled = enabled; }
+ float mediaVolume() const { return m_mediaVolume; }
+ void setMediaVolume(float volume);
+
void userStyleSheetLocationChanged();
const String& userStyleSheet() const;
@@ -163,13 +174,17 @@ namespace WebCore {
static void removeAllVisitedLinks();
static void allVisitedStateChanged(PageGroup*);
- static void visitedStateChanged(PageGroup*, unsigned visitedHash);
+ static void visitedStateChanged(PageGroup*, LinkHash visitedHash);
#if ENABLE(DOM_STORAGE)
SessionStorage* sessionStorage(bool optionalCreate = true);
void setSessionStorage(PassRefPtr<SessionStorage>);
#endif
+#if ENABLE(WML)
+ WMLPageState* wmlPageState();
+#endif
+
void setCustomHTMLTokenizerTimeDelay(double);
bool hasCustomHTMLTokenizerTimeDelay() const { return m_customHTMLTokenizerTimeDelay != -1; }
double customHTMLTokenizerTimeDelay() const { ASSERT(m_customHTMLTokenizerTimeDelay != -1); return m_customHTMLTokenizerTimeDelay; }
@@ -178,6 +193,9 @@ namespace WebCore {
bool hasCustomHTMLTokenizerChunkSize() const { return m_customHTMLTokenizerChunkSize != -1; }
int customHTMLTokenizerChunkSize() const { ASSERT(m_customHTMLTokenizerChunkSize != -1); return m_customHTMLTokenizerChunkSize; }
+ void setMemoryCacheClientCallsEnabled(bool);
+ bool areMemoryCacheClientCallsEnabled() const { return m_areMemoryCacheClientCallsEnabled; }
+
private:
void initGroup();
@@ -193,6 +211,8 @@ namespace WebCore {
RefPtr<BackForwardList> m_backForwardList;
RefPtr<Frame> m_mainFrame;
+ RefPtr<HistoryItem> m_globalHistoryItem;
+
mutable RefPtr<PluginData> m_pluginData;
EditorClient* m_editorClient;
@@ -205,6 +225,8 @@ namespace WebCore {
bool m_inLowQualityInterpolationMode;
bool m_cookieEnabled;
+ bool m_areMemoryCacheClientCallsEnabled;
+ float m_mediaVolume;
InspectorController* m_parentInspectorController;
@@ -227,9 +249,14 @@ namespace WebCore {
#if ENABLE(DOM_STORAGE)
RefPtr<SessionStorage> m_sessionStorage;
#endif
+
#if PLATFORM(WIN) || (PLATFORM(WX) && defined(__WXMSW__)) || (PLATFORM(QT) && defined(Q_WS_WIN))
static HINSTANCE s_instanceHandle;
#endif
+
+#if ENABLE(WML)
+ OwnPtr<WMLPageState> m_wmlPageState;
+#endif
};
} // namespace WebCore
diff --git a/WebCore/page/PageGroup.cpp b/WebCore/page/PageGroup.cpp
index 6b72be2..f0951eb 100644
--- a/WebCore/page/PageGroup.cpp
+++ b/WebCore/page/PageGroup.cpp
@@ -36,6 +36,10 @@
#include "StorageArea.h"
#endif
+#if PLATFORM(CHROMIUM)
+#include "ChromiumBridge.h"
+#endif
+
namespace WebCore {
static unsigned getUniqueIdentifier()
@@ -117,23 +121,29 @@ void PageGroup::removePage(Page* page)
m_pages.remove(page);
}
-bool PageGroup::isLinkVisited(unsigned visitedLinkHash)
+bool PageGroup::isLinkVisited(LinkHash visitedLinkHash)
{
+#if PLATFORM(CHROMIUM)
+ // Use Chromium's built-in visited link database.
+ return ChromiumBridge::isLinkVisited(visitedLinkHash);
+#else
if (!m_visitedLinksPopulated) {
m_visitedLinksPopulated = true;
ASSERT(!m_pages.isEmpty());
(*m_pages.begin())->chrome()->client()->populateVisitedLinks();
}
return m_visitedLinkHashes.contains(visitedLinkHash);
+#endif
}
-inline void PageGroup::addVisitedLink(unsigned stringHash)
+inline void PageGroup::addVisitedLink(LinkHash hash)
{
ASSERT(shouldTrackVisitedLinks);
- unsigned visitedLinkHash = AlreadyHashed::avoidDeletedValue(stringHash);
- if (!m_visitedLinkHashes.add(visitedLinkHash).second)
+#if !PLATFORM(CHROMIUM)
+ if (!m_visitedLinkHashes.add(hash).second)
return;
- Page::visitedStateChanged(this, visitedLinkHash);
+#endif
+ Page::visitedStateChanged(this, hash);
}
void PageGroup::addVisitedLink(const KURL& url)
@@ -141,14 +151,14 @@ void PageGroup::addVisitedLink(const KURL& url)
if (!shouldTrackVisitedLinks)
return;
ASSERT(!url.isEmpty());
- addVisitedLink(url.string().impl()->hash());
+ addVisitedLink(visitedLinkHash(url.string().characters(), url.string().length()));
}
void PageGroup::addVisitedLink(const UChar* characters, size_t length)
{
if (!shouldTrackVisitedLinks)
return;
- addVisitedLink(StringImpl::computeHash(characters, length));
+ addVisitedLink(visitedLinkHash(characters, length));
}
void PageGroup::removeVisitedLinks()
diff --git a/WebCore/page/PageGroup.h b/WebCore/page/PageGroup.h
index b25892d..097fb87 100644
--- a/WebCore/page/PageGroup.h
+++ b/WebCore/page/PageGroup.h
@@ -28,6 +28,7 @@
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
+#include "LinkHash.h"
#include "StringHash.h"
namespace WebCore {
@@ -49,7 +50,7 @@ namespace WebCore {
void addPage(Page*);
void removePage(Page*);
- bool isLinkVisited(unsigned visitedLinkHash);
+ bool isLinkVisited(LinkHash);
void addVisitedLink(const KURL&);
void addVisitedLink(const UChar*, size_t);
@@ -66,12 +67,13 @@ namespace WebCore {
#endif
private:
- void addVisitedLink(unsigned stringHash);
+ void addVisitedLink(LinkHash stringHash);
String m_name;
HashSet<Page*> m_pages;
- HashSet<unsigned, AlreadyHashed> m_visitedLinkHashes;
+
+ HashSet<LinkHash, LinkHashHash> m_visitedLinkHashes;
bool m_visitedLinksPopulated;
unsigned m_identifier;
diff --git a/WebCore/page/PositionError.h b/WebCore/page/PositionError.h
index 1d68bde..1d31f3b 100644
--- a/WebCore/page/PositionError.h
+++ b/WebCore/page/PositionError.h
@@ -35,11 +35,10 @@ namespace WebCore {
class PositionError : public RefCounted<PositionError> {
public:
enum ErrorCode {
- PERMISSION_ERROR = 1,
- LOCATION_PROVIDER_ERROR,
- POSITION_NOT_FOUND_ERROR,
- TIMEOUT_ERROR,
- UNKNOWN_ERROR
+ UNKNOWN_ERROR = 0,
+ PERMISSION_DENIED = 1,
+ POSITION_UNAVAILABLE = 2,
+ TIMEOUT = 3
};
static PassRefPtr<PositionError> create(ErrorCode code, const String& message) { return adoptRef(new PositionError(code, message)); }
diff --git a/WebCore/page/PositionError.idl b/WebCore/page/PositionError.idl
index 8c8c335..cb2ef5e 100644
--- a/WebCore/page/PositionError.idl
+++ b/WebCore/page/PositionError.idl
@@ -28,8 +28,13 @@ module core {
interface [
GenerateConstructor
] PositionError {
- readonly attribute long code;
+ readonly attribute unsigned short code;
readonly attribute DOMString message;
+
+ const unsigned short UNKNOWN_ERROR = 0;
+ const unsigned short PERMISSION_DENIED = 1;
+ const unsigned short POSITION_UNAVAILABLE = 2;
+ const unsigned short TIMEOUT = 3;
};
}
diff --git a/WebCore/page/SecurityOrigin.cpp b/WebCore/page/SecurityOrigin.cpp
index 6de7508..fd8144f 100644
--- a/WebCore/page/SecurityOrigin.cpp
+++ b/WebCore/page/SecurityOrigin.cpp
@@ -33,6 +33,7 @@
#include "FrameLoader.h"
#include "KURL.h"
#include "PlatformString.h"
+#include <wtf/StdLibExtras.h>
namespace WebCore {
@@ -41,7 +42,8 @@ static bool isDefaultPortForProtocol(unsigned short port, const String& protocol
if (protocol.isEmpty())
return false;
- static HashMap<String, unsigned> defaultPorts;
+ typedef HashMap<String, unsigned> DefaultPortsMap;
+ DEFINE_STATIC_LOCAL(DefaultPortsMap, defaultPorts, ());
if (defaultPorts.isEmpty()) {
defaultPorts.set("http", 80);
defaultPorts.set("https", 443);
@@ -94,6 +96,8 @@ bool SecurityOrigin::isEmpty() const
PassRefPtr<SecurityOrigin> SecurityOrigin::create(const KURL& url)
{
+ if (!url.isValid())
+ return adoptRef(new SecurityOrigin(KURL()));
return adoptRef(new SecurityOrigin(url));
}
@@ -222,7 +226,7 @@ String SecurityOrigin::toString() const
PassRefPtr<SecurityOrigin> SecurityOrigin::createFromString(const String& originString)
{
- return SecurityOrigin::create(KURL(originString));
+ return SecurityOrigin::create(KURL(KURL(), originString));
}
static const char SeparatorCharacter = '_';
@@ -260,7 +264,7 @@ PassRefPtr<SecurityOrigin> SecurityOrigin::createFromDatabaseIdentifier(const St
String SecurityOrigin::databaseIdentifier() const
{
- static String separatorString = String(&SeparatorCharacter, 1);
+ DEFINE_STATIC_LOCAL(String, separatorString, (&SeparatorCharacter, 1));
return m_protocol + separatorString + m_host + separatorString + String::number(m_port);
}
diff --git a/WebCore/page/Settings.cpp b/WebCore/page/Settings.cpp
index b9b3925..8c9bb44 100644
--- a/WebCore/page/Settings.cpp
+++ b/WebCore/page/Settings.cpp
@@ -33,10 +33,6 @@
#include "PageCache.h"
#include <limits>
-#if ENABLE(DATABASE)
-#include "DatabaseTracker.h"
-#endif
-
namespace WebCore {
static void setNeedsReapplyStylesInAllFrames(Page* page)
@@ -55,6 +51,7 @@ Settings::Settings(Page* page)
, m_layoutAlgorithm(kLayoutFitColumnToScreen)
#endif
, m_editableLinkBehavior(EditableLinkDefaultBehavior)
+ , m_textDirectionSubmenuInclusionBehavior(TextDirectionSubmenuAutomaticallyIncluded)
, m_minimumFontSize(0)
, m_minimumLogicalFontSize(0)
, m_defaultFontSize(0)
@@ -72,6 +69,8 @@ Settings::Settings(Page* page)
, m_loadsImagesAutomatically(false)
, m_privateBrowsingEnabled(false)
, m_arePluginsEnabled(false)
+ , m_databasesEnabled(false)
+ , m_localStorageEnabled(false)
, m_isJavaScriptEnabled(false)
, m_javaScriptCanOpenWindowsAutomatically(false)
, m_shouldPrintBackgrounds(false)
@@ -98,6 +97,7 @@ Settings::Settings(Page* page)
, m_zoomsTextOnly(false)
, m_enforceCSSMIMETypeInStrictMode(true)
, m_maximumDecodedImageSize(std::numeric_limits<size_t>::max())
+ , m_needsIChatMemoryCacheCallsQuirk(false)
{
// A Frame may not have been created yet, so we initialize the AtomicString
// hash before trying to use it.
@@ -231,6 +231,16 @@ void Settings::setPluginsPath(const String& pluginsPath)
}
#endif
+void Settings::setDatabasesEnabled(bool databasesEnabled)
+{
+ m_databasesEnabled = databasesEnabled;
+}
+
+void Settings::setLocalStorageEnabled(bool localStorageEnabled)
+{
+ m_localStorageEnabled = localStorageEnabled;
+}
+
void Settings::setPrivateBrowsingEnabled(bool privateBrowsingEnabled)
{
m_privateBrowsingEnabled = privateBrowsingEnabled;
@@ -276,6 +286,11 @@ void Settings::setEditableLinkBehavior(EditableLinkBehavior editableLinkBehavior
m_editableLinkBehavior = editableLinkBehavior;
}
+void Settings::setTextDirectionSubmenuInclusionBehavior(TextDirectionSubmenuInclusionBehavior behavior)
+{
+ m_textDirectionSubmenuInclusionBehavior = behavior;
+}
+
#if ENABLE(DASHBOARD_SUPPORT)
void Settings::setUsesDashboardBackwardCompatibilityMode(bool usesDashboardBackwardCompatibilityMode)
{
@@ -509,4 +524,9 @@ void Settings::setShouldPaintNativeControls(bool shouldPaintNativeControls)
}
#endif
+void Settings::setNeedsIChatMemoryCacheCallsQuirk(bool needsIChatMemoryCacheCallsQuirk)
+{
+ m_needsIChatMemoryCacheCallsQuirk = needsIChatMemoryCacheCallsQuirk;
+}
+
} // namespace WebCore
diff --git a/WebCore/page/Settings.h b/WebCore/page/Settings.h
index 8acc998..b9b888f 100644
--- a/WebCore/page/Settings.h
+++ b/WebCore/page/Settings.h
@@ -43,6 +43,12 @@ namespace WebCore {
EditableLinkNeverLive
};
+ enum TextDirectionSubmenuInclusionBehavior {
+ TextDirectionSubmenuNeverIncluded,
+ TextDirectionSubmenuAutomaticallyIncluded,
+ TextDirectionSubmenuAlwaysIncluded
+ };
+
class Settings {
public:
Settings(Page*);
@@ -120,6 +126,12 @@ namespace WebCore {
const String& pluginsPath() const { return m_pluginsPath; }
#endif
+ void setDatabasesEnabled(bool);
+ bool databasesEnabled() const { return m_databasesEnabled; }
+
+ void setLocalStorageEnabled(bool);
+ bool localStorageEnabled() const { return m_localStorageEnabled; }
+
void setPrivateBrowsingEnabled(bool);
bool privateBrowsingEnabled() const { return m_privateBrowsingEnabled; }
@@ -137,7 +149,10 @@ namespace WebCore {
void setEditableLinkBehavior(EditableLinkBehavior);
EditableLinkBehavior editableLinkBehavior() const { return m_editableLinkBehavior; }
-
+
+ void setTextDirectionSubmenuInclusionBehavior(TextDirectionSubmenuInclusionBehavior);
+ TextDirectionSubmenuInclusionBehavior textDirectionSubmenuInclusionBehavior() const { return m_textDirectionSubmenuInclusionBehavior; }
+
#if ENABLE(DASHBOARD_SUPPORT)
void setUsesDashboardBackwardCompatibilityMode(bool);
bool usesDashboardBackwardCompatibilityMode() const { return m_usesDashboardBackwardCompatibilityMode; }
@@ -230,6 +245,9 @@ namespace WebCore {
static bool shouldPaintNativeControls() { return gShouldPaintNativeControls; }
#endif
+ void setNeedsIChatMemoryCacheCallsQuirk(bool);
+ bool needsIChatMemoryCacheCallsQuirk() const { return m_needsIChatMemoryCacheCallsQuirk; }
+
private:
Page* m_page;
@@ -250,6 +268,7 @@ namespace WebCore {
LayoutAlgorithm m_layoutAlgorithm;
#endif
EditableLinkBehavior m_editableLinkBehavior;
+ TextDirectionSubmenuInclusionBehavior m_textDirectionSubmenuInclusionBehavior;
int m_minimumFontSize;
int m_minimumLogicalFontSize;
int m_defaultFontSize;
@@ -289,6 +308,8 @@ namespace WebCore {
bool m_loadsImagesAutomatically : 1;
bool m_privateBrowsingEnabled : 1;
bool m_arePluginsEnabled : 1;
+ bool m_databasesEnabled : 1;
+ bool m_localStorageEnabled : 1;
bool m_isJavaScriptEnabled : 1;
bool m_javaScriptCanOpenWindowsAutomatically : 1;
bool m_shouldPrintBackgrounds : 1;
@@ -315,6 +336,7 @@ namespace WebCore {
bool m_zoomsTextOnly : 1;
bool m_enforceCSSMIMETypeInStrictMode : 1;
size_t m_maximumDecodedImageSize;
+ bool m_needsIChatMemoryCacheCallsQuirk : 1;
#if USE(SAFARI_THEME)
static bool gShouldPaintNativeControls;
diff --git a/WebCore/page/WorkerNavigator.cpp b/WebCore/page/WorkerNavigator.cpp
new file mode 100644
index 0000000..339f107
--- /dev/null
+++ b/WebCore/page/WorkerNavigator.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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"
+
+#if ENABLE(WORKERS)
+
+#include "WorkerNavigator.h"
+
+namespace WebCore {
+
+WorkerNavigator::WorkerNavigator(const String& userAgent)
+ : m_userAgent(userAgent)
+{
+}
+
+WorkerNavigator::~WorkerNavigator()
+{
+}
+
+String WorkerNavigator::userAgent() const
+{
+ return m_userAgent;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/WebCore/page/WorkerNavigator.h b/WebCore/page/WorkerNavigator.h
new file mode 100644
index 0000000..8ca2fd9
--- /dev/null
+++ b/WebCore/page/WorkerNavigator.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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.
+*/
+
+#ifndef WorkerNavigator_h
+#define WorkerNavigator_h
+
+#if ENABLE(WORKERS)
+
+#include "NavigatorBase.h"
+#include "PlatformString.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+ class WorkerNavigator : public NavigatorBase, public RefCounted<WorkerNavigator> {
+ public:
+ static PassRefPtr<WorkerNavigator> create(const String& userAgent) { return adoptRef(new WorkerNavigator(userAgent)); }
+ virtual ~WorkerNavigator();
+
+ virtual String userAgent() const;
+
+ private:
+ WorkerNavigator(const String&);
+
+ String m_userAgent;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // WorkerNavigator_h
diff --git a/WebCore/page/WorkerNavigator.idl b/WebCore/page/WorkerNavigator.idl
new file mode 100644
index 0000000..195f0bc
--- /dev/null
+++ b/WebCore/page/WorkerNavigator.idl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 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.
+ */
+
+module threads {
+
+ interface [
+ Conditional=WORKERS,
+ NoStaticTables
+ ] WorkerNavigator {
+ readonly attribute DOMString appName;
+ readonly attribute DOMString appVersion;
+ readonly attribute DOMString platform;
+ readonly attribute DOMString userAgent;
+
+ readonly attribute boolean onLine;
+ };
+
+}
diff --git a/WebCore/page/android/DragControllerAndroid.cpp b/WebCore/page/android/DragControllerAndroid.cpp
index ae87f02..7a52b56 100644
--- a/WebCore/page/android/DragControllerAndroid.cpp
+++ b/WebCore/page/android/DragControllerAndroid.cpp
@@ -46,6 +46,10 @@ DragOperation DragController::dragOperation(DragData* dragData)
return DragOperationNone;
}
+void DragController::cleanupAfterSystemDrag()
+{
+}
+
const float DragController::DragImageAlpha = 1.0f;
static IntSize dummy;
const IntSize& DragController::maxDragImageSize() { return dummy; }
diff --git a/WebCore/page/android/EventHandlerAndroid.cpp b/WebCore/page/android/EventHandlerAndroid.cpp
index 62ccd2e..df73fe0 100644
--- a/WebCore/page/android/EventHandlerAndroid.cpp
+++ b/WebCore/page/android/EventHandlerAndroid.cpp
@@ -39,8 +39,6 @@
namespace WebCore {
-unsigned EventHandler::s_accessKeyModifiers = PlatformKeyboardEvent::AltKey;
-
bool EventHandler::tabsToAllControls(KeyboardEvent* ) const
{
return true;
@@ -124,6 +122,11 @@ PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
return PassRefPtr<Clipboard>(0);
}
+unsigned EventHandler::accessKeyModifiers()
+{
+ return PlatformKeyboardEvent::AltKey;
+}
+
const double EventHandler::TextDragDelay = 0.0;
} // namespace WebCore
diff --git a/WebCore/page/android/InspectorControllerAndroid.cpp b/WebCore/page/android/InspectorControllerAndroid.cpp
index 4f55ec4..d6222d7 100644
--- a/WebCore/page/android/InspectorControllerAndroid.cpp
+++ b/WebCore/page/android/InspectorControllerAndroid.cpp
@@ -78,10 +78,10 @@ void InspectorController::willSendRequest(DocumentLoader*, unsigned long, Resour
void InspectorController::didReceiveResponse(DocumentLoader*, unsigned long, ResourceResponse const&) {}
void InspectorController::didReceiveContentLength(DocumentLoader*, unsigned long, int) {}
void InspectorController::didFinishLoading(DocumentLoader*, unsigned long) {}
-void InspectorController::didLoadResourceFromMemoryCache(DocumentLoader*, ResourceRequest const&, ResourceResponse const&, int) {}
+void InspectorController::didLoadResourceFromMemoryCache(DocumentLoader*, const CachedResource*) {}
void InspectorController::frameDetachedFromParent(Frame*) {}
-void InspectorController::addMessageToConsole(MessageSource, MessageLevel, JSC::ExecState*, JSC::ArgList const&, unsigned int, String const&) {}
+void InspectorController::addMessageToConsole(MessageSource, MessageLevel, ScriptCallStack*) {}
void InspectorController::addMessageToConsole(MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceID) {}
#if ENABLE(DATABASE)
void InspectorController::didOpenDatabase(Database*, String const&, String const&, String const&) {}
@@ -91,14 +91,14 @@ void InspectorController::inspect(Node*) {}
bool InspectorController::windowVisible() { return false; }
void InspectorController::addProfile(PassRefPtr<JSC::Profile>, unsigned int, const JSC::UString&) {}
void InspectorController::inspectedPageDestroyed() {}
-void InspectorController::resourceRetrievedByXMLHttpRequest(unsigned long identifier, JSC::UString& sourceString) {}
+void InspectorController::resourceRetrievedByXMLHttpRequest(unsigned long identifier, const JSC::UString& sourceString) {}
void InspectorController::inspectedWindowScriptObjectCleared(Frame* frame) {}
-void InspectorController::startGroup(MessageSource source, JSC::ExecState* exec, const JSC::ArgList& arguments, unsigned lineNumber, const String& sourceURL) {}
+void InspectorController::startGroup(MessageSource source, ScriptCallStack* callFrame) {}
void InspectorController::endGroup(MessageSource source, unsigned lineNumber, const String& sourceURL) {}
-void InspectorController::startTiming(const JSC::UString& title) {}
-bool InspectorController::stopTiming(const JSC::UString& title, double& elapsed) { return false; }
-void InspectorController::count(const JSC::UString& title, unsigned lineNumber, const String& sourceID) {}
+void InspectorController::startTiming(const String& title) {}
+bool InspectorController::stopTiming(const String& title, double& elapsed) { return false; }
+void InspectorController::count(const String& title, unsigned lineNumber, const String& sourceID) {}
void InspectorController::mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags) {}
void InspectorController::handleMousePressOnNode(Node*) {}
diff --git a/WebCore/page/animation/AnimationBase.cpp b/WebCore/page/animation/AnimationBase.cpp
index fc28469..3e43f66 100644
--- a/WebCore/page/animation/AnimationBase.cpp
+++ b/WebCore/page/animation/AnimationBase.cpp
@@ -30,6 +30,8 @@
#include "AnimationBase.h"
#include "AnimationController.h"
+#include "CSSMutableStyleDeclaration.h"
+#include "CSSPropertyLonghand.h"
#include "CSSPropertyNames.h"
#include "CString.h"
#include "CompositeAnimation.h"
@@ -43,13 +45,10 @@
#include "MatrixTransformOperation.h"
#include "RenderObject.h"
#include "RenderStyle.h"
-#include "SystemTime.h"
#include "UnitBezier.h"
namespace WebCore {
-static const double cAnimationTimerDelay = 0.025;
-
// The epsilon value we pass to UnitBezier::solve given that the animation is going to run over |dur| seconds. The longer the
// animation, the more precision we need in the timing function result to avoid ugly discontinuities.
static inline double solveEpsilon(double duration)
@@ -65,35 +64,34 @@ static inline double solveCubicBezierFunction(double p1x, double p1y, double p2x
return bezier.solve(t, solveEpsilon(duration));
}
-void AnimationTimerCallback::timerFired(Timer<AnimationTimerBase>*)
-{
- m_anim->animationTimerCallbackFired(m_eventType, m_elapsedTime);
-}
-
-static inline int blendFunc(const AnimationBase* anim, int from, int to, double progress)
+static inline int blendFunc(const AnimationBase*, int from, int to, double progress)
{
return int(from + (to - from) * progress);
}
-static inline double blendFunc(const AnimationBase* anim, double from, double to, double progress)
+static inline double blendFunc(const AnimationBase*, double from, double to, double progress)
{
return from + (to - from) * progress;
}
-static inline float blendFunc(const AnimationBase* anim, float from, float to, double progress)
+static inline float blendFunc(const AnimationBase*, float from, float to, double progress)
{
return narrowPrecisionToFloat(from + (to - from) * progress);
}
static inline Color blendFunc(const AnimationBase* anim, const Color& from, const Color& to, double progress)
-{
+{
+ // We need to preserve the state of the valid flag at the end of the animation
+ if (progress == 1 && !to.isValid())
+ return Color();
+
return Color(blendFunc(anim, from.red(), to.red(), progress),
blendFunc(anim, from.green(), to.green(), progress),
blendFunc(anim, from.blue(), to.blue(), progress),
blendFunc(anim, from.alpha(), to.alpha(), progress));
}
-static inline Length blendFunc(const AnimationBase* anim, const Length& from, const Length& to, double progress)
+static inline Length blendFunc(const AnimationBase*, const Length& from, const Length& to, double progress)
{
return to.blend(from, progress);
}
@@ -136,9 +134,9 @@ static inline TransformOperations blendFunc(const AnimationBase* anim, const Tra
}
} else {
// Convert the TransformOperations into matrices
- IntSize size = anim->renderer()->borderBox().size();
- AffineTransform fromT;
- AffineTransform toT;
+ IntSize size = anim->renderer()->isBox() ? toRenderBox(anim->renderer())->borderBoxRect().size() : IntSize();
+ TransformationMatrix fromT;
+ TransformationMatrix toT;
from.apply(size, fromT);
to.apply(size, toT);
@@ -162,6 +160,11 @@ static inline EVisibility blendFunc(const AnimationBase* anim, EVisibility from,
return result > 0. ? VISIBLE : (to != VISIBLE ? to : from);
}
+class PropertyWrapperBase;
+
+static void addShorthandProperties();
+static PropertyWrapperBase* wrapperForProperty(int propertyID);
+
class PropertyWrapperBase {
public:
PropertyWrapperBase(int prop)
@@ -170,6 +173,8 @@ public:
}
virtual ~PropertyWrapperBase() { }
+
+ virtual bool isShorthandWrapper() const { return false; }
virtual bool equals(const RenderStyle* a, const RenderStyle* b) const = 0;
virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const = 0;
@@ -296,9 +301,48 @@ private:
void (RenderStyle::*m_setter)(const Color&);
};
+class ShorthandPropertyWrapper : public PropertyWrapperBase {
+public:
+ ShorthandPropertyWrapper(int property, const CSSPropertyLonghand& longhand)
+ : PropertyWrapperBase(property)
+ {
+ for (unsigned i = 0; i < longhand.length(); ++i) {
+ PropertyWrapperBase* wrapper = wrapperForProperty(longhand.properties()[i]);
+ if (wrapper)
+ m_propertyWrappers.append(wrapper);
+ }
+ }
+
+ virtual bool isShorthandWrapper() const { return true; }
+
+ virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
+ {
+ Vector<PropertyWrapperBase*>::const_iterator end = m_propertyWrappers.end();
+ for (Vector<PropertyWrapperBase*>::const_iterator it = m_propertyWrappers.begin(); it != end; ++it) {
+ if (!(*it)->equals(a, b))
+ return false;
+ }
+ return true;
+ }
+
+ virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
+ {
+ Vector<PropertyWrapperBase*>::const_iterator end = m_propertyWrappers.end();
+ for (Vector<PropertyWrapperBase*>::const_iterator it = m_propertyWrappers.begin(); it != end; ++it)
+ (*it)->blend(anim, dst, a, b, progress);
+ }
+
+private:
+ Vector<PropertyWrapperBase*> m_propertyWrappers;
+};
+
+
static Vector<PropertyWrapperBase*>* gPropertyWrappers = 0;
static int gPropertyWrapperMap[numCSSProperties];
+static const int cInvalidPropertyWrapperIndex = -1;
+
+
static void ensurePropertyMap()
{
// FIXME: This data is never destroyed. Maybe we should ref count it and toss it when the last AnimationController is destroyed?
@@ -368,37 +412,122 @@ static void ensurePropertyMap()
gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyStrokeOpacity, &RenderStyle::strokeOpacity, &RenderStyle::setStrokeOpacity));
#endif
+ // TODO:
+ //
+ // CSSPropertyBackground, CSSPropertyBackgroundPosition
+ // CSSPropertyMinWidth, CSSPropertyMaxWidth, CSSPropertyMinHeight, CSSPropertyMaxHeight
+ // CSSPropertyTextIndent
+ // CSSPropertyVerticalAlign
+ // CSSPropertyWebkitBackgroundOrigin
+ // CSSPropertyWebkitBackgroundSize
+ // CSSPropertyWebkitMaskPosition
+ // CSSPropertyWebkitMaskOrigin
+ // CSSPropertyWebkitMaskSize
+ //
+ // Compound properties that have components that should be animatable:
+ //
+ // CSSPropertyWebkitColumns
+ // CSSPropertyWebkitMask
+ // CSSPropertyWebkitBoxReflect
+
// Make sure unused slots have a value
- for (unsigned int i = 0; i < (unsigned int) numCSSProperties; ++i)
- gPropertyWrapperMap[i] = CSSPropertyInvalid;
+ for (unsigned int i = 0; i < static_cast<unsigned int>(numCSSProperties); ++i)
+ gPropertyWrapperMap[i] = cInvalidPropertyWrapperIndex;
+ // First we put the non-shorthand property wrappers into the map, so the shorthand-building
+ // code can find them.
size_t n = gPropertyWrappers->size();
for (unsigned int i = 0; i < n; ++i) {
ASSERT((*gPropertyWrappers)[i]->property() - firstCSSProperty < numCSSProperties);
gPropertyWrapperMap[(*gPropertyWrappers)[i]->property() - firstCSSProperty] = i;
}
+
+ // Now add the shorthand wrappers.
+ addShorthandProperties();
}
}
+static void addPropertyWrapper(int propertyID, PropertyWrapperBase* wrapper)
+{
+ int propIndex = propertyID - firstCSSProperty;
+
+ ASSERT(gPropertyWrapperMap[propIndex] == cInvalidPropertyWrapperIndex);
+
+ unsigned wrapperIndex = gPropertyWrappers->size();
+ gPropertyWrappers->append(wrapper);
+ gPropertyWrapperMap[propIndex] = wrapperIndex;
+}
+
+static void addShorthandProperties()
+{
+ static const int animatableShorthandProperties[] = {
+ CSSPropertyBackground, // for background-color
+ CSSPropertyBorderTop, CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft,
+ CSSPropertyBorderColor,
+ CSSPropertyBorderWidth,
+ CSSPropertyBorder,
+ CSSPropertyBorderSpacing,
+ CSSPropertyMargin,
+ CSSPropertyOutline,
+ CSSPropertyPadding,
+ CSSPropertyWebkitTextStroke,
+ CSSPropertyWebkitColumnRule,
+ CSSPropertyWebkitBorderRadius,
+ CSSPropertyWebkitTransformOrigin
+ };
+
+ for (unsigned i = 0; i < sizeof(animatableShorthandProperties) / sizeof(animatableShorthandProperties[0]); ++i) {
+ int propertyID = animatableShorthandProperties[i];
+ CSSPropertyLonghand longhand = longhandForProperty(propertyID);
+ if (longhand.length() > 0)
+ addPropertyWrapper(propertyID, new ShorthandPropertyWrapper(propertyID, longhand));
+ }
+
+ // 'font' is not in the shorthand map.
+ static const int animatableFontProperties[] = {
+ CSSPropertyFontSize,
+ CSSPropertyFontWeight
+ };
+
+ CSSPropertyLonghand fontLonghand(animatableFontProperties, sizeof(animatableFontProperties) / sizeof(animatableFontProperties[0]));
+ addPropertyWrapper(CSSPropertyFont, new ShorthandPropertyWrapper(CSSPropertyFont, fontLonghand));
+}
+
+static PropertyWrapperBase* wrapperForProperty(int propertyID)
+{
+ int propIndex = propertyID - firstCSSProperty;
+ if (propIndex >= 0 && propIndex < numCSSProperties) {
+ int wrapperIndex = gPropertyWrapperMap[propIndex];
+ if (wrapperIndex >= 0)
+ return (*gPropertyWrappers)[wrapperIndex];
+ }
+ return 0;
+}
+
AnimationBase::AnimationBase(const Animation* transition, RenderObject* renderer, CompositeAnimation* compAnim)
: m_animState(AnimationStateNew)
- , m_iteration(0)
, m_isAnimating(false)
, m_waitedForResponse(false)
, m_startTime(0)
, m_pauseTime(-1)
+ , m_requestedStartTime(0)
, m_object(renderer)
- , m_animationTimerCallback(const_cast<AnimationBase*>(this))
, m_animation(const_cast<Animation*>(transition))
, m_compAnim(compAnim)
, m_transformFunctionListValid(false)
+ , m_nextIterationDuration(-1)
+ , m_next(0)
{
+ // Compute the total duration
+ m_totalDuration = -1;
+ if (m_animation->iterationCount() > 0)
+ m_totalDuration = m_animation->duration() * m_animation->iterationCount();
}
AnimationBase::~AnimationBase()
{
if (m_animState == AnimationStateStartWaitStyleAvailable)
- m_compAnim->setWaitingForStyleAvailable(false);
+ m_compAnim->removeFromStyleAvailableWaitList(this);
}
bool AnimationBase::propertiesEqual(int prop, const RenderStyle* a, const RenderStyle* b)
@@ -407,27 +536,28 @@ bool AnimationBase::propertiesEqual(int prop, const RenderStyle* a, const Render
if (prop == cAnimateAll) {
size_t n = gPropertyWrappers->size();
for (unsigned int i = 0; i < n; ++i) {
- if (!(*gPropertyWrappers)[i]->equals(a, b))
+ PropertyWrapperBase* wrapper = (*gPropertyWrappers)[i];
+ // No point comparing shorthand wrappers for 'all'.
+ if (!wrapper->isShorthandWrapper() && !wrapper->equals(a, b))
return false;
}
} else {
- int propIndex = prop - firstCSSProperty;
-
- if (propIndex >= 0 && propIndex < numCSSProperties) {
- int i = gPropertyWrapperMap[propIndex];
- return i >= 0 ? (*gPropertyWrappers)[i]->equals(a, b) : true;
- }
+ PropertyWrapperBase* wrapper = wrapperForProperty(prop);
+ if (wrapper)
+ return wrapper->equals(a, b);
}
return true;
}
-int AnimationBase::getPropertyAtIndex(int i)
+int AnimationBase::getPropertyAtIndex(int i, bool& isShorthand)
{
ensurePropertyMap();
if (i < 0 || i >= static_cast<int>(gPropertyWrappers->size()))
return CSSPropertyInvalid;
- return (*gPropertyWrappers)[i]->property();
+ PropertyWrapperBase* wrapper = (*gPropertyWrappers)[i];
+ isShorthand = wrapper->isShorthandWrapper();
+ return wrapper->property();
}
int AnimationBase::getNumProperties()
@@ -440,31 +570,12 @@ int AnimationBase::getNumProperties()
bool AnimationBase::blendProperties(const AnimationBase* anim, int prop, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress)
{
ASSERT(prop != cAnimateAll);
- // FIXME: Why can this happen?
-
- ensurePropertyMap();
- if (prop == cAnimateAll) {
- bool needsTimer = false;
- size_t n = gPropertyWrappers->size();
- for (unsigned int i = 0; i < n; ++i) {
- PropertyWrapperBase* wrapper = (*gPropertyWrappers)[i];
- if (!wrapper->equals(a, b)) {
- wrapper->blend(anim, dst, a, b, progress);
- needsTimer = true;
- }
- }
- return needsTimer;
- }
-
- int propIndex = prop - firstCSSProperty;
- if (propIndex >= 0 && propIndex < numCSSProperties) {
- int i = gPropertyWrapperMap[propIndex];
- if (i >= 0) {
- PropertyWrapperBase* wrapper = (*gPropertyWrappers)[i];
- wrapper->blend(anim, dst, a, b, progress);
- return true;
- }
+ ensurePropertyMap();
+ PropertyWrapperBase* wrapper = wrapperForProperty(prop);
+ if (wrapper) {
+ wrapper->blend(anim, dst, a, b, progress);
+ return true;
}
return false;
@@ -473,7 +584,8 @@ bool AnimationBase::blendProperties(const AnimationBase* anim, int prop, RenderS
void AnimationBase::setChanged(Node* node)
{
ASSERT(!node || (node->document() && !node->document()->inPageCache()));
- node->setChanged(AnimationStyleChange);
+ if (node)
+ node->setChanged(AnimationStyleChange);
}
double AnimationBase::duration() const
@@ -483,7 +595,7 @@ double AnimationBase::duration() const
bool AnimationBase::playStatePlaying() const
{
- return m_animation && m_animation->playState() == AnimPlayStatePlaying;
+ return m_animation->playState() == AnimPlayStatePlaying;
}
bool AnimationBase::animationsMatch(const Animation* anim) const
@@ -496,22 +608,25 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
// If we get AnimationStateInputRestartAnimation then we force a new animation, regardless of state.
if (input == AnimationStateInputMakeNew) {
if (m_animState == AnimationStateStartWaitStyleAvailable)
- m_compAnim->setWaitingForStyleAvailable(false);
+ m_compAnim->removeFromStyleAvailableWaitList(this);
m_animState = AnimationStateNew;
m_startTime = 0;
m_pauseTime = -1;
+ m_requestedStartTime = 0;
+ m_nextIterationDuration = -1;
m_waitedForResponse = false;
endAnimation(false);
return;
}
if (input == AnimationStateInputRestartAnimation) {
- cancelTimers();
if (m_animState == AnimationStateStartWaitStyleAvailable)
- m_compAnim->setWaitingForStyleAvailable(false);
+ m_compAnim->removeFromStyleAvailableWaitList(this);
m_animState = AnimationStateNew;
m_startTime = 0;
m_pauseTime = -1;
+ m_requestedStartTime = 0;
+ m_nextIterationDuration = -1;
endAnimation(false);
if (!paused())
@@ -520,9 +635,8 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
}
if (input == AnimationStateInputEndAnimation) {
- cancelTimers();
if (m_animState == AnimationStateStartWaitStyleAvailable)
- m_compAnim->setWaitingForStyleAvailable(false);
+ m_compAnim->removeFromStyleAvailableWaitList(this);
m_animState = AnimationStateDone;
endAnimation(true);
return;
@@ -533,7 +647,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
// If we are in AnimationStateStartWaitResponse, the animation will get canceled before
// we get a response, so move to the next state.
endAnimation(false);
- updateStateMachine(AnimationStateInputStartTimeSet, currentTime());
+ updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
}
return;
}
@@ -551,10 +665,9 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
case AnimationStateNew:
ASSERT(input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunnning || input == AnimationStateInputPlayStatePaused);
if (input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunnning) {
- // Set the start timer to the initial delay (0 if no delay)
m_waitedForResponse = false;
+ m_requestedStartTime = beginAnimationUpdateTime();
m_animState = AnimationStateStartWaitTimer;
- m_animationTimerCallback.startTimer(m_animation->delay(), eventNames().webkitAnimationStartEvent, m_animation->delay());
}
break;
case AnimationStateStartWaitTimer:
@@ -564,48 +677,36 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
ASSERT(param >= 0);
// Start timer has fired, tell the animation to start and wait for it to respond with start time
m_animState = AnimationStateStartWaitStyleAvailable;
- m_compAnim->setWaitingForStyleAvailable(true);
+ m_compAnim->addToStyleAvailableWaitList(this);
// Trigger a render so we can start the animation
- setChanged(m_object->element());
- m_object->animation()->startUpdateRenderingDispatcher();
+ if (m_object)
+ m_object->animation()->addNodeChangeToDispatch(m_object->element());
} else {
ASSERT(!paused());
// We're waiting for the start timer to fire and we got a pause. Cancel the timer, pause and wait
- m_pauseTime = currentTime();
- cancelTimers();
+ m_pauseTime = beginAnimationUpdateTime();
m_animState = AnimationStatePausedWaitTimer;
}
break;
case AnimationStateStartWaitStyleAvailable:
ASSERT(input == AnimationStateInputStyleAvailable || input == AnimationStateInputPlayStatePaused);
- m_compAnim->setWaitingForStyleAvailable(false);
-
- if (input == AnimationStateInputStyleAvailable) {
- // Start timer has fired, tell the animation to start and wait for it to respond with start time
- m_animState = AnimationStateStartWaitResponse;
+ // Start timer has fired, tell the animation to start and wait for it to respond with start time
+ m_animState = AnimationStateStartWaitResponse;
- overrideAnimations();
+ overrideAnimations();
- // Send start event, if needed
- onAnimationStart(0); // The elapsedTime is always 0 here
+ // Send start event, if needed
+ onAnimationStart(0); // The elapsedTime is always 0 here
- // Start the animation
- if (overridden() || !startAnimation(0)) {
- // We're not going to get a startTime callback, so fire the start time here
- m_animState = AnimationStateStartWaitResponse;
- updateStateMachine(AnimationStateInputStartTimeSet, currentTime());
- } else
- m_waitedForResponse = true;
- } else {
- ASSERT(!paused());
- // We're waiting for the a notification that the style has been setup. If we're asked to wait
- // at this point, the style must have been processed, so we can deal with this like we would
- // for WAIT_RESPONSE, except that we don't need to do an endAnimation().
- m_pauseTime = 0;
+ // Start the animation
+ if (overridden() || !startAnimation(0)) {
+ // We're not going to get a startTime callback, so fire the start time here
m_animState = AnimationStateStartWaitResponse;
- }
+ updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
+ } else
+ m_waitedForResponse = true;
break;
case AnimationStateStartWaitResponse:
ASSERT(input == AnimationStateInputStartTimeSet || input == AnimationStateInputPlayStatePaused);
@@ -616,16 +717,16 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
if (m_startTime <= 0)
m_startTime = param;
- // Decide when the end or loop event needs to fire
- primeEventTimers();
+ // Decide whether to go into looping or ending state
+ goIntoEndingOrLoopingState();
- // Trigger a render so we can start the animation
- setChanged(m_object->element());
- m_object->animation()->startUpdateRenderingDispatcher();
+ // Dispatch updateRendering so we can start the animation
+ if (m_object)
+ m_object->animation()->addNodeChangeToDispatch(m_object->element());
} else {
// We are pausing while waiting for a start response. Cancel the animation and wait. When
// we unpause, we will act as though the start timer just fired
- m_pauseTime = 0;
+ m_pauseTime = -1;
endAnimation(false);
m_animState = AnimationStatePausedWaitResponse;
}
@@ -637,11 +738,12 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
ASSERT(param >= 0);
// Loop timer fired, loop again or end.
onAnimationIteration(param);
- primeEventTimers();
+
+ // Decide whether to go into looping or ending state
+ goIntoEndingOrLoopingState();
} else {
// We are pausing while running. Cancel the animation and wait
- m_pauseTime = currentTime();
- cancelTimers();
+ m_pauseTime = beginAnimationUpdateTime();
endAnimation(false);
m_animState = AnimationStatePausedRun;
}
@@ -654,17 +756,17 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
// End timer fired, finish up
onAnimationEnd(param);
- resumeOverriddenAnimations();
-
- // Fire off another style change so we can set the final value
- setChanged(m_object->element());
m_animState = AnimationStateDone;
- m_object->animation()->startUpdateRenderingDispatcher();
- // |this| may be deleted here when we've been called from timerFired()
+
+ if (m_object) {
+ resumeOverriddenAnimations();
+
+ // Fire off another style change so we can set the final value
+ m_object->animation()->addNodeChangeToDispatch(m_object->element());
+ }
} else {
// We are pausing while running. Cancel the animation and wait
- m_pauseTime = currentTime();
- cancelTimers();
+ m_pauseTime = beginAnimationUpdateTime();
endAnimation(false);
m_animState = AnimationStatePausedRun;
}
@@ -674,7 +776,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
ASSERT(input == AnimationStateInputPlayStateRunnning);
ASSERT(paused());
// Update the times
- m_startTime += currentTime() - m_pauseTime;
+ m_startTime += beginAnimationUpdateTime() - m_pauseTime;
m_pauseTime = -1;
// we were waiting for the start timer to fire, go back and wait again
@@ -691,7 +793,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
ASSERT(paused());
// Update the times
if (m_animState == AnimationStatePausedRun)
- m_startTime += currentTime() - m_pauseTime;
+ m_startTime += beginAnimationUpdateTime() - m_pauseTime;
else
m_startTime = 0;
m_pauseTime = -1;
@@ -702,7 +804,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
// Start the animation
if (overridden() || !startAnimation(m_startTime)) {
// We're not going to get a startTime callback, so fire the start time here
- updateStateMachine(AnimationStateInputStartTimeSet, currentTime());
+ updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
} else
m_waitedForResponse = true;
break;
@@ -710,21 +812,53 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
// We're done. Stay in this state until we are deleted
break;
}
- // |this| may be deleted here if we came out of AnimationStateEnding when we've been called from timerFired()
}
-void AnimationBase::animationTimerCallbackFired(const AtomicString& eventType, double elapsedTime)
+void AnimationBase::fireAnimationEventsIfNeeded()
{
- ASSERT(m_object->document() && !m_object->document()->inPageCache());
+ // If we are waiting for the delay time to expire and it has, go to the next state
+ if (m_animState != AnimationStateStartWaitTimer && m_animState != AnimationStateLooping && m_animState != AnimationStateEnding)
+ return;
- // FIXME: use an enum
- if (eventType == eventNames().webkitAnimationStartEvent)
- updateStateMachine(AnimationStateInputStartTimerFired, elapsedTime);
- else if (eventType == eventNames().webkitAnimationIterationEvent)
- updateStateMachine(AnimationStateInputLoopTimerFired, elapsedTime);
- else if (eventType == eventNames().webkitAnimationEndEvent) {
- updateStateMachine(AnimationStateInputEndTimerFired, elapsedTime);
- // |this| may be deleted here
+ // We have to make sure to keep a ref to the this pointer, because it could get destroyed
+ // during an animation callback that might get called. Since the owner is a CompositeAnimation
+ // and it ref counts this object, we will keep a ref to that instead. That way the AnimationBase
+ // can still access the resources of its CompositeAnimation as needed.
+ RefPtr<AnimationBase> protector(this);
+ RefPtr<CompositeAnimation> compProtector(m_compAnim);
+
+ // Check for start timeout
+ if (m_animState == AnimationStateStartWaitTimer) {
+ if (beginAnimationUpdateTime() - m_requestedStartTime >= m_animation->delay())
+ updateStateMachine(AnimationStateInputStartTimerFired, 0);
+ return;
+ }
+
+ double elapsedDuration = beginAnimationUpdateTime() - m_startTime;
+ ASSERT(elapsedDuration >= 0);
+
+ // Check for end timeout
+ if (m_totalDuration >= 0 && elapsedDuration >= m_totalDuration) {
+ // Fire an end event
+ updateStateMachine(AnimationStateInputEndTimerFired, m_totalDuration);
+ }
+ else {
+ // Check for iteration timeout
+ if (m_nextIterationDuration < 0) {
+ // Hasn't been set yet, set it
+ double durationLeft = m_animation->duration() - fmod(elapsedDuration, m_animation->duration());
+ m_nextIterationDuration = elapsedDuration + durationLeft;
+ }
+
+ if (elapsedDuration >= m_nextIterationDuration) {
+ // Set to the next iteration
+ double previous = m_nextIterationDuration;
+ double durationLeft = m_animation->duration() - fmod(elapsedDuration, m_animation->duration());
+ m_nextIterationDuration = elapsedDuration + durationLeft;
+
+ // Send the event
+ updateStateMachine(AnimationStateInputLoopTimerFired, previous);
+ }
}
}
@@ -734,14 +868,28 @@ void AnimationBase::updatePlayState(bool run)
updateStateMachine(run ? AnimationStateInputPlayStateRunnning : AnimationStateInputPlayStatePaused, -1);
}
+double AnimationBase::willNeedService() const
+{
+ // Returns the time at which next service is required. -1 means no service is required. 0 means
+ // service is required now, and > 0 means service is required that many seconds in the future.
+ if (paused() || isNew())
+ return -1;
+
+ if (m_animState == AnimationStateStartWaitTimer) {
+ double timeFromNow = m_animation->delay() - (beginAnimationUpdateTime() - m_requestedStartTime);
+ return (float) ((timeFromNow > 0) ? timeFromNow : 0);
+ }
+
+ // In all other cases, we need service right away.
+ return 0;
+}
+
double AnimationBase::progress(double scale, double offset, const TimingFunction* tf) const
{
if (preActive())
return 0;
- double elapsedTime = running() ? (currentTime() - m_startTime) : (m_pauseTime - m_startTime);
- if (running() && elapsedTime < 0)
- return 0;
+ double elapsedTime = getElapsedTime();
double dur = m_animation->duration();
if (m_animation->iterationCount() > 0)
@@ -778,38 +926,53 @@ double AnimationBase::progress(double scale, double offset, const TimingFunction
return result;
}
-void AnimationBase::primeEventTimers()
+void AnimationBase::goIntoEndingOrLoopingState()
{
// Decide when the end or loop event needs to fire
- double ct = currentTime();
- const double elapsedDuration = ct - m_startTime;
- ASSERT(elapsedDuration >= 0);
-
double totalDuration = -1;
if (m_animation->iterationCount() > 0)
totalDuration = m_animation->duration() * m_animation->iterationCount();
+ const double elapsedDuration = beginAnimationUpdateTime() - m_startTime;
+ ASSERT(elapsedDuration >= 0);
double durationLeft = 0;
double nextIterationTime = totalDuration;
+
if (totalDuration < 0 || elapsedDuration < totalDuration) {
durationLeft = m_animation->duration() - fmod(elapsedDuration, m_animation->duration());
nextIterationTime = elapsedDuration + durationLeft;
}
- // At this point, we may have 0 durationLeft, if we've gotten the event late and we are already
- // past totalDuration. In this case we still fire an end timer before processing the end.
- // This defers the call to sendAnimationEvents to avoid re-entrant calls that destroy
- // the RenderObject, and therefore |this| before we're done with it.
if (totalDuration < 0 || nextIterationTime < totalDuration) {
- // We are not at the end yet, send a loop event
+ // We are not at the end yet
ASSERT(nextIterationTime > 0);
m_animState = AnimationStateLooping;
- m_animationTimerCallback.startTimer(durationLeft, eventNames().webkitAnimationIterationEvent, nextIterationTime);
} else {
- // We are at the end, send an end event
+ // We are at the end
m_animState = AnimationStateEnding;
- m_animationTimerCallback.startTimer(durationLeft, eventNames().webkitAnimationEndEvent, nextIterationTime);
}
}
+void AnimationBase::pauseAtTime(double t)
+{
+ updatePlayState(false);
+ m_pauseTime = m_startTime + t - m_animation->delay();
+}
+
+double AnimationBase::beginAnimationUpdateTime() const
+{
+ return m_compAnim->animationController()->beginAnimationUpdateTime();
+}
+
+double AnimationBase::getElapsedTime() const
+{
+ if (paused())
+ return m_pauseTime - m_startTime;
+ if (m_startTime <= 0)
+ return 0;
+ if (postActive())
+ return 1;
+ return beginAnimationUpdateTime() - m_startTime;
+}
+
} // namespace WebCore
diff --git a/WebCore/page/animation/AnimationBase.h b/WebCore/page/animation/AnimationBase.h
index 925c0d5..ce16f93 100644
--- a/WebCore/page/animation/AnimationBase.h
+++ b/WebCore/page/animation/AnimationBase.h
@@ -30,7 +30,6 @@
#define AnimationBase_h
#include "AtomicString.h"
-#include "Timer.h"
#include <wtf/HashMap.h>
namespace WebCore {
@@ -45,60 +44,6 @@ class RenderObject;
class RenderStyle;
class TimingFunction;
-class AnimationTimerBase {
-public:
- AnimationTimerBase(AnimationBase* anim)
- : m_timer(this, &AnimationTimerBase::timerFired)
- , m_anim(anim)
- {
- m_timer.startOneShot(0);
- }
-
- virtual ~AnimationTimerBase() { }
-
- void startTimer(double timeout = 0)
- {
- m_timer.startOneShot(timeout);
- }
-
- void cancelTimer()
- {
- m_timer.stop();
- }
-
- virtual void timerFired(Timer<AnimationTimerBase>*) = 0;
-
-private:
- Timer<AnimationTimerBase> m_timer;
-
-protected:
- AnimationBase* m_anim;
-};
-
-class AnimationTimerCallback : public AnimationTimerBase {
-public:
- AnimationTimerCallback(AnimationBase* anim)
- : AnimationTimerBase(anim)
- , m_elapsedTime(0)
- {
- }
-
- virtual ~AnimationTimerCallback() { }
-
- virtual void timerFired(Timer<AnimationTimerBase>*);
-
- void startTimer(double timeout, const AtomicString& eventType, double elapsedTime)
- {
- m_eventType = eventType;
- m_elapsedTime = elapsedTime;
- AnimationTimerBase::startTimer(timeout);
- }
-
-private:
- AtomicString m_eventType;
- double m_elapsedTime;
-};
-
class AnimationBase : public RefCounted<AnimationBase> {
friend class CompositeAnimationPrivate;
@@ -107,14 +52,10 @@ public:
virtual ~AnimationBase();
RenderObject* renderer() const { return m_object; }
- double startTime() const { return m_startTime; }
+ void clearRenderer() { m_object = 0; }
+
double duration() const;
- void cancelTimers()
- {
- m_animationTimerCallback.cancelTimer();
- }
-
// Animations and Transitions go through the states below. When entering the STARTED state
// the animation is started. This may or may not require deferred response from the animator.
// If so, we stay in this state until that response is received (and it returns the start time).
@@ -176,16 +117,16 @@ public:
// "animating" means that something is running that requires a timer to keep firing
// (e.g. a software animation)
void setAnimating(bool inAnimating = true) { m_isAnimating = inAnimating; }
- bool isAnimating() const { return m_isAnimating; }
+ double willNeedService() const;
double progress(double scale, double offset, const TimingFunction*) const;
- virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* currentStyle,
- const RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle) { }
+ virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* /*currentStyle*/,
+ const RenderStyle* /*targetStyle*/, RefPtr<RenderStyle>& /*animatedStyle*/) { }
virtual bool shouldFireEvents() const { return false; }
- void animationTimerCallbackFired(const AtomicString& eventType, double elapsedTime);
+ void fireAnimationEventsIfNeeded();
bool animationsMatch(const Animation*) const;
@@ -198,7 +139,7 @@ public:
virtual bool overridden() const { return false; }
// Does this animation/transition involve the given property?
- virtual bool affectsProperty(int property) const { return false; }
+ virtual bool affectsProperty(int /*property*/) const { return false; }
bool isAnimatingProperty(int property, bool isRunningNow) const
{
if (isRunningNow)
@@ -209,6 +150,21 @@ public:
bool isTransformFunctionListValid() const { return m_transformFunctionListValid; }
+ void pauseAtTime(double t);
+
+ double beginAnimationUpdateTime() const;
+
+ double getElapsedTime() const;
+
+ AnimationBase* next() const { return m_next; }
+ void setNext(AnimationBase* animation) { m_next = animation; }
+
+ void styleAvailable()
+ {
+ ASSERT(waitingForStyleAvailable());
+ updateStateMachine(AnimationBase::AnimationStateInputStyleAvailable, -1);
+ }
+
protected:
virtual void overrideAnimations() { }
virtual void resumeOverriddenAnimations() { }
@@ -216,16 +172,16 @@ protected:
CompositeAnimation* compositeAnimation() { return m_compAnim; }
// These are called when the corresponding timer fires so subclasses can do any extra work
- virtual void onAnimationStart(double elapsedTime) { }
- virtual void onAnimationIteration(double elapsedTime) { }
- virtual void onAnimationEnd(double elapsedTime) { }
- virtual bool startAnimation(double beginTime) { return false; }
- virtual void endAnimation(bool reset) { }
+ virtual void onAnimationStart(double /*elapsedTime*/) { }
+ virtual void onAnimationIteration(double /*elapsedTime*/) { }
+ virtual void onAnimationEnd(double /*elapsedTime*/) { }
+ virtual bool startAnimation(double /*beginTime*/) { return false; }
+ virtual void endAnimation(bool /*reset*/) { }
- void primeEventTimers();
+ void goIntoEndingOrLoopingState();
static bool propertiesEqual(int prop, const RenderStyle* a, const RenderStyle* b);
- static int getPropertyAtIndex(int);
+ static int getPropertyAtIndex(int, bool& isShorthand);
static int getNumProperties();
// Return true if we need to start software animation timers
@@ -233,20 +189,21 @@ protected:
static void setChanged(Node*);
-protected:
AnimState m_animState;
- int m_iteration;
bool m_isAnimating; // transition/animation requires continual timer firing
bool m_waitedForResponse;
double m_startTime;
double m_pauseTime;
+ double m_requestedStartTime;
RenderObject* m_object;
- AnimationTimerCallback m_animationTimerCallback;
RefPtr<Animation> m_animation;
CompositeAnimation* m_compAnim;
bool m_transformFunctionListValid;
+ double m_totalDuration, m_nextIterationDuration;
+
+ AnimationBase* m_next;
};
} // namespace WebCore
diff --git a/WebCore/page/animation/AnimationController.cpp b/WebCore/page/animation/AnimationController.cpp
index d449afe..f85e6c1 100644
--- a/WebCore/page/animation/AnimationController.cpp
+++ b/WebCore/page/animation/AnimationController.cpp
@@ -28,27 +28,34 @@
#include "config.h"
#include "AnimationController.h"
+#include "AnimationBase.h"
#include "CompositeAnimation.h"
+#include "CSSParser.h"
+#include "EventNames.h"
#include "Frame.h"
#include "Timer.h"
+#include <wtf/CurrentTime.h>
namespace WebCore {
static const double cAnimationTimerDelay = 0.025;
+static const double cBeginAnimationUpdateTimeNotSet = -1;
class AnimationControllerPrivate {
public:
AnimationControllerPrivate(Frame*);
~AnimationControllerPrivate();
- CompositeAnimation* accessCompositeAnimation(RenderObject*);
+ PassRefPtr<CompositeAnimation> accessCompositeAnimation(RenderObject*);
bool clear(RenderObject*);
void animationTimerFired(Timer<AnimationControllerPrivate>*);
- void updateAnimationTimer();
+ void updateAnimationTimer(bool callSetChanged = false);
void updateRenderingDispatcherFired(Timer<AnimationControllerPrivate>*);
void startUpdateRenderingDispatcher();
+ void addEventToDispatch(PassRefPtr<Element> element, const AtomicString& eventType, const String& name, double elapsedTime);
+ void addNodeChangeToDispatch(PassRefPtr<Node>);
bool hasAnimations() const { return !m_compositeAnimations.isEmpty(); }
@@ -59,32 +66,65 @@ public:
bool isAnimatingPropertyOnRenderer(RenderObject*, int property, bool isRunningNow) const;
+ bool pauseAnimationAtTime(RenderObject*, const String& name, double t);
+ bool pauseTransitionAtTime(RenderObject*, const String& property, double t);
+ unsigned numberOfActiveAnimations() const;
+
+ double beginAnimationUpdateTime()
+ {
+ if (m_beginAnimationUpdateTime == cBeginAnimationUpdateTimeNotSet)
+ m_beginAnimationUpdateTime = currentTime();
+ return m_beginAnimationUpdateTime;
+ }
+
+ void setBeginAnimationUpdateTime(double t) { m_beginAnimationUpdateTime = t; }
+
+ void addToStyleAvailableWaitList(AnimationBase*);
+ void removeFromStyleAvailableWaitList(AnimationBase*);
+
private:
- typedef HashMap<RenderObject*, CompositeAnimation*> RenderObjectAnimationMap;
+ typedef HashMap<RenderObject*, RefPtr<CompositeAnimation> > RenderObjectAnimationMap;
RenderObjectAnimationMap m_compositeAnimations;
Timer<AnimationControllerPrivate> m_animationTimer;
Timer<AnimationControllerPrivate> m_updateRenderingDispatcher;
Frame* m_frame;
+
+ class EventToDispatch {
+ public:
+ RefPtr<Element> element;
+ AtomicString eventType;
+ String name;
+ double elapsedTime;
+ };
+
+ Vector<EventToDispatch> m_eventsToDispatch;
+ Vector<RefPtr<Node> > m_nodeChangesToDispatch;
+
+ double m_beginAnimationUpdateTime;
+ AnimationBase* m_styleAvailableWaiters;
+ AnimationBase* m_lastStyleAvailableWaiter;
};
AnimationControllerPrivate::AnimationControllerPrivate(Frame* frame)
: m_animationTimer(this, &AnimationControllerPrivate::animationTimerFired)
, m_updateRenderingDispatcher(this, &AnimationControllerPrivate::updateRenderingDispatcherFired)
, m_frame(frame)
+ , m_beginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet)
+ , m_styleAvailableWaiters(0)
+ , m_lastStyleAvailableWaiter(0)
{
}
AnimationControllerPrivate::~AnimationControllerPrivate()
{
- deleteAllValues(m_compositeAnimations);
}
-CompositeAnimation* AnimationControllerPrivate::accessCompositeAnimation(RenderObject* renderer)
+PassRefPtr<CompositeAnimation> AnimationControllerPrivate::accessCompositeAnimation(RenderObject* renderer)
{
- CompositeAnimation* animation = m_compositeAnimations.get(renderer);
+ RefPtr<CompositeAnimation> animation = m_compositeAnimations.get(renderer);
if (!animation) {
- animation = new CompositeAnimation(m_frame->animation());
+ animation = CompositeAnimation::create(m_frame->animation());
m_compositeAnimations.set(renderer, animation);
}
return animation;
@@ -94,44 +134,81 @@ bool AnimationControllerPrivate::clear(RenderObject* renderer)
{
// Return false if we didn't do anything OR we are suspended (so we don't try to
// do a setChanged() when suspended).
- CompositeAnimation* animation = m_compositeAnimations.take(renderer);
+ PassRefPtr<CompositeAnimation> animation = m_compositeAnimations.take(renderer);
if (!animation)
return false;
- animation->resetTransitions(renderer);
- bool wasSuspended = animation->isSuspended();
- delete animation;
- return !wasSuspended;
+ animation->clearRenderer();
+ return animation->isSuspended();
}
-void AnimationControllerPrivate::styleAvailable()
+void AnimationControllerPrivate::updateAnimationTimer(bool callSetChanged/* = false*/)
{
- RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end();
- for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it)
- it->second->styleAvailable();
-}
-
-void AnimationControllerPrivate::updateAnimationTimer()
-{
- bool isAnimating = false;
+ double needsService = -1;
+ bool calledSetChanged = false;
RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end();
for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) {
- CompositeAnimation* compAnim = it->second;
- if (!compAnim->isSuspended() && compAnim->isAnimating()) {
- isAnimating = true;
- break;
+ RefPtr<CompositeAnimation> compAnim = it->second;
+ if (!compAnim->isSuspended() && compAnim->hasAnimations()) {
+ double t = compAnim->willNeedService();
+ if (t != -1 && (t < needsService || needsService == -1))
+ needsService = t;
+ if (needsService == 0) {
+ if (callSetChanged) {
+ Node* node = it->first->element();
+ ASSERT(!node || (node->document() && !node->document()->inPageCache()));
+ node->setChanged(AnimationStyleChange);
+ calledSetChanged = true;
+ }
+ else
+ break;
+ }
}
}
- if (isAnimating) {
- if (!m_animationTimer.isActive())
+ if (calledSetChanged)
+ m_frame->document()->updateRendering();
+
+ // If we want service immediately, we start a repeating timer to reduce the overhead of starting
+ if (needsService == 0) {
+ if (!m_animationTimer.isActive() || m_animationTimer.repeatInterval() == 0)
m_animationTimer.startRepeating(cAnimationTimerDelay);
- } else if (m_animationTimer.isActive())
+ return;
+ }
+
+ // If we don't need service, we want to make sure the timer is no longer running
+ if (needsService < 0) {
+ if (m_animationTimer.isActive())
+ m_animationTimer.stop();
+ return;
+ }
+
+ // Otherwise, we want to start a one-shot timer so we get here again
+ if (m_animationTimer.isActive())
m_animationTimer.stop();
+ m_animationTimer.startOneShot(needsService);
}
void AnimationControllerPrivate::updateRenderingDispatcherFired(Timer<AnimationControllerPrivate>*)
{
+ // fire all the events
+ Vector<EventToDispatch>::const_iterator eventsToDispatchEnd = m_eventsToDispatch.end();
+ for (Vector<EventToDispatch>::const_iterator it = m_eventsToDispatch.begin(); it != eventsToDispatchEnd; ++it) {
+ if (it->eventType == eventNames().webkitTransitionEndEvent)
+ it->element->dispatchWebKitTransitionEvent(it->eventType,it->name, it->elapsedTime);
+ else
+ it->element->dispatchWebKitAnimationEvent(it->eventType,it->name, it->elapsedTime);
+ }
+
+ m_eventsToDispatch.clear();
+
+ // call setChanged on all the elements
+ Vector<RefPtr<Node> >::const_iterator nodeChangesToDispatchEnd = m_nodeChangesToDispatch.end();
+ for (Vector<RefPtr<Node> >::const_iterator it = m_nodeChangesToDispatch.begin(); it != nodeChangesToDispatchEnd; ++it)
+ (*it)->setChanged(AnimationStyleChange);
+
+ m_nodeChangesToDispatch.clear();
+
if (m_frame && m_frame->document())
m_frame->document()->updateRendering();
}
@@ -142,32 +219,38 @@ void AnimationControllerPrivate::startUpdateRenderingDispatcher()
m_updateRenderingDispatcher.startOneShot(0);
}
-void AnimationControllerPrivate::animationTimerFired(Timer<AnimationControllerPrivate>* timer)
+void AnimationControllerPrivate::addEventToDispatch(PassRefPtr<Element> element, const AtomicString& eventType, const String& name, double elapsedTime)
{
- // When the timer fires, all we do is call setChanged on all DOM nodes with running animations and then do an immediate
- // updateRendering. It will then call back to us with new information.
- bool isAnimating = false;
- RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end();
- for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) {
- CompositeAnimation* compAnim = it->second;
- if (!compAnim->isSuspended() && compAnim->isAnimating()) {
- isAnimating = true;
- compAnim->setAnimating(false);
-
- Node* node = it->first->element();
- ASSERT(!node || (node->document() && !node->document()->inPageCache()));
- node->setChanged(AnimationStyleChange);
- }
- }
+ m_eventsToDispatch.grow(m_eventsToDispatch.size()+1);
+ EventToDispatch& event = m_eventsToDispatch[m_eventsToDispatch.size()-1];
+ event.element = element;
+ event.eventType = eventType;
+ event.name = name;
+ event.elapsedTime = elapsedTime;
+
+ startUpdateRenderingDispatcher();
+}
+
+void AnimationControllerPrivate::addNodeChangeToDispatch(PassRefPtr<Node> node)
+{
+ m_nodeChangesToDispatch.append(node);
+ startUpdateRenderingDispatcher();
+}
- m_frame->document()->updateRendering();
+void AnimationControllerPrivate::animationTimerFired(Timer<AnimationControllerPrivate>*)
+{
+ // Make sure animationUpdateTime is updated, so that it is current even if no
+ // styleChange has happened (e.g. hardware animations)
+ setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);
- updateAnimationTimer();
+ // When the timer fires, all we do is call setChanged on all DOM nodes with running animations and then do an immediate
+ // updateRendering. It will then call back to us with new information.
+ updateAnimationTimer(true);
}
bool AnimationControllerPrivate::isAnimatingPropertyOnRenderer(RenderObject* renderer, int property, bool isRunningNow) const
{
- CompositeAnimation* animation = m_compositeAnimations.get(renderer);
+ RefPtr<CompositeAnimation> animation = m_compositeAnimations.get(renderer);
if (!animation)
return false;
@@ -179,7 +262,7 @@ void AnimationControllerPrivate::suspendAnimations(Document* document)
RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end();
for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) {
RenderObject* renderer = it->first;
- CompositeAnimation* compAnim = it->second;
+ RefPtr<CompositeAnimation> compAnim = it->second;
if (renderer->document() == document)
compAnim->suspendAnimations();
}
@@ -192,7 +275,7 @@ void AnimationControllerPrivate::resumeAnimations(Document* document)
RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end();
for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) {
RenderObject* renderer = it->first;
- CompositeAnimation* compAnim = it->second;
+ RefPtr<CompositeAnimation> compAnim = it->second;
if (renderer->document() == document)
compAnim->resumeAnimations();
}
@@ -200,9 +283,96 @@ void AnimationControllerPrivate::resumeAnimations(Document* document)
updateAnimationTimer();
}
+bool AnimationControllerPrivate::pauseAnimationAtTime(RenderObject* renderer, const String& name, double t)
+{
+ if (!renderer)
+ return false;
+
+ RefPtr<CompositeAnimation> compAnim = accessCompositeAnimation(renderer);
+ if (!compAnim)
+ return false;
+
+ if (compAnim->pauseAnimationAtTime(name, t)) {
+ renderer->node()->setChanged(AnimationStyleChange);
+ return true;
+ }
+
+ return false;
+}
+
+bool AnimationControllerPrivate::pauseTransitionAtTime(RenderObject* renderer, const String& property, double t)
+{
+ if (!renderer)
+ return false;
+
+ RefPtr<CompositeAnimation> compAnim = accessCompositeAnimation(renderer);
+ if (!compAnim)
+ return false;
+
+ if (compAnim->pauseTransitionAtTime(cssPropertyID(property), t)) {
+ renderer->node()->setChanged(AnimationStyleChange);
+ return true;
+ }
+
+ return false;
+}
+
+unsigned AnimationControllerPrivate::numberOfActiveAnimations() const
+{
+ unsigned count = 0;
+
+ RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end();
+ for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) {
+ CompositeAnimation* compAnim = it->second.get();
+ count += compAnim->numberOfActiveAnimations();
+ }
+
+ return count;
+}
+
+void AnimationControllerPrivate::addToStyleAvailableWaitList(AnimationBase* animation)
+{
+ ASSERT(!animation->next());
+
+ if (m_styleAvailableWaiters)
+ m_lastStyleAvailableWaiter->setNext(animation);
+ else
+ m_styleAvailableWaiters = animation;
+
+ m_lastStyleAvailableWaiter = animation;
+ animation->setNext(0);
+}
+
+void AnimationControllerPrivate::removeFromStyleAvailableWaitList(AnimationBase* animationToRemove)
+{
+ AnimationBase* prevAnimation = 0;
+ for (AnimationBase* animation = m_styleAvailableWaiters; animation; animation = animation->next()) {
+ if (animation == animationToRemove) {
+ if (prevAnimation)
+ prevAnimation->setNext(animation->next());
+ else
+ m_styleAvailableWaiters = animation->next();
+
+ if (m_lastStyleAvailableWaiter == animation)
+ m_lastStyleAvailableWaiter = prevAnimation;
+
+ animationToRemove->setNext(0);
+ }
+ }
+}
+
+void AnimationControllerPrivate::styleAvailable()
+{
+ // Go through list of waiters and send them on their way
+ for (AnimationBase* animation = m_styleAvailableWaiters; animation; animation = animation->next())
+ animation->styleAvailable();
+
+ m_styleAvailableWaiters = 0;
+ m_lastStyleAvailableWaiter = 0;
+}
+
AnimationController::AnimationController(Frame* frame)
: m_data(new AnimationControllerPrivate(frame))
- , m_numStyleAvailableWaiters(0)
{
}
@@ -224,7 +394,7 @@ void AnimationController::cancelAnimations(RenderObject* renderer)
}
PassRefPtr<RenderStyle> AnimationController::updateAnimations(RenderObject* renderer, RenderStyle* newStyle)
-{
+{
// Don't do anything if we're in the cache
if (!renderer->document() || renderer->document()->inPageCache())
return newStyle;
@@ -240,7 +410,7 @@ PassRefPtr<RenderStyle> AnimationController::updateAnimations(RenderObject* rend
// a new style.
ASSERT(renderer->element()); // FIXME: We do not animate generated content yet.
- CompositeAnimation* rendererAnimations = m_data->accessCompositeAnimation(renderer);
+ RefPtr<CompositeAnimation> rendererAnimations = m_data->accessCompositeAnimation(renderer);
RefPtr<RenderStyle> blendedStyle = rendererAnimations->animate(renderer, oldStyle, newStyle);
m_data->updateAnimationTimer();
@@ -257,16 +427,31 @@ PassRefPtr<RenderStyle> AnimationController::updateAnimations(RenderObject* rend
void AnimationController::setAnimationStartTime(RenderObject* renderer, double t)
{
- CompositeAnimation* rendererAnimations = m_data->accessCompositeAnimation(renderer);
+ RefPtr<CompositeAnimation> rendererAnimations = m_data->accessCompositeAnimation(renderer);
rendererAnimations->setAnimationStartTime(t);
}
void AnimationController::setTransitionStartTime(RenderObject* renderer, int property, double t)
{
- CompositeAnimation* rendererAnimations = m_data->accessCompositeAnimation(renderer);
+ RefPtr<CompositeAnimation> rendererAnimations = m_data->accessCompositeAnimation(renderer);
rendererAnimations->setTransitionStartTime(property, t);
}
+bool AnimationController::pauseAnimationAtTime(RenderObject* renderer, const String& name, double t)
+{
+ return m_data->pauseAnimationAtTime(renderer, name, t);
+}
+
+unsigned AnimationController::numberOfActiveAnimations() const
+{
+ return m_data->numberOfActiveAnimations();
+}
+
+bool AnimationController::pauseTransitionAtTime(RenderObject* renderer, const String& property, double t)
+{
+ return m_data->pauseTransitionAtTime(renderer, property, t);
+}
+
bool AnimationController::isAnimatingPropertyOnRenderer(RenderObject* renderer, int property, bool isRunningNow) const
{
return m_data->isAnimatingPropertyOnRenderer(renderer, property, isRunningNow);
@@ -287,12 +472,41 @@ void AnimationController::startUpdateRenderingDispatcher()
m_data->startUpdateRenderingDispatcher();
}
-void AnimationController::styleAvailable()
+void AnimationController::addEventToDispatch(PassRefPtr<Element> element, const AtomicString& eventType, const String& name, double elapsedTime)
{
- if (!m_numStyleAvailableWaiters)
- return;
+ m_data->addEventToDispatch(element, eventType, name, elapsedTime);
+}
+
+void AnimationController::addNodeChangeToDispatch(PassRefPtr<Node> node)
+{
+ ASSERT(!node || (node->document() && !node->document()->inPageCache()));
+ if (node)
+ m_data->addNodeChangeToDispatch(node);
+}
+double AnimationController::beginAnimationUpdateTime()
+{
+ return m_data->beginAnimationUpdateTime();
+}
+
+void AnimationController::beginAnimationUpdate()
+{
+ m_data->setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);
+}
+
+void AnimationController::endAnimationUpdate()
+{
m_data->styleAvailable();
}
+void AnimationController::addToStyleAvailableWaitList(AnimationBase* animation)
+{
+ m_data->addToStyleAvailableWaitList(animation);
+}
+
+void AnimationController::removeFromStyleAvailableWaitList(AnimationBase* animation)
+{
+ m_data->removeFromStyleAvailableWaitList(animation);
+}
+
} // namespace WebCore
diff --git a/WebCore/page/animation/AnimationController.h b/WebCore/page/animation/AnimationController.h
index bc13a2a..13ea1bd 100644
--- a/WebCore/page/animation/AnimationController.h
+++ b/WebCore/page/animation/AnimationController.h
@@ -33,11 +33,16 @@
namespace WebCore {
+class AnimationBase;
class AnimationControllerPrivate;
+class AtomicString;
class Document;
+class Element;
class Frame;
+class Node;
class RenderObject;
class RenderStyle;
+class String;
class AnimationController {
public:
@@ -50,27 +55,29 @@ public:
void setAnimationStartTime(RenderObject*, double t);
void setTransitionStartTime(RenderObject*, int property, double t);
+ bool pauseAnimationAtTime(RenderObject*, const String& name, double t); // To be used only for testing
+ bool pauseTransitionAtTime(RenderObject*, const String& property, double t); // To be used only for testing
+ unsigned numberOfActiveAnimations() const; // To be used only for testing
+
bool isAnimatingPropertyOnRenderer(RenderObject*, int property, bool isRunningNow) const;
void suspendAnimations(Document*);
void resumeAnimations(Document*);
- void updateAnimationTimer();
void startUpdateRenderingDispatcher();
+ void addEventToDispatch(PassRefPtr<Element>, const AtomicString& eventType, const String& name, double elapsedTime);
+ void addNodeChangeToDispatch(PassRefPtr<Node>);
- void styleAvailable();
+ void addToStyleAvailableWaitList(AnimationBase*);
+ void removeFromStyleAvailableWaitList(AnimationBase*);
- void setWaitingForStyleAvailable(bool waiting)
- {
- if (waiting)
- m_numStyleAvailableWaiters++;
- else
- m_numStyleAvailableWaiters--;
- }
+ double beginAnimationUpdateTime();
+
+ void beginAnimationUpdate();
+ void endAnimationUpdate();
private:
AnimationControllerPrivate* m_data;
- unsigned m_numStyleAvailableWaiters;
};
} // namespace WebCore
diff --git a/WebCore/page/animation/CompositeAnimation.cpp b/WebCore/page/animation/CompositeAnimation.cpp
index 2ae68d9..bf61b78 100644
--- a/WebCore/page/animation/CompositeAnimation.cpp
+++ b/WebCore/page/animation/CompositeAnimation.cpp
@@ -50,15 +50,16 @@ public:
~CompositeAnimationPrivate();
+ void clearRenderer();
+
PassRefPtr<RenderStyle> animate(RenderObject*, RenderStyle* currentStyle, RenderStyle* targetStyle);
+ AnimationController* animationController() { return m_animationController; }
+
void setAnimating(bool);
- bool isAnimating() const;
+ double willNeedService() const;
- const KeyframeAnimation* getAnimationForProperty(int property) const;
-
- void resetTransitions(RenderObject*);
- void resetAnimations(RenderObject*);
+ PassRefPtr<KeyframeAnimation> getAnimationForProperty(int property);
void cleanupFinishedAnimations(RenderObject*);
@@ -72,11 +73,16 @@ public:
void overrideImplicitAnimations(int property);
void resumeOverriddenImplicitAnimations(int property);
- void styleAvailable();
+ bool hasAnimations() const { return !m_transitions.isEmpty() || !m_keyframeAnimations.isEmpty(); }
bool isAnimatingProperty(int property, bool isRunningNow) const;
- void setWaitingForStyleAvailable(bool);
+ void addToStyleAvailableWaitList(AnimationBase*);
+ void removeFromStyleAvailableWaitList(AnimationBase*);
+
+ bool pauseAnimationAtTime(const AtomicString& name, double t);
+ bool pauseTransitionAtTime(int property, double t);
+ unsigned numberOfActiveAnimations() const;
protected:
void updateTransitions(RenderObject*, RenderStyle* currentStyle, RenderStyle* targetStyle);
@@ -96,9 +102,30 @@ private:
CompositeAnimationPrivate::~CompositeAnimationPrivate()
{
+ // Toss the refs to all animations
m_transitions.clear();
m_keyframeAnimations.clear();
}
+
+void CompositeAnimationPrivate::clearRenderer()
+{
+ if (!m_transitions.isEmpty()) {
+ // Clear the renderers from all running animations, in case we are in the middle of
+ // an animation callback (see https://bugs.webkit.org/show_bug.cgi?id=22052)
+ CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
+ ImplicitAnimation* transition = it->second.get();
+ transition->clearRenderer();
+ }
+ }
+ if (!m_keyframeAnimations.isEmpty()) {
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ KeyframeAnimation* anim = it->second.get();
+ anim->clearRenderer();
+ }
+ }
+}
void CompositeAnimationPrivate::updateTransitions(RenderObject* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle)
{
@@ -122,17 +149,20 @@ void CompositeAnimationPrivate::updateTransitions(RenderObject* renderer, Render
// through the loop.
for (int propertyIndex = 0; propertyIndex < AnimationBase::getNumProperties(); ++propertyIndex) {
if (all) {
- // Get the next property
- prop = AnimationBase::getPropertyAtIndex(propertyIndex);
+ // Get the next property which is not a shorthand.
+ bool isShorthand;
+ prop = AnimationBase::getPropertyAtIndex(propertyIndex, isShorthand);
+ if (isShorthand)
+ continue;
}
// ImplicitAnimations are always hashed by actual properties, never cAnimateAll
- ASSERT(prop > firstCSSProperty && prop < (firstCSSProperty + numCSSProperties));
+ ASSERT(prop >= firstCSSProperty && prop < (firstCSSProperty + numCSSProperties));
// If there is a running animation for this property, the transition is overridden
// and we have to use the unanimatedStyle from the animation. We do the test
// against the unanimated style here, but we "override" the transition later.
- const KeyframeAnimation* keyframeAnim = getAnimationForProperty(prop);
+ RefPtr<KeyframeAnimation> keyframeAnim = getAnimationForProperty(prop);
RenderStyle* fromStyle = keyframeAnim ? keyframeAnim->unanimatedStyle() : currentStyle;
// See if there is a current transition for this prop
@@ -140,14 +170,12 @@ void CompositeAnimationPrivate::updateTransitions(RenderObject* renderer, Render
bool equal = true;
if (implAnim) {
- // This implAnim might not be an already running transition. It might be
- // newly added to the list in a previous iteration. This would happen if
- // you have both an explicit transition-property and 'all' in the same
- // list. In this case, the latter one overrides the earlier one, so we
- // behave as though this is a running animation being replaced.
- if (!isActiveTransition)
- m_transitions.remove(prop);
- else if (!implAnim->isTargetPropertyEqual(prop, targetStyle)) {
+ // This implAnim might not be an already running transition. It might be
+ // newly added to the list in a previous iteration. This would happen if
+ // you have both an explicit transition-property and 'all' in the same
+ // list. In this case, the latter one overrides the earlier one, so we
+ // behave as though this is a running animation being replaced.
+ if (!implAnim->isTargetPropertyEqual(prop, targetStyle)) {
m_transitions.remove(prop);
equal = false;
}
@@ -239,10 +267,12 @@ PassRefPtr<RenderStyle> CompositeAnimationPrivate::animate(RenderObject* rendere
if (currentStyle) {
// Now that we have transition objects ready, let them know about the new goal state. We want them
// to fill in a RenderStyle*& only if needed.
- CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
- if (ImplicitAnimation* anim = it->second.get())
- anim->animate(m_compositeAnimation, renderer, currentStyle, targetStyle, resultStyle);
+ if (!m_transitions.isEmpty()) {
+ CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
+ if (ImplicitAnimation* anim = it->second.get())
+ anim->animate(m_compositeAnimation, renderer, currentStyle, targetStyle, resultStyle);
+ }
}
}
@@ -269,123 +299,139 @@ PassRefPtr<RenderStyle> CompositeAnimationPrivate::animate(RenderObject* rendere
// "animating" means that something is running that requires the timer to keep firing
void CompositeAnimationPrivate::setAnimating(bool animating)
{
- CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
- ImplicitAnimation* transition = it->second.get();
- transition->setAnimating(animating);
+ if (!m_transitions.isEmpty()) {
+ CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
+ ImplicitAnimation* transition = it->second.get();
+ transition->setAnimating(animating);
+ }
}
-
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- KeyframeAnimation* anim = it->second.get();
- anim->setAnimating(animating);
+ if (!m_keyframeAnimations.isEmpty()) {
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ KeyframeAnimation* anim = it->second.get();
+ anim->setAnimating(animating);
+ }
}
}
-bool CompositeAnimationPrivate::isAnimating() const
+double CompositeAnimationPrivate::willNeedService() const
{
- CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
- ImplicitAnimation* transition = it->second.get();
- if (transition && transition->isAnimating() && transition->running())
- return true;
+ // Returns the time at which next service is required. -1 means no service is required. 0 means
+ // service is required now, and > 0 means service is required that many seconds in the future.
+ double minT = -1;
+
+ if (!m_transitions.isEmpty()) {
+ CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
+ ImplicitAnimation* transition = it->second.get();
+ double t = transition ? transition->willNeedService() : -1;
+ if (t < minT || minT == -1)
+ minT = t;
+ if (minT == 0)
+ return 0;
+ }
}
-
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- KeyframeAnimation* anim = it->second.get();
- if (anim && !anim->paused() && anim->isAnimating() && anim->active())
- return true;
+ if (!m_keyframeAnimations.isEmpty()) {
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ KeyframeAnimation* animation = it->second.get();
+ double t = animation ? animation->willNeedService() : -1;
+ if (t < minT || minT == -1)
+ minT = t;
+ if (minT == 0)
+ return 0;
+ }
}
- return false;
+ return minT;
}
-const KeyframeAnimation* CompositeAnimationPrivate::getAnimationForProperty(int property) const
+PassRefPtr<KeyframeAnimation> CompositeAnimationPrivate::getAnimationForProperty(int property)
{
- const KeyframeAnimation* retval = 0;
+ RefPtr<KeyframeAnimation> retval;
// We want to send back the last animation with the property if there are multiples.
// So we need to iterate through all animations
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- const KeyframeAnimation* anim = it->second.get();
- if (anim->hasAnimationForProperty(property))
- retval = anim;
+ if (!m_keyframeAnimations.isEmpty()) {
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ RefPtr<KeyframeAnimation> anim = it->second;
+ if (anim->hasAnimationForProperty(property))
+ retval = anim;
+ }
}
return retval;
}
-void CompositeAnimationPrivate::resetTransitions(RenderObject* renderer)
-{
- m_transitions.clear();
-}
-
-void CompositeAnimationPrivate::resetAnimations(RenderObject*)
-{
- m_keyframeAnimations.clear();
-}
-
-void CompositeAnimationPrivate::cleanupFinishedAnimations(RenderObject* renderer)
+void CompositeAnimationPrivate::cleanupFinishedAnimations(RenderObject*)
{
if (isSuspended())
return;
// Make a list of transitions to be deleted
Vector<int> finishedTransitions;
- CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
+ if (!m_transitions.isEmpty()) {
+ CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
- ImplicitAnimation* anim = it->second.get();
- if (!anim)
- continue;
- if (anim->postActive())
- finishedTransitions.append(anim->animatingProperty());
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
+ ImplicitAnimation* anim = it->second.get();
+ if (!anim)
+ continue;
+ if (anim->postActive())
+ finishedTransitions.append(anim->animatingProperty());
+ }
+
+ // Delete them
+ size_t finishedTransitionCount = finishedTransitions.size();
+ for (size_t i = 0; i < finishedTransitionCount; ++i)
+ m_transitions.remove(finishedTransitions[i]);
}
- // Delete them
- size_t finishedTransitionCount = finishedTransitions.size();
- for (size_t i = 0; i < finishedTransitionCount; ++i)
- m_transitions.remove(finishedTransitions[i]);
-
// Make a list of animations to be deleted
Vector<AtomicStringImpl*> finishedAnimations;
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ if (!m_keyframeAnimations.isEmpty()) {
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- KeyframeAnimation* anim = it->second.get();
- if (!anim)
- continue;
- if (anim->postActive())
- finishedAnimations.append(anim->name().impl());
- }
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ KeyframeAnimation* anim = it->second.get();
+ if (!anim)
+ continue;
+ if (anim->postActive())
+ finishedAnimations.append(anim->name().impl());
+ }
- // Delete them
- size_t finishedAnimationCount = finishedAnimations.size();
- for (size_t i = 0; i < finishedAnimationCount; ++i)
- m_keyframeAnimations.remove(finishedAnimations[i]);
+ // Delete them
+ size_t finishedAnimationCount = finishedAnimations.size();
+ for (size_t i = 0; i < finishedAnimationCount; ++i)
+ m_keyframeAnimations.remove(finishedAnimations[i]);
+ }
}
void CompositeAnimationPrivate::setAnimationStartTime(double t)
{
// Set start time on all animations waiting for it
- AnimationNameMap::const_iterator end = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != end; ++it) {
- KeyframeAnimation* anim = it->second.get();
- if (anim && anim->waitingForStartTime())
- anim->updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, t);
+ if (!m_keyframeAnimations.isEmpty()) {
+ AnimationNameMap::const_iterator end = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != end; ++it) {
+ KeyframeAnimation* anim = it->second.get();
+ if (anim && anim->waitingForStartTime())
+ anim->updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, t);
+ }
}
}
void CompositeAnimationPrivate::setTransitionStartTime(int property, double t)
{
// Set the start time for given property transition
- CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
- ImplicitAnimation* anim = it->second.get();
- if (anim && anim->waitingForStartTime() && anim->animatingProperty() == property)
- anim->updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, t);
+ if (!m_transitions.isEmpty()) {
+ CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
+ ImplicitAnimation* anim = it->second.get();
+ if (anim && anim->waitingForStartTime() && anim->animatingProperty() == property)
+ anim->updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, t);
+ }
}
}
@@ -396,17 +442,20 @@ void CompositeAnimationPrivate::suspendAnimations()
m_isSuspended = true;
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- if (KeyframeAnimation* anim = it->second.get())
- anim->updatePlayState(false);
+ if (!m_keyframeAnimations.isEmpty()) {
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ if (KeyframeAnimation* anim = it->second.get())
+ anim->updatePlayState(false);
+ }
}
-
- CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
- ImplicitAnimation* anim = it->second.get();
- if (anim && anim->hasStyle())
- anim->updatePlayState(false);
+ if (!m_transitions.isEmpty()) {
+ CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
+ ImplicitAnimation* anim = it->second.get();
+ if (anim && anim->hasStyle())
+ anim->updatePlayState(false);
+ }
}
}
@@ -417,98 +466,139 @@ void CompositeAnimationPrivate::resumeAnimations()
m_isSuspended = false;
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- KeyframeAnimation* anim = it->second.get();
- if (anim && anim->playStatePlaying())
- anim->updatePlayState(true);
+ if (!m_keyframeAnimations.isEmpty()) {
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ KeyframeAnimation* anim = it->second.get();
+ if (anim && anim->playStatePlaying())
+ anim->updatePlayState(true);
+ }
}
- CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
- ImplicitAnimation* anim = it->second.get();
- if (anim && anim->hasStyle())
- anim->updatePlayState(true);
+ if (!m_transitions.isEmpty()) {
+ CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
+ ImplicitAnimation* anim = it->second.get();
+ if (anim && anim->hasStyle())
+ anim->updatePlayState(true);
+ }
}
}
void CompositeAnimationPrivate::overrideImplicitAnimations(int property)
{
CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
- ImplicitAnimation* anim = it->second.get();
- if (anim && anim->animatingProperty() == property)
- anim->setOverridden(true);
+ if (!m_transitions.isEmpty()) {
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
+ ImplicitAnimation* anim = it->second.get();
+ if (anim && anim->animatingProperty() == property)
+ anim->setOverridden(true);
+ }
}
}
void CompositeAnimationPrivate::resumeOverriddenImplicitAnimations(int property)
{
- CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
- ImplicitAnimation* anim = it->second.get();
- if (anim && anim->animatingProperty() == property)
- anim->setOverridden(false);
+ if (!m_transitions.isEmpty()) {
+ CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
+ ImplicitAnimation* anim = it->second.get();
+ if (anim && anim->animatingProperty() == property)
+ anim->setOverridden(false);
+ }
+ }
+}
+
+bool CompositeAnimationPrivate::isAnimatingProperty(int property, bool isRunningNow) const
+{
+ if (!m_keyframeAnimations.isEmpty()) {
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ KeyframeAnimation* anim = it->second.get();
+ if (anim && anim->isAnimatingProperty(property, isRunningNow))
+ return true;
+ }
+ }
+
+ if (!m_transitions.isEmpty()) {
+ CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
+ ImplicitAnimation* anim = it->second.get();
+ if (anim && anim->isAnimatingProperty(property, isRunningNow))
+ return true;
+ }
}
+ return false;
}
-static inline bool compareAnimationIndices(RefPtr<KeyframeAnimation> a, const RefPtr<KeyframeAnimation> b)
+void CompositeAnimationPrivate::addToStyleAvailableWaitList(AnimationBase* animation)
{
- return a->index() < b->index();
+ m_animationController->addToStyleAvailableWaitList(animation);
}
-void CompositeAnimationPrivate::styleAvailable()
+void CompositeAnimationPrivate::removeFromStyleAvailableWaitList(AnimationBase* animation)
{
- if (m_numStyleAvailableWaiters == 0)
- return;
+ m_animationController->removeFromStyleAvailableWaitList(animation);
+}
- // We have to go through animations in the order in which they appear in
- // the style, because order matters for additivity.
- Vector<RefPtr<KeyframeAnimation> > animations(m_keyframeAnimations.size());
- copyValuesToVector(m_keyframeAnimations, animations);
+bool CompositeAnimationPrivate::pauseAnimationAtTime(const AtomicString& name, double t)
+{
+ if (!name)
+ return false;
- if (animations.size() > 1)
- std::stable_sort(animations.begin(), animations.end(), compareAnimationIndices);
+ RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(name.impl());
+ if (!keyframeAnim || !keyframeAnim->running())
+ return false;
- for (size_t i = 0; i < animations.size(); ++i) {
- KeyframeAnimation* anim = animations[i].get();
- if (anim && anim->waitingForStyleAvailable())
- anim->updateStateMachine(AnimationBase::AnimationStateInputStyleAvailable, -1);
+ int count = keyframeAnim->m_animation->iterationCount();
+ if ((t >= 0.0) && (!count || (t <= count * keyframeAnim->duration()))) {
+ keyframeAnim->pauseAtTime(t);
+ return true;
}
- CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
- ImplicitAnimation* anim = it->second.get();
- if (anim && anim->waitingForStyleAvailable())
- anim->updateStateMachine(AnimationBase::AnimationStateInputStyleAvailable, -1);
- }
+ return false;
}
-bool CompositeAnimationPrivate::isAnimatingProperty(int property, bool isRunningNow) const
+bool CompositeAnimationPrivate::pauseTransitionAtTime(int property, double t)
{
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- KeyframeAnimation* anim = it->second.get();
- if (anim && anim->isAnimatingProperty(property, isRunningNow))
- return true;
- }
+ if ((property < firstCSSProperty) || (property >= firstCSSProperty + numCSSProperties))
+ return false;
+
+ ImplicitAnimation* implAnim = m_transitions.get(property).get();
+ if (!implAnim || !implAnim->running())
+ return false;
- CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
- ImplicitAnimation* anim = it->second.get();
- if (anim && anim->isAnimatingProperty(property, isRunningNow))
- return true;
+ if ((t >= 0.0) && (t <= implAnim->duration())) {
+ implAnim->pauseAtTime(t);
+ return true;
}
+
return false;
}
-void CompositeAnimationPrivate::setWaitingForStyleAvailable(bool waiting)
+unsigned CompositeAnimationPrivate::numberOfActiveAnimations() const
{
- if (waiting)
- m_numStyleAvailableWaiters++;
- else
- m_numStyleAvailableWaiters--;
- m_animationController->setWaitingForStyleAvailable(waiting);
+ unsigned count = 0;
+
+ if (!m_keyframeAnimations.isEmpty()) {
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ KeyframeAnimation* anim = it->second.get();
+ if (anim->running())
+ ++count;
+ }
+ }
+
+ if (!m_transitions.isEmpty()) {
+ CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
+ ImplicitAnimation* anim = it->second.get();
+ if (anim->running())
+ ++count;
+ }
+ }
+
+ return count;
}
CompositeAnimation::CompositeAnimation(AnimationController* animationController)
@@ -521,24 +611,34 @@ CompositeAnimation::~CompositeAnimation()
delete m_data;
}
+AnimationController* CompositeAnimation::animationController()
+{
+ return m_data->animationController();
+}
+
+void CompositeAnimation::clearRenderer()
+{
+ m_data->clearRenderer();
+}
+
PassRefPtr<RenderStyle> CompositeAnimation::animate(RenderObject* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle)
{
return m_data->animate(renderer, currentStyle, targetStyle);
}
-bool CompositeAnimation::isAnimating() const
+double CompositeAnimation::willNeedService() const
{
- return m_data->isAnimating();
+ return m_data->willNeedService();
}
-void CompositeAnimation::setWaitingForStyleAvailable(bool b)
+void CompositeAnimation::addToStyleAvailableWaitList(AnimationBase* animation)
{
- m_data->setWaitingForStyleAvailable(b);
+ m_data->addToStyleAvailableWaitList(animation);
}
-void CompositeAnimation::resetTransitions(RenderObject* renderer)
+void CompositeAnimation::removeFromStyleAvailableWaitList(AnimationBase* animation)
{
- m_data->resetTransitions(renderer);
+ m_data->removeFromStyleAvailableWaitList(animation);
}
void CompositeAnimation::suspendAnimations()
@@ -556,9 +656,9 @@ bool CompositeAnimation::isSuspended() const
return m_data->isSuspended();
}
-void CompositeAnimation::styleAvailable()
+bool CompositeAnimation::hasAnimations() const
{
- m_data->styleAvailable();
+ return m_data->hasAnimations();
}
void CompositeAnimation::setAnimating(bool b)
@@ -571,6 +671,11 @@ bool CompositeAnimation::isAnimatingProperty(int property, bool isRunningNow) co
return m_data->isAnimatingProperty(property, isRunningNow);
}
+PassRefPtr<KeyframeAnimation> CompositeAnimation::getAnimationForProperty(int property)
+{
+ return m_data->getAnimationForProperty(property);
+}
+
void CompositeAnimation::setAnimationStartTime(double t)
{
m_data->setAnimationStartTime(t);
@@ -591,4 +696,19 @@ void CompositeAnimation::resumeOverriddenImplicitAnimations(int property)
m_data->resumeOverriddenImplicitAnimations(property);
}
+bool CompositeAnimation::pauseAnimationAtTime(const AtomicString& name, double t)
+{
+ return m_data->pauseAnimationAtTime(name, t);
+}
+
+bool CompositeAnimation::pauseTransitionAtTime(int property, double t)
+{
+ return m_data->pauseTransitionAtTime(property, t);
+}
+
+unsigned CompositeAnimation::numberOfActiveAnimations() const
+{
+ return m_data->numberOfActiveAnimations();
+}
+
} // namespace WebCore
diff --git a/WebCore/page/animation/CompositeAnimation.h b/WebCore/page/animation/CompositeAnimation.h
index 13f1179..3517b34 100644
--- a/WebCore/page/animation/CompositeAnimation.h
+++ b/WebCore/page/animation/CompositeAnimation.h
@@ -37,30 +37,41 @@
namespace WebCore {
class CompositeAnimationPrivate;
+class AnimationBase;
class AnimationController;
+class KeyframeAnimation;
class RenderObject;
class RenderStyle;
// A CompositeAnimation represents a collection of animations that are running
// on a single RenderObject, such as a number of properties transitioning at once.
-class CompositeAnimation : public Noncopyable {
+class CompositeAnimation : public RefCounted<CompositeAnimation> {
public:
- CompositeAnimation(AnimationController* animationController);
+ static PassRefPtr<CompositeAnimation> create(AnimationController* animationController)
+ {
+ return adoptRef(new CompositeAnimation(animationController));
+ };
+
~CompositeAnimation();
+
+ void clearRenderer();
PassRefPtr<RenderStyle> animate(RenderObject*, RenderStyle* currentStyle, RenderStyle* targetStyle);
- bool isAnimating() const;
-
- void setWaitingForStyleAvailable(bool);
- void resetTransitions(RenderObject*);
+ double willNeedService() const;
+
+ AnimationController* animationController();
void suspendAnimations();
void resumeAnimations();
bool isSuspended() const;
+
+ bool hasAnimations() const;
- void styleAvailable();
void setAnimating(bool);
bool isAnimatingProperty(int property, bool isRunningNow) const;
+
+ PassRefPtr<KeyframeAnimation> getAnimationForProperty(int property);
+
void setAnimationStartTime(double t);
void setTransitionStartTime(int property, double t);
@@ -68,7 +79,16 @@ public:
void overrideImplicitAnimations(int property);
void resumeOverriddenImplicitAnimations(int property);
+ bool pauseAnimationAtTime(const AtomicString& name, double t);
+ bool pauseTransitionAtTime(int property, double t);
+ unsigned numberOfActiveAnimations() const;
+
+ void addToStyleAvailableWaitList(AnimationBase*);
+ void removeFromStyleAvailableWaitList(AnimationBase*);
+
private:
+ CompositeAnimation(AnimationController* animationController);
+
CompositeAnimationPrivate* m_data;
};
diff --git a/WebCore/page/animation/ImplicitAnimation.cpp b/WebCore/page/animation/ImplicitAnimation.cpp
index 4d470e4..f984909 100644
--- a/WebCore/page/animation/ImplicitAnimation.cpp
+++ b/WebCore/page/animation/ImplicitAnimation.cpp
@@ -27,9 +27,13 @@
*/
#include "config.h"
+
+#include "AnimationController.h"
+#include "CompositeAnimation.h"
#include "CSSPropertyNames.h"
#include "EventNames.h"
#include "ImplicitAnimation.h"
+#include "KeyframeAnimation.h"
#include "RenderObject.h"
namespace WebCore {
@@ -56,12 +60,8 @@ bool ImplicitAnimation::shouldSendEventForListener(Document::ListenerType inList
return m_object->document()->hasListenerType(inListenerType);
}
-void ImplicitAnimation::animate(CompositeAnimation* animation, RenderObject* renderer, RenderStyle* currentStyle,
- RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle)
+void ImplicitAnimation::animate(CompositeAnimation*, RenderObject*, RenderStyle*, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle)
{
- if (paused())
- return;
-
// If we get this far and the animation is done, it means we are cleaning up a just finished animation.
// So just return. Everything is already all cleaned up.
if (postActive())
@@ -78,10 +78,22 @@ void ImplicitAnimation::animate(CompositeAnimation* animation, RenderObject* ren
if (blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0)))
setAnimating();
+
+ // Fire the start timeout if needed
+ fireAnimationEventsIfNeeded();
}
void ImplicitAnimation::onAnimationEnd(double elapsedTime)
{
+ // If we have a keyframe animation on this property, this transition is being overridden. The keyframe
+ // animation keeps an unanimated style in case a transition starts while the keyframe animation is
+ // running. But now that the transition has completed, we need to update this style with its new
+ // destination. If we didn't, the next time through we would think a transition had started
+ // (comparing the old unanimated style with the new final style of the transition).
+ RefPtr<KeyframeAnimation> keyframeAnim = m_compAnim->getAnimationForProperty(m_animatingProperty);
+ if (keyframeAnim)
+ keyframeAnim->setUnanimatedStyle(m_toStyle);
+
if (!sendTransitionEvent(eventNames().webkitTransitionEndEvent, elapsedTime)) {
// We didn't dispatch an event, which would call endAnimation(), so we'll just call it here.
endAnimation(true);
@@ -107,14 +119,11 @@ bool ImplicitAnimation::sendTransitionEvent(const AtomicString& eventType, doubl
if (!element)
return false;
- // Keep a reference to this ImplicitAnimation so it doesn't go away in the handler
- RefPtr<ImplicitAnimation> retainer(this);
-
- // Call the event handler
- element->dispatchWebKitTransitionEvent(eventType, propertyName, elapsedTime);
+ // Schedule event handling
+ m_object->animation()->addEventToDispatch(element, eventType, propertyName, elapsedTime);
// Restore the original (unanimated) style
- if (eventType == eventNames().webkitAnimationEndEvent && element->renderer())
+ if (eventType == eventNames().webkitTransitionEndEvent && element->renderer())
setChanged(element.get());
return true; // Did dispatch an event
diff --git a/WebCore/page/animation/ImplicitAnimation.h b/WebCore/page/animation/ImplicitAnimation.h
index 7c9d50f..cf98bba 100644
--- a/WebCore/page/animation/ImplicitAnimation.h
+++ b/WebCore/page/animation/ImplicitAnimation.h
@@ -54,8 +54,6 @@ public:
void setOverridden(bool);
virtual bool overridden() const { return m_overridden; }
- virtual bool shouldFireEvents() const { return true; }
-
virtual bool affectsProperty(int) const;
bool hasStyle() const { return m_fromStyle && m_toStyle; }
diff --git a/WebCore/page/animation/KeyframeAnimation.cpp b/WebCore/page/animation/KeyframeAnimation.cpp
index 69fdd11..2efa578 100644
--- a/WebCore/page/animation/KeyframeAnimation.cpp
+++ b/WebCore/page/animation/KeyframeAnimation.cpp
@@ -29,12 +29,12 @@
#include "config.h"
#include "KeyframeAnimation.h"
+#include "AnimationController.h"
#include "CSSPropertyNames.h"
#include "CSSStyleSelector.h"
#include "CompositeAnimation.h"
#include "EventNames.h"
#include "RenderObject.h"
-#include "SystemTime.h"
namespace WebCore {
@@ -59,9 +59,11 @@ KeyframeAnimation::~KeyframeAnimation()
updateStateMachine(AnimationStateInputEndAnimation, -1);
}
-void KeyframeAnimation::animate(CompositeAnimation* animation, RenderObject* renderer, const RenderStyle* currentStyle,
- const RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle)
+void KeyframeAnimation::animate(CompositeAnimation*, RenderObject*, const RenderStyle*, const RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle)
{
+ // Fire the start timeout if needed
+ fireAnimationEventsIfNeeded();
+
// If we have not yet started, we will not have a valid start time, so just start the animation if needed.
if (isNew() && m_animation->playState() == AnimPlayStatePlaying)
updateStateMachine(AnimationStateInputStartAnimation, -1);
@@ -84,9 +86,7 @@ void KeyframeAnimation::animate(CompositeAnimation* animation, RenderObject* ren
// We should cache the last pair or something.
// Find the first key
- double elapsedTime = (m_startTime > 0) ? ((!paused() ? currentTime() : m_pauseTime) - m_startTime) : 0;
- if (elapsedTime < 0)
- elapsedTime = 0;
+ double elapsedTime = getElapsedTime();
double t = m_animation->duration() ? (elapsedTime / m_animation->duration()) : 1;
int i = static_cast<int>(t);
@@ -200,11 +200,8 @@ bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double
if (!element)
return false;
- // Keep a reference to this ImplicitAnimation so it doesn't go away in the handler
- RefPtr<KeyframeAnimation> retainer(this);
-
- // Call the event handler
- element->dispatchWebKitAnimationEvent(eventType, m_keyframes.animationName(), elapsedTime);
+ // Schedule event handling
+ m_object->animation()->addEventToDispatch(element, eventType, m_keyframes.animationName(), elapsedTime);
// Restore the original (unanimated) style
if (eventType == eventNames().webkitAnimationEndEvent && element->renderer())
diff --git a/WebCore/page/animation/KeyframeAnimation.h b/WebCore/page/animation/KeyframeAnimation.h
index 55b429a..5c3176c 100644
--- a/WebCore/page/animation/KeyframeAnimation.h
+++ b/WebCore/page/animation/KeyframeAnimation.h
@@ -51,10 +51,9 @@ public:
int index() const { return m_index; }
void setIndex(int i) { m_index = i; }
- virtual bool shouldFireEvents() const { return true; }
-
bool hasAnimationForProperty(int property) const;
+ void setUnanimatedStyle(PassRefPtr<RenderStyle> style) { m_unanimatedStyle = style; }
RenderStyle* unanimatedStyle() const { return m_unanimatedStyle.get(); }
protected:
diff --git a/WebCore/page/chromium/AXObjectCacheChromium.cpp b/WebCore/page/chromium/AXObjectCacheChromium.cpp
new file mode 100644
index 0000000..bbaf21d
--- /dev/null
+++ b/WebCore/page/chromium/AXObjectCacheChromium.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008 Google Inc.
+ *
+ * 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. ``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
+ * 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 "AXObjectCache.h"
+
+#include "AccessibilityObject.h"
+
+namespace WebCore {
+
+void AXObjectCache::detachWrapper(AccessibilityObject* obj)
+{
+ // In Chromium, AccessibilityObjects are wrapped lazily.
+ if (AccessibilityObjectWrapper* wrapper = obj->wrapper())
+ wrapper->detach();
+}
+
+void AXObjectCache::attachWrapper(AccessibilityObject*)
+{
+ // In Chromium, AccessibilityObjects are wrapped lazily.
+}
+
+void AXObjectCache::postNotification(RenderObject*, const String&)
+{
+}
+
+void AXObjectCache::postNotificationToElement(RenderObject*, const String&)
+{
+}
+
+void AXObjectCache::handleFocusedUIElementChanged()
+{
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/PositionOptions.idl b/WebCore/page/chromium/AccessibilityObjectChromium.cpp
index 29253df..650fb3a 100644
--- a/WebCore/page/PositionOptions.idl
+++ b/WebCore/page/chromium/AccessibilityObjectChromium.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008 Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,13 +24,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-module core {
+#include "config.h"
+#include "AccessibilityObject.h"
- interface [
- GenerateConstructor
- ] PositionOptions {
- attribute boolean enableHighAccuracy;
- attribute unsigned long timeout;
- };
+namespace WebCore {
+bool AccessibilityObject::accessibilityIgnoreAttachment() const
+{
+ return false;
}
+
+} // namespace WebCore
diff --git a/WebCore/page/chromium/AccessibilityObjectWrapper.h b/WebCore/page/chromium/AccessibilityObjectWrapper.h
new file mode 100644
index 0000000..9920e4d
--- /dev/null
+++ b/WebCore/page/chromium/AccessibilityObjectWrapper.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008 Google Inc.
+ *
+ * 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. ``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
+ * 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.
+ */
+
+#ifndef AccessibilityObjectWrapper_h
+#define AccessibilityObjectWrapper_h
+
+namespace WebCore {
+
+ class AccessibilityObject;
+ class AccessibilityObjectWrapper : public RefCounted<AccessibilityObjectWrapper> {
+ public:
+ virtual ~AccessibilityObjectWrapper() {}
+ virtual void detach() = 0;
+ bool attached() const { return m_object; }
+ AccessibilityObject* accessibilityObject() const { return m_object; }
+
+ protected:
+ AccessibilityObjectWrapper(AccessibilityObject* obj)
+ : RefCounted<AccessibilityObjectWrapper>(0), m_object(obj) { }
+ AccessibilityObjectWrapper() : m_object(0) { }
+
+ AccessibilityObject* m_object;
+ };
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/page/chromium/ChromeClientChromium.h b/WebCore/page/chromium/ChromeClientChromium.h
new file mode 100644
index 0000000..5821dff
--- /dev/null
+++ b/WebCore/page/chromium/ChromeClientChromium.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2008, Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR 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.
+ */
+
+#ifndef ChromeClientChromium_h
+#define ChromeClientChromium_h
+
+#include "ChromeClient.h"
+#include <wtf/Forward.h>
+
+namespace WebCore {
+ class FramelessScrollView;
+ class IntRect;
+
+ // Contains Chromium-specific extensions to the ChromeClient. Only put
+ // things here that don't make sense for other ports.
+ class ChromeClientChromium : public ChromeClient {
+ public:
+ // Notifies the client of a new popup widget. The client should place
+ // and size the widget with the given bounds, relative to the screen.
+ virtual void popupOpened(FramelessScrollView* popupView, const IntRect& bounds, bool focusOnShow) = 0;
+ };
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/page/chromium/DragControllerChromium.cpp b/WebCore/page/chromium/DragControllerChromium.cpp
new file mode 100644
index 0000000..18688fd
--- /dev/null
+++ b/WebCore/page/chromium/DragControllerChromium.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Google Inc.
+ *
+ * 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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 "DragController.h"
+
+#include "DragData.h"
+#include "SelectionController.h"
+#include <wtf/RefPtr.h>
+
+#if PLATFORM(WIN_OS)
+#include <windows.h>
+#endif
+
+namespace WebCore {
+
+const int DragController::LinkDragBorderInset = 2;
+const int DragController::MaxOriginalImageArea = 1500 * 1500;
+const int DragController::DragIconRightInset = 7;
+const int DragController::DragIconBottomInset = 3;
+
+const float DragController::DragImageAlpha = 0.75f;
+
+DragOperation DragController::dragOperation(DragData* dragData)
+{
+ // FIXME: To match the MacOS behaviour we should return DragOperationNone
+ // if we are a modal window, we are the drag source, or the window is an
+ // attached sheet If this can be determined from within WebCore
+ // operationForDrag can be pulled into WebCore itself
+ ASSERT(dragData);
+ return dragData->containsURL() && !m_didInitiateDrag ? DragOperationCopy : DragOperationNone;
+}
+
+bool DragController::isCopyKeyDown()
+{
+ // FIXME: This should not be OS specific. Delegate to the embedder instead.
+#if PLATFORM(WIN_OS)
+ return ::GetAsyncKeyState(VK_CONTROL);
+#else
+ return false;
+#endif
+}
+
+const IntSize& DragController::maxDragImageSize()
+{
+ static const IntSize maxDragImageSize(200, 200);
+ return maxDragImageSize;
+}
+
+void DragController::cleanupAfterSystemDrag()
+{
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/chromium/EventHandlerChromium.cpp b/WebCore/page/chromium/EventHandlerChromium.cpp
new file mode 100644
index 0000000..883bece
--- /dev/null
+++ b/WebCore/page/chromium/EventHandlerChromium.cpp
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Google Inc.
+ *
+ * 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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 "EventHandler.h"
+
+#include "ChromiumDataObject.h"
+#include "ClipboardChromium.h"
+#include "Cursor.h"
+#include "FloatPoint.h"
+#include "FocusController.h"
+#include "FrameView.h"
+#include "Frame.h"
+#include "HitTestRequest.h"
+#include "HitTestResult.h"
+#include "MouseEventWithHitTestResults.h"
+#include "NotImplemented.h"
+#include "Page.h"
+#include "PlatformKeyboardEvent.h"
+#include "PlatformWheelEvent.h"
+#include "RenderWidget.h"
+#include "SelectionController.h"
+
+namespace WebCore {
+
+#if PLATFORM(DARWIN)
+const double EventHandler::TextDragDelay = 0.15;
+#else
+const double EventHandler::TextDragDelay = 0.0;
+#endif
+
+bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
+{
+ // If we're clicking into a frame that is selected, the frame will appear
+ // greyed out even though we're clicking on the selection. This looks
+ // really strange (having the whole frame be greyed out), so we deselect the
+ // selection.
+ IntPoint p = m_frame->view()->windowToContents(mev.event().pos());
+ if (m_frame->selection()->contains(p)) {
+ VisiblePosition visiblePos(
+ mev.targetNode()->renderer()->positionForPoint(mev.localPoint()));
+ Selection newSelection(visiblePos);
+ if (m_frame->shouldChangeSelection(newSelection))
+ m_frame->selection()->setSelection(newSelection);
+ }
+
+ subframe->eventHandler()->handleMousePressEvent(mev.event());
+ return true;
+}
+
+bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe, HitTestResult* hoveredNode)
+{
+ if (m_mouseDownMayStartDrag && !m_mouseDownWasInSubframe)
+ return false;
+ subframe->eventHandler()->handleMouseMoveEvent(mev.event(), hoveredNode);
+ return true;
+}
+
+bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
+{
+ subframe->eventHandler()->handleMouseReleaseEvent(mev.event());
+ return true;
+}
+
+bool EventHandler::passWheelEventToWidget(PlatformWheelEvent& wheelEvent, Widget* widget)
+{
+ // We can sometimes get a null widget! EventHandlerMac handles a null
+ // widget by returning false, so we do the same.
+ if (!widget)
+ return false;
+
+ // If not a FrameView, then probably a plugin widget. Those will receive
+ // the event via an EventTargetNode dispatch when this returns false.
+ if (!widget->isFrameView())
+ return false;
+
+ return static_cast<FrameView*>(widget)->frame()->eventHandler()->handleWheelEvent(wheelEvent);
+}
+
+bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event)
+{
+ // Figure out which view to send the event to.
+ if (!event.targetNode() || !event.targetNode()->renderer() || !event.targetNode()->renderer()->isWidget())
+ return false;
+
+ return passMouseDownEventToWidget(static_cast<RenderWidget*>(event.targetNode()->renderer())->widget());
+}
+
+bool EventHandler::passMouseDownEventToWidget(Widget* widget)
+{
+ notImplemented();
+ return false;
+}
+
+bool EventHandler::tabsToAllControls(KeyboardEvent*) const
+{
+ return true;
+}
+
+bool EventHandler::eventActivatedView(const PlatformMouseEvent& event) const
+{
+ // FIXME: EventHandlerWin.cpp does the following:
+ // return event.activatedWebView();
+ return false;
+}
+
+PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
+{
+ RefPtr<ChromiumDataObject> dataObject = ChromiumDataObject::create();
+ return ClipboardChromium::create(true, dataObject.get(), ClipboardWritable);
+}
+
+void EventHandler::focusDocumentView()
+{
+ Page* page = m_frame->page();
+ if (!page)
+ return;
+ page->focusController()->setFocusedFrame(m_frame);
+}
+
+bool EventHandler::passWidgetMouseDownEventToWidget(RenderWidget* renderWidget)
+{
+ return passMouseDownEventToWidget(renderWidget->widget());
+}
+
+unsigned EventHandler::accessKeyModifiers()
+{
+ return PlatformKeyboardEvent::AltKey;
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/chromium/FrameChromium.cpp b/WebCore/page/chromium/FrameChromium.cpp
new file mode 100644
index 0000000..1e4ed16
--- /dev/null
+++ b/WebCore/page/chromium/FrameChromium.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Google Inc.
+ *
+ * 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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 "FrameChromium.h"
+
+#include "Document.h"
+#include "FloatRect.h"
+#include "RenderView.h"
+#include "Settings.h"
+
+using std::min;
+
+namespace WebCore {
+
+void computePageRectsForFrame(Frame* frame, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, Vector<IntRect>& pages, int& outPageHeight)
+{
+ ASSERT(frame);
+
+ pages.clear();
+ outPageHeight = 0;
+
+ if (!frame->document() || !frame->view() || !frame->document()->renderer())
+ return;
+
+ RenderView* root = static_cast<RenderView*>(frame->document()->renderer());
+
+ if (!root) {
+ LOG_ERROR("document to be printed has no renderer");
+ return;
+ }
+
+ if (userScaleFactor <= 0) {
+ LOG_ERROR("userScaleFactor has bad value %.2f", userScaleFactor);
+ return;
+ }
+
+ float ratio = static_cast<float>(printRect.height()) / static_cast<float>(printRect.width());
+
+ float pageWidth = static_cast<float>(root->docWidth());
+ float pageHeight = pageWidth * ratio;
+ outPageHeight = static_cast<int>(pageHeight); // this is the height of the page adjusted by margins
+ pageHeight -= (headerHeight + footerHeight);
+
+ if (pageHeight <= 0) {
+ LOG_ERROR("pageHeight has bad value %.2f", pageHeight);
+ return;
+ }
+
+ float currPageHeight = pageHeight / userScaleFactor;
+ float docHeight = root->layer()->height();
+ float currPageWidth = pageWidth / userScaleFactor;
+
+
+ // always return at least one page, since empty files should print a blank page
+ float printedPagesHeight = 0.0f;
+ do {
+ float proposedBottom = min(docHeight, printedPagesHeight + pageHeight);
+ frame->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight);
+ currPageHeight = max(1.0f, proposedBottom - printedPagesHeight);
+
+ pages.append(IntRect(0, printedPagesHeight, currPageWidth, currPageHeight));
+ printedPagesHeight += currPageHeight;
+ } while (printedPagesHeight < docHeight);
+}
+
+DragImageRef Frame::dragImageForSelection()
+{
+ if (selection()->isRange())
+ return 0; // FIXME: implement me!
+
+ return 0;
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/chromium/FrameChromium.h b/WebCore/page/chromium/FrameChromium.h
new file mode 100644
index 0000000..faa78e7
--- /dev/null
+++ b/WebCore/page/chromium/FrameChromium.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Google Inc.
+ *
+ * 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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.
+ */
+
+#ifndef FrameChromium_h
+#define FrameChromium_h
+
+#include "Frame.h"
+
+namespace WebCore {
+
+ // printRect is only used for the width/height ratio. Their absolute values aren't used.
+ void computePageRectsForFrame(Frame*, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, Vector<IntRect>& pages, int& pageHeight);
+
+}
+
+#endif
diff --git a/WebCore/page/gtk/AccessibilityObjectAtk.cpp b/WebCore/page/gtk/AccessibilityObjectAtk.cpp
index b755645..1710027 100644
--- a/WebCore/page/gtk/AccessibilityObjectAtk.cpp
+++ b/WebCore/page/gtk/AccessibilityObjectAtk.cpp
@@ -20,6 +20,8 @@
#include "config.h"
#include "AccessibilityObject.h"
+#if HAVE(ACCESSIBILITY)
+
namespace WebCore {
bool AccessibilityObject::accessibilityIgnoreAttachment() const
@@ -28,3 +30,5 @@ bool AccessibilityObject::accessibilityIgnoreAttachment() const
}
} // namespace WebCore
+
+#endif // HAVE(ACCESSIBILITY)
diff --git a/WebCore/page/gtk/AccessibilityObjectWrapperAtk.cpp b/WebCore/page/gtk/AccessibilityObjectWrapperAtk.cpp
index b46fb60..c1a405e 100644
--- a/WebCore/page/gtk/AccessibilityObjectWrapperAtk.cpp
+++ b/WebCore/page/gtk/AccessibilityObjectWrapperAtk.cpp
@@ -20,6 +20,8 @@
#include "config.h"
#include "AccessibilityObjectWrapperAtk.h"
+#if HAVE(ACCESSIBILITY)
+
#include "AXObjectCache.h"
#include "AccessibilityListBox.h"
#include "AccessibilityRenderObject.h"
@@ -674,3 +676,5 @@ void AccessibilityObject::setWrapper(AccessibilityObjectWrapper* wrapper)
}
} // namespace WebCore
+
+#endif // HAVE(ACCESSIBILITY)
diff --git a/WebCore/page/gtk/DragControllerGtk.cpp b/WebCore/page/gtk/DragControllerGtk.cpp
index 62f4421..9e17255 100644
--- a/WebCore/page/gtk/DragControllerGtk.cpp
+++ b/WebCore/page/gtk/DragControllerGtk.cpp
@@ -63,4 +63,8 @@ const IntSize& DragController::maxDragImageSize()
return maxDragImageSize;
}
+void DragController::cleanupAfterSystemDrag()
+{
+}
+
}
diff --git a/WebCore/page/gtk/EventHandlerGtk.cpp b/WebCore/page/gtk/EventHandlerGtk.cpp
index bb650b4..7692dae 100644
--- a/WebCore/page/gtk/EventHandlerGtk.cpp
+++ b/WebCore/page/gtk/EventHandlerGtk.cpp
@@ -42,8 +42,6 @@
namespace WebCore {
-unsigned EventHandler::s_accessKeyModifiers = PlatformKeyboardEvent::AltKey;
-
const double EventHandler::TextDragDelay = 0.0;
bool EventHandler::tabsToAllControls(KeyboardEvent* event) const
@@ -120,4 +118,9 @@ bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&
return true;
}
+unsigned EventHandler::accessKeyModifiers()
+{
+ return PlatformKeyboardEvent::AltKey;
+}
+
}
diff --git a/WebCore/page/mac/AXObjectCacheMac.mm b/WebCore/page/mac/AXObjectCacheMac.mm
index 10ae1cc..d5ce8f3 100644
--- a/WebCore/page/mac/AXObjectCacheMac.mm
+++ b/WebCore/page/mac/AXObjectCacheMac.mm
@@ -26,6 +26,8 @@
#import "config.h"
#import "AXObjectCache.h"
+#if HAVE(ACCESSIBILITY)
+
#import "AccessibilityObject.h"
#import "AccessibilityObjectWrapper.h"
#import "RenderObject.h"
@@ -85,3 +87,5 @@ void AXObjectCache::handleFocusedUIElementChanged()
}
}
+
+#endif // HAVE(ACCESSIBILITY)
diff --git a/WebCore/page/mac/AccessibilityObjectMac.mm b/WebCore/page/mac/AccessibilityObjectMac.mm
index 872e108..8f47af0 100644
--- a/WebCore/page/mac/AccessibilityObjectMac.mm
+++ b/WebCore/page/mac/AccessibilityObjectMac.mm
@@ -26,6 +26,8 @@
#import "config.h"
#import "AccessibilityObject.h"
+#if HAVE(ACCESSIBILITY)
+
#import "AccessibilityObjectWrapper.h"
namespace WebCore {
@@ -36,3 +38,5 @@ bool AccessibilityObject::accessibilityIgnoreAttachment() const
}
} // WebCore
+
+#endif // HAVE(ACCESSIBILITY)
diff --git a/WebCore/page/mac/AccessibilityObjectWrapper.mm b/WebCore/page/mac/AccessibilityObjectWrapper.mm
index 2104ca9..1e28f00 100644
--- a/WebCore/page/mac/AccessibilityObjectWrapper.mm
+++ b/WebCore/page/mac/AccessibilityObjectWrapper.mm
@@ -29,6 +29,8 @@
#import "config.h"
#import "AccessibilityObjectWrapper.h"
+#if HAVE(ACCESSIBILITY)
+
#import "AXObjectCache.h"
#import "AccessibilityListBox.h"
#import "AccessibilityList.h"
@@ -56,6 +58,7 @@
#import "WebCoreViewFactory.h"
#import "htmlediting.h"
#import "visible_units.h"
+#import <runtime/InitializeThreading.h>
using namespace WebCore;
using namespace HTMLNames;
@@ -99,6 +102,15 @@ using namespace std;
#define NSAccessibilityDefinitionListSubrole @"AXDefinitionList"
#endif
+// Miscellaneous
+#ifndef NSAccessibilityBlockQuoteLevelAttribute
+#define NSAccessibilityBlockQuoteLevelAttribute @"AXBlockQuoteLevel"
+#endif
+
+#ifndef NSAccessibilityAccessKeyAttribute
+#define NSAccessibilityAccessKeyAttribute @"AXAccessKey"
+#endif
+
#ifdef BUILDING_ON_TIGER
typedef unsigned NSUInteger;
#endif
@@ -113,12 +125,13 @@ typedef unsigned NSUInteger;
@implementation AccessibilityObjectWrapper
-#ifndef BUILDING_ON_TIGER
+ (void)initialize
{
+ JSC::initializeThreading();
+#ifndef BUILDING_ON_TIGER
WebCoreObjCFinalizeOnMainThread(self);
-}
#endif
+}
- (id)initWithAccessibilityObject:(AccessibilityObject*)axObject
{
@@ -265,15 +278,16 @@ static CGColorRef CreateCGColorIfDifferent(NSColor* nsColor, CGColorRef existing
[rgbColor getRed:&components[0] green:&components[1] blue:&components[2] alpha:&components[3]];
// create a new CGColorRef to return
- CGColorSpaceRef cgColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+ CGColorSpaceRef cgColorSpace = CGColorSpaceCreateDeviceRGB();
CGColorRef cgColor = CGColorCreate(cgColorSpace, components);
CGColorSpaceRelease(cgColorSpace);
- CFMakeCollectable(cgColor);
// check for match with existing color
- if (existingColor && CGColorEqualToColor(cgColor, existingColor))
- cgColor = nil;
-
+ if (existingColor && CGColorEqualToColor(cgColor, existingColor)) {
+ CGColorRelease(cgColor);
+ cgColor = 0;
+ }
+
return cgColor;
}
@@ -356,6 +370,9 @@ static void AXAttributeStringSetStyle(NSMutableAttributedString* attrString, Ren
static int blockquoteLevel(RenderObject* renderer)
{
+ if (!renderer)
+ return 0;
+
int result = 0;
for (Node* node = renderer->element(); node; node = node->parent()) {
if (node->hasTagName(blockquoteTag))
@@ -370,9 +387,9 @@ static void AXAttributeStringSetBlockquoteLevel(NSMutableAttributedString* attrS
int quoteLevel = blockquoteLevel(renderer);
if (quoteLevel)
- [attrString addAttribute:@"AXBlockQuoteLevel" value:[NSNumber numberWithInt:quoteLevel] range:range];
+ [attrString addAttribute:NSAccessibilityBlockQuoteLevelAttribute value:[NSNumber numberWithInt:quoteLevel] range:range];
else
- [attrString removeAttribute:@"AXBlockQuoteLevel" range:range];
+ [attrString removeAttribute:NSAccessibilityBlockQuoteLevelAttribute range:range];
}
static void AXAttributeStringSetSpelling(NSMutableAttributedString* attrString, Node* node, int offset, NSRange range)
@@ -404,7 +421,7 @@ static void AXAttributeStringSetSpelling(NSMutableAttributedString* attrString,
}
}
-static void AXAttributeStringSetHeadingLevel(AccessibilityObject* object, NSMutableAttributedString* attrString, RenderObject* renderer, NSRange range)
+static void AXAttributeStringSetHeadingLevel(NSMutableAttributedString* attrString, RenderObject* renderer, NSRange range)
{
int parentHeadingLevel = AccessibilityRenderObject::headingLevel(renderer->parent()->element());
@@ -458,7 +475,7 @@ static void AXAttributeStringSetElement(NSMutableAttributedString* attrString, N
[attrString removeAttribute:attribute range:range];
}
-static void AXAttributedStringAppendText(AccessibilityObject* object, NSMutableAttributedString* attrString, Node* node, int offset, const UChar* chars, int length)
+static void AXAttributedStringAppendText(NSMutableAttributedString* attrString, Node* node, int offset, const UChar* chars, int length)
{
// skip invisible text
if (!node->renderer())
@@ -480,7 +497,7 @@ static void AXAttributedStringAppendText(AccessibilityObject* object, NSMutableA
// set new attributes
AXAttributeStringSetStyle(attrString, node->renderer(), attrStringRange);
- AXAttributeStringSetHeadingLevel(object, attrString, node->renderer(), attrStringRange);
+ AXAttributeStringSetHeadingLevel(attrString, node->renderer(), attrStringRange);
AXAttributeStringSetBlockquoteLevel(attrString, node->renderer(), attrStringRange);
AXAttributeStringSetElement(attrString, NSAccessibilityLinkTextAttribute, AXLinkElementForNode(node), attrStringRange);
@@ -530,7 +547,7 @@ static NSString* nsStringForReplacedNode(Node* replacedNode)
// non-zero length means textual node, zero length means replaced node (AKA "attachments" in AX)
if (it.length() != 0) {
- AXAttributedStringAppendText(m_object, attrString, node, offset, it.characters(), it.length());
+ AXAttributedStringAppendText(attrString, node, offset, it.characters(), it.length());
} else {
Node* replacedNode = node->childNode(offset);
NSString *attachmentString = nsStringForReplacedNode(replacedNode);
@@ -563,6 +580,8 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
- (NSArray*)accessibilityActionNames
{
+ m_object->updateBackingStore();
+
static NSArray* actionElementActions = [[NSArray alloc] initWithObjects: NSAccessibilityPressAction, NSAccessibilityShowMenuAction, nil];
static NSArray* defaultElementActions = [[NSArray alloc] initWithObjects: NSAccessibilityShowMenuAction, nil];
static NSArray* menuElementActions = [[NSArray alloc] initWithObjects: NSAccessibilityCancelAction, NSAccessibilityPressAction, nil];
@@ -582,6 +601,8 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
- (NSArray*)accessibilityAttributeNames
{
+ m_object->updateBackingStore();
+
if (m_object->isAttachment())
return [[self attachmentView] accessibilityAttributeNames];
@@ -601,6 +622,8 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
static NSArray* tableRowAttrs = nil;
static NSArray* tableColAttrs = nil;
static NSArray* tableCellAttrs = nil;
+ static NSArray* groupAttrs = nil;
+ static NSArray* inputImageAttrs = nil;
NSMutableArray* tempArray;
if (attributes == nil) {
attributes = [[NSArray alloc] initWithObjects: NSAccessibilityRoleAttribute,
@@ -623,7 +646,7 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
@"AXVisited",
NSAccessibilityLinkedUIElementsAttribute,
NSAccessibilitySelectedAttribute,
- @"AXBlockQuoteLevel",
+ NSAccessibilityBlockQuoteLevelAttribute,
NSAccessibilityTopLevelUIElementAttribute,
nil];
}
@@ -640,6 +663,7 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
if (anchorAttrs == nil) {
tempArray = [[NSMutableArray alloc] initWithArray:attributes];
[tempArray addObject:NSAccessibilityURLAttribute];
+ [tempArray addObject:NSAccessibilityAccessKeyAttribute];
anchorAttrs = [[NSArray alloc] initWithArray:tempArray];
[tempArray release];
}
@@ -660,6 +684,7 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
[tempArray addObject:NSAccessibilityVisibleCharacterRangeAttribute];
[tempArray addObject:NSAccessibilityInsertionPointLineNumberAttribute];
[tempArray addObject:NSAccessibilityTitleUIElementAttribute];
+ [tempArray addObject:NSAccessibilityAccessKeyAttribute];
textAttrs = [[NSArray alloc] initWithArray:tempArray];
[tempArray release];
}
@@ -669,6 +694,7 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
[tempArray addObject:NSAccessibilityVisibleChildrenAttribute];
[tempArray addObject:NSAccessibilityOrientationAttribute];
[tempArray addObject:NSAccessibilityTitleUIElementAttribute];
+ [tempArray addObject:NSAccessibilityAccessKeyAttribute];
listBoxAttrs = [[NSArray alloc] initWithArray:tempArray];
[tempArray release];
}
@@ -728,6 +754,7 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
if (controlAttrs == nil) {
tempArray = [[NSMutableArray alloc] initWithArray:attributes];
[tempArray addObject:NSAccessibilityTitleUIElementAttribute];
+ [tempArray addObject:NSAccessibilityAccessKeyAttribute];
controlAttrs = [[NSArray alloc] initWithArray:tempArray];
[tempArray release];
}
@@ -766,6 +793,19 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
tableCellAttrs = [[NSArray alloc] initWithArray:tempArray];
[tempArray release];
}
+ if (groupAttrs == nil) {
+ tempArray = [[NSMutableArray alloc] initWithArray:attributes];
+ [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
+ groupAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+ if (inputImageAttrs == nil) {
+ tempArray = [[NSMutableArray alloc] initWithArray:controlAttrs];
+ [tempArray addObject:NSAccessibilityURLAttribute];
+ [tempArray addObject:NSAccessibilityAccessKeyAttribute];
+ inputImageAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
if (m_object->isPasswordField())
return attributes;
@@ -794,9 +834,15 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
if (m_object->isProgressIndicator() || m_object->isSlider())
return rangeAttrs;
+ if (m_object->isInputImage())
+ return inputImageAttrs;
+
if (m_object->isControl())
return controlAttrs;
+ if (m_object->isGroup())
+ return groupAttrs;
+
if (m_object->isMenu())
return menuAttrs;
if (m_object->isMenuBar())
@@ -819,7 +865,7 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
Widget* widget = m_object->widget();
if (!widget)
return nil;
- return [(widget->getOuterView()) accessibilityAttributeValue: NSAccessibilityChildrenAttribute];
+ return [(widget->platformWidget()) accessibilityAttributeValue: NSAccessibilityChildrenAttribute];
}
static void convertToVector(NSArray* array, AccessibilityObject::AccessibilityChildrenVector& vector)
@@ -1082,6 +1128,8 @@ static NSString* roleValueToNSString(AccessibilityRole value)
if (!m_object)
return nil;
+ m_object->updateBackingStore();
+
if ([attributeName isEqualToString: NSAccessibilityRoleAttribute])
return [self role];
@@ -1246,6 +1294,13 @@ static NSString* roleValueToNSString(AccessibilityRole value)
return nil;
}
+ if ([attributeName isEqualToString:NSAccessibilityAccessKeyAttribute]) {
+ AtomicString accessKey = m_object->accessKey();
+ if (accessKey.isNull())
+ return nil;
+ return accessKey;
+ }
+
if (m_object->isDataTable()) {
// TODO: distinguish between visible and non-visible rows
if ([attributeName isEqualToString:NSAccessibilityRowsAttribute] ||
@@ -1341,8 +1396,15 @@ static NSString* roleValueToNSString(AccessibilityRole value)
if ([attributeName isEqualToString: @"AXEndTextMarker"])
return textMarkerForVisiblePosition(endOfDocument(renderer->document()));
- if ([attributeName isEqualToString: @"AXBlockQuoteLevel"])
+ if ([attributeName isEqualToString:NSAccessibilityBlockQuoteLevelAttribute])
return [NSNumber numberWithInt:blockquoteLevel(renderer)];
+ } else {
+ if ([attributeName isEqualToString:NSAccessibilityBlockQuoteLevelAttribute]) {
+ AccessibilityObject* parent = m_object->parentObjectUnignored();
+ if (!parent)
+ return [NSNumber numberWithInt:0];
+ return [parent->wrapper() accessibilityAttributeValue:NSAccessibilityBlockQuoteLevelAttribute];
+ }
}
if ([attributeName isEqualToString: NSAccessibilityLinkedUIElementsAttribute]) {
@@ -1374,6 +1436,8 @@ static NSString* roleValueToNSString(AccessibilityRole value)
- (id)accessibilityFocusedUIElement
{
+ m_object->updateBackingStore();
+
RefPtr<AccessibilityObject> focusedObj = m_object->focusedUIElement();
if (!focusedObj)
@@ -1384,6 +1448,8 @@ static NSString* roleValueToNSString(AccessibilityRole value)
- (id)accessibilityHitTest:(NSPoint)point
{
+ m_object->updateBackingStore();
+
RefPtr<AccessibilityObject> axObject = m_object->doAccessibilityHitTest(IntPoint(point));
if (axObject)
return NSAccessibilityUnignoredAncestor(axObject->wrapper());
@@ -1392,6 +1458,8 @@ static NSString* roleValueToNSString(AccessibilityRole value)
- (BOOL)accessibilityIsAttributeSettable:(NSString*)attributeName
{
+ m_object->updateBackingStore();
+
if ([attributeName isEqualToString: @"AXSelectedTextMarkerRange"])
return YES;
@@ -1426,6 +1494,8 @@ static NSString* roleValueToNSString(AccessibilityRole value)
// Registering an object is also required for observing notifications. Only registered objects can be observed.
- (BOOL)accessibilityIsIgnored
{
+ m_object->updateBackingStore();
+
if (m_object->isAttachment())
return [[self attachmentView] accessibilityIsIgnored];
return m_object->accessibilityIsIgnored();
@@ -1433,6 +1503,8 @@ static NSString* roleValueToNSString(AccessibilityRole value)
- (NSArray* )accessibilityParameterizedAttributeNames
{
+ m_object->updateBackingStore();
+
if (m_object->isAttachment())
return nil;
@@ -1513,6 +1585,8 @@ static NSString* roleValueToNSString(AccessibilityRole value)
- (void)accessibilityPerformPressAction
{
+ m_object->updateBackingStore();
+
if (m_object->isAttachment())
[[self attachmentView] accessibilityPerformAction:NSAccessibilityPressAction];
@@ -1557,6 +1631,8 @@ static NSString* roleValueToNSString(AccessibilityRole value)
- (void)accessibilityPerformAction:(NSString*)action
{
+ m_object->updateBackingStore();
+
if ([action isEqualToString:NSAccessibilityPressAction])
[self accessibilityPerformPressAction];
@@ -1566,6 +1642,8 @@ static NSString* roleValueToNSString(AccessibilityRole value)
- (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attributeName
{
+ m_object->updateBackingStore();
+
WebCoreTextMarkerRange* textMarkerRange = nil;
NSNumber* number = nil;
NSString* string = nil;
@@ -1688,6 +1766,8 @@ static RenderObject* rendererForView(NSView* view)
if (!m_object || !attribute || !parameter)
return nil;
+ m_object->updateBackingStore();
+
// common parameter type check/casting. Nil checks in handlers catch wrong type case.
// NOTE: This assumes nil is not a valid parameter, because it is indistinguishable from
// a parameter of the wrong type.
@@ -1933,6 +2013,8 @@ static RenderObject* rendererForView(NSView* view)
// API that AppKit uses for faster access
- (NSUInteger)accessibilityIndexOfChild:(id)child
{
+ m_object->updateBackingStore();
+
const AccessibilityObject::AccessibilityChildrenVector& children = m_object->children();
if (children.isEmpty())
@@ -1949,6 +2031,8 @@ static RenderObject* rendererForView(NSView* view)
- (NSUInteger)accessibilityArrayAttributeCount:(NSString *)attribute
{
+ m_object->updateBackingStore();
+
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
const AccessibilityObject::AccessibilityChildrenVector& children = m_object->children();
if (children.isEmpty())
@@ -1962,6 +2046,8 @@ static RenderObject* rendererForView(NSView* view)
- (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount
{
+ m_object->updateBackingStore();
+
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
if (m_object->children().isEmpty()) {
NSArray *children = [self renderWidgetChildren];
@@ -1994,3 +2080,5 @@ static RenderObject* rendererForView(NSView* view)
}
@end
+
+#endif // HAVE(ACCESSIBILITY)
diff --git a/WebCore/page/mac/DragControllerMac.mm b/WebCore/page/mac/DragControllerMac.mm
index 2ab9d41..86d8f66 100644
--- a/WebCore/page/mac/DragControllerMac.mm
+++ b/WebCore/page/mac/DragControllerMac.mm
@@ -66,4 +66,13 @@ const IntSize& DragController::maxDragImageSize()
return maxDragImageSize;
}
+void DragController::cleanupAfterSystemDrag()
+{
+ // Drag has ended, dragEnded *should* have been called, however it is possible
+ // for the UIDelegate to take over the drag, and fail to send the appropriate
+ // drag termination event. As dragEnded just resets drag variables, we just
+ // call it anyway to be on the safe side
+ dragEnded();
+}
+
}
diff --git a/WebCore/page/mac/EventHandlerMac.mm b/WebCore/page/mac/EventHandlerMac.mm
index 562c1dd..5d09843 100644
--- a/WebCore/page/mac/EventHandlerMac.mm
+++ b/WebCore/page/mac/EventHandlerMac.mm
@@ -26,6 +26,7 @@
#include "config.h"
#include "EventHandler.h"
+#include "AXObjectCache.h"
#include "BlockExceptions.h"
#include "ChromeClient.h"
#include "ClipboardMac.h"
@@ -42,16 +43,15 @@
#include "RenderWidget.h"
#include "Scrollbar.h"
#include "Settings.h"
+#include <wtf/StdLibExtras.h>
namespace WebCore {
-unsigned EventHandler::s_accessKeyModifiers = PlatformKeyboardEvent::CtrlKey | PlatformKeyboardEvent::AltKey;
-
const double EventHandler::TextDragDelay = 0.15;
static RetainPtr<NSEvent>& currentEvent()
{
- static RetainPtr<NSEvent> event;
+ DEFINE_STATIC_LOCAL(RetainPtr<NSEvent>, event, ());
return event;
}
@@ -643,4 +643,15 @@ bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&
return passSubframeEventToSubframe(mev, subframe);
}
+unsigned EventHandler::accessKeyModifiers()
+{
+ // Control+Option key combinations are usually unused on Mac OS X, but not when VoiceOver is enabled.
+ // So, we use Control in this case, even though it conflicts with Emacs-style key bindings.
+ // See <https://bugs.webkit.org/show_bug.cgi?id=21107> for more detail.
+ if (AXObjectCache::accessibilityEnhancedUserInterfaceEnabled())
+ return PlatformKeyboardEvent::CtrlKey;
+
+ return PlatformKeyboardEvent::CtrlKey | PlatformKeyboardEvent::AltKey;
+}
+
}
diff --git a/WebCore/page/mac/FrameMac.mm b/WebCore/page/mac/FrameMac.mm
index 66e2d04..84d7549 100644
--- a/WebCore/page/mac/FrameMac.mm
+++ b/WebCore/page/mac/FrameMac.mm
@@ -36,7 +36,6 @@
#import "EditorClient.h"
#import "Event.h"
#import "FrameLoaderClient.h"
-#import "FramePrivate.h"
#import "FrameView.h"
#import "GraphicsContext.h"
#import "HTMLNames.h"
@@ -59,6 +58,7 @@
#import <Carbon/Carbon.h>
#import <runtime/JSLock.h>
+#import <wtf/StdLibExtras.h>
#if ENABLE(DASHBOARD_SUPPORT)
#import "WebDashboardRegion.h"
@@ -78,7 +78,7 @@ using namespace HTMLNames;
// Either get cached regexp or build one that matches any of the labels.
// The regexp we build is of the form: (STR1|STR2|STRN)
-RegularExpression* regExpForLabels(NSArray* labels)
+static RegularExpression* regExpForLabels(NSArray* labels)
{
// All the ObjC calls in this method are simple array and string
// calls which we can assume do not raise exceptions
@@ -88,8 +88,8 @@ RegularExpression* regExpForLabels(NSArray* labels)
// that the app will use is equal to the number of locales is used in searching.
static const unsigned int regExpCacheSize = 4;
static NSMutableArray* regExpLabels = nil;
- static Vector<RegularExpression*> regExps;
- static RegularExpression wordRegExp = RegularExpression("\\w");
+ DEFINE_STATIC_LOCAL(Vector<RegularExpression*>, regExps, ());
+ DEFINE_STATIC_LOCAL(RegularExpression, wordRegExp, ("\\w", TextCaseSensitive));
RegularExpression* result;
if (!regExpLabels)
@@ -107,8 +107,8 @@ RegularExpression* regExpForLabels(NSArray* labels)
bool startsWithWordChar = false;
bool endsWithWordChar = false;
if (label.length() != 0) {
- startsWithWordChar = wordRegExp.search(label.substring(0, 1)) >= 0;
- endsWithWordChar = wordRegExp.search(label.substring(label.length() - 1, 1)) >= 0;
+ startsWithWordChar = wordRegExp.match(label.substring(0, 1)) >= 0;
+ endsWithWordChar = wordRegExp.match(label.substring(label.length() - 1, 1)) >= 0;
}
if (i != 0)
@@ -123,7 +123,7 @@ RegularExpression* regExpForLabels(NSArray* labels)
pattern.append("\\b");
}
pattern.append(")");
- result = new RegularExpression(pattern, false);
+ result = new RegularExpression(pattern, TextCaseInsensitive);
}
// add regexp to the cache, making sure it is at the front for LRU ordering
@@ -196,8 +196,7 @@ NSString* Frame::searchForLabelsBeforeElement(NSArray* labels, Element* element)
n = n->traversePreviousNode())
{
if (n->hasTagName(formTag)
- || (n->isHTMLElement()
- && static_cast<HTMLElement*>(n)->isGenericFormElement()))
+ || (n->isHTMLElement() && static_cast<Element*>(n)->isFormControlElement()))
{
// We hit another form element or the start of the form - bail out
break;
@@ -240,7 +239,7 @@ NSString* Frame::matchLabelsAgainstElement(NSArray* labels, Element* element)
return nil;
// Make numbers and _'s in field names behave like word boundaries, e.g., "address2"
- replace(name, RegularExpression("\\d"), " ");
+ replace(name, RegularExpression("\\d", TextCaseSensitive), " ");
name.replace('_', ' ');
RegularExpression* regExp = regExpForLabels(labels);
@@ -251,7 +250,7 @@ NSString* Frame::matchLabelsAgainstElement(NSArray* labels, Element* element)
int bestLength = -1;
int start = 0;
do {
- pos = regExp->search(name, start);
+ pos = regExp->match(name, start);
if (pos != -1) {
length = regExp->matchedLength();
if (length >= bestLength) {
@@ -269,7 +268,7 @@ NSString* Frame::matchLabelsAgainstElement(NSArray* labels, Element* element)
NSImage* Frame::imageFromRect(NSRect rect) const
{
- NSView* view = d->m_view->documentView();
+ NSView* view = m_view->documentView();
if (!view)
return nil;
if (![view respondsToSelector:@selector(drawSingleRect:)])
@@ -314,10 +313,10 @@ NSImage* Frame::imageFromRect(NSRect rect) const
NSImage* Frame::selectionImage(bool forceBlackText) const
{
- d->m_view->setPaintRestriction(forceBlackText ? PaintRestrictionSelectionOnlyBlackText : PaintRestrictionSelectionOnly);
- d->m_doc->updateLayout();
- NSImage* result = imageFromRect(selectionRect());
- d->m_view->setPaintRestriction(PaintRestrictionNone);
+ m_view->setPaintRestriction(forceBlackText ? PaintRestrictionSelectionOnlyBlackText : PaintRestrictionSelectionOnly);
+ m_doc->updateLayout();
+ NSImage* result = imageFromRect(selectionBounds());
+ m_view->setPaintRestriction(PaintRestrictionNone);
return result;
}
@@ -328,16 +327,16 @@ NSImage* Frame::snapshotDragImage(Node* node, NSRect* imageRect, NSRect* element
return nil;
renderer->updateDragState(true); // mark dragged nodes (so they pick up the right CSS)
- d->m_doc->updateLayout(); // forces style recalc - needed since changing the drag state might
+ m_doc->updateLayout(); // forces style recalc - needed since changing the drag state might
// imply new styles, plus JS could have changed other things
IntRect topLevelRect;
NSRect paintingRect = renderer->paintingRootRect(topLevelRect);
- d->m_view->setNodeToDraw(node); // invoke special sub-tree drawing mode
+ m_view->setNodeToDraw(node); // invoke special sub-tree drawing mode
NSImage* result = imageFromRect(paintingRect);
renderer->updateDragState(false);
- d->m_doc->updateLayout();
- d->m_view->setNodeToDraw(0);
+ m_doc->updateLayout();
+ m_view->setNodeToDraw(0);
if (elementRect)
*elementRect = topLevelRect;
@@ -352,14 +351,14 @@ NSImage* Frame::nodeImage(Node* node) const
if (!renderer)
return nil;
- d->m_doc->updateLayout(); // forces style recalc
+ m_doc->updateLayout(); // forces style recalc
IntRect topLevelRect;
NSRect paintingRect = renderer->paintingRootRect(topLevelRect);
- d->m_view->setNodeToDraw(node); // invoke special sub-tree drawing mode
+ m_view->setNodeToDraw(node); // invoke special sub-tree drawing mode
NSImage* result = imageFromRect(paintingRect);
- d->m_view->setNodeToDraw(0);
+ m_view->setNodeToDraw(0);
return result;
}
@@ -536,18 +535,18 @@ DragImageRef Frame::dragImageForSelection()
void Frame::setUserStyleSheetLocation(const KURL& url)
{
- delete d->m_userStyleSheetLoader;
- d->m_userStyleSheetLoader = 0;
- if (d->m_doc && d->m_doc->docLoader())
- d->m_userStyleSheetLoader = new UserStyleSheetLoader(d->m_doc, url.string());
+ delete m_userStyleSheetLoader;
+ m_userStyleSheetLoader = 0;
+ if (m_doc && m_doc->docLoader())
+ m_userStyleSheetLoader = new UserStyleSheetLoader(m_doc, url.string());
}
void Frame::setUserStyleSheet(const String& styleSheet)
{
- delete d->m_userStyleSheetLoader;
- d->m_userStyleSheetLoader = 0;
- if (d->m_doc)
- d->m_doc->setUserStyleSheet(styleSheet);
+ delete m_userStyleSheetLoader;
+ m_userStyleSheetLoader = 0;
+ if (m_doc)
+ m_doc->setUserStyleSheet(styleSheet);
}
} // namespace WebCore
diff --git a/WebCore/page/mac/WebCoreViewFactory.h b/WebCore/page/mac/WebCoreViewFactory.h
index 4caef54..883d586 100644
--- a/WebCore/page/mac/WebCoreViewFactory.h
+++ b/WebCore/page/mac/WebCoreViewFactory.h
@@ -79,6 +79,7 @@
- (NSString *)contextMenuItemTagStartSpeaking;
- (NSString *)contextMenuItemTagStopSpeaking;
- (NSString *)contextMenuItemTagWritingDirectionMenu;
+- (NSString *)contextMenuItemTagTextDirectionMenu;
- (NSString *)contextMenuItemTagDefaultDirection;
- (NSString *)contextMenuItemTagLeftToRight;
- (NSString *)contextMenuItemTagRightToLeft;
@@ -103,6 +104,7 @@
- (WebCoreTextMarker *)endOfTextMarkerRange:(WebCoreTextMarkerRange *)range;
- (void)accessibilityHandleFocusChanged;
+- (CGRect)accessibilityConvertScreenRect:(CGRect)bounds;
- (AXUIElementRef)AXUIElementForElement:(id)element;
- (void)unregisterUniqueIdForUIElement:(id)element;
diff --git a/WebCore/page/mac/WebDashboardRegion.m b/WebCore/page/mac/WebDashboardRegion.m
index d2eb07f..a6b9872 100644
--- a/WebCore/page/mac/WebDashboardRegion.m
+++ b/WebCore/page/mac/WebDashboardRegion.m
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -22,11 +22,16 @@
* (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"
+
+#import "config.h"
#import "WebDashboardRegion.h"
+#import <wtf/UnusedParam.h>
+
#if ENABLE(DASHBOARD_SUPPORT)
+
@implementation WebDashboardRegion
+
- initWithRect:(NSRect)r clip:(NSRect)c type:(WebDashboardRegionType)t
{
self = [super init];
@@ -36,8 +41,10 @@
return self;
}
-- (id)copyWithZone:(NSZone *)zone
+- (id)copyWithZone:(NSZone *)unusedZone
{
+ UNUSED_PARAM(unusedZone);
+
return [self retain];
}
@@ -56,22 +63,32 @@
return type;
}
+static const char* typeName(WebDashboardRegionType type)
+{
+ switch (type) {
+ case WebDashboardRegionTypeNone:
+ return "None";
+ case WebDashboardRegionTypeCircle:
+ return "Circle";
+ case WebDashboardRegionTypeRectangle:
+ return "Rectangle";
+ case WebDashboardRegionTypeScrollerRectangle:
+ return "ScrollerRectangle";
+ }
+ return "Unknown";
+}
+
- (NSString *)description
{
- return [NSString stringWithFormat:@"rect:%@ clip:%@ type:%s",
- NSStringFromRect(rect),
- NSStringFromRect(clip),
- type == WebDashboardRegionTypeNone ? "None" :
- (type == WebDashboardRegionTypeCircle ? "Circle" :
- (type == WebDashboardRegionTypeRectangle ? "Rectangle" :
- (type == WebDashboardRegionTypeScrollerRectangle ? "ScrollerRectangle" :
- "Unknown")))];
+ return [NSString stringWithFormat:@"rect:%@ clip:%@ type:%s", NSStringFromRect(rect), NSStringFromRect(clip), typeName(type)];
}
+// FIXME: Overriding isEqual: without overriding hash will cause trouble if this ever goes into a NSSet or is the key in an NSDictionary.
- (BOOL)isEqual:(id)other
{
- return NSEqualRects (rect, [other dashboardRegionRect]) && NSEqualRects (clip, [other dashboardRegionClip]) && type == [other dashboardRegionType];
+ return NSEqualRects(rect, [other dashboardRegionRect]) && NSEqualRects(clip, [other dashboardRegionClip]) && type == [other dashboardRegionType];
}
@end
+
#endif
diff --git a/WebCore/page/qt/AccessibilityObjectQt.cpp b/WebCore/page/qt/AccessibilityObjectQt.cpp
index b755645..1710027 100644
--- a/WebCore/page/qt/AccessibilityObjectQt.cpp
+++ b/WebCore/page/qt/AccessibilityObjectQt.cpp
@@ -20,6 +20,8 @@
#include "config.h"
#include "AccessibilityObject.h"
+#if HAVE(ACCESSIBILITY)
+
namespace WebCore {
bool AccessibilityObject::accessibilityIgnoreAttachment() const
@@ -28,3 +30,5 @@ bool AccessibilityObject::accessibilityIgnoreAttachment() const
}
} // namespace WebCore
+
+#endif // HAVE(ACCESSIBILITY)
diff --git a/WebCore/page/qt/DragControllerQt.cpp b/WebCore/page/qt/DragControllerQt.cpp
index 62372d0..1fe56b4 100644
--- a/WebCore/page/qt/DragControllerQt.cpp
+++ b/WebCore/page/qt/DragControllerQt.cpp
@@ -65,4 +65,8 @@ const IntSize& DragController::maxDragImageSize()
return maxDragImageSize;
}
+void DragController::cleanupAfterSystemDrag()
+{
+}
+
}
diff --git a/WebCore/page/qt/EventHandlerQt.cpp b/WebCore/page/qt/EventHandlerQt.cpp
index 421caaf..3425289 100644
--- a/WebCore/page/qt/EventHandlerQt.cpp
+++ b/WebCore/page/qt/EventHandlerQt.cpp
@@ -56,8 +56,6 @@ QT_END_NAMESPACE
namespace WebCore {
-unsigned EventHandler::s_accessKeyModifiers = PlatformKeyboardEvent::CtrlKey;
-
const double EventHandler::TextDragDelay = 0.0;
static bool isKeyboardOptionTab(KeyboardEvent* event)
@@ -132,4 +130,9 @@ bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&
return true;
}
+unsigned EventHandler::accessKeyModifiers()
+{
+ return PlatformKeyboardEvent::CtrlKey;
+}
+
}
diff --git a/WebCore/page/qt/FrameQt.cpp b/WebCore/page/qt/FrameQt.cpp
index 1bbbff5..388bf66 100644
--- a/WebCore/page/qt/FrameQt.cpp
+++ b/WebCore/page/qt/FrameQt.cpp
@@ -23,7 +23,7 @@
#include "config.h"
#include "Frame.h"
-#include "FramePrivate.h"
+
#include "UserStyleSheetLoader.h"
namespace WebCore {
@@ -35,18 +35,18 @@ DragImageRef Frame::dragImageForSelection()
void Frame::setUserStyleSheetLocation(const KURL& url)
{
- delete d->m_userStyleSheetLoader;
- d->m_userStyleSheetLoader = 0;
- if (d->m_doc && d->m_doc->docLoader())
- d->m_userStyleSheetLoader = new UserStyleSheetLoader(d->m_doc, url.string());
+ delete m_userStyleSheetLoader;
+ m_userStyleSheetLoader = 0;
+ if (m_doc && m_doc->docLoader())
+ m_userStyleSheetLoader = new UserStyleSheetLoader(m_doc, url.string());
}
void Frame::setUserStyleSheet(const String& styleSheet)
{
- delete d->m_userStyleSheetLoader;
- d->m_userStyleSheetLoader = 0;
- if (d->m_doc)
- d->m_doc->setUserStyleSheet(styleSheet);
+ delete m_userStyleSheetLoader;
+ m_userStyleSheetLoader = 0;
+ if (m_doc)
+ m_doc->setUserStyleSheet(styleSheet);
}
}
diff --git a/WebCore/page/win/AccessibilityObjectWin.cpp b/WebCore/page/win/AccessibilityObjectWin.cpp
index e309ac8..0a386c7 100644
--- a/WebCore/page/win/AccessibilityObjectWin.cpp
+++ b/WebCore/page/win/AccessibilityObjectWin.cpp
@@ -23,10 +23,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
#include "config.h"
#include "AccessibilityObject.h"
+#if HAVE(ACCESSIBILITY)
+
namespace WebCore {
bool AccessibilityObject::accessibilityIgnoreAttachment() const
@@ -35,3 +36,5 @@ bool AccessibilityObject::accessibilityIgnoreAttachment() const
}
} // namespace WebCore
+
+#endif // HAVE(ACCESSIBILITY)
diff --git a/WebCore/page/win/DragControllerWin.cpp b/WebCore/page/win/DragControllerWin.cpp
index 41f3008..dca8ea2 100644
--- a/WebCore/page/win/DragControllerWin.cpp
+++ b/WebCore/page/win/DragControllerWin.cpp
@@ -61,4 +61,8 @@ const IntSize& DragController::maxDragImageSize()
return maxDragImageSize;
}
+void DragController::cleanupAfterSystemDrag()
+{
+}
+
}
diff --git a/WebCore/page/win/EventHandlerWin.cpp b/WebCore/page/win/EventHandlerWin.cpp
index bfd2b02..88bc373 100644
--- a/WebCore/page/win/EventHandlerWin.cpp
+++ b/WebCore/page/win/EventHandlerWin.cpp
@@ -45,8 +45,6 @@
namespace WebCore {
-unsigned EventHandler::s_accessKeyModifiers = PlatformKeyboardEvent::AltKey;
-
const double EventHandler::TextDragDelay = 0.0;
bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
@@ -108,4 +106,9 @@ bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestR
return false;
}
+unsigned EventHandler::accessKeyModifiers()
+{
+ return PlatformKeyboardEvent::AltKey;
+}
+
}
diff --git a/WebCore/page/win/FrameCGWin.cpp b/WebCore/page/win/FrameCGWin.cpp
index ad22967..8b0408d 100644
--- a/WebCore/page/win/FrameCGWin.cpp
+++ b/WebCore/page/win/FrameCGWin.cpp
@@ -44,18 +44,13 @@ static void drawRectIntoContext(IntRect rect, FrameView* view, GraphicsContext*
rect.move(-offset.width(), -offset.height());
rect = view->convertToContainingWindow(rect);
- gc->concatCTM(AffineTransform().translate(-rect.x(), -rect.y()));
+ gc->concatCTM(TransformationMatrix().translate(-rect.x(), -rect.y()));
view->paint(gc, rect);
}
-HBITMAP imageFromSelection(Frame* frame, bool forceBlackText)
+static HBITMAP imageFromRect(const Frame* frame, IntRect& ir)
{
- frame->view()->setPaintRestriction(forceBlackText ? PaintRestrictionSelectionOnlyBlackText : PaintRestrictionSelectionOnly);
- FloatRect fr = frame->selectionRect();
- IntRect ir(static_cast<int>(fr.x()), static_cast<int>(fr.y()),
- static_cast<int>(fr.width()), static_cast<int>(fr.height()));
-
void* bits;
HDC hdc = CreateCompatibleDC(0);
int w = ir.width();
@@ -72,16 +67,44 @@ HBITMAP imageFromSelection(Frame* frame, bool forceBlackText)
GraphicsContext gc(context);
- frame->document()->updateLayout();
drawRectIntoContext(ir, frame->view(), &gc);
CGContextRelease(context);
SelectObject(hdc, hbmpOld);
DeleteDC(hdc);
+ return hbmp;
+}
+
+HBITMAP imageFromSelection(Frame* frame, bool forceBlackText)
+{
+ frame->document()->updateLayout();
+
+ frame->view()->setPaintRestriction(forceBlackText ? PaintRestrictionSelectionOnlyBlackText : PaintRestrictionSelectionOnly);
+ FloatRect fr = frame->selectionBounds();
+ IntRect ir(static_cast<int>(fr.x()), static_cast<int>(fr.y()),
+ static_cast<int>(fr.width()), static_cast<int>(fr.height()));
+ HBITMAP image = imageFromRect(frame, ir);
frame->view()->setPaintRestriction(PaintRestrictionNone);
+ return image;
+}
- return hbmp;
+HBITMAP Frame::nodeImage(Node* node) const
+{
+ RenderObject* renderer = node->renderer();
+ if (!renderer)
+ return 0;
+
+ IntRect topLevelRect;
+ IntRect paintingRect = renderer->paintingRootRect(topLevelRect);
+
+ document()->updateLayout();
+
+ m_view->setNodeToDraw(node); // invoke special sub-tree drawing mode
+ HBITMAP result = imageFromRect(this, paintingRect);
+ m_view->setNodeToDraw(0);
+
+ return result;
}
} // namespace WebCore
diff --git a/WebCore/page/win/FrameCairoWin.cpp b/WebCore/page/win/FrameCairoWin.cpp
index a645a10..f5b832e 100644
--- a/WebCore/page/win/FrameCairoWin.cpp
+++ b/WebCore/page/win/FrameCairoWin.cpp
@@ -39,4 +39,10 @@ HBITMAP imageFromSelection(Frame* frame, bool forceBlackText)
return 0;
}
+HBITMAP Frame::nodeImage(Node*) const
+{
+ notImplemented();
+ return 0;
+}
+
} // namespace WebCore
diff --git a/WebCore/page/win/FrameWin.cpp b/WebCore/page/win/FrameWin.cpp
index 536f5d8..fef1ffa 100644
--- a/WebCore/page/win/FrameWin.cpp
+++ b/WebCore/page/win/FrameWin.cpp
@@ -27,10 +27,9 @@
#include "runtime.h"
#include "FrameWin.h"
-#include "AffineTransform.h"
+#include "TransformationMatrix.h"
#include "FloatRect.h"
#include "Document.h"
-#include "FramePrivate.h"
#include "RenderView.h"
#include "Settings.h"
diff --git a/WebCore/page/wx/AccessibilityObjectWx.cpp b/WebCore/page/wx/AccessibilityObjectWx.cpp
index b755645..1710027 100644
--- a/WebCore/page/wx/AccessibilityObjectWx.cpp
+++ b/WebCore/page/wx/AccessibilityObjectWx.cpp
@@ -20,6 +20,8 @@
#include "config.h"
#include "AccessibilityObject.h"
+#if HAVE(ACCESSIBILITY)
+
namespace WebCore {
bool AccessibilityObject::accessibilityIgnoreAttachment() const
@@ -28,3 +30,5 @@ bool AccessibilityObject::accessibilityIgnoreAttachment() const
}
} // namespace WebCore
+
+#endif // HAVE(ACCESSIBILITY)
diff --git a/WebCore/page/wx/DragControllerWx.cpp b/WebCore/page/wx/DragControllerWx.cpp
index 659364f..c288a01 100644
--- a/WebCore/page/wx/DragControllerWx.cpp
+++ b/WebCore/page/wx/DragControllerWx.cpp
@@ -65,4 +65,8 @@ const IntSize& DragController::maxDragImageSize()
return maxDragImageSize;
}
+void DragController::cleanupAfterSystemDrag()
+{
+}
+
}
diff --git a/WebCore/page/wx/EventHandlerWx.cpp b/WebCore/page/wx/EventHandlerWx.cpp
index ce4473f..a0d8b23 100644
--- a/WebCore/page/wx/EventHandlerWx.cpp
+++ b/WebCore/page/wx/EventHandlerWx.cpp
@@ -39,8 +39,6 @@
namespace WebCore {
-unsigned EventHandler::s_accessKeyModifiers = PlatformKeyboardEvent::AltKey;
-
const double EventHandler::TextDragDelay = 0.0;
bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
@@ -91,4 +89,9 @@ PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
return ClipboardWx::create(ClipboardWritable, true);
}
+unsigned EventHandler::accessKeyModifiers()
+{
+ return PlatformKeyboardEvent::AltKey;
+}
+
}