Commit 628cb2cd authored by weinig@apple.com's avatar weinig@apple.com

WebCore: Fix for https://bugs.webkit.org/show_bug.cgi?id=27046

Implement CSSOM DocumentView.caretRangeFromPoint

Reviewed by Timothy Hatcher.

Tests: fast/dom/Document/CaretRangeFromPoint/basic.html
       fast/dom/Document/CaretRangeFromPoint/replace-element.html

* dom/Document.cpp:
(WebCore::Document::caretRangeFromPoint):
* dom/Document.h:
* dom/Document.idl:

LayoutTests: Test for https://bugs.webkit.org/show_bug.cgi?id=27046
Implement CSSOM DocumentView.caretRangeFromPoint

Reviewed by Timothy Hatcher.

* fast/dom/Document/CaretRangeFromPoint: Added.
* fast/dom/Document/CaretRangeFromPoint/basic-expected.txt: Added.
* fast/dom/Document/CaretRangeFromPoint/basic.html: Added.
* fast/dom/Document/CaretRangeFromPoint/replace-element-expected.txt: Added.
* fast/dom/Document/CaretRangeFromPoint/replace-element.html: Added.
* fast/dom/Window/window-properties-expected.txt:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@48188 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 7c91c357
2009-09-08 Sam Weinig <sam@webkit.org>
Reviewed by Timothy Hatcher.
Test for https://bugs.webkit.org/show_bug.cgi?id=27046
Implement CSSOM DocumentView.caretRangeFromPoint
* fast/dom/Document/CaretRangeFromPoint: Added.
* fast/dom/Document/CaretRangeFromPoint/basic-expected.txt: Added.
* fast/dom/Document/CaretRangeFromPoint/basic.html: Added.
* fast/dom/Document/CaretRangeFromPoint/replace-element-expected.txt: Added.
* fast/dom/Document/CaretRangeFromPoint/replace-element.html: Added.
* fast/dom/Window/window-properties-expected.txt:
2009-09-08 Brian Weinstein <bweinstein@apple.com>
Rubber-stamped by Adam Roben.
......
Testing upper left
PASS: range.startContainer == element.firstChild.
PASS: range.startOffset == 0.
Testing upper right
PASS: range.startContainer == element.firstChild.
PASS: range.startOffset == 23.
Testing lower left
PASS: range.startContainer == element.firstChild.
PASS: range.startOffset == 72.
Testing lower right
PASS: range.startContainer == element.firstChild.
PASS: range.startOffset == 95.
Testing somewhere in the middle
PASS: range.startContainer == element.firstChild.
PASS: range.startOffset == 36.
Testing negative values
PASS: range is null.
PASS: range is null.
PASS: range is null.
Testing values larger than the viewport
PASS: range is null.
PASS: range is null.
PASS: range is null.
<html>
<head>
<style>
#test {
width: 400px;
font-family: "Ahem";
}
</style>
<script>
if (window.layoutTestController)
layoutTestController.dumpAsText();
var _log = "";
function log(msg)
{
_log += msg + "\n";
}
function swapInLog()
{
var element = document.getElementById('test');
var parent = element.parentNode;
parent.removeChild(element);
var console = document.createElement("pre");
console.textContent = _log;
parent.appendChild(console);
}
var element;
function test(x, y, __expectedContainer, __expectedOffset)
{
var expectedContainer = eval(__expectedContainer);
var expectedOffset = eval(__expectedOffset);
var range = document.caretRangeFromPoint(x, y);
if (range.startContainer == expectedContainer) {
log("PASS: range.startContainer == " + __expectedContainer + ".");
} else {
log("FAIL: range.startContainer == " + range.startContainer + ".");
}
if (range.startOffset == expectedOffset) {
log("PASS: range.startOffset == " + __expectedOffset + ".");
} else {
log("FAIL: range.startOffset == " + range.startOffset + ".");
}
}
function shouldBeNull(x, y)
{
var range = document.caretRangeFromPoint(x, y);
if (range === null) {
log("PASS: range is null.");
} else {
log("FAIL: range is not null.");
}
}
window.onload = function()
{
element = document.getElementById('test');
text = element.firstChild;
var rect = element.getBoundingClientRect();
log("Testing upper left");
test(rect.left, rect.top, "element.firstChild", "0");
log("Testing upper right");
test(rect.left + rect.width, rect.top, "element.firstChild", "23");
log("Testing lower left");
test(rect.left, rect.top + rect.height, "element.firstChild", "72");
log("Testing lower right");
test(rect.left + rect.width, rect.top + rect.height, "element.firstChild", "95");
log("Testing somewhere in the middle");
test((rect.left + rect.width) / 2, (rect.top + rect.height) / 2, "element.firstChild", "36");
log("Testing negative values");
shouldBeNull(-10, 10);
shouldBeNull(10, -10);
shouldBeNull(-10, -10);
log("Testing values larger than the viewport");
shouldBeNull(window.innerWidth + 100, 10);
shouldBeNull(10, window.innerHeight + 100);
shouldBeNull(window.innerWidth + 100, window.innerHeight + 100);
swapInLog();
}
</script>
</head>
<body>
<div id="test">xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx</div>
</body>
</html>
Testing left of the image
PASS: range.startContainer == image.previousSibling.
PASS: range.startOffset == 34.
Testing right of the image
PASS: range.startContainer == image.nextSibling.
PASS: range.startOffset == 1.
Testing on the image
PASS: range.startContainer == image.previousSibling.
PASS: range.startOffset == 35.
<html>
<head>
<style>
#test {
width: 400px;
font-family: "Ahem";
}
</style>
<script>
if (window.layoutTestController)
layoutTestController.dumpAsText();
var _log = "";
function log(msg)
{
_log += msg + "\n";
}
function swapInLog()
{
var element = document.getElementById('test');
var parent = element.parentNode;
parent.removeChild(element);
var console = document.createElement("pre");
console.textContent = _log;
parent.appendChild(console);
}
var element;
var image;
function test(x, y, __expectedContainer, __expectedOffset)
{
var expectedContainer = eval(__expectedContainer);
var expectedOffset = eval(__expectedOffset);
var range = document.caretRangeFromPoint(x, y);
if (range.startContainer == expectedContainer) {
log("PASS: range.startContainer == " + __expectedContainer + ".");
} else {
log("FAIL: range.startContainer == " + range.startContainer + ".");
}
if (range.startOffset == expectedOffset) {
log("PASS: range.startOffset == " + __expectedOffset + ".");
} else {
log("FAIL: range.startOffset == " + range.startOffset + ".");
}
}
window.onload = function()
{
element = document.getElementById('test');
image = document.getElementById('image');
var rect = element.getBoundingClientRect();
var imageRect = image.getBoundingClientRect();
log("Testing left of the image");
test(imageRect.left - 10, (imageRect.top + imageRect.height) - 5, "image.previousSibling", "34");
log("Testing right of the image");
test((imageRect.left + imageRect.width) + 10, (imageRect.top + imageRect.height) - 5, "image.nextSibling", "1");
log("Testing on the image");
test((imageRect.left + (imageRect.width / 2)) , (imageRect.top + imageRect.height) - 5, "image.previousSibling", "35");
swapInLog();
}
</script>
</head>
<body>
<div id="test">xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx<img id="image" src="../../resources/abe.png">xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx</div>
</body>
</html>
......@@ -539,6 +539,7 @@ window.Document.prototype.TEXT_NODE [number]
window.Document.prototype.addEventListener [function]
window.Document.prototype.adoptNode [function]
window.Document.prototype.appendChild [function]
window.Document.prototype.caretRangeFromPoint [function]
window.Document.prototype.cloneNode [function]
window.Document.prototype.compareDocumentPosition [function]
window.Document.prototype.createAttribute [function]
......
2009-09-08 Sam Weinig <sam@webkit.org>
Reviewed by Timothy Hatcher.
Fix for https://bugs.webkit.org/show_bug.cgi?id=27046
Implement CSSOM DocumentView.caretRangeFromPoint
Tests: fast/dom/Document/CaretRangeFromPoint/basic.html
fast/dom/Document/CaretRangeFromPoint/replace-element.html
* dom/Document.cpp:
(WebCore::Document::caretRangeFromPoint):
* dom/Document.h:
* dom/Document.idl:
2009-09-08 Kevin Ollivier <kevino@theolliviers.com>
wx build fix, generate derived sources earlier in order to make sure
......@@ -110,11 +110,6 @@
#include "SegmentedString.h"
#include "SelectionController.h"
#include "Settings.h"
#if ENABLE(SHARED_WORKERS)
#include "SharedWorkerRepository.h"
#endif
#include "StyleSheetList.h"
#include "TextEvent.h"
#include "TextIterator.h"
......@@ -128,6 +123,7 @@
#include "XMLHttpRequest.h"
#include "XMLNames.h"
#include "XMLTokenizer.h"
#include "htmlediting.h"
#include <wtf/CurrentTime.h>
#include <wtf/HashFunctions.h>
#include <wtf/MainThread.h>
......@@ -139,6 +135,10 @@
#include "DatabaseThread.h"
#endif
#if ENABLE(SHARED_WORKERS)
#include "SharedWorkerRepository.h"
#endif
#if ENABLE(DOM_STORAGE)
#include "StorageEvent.h"
#endif
......@@ -943,6 +943,49 @@ Element* Document::elementFromPoint(int x, int y) const
return static_cast<Element*>(n);
}
PassRefPtr<Range> Document::caretRangeFromPoint(int x, int y)
{
if (!renderer())
return 0;
Frame* frame = this->frame();
if (!frame)
return 0;
float zoomFactor = frame->pageZoomFactor();
IntPoint point = roundedIntPoint(FloatPoint(x * zoomFactor, y * zoomFactor));
FrameView* frameView = frame->view();
if (!frameView)
return 0;
if (!frameView->boundsRect().contains(point))
return 0;
HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
HitTestResult result(point);
renderView()->layer()->hitTest(request, result);
Node* node = result.innerNode();
if (!node)
return 0;
Node* shadowAncestorNode = node->shadowAncestorNode();
if (shadowAncestorNode != node) {
unsigned offset = shadowAncestorNode->nodeIndex();
Node* container = shadowAncestorNode->parentNode();
return Range::create(this, container, offset, container, offset);
}
RenderObject* renderer = node->renderer();
if (!renderer)
return 0;
VisiblePosition visiblePosition = renderer->positionForPoint(result.localPoint());
if (visiblePosition.isNull())
return 0;
Position rangeCompliantPosition = rangeCompliantEquivalent(visiblePosition);
return Range::create(this, rangeCompliantPosition, rangeCompliantPosition);
}
void Document::addElementById(const AtomicString& elementId, Element* element)
{
typedef HashMap<AtomicStringImpl*, Element*>::iterator iterator;
......
......@@ -228,6 +228,8 @@ public:
bool containsMultipleElementsWithId(const AtomicString& elementId) { return m_duplicateIds.contains(elementId.impl()); }
Element* elementFromPoint(int x, int y) const;
PassRefPtr<Range> caretRangeFromPoint(int x, int y);
String readyState() const;
String defaultCharset() const;
......
......@@ -191,6 +191,7 @@ module core {
readonly attribute [ConvertNullStringTo=Undefined] DOMString readyState;
Element elementFromPoint(in long x, in long y);
Range caretRangeFromPoint(in long x, in long y);
// Mozilla extensions
#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment