summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-06-17 17:06:07 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-06-17 17:06:07 (GMT)
commit6aa50af000f85cc4497749fcf0860c8ed244a60e (patch)
treed5b5d845572521d1f04519386945fa7235ef674c
parent0610902bcd722605f10840a6a3d1600e1e07f771 (diff)
parent24605a8cd542b44e6ed2bb6dbb7fe12633015853 (diff)
downloadQt-6aa50af000f85cc4497749fcf0860c8ed244a60e.zip
Qt-6aa50af000f85cc4497749fcf0860c8ed244a60e.tar.gz
Qt-6aa50af000f85cc4497749fcf0860c8ed244a60e.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-webkit into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/qt-webkit: Updated WebKit to 6623b5da196390748dc619461739f9cb84524736
-rw-r--r--src/3rdparty/webkit/.tag2
-rw-r--r--src/3rdparty/webkit/ChangeLog13
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/ChangeLog13
-rw-r--r--src/3rdparty/webkit/VERSION2
-rw-r--r--src/3rdparty/webkit/WebCore/ChangeLog201
-rw-r--r--src/3rdparty/webkit/WebCore/page/FocusController.cpp176
-rw-r--r--src/3rdparty/webkit/WebCore/page/FrameView.cpp54
-rw-r--r--src/3rdparty/webkit/WebCore/page/FrameView.h14
-rw-r--r--src/3rdparty/webkit/WebCore/page/SpatialNavigation.cpp25
-rw-r--r--src/3rdparty/webkit/WebCore/page/SpatialNavigation.h7
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp18
-rw-r--r--src/3rdparty/webkit/WebCore/plugins/qt/PluginPackageQt.cpp23
-rw-r--r--src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp45
-rw-r--r--src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp7
-rw-r--r--src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.h3
-rw-r--r--src/3rdparty/webkit/WebKit/qt/ChangeLog37
16 files changed, 541 insertions, 99 deletions
diff --git a/src/3rdparty/webkit/.tag b/src/3rdparty/webkit/.tag
index 07a02d7..f5b6af3 100644
--- a/src/3rdparty/webkit/.tag
+++ b/src/3rdparty/webkit/.tag
@@ -1 +1 @@
-40c2d6907ef75288b4f15e7fad334b9138acdbbf
+6623b5da196390748dc619461739f9cb84524736
diff --git a/src/3rdparty/webkit/ChangeLog b/src/3rdparty/webkit/ChangeLog
index c2862fd..51d08a0 100644
--- a/src/3rdparty/webkit/ChangeLog
+++ b/src/3rdparty/webkit/ChangeLog
@@ -1,3 +1,16 @@
+2010-06-17 Mark Brand <mabrand@mabrand.nl>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] use "win32-g++*" scope to match all MinGW makespecs
+
+ The scope "win32-g++" comes from the name of the makespec. However, it
+ is frequently used to check for MinGW. This works fine as long as
+ win32-g++ is the only makespec for MinGW. Now we need the wildcard
+ to cover "win32-g++-cross" as well.
+
+ * WebKit.pri:
+
2010-05-04 Laszlo Gombos <laszlo.1.gombos@nokia.com>
Unreviewed, build fix for Symbian.
diff --git a/src/3rdparty/webkit/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/JavaScriptCore/ChangeLog
index d9b2987..adaf390 100644
--- a/src/3rdparty/webkit/JavaScriptCore/ChangeLog
+++ b/src/3rdparty/webkit/JavaScriptCore/ChangeLog
@@ -1,3 +1,16 @@
+2010-06-17 Mark Brand <mabrand@mabrand.nl>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] use "win32-g++*" scope to match all MinGW makespecs
+
+ The scope "win32-g++" comes from the name of the makespec. However, it
+ is frequently used to check for MinGW. This works fine as long as
+ win32-g++ is the only makespec for MinGW. Now we need the wildcard
+ to cover "win32-g++-cross" as well.
+
+ * JavaScriptCore.pro:
+
2010-06-07 Benjamin Poulain <benjamin.poulain@nokia.com>
Reviewed by Simon Hausmann.
diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION
index b648b94..1e7351f 100644
--- a/src/3rdparty/webkit/VERSION
+++ b/src/3rdparty/webkit/VERSION
@@ -4,4 +4,4 @@ This is a snapshot of the Qt port of WebKit from
and has the sha1 checksum
- 40c2d6907ef75288b4f15e7fad334b9138acdbbf
+ 6623b5da196390748dc619461739f9cb84524736
diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog
index 6a7da30..c17a8aa 100644
--- a/src/3rdparty/webkit/WebCore/ChangeLog
+++ b/src/3rdparty/webkit/WebCore/ChangeLog
@@ -1,3 +1,204 @@
+2010-06-17 Mark Brand <mabrand@mabrand.nl>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] use "win32-g++*" scope to match all MinGW makespecs
+
+ The scope "win32-g++" comes from the name of the makespec. However, it
+ is frequently used to check for MinGW. This works fine as long as
+ win32-g++ is the only makespec for MinGW. Now we need the wildcard
+ to cover "win32-g++-cross" as well.
+
+ * WebCore.pro:
+
+2010-06-16 Antonio Gomes <tonikitoo@webkit.org>
+
+ Reviewed by Kenneth Christiansen.
+
+ Spatial Navigation: using offset{Left,Top} is not enough to get the proper inner frames position
+ https://bugs.webkit.org/show_bug.cgi?id=39439
+
+ As pointed out by Darin Adler in https://bugs.webkit.org/show_bug.cgi?id=18662#c20,
+ "It's not correct to use the offsetLeft and offsetTop of the frame owner element's renderer because
+ that's just the distance from the offsetParent, not the absolute position".
+
+ Patch fixes that behavior by now considering the offsetTop and offsetLeft the offsetParent recursively,
+ starting from the HtmlFrameOwnerElement. Previously, only calling offsetTop and offsetLeft works
+ because all tests were done in htmls where the {i}frame element was a directly a child of the body,
+ e.g. <html>...<body><iframe src=xxx>....<body></html>.
+
+ Test: fast/events/spatial-navigation/snav-iframe-recursive-offset-parent.html
+
+ * page/SpatialNavigation.cpp:
+ (WebCore::renderRectRelativeToRootDocument):
+
+2010-06-16 Antonio Gomes <tonikitoo@webkit.org>
+
+ Reviewed by Simon Fraser.
+
+ Spatial Navigation: refactor scrollInDirection to work with scrollable content
+ https://bugs.webkit.org/show_bug.cgi?id=39195
+
+ scrollInDirection now receives as parameter the node that the Spatial Navigation
+ found as the more appropriated to move focus to. If it is in a scrollable container
+ (e.g. <div> with clipped overflow content), it scrolls recursively starting from
+ the container, not the current focused node.
+
+ Test: fast/events/spatial-navigation/snav-only-clipped-overflow-content.html
+
+ * page/FocusController.cpp:
+ (WebCore::FocusController::advanceFocusDirectionally):
+ * page/SpatialNavigation.cpp:
+ (WebCore::scrollInDirection):
+ * page/SpatialNavigation.h:
+
+2010-05-28 Viatcheslav Ostapenko <ostapenko.viatcheslav@nokia.com>
+
+ Reviewed by Simon Hausmann, Antti Koivisto
+
+ Make repaint throttling parameters runtime configurable.
+ https://bugs.webkit.org/show_bug.cgi?id=38401
+
+ REPAINT_THROTTLING now chooses default values for throttling parameters.
+ Should be removed when applications start using runtime configuration.
+
+ * page/FrameView.cpp:
+ (WebCore::FrameView::reset):
+ (WebCore::FrameView::updateDeferredRepaintDelay):
+ (WebCore::FrameView::setRepaintThrottlingDeferredRepaintDelay):
+ (WebCore::FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading):
+ (WebCore::FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading):
+ (WebCore::FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading):
+ * page/FrameView.h:
+
+2010-06-16 Dawit Alemayehu <adawit@kde.org>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] QtWebKit crashes while initializing flash plugin 10.1.53.64.
+ https://bugs.webkit.org/show_bug.cgi?id=40567
+
+ Avoid preventable crashes by ensuring gtk_init() is called in the
+ flash viewer plugins before calling NP_Initialize.
+
+ * plugins/qt/PluginPackageQt.cpp:
+ (WebCore::PluginPackage::load):
+
+2010-04-21 Zoltan Herczeg <zherczeg@webkit.org>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] startAnimation() is not needed to preceede nativeImageForCurrentFrame()
+ https://bugs.webkit.org/show_bug.cgi?id=37844
+
+ nativeImageForCurrentFrame() resets the m_decoder parameter under Qt,
+ which is required by startAnimation() to detect frame and repetition counts.
+ Hence, Image::drawTiled cannot start animations under Qt:
+ <html><body background="animated.gif"></body></html> does not work
+
+ * platform/graphics/qt/ImageDecoderQt.cpp:
+ (WebCore::ImageDecoderQt::internalHandleCurrentImage):
+
+2010-05-28 Peter Kasting <pkasting@google.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=39857
+ Make GIFs loop the correct number of times. Previously, everyone looped
+ one time too few for non-infinitely-looping GIFs.
+
+ Modified a Qt manual test to be correct and moved it to the general
+ manual test directory.
+
+ * manual-tests/animated-gif-looping.html: Copied from WebCore/manual-tests/qt/qt-gif-test.html.
+ * manual-tests/qt/qt-10loop-anim.gif: Removed.
+ * manual-tests/qt/qt-anim.gif: Removed.
+ * manual-tests/qt/qt-gif-test.html: Removed.
+ * manual-tests/qt/qt-noanim.gif: Removed.
+ * manual-tests/resources/animated-10x.gif: Copied from WebCore/manual-tests/qt/qt-10loop-anim.gif and modified.
+ * manual-tests/resources/animated-infinite.gif: Copied from WebCore/manual-tests/qt/qt-anim.gif.
+ * manual-tests/resources/non-animated.gif: Copied from WebCore/manual-tests/qt/qt-noanim.gif.
+ * platform/graphics/BitmapImage.cpp:
+ (WebCore::BitmapImage::internalAdvanceAnimation): For a loop count of n, show a total of n + 1 animation cycles.
+ * platform/graphics/ImageSource.h:
+ * platform/graphics/cg/ImageSourceCG.cpp:
+ (WebCore::ImageSource::repetitionCount):
+ * platform/graphics/qt/ImageDecoderQt.cpp:
+ (WebCore::ImageDecoderQt::repetitionCount): Remove translation code now that WebCore matches Qt's internal handling of the loop count. Qt itself may still have a bug here.
+ * platform/image-decoders/gif/GIFImageDecoder.cpp:
+ (WebCore::GIFImageDecoder::repetitionCount):
+ * platform/image-decoders/gif/GIFImageReader.cpp:
+ (GIFImageReader::read): Translate loop count 0 to "loop infinitely" (by restoring one piece of the Mozilla code we'd removed).
+
+2010-05-04 Tucker Jay <jay.tucker@nokia.com>
+
+ Reviewed by Holger Freyther.
+
+ Animated GIF images does not animate 10x as expected by default.
+ https://bugs.webkit.org/show_bug.cgi?id=36818
+
+ Added test case to existing manual test to test the
+ fixed functionality.
+
+ * manual-tests/qt/qt-10loop-anim.gif: Added.
+ * manual-tests/qt/qt-gif-test.html:
+ * platform/graphics/qt/ImageDecoderQt.cpp:
+ (WebCore::ImageDecoderQt::repetitionCount):
+
+2010-05-16 Antonio Gomes <tonikitoo@webkit.org>
+
+ Unreviewed naming fixes of local variables used in Spatial Navigation methods.
+
+ Summary:
+ * "candidate" renamed to "node";
+ * "currentFocusCandidate" renamed to "candidate"
+ * "closestFocusCandidate" renamed to "closest"
+
+ That way naming is more consistent in the various Spatial Navigation methods.
+
+ * page/FocusController.cpp:
+ (WebCore::FocusController::findFocusableNodeInDirection):
+ (WebCore::FocusController::deepFindFocusableNodeInDirection):
+
+2010-06-14 Antonio Gomes <tonikitoo@webkit.org>
+
+ Reviewed by Simon Fraser and Kenneth Christiansen.
+
+ Spatial Navigation: make it work with focusable elements in overflow content
+ https://bugs.webkit.org/show_bug.cgi?id=36463
+
+ This patch addresses the problem with Spatial Navigation. It currently does not
+ properly traverse scrollable contents, including scrollable div's. For this to work,
+ a new class member called scrollableEnclosingBox was introduced to FocusCandidate class which
+ keeps track of the current scrollable box Node wrapping a FocusCandidate.
+
+ To make use of enclosingScrollableBox of FocusCandidate, the DOM traversal routine
+ (FocusController::findNextFocusableInDirection) was changed as follows: when it
+ encounters a scrollable Node, each focusable node which is 'inner' keeps track of
+ the container reference. By the time a sibling of the scrollable Node is encountered,
+ there is no need to track this reference any more and the traversal algorithm continues
+ normally.
+
+ The common case is obviously that there is no scrollable container wrapping it.
+
+ updateFocusCandiditeIfCloser logic was also adapted to fit the need of the
+ newly introduced enclosingScrollableBox class member, getting simpler and more
+ easily maintainable.
+
+ Tests: fast/events/spatial-navigation/snav-div-scrollable-but-without-focusable-content.html
+ fast/events/spatial-navigation/snav-clipped-overflow-content.html
+
+ * page/FocusController.cpp:
+ (WebCore::updateFocusCandidateInSameContainer):
+ (WebCore::updateFocusCandidateIfCloser):
+ (WebCore::FocusController::findFocusableNodeInDirection):
+ (WebCore::FocusController::deepFindFocusableNodeInDirection):
+ * page/SpatialNavigation.cpp:
+ (WebCore::isScrollableContainerNode):
+ * page/SpatialNavigation.h:
+ (WebCore::FocusCandidate::FocusCandidate):
+ (WebCore::FocusCandidate::isInScrollableContainer):
+
2010-06-15 Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
Reviewed by Simon Hausmann.
diff --git a/src/3rdparty/webkit/WebCore/page/FocusController.cpp b/src/3rdparty/webkit/WebCore/page/FocusController.cpp
index 6c2a956..a285e52 100644
--- a/src/3rdparty/webkit/WebCore/page/FocusController.cpp
+++ b/src/3rdparty/webkit/WebCore/page/FocusController.cpp
@@ -319,7 +319,7 @@ bool FocusController::advanceFocusDirectionally(FocusDirection direction, Keyboa
// if |node| element is not in the viewport.
if (hasOffscreenRect(node)) {
Frame* frame = node->document()->view()->frame();
- scrollInDirection(frame, direction);
+ scrollInDirection(frame, direction, focusCandidate);
return true;
}
@@ -341,105 +341,152 @@ bool FocusController::advanceFocusDirectionally(FocusDirection direction, Keyboa
return true;
}
-// FIXME: Make this method more modular, and simpler to understand and maintain.
-static void updateFocusCandidateIfCloser(Node* focusedNode, const FocusCandidate& candidate, FocusCandidate& closest)
+static void updateFocusCandidateInSameContainer(const FocusCandidate& candidate, FocusCandidate& closest)
{
- bool sameDocument = candidate.document() == closest.document();
- if (sameDocument) {
- if (closest.alignment > candidate.alignment
- || (closest.parentAlignment && candidate.alignment > closest.parentAlignment))
- return;
- } else if (closest.alignment > candidate.alignment
- && (closest.parentAlignment && candidate.alignment > closest.parentAlignment))
+ if (closest.isNull()) {
+ closest = candidate;
return;
+ }
- if (candidate.alignment != None
- || (closest.parentAlignment >= candidate.alignment
- && closest.document() == candidate.document())) {
+ if (candidate.alignment == closest.alignment) {
+ if (candidate.distance < closest.distance)
+ closest = candidate;
+ return;
+ }
- // If we are now in an higher precedent case, lets reset the current closest's
- // distance so we force it to be bigger than any result we will get from
- // spatialDistance().
- if (closest.alignment < candidate.alignment
- && closest.parentAlignment < candidate.alignment)
- closest.distance = maxDistance();
+ if (candidate.alignment > closest.alignment)
+ closest = candidate;
+}
- closest.alignment = candidate.alignment;
+static void updateFocusCandidateIfCloser(Node* focusedNode, const FocusCandidate& candidate, FocusCandidate& closest)
+{
+ // First, check the common case: neither candidate nor closest are
+ // inside scrollable content, then no need to care about enclosingScrollableBox
+ // heuristics or parent{Distance,Alignment}, but only distance and alignment.
+ if (!candidate.inScrollableContainer() && !closest.inScrollableContainer()) {
+ updateFocusCandidateInSameContainer(candidate, closest);
+ return;
}
- // Bail out if candidate's distance is larger than that of the closest candidate.
- if (candidate.distance >= closest.distance)
+ bool sameContainer = candidate.document() == closest.document() && candidate.enclosingScrollableBox == closest.enclosingScrollableBox;
+
+ // Second, if candidate and closest are in the same "container" (i.e. {i}frame or any
+ // scrollable block element), we can handle them as common case.
+ if (sameContainer) {
+ updateFocusCandidateInSameContainer(candidate, closest);
return;
+ }
- if (closest.isNull()) {
+ // Last, we are considering moving to a candidate located in a different enclosing
+ // scrollable box than closest.
+ bool isInInnerDocument = !isInRootDocument(focusedNode);
+
+ bool sameContainerAsCandidate = isInInnerDocument ? focusedNode->document() == candidate.document() :
+ focusedNode->isDescendantOf(candidate.enclosingScrollableBox);
+
+ bool sameContainerAsClosest = isInInnerDocument ? focusedNode->document() == closest.document() :
+ focusedNode->isDescendantOf(closest.enclosingScrollableBox);
+
+ // sameContainerAsCandidate and sameContainerAsClosest are mutually exclusive.
+ ASSERT(!(sameContainerAsCandidate && sameContainerAsClosest));
+
+ if (sameContainerAsCandidate) {
closest = candidate;
return;
}
- // If the focused node and the candadate are in the same document and current
- // closest candidate is not in an {i}frame that is preferable to get focused ...
- if (focusedNode->document() == candidate.document()
- && candidate.distance < closest.parentDistance)
- closest = candidate;
- else if (focusedNode->document() != candidate.document()) {
- // If the focusedNode is in an inner document and candidate is in a
- // different document, we only consider to change focus if there is not
- // another already good focusable candidate in the same document as focusedNode.
- if (!((isInRootDocument(candidate.node) && !isInRootDocument(focusedNode))
- && focusedNode->document() == closest.document()))
+ if (sameContainerAsClosest) {
+ // Nothing to be done.
+ return;
+ }
+
+ // NOTE: !sameContainerAsCandidate && !sameContainerAsClosest
+ // If distance is shorter, and we are talking about scrollable container,
+ // lets compare parent distance and alignment before anything.
+ if (candidate.distance < closest.distance) {
+ if (candidate.alignment >= closest.parentAlignment
+ || candidate.parentAlignment == closest.parentAlignment) {
closest = candidate;
+ return;
+ }
+
+ } else if (candidate.parentDistance < closest.distance) {
+ if (candidate.parentAlignment >= closest.alignment) {
+ closest = candidate;
+ return;
+ }
}
}
void FocusController::findFocusableNodeInDirection(Node* outer, Node* focusedNode,
FocusDirection direction, KeyboardEvent* event,
- FocusCandidate& closestFocusCandidate,
- const FocusCandidate& candidateParent)
+ FocusCandidate& closest, const FocusCandidate& candidateParent)
{
ASSERT(outer);
ASSERT(candidateParent.isNull()
|| candidateParent.node->hasTagName(frameTag)
- || candidateParent.node->hasTagName(iframeTag));
+ || candidateParent.node->hasTagName(iframeTag)
+ || isScrollableContainerNode(candidateParent.node));
+
+ // Walk all the child nodes and update closest if we find a nearer node.
+ Node* node = outer;
+ while (node) {
- // Walk all the child nodes and update closestFocusCandidate if we find a nearer node.
- Node* candidate = outer;
- while (candidate) {
// Inner documents case.
+ if (node->isFrameOwnerElement()) {
+ deepFindFocusableNodeInDirection(node, focusedNode, direction, event, closest);
- if (candidate->isFrameOwnerElement())
- deepFindFocusableNodeInDirection(candidate, focusedNode, direction, event, closestFocusCandidate);
- else if (candidate != focusedNode && candidate->isKeyboardFocusable(event)) {
- FocusCandidate currentFocusCandidate(candidate);
+ // Scrollable block elements (e.g. <div>, etc) case.
+ } else if (isScrollableContainerNode(node)) {
+ deepFindFocusableNodeInDirection(node, focusedNode, direction, event, closest);
+ node = node->traverseNextSibling();
+ continue;
+
+ } else if (node != focusedNode && node->isKeyboardFocusable(event)) {
+ FocusCandidate candidate(node);
+
+ // There are two ways to identify we are in a recursive call from deepFindFocusableNodeInDirection
+ // (i.e. processing an element in an iframe, frame or a scrollable block element):
+
+ // 1) If candidateParent is not null, and it holds the distance and alignment data of the
+ // parent container element itself;
+ // 2) Parent of outer is <frame> or <iframe>;
+ // 3) Parent is any other scrollable block element.
+ if (!candidateParent.isNull()) {
+ candidate.parentAlignment = candidateParent.alignment;
+ candidate.parentDistance = candidateParent.distance;
+ candidate.enclosingScrollableBox = candidateParent.node;
+
+ } else if (!isInRootDocument(outer)) {
+ if (Document* document = static_cast<Document*>(outer->parent()))
+ candidate.enclosingScrollableBox = static_cast<Node*>(document->ownerElement());
+
+ } else if (isScrollableContainerNode(outer->parent()))
+ candidate.enclosingScrollableBox = outer->parent();
// Get distance and alignment from current candidate.
- distanceDataForNode(direction, focusedNode, currentFocusCandidate);
+ distanceDataForNode(direction, focusedNode, candidate);
// Bail out if distance is maximum.
- if (currentFocusCandidate.distance == maxDistance()) {
- candidate = candidate->traverseNextNode(outer->parent());
+ if (candidate.distance == maxDistance()) {
+ node = node->traverseNextNode(outer->parent());
continue;
}
- // If candidateParent is not null, it means that we are in a recursive call
- // from deepFineFocusableNodeInDirection (i.e. processing an element in an iframe),
- // and holds the distance and alignment data of the iframe element itself.
- if (!candidateParent.isNull()) {
- currentFocusCandidate.parentAlignment = candidateParent.alignment;
- currentFocusCandidate.parentDistance = candidateParent.distance;
- }
-
- updateFocusCandidateIfCloser(focusedNode, currentFocusCandidate, closestFocusCandidate);
+ updateFocusCandidateIfCloser(focusedNode, candidate, closest);
}
- candidate = candidate->traverseNextNode(outer->parent());
+ node = node->traverseNextNode(outer->parent());
}
}
void FocusController::deepFindFocusableNodeInDirection(Node* container, Node* focusedNode,
FocusDirection direction, KeyboardEvent* event,
- FocusCandidate& closestFocusCandidate)
+ FocusCandidate& closest)
{
- ASSERT(container->hasTagName(frameTag) || container->hasTagName(iframeTag));
+ ASSERT(container->hasTagName(frameTag)
+ || container->hasTagName(iframeTag)
+ || isScrollableContainerNode(container));
// Track if focusedNode is a descendant of the current container node being processed.
bool descendantOfContainer = false;
@@ -459,10 +506,15 @@ void FocusController::deepFindFocusableNodeInDirection(Node* container, Node* fo
descendantOfContainer = innerDocument == focusedNode->document();
firstChild = innerDocument->firstChild();
+ // Scrollable block elements (e.g. <div>, etc)
+ } else if (isScrollableContainerNode(container)) {
+
+ firstChild = container->firstChild();
+ descendantOfContainer = focusedNode->isDescendantOf(container);
}
if (descendantOfContainer) {
- findFocusableNodeInDirection(firstChild, focusedNode, direction, event, closestFocusCandidate);
+ findFocusableNodeInDirection(firstChild, focusedNode, direction, event, closest);
return;
}
@@ -476,8 +528,8 @@ void FocusController::deepFindFocusableNodeInDirection(Node* container, Node* fo
return;
// FIXME: Consider alignment?
- if (candidateParent.distance < closestFocusCandidate.distance)
- findFocusableNodeInDirection(firstChild, focusedNode, direction, event, closestFocusCandidate, candidateParent);
+ if (candidateParent.distance < closest.distance)
+ findFocusableNodeInDirection(firstChild, focusedNode, direction, event, closest, candidateParent);
}
static bool relinquishesEditingFocus(Node *node)
diff --git a/src/3rdparty/webkit/WebCore/page/FrameView.cpp b/src/3rdparty/webkit/WebCore/page/FrameView.cpp
index bc0519f..a53db36 100644
--- a/src/3rdparty/webkit/WebCore/page/FrameView.cpp
+++ b/src/3rdparty/webkit/WebCore/page/FrameView.cpp
@@ -80,23 +80,25 @@ using namespace HTMLNames;
double FrameView::sCurrentPaintTimeStamp = 0.0;
+// REPAINT_THROTTLING now chooses default values for throttling parameters.
+// Should be removed when applications start using runtime configuration.
#if ENABLE(REPAINT_THROTTLING)
// Normal delay
-static const double deferredRepaintDelay = 0.025;
+double FrameView::s_deferredRepaintDelay = 0.025;
// Negative value would mean that first few repaints happen without a delay
-static const double initialDeferredRepaintDelayDuringLoading = 0;
+double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0;
// The delay grows on each repaint to this maximum value
-static const double maxDeferredRepaintDelayDuringLoading = 2.5;
+double FrameView::s_maxDeferredRepaintDelayDuringLoading = 2.5;
// On each repaint the delay increses by this amount
-static const double deferredRepaintDelayIncrementDuringLoading = 0.5;
+double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0.5;
#else
// FIXME: Repaint throttling could be good to have on all platform.
// The balance between CPU use and repaint frequency will need some tuning for desktop.
// More hooks may be needed to reset the delay on things like GIF and CSS animations.
-static const double deferredRepaintDelay = 0;
-static const double initialDeferredRepaintDelayDuringLoading = 0;
-static const double maxDeferredRepaintDelayDuringLoading = 0;
-static const double deferredRepaintDelayIncrementDuringLoading = 0;
+double FrameView::s_deferredRepaintDelay = 0;
+double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0;
+double FrameView::s_maxDeferredRepaintDelayDuringLoading = 0;
+double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0;
#endif
// The maximum number of updateWidgets iterations that should be done before returning.
@@ -200,7 +202,7 @@ void FrameView::reset()
m_deferringRepaints = 0;
m_repaintCount = 0;
m_repaintRects.clear();
- m_deferredRepaintDelay = initialDeferredRepaintDelayDuringLoading;
+ m_deferredRepaintDelay = s_initialDeferredRepaintDelayDuringLoading;
m_deferredRepaintTimer.stop();
m_lastPaintTime = 0;
m_paintBehavior = PaintBehaviorNormal;
@@ -1218,13 +1220,13 @@ void FrameView::updateDeferredRepaintDelay()
{
Document* document = m_frame->document();
if (!document || (!document->parsing() && !document->docLoader()->requestCount())) {
- m_deferredRepaintDelay = deferredRepaintDelay;
+ m_deferredRepaintDelay = s_deferredRepaintDelay;
return;
}
- if (m_deferredRepaintDelay < maxDeferredRepaintDelayDuringLoading) {
- m_deferredRepaintDelay += deferredRepaintDelayIncrementDuringLoading;
- if (m_deferredRepaintDelay > maxDeferredRepaintDelayDuringLoading)
- m_deferredRepaintDelay = maxDeferredRepaintDelayDuringLoading;
+ if (m_deferredRepaintDelay < s_maxDeferredRepaintDelayDuringLoading) {
+ m_deferredRepaintDelay += s_deferredRepaintDelayIncrementDuringLoading;
+ if (m_deferredRepaintDelay > s_maxDeferredRepaintDelayDuringLoading)
+ m_deferredRepaintDelay = s_maxDeferredRepaintDelayDuringLoading;
}
}
@@ -2143,4 +2145,28 @@ IntPoint FrameView::convertFromContainingView(const IntPoint& parentPoint) const
return parentPoint;
}
+// Normal delay
+void FrameView::setRepaintThrottlingDeferredRepaintDelay(double p)
+{
+ s_deferredRepaintDelay = p;
+}
+
+// Negative value would mean that first few repaints happen without a delay
+void FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(double p)
+{
+ s_initialDeferredRepaintDelayDuringLoading = p;
+}
+
+// The delay grows on each repaint to this maximum value
+void FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(double p)
+{
+ s_maxDeferredRepaintDelayDuringLoading = p;
+}
+
+// On each repaint the delay increases by this amount
+void FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(double p)
+{
+ s_deferredRepaintDelayIncrementDuringLoading = p;
+}
+
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/FrameView.h b/src/3rdparty/webkit/WebCore/page/FrameView.h
index 71e2966..71fa8cd 100644
--- a/src/3rdparty/webkit/WebCore/page/FrameView.h
+++ b/src/3rdparty/webkit/WebCore/page/FrameView.h
@@ -210,6 +210,15 @@ public:
bool isFrameViewScrollCorner(RenderScrollbarPart* scrollCorner) const { return m_scrollCorner == scrollCorner; }
void invalidateScrollCorner();
+ // Normal delay
+ static void setRepaintThrottlingDeferredRepaintDelay(double p);
+ // Negative value would mean that first few repaints happen without a delay
+ static void setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(double p);
+ // The delay grows on each repaint to this maximum value
+ static void setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(double p);
+ // On each repaint the delay increses by this amount
+ static void setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(double p);
+
protected:
virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
@@ -340,6 +349,11 @@ private:
// Renderer to hold our custom scroll corner.
RenderScrollbarPart* m_scrollCorner;
+
+ static double s_deferredRepaintDelay;
+ static double s_initialDeferredRepaintDelayDuringLoading;
+ static double s_maxDeferredRepaintDelayDuringLoading;
+ static double s_deferredRepaintDelayIncrementDuringLoading;
};
#if ENABLE(INSPECTOR)
diff --git a/src/3rdparty/webkit/WebCore/page/SpatialNavigation.cpp b/src/3rdparty/webkit/WebCore/page/SpatialNavigation.cpp
index d7eaf25..1ce61c3 100644
--- a/src/3rdparty/webkit/WebCore/page/SpatialNavigation.cpp
+++ b/src/3rdparty/webkit/WebCore/page/SpatialNavigation.cpp
@@ -124,8 +124,11 @@ static IntRect renderRectRelativeToRootDocument(RenderObject* render)
// Handle nested frames.
for (Frame* frame = render->document()->frame(); frame; frame = frame->tree()->parent()) {
- if (HTMLFrameOwnerElement* ownerElement = frame->ownerElement())
- rect.move(ownerElement->offsetLeft(), ownerElement->offsetTop());
+ if (Element* element = static_cast<Element*>(frame->ownerElement())) {
+ do {
+ rect.move(element->offsetLeft(), element->offsetTop());
+ } while ((element = element->offsetParent()));
+ }
}
return rect;
@@ -444,7 +447,7 @@ bool hasOffscreenRect(Node* node)
// In a bottom-up way, this method tries to scroll |frame| in a given direction
// |direction|, going up in the frame tree hierarchy in case it does not succeed.
-bool scrollInDirection(Frame* frame, FocusDirection direction)
+bool scrollInDirection(Frame* frame, FocusDirection direction, const FocusCandidate& candidate)
{
if (!frame)
return false;
@@ -468,6 +471,9 @@ bool scrollInDirection(Frame* frame, FocusDirection direction)
return false;
}
+ if (!candidate.isNull() && isScrollableContainerNode(candidate.enclosingScrollableBox))
+ return frame->eventHandler()->scrollRecursively(scrollDirection, ScrollByLine, candidate.enclosingScrollableBox);
+
return frame->eventHandler()->scrollRecursively(scrollDirection, ScrollByLine);
}
@@ -526,4 +532,17 @@ static bool checkNegativeCoordsForNode(Node* node, const IntRect& curRect)
return canBeScrolled;
}
+bool isScrollableContainerNode(Node* node)
+{
+ if (!node)
+ return false;
+
+ if (RenderObject* renderer = node->renderer()) {
+ return (renderer->isBox() && toRenderBox(renderer)->canBeScrolledAndHasScrollableArea()
+ && node->hasChildNodes() && !node->isDocumentNode());
+ }
+
+ return false;
+}
+
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/SpatialNavigation.h b/src/3rdparty/webkit/WebCore/page/SpatialNavigation.h
index 309b095..06389a3 100644
--- a/src/3rdparty/webkit/WebCore/page/SpatialNavigation.h
+++ b/src/3rdparty/webkit/WebCore/page/SpatialNavigation.h
@@ -97,6 +97,7 @@ enum RectsAlignment {
struct FocusCandidate {
FocusCandidate()
: node(0)
+ , enclosingScrollableBox(0)
, distance(maxDistance())
, parentDistance(maxDistance())
, alignment(None)
@@ -106,6 +107,7 @@ struct FocusCandidate {
FocusCandidate(Node* n)
: node(n)
+ , enclosingScrollableBox(0)
, distance(maxDistance())
, parentDistance(maxDistance())
, alignment(None)
@@ -114,9 +116,11 @@ struct FocusCandidate {
}
bool isNull() const { return !node; }
+ bool inScrollableContainer() const { return node && enclosingScrollableBox; }
Document* document() const { return node ? node->document() : 0; }
Node* node;
+ Node* enclosingScrollableBox;
long long distance;
long long parentDistance;
RectsAlignment alignment;
@@ -124,10 +128,11 @@ struct FocusCandidate {
};
void distanceDataForNode(FocusDirection direction, Node* start, FocusCandidate& candidate);
-bool scrollInDirection(Frame*, FocusDirection);
+bool scrollInDirection(Frame*, FocusDirection, const FocusCandidate& candidate = FocusCandidate());
void scrollIntoView(Element*);
bool hasOffscreenRect(Node*);
bool isInRootDocument(Node*);
+bool isScrollableContainerNode(Node*);
} // namspace WebCore
diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
index b10cc71..cc707da 100644
--- a/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
+++ b/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
@@ -115,22 +115,8 @@ size_t ImageDecoderQt::frameCount()
int ImageDecoderQt::repetitionCount() const
{
- if (m_reader && m_reader->supportsAnimation()) {
+ if (m_reader && m_reader->supportsAnimation())
m_repetitionCount = m_reader->loopCount();
-
- // Qt and WebCore have a incompatible understanding of
- // the loop count and we can not completely map everything.
- // Qt | WebCore | description
- // -1 | 0 | infinite animation
- // 0 | cAnimationLoopOnce | show every frame once
- // n | n | no idea if that is supported
- // n/a | cAnimationNone | show only the first frame
- if (m_repetitionCount == -1)
- m_repetitionCount = 0;
- else if (m_repetitionCount == 0)
- m_repetitionCount = cAnimationLoopOnce;
- }
-
return m_repetitionCount;
}
@@ -205,6 +191,8 @@ bool ImageDecoderQt::internalHandleCurrentImage(size_t frameIndex)
// Now get the QImage from Qt and place it in the RGBA32Buffer
QImage img;
if (!m_reader->read(&img)) {
+ frameCount();
+ repetitionCount();
clearPointers();
return false;
}
diff --git a/src/3rdparty/webkit/WebCore/plugins/qt/PluginPackageQt.cpp b/src/3rdparty/webkit/WebCore/plugins/qt/PluginPackageQt.cpp
index 74deaf6..d5292fe 100644
--- a/src/3rdparty/webkit/WebCore/plugins/qt/PluginPackageQt.cpp
+++ b/src/3rdparty/webkit/WebCore/plugins/qt/PluginPackageQt.cpp
@@ -35,6 +35,8 @@
namespace WebCore {
+typedef void gtkInitFunc(int *argc, char ***argv);
+
bool PluginPackage::fetchInfo()
{
if (!load())
@@ -109,6 +111,7 @@ bool PluginPackage::load()
NP_InitializeFuncPtr NP_Initialize;
NPError npErr;
+ gtkInitFunc* gtkInit;
NP_Initialize = (NP_InitializeFuncPtr)m_module->resolve("NP_Initialize");
m_NPP_Shutdown = (NPP_ShutdownProcPtr)m_module->resolve("NP_Shutdown");
@@ -127,6 +130,26 @@ bool PluginPackage::load()
m_browserFuncs.getvalue = staticPluginQuirkRequiresGtkToolKit_NPN_GetValue;
}
+ // WORKAROUND: Prevent gtk based plugin crashes such as BR# 40567 by
+ // explicitly forcing the initializing of Gtk, i.e. calling gtk_init,
+ // whenver the symbol is present in the plugin library loaded above.
+ // Note that this workaround is based on code from the NSPluginClass ctor
+ // in KDE's kdebase/apps/nsplugins/viewer/nsplugin.cpp file.
+ gtkInit = (gtkInitFunc*)m_module->resolve("gtk_init");
+ if (gtkInit) {
+ // Prevent gtk_init() from replacing the X error handlers, since the Gtk
+ // handlers abort when they receive an X error, thus killing the viewer.
+#ifdef Q_WS_X11
+ int (*old_error_handler)(Display*, XErrorEvent*) = XSetErrorHandler(0);
+ int (*old_io_error_handler)(Display*) = XSetIOErrorHandler(0);
+#endif
+ gtkInit(0, 0);
+#ifdef Q_WS_X11
+ XSetErrorHandler(old_error_handler);
+ XSetIOErrorHandler(old_io_error_handler);
+#endif
+ }
+
#if defined(XP_UNIX)
npErr = NP_Initialize(&m_browserFuncs, &m_pluginFuncs);
#else
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp
index 8c7b93d..4460ad3 100644
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp
@@ -1371,6 +1371,14 @@ void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev)
}
#ifndef QT_NO_PROPERTIES
+typedef struct {
+ const char* name;
+ double deferredRepaintDelay;
+ double initialDeferredRepaintDelayDuringLoading;
+ double maxDeferredRepaintDelayDuringLoading;
+ double deferredRepaintDelayIncrementDuringLoading;
+} QRepaintThrottlingPreset;
+
void QWebPagePrivate::dynamicPropertyChangeEvent(QDynamicPropertyChangeEvent* event)
{
if (event->propertyName() == "_q_viewMode") {
@@ -1388,7 +1396,42 @@ void QWebPagePrivate::dynamicPropertyChangeEvent(QDynamicPropertyChangeEvent* ev
} else if (event->propertyName() == "_q_HTMLTokenizerTimeDelay") {
double timeDelay = q->property("_q_HTMLTokenizerTimeDelay").toDouble();
q->handle()->page->setCustomHTMLTokenizerTimeDelay(timeDelay);
- }
+ } else if (event->propertyName() == "_q_RepaintThrottlingDeferredRepaintDelay") {
+ double p = q->property("_q_RepaintThrottlingDeferredRepaintDelay").toDouble();
+ FrameView::setRepaintThrottlingDeferredRepaintDelay(p);
+ } else if (event->propertyName() == "_q_RepaintThrottlingnInitialDeferredRepaintDelayDuringLoading") {
+ double p = q->property("_q_RepaintThrottlingnInitialDeferredRepaintDelayDuringLoading").toDouble();
+ FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(p);
+ } else if (event->propertyName() == "_q_RepaintThrottlingMaxDeferredRepaintDelayDuringLoading") {
+ double p = q->property("_q_RepaintThrottlingMaxDeferredRepaintDelayDuringLoading").toDouble();
+ FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(p);
+ } else if (event->propertyName() == "_q_RepaintThrottlingDeferredRepaintDelayIncrementDuringLoading") {
+ double p = q->property("_q_RepaintThrottlingDeferredRepaintDelayIncrementDuringLoading").toDouble();
+ FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(p);
+ } else if (event->propertyName() == "_q_RepaintThrottlingPreset") {
+ static const QRepaintThrottlingPreset presets[] = {
+ { "NoThrottling", 0, 0, 0, 0 },
+ { "Legacy", 0.025, 0, 2.5, 0.5 },
+ { "Minimal", 0.01, 0, 1, 0.2 },
+ { "Medium", 0.025, 1, 5, 0.5 },
+ { "Heavy", 0.1, 2, 10, 1 }
+ };
+
+ QString p = q->property("_q_RepaintThrottlingPreset").toString();
+ for(int i = 0; i < sizeof(presets) / sizeof(presets[0]); i++) {
+ if(p == presets[i].name) {
+ FrameView::setRepaintThrottlingDeferredRepaintDelay(
+ presets[i].deferredRepaintDelay);
+ FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(
+ presets[i].initialDeferredRepaintDelayDuringLoading);
+ FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(
+ presets[i].maxDeferredRepaintDelayDuringLoading);
+ FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(
+ presets[i].deferredRepaintDelayIncrementDuringLoading);
+ break;
+ }
+ }
+ }
#if ENABLE(TILED_BACKING_STORE)
else if (event->propertyName() == "_q_TiledBackingStoreTileSize") {
WebCore::Frame* frame = QWebFramePrivate::core(q->mainFrame());
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp
index a5fc794..47b4f3b 100644
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp
@@ -245,6 +245,10 @@ void QWebSettingsPrivate::apply()
settings->setTiledBackingStoreEnabled(value);
#endif
+ value = attributes.value(QWebSettings::SiteSpecificQuirksEnabled,
+ global->attributes.value(QWebSettings::SiteSpecificQuirksEnabled));
+ settings->setNeedsSiteSpecificQuirks(value);
+
settings->setUsesPageCache(WebCore::pageCache()->capacity());
} else {
QList<QWebSettingsPrivate*> settings = *::allSettings();
@@ -426,6 +430,8 @@ QWebSettings* QWebSettings::globalSettings()
and at other times scrolling the page itself. For this reason iframes and framesets are
barely usable on touch devices. This will flatten all the frames to become one scrollable page.
This is disabled by default.
+ \value SiteSpecificQuirksEnabled This setting enables WebKit's workaround for broken sites. It is
+ enabled by default.
*/
/*!
@@ -461,6 +467,7 @@ QWebSettings::QWebSettings()
d->attributes.insert(QWebSettings::AcceleratedCompositingEnabled, true);
d->attributes.insert(QWebSettings::TiledBackingStoreEnabled, false);
d->attributes.insert(QWebSettings::FrameFlatteningEnabled, false);
+ d->attributes.insert(QWebSettings::SiteSpecificQuirksEnabled, true);
d->offlineStorageDefaultQuota = 5 * 1024 * 1024;
d->defaultTextEncoding = QLatin1String("iso-8859-1");
}
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.h b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.h
index b978f5e..207a9b6 100644
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.h
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.h
@@ -73,7 +73,8 @@ public:
SpatialNavigationEnabled,
LocalContentCanAccessFileUrls,
TiledBackingStoreEnabled,
- FrameFlatteningEnabled
+ FrameFlatteningEnabled,
+ SiteSpecificQuirksEnabled
};
enum WebGraphic {
MissingImageGraphic,
diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog
index 671acec..475d22d 100644
--- a/src/3rdparty/webkit/WebKit/qt/ChangeLog
+++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog
@@ -1,3 +1,40 @@
+2010-06-17 Mark Brand <mabrand@mabrand.nl>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] use "win32-g++*" scope to match all MinGW makespecs
+
+ The scope "win32-g++" comes from the name of the makespec. However, it
+ is frequently used to check for MinGW. This works fine as long as
+ win32-g++ is the only makespec for MinGW. Now we need the wildcard
+ to cover "win32-g++-cross" as well.
+
+ * Api/DerivedSources.pro:
+
+2010-05-28 Viatcheslav Ostapenko <ostapenko.viatcheslav@nokia.com>
+
+ Reviewed by Simon Hausmann, Antti Koivisto
+
+ [Qt] Add internal Qt Api to configure repaint throttling parameters.
+ https://bugs.webkit.org/show_bug.cgi?id=38401
+
+ * Api/qwebpage.cpp:
+ (QWebPagePrivate::dynamicPropertyChangeEvent):
+
+2010-06-12 Dawit Alemayehu <adawit@kde.org>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Added an attribute to enable/disable site specific quirks mode in WebKit.
+ The attribute is enabled by default.
+
+ https://bugs.webkit.org/show_bug.cgi?id=40073
+
+ * Api/qwebsettings.cpp:
+ (QWebSettingsPrivate::apply):
+ (QWebSettings::QWebSettings):
+ * Api/qwebsettings.h:
+
2010-06-09 Pierre Rossi <pierre.rossi@nokia.com>
Reviewed by Kenneth Rohde Christiansen.