bug 654352 - document.caretPositionFromPoint API r=roc,smaug

This commit is contained in:
Brad Lassey 2011-08-18 16:54:34 -04:00
parent eb0c0c8650
commit 0ff9802473
11 changed files with 302 additions and 1 deletions

View File

@ -95,6 +95,7 @@ CPPSRCS = \
nsDOMAttribute.cpp \
nsDOMAttributeMap.cpp \
nsDOMBlobBuilder.cpp \
nsDOMCaretPosition.cpp \
nsDOMDocumentType.cpp \
nsDOMEventTargetWrapperCache.cpp \
nsDOMFile.cpp \

View File

@ -0,0 +1,77 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org.
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brad Lassey <blassey@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsDOMCaretPosition.h"
#include "nsDOMClassInfoID.h"
#include "nsIDOMClassInfo.h"
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMCaretPosition)
NS_INTERFACE_MAP_ENTRY(nsIDOMCaretPosition)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMCaretPosition)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CaretPosition)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_1(nsDOMCaretPosition, mNode)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMCaretPosition)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMCaretPosition)
DOMCI_DATA(CaretPosition, nsDOMCaretPosition)
nsDOMCaretPosition::nsDOMCaretPosition(nsIDOMNode* aNode, PRUint32 aOffset)
: mNode(aNode), mOffset(aOffset)
{
}
nsDOMCaretPosition::~nsDOMCaretPosition()
{
}
NS_IMETHODIMP nsDOMCaretPosition::GetOffsetNode(nsIDOMNode** aOffsetNode)
{
nsCOMPtr<nsIDOMNode> node = mNode;
node.forget(aOffsetNode);
return NS_OK;
}
NS_IMETHODIMP nsDOMCaretPosition::GetOffset(PRUint32* aOffset)
{
*aOffset = mOffset;
return NS_OK;
}

View File

@ -0,0 +1,59 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org.
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brad Lassey <blassey@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsDOMCaretPosition_h
#define nsDOMCaretPosition_h
#include "nsIDOMCaretPosition.h"
#include "nsCycleCollectionParticipant.h"
#include "nsCOMPtr.h"
class nsDOMCaretPosition : public nsIDOMCaretPosition
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(nsDOMCaretPosition)
NS_DECL_NSIDOMCARETPOSITION
nsDOMCaretPosition(nsIDOMNode* aNode, PRUint32 aOffset);
protected:
virtual ~nsDOMCaretPosition();
PRUint32 mOffset;
nsCOMPtr<nsIDOMNode> mNode;
};
#endif

View File

