1998-09-06 00:16:36 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
*
|
1999-11-06 03:40:37 +00:00
|
|
|
* The contents of this file are subject to the Netscape 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/NPL/
|
1998-09-06 00:16:36 +00:00
|
|
|
*
|
1999-11-06 03:40:37 +00:00
|
|
|
* 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.
|
1998-09-06 00:16:36 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Mozilla Communicator client code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape Communications
|
1999-11-06 03:40:37 +00:00
|
|
|
* Corporation. Portions created by Netscape are
|
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
|
|
* Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
1998-09-06 00:16:36 +00:00
|
|
|
*/
|
1998-09-06 04:16:22 +00:00
|
|
|
#include "nsGenericDOMDataNode.h"
|
1999-01-14 23:14:02 +00:00
|
|
|
#include "nsGenericElement.h"
|
1999-01-21 19:33:03 +00:00
|
|
|
#include "nsIDocument.h"
|
1998-09-06 00:16:36 +00:00
|
|
|
#include "nsIEventListenerManager.h"
|
|
|
|
#include "nsIDocument.h"
|
1998-12-17 07:22:28 +00:00
|
|
|
#include "nsIDOMRange.h"
|
1999-01-21 19:33:03 +00:00
|
|
|
#include "nsIDOMDocument.h"
|
|
|
|
#include "nsIDOMDocumentFragment.h"
|
2000-05-13 08:07:34 +00:00
|
|
|
#include "nsIXIFConverter.h"
|
1999-01-03 14:29:54 +00:00
|
|
|
#include "nsRange.h"
|
1999-10-21 20:40:51 +00:00
|
|
|
#include "nsTextContentChangeData.h"
|
1999-02-11 23:12:28 +00:00
|
|
|
#include "nsIDOMSelection.h"
|
1999-01-21 21:45:17 +00:00
|
|
|
#include "nsIEnumerator.h"
|
2000-08-23 17:27:06 +00:00
|
|
|
#include "nsReadableUtils.h"
|
1999-01-21 21:45:17 +00:00
|
|
|
|
1998-09-06 00:16:36 +00:00
|
|
|
#include "nsCRT.h"
|
|
|
|
#include "nsIEventStateManager.h"
|
|
|
|
#include "nsIPrivateDOMEvent.h"
|
|
|
|
#include "nsISizeOfHandler.h"
|
|
|
|
#include "nsDOMEvent.h"
|
1999-03-31 20:49:25 +00:00
|
|
|
#include "nsIDOMText.h"
|
1998-09-10 17:11:46 +00:00
|
|
|
#include "nsIDOMScriptObjectFactory.h"
|
1999-12-03 09:24:22 +00:00
|
|
|
#include "nsIScriptGlobalObject.h"
|
1998-09-29 22:34:30 +00:00
|
|
|
#include "prprf.h"
|
1999-01-21 21:45:17 +00:00
|
|
|
#include "nsCOMPtr.h"
|
1998-09-06 00:16:36 +00:00
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
1998-09-06 04:16:22 +00:00
|
|
|
nsGenericDOMDataNode::nsGenericDOMDataNode()
|
1998-10-20 00:20:04 +00:00
|
|
|
: mText()
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
|
|
|
mDocument = nsnull;
|
|
|
|
mParent = nsnull;
|
|
|
|
mScriptObject = nsnull;
|
|
|
|
mListenerManager = nsnull;
|
1998-12-17 07:22:28 +00:00
|
|
|
mRangeList = nsnull;
|
1999-03-28 22:22:54 +00:00
|
|
|
mCapturer = nsnull;
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
|
1998-09-06 04:16:22 +00:00
|
|
|
nsGenericDOMDataNode::~nsGenericDOMDataNode()
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
2000-05-16 11:35:12 +00:00
|
|
|
if (mListenerManager) {
|
|
|
|
mListenerManager->SetListenerTarget(nsnull);
|
|
|
|
NS_RELEASE(mListenerManager);
|
|
|
|
}
|
1998-12-17 07:22:28 +00:00
|
|
|
delete mRangeList;
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-08-23 17:27:06 +00:00
|
|
|
nsGenericDOMDataNode::GetNodeValue(nsAWritableString& aNodeValue)
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
1999-01-21 19:33:03 +00:00
|
|
|
return GetData(aNodeValue);
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-03-22 01:23:42 +00:00
|
|
|
nsGenericDOMDataNode::SetNodeValue(nsIContent *aOuterContent,
|
2000-08-23 17:27:06 +00:00
|
|
|
const nsAReadableString& aNodeValue)
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
2000-03-22 01:23:42 +00:00
|
|
|
return SetData(aOuterContent, aNodeValue);
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1998-09-06 04:16:22 +00:00
|
|
|
nsGenericDOMDataNode::GetParentNode(nsIDOMNode** aParentNode)
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
1999-04-17 00:56:25 +00:00
|
|
|
nsresult res = NS_OK;
|
|
|
|
|
1998-09-06 00:16:36 +00:00
|
|
|
if (nsnull != mParent) {
|
2000-09-09 05:46:14 +00:00
|
|
|
res = mParent->QueryInterface(NS_GET_IID(nsIDOMNode), (void**)aParentNode);
|
1998-09-06 00:16:36 +00:00
|
|
|
NS_ASSERTION(NS_OK == res, "Must be a DOM Node");
|
|
|
|
}
|
1999-01-21 19:33:03 +00:00
|
|
|
else if (nsnull == mDocument) {
|
1999-04-17 00:56:25 +00:00
|
|
|
*aParentNode = nsnull;
|
1999-01-21 19:33:03 +00:00
|
|
|
}
|
1998-09-06 00:16:36 +00:00
|
|
|
else {
|
1999-01-21 19:33:03 +00:00
|
|
|
// If we don't have a parent, but we're in the document, we must
|
1999-04-17 00:56:25 +00:00
|
|
|
// be the root node of the document. The DOM says that the root
|
|
|
|
// is the document.
|
2000-09-09 05:46:14 +00:00
|
|
|
res = mDocument->QueryInterface(NS_GET_IID(nsIDOMNode), (void**)aParentNode);
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
1999-04-17 00:56:25 +00:00
|
|
|
|
|
|
|
return res;
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-03-22 01:23:42 +00:00
|
|
|
nsGenericDOMDataNode::GetPreviousSibling(nsIContent *aOuterContent,
|
|
|
|
nsIDOMNode** aPrevSibling)
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
1999-03-31 20:49:25 +00:00
|
|
|
nsIContent* sibling = nsnull;
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
1998-09-06 00:16:36 +00:00
|
|
|
if (nsnull != mParent) {
|
|
|
|
PRInt32 pos;
|
2000-03-22 01:23:42 +00:00
|
|
|
mParent->IndexOf(aOuterContent, pos);
|
1999-03-31 20:49:25 +00:00
|
|
|
if (pos > -1 ) {
|
|
|
|
mParent->ChildAt(--pos, sibling);
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
}
|
1999-03-31 20:49:25 +00:00
|
|
|
else if (nsnull != mDocument) {
|
|
|
|
// Nodes that are just below the document (their parent is the
|
|
|
|
// document) need to go to the document to find their next sibling.
|
|
|
|
PRInt32 pos;
|
2000-03-22 01:23:42 +00:00
|
|
|
mDocument->IndexOf(aOuterContent, pos);
|
1999-03-31 20:49:25 +00:00
|
|
|
if (pos > -1 ) {
|
|
|
|
mDocument->ChildAt(--pos, sibling);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nsnull != sibling) {
|
2000-09-09 05:46:14 +00:00
|
|
|
result = sibling->QueryInterface(NS_GET_IID(nsIDOMNode),(void**)aPrevSibling);
|
1999-03-31 20:49:25 +00:00
|
|
|
NS_ASSERTION(NS_OK == result, "Must be a DOM Node");
|
|
|
|
NS_RELEASE(sibling); // balance the AddRef in ChildAt()
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aPrevSibling = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-03-22 01:23:42 +00:00
|
|
|
nsGenericDOMDataNode::GetNextSibling(nsIContent *aOuterContent,
|
|
|
|
nsIDOMNode** aNextSibling)
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
1999-03-31 20:49:25 +00:00
|
|
|
nsIContent* sibling = nsnull;
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
1998-09-06 00:16:36 +00:00
|
|
|
if (nsnull != mParent) {
|
|
|
|
PRInt32 pos;
|
2000-03-22 01:23:42 +00:00
|
|
|
mParent->IndexOf(aOuterContent, pos);
|
1998-09-06 00:16:36 +00:00
|
|
|
if (pos > -1 ) {
|
1999-03-31 20:49:25 +00:00
|
|
|
mParent->ChildAt(++pos, sibling);
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
}
|
1999-03-31 20:49:25 +00:00
|
|
|
else if (nsnull != mDocument) {
|
|
|
|
// Nodes that are just below the document (their parent is the
|
|
|
|
// document) need to go to the document to find their next sibling.
|
|
|
|
PRInt32 pos;
|
2000-03-22 01:23:42 +00:00
|
|
|
mDocument->IndexOf(aOuterContent, pos);
|
1999-03-31 20:49:25 +00:00
|
|
|
if (pos > -1 ) {
|
|
|
|
mDocument->ChildAt(++pos, sibling);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nsnull != sibling) {
|
2000-09-09 05:46:14 +00:00
|
|
|
result = sibling->QueryInterface(NS_GET_IID(nsIDOMNode),(void**)aNextSibling);
|
1999-03-31 20:49:25 +00:00
|
|
|
NS_ASSERTION(NS_OK == result, "Must be a DOM Node");
|
|
|
|
NS_RELEASE(sibling); // balance the AddRef in ChildAt()
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aNextSibling = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
|
1999-08-25 07:35:45 +00:00
|
|
|
nsresult
|
|
|
|
nsGenericDOMDataNode::GetChildNodes(nsIDOMNodeList** aChildNodes)
|
|
|
|
{
|
|
|
|
// XXX Since we believe this won't be done very often, we won't
|
|
|
|
// burn another slot in the data node and just create a new
|
|
|
|
// (empty) childNodes list every time we're asked.
|
|
|
|
nsChildContentList* list = new nsChildContentList(nsnull);
|
|
|
|
if (nsnull == list) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
|
2000-09-09 05:46:14 +00:00
|
|
|
return list->QueryInterface(NS_GET_IID(nsIDOMNodeList), (void**)aChildNodes);
|
1999-08-25 07:35:45 +00:00
|
|
|
}
|
|
|
|
|
1998-10-20 17:07:23 +00:00
|
|
|
nsresult
|
|
|
|
nsGenericDOMDataNode::GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
|
|
|
|
{
|
|
|
|
// XXX Actually the owner document is the document in whose context
|
|
|
|
// the node has been created. We should be able to get at it
|
|
|
|
// whether or not we are attached to the document.
|
|
|
|
if (nsnull != mDocument) {
|
2000-09-09 05:46:14 +00:00
|
|
|
return mDocument->QueryInterface(NS_GET_IID(nsIDOMDocument), (void **)aOwnerDocument);
|
1998-10-20 17:07:23 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aOwnerDocument = nsnull;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-04-01 13:31:23 +00:00
|
|
|
nsresult
|
2000-08-23 17:27:06 +00:00
|
|
|
nsGenericDOMDataNode::GetNamespaceURI(nsAWritableString& aNamespaceURI)
|
2000-04-01 13:31:23 +00:00
|
|
|
{
|
2000-06-23 00:21:32 +00:00
|
|
|
aNamespaceURI.Truncate();
|
2000-04-01 13:31:23 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-08-23 17:27:06 +00:00
|
|
|
nsGenericDOMDataNode::GetPrefix(nsAWritableString& aPrefix)
|
2000-04-01 13:31:23 +00:00
|
|
|
{
|
2000-06-23 00:21:32 +00:00
|
|
|
aPrefix.Truncate();
|
2000-04-01 13:31:23 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-08-23 17:27:06 +00:00
|
|
|
nsGenericDOMDataNode::SetPrefix(const nsAReadableString& aPrefix)
|
2000-04-01 13:31:23 +00:00
|
|
|
{
|
|
|
|
return NS_ERROR_DOM_NAMESPACE_ERR;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericDOMDataNode::Normalize()
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-09-14 05:19:00 +00:00
|
|
|
nsGenericDOMDataNode::IsSupported(const nsAReadableString& aFeature,
|
|
|
|
const nsAReadableString& aVersion,
|
|
|
|
PRBool* aReturn)
|
2000-04-01 13:31:23 +00:00
|
|
|
{
|
2000-09-14 05:19:00 +00:00
|
|
|
return nsGenericElement::InternalIsSupported(aFeature, aVersion, aReturn);
|
2000-04-01 13:31:23 +00:00
|
|
|
}
|
|
|
|
|
1998-09-06 00:16:36 +00:00
|
|
|
#if 0
|
|
|
|
nsresult
|
1998-09-06 04:16:22 +00:00
|
|
|
nsGenericDOMDataNode::Equals(nsIDOMNode* aNode, PRBool aDeep, PRBool* aReturn)
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
|
|
|
*aReturn = PR_FALSE;
|
|
|
|
PRInt32 nt1, nt2;
|
|
|
|
GetNodeType(&nt1);
|
|
|
|
aNode->GetNodeType(&nt2);
|
|
|
|
if (nt1 != nt2) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
1998-10-20 17:07:23 +00:00
|
|
|
// Implementation of nsIDOMCharacterData
|
1998-09-06 00:16:36 +00:00
|
|
|
|
|
|
|
nsresult
|
2000-08-23 17:27:06 +00:00
|
|
|
nsGenericDOMDataNode::GetData(nsAWritableString& aData)
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
1998-10-20 00:20:04 +00:00
|
|
|
if (mText.Is2b()) {
|
2000-03-12 09:14:14 +00:00
|
|
|
aData.Assign(mText.Get2b(), mText.GetLength());
|
1998-10-20 00:20:04 +00:00
|
|
|
}
|
|
|
|
else {
|
2000-08-23 17:27:06 +00:00
|
|
|
aData.Assign(NS_ConvertASCIItoUCS2(mText.Get1b(), mText.GetLength()));
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-08-23 17:27:06 +00:00
|
|
|
nsGenericDOMDataNode::SetData(nsIContent *aOuterContent, const nsAReadableString& aData)
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
1999-01-03 14:29:54 +00:00
|
|
|
// inform any enclosed ranges of change
|
|
|
|
// we can lie and say we are deleting all the text, since in a total
|
|
|
|
// text replacement we should just collapse all the ranges.
|
2000-03-22 01:23:42 +00:00
|
|
|
if (mRangeList) nsRange::TextOwnerChanged(aOuterContent, 0,
|
|
|
|
mText.GetLength(), 0);
|
1998-09-06 00:16:36 +00:00
|
|
|
|
1999-08-25 07:35:45 +00:00
|
|
|
nsresult result;
|
2000-03-22 01:23:42 +00:00
|
|
|
nsCOMPtr<nsITextContent> textContent = do_QueryInterface(aOuterContent,
|
|
|
|
&result);
|
1999-08-25 07:35:45 +00:00
|
|
|
|
|
|
|
// If possible, let the container content object have a go at it.
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
2000-08-23 17:27:06 +00:00
|
|
|
result = textContent->SetText(aData, PR_TRUE);
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
1999-08-25 07:35:45 +00:00
|
|
|
else {
|
2000-08-23 17:27:06 +00:00
|
|
|
result = SetText(aOuterContent, aData, PR_TRUE);
|
1999-08-25 07:35:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1998-10-20 17:07:23 +00:00
|
|
|
nsGenericDOMDataNode::GetLength(PRUint32* aLength)
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
1998-10-20 17:07:23 +00:00
|
|
|
*aLength = mText.GetLength();
|
1998-09-06 00:16:36 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1998-10-20 17:07:23 +00:00
|
|
|
nsGenericDOMDataNode::SubstringData(PRUint32 aStart,
|
|
|
|
PRUint32 aCount,
|
2000-08-23 17:27:06 +00:00
|
|
|
nsAWritableString& aReturn)
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
|
|
|
aReturn.Truncate();
|
1998-10-20 00:20:04 +00:00
|
|
|
|
|
|
|
// XXX add <0 checks if types change
|
|
|
|
PRUint32 textLength = PRUint32( mText.GetLength() );
|
1999-10-15 22:18:23 +00:00
|
|
|
if (aStart > textLength) {
|
1999-10-06 00:06:53 +00:00
|
|
|
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
1998-10-20 00:20:04 +00:00
|
|
|
|
|
|
|
PRUint32 amount = aCount;
|
|
|
|
if (aStart + amount > textLength) {
|
|
|
|
amount = textLength - aStart;
|
|
|
|
}
|
|
|
|
if (mText.Is2b()) {
|
2000-03-12 09:14:14 +00:00
|
|
|
aReturn.Assign(mText.Get2b() + aStart, amount);
|
1998-10-20 00:20:04 +00:00
|
|
|
}
|
|
|
|
else {
|
2000-09-13 08:21:04 +00:00
|
|
|
aReturn.Assign(NS_ConvertASCIItoUCS2(mText.Get1b() + aStart, amount).get(), amount);
|
1998-10-20 00:20:04 +00:00
|
|
|
}
|
|
|
|
|
1998-09-06 00:16:36 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-10-21 20:40:51 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
1998-09-06 00:16:36 +00:00
|
|
|
nsresult
|
2000-03-22 01:23:42 +00:00
|
|
|
nsGenericDOMDataNode::AppendData(nsIContent *aOuterContent,
|
2000-08-23 17:27:06 +00:00
|
|
|
const nsAReadableString& aData)
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
1999-10-21 20:40:51 +00:00
|
|
|
#if 1
|
|
|
|
// Allocate new buffer
|
1999-11-11 01:28:32 +00:00
|
|
|
nsresult result = NS_OK;
|
2000-08-23 17:27:06 +00:00
|
|
|
PRUint32 dataLength = aData.Length();
|
1999-10-21 20:40:51 +00:00
|
|
|
PRInt32 textLength = mText.GetLength();
|
|
|
|
PRInt32 newSize = textLength + dataLength;
|
1999-11-23 23:13:03 +00:00
|
|
|
PRUnichar* to = new PRUnichar[newSize + 1];
|
1999-10-21 20:40:51 +00:00
|
|
|
if (nsnull == to) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
// XXX This is slow...
|
|
|
|
|
|
|
|
// Fill new buffer with old data and new data
|
|
|
|
if (textLength) {
|
|
|
|
mText.CopyTo(to, 0, textLength);
|
|
|
|
}
|
2000-08-23 17:27:06 +00:00
|
|
|
CopyUnicodeTo(aData, to + textLength, dataLength);
|
1999-10-21 20:40:51 +00:00
|
|
|
|
1999-11-23 23:13:03 +00:00
|
|
|
// Null terminate the new buffer...
|
|
|
|
to[newSize] = (PRUnichar)0;
|
|
|
|
|
2000-03-22 01:23:42 +00:00
|
|
|
nsCOMPtr<nsITextContent> textContent(do_QueryInterface(aOuterContent,
|
|
|
|
&result));
|
1999-11-11 01:28:32 +00:00
|
|
|
|
1999-10-21 20:40:51 +00:00
|
|
|
// Switch to new buffer
|
1999-11-11 01:28:32 +00:00
|
|
|
// Dont do notification in SetText, since we will do it later
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
result = textContent->SetText(to, newSize, PR_FALSE);
|
|
|
|
}
|
|
|
|
else {
|
2000-03-22 01:23:42 +00:00
|
|
|
result = SetText(aOuterContent, to, newSize, PR_FALSE);
|
1999-11-11 01:28:32 +00:00
|
|
|
}
|
1999-10-21 20:40:51 +00:00
|
|
|
|
|
|
|
delete [] to;
|
|
|
|
|
|
|
|
// Trigger a reflow
|
|
|
|
if (nsnull != mDocument) {
|
|
|
|
nsTextContentChangeData* tccd = nsnull;
|
1999-11-11 01:28:32 +00:00
|
|
|
result = NS_NewTextContentChangeData(&tccd);
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
1999-10-21 20:40:51 +00:00
|
|
|
tccd->SetData(nsITextContentChangeData::Append, textLength, dataLength);
|
2000-03-22 01:23:42 +00:00
|
|
|
result = mDocument->ContentChanged(aOuterContent, tccd);
|
1999-10-21 20:40:51 +00:00
|
|
|
NS_RELEASE(tccd);
|
|
|
|
}
|
|
|
|
else {
|
2000-03-22 01:23:42 +00:00
|
|
|
result = mDocument->ContentChanged(aOuterContent, nsnull);
|
1999-10-21 20:40:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-11-11 01:28:32 +00:00
|
|
|
return result;
|
1999-10-21 20:40:51 +00:00
|
|
|
#else
|
1998-10-20 17:07:23 +00:00
|
|
|
return ReplaceData(mText.GetLength(), 0, aData);
|
1999-10-21 20:40:51 +00:00
|
|
|
#endif
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-03-22 01:23:42 +00:00
|
|
|
nsGenericDOMDataNode::InsertData(nsIContent *aOuterContent, PRUint32 aOffset,
|
2000-08-23 17:27:06 +00:00
|
|
|
const nsAReadableString& aData)
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
2000-03-22 01:23:42 +00:00
|
|
|
return ReplaceData(aOuterContent, aOffset, 0, aData);
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-03-22 01:23:42 +00:00
|
|
|
nsGenericDOMDataNode::DeleteData(nsIContent *aOuterContent, PRUint32 aOffset,
|
|
|
|
PRUint32 aCount)
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
|
|
|
nsAutoString empty;
|
2000-03-22 01:23:42 +00:00
|
|
|
return ReplaceData(aOuterContent, aOffset, aCount, empty);
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-03-22 01:23:42 +00:00
|
|
|
nsGenericDOMDataNode::ReplaceData(nsIContent *aOuterContent, PRUint32 aOffset,
|
2000-08-23 17:27:06 +00:00
|
|
|
PRUint32 aCount, const nsAReadableString& aData)
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
1999-08-25 07:35:45 +00:00
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
1998-09-06 00:16:36 +00:00
|
|
|
// sanitize arguments
|
1998-10-20 00:20:04 +00:00
|
|
|
PRUint32 textLength = mText.GetLength();
|
1999-11-11 01:48:25 +00:00
|
|
|
if ((aOffset > textLength) || (aOffset < 0) || (aCount < 0)) {
|
|
|
|
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Allocate new buffer
|
1998-10-20 00:20:04 +00:00
|
|
|
PRUint32 endOffset = aOffset + aCount;
|
|
|
|
if (endOffset > textLength) {
|
|
|
|
aCount = textLength - aOffset;
|
|
|
|
endOffset = textLength;
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
PRInt32 dataLength = aData.Length();
|
1998-10-20 00:20:04 +00:00
|
|
|
PRInt32 newLength = textLength - aCount + dataLength;
|
1999-08-28 05:12:11 +00:00
|
|
|
PRUnichar* to = new PRUnichar[newLength ? newLength+1 : 1];
|
1998-09-06 00:16:36 +00:00
|
|
|
if (nsnull == to) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
|
1999-01-03 14:29:54 +00:00
|
|
|
// inform any enclosed ranges of change
|
2000-03-22 01:23:42 +00:00
|
|
|
if (mRangeList) nsRange::TextOwnerChanged(aOuterContent, aOffset,
|
|
|
|
endOffset, dataLength);
|
1999-01-03 14:29:54 +00:00
|
|
|
|
1998-09-06 00:16:36 +00:00
|
|
|
// Copy over appropriate data
|
|
|
|
if (0 != aOffset) {
|
1998-10-20 00:20:04 +00:00
|
|
|
mText.CopyTo(to, 0, aOffset);
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
if (0 != dataLength) {
|
2000-08-23 17:27:06 +00:00
|
|
|
CopyUnicodeTo(aData, to+aOffset, dataLength);
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
1998-10-20 00:20:04 +00:00
|
|
|
if (endOffset != textLength) {
|
|
|
|
mText.CopyTo(to + aOffset + dataLength, endOffset, textLength - endOffset);
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
|
1999-08-28 05:12:11 +00:00
|
|
|
// Null terminate the new buffer...
|
|
|
|
to[newLength] = (PRUnichar)0;
|
|
|
|
|
1998-09-06 00:16:36 +00:00
|
|
|
// Switch to new buffer
|
2000-03-22 01:23:42 +00:00
|
|
|
nsCOMPtr<nsITextContent> textContent(do_QueryInterface(aOuterContent,
|
|
|
|
&result));
|
1998-09-06 00:16:36 +00:00
|
|
|
|
1999-08-25 07:35:45 +00:00
|
|
|
// If possible, let the container content object have a go at it.
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
result = textContent->SetText(to, newLength, PR_TRUE);
|
|
|
|
}
|
|
|
|
else {
|
2000-03-22 01:23:42 +00:00
|
|
|
result = SetText(aOuterContent, to, newLength, PR_TRUE);
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
1999-08-25 07:35:45 +00:00
|
|
|
delete [] to;
|
1998-09-06 00:16:36 +00:00
|
|
|
|
1999-08-25 07:35:45 +00:00
|
|
|
return result;
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
// nsIScriptObjectOwner implementation
|
|
|
|
|
|
|
|
nsresult
|
2000-03-22 01:23:42 +00:00
|
|
|
nsGenericDOMDataNode::GetScriptObject(nsIContent *aOuterContent,
|
|
|
|
nsIScriptContext* aContext,
|
1998-09-06 00:16:36 +00:00
|
|
|
void** aScriptObject)
|
|
|
|
{
|
|
|
|
nsresult res = NS_OK;
|
|
|
|
if (nsnull == mScriptObject) {
|
1998-09-10 17:11:46 +00:00
|
|
|
nsIDOMScriptObjectFactory *factory;
|
|
|
|
|
1998-11-11 22:06:16 +00:00
|
|
|
res = nsGenericElement::GetScriptObjectFactory(&factory);
|
1998-09-10 17:11:46 +00:00
|
|
|
if (NS_OK != res) {
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
1999-01-21 19:33:03 +00:00
|
|
|
nsIDOMNode* node;
|
|
|
|
PRUint16 nodeType;
|
|
|
|
|
2000-09-09 05:46:14 +00:00
|
|
|
res = aOuterContent->QueryInterface(NS_GET_IID(nsIDOMNode), (void**)&node);
|
1999-01-21 19:33:03 +00:00
|
|
|
if (NS_OK != res) {
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
node->GetNodeType(&nodeType);
|
|
|
|
res = factory->NewScriptCharacterData(nodeType,
|
2000-03-22 01:23:42 +00:00
|
|
|
aContext, aOuterContent,
|
1998-10-20 17:07:23 +00:00
|
|
|
mParent, (void**)&mScriptObject);
|
1998-10-26 23:26:01 +00:00
|
|
|
if (nsnull != mDocument) {
|
|
|
|
aContext->AddNamedReference((void *)&mScriptObject,
|
|
|
|
mScriptObject,
|
2000-05-03 23:42:20 +00:00
|
|
|
"nsGenericDOMDataNode::mScriptObject");
|
1998-10-26 23:26:01 +00:00
|
|
|
}
|
1999-01-21 19:33:03 +00:00
|
|
|
NS_RELEASE(node);
|
1998-09-10 17:11:46 +00:00
|
|
|
NS_RELEASE(factory);
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
*aScriptObject = mScriptObject;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1998-09-17 01:53:52 +00:00
|
|
|
nsGenericDOMDataNode::SetScriptObject(void *aScriptObject)
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
1998-09-17 01:53:52 +00:00
|
|
|
mScriptObject = aScriptObject;
|
1998-09-06 00:16:36 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
nsresult
|
2000-05-16 11:35:12 +00:00
|
|
|
nsGenericDOMDataNode::GetListenerManager(nsIContent* aOuterContent, nsIEventListenerManager** aResult)
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
|
|
|
if (nsnull != mListenerManager) {
|
|
|
|
NS_ADDREF(mListenerManager);
|
|
|
|
*aResult = mListenerManager;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
nsresult rv = NS_NewEventListenerManager(aResult);
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
mListenerManager = *aResult;
|
|
|
|
NS_ADDREF(mListenerManager);
|
2000-05-16 11:35:12 +00:00
|
|
|
mListenerManager->SetListenerTarget(aOuterContent);
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Implementation of nsIContent
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
2000-05-13 08:07:34 +00:00
|
|
|
nsGenericDOMDataNode::BeginConvertToXIF(nsIXIFConverter* aConverter) const
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-05-13 08:07:34 +00:00
|
|
|
nsGenericDOMDataNode::FinishConvertToXIF(nsIXIFConverter* aConverter) const
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Translate the content object into the (XIF) XML Interchange Format
|
|
|
|
* XIF is an intermediate form of the content model, the buffer
|
|
|
|
* will then be parsed into any number of formats including HTML, TXT, etc.
|
|
|
|
*/
|
|
|
|
nsresult
|
2000-03-22 01:23:42 +00:00
|
|
|
nsGenericDOMDataNode::ConvertContentToXIF(const nsIContent *aOuterContent,
|
2000-05-13 08:07:34 +00:00
|
|
|
nsIXIFConverter* aConverter) const
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
2000-03-22 01:23:42 +00:00
|
|
|
const nsIContent* content = aOuterContent;
|
2000-05-13 08:07:34 +00:00
|
|
|
nsCOMPtr<nsIDOMSelection> sel;
|
|
|
|
aConverter->GetSelection(getter_AddRefs(sel));
|
1998-09-06 00:16:36 +00:00
|
|
|
|
2000-08-17 08:11:11 +00:00
|
|
|
if (sel && mDocument && mDocument->IsInSelection(sel,content))
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
2000-01-19 22:56:25 +00:00
|
|
|
nsCOMPtr<nsIEnumerator> enumerator;
|
|
|
|
if (NS_SUCCEEDED(sel->GetEnumerator(getter_AddRefs(enumerator)))) {
|
1999-01-21 21:45:17 +00:00
|
|
|
for (enumerator->First();NS_OK != enumerator->IsDone(); enumerator->Next()) {
|
|
|
|
nsIDOMRange* range = nsnull;
|
|
|
|
if (NS_SUCCEEDED(enumerator->CurrentItem((nsISupports**)&range))) {
|
|
|
|
|
2000-06-07 22:58:39 +00:00
|
|
|
// add whatever part of the node is actually in this range:
|
|
|
|
nsCOMPtr<nsIDOMNSRange> nsrange (do_QueryInterface(range));
|
|
|
|
if (!nsrange)
|
|
|
|
continue;
|
|
|
|
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(NS_CONST_CAST(nsIContent*,content)));
|
|
|
|
if (!node)
|
|
|
|
continue;
|
|
|
|
PRBool intersects;
|
|
|
|
nsresult rv = nsrange->IntersectsNode(node, &intersects);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
if (!intersects)
|
|
|
|
continue; // This range doesn't intersect the node at all
|
|
|
|
|
|
|
|
// Put all of our text into the buffer, initially:
|
2000-08-23 17:27:06 +00:00
|
|
|
nsAutoString buffer;
|
2000-06-07 22:58:39 +00:00
|
|
|
mText.AppendTo(buffer);
|
|
|
|
|
|
|
|
// Clip to whatever is inside the range:
|
1999-01-21 21:45:17 +00:00
|
|
|
nsCOMPtr<nsIDOMNode> startNode;
|
|
|
|
nsCOMPtr<nsIDOMNode> endNode;
|
|
|
|
PRInt32 startOffset = 0;
|
|
|
|
PRInt32 endOffset = 0;
|
|
|
|
|
2000-08-24 03:54:30 +00:00
|
|
|
range->GetStartContainer(getter_AddRefs(startNode));
|
|
|
|
range->GetEndContainer(getter_AddRefs(endNode));
|
1999-01-21 21:45:17 +00:00
|
|
|
|
|
|
|
range->GetStartOffset(&startOffset);
|
|
|
|
range->GetEndOffset(&endOffset);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> startContent;
|
|
|
|
nsCOMPtr<nsIContent> endContent;
|
1999-02-17 02:08:00 +00:00
|
|
|
startContent = do_QueryInterface(startNode);
|
|
|
|
endContent = do_QueryInterface(endNode);
|
1999-01-21 21:45:17 +00:00
|
|
|
|
1999-02-17 04:39:22 +00:00
|
|
|
if (startContent.get() == content || endContent.get() == content)
|
1999-01-21 21:45:17 +00:00
|
|
|
{
|
|
|
|
// NOTE: ORDER MATTERS!
|
|
|
|
// This must go before the Cut
|
1999-02-17 04:39:22 +00:00
|
|
|
if (endContent.get() == content)
|
1999-01-21 21:45:17 +00:00
|
|
|
buffer.Truncate(endOffset);
|
|
|
|
|
2000-06-07 22:58:39 +00:00
|
|
|
// This must go after the Truncate
|
1999-02-17 04:39:22 +00:00
|
|
|
if (startContent.get() == content)
|
2000-06-07 22:58:39 +00:00
|
|
|
buffer.Cut(0,startOffset);
|
1999-01-21 21:45:17 +00:00
|
|
|
}
|
2000-06-07 22:58:39 +00:00
|
|
|
|
2000-05-13 08:07:34 +00:00
|
|
|
aConverter->AddContent(buffer);
|
2000-05-01 00:26:37 +00:00
|
|
|
|
|
|
|
NS_RELEASE(range);
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2000-08-23 17:27:06 +00:00
|
|
|
nsAutoString buffer;
|
1998-10-20 00:20:04 +00:00
|
|
|
mText.AppendTo(buffer);
|
2000-05-13 08:07:34 +00:00
|
|
|
aConverter->AddContent(buffer);
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2000-08-23 17:27:06 +00:00
|
|
|
nsGenericDOMDataNode::ToCString(nsAWritableString& aBuf, PRInt32 aOffset,
|
1998-09-06 00:16:36 +00:00
|
|
|
PRInt32 aLen) const
|
|
|
|
{
|
1998-10-20 00:20:04 +00:00
|
|
|
if (mText.Is2b()) {
|
|
|
|
const PRUnichar* cp = mText.Get2b() + aOffset;
|
|
|
|
const PRUnichar* end = cp + aLen;
|
|
|
|
while (cp < end) {
|
|
|
|
PRUnichar ch = *cp++;
|
|
|
|
if (ch == '\r') {
|
2000-08-23 17:27:06 +00:00
|
|
|
aBuf.Append(NS_LITERAL_STRING("\\r"));
|
1998-10-20 00:20:04 +00:00
|
|
|
} else if (ch == '\n') {
|
2000-08-23 17:27:06 +00:00
|
|
|
aBuf.Append(NS_LITERAL_STRING("\\n"));
|
1998-10-20 00:20:04 +00:00
|
|
|
} else if (ch == '\t') {
|
2000-08-23 17:27:06 +00:00
|
|
|
aBuf.Append(NS_LITERAL_STRING("\\t"));
|
1998-10-20 00:20:04 +00:00
|
|
|
} else if ((ch < ' ') || (ch >= 127)) {
|
|
|
|
char buf[10];
|
|
|
|
PR_snprintf(buf, sizeof(buf), "\\u%04x", ch);
|
2000-08-23 17:27:06 +00:00
|
|
|
aBuf.Append(NS_ConvertASCIItoUCS2(buf));
|
1998-10-20 00:20:04 +00:00
|
|
|
} else {
|
|
|
|
aBuf.Append(ch);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
unsigned char* cp = (unsigned char*)mText.Get1b() + aOffset;
|
|
|
|
const unsigned char* end = cp + aLen;
|
|
|
|
while (cp < end) {
|
|
|
|
PRUnichar ch = *cp++;
|
|
|
|
if (ch == '\r') {
|
2000-08-23 17:27:06 +00:00
|
|
|
aBuf.Append(NS_LITERAL_STRING("\\r"));
|
1998-10-20 00:20:04 +00:00
|
|
|
} else if (ch == '\n') {
|
2000-08-23 17:27:06 +00:00
|
|
|
aBuf.Append(NS_LITERAL_STRING("\\n"));
|
1998-10-20 00:20:04 +00:00
|
|
|
} else if (ch == '\t') {
|
2000-08-23 17:27:06 +00:00
|
|
|
aBuf.Append(NS_LITERAL_STRING("\\t"));
|
1998-10-20 00:20:04 +00:00
|
|
|
} else if ((ch < ' ') || (ch >= 127)) {
|
|
|
|
char buf[10];
|
|
|
|
PR_snprintf(buf, sizeof(buf), "\\u%04x", ch);
|
2000-08-23 17:27:06 +00:00
|
|
|
aBuf.Append(NS_ConvertASCIItoUCS2(buf));
|
1998-10-20 00:20:04 +00:00
|
|
|
} else {
|
|
|
|
aBuf.Append(ch);
|
|
|
|
}
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1998-09-06 04:16:22 +00:00
|
|
|
nsGenericDOMDataNode::GetDocument(nsIDocument*& aResult) const
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
|
|
|
aResult = mDocument;
|
|
|
|
NS_IF_ADDREF(mDocument);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-10-26 23:26:01 +00:00
|
|
|
|
1998-09-06 00:16:36 +00:00
|
|
|
nsresult
|
2000-05-19 04:48:43 +00:00
|
|
|
nsGenericDOMDataNode::SetDocument(nsIDocument* aDocument, PRBool aDeep, PRBool aCompileEventHandlers)
|
1998-10-26 23:26:01 +00:00
|
|
|
{
|
|
|
|
// If we were part of a document, make sure we get rid of the
|
|
|
|
// script context reference to our script object so that our
|
|
|
|
// script object can be freed (or collected).
|
|
|
|
if ((nsnull != mDocument) && (nsnull != mScriptObject)) {
|
1999-12-03 09:24:22 +00:00
|
|
|
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
|
|
|
mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
|
|
|
if (globalObject) {
|
|
|
|
nsCOMPtr<nsIScriptContext> context;
|
2000-01-04 21:24:37 +00:00
|
|
|
if (NS_OK == globalObject->GetContext(getter_AddRefs(context)) && context) {
|
1998-10-26 23:26:01 +00:00
|
|
|
context->RemoveReference((void *)&mScriptObject,
|
|
|
|
mScriptObject);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-09-06 00:16:36 +00:00
|
|
|
mDocument = aDocument;
|
1998-10-26 23:26:01 +00:00
|
|
|
|
|
|
|
// If we already have a script object and now we're being added
|
|
|
|
// to a document, make sure that the script context adds a
|
|
|
|
// reference to our script object. This will ensure that it
|
|
|
|
// won't be freed (or collected) out from under us.
|
|
|
|
if ((nsnull != mDocument) && (nsnull != mScriptObject)) {
|
1999-12-03 09:24:22 +00:00
|
|
|
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
|
|
|
mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
|
|
|
if (globalObject) {
|
|
|
|
nsCOMPtr<nsIScriptContext> context;
|
2000-01-04 21:24:37 +00:00
|
|
|
if (NS_OK == globalObject->GetContext(getter_AddRefs(context)) && context) {
|
1998-10-26 23:26:01 +00:00
|
|
|
context->AddNamedReference((void *)&mScriptObject,
|
|
|
|
mScriptObject,
|
|
|
|
"Text");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-09-06 00:16:36 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1998-09-06 04:16:22 +00:00
|
|
|
nsGenericDOMDataNode::GetParent(nsIContent*& aResult) const
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
|
|
|
NS_IF_ADDREF(mParent);
|
|
|
|
aResult = mParent;
|
|
|
|
return NS_OK;;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1998-09-06 04:16:22 +00:00
|
|
|
nsGenericDOMDataNode::SetParent(nsIContent* aParent)
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
|
|
|
mParent = aParent;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-11-24 06:03:41 +00:00
|
|
|
nsGenericDOMDataNode::HandleDOMEvent(nsIPresContext* aPresContext,
|
1998-09-06 00:16:36 +00:00
|
|
|
nsEvent* aEvent,
|
|
|
|
nsIDOMEvent** aDOMEvent,
|
|
|
|
PRUint32 aFlags,
|
1999-11-24 06:03:41 +00:00
|
|
|
nsEventStatus* aEventStatus)
|
1998-09-06 00:16:36 +00:00
|
|
|
{
|
|
|
|
nsresult ret = NS_OK;
|
|
|
|
nsIDOMEvent* domEvent = nsnull;
|
1999-03-28 22:22:54 +00:00
|
|
|
|
2000-05-16 11:35:12 +00:00
|
|
|
if (NS_EVENT_FLAG_INIT & aFlags) {
|
2000-05-17 05:27:22 +00:00
|
|
|
if (!aDOMEvent) {
|
|
|
|
aDOMEvent = &domEvent;
|
|
|
|
}
|
2000-05-16 11:35:12 +00:00
|
|
|
aEvent->flags = aFlags;
|
|
|
|
aFlags &= ~(NS_EVENT_FLAG_CANT_BUBBLE | NS_EVENT_FLAG_CANT_CANCEL);
|
1999-03-28 22:22:54 +00:00
|
|
|
|
|
|
|
//Initiate capturing phase. Special case first call to document
|
|
|
|
if (nsnull != mDocument) {
|
|
|
|
mDocument->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, NS_EVENT_FLAG_CAPTURE, aEventStatus);
|
|
|
|
}
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
|
1999-03-28 22:22:54 +00:00
|
|
|
//Capturing stage evaluation
|
|
|
|
//Always pass capturing up the tree before local evaulation
|
|
|
|
if (NS_EVENT_FLAG_BUBBLE != aFlags && nsnull != mCapturer) {
|
|
|
|
mCapturer->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, NS_EVENT_FLAG_CAPTURE, aEventStatus);
|
|
|
|
}
|
1998-09-06 00:16:36 +00:00
|
|
|
|
|
|
|
//Local handling stage
|
2000-05-16 11:35:12 +00:00
|
|
|
if (mListenerManager && !(aEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH) &&
|
|
|
|
!(NS_EVENT_FLAG_BUBBLE & aFlags && NS_EVENT_FLAG_CANT_BUBBLE & aEvent->flags)) {
|
2000-02-08 02:05:57 +00:00
|
|
|
aEvent->flags |= aFlags;
|
2000-05-16 11:35:12 +00:00
|
|
|
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, nsnull, aFlags, aEventStatus);
|
2000-02-08 02:05:57 +00:00
|
|
|
aEvent->flags &= ~aFlags;
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//Bubbling stage
|
1999-03-28 22:22:54 +00:00
|
|
|
if (NS_EVENT_FLAG_CAPTURE != aFlags && mParent != nsnull) {
|
1998-09-06 00:16:36 +00:00
|
|
|
ret = mParent->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
|
1999-03-28 22:22:54 +00:00
|
|
|
NS_EVENT_FLAG_BUBBLE, aEventStatus);
|
1998-09-06 00:16:36 +00:00
|
|
|
}
|
|
|
|
|
2000-05-16 11:35:12 +00:00
|
|
|
if (NS_EVENT_FLAG_INIT & aFlags) {
|
1998-09-06 00:16:36 +00:00
|
|
|
// We're leaving the DOM event loop so if we created a DOM event,
|
|
|
|
// release here.
|
|
|
|
if (nsnull != *aDOMEvent) {
|
|
|
|
if (0 != (*aDOMEvent)->Release()) {
|
|
|
|
// Okay, so someone in the DOM loop (a listener, JS object)
|
|
|
|
// still has a ref to the DOM Event but the internal data
|
|
|
|
// hasn't been malloc'd. Force a copy of the data here so the
|
|
|
|
// DOM Event is still valid.
|
|
|
|
nsIPrivateDOMEvent *privateEvent;
|
2000-09-09 05:46:14 +00:00
|
|
|
if (NS_OK == (*aDOMEvent)->QueryInterface(NS_GET_IID(nsIPrivateDOMEvent), (void**)&privateEvent)) {
|
1998-09-06 00:16:36 +00:00
|
|
|
privateEvent->DuplicatePrivateData();
|
|
|
|
NS_RELEASE(privateEvent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
aDOMEvent = nsnull;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
1998-12-17 07:22:28 +00:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericDOMDataNode::RangeAdd(nsIDOMRange& aRange)
|
|
|
|
{
|
1999-01-04 16:48:33 +00:00
|
|
|
// lazy allocation of range list
|
1998-12-17 07:22:28 +00:00
|
|
|
if (nsnull == mRangeList) {
|
|
|
|
mRangeList = new nsVoidArray();
|
|
|
|
}
|
|
|
|
if (nsnull == mRangeList) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
1999-08-06 10:33:09 +00:00
|
|
|
|
|
|
|
// Make sure we don't add a range that is already
|
|
|
|
// in the list!
|
|
|
|
PRInt32 i = mRangeList->IndexOf(&aRange);
|
|
|
|
if (i >= 0) {
|
|
|
|
// Range is already in the list, so there
|
|
|
|
// is nothing to do!
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-12-17 07:22:28 +00:00
|
|
|
// dont need to addref - this call is made by the range object itself
|
|
|
|
PRBool rv = mRangeList->AppendElement(&aRange);
|
|
|
|
if (rv) return NS_OK;
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericDOMDataNode::RangeRemove(nsIDOMRange& aRange)
|
|
|
|
{
|
1999-01-04 16:48:33 +00:00
|
|
|
if (mRangeList) {
|
1998-12-17 07:22:28 +00:00
|
|
|
// dont need to release - this call is made by the range object itself
|
|
|
|
PRBool rv = mRangeList->RemoveElement(&aRange);
|
1998-12-18 02:51:34 +00:00
|
|
|
if (rv) {
|
|
|
|
if (mRangeList->Count() == 0) {
|
|
|
|
delete mRangeList;
|
1999-01-04 16:48:33 +00:00
|
|
|
mRangeList = nsnull;
|
1998-12-18 02:51:34 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1998-12-17 07:22:28 +00:00
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
1998-12-18 02:51:34 +00:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericDOMDataNode::GetRangeList(nsVoidArray*& aResult) const
|
|
|
|
{
|
|
|
|
aResult = mRangeList;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-03-31 20:49:25 +00:00
|
|
|
|
2000-04-04 23:55:31 +00:00
|
|
|
nsresult
|
|
|
|
nsGenericDOMDataNode::SetFocus(nsIPresContext* aPresContext)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericDOMDataNode::RemoveFocus(nsIPresContext* aPresContext)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-08-12 06:28:02 +00:00
|
|
|
nsresult
|
|
|
|
nsGenericDOMDataNode::GetBindingParent(nsIContent** aContent)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericDOMDataNode::SetBindingParent(nsIContent* aParent)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-10-05 23:47:46 +00:00
|
|
|
nsresult
|
|
|
|
nsGenericDOMDataNode::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult,
|
|
|
|
size_t aInstanceSize) const
|
|
|
|
{
|
|
|
|
if (!aResult) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
PRUint32 sum = 0;
|
|
|
|
#ifdef DEBUG
|
|
|
|
sum += (PRUint32) aInstanceSize;
|
|
|
|
sum += mText.GetLength() *
|
|
|
|
(mText.Is2b() ? sizeof(PRUnichar) : sizeof(char));
|
|
|
|
#endif
|
|
|
|
*aResult = sum;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-03-31 20:49:25 +00:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Implementation of the nsIDOMText interface
|
|
|
|
|
|
|
|
nsresult
|
2000-03-22 01:23:42 +00:00
|
|
|
nsGenericDOMDataNode::SplitText(nsIContent *aOuterContent, PRUint32 aOffset,
|
|
|
|
nsIDOMText** aReturn)
|
1999-03-31 20:49:25 +00:00
|
|
|
{
|
1999-12-22 01:51:58 +00:00
|
|
|
nsresult rv = NS_OK;
|
1999-03-31 20:49:25 +00:00
|
|
|
nsAutoString cutText;
|
|
|
|
PRUint32 length;
|
|
|
|
|
|
|
|
GetLength(&length);
|
1999-12-22 01:51:58 +00:00
|
|
|
if (aOffset > length) {
|
|
|
|
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
1999-03-31 20:49:25 +00:00
|
|
|
}
|
|
|
|
|
1999-12-22 01:51:58 +00:00
|
|
|
rv = SubstringData(aOffset, length-aOffset, cutText);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2000-03-22 01:23:42 +00:00
|
|
|
rv = DeleteData(aOuterContent, aOffset, length-aOffset);
|
1999-12-22 01:51:58 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Use CloneContent() for creating the new node so that the new node is of
|
|
|
|
* same class as this node!
|
|
|
|
*/
|
|
|
|
|
2000-03-22 01:23:42 +00:00
|
|
|
nsCOMPtr<nsITextContent> tmpContent(do_QueryInterface(aOuterContent, &rv));
|
1999-12-22 01:51:58 +00:00
|
|
|
nsCOMPtr<nsITextContent> newContent;
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = tmpContent->CloneContent(PR_FALSE, getter_AddRefs(newContent));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMNode> newNode = do_QueryInterface(newContent, &rv);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = newNode->SetNodeValue(cutText);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> parentNode;
|
|
|
|
GetParent(*getter_AddRefs(parentNode));
|
|
|
|
|
|
|
|
if (parentNode) {
|
|
|
|
PRInt32 index;
|
|
|
|
|
2000-03-22 01:23:42 +00:00
|
|
|
rv = parentNode->IndexOf(aOuterContent, index);
|
1999-12-22 01:51:58 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
nsCOMPtr<nsIContent> content(do_QueryInterface(newNode));
|
|
|
|
|
|
|
|
rv = parentNode->InsertChildAt(content, index+1, PR_TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-09-09 05:46:14 +00:00
|
|
|
return newNode->QueryInterface(NS_GET_IID(nsIDOMText), (void**)aReturn);
|
1999-03-31 20:49:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Implementation of the nsITextContent interface
|
|
|
|
|
|
|
|
nsresult
|
1999-10-15 23:36:07 +00:00
|
|
|
nsGenericDOMDataNode::GetText(const nsTextFragment** aFragmentsResult)
|
1999-03-31 20:49:25 +00:00
|
|
|
{
|
1999-10-15 23:36:07 +00:00
|
|
|
*aFragmentsResult = &mText;
|
1999-03-31 20:49:25 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-08-27 21:40:47 +00:00
|
|
|
nsresult
|
|
|
|
nsGenericDOMDataNode::GetTextLength(PRInt32* aLengthResult)
|
|
|
|
{
|
|
|
|
if (!aLengthResult) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
*aLengthResult = mText.GetLength();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-08-23 17:27:06 +00:00
|
|
|
nsGenericDOMDataNode::CopyText(nsAWritableString& aResult)
|
1999-08-27 21:40:47 +00:00
|
|
|
{
|
|
|
|
if (mText.Is2b()) {
|
2000-03-12 09:14:14 +00:00
|
|
|
aResult.Assign(mText.Get2b(), mText.GetLength());
|
1999-08-27 21:40:47 +00:00
|
|
|
}
|
|
|
|
else {
|
2000-09-13 08:21:04 +00:00
|
|
|
aResult.Assign(NS_ConvertASCIItoUCS2(mText.Get1b(), mText.GetLength()).get(),
|
2000-08-23 17:27:06 +00:00
|
|
|
mText.GetLength());
|
1999-08-27 21:40:47 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-03-31 20:49:25 +00:00
|
|
|
nsresult
|
2000-03-22 01:23:42 +00:00
|
|
|
nsGenericDOMDataNode::SetText(nsIContent *aOuterContent,
|
|
|
|
const PRUnichar* aBuffer,
|
|
|
|
PRInt32 aLength,
|
1999-03-31 20:49:25 +00:00
|
|
|
PRBool aNotify)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION((aLength >= 0) && (nsnull != aBuffer), "bad args");
|
|
|
|
if (aLength < 0) {
|
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
|
|
|
}
|
|
|
|
if (nsnull == aBuffer) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
2000-01-28 23:43:12 +00:00
|
|
|
if (aNotify && (nsnull != mDocument)) {
|
|
|
|
mDocument->BeginUpdate();
|
|
|
|
}
|
1999-03-31 20:49:25 +00:00
|
|
|
mText.SetTo(aBuffer, aLength);
|
|
|
|
|
|
|
|
// Trigger a reflow
|
|
|
|
if (aNotify && (nsnull != mDocument)) {
|
2000-03-22 01:23:42 +00:00
|
|
|
mDocument->ContentChanged(aOuterContent, nsnull);
|
2000-01-28 23:43:12 +00:00
|
|
|
mDocument->EndUpdate();
|
1999-03-31 20:49:25 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-03-22 01:23:42 +00:00
|
|
|
nsGenericDOMDataNode::SetText(nsIContent *aOuterContent, const char* aBuffer,
|
|
|
|
PRInt32 aLength, PRBool aNotify)
|
1999-03-31 20:49:25 +00:00
|
|
|
{
|
|
|
|
NS_PRECONDITION((aLength >= 0) && (nsnull != aBuffer), "bad args");
|
|
|
|
if (aLength < 0) {
|
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
|
|
|
}
|
|
|
|
if (nsnull == aBuffer) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
2000-01-28 23:43:12 +00:00
|
|
|
if (aNotify && (nsnull != mDocument)) {
|
|
|
|
mDocument->BeginUpdate();
|
|
|
|
}
|
1999-03-31 20:49:25 +00:00
|
|
|
mText.SetTo(aBuffer, aLength);
|
|
|
|
|
|
|
|
// Trigger a reflow
|
|
|
|
if (aNotify && (nsnull != mDocument)) {
|
2000-03-22 01:23:42 +00:00
|
|
|
mDocument->ContentChanged(aOuterContent, nsnull);
|
2000-01-28 23:43:12 +00:00
|
|
|
mDocument->EndUpdate();
|
1999-03-31 20:49:25 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-08-23 17:27:06 +00:00
|
|
|
nsresult
|
|
|
|
nsGenericDOMDataNode::SetText(nsIContent *aOuterContent,
|
|
|
|
const nsAReadableString& aStr,
|
|
|
|
PRBool aNotify)
|
|
|
|
{
|
|
|
|
if (aNotify && (nsnull != mDocument)) {
|
|
|
|
mDocument->BeginUpdate();
|
|
|
|
}
|
|
|
|
mText = aStr;
|
|
|
|
|
|
|
|
// Trigger a reflow
|
|
|
|
if (aNotify && (nsnull != mDocument)) {
|
|
|
|
mDocument->ContentChanged(aOuterContent, nsnull);
|
|
|
|
mDocument->EndUpdate();
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-03-31 20:49:25 +00:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsGenericDOMDataNode::IsOnlyWhitespace(PRBool* aResult)
|
|
|
|
{
|
|
|
|
nsTextFragment& frag = mText;
|
|
|
|
if (frag.Is2b()) {
|
|
|
|
const PRUnichar* cp = frag.Get2b();
|
|
|
|
const PRUnichar* end = cp + frag.GetLength();
|
|
|
|
while (cp < end) {
|
|
|
|
PRUnichar ch = *cp++;
|
|
|
|
if (!XP_IS_SPACE(ch)) {
|
|
|
|
*aResult = PR_FALSE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
const char* cp = frag.Get1b();
|
|
|
|
const char* end = cp + frag.GetLength();
|
|
|
|
while (cp < end) {
|
|
|
|
PRUnichar ch = PRUnichar(*(unsigned char*)cp);
|
|
|
|
cp++;
|
|
|
|
if (!XP_IS_SPACE(ch)) {
|
|
|
|
*aResult = PR_FALSE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*aResult = PR_TRUE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|