@ -202,9 +202,13 @@
#include "nsDOMTouchEvent.h"
#include "mozilla/Preferences.h"
#include "nsFrame.h"
#include "imgILoader.h"
#include "nsDOMCaretPosition.h"
#include "nsIDOMHTMLTextAreaElement.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -8394,6 +8398,58 @@ nsDocument::CreateTouchList(nsIVariant* aPoints,
return NS_OK;
}
NS_IMETHODIMP
nsDocument::CaretPositionFromPoint(float aX, float aY, nsIDOMCaretPosition** aCaretPos)
{
NS_ENSURE_ARG_POINTER(aCaretPos);
*aCaretPos = nsnull;
nscoord x = nsPresContext::CSSPixelsToAppUnits(aX);
nscoord y = nsPresContext::CSSPixelsToAppUnits(aY);
nsPoint pt(x, y);
nsIPresShell *ps = GetShell();
if (!ps) {
return NS_OK;
}
nsIFrame *rootFrame = ps->GetRootFrame();
// XUL docs, unlike HTML, have no frame tree until everything's done loading
if (!rootFrame) {
return NS_OK; // return null to premature XUL callers as a reminder to wait
}
nsIFrame *ptFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, pt, PR_TRUE,
PR_FALSE);
if (!ptFrame) {
return NS_OK;
}
nsFrame::ContentOffsets offsets = ptFrame->GetContentOffsetsFromPoint(pt);
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(offsets.content);
nsIContent* ptContent = offsets.content;
PRInt32 offset = offsets.offset;
if (ptContent && ptContent->IsInNativeAnonymousSubtree()) {
nsIContent* nonanon = ptContent->FindFirstNonNativeAnonymous();
nsCOMPtr<nsIDOMHTMLInputElement> input = do_QueryInterface(nonanon);
nsCOMPtr<nsIDOMHTMLTextAreaElement> textArea = do_QueryInterface(nonanon);
PRBool isText;
if (textArea || (input &&
NS_SUCCEEDED(input->MozIsTextField(PR_FALSE, &isText)) &&
isText)) {
node = do_QueryInterface(nonanon);
} else {
node = nsnull;
offset = 0;
}
}
*aCaretPos = new nsDOMCaretPosition(node, offset);
NS_ADDREF(*aCaretPos);
return NS_OK;
}
PRInt64
nsIDocument::SizeOf() const
{

View File

@ -503,6 +503,7 @@ _TEST_FILES2 = \
test_bug666604.html \
test_bug675121.html \
file_bug675121.sjs \
test_bug654352.html \
$(NULL)
_CHROME_FILES = \

View File

@ -0,0 +1,50 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=654352
-->
<head>
<title>Test for Bug 654352</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=654352">Mozilla Bug 654352</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 654352 **/
SimpleTest.waitForExplicitFinish();
function afterLoad() {
var testpre = document.getElementById("testpre");
var rect1 = testpre.getBoundingClientRect();
dump(rect1 + "\n");
var caret1 = document.caretPositionFromPoint(rect1.left + 30, rect1.top + 10);
ok(caret1.offsetNode == testpre.firstChild, "node in CaretPosition not correct (" + caret1.offsetNode + " == " + testpre.firstChild + ")")
ok(caret1.offset == 5, "offset in CaretPosition not correct (" + caret1.offset + "== 5)")
var testinput = document.getElementById("testinput");
var rect2 = testinput.getBoundingClientRect();
dump(rect2.top +", " + rect2.left + "\n");
var caret2 = document.caretPositionFromPoint( rect2.left + 30, rect2.top + 10);
ok(caret2.offsetNode == testinput, "node in CaretPosition not correct (" + caret2.offsetNode + " == " + testinput + ")")
ok(caret2.offset == 6, "offset in CaretPosition not correct (" + caret2.offset + "== 6)")
SimpleTest.finish();
};
addLoadEvent(afterLoad);
</script>
</pre>
<span id="testdiv">
<pre id="testpre">test text</pre>
</span>
<br>
<br>
</div>
<input id="testinput" type="text" value="test text"></input>
</div>
</body>
</html>

View File

@ -95,6 +95,7 @@
#include "nsIDOMGlobalPropertyInitializer.h"
#include "mozilla/Preferences.h"
#include "nsLocation.h"
#include "nsIDOMCaretPosition.h"
// Window scriptable helper includes
#include "nsIDocShell.h"
@ -665,6 +666,9 @@ static nsDOMClassInfoData sClassInfoData[] = {
(DOM_DEFAULT_SCRIPTABLE_FLAGS &
~nsIXPCScriptable::ALLOW_PROP_MODS_TO_PROTOTYPE))
NS_DEFINE_CLASSINFO_DATA(CaretPosition, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(Navigator, nsNavigatorSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS |
nsIXPCScriptable::WANT_PRECREATE)
@ -2280,6 +2284,10 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMLocation)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(CaretPosition, nsIDOMCaretPosition)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMCaretPosition)
DOM_CLASSINFO_MAP_END
if (nsNavigator::HasDesktopNotificationSupport()) {
DOM_CLASSINFO_MAP_BEGIN(Navigator, nsIDOMNavigator)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigator)

View File

@ -38,6 +38,7 @@
DOMCI_CLASS(Window)
DOMCI_CLASS(Location)
DOMCI_CLASS(CaretPosition)
DOMCI_CLASS(Navigator)
DOMCI_CLASS(Plugin)
DOMCI_CLASS(PluginArray)

View File

@ -48,6 +48,7 @@ GRE_MODULE = 1
SDK_XPIDLSRCS = \
nsIDOMAttr.idl \
nsIDOMCaretPosition.idl \
nsIDOMCDATASection.idl \
nsIDOMCharacterData.idl \
nsIDOMComment.idl \

View File

@ -0,0 +1,44 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org.
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brad Lassey <blassey@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsIDOMNode.idl"
[scriptable, uuid(cf5ad6cf-6f49-4ca7-9b50-590d7bb27a13)]
interface nsIDOMCaretPosition : nsISupports {
readonly attribute nsIDOMNode offsetNode;
readonly attribute unsigned long offset;
};

View File

@ -48,6 +48,7 @@ interface nsIDOMNodeIterator;
interface nsIDOMNodeFilter;
interface nsIDOMTreeWalker;
interface nsIDOMLocation;
interface nsIDOMCaretPosition;
/**
* The nsIDOMDocument interface represents the entire HTML or XML document.
@ -62,7 +63,7 @@ interface nsIDOMLocation;
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
*/
[scriptable, uuid(10034b87-384e-4e19-902c-c4edafb899be)]
[scriptable, uuid(d19897dc-948a-42e7-8ac6-d8a0bd141b85)]
interface nsIDOMDocument : nsIDOMNode
{
readonly attribute nsIDOMDocumentType doctype;
@ -368,4 +369,6 @@ interface nsIDOMDocument : nsIDOMNode
*/
void mozSetImageElement(in DOMString aImageElementId,
in nsIDOMElement aImageElement);
nsIDOMCaretPosition caretPositionFromPoint(in float x, in float y);
};