big checkin. fixing problems blocking Cmanske (also a reviewer). Checking in preliminary for gen content.(nothing damaged yet) lots of bug numbers not going to look them up, the tree just opened.

This commit is contained in:
mjudge%netscape.com 2000-02-10 04:35:51 +00:00
Родитель b2391ea944
Коммит b32999a1de
40 изменённых файлов: 1539 добавлений и 27 удалений

Просмотреть файл

@ -25,6 +25,8 @@
#include "nsISupports.h"
class nsIFocusTracker;
class nsIContent;
class nsIDOMRange;
@ -32,6 +34,11 @@ class nsIDOMRange;
{0xa6cf90e4, 0x15b3, 0x11d2, \
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
// {B4BC9F63-D9BA-11d3-9938-00108301233C}
#define NS_IGENERATEDCONTENTITERTOR_IID \
{ 0xb4bc9f63, 0xd9ba, 0x11d3, \
{ 0x99, 0x38, 0x0, 0x10, 0x83, 0x1, 0x23, 0x3c } }
class nsIContentIterator : public nsISupports {
public:
@ -86,6 +93,16 @@ public:
};
class nsIGeneratedContentIterator : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IGENERATEDCONTENTITERTOR_IID; return iid; }
/* Initializes an iterator for the subtree rooted by the node aRoot
*/
NS_IMETHOD Init(nsIFocusTracker *aTracker, nsIDOMRange* aRange, PRBool aSelectBefore, PRBool aSelectAfter)=0;
};
#endif // __nsIContentIterator_h___

Просмотреть файл

@ -33,10 +33,15 @@
#include "nsIContent.h"
#include "nsIDOMText.h"
#include "nsISupportsArray.h"
#include "nsIFocusTracker.h"
#include "nsCOMPtr.h"
#include "nsIPresContext.h"
#include "nsIComponentManager.h"
#include "nsLayoutCID.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
static NS_DEFINE_IID(kCSubtreeIteratorCID, NS_SUBTREEITERATOR_CID);
// couple of utility static functs
@ -159,6 +164,65 @@ private:
};
nsresult NS_NewContentIterator(nsIContentIterator** aInstancePtrResult);
nsresult NS_NewGeneratedContentIterator(nsIGeneratedContentIterator** aInstancePtrResult);
class nsGeneratedContentIterator : public nsContentIterator, nsIGeneratedContentIterator
{
public:
NS_DECL_ISUPPORTS
nsGeneratedContentIterator();
virtual ~nsGeneratedContentIterator();
// nsIGeneratedContentIterator interface methods ------------------------------
NS_IMETHOD Init(nsIFocusTracker *aTracker, nsIDOMRange* aRange, PRBool aSelectBefore, PRBool aSelectAfter);
NS_IMETHOD First();
NS_IMETHOD Last();
NS_IMETHOD Next();
NS_IMETHOD Prev();
NS_IMETHOD CurrentNode(nsIContent **aNode);
protected:
PRBool mSelectBefore;//set at init time
PRBool mSelectAfter;
nsCOMPtr<nsIContentIterator> mGenIter;//reset for every before and after
nsIFocusTracker *mTracker;//weak reference
nsresult FillGenIter(PRInt8 aSide);
PRInt8 mCurSideOfContent; //-1= before, 0 = current, 1=next
};
nsGeneratedContentIterator::nsGeneratedContentIterator()
:mSelectBefore(0),mSelectAfter(0), mCurSideOfContent(-1)
{
}
nsGeneratedContentIterator::~nsGeneratedContentIterator()
{
}
NS_IMPL_ADDREF_INHERITED(nsGeneratedContentIterator, nsContentIterator)
NS_IMPL_RELEASE_INHERITED(nsGeneratedContentIterator, nsContentIterator)
NS_IMETHODIMP
nsGeneratedContentIterator::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (nsnull == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(nsIGeneratedContentIterator::GetIID())) {
*aInstancePtr = NS_STATIC_CAST(nsIGeneratedContentIterator *,this);
NS_ADDREF_THIS();
return NS_OK;
}
return nsContentIterator::QueryInterface(aIID,aInstancePtr);
}
/******************************************************
@ -173,6 +237,14 @@ nsresult NS_NewContentIterator(nsIContentIterator** aInstancePtrResult)
return NS_ERROR_OUT_OF_MEMORY;
}
nsresult NS_NewGeneratedContentIterator(nsIContentIterator** aInstancePtrResult)
{
nsGeneratedContentIterator * iter = new nsGeneratedContentIterator();
if (iter)
return iter->QueryInterface(NS_GET_IID(nsIContentIterator), (void**) aInstancePtrResult);
return NS_ERROR_OUT_OF_MEMORY;
}
/******************************************************
* XPCOM cruft
@ -1086,4 +1158,478 @@ nsresult nsContentSubtreeIterator::GetTopAncestorInRange(
return NS_ERROR_FAILURE;
}
/******************************************************
* nsGeneratedSubtreeIterator
******************************************************/
nsresult NS_NewGeneratedSubtreeIterator(nsIGeneratedContentIterator** aInstancePtrResult);
class nsGeneratedSubTreeIterator : public nsContentSubtreeIterator, nsIGeneratedContentIterator
{
public:
NS_DECL_ISUPPORTS
nsGeneratedSubTreeIterator();
virtual ~nsGeneratedSubTreeIterator();
// nsIGeneratedContentIterator interface methods ------------------------------
NS_IMETHOD Init(nsIFocusTracker *aTracker, nsIContent* aRange, PRBool aSelectBefore, PRBool aSelectAfter);
NS_IMETHOD First();
NS_IMETHOD Last();
NS_IMETHOD Next();
NS_IMETHOD Prev();
NS_IMETHOD CurrentNode(nsIContent **aNode);
protected:
PRBool mSelectBefore;//set at init time
PRBool mSelectAfter;
nsCOMPtr<nsIContentIterator> mGenIter;//reset for every before and after
nsIFocusTracker *mTracker;//weak reference
nsresult FillGenIter(PRInt8 aSide);
PRInt8 mCurSideOfContent; //-1= before, 0 = current, 1=next
};
nsGeneratedSubTreeIterator::nsGeneratedSubTreeIterator()
:mSelectBefore(0),mSelectAfter(0), mCurSideOfContent(-1)
{
}
nsGeneratedSubTreeIterator::~nsGeneratedSubTreeIterator()
{
}
NS_IMPL_ADDREF_INHERITED(nsGeneratedSubTreeIterator, nsContentIterator)
NS_IMPL_RELEASE_INHERITED(nsGeneratedSubTreeIterator, nsContentIterator)
NS_IMETHODIMP
nsGeneratedSubTreeIterator::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (nsnull == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(nsIGeneratedContentIterator::GetIID())) {
*aInstancePtr = NS_STATIC_CAST(nsIGeneratedContentIterator *,this);
NS_ADDREF_THIS();
return NS_OK;
}
return nsContentSubtreeIterator::QueryInterface(aIID,aInstancePtr);
}
/******************************************************
* nsGeneratedSubTreeIterator
******************************************************/
nsresult nsGeneratedSubTreeIterator::Init(nsIFocusTracker *aTracker, nsIContent* aContent, PRBool aSelectBefore, PRBool aSelectAfter)
{
mTracker = aTracker;
mSelectBefore = aSelectBefore;
mSelectAfter = aSelectAfter;
return nsContentSubtreeIterator::Init(aContent);
}
nsresult nsGeneratedSubTreeIterator::First()
{
nsContentSubtreeIterator::First();
if (!mFirst)
return NS_ERROR_FAILURE;
mIsDone = PR_FALSE;
mGenIter = 0;
if (mSelectBefore)
{
mCurSideOfContent = -1;//get generated from in FRONT of this node
FillGenIter(mCurSideOfContent);
}
if (!mGenIter)
mCurSideOfContent = 0;
return NS_OK;
}
nsresult nsGeneratedSubTreeIterator::Next()
{
if (mIsDone)
return NS_OK;
if (!mCurNode)
return NS_OK;
nsresult result = NS_OK;
if (mGenIter)
{
result = mGenIter->Next();
if (NS_FAILED(result) || (NS_SUCCEEDED(mGenIter->IsDone()) ))
{
mGenIter = 0;
}
else
return result;
}
if (mCurNode == mLast && !mGenIter)
{
mIsDone = PR_TRUE;
return NS_OK;
}
mCurSideOfContent ++;
if (mCurSideOfContent > 0)//current node currently
{
FillGenIter(mCurSideOfContent);
}
if (!mGenIter) //nothing after current node
{
mCurSideOfContent = -1;
result = nsContentSubtreeIterator::NextNode(&mCurNode);
FillGenIter(mCurSideOfContent);
if (!mGenIter)//nothing before new node.
mCurSideOfContent = 0;//advance to actual node
}
return result;
}
nsresult nsGeneratedSubTreeIterator::Prev()
{
if (mIsDone)
return NS_OK;
if (!mCurNode)
return NS_OK;
nsresult result = NS_OK;
if (mGenIter)
{
result = mGenIter->Prev();
if (NS_FAILED(result) || (NS_SUCCEEDED(mGenIter->IsDone()) ))
{
mGenIter = 0;
}
else
return result;
}
if (mCurNode == mFirst && !mGenIter)
{
mIsDone = PR_TRUE;
return NS_OK;
}
mCurSideOfContent --;
if (mCurSideOfContent < 0)//current node currently
{
FillGenIter(mCurSideOfContent);
}
if (!mGenIter) //nothing after current node
{
mCurSideOfContent = 1;
result = nsContentSubtreeIterator::PrevNode(&mCurNode);
FillGenIter(mCurSideOfContent);
if (!mGenIter)//nothing before new node.
mCurSideOfContent = 0;//advance to actual node
}
return result;
}
nsresult nsGeneratedSubTreeIterator::Last()
{
if (!mLast)
return NS_ERROR_FAILURE;
nsContentSubtreeIterator::Last();
mGenIter = 0;
mIsDone = PR_FALSE;
if (mSelectAfter)
{
mCurSideOfContent = 1;
FillGenIter(mCurSideOfContent);
}
if (!mGenIter)
mCurSideOfContent = 0;
return NS_OK;
}
nsresult
nsGeneratedSubTreeIterator::FillGenIter(PRInt8 aSide)
{
if (!mCurNode || !mTracker)
return NS_ERROR_NULL_POINTER;
nsresult result;
if (aSide == 0)
return NS_OK;
nsFrameState frameState;
nsIFrame *genFrame;
result = mTracker->GetPrimaryFrameFor(mCurNode, &genFrame);
if (NS_FAILED(result))
return result;
if (!genFrame)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIPresContext> context;
result = mTracker->GetPresContext(getter_AddRefs(context));
if (NS_FAILED(result) || !context)
return result?result:NS_ERROR_FAILURE;
result = genFrame->FirstChild(context,nsnull,&genFrame);
if (NS_FAILED(result) || !genFrame)
return NS_OK;//fine nothing to do here
if (aSide < 0)
{
//we SHOULD now have a generated content frame if one exists. we need to check the flag for gen content
result = genFrame->GetFrameState(&frameState);
if (NS_FAILED(result))
return result;
}
else if (aSide > 0)
{
nsIFrame *nextFrame = genFrame;
while(nextFrame)
{
result = nextFrame->GetNextSibling(&nextFrame);
if (NS_SUCCEEDED(result) && nextFrame)
genFrame = nextFrame;
else
nextFrame = nsnull;
}
}
if (frameState & NS_FRAME_GENERATED_CONTENT) {
nsCOMPtr<nsIContent> content;
result = genFrame->GetContent(getter_AddRefs(content));
if (NS_FAILED(result) || !content)
return result ? result:NS_ERROR_FAILURE;
result = nsComponentManager::CreateInstance(kCSubtreeIteratorCID, nsnull,
NS_GET_IID(nsIContentIterator),
getter_AddRefs(mGenIter));
if (NS_FAILED(result) || !mGenIter)
return result ? result:NS_ERROR_FAILURE;
mGenIter->Init(content);
if (aSide > 0)
mGenIter->Last();
}
return NS_OK;
}
nsresult nsGeneratedSubTreeIterator::CurrentNode(nsIContent **aNode)
{
if (!mCurNode)
return NS_ERROR_FAILURE;
if (mIsDone)
return NS_ERROR_FAILURE;
if (mGenIter)
return mGenIter->CurrentNode(aNode);
return mCurNode->QueryInterface(nsIContent::GetIID(), (void**) aNode);
}
/******************************************************
* nsGeneratedContentIterator
******************************************************/
nsresult nsGeneratedContentIterator::Init(nsIFocusTracker *aTracker, nsIDOMRange* aRange, PRBool aSelectBefore, PRBool aSelectAfter)
{
mTracker = aTracker;
mSelectBefore = aSelectBefore;
mSelectAfter = aSelectAfter;
return nsContentIterator::Init(aRange);
}
nsresult nsGeneratedContentIterator::First()
{
nsContentIterator::First();
if (!mFirst)
return NS_ERROR_FAILURE;
mIsDone = PR_FALSE;
mGenIter = 0;
if (mSelectBefore)
{
mCurSideOfContent = -1;//get generated from in FRONT of this node
FillGenIter(mCurSideOfContent);
}
if (!mGenIter)
mCurSideOfContent = 0;
return NS_OK;
}
nsresult nsGeneratedContentIterator::Next()
{
if (mIsDone)
return NS_OK;
if (!mCurNode)
return NS_OK;
nsresult result = NS_OK;
if (mGenIter)
{
result = mGenIter->Next();
if (NS_FAILED(result) || (NS_SUCCEEDED(mGenIter->IsDone()) ))
{
mGenIter = 0;
}
else
return result;
}
if (mCurNode == mLast && !mGenIter)
{
mIsDone = PR_TRUE;
return NS_OK;
}
mCurSideOfContent ++;
if (mCurSideOfContent > 0)//current node currently
{
FillGenIter(mCurSideOfContent);
}
if (!mGenIter) //nothing after current node
{
mCurSideOfContent = -1;
result = nsContentIterator::NextNode(&mCurNode);
FillGenIter(mCurSideOfContent);
if (!mGenIter)//nothing before new node.
mCurSideOfContent = 0;//advance to actual node
}
return result;
}
nsresult nsGeneratedContentIterator::Prev()
{
if (mIsDone)
return NS_OK;
if (!mCurNode)
return NS_OK;
nsresult result = NS_OK;
if (mGenIter)
{
result = mGenIter->Prev();
if (NS_FAILED(result) || (NS_SUCCEEDED(mGenIter->IsDone()) ))
{
mGenIter = 0;
}
else
return result;
}
if (mCurNode == mFirst && !mGenIter)
{
mIsDone = PR_TRUE;
return NS_OK;
}
mCurSideOfContent --;
if (mCurSideOfContent < 0)//current node currently
{
FillGenIter(mCurSideOfContent);
}
if (!mGenIter) //nothing after current node
{
mCurSideOfContent = 1;
result = nsContentIterator::PrevNode(&mCurNode);
FillGenIter(mCurSideOfContent);
if (!mGenIter)//nothing before new node.
mCurSideOfContent = 0;//advance to actual node
}
return result;
}
nsresult nsGeneratedContentIterator::Last()
{
nsContentIterator::Last();
if (!mLast)
return NS_ERROR_FAILURE;
mGenIter = 0;
mIsDone = PR_FALSE;
mCurNode = mLast;
mCurSideOfContent = 1;
FillGenIter(mCurSideOfContent);
if (!mGenIter)
mCurSideOfContent = 0;
return NS_OK;
}
nsresult
nsGeneratedContentIterator::FillGenIter(PRInt8 aSide)
{
if (!mCurNode || !mTracker)
return NS_ERROR_NULL_POINTER;
nsresult result;
if (aSide == 0)
return NS_OK;
nsFrameState frameState;
nsIFrame *genFrame;
result = mTracker->GetPrimaryFrameFor(mCurNode, &genFrame);
if (NS_FAILED(result))
return result;
if (!genFrame)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIPresContext> context;
result = mTracker->GetPresContext(getter_AddRefs(context));
if (NS_FAILED(result) || !context)
return result?result:NS_ERROR_FAILURE;
result = genFrame->FirstChild(context,nsnull,&genFrame);
if (NS_FAILED(result) || !genFrame)
return NS_OK;//fine nothing to do here
if (aSide < 0)
{
//we SHOULD now have a generated content frame if one exists. we need to check the flag for gen content
result = genFrame->GetFrameState(&frameState);
if (NS_FAILED(result))
return result;
}
else if (aSide > 0)
{
nsIFrame *nextFrame = genFrame;
while(nextFrame)
{
result = nextFrame->GetNextSibling(&nextFrame);
if (NS_SUCCEEDED(result) && nextFrame)
genFrame = nextFrame;
else
nextFrame = nsnull;
}
}
if (frameState & NS_FRAME_GENERATED_CONTENT) {
nsCOMPtr<nsIContent> content;
result = genFrame->GetContent(getter_AddRefs(content));
if (NS_FAILED(result) || !content)
return result ? result:NS_ERROR_FAILURE;
result = nsComponentManager::CreateInstance(kCSubtreeIteratorCID, nsnull,
NS_GET_IID(nsIContentIterator),
getter_AddRefs(mGenIter));
if (NS_FAILED(result) || !mGenIter)
return result ? result:NS_ERROR_FAILURE;
mGenIter->Init(content);
if (aSide > 0)
mGenIter->Last();
}
return NS_OK;
}
nsresult nsGeneratedContentIterator::CurrentNode(nsIContent **aNode)
{
if (!mCurNode)
return NS_ERROR_FAILURE;
if (mIsDone)
return NS_ERROR_FAILURE;
if (mGenIter)
return mGenIter->CurrentNode(aNode);
return mCurNode->QueryInterface(nsIContent::GetIID(), (void**) aNode);
}

Просмотреть файл

@ -1609,3 +1609,10 @@ NS_IMETHODIMP DocumentViewerImpl::NotifySelectionChanged(void)
// to the right nsIDOMXULCommandDispatcher yet.
return NS_OK;
}
NS_IMETHODIMP DocumentViewerImpl::TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset)
{
//stub
return NS_OK;
}

Просмотреть файл

@ -58,6 +58,7 @@ nsVoidArray* nsRange::mStartAncestorOffsets = nsnull;
nsVoidArray* nsRange::mEndAncestorOffsets = nsnull;
nsresult NS_NewContentIterator(nsIContentIterator** aInstancePtrResult);
nsresult NS_NewGeneratedContentIterator(nsIContentIterator** aInstancePtrResult);
/******************************************************
@ -1974,6 +1975,44 @@ nsRange::IsValidFragment(const nsString& aFragment, PRBool* aReturn)
return result;
}
NS_IMETHODIMP
nsRange::GetHasGeneratedBefore(PRBool *aBool)
{
NS_ENSURE_ARG_POINTER(aBool);
*aBool = mBeforeGenContent;
return NS_OK;
}
NS_IMETHODIMP
nsRange::GetHasGeneratedAfter(PRBool *aBool)
{
NS_ENSURE_ARG_POINTER(aBool);
*aBool = mAfterGenContent;
return NS_OK;
}
NS_IMETHODIMP
nsRange::SetHasGeneratedBefore(PRBool aBool)
{
mBeforeGenContent = aBool;
return NS_OK;
}
NS_IMETHODIMP
nsRange::SetHasGeneratedAfter(PRBool aBool)
{
mAfterGenContent = aBool;
return NS_OK;
}
NS_IMETHODIMP
nsRange::SetBeforeAndAfter(PRBool aBefore, PRBool aAfter)
{
mBeforeGenContent = aBefore;
mBeforeGenContent = aAfter;
return NS_OK;
}
// BEGIN nsIScriptObjectOwner interface implementations
NS_IMETHODIMP
nsRange::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)

Просмотреть файл

@ -94,12 +94,18 @@ public:
NS_IMETHOD CreateContextualFragment(const nsString& aFragment,
nsIDOMDocumentFragment** aReturn);
NS_IMETHOD IsValidFragment(const nsString& aFragment, PRBool* aReturn);
NS_IMETHOD GetHasGeneratedBefore(PRBool *aBool);
NS_IMETHOD GetHasGeneratedAfter(PRBool *aBool);
NS_IMETHOD SetHasGeneratedBefore(PRBool aBool);
NS_IMETHOD SetHasGeneratedAfter(PRBool aBool);
NS_IMETHOD SetBeforeAndAfter(PRBool aBefore, PRBool aAfter);
/*BEGIN nsIScriptObjectOwner interface implementations*/
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
/*END nsIScriptObjectOwner interface implementations*/
// nsRange interface extensions
static NS_METHOD OwnerGone(nsIContent* aParentNode);
@ -169,6 +175,8 @@ public:
protected:
void* mScriptObject;
PRBool mBeforeGenContent;
PRBool mAfterGenContent;
};

Просмотреть файл

@ -35,6 +35,7 @@
class nsIHTMLTableCellElement : public nsISupports
{
public:
static const nsIID& GetIID() { static nsIID iid = NS_IHTMLTABLECELLELEMENT_IID; return iid; }
/** @return the starting column for this cell. Always >= 1 */
NS_IMETHOD GetColIndex (PRInt32* aColIndex) = 0;

Просмотреть файл

@ -3,5 +3,10 @@
{ 0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} } */
void notifySelectionChanged();
/* tableCellNotification is a call back for when a cell is trying to be
selected. No selection action will take place. only this notification.
currently CTRL-LEFTMOUSEBUTTON in a table cell is the event that will
trigger this call.*/
void tableCellNotification(in Node parent, in long offset);
};

Просмотреть файл

@ -782,6 +782,7 @@ enum nsDOMProp {
NS_DOM_PROP_SELECTION_STARTBATCHCHANGES,
NS_DOM_PROP_SELECTION_TOSTRING,
NS_DOM_PROP_SELECTIONLISTENER_NOTIFYSELECTIONCHANGED,
NS_DOM_PROP_SELECTIONLISTENER_TABLECELLNOTIFICATION,
NS_DOM_PROP_STYLESHEET_DISABLED,
NS_DOM_PROP_STYLESHEET_READONLY,
NS_DOM_PROP_STYLESHEET_TYPE,

Просмотреть файл

@ -28,6 +28,7 @@
#include "nsString.h"
#include "nsIScriptContext.h"
class nsIDOMNode;
#define NS_IDOMSELECTIONLISTENER_IID \
{ 0xa6cf90e2, 0x15b3, 0x11d2, \
@ -38,16 +39,20 @@ public:
static const nsIID& GetIID() { static nsIID iid = NS_IDOMSELECTIONLISTENER_IID; return iid; }
NS_IMETHOD NotifySelectionChanged()=0;
NS_IMETHOD TableCellNotification(nsIDOMNode* aParent, PRInt32 aOffset)=0;
};
#define NS_DECL_IDOMSELECTIONLISTENER \
NS_IMETHOD NotifySelectionChanged(); \
NS_IMETHOD TableCellNotification(nsIDOMNode* aParent, PRInt32 aOffset); \
#define NS_FORWARD_IDOMSELECTIONLISTENER(_to) \
NS_IMETHOD NotifySelectionChanged() { return _to NotifySelectionChanged(); } \
NS_IMETHOD TableCellNotification(nsIDOMNode* aParent, PRInt32 aOffset) { return _to TableCellNotification(aParent, aOffset); } \
extern "C" NS_DOM nsresult NS_InitSelectionListenerClass(nsIScriptContext *aContext, void **aPrototype);

Просмотреть файл

@ -34,12 +34,14 @@
#include "nsCOMPtr.h"
#include "nsDOMPropEnums.h"
#include "nsString.h"
#include "nsIDOMNode.h"
#include "nsIDOMSelectionListener.h"
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
static NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID);
static NS_DEFINE_IID(kIScriptGlobalObjectIID, NS_ISCRIPTGLOBALOBJECT_IID);
static NS_DEFINE_IID(kINodeIID, NS_IDOMNODE_IID);
static NS_DEFINE_IID(kISelectionListenerIID, NS_IDOMSELECTIONLISTENER_IID);
@ -184,6 +186,64 @@ SelectionListenerNotifySelectionChanged(JSContext *cx, JSObject *obj, uintN argc
}
//
// Native method TableCellNotification
//
PR_STATIC_CALLBACK(JSBool)
SelectionListenerTableCellNotification(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMSelectionListener *nativeThis = (nsIDOMSelectionListener*)nsJSUtils::nsGetNativeThis(cx, obj);
nsresult result = NS_OK;
nsCOMPtr<nsIDOMNode> b0;
PRInt32 b1;
// If there's no private data, this must be the prototype, so ignore
if (nsnull == nativeThis) {
return JS_TRUE;
}
{
*rval = JSVAL_NULL;
{
nsresult rv;
NS_WITH_SERVICE(nsIScriptSecurityManager, secMan,
NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
if (NS_SUCCEEDED(rv)) {
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_SELECTIONLISTENER_TABLECELLNOTIFICATION, PR_FALSE);
}
if (NS_FAILED(rv)) {
return nsJSUtils::nsReportError(cx, obj, rv);
}
}
if (argc < 2) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_TOO_FEW_PARAMETERS_ERR);
}
if (JS_FALSE == nsJSUtils::nsConvertJSValToObject((nsISupports **)(void**)getter_AddRefs(b0),
kINodeIID,
"Node",
cx,
argv[0])) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_NOT_OBJECT_ERR);
}
if (!JS_ValueToInt32(cx, argv[1], (int32 *)&b1)) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_NOT_NUMBER_ERR);
}
result = nativeThis->TableCellNotification(b0, b1);
if (NS_FAILED(result)) {
return nsJSUtils::nsReportError(cx, obj, result);
}
*rval = JSVAL_VOID;
}
return JS_TRUE;
}
/***********************************************************************/
//
// class for SelectionListener
@ -219,6 +279,7 @@ static JSPropertySpec SelectionListenerProperties[] =
static JSFunctionSpec SelectionListenerMethods[] =
{
{"notifySelectionChanged", SelectionListenerNotifySelectionChanged, 0},
{"tableCellNotification", SelectionListenerTableCellNotification, 2},
{0}
};

Просмотреть файл

@ -57,3 +57,8 @@ NS_IMETHODIMP TypeInState::NotifySelectionChanged()
return NS_OK;
};
NS_IMETHODIMP TypeInState::TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset)
{
//stub
return NS_OK;
}

Просмотреть файл

@ -38,6 +38,7 @@ public:
virtual ~TypeInState();
NS_IMETHOD NotifySelectionChanged();
NS_IMETHOD TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset);
void GetEnumForName(nsIAtom *aPropName, PRUint32 &aEnum);
void GetPropertyIsString(PRUint32 aProp, PRUint32 &aIsString);

Просмотреть файл

@ -115,6 +115,13 @@ nsInterfaceState::NotifyDocumentCreated()
return NS_OK;
}
NS_IMETHODIMP
nsInterfaceState::TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset)
{
//stub
return NS_OK;
}
NS_IMETHODIMP
nsInterfaceState::NotifyDocumentWillBeDestroyed()
{

Просмотреть файл

@ -53,7 +53,8 @@ public:
// nsIDOMSelectionListener interface
NS_IMETHOD NotifySelectionChanged();
NS_IMETHOD TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset);
NS_DECL_NSIDOCUMENTSTATELISTENER
protected:

Просмотреть файл

@ -115,6 +115,13 @@ nsInterfaceState::NotifyDocumentCreated()
return NS_OK;
}
NS_IMETHODIMP
nsInterfaceState::TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset)
{
//stub
return NS_OK;
}
NS_IMETHODIMP
nsInterfaceState::NotifyDocumentWillBeDestroyed()
{

Просмотреть файл

@ -53,7 +53,8 @@ public:
// nsIDOMSelectionListener interface
NS_IMETHOD NotifySelectionChanged();
NS_IMETHOD TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset);
NS_DECL_NSIDOCUMENTSTATELISTENER
protected:

Просмотреть файл

@ -57,3 +57,8 @@ NS_IMETHODIMP TypeInState::NotifySelectionChanged()
return NS_OK;
};
NS_IMETHODIMP TypeInState::TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset)
{
//stub
return NS_OK;
}

Просмотреть файл

@ -38,6 +38,7 @@ public:
virtual ~TypeInState();
NS_IMETHOD NotifySelectionChanged();
NS_IMETHOD TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset);
void GetEnumForName(nsIAtom *aPropName, PRUint32 &aEnum);
void GetPropertyIsString(PRUint32 aProp, PRUint32 &aIsString);

Просмотреть файл

@ -858,13 +858,27 @@ nsCSSFrameConstructor::CreateGeneratedContentFrame(nsIPresShell* aPresShe
// the 'display' property
nsIFrame* containerFrame;
nsFrameItems childFrames;
nsCOMPtr<nsIDOMElement>containerElement;
nsCOMPtr<nsIContent> containerContent;
nsCOMPtr<nsIDocument> document;
aContent->GetDocument(*getter_AddRefs(document));
nsCOMPtr<nsIDOMDocument> domdoc(do_QueryInterface(document));
nsresult result;
result = domdoc->CreateElement("SPAN",getter_AddRefs(containerElement));//is the literal the correct way?
if (NS_SUCCEEDED(result) && containerElement)
{
containerContent = do_QueryInterface(containerElement);
}
if (NS_STYLE_DISPLAY_BLOCK == displayValue) {
NS_NewBlockFrame(aPresShell, &containerFrame);
} else {
NS_NewInlineFrame(aPresShell, &containerFrame);
}
InitAndRestoreFrame(aPresContext, aState, aContent,
InitAndRestoreFrame(aPresContext, aState, containerContent?containerContent:aContent,
aFrame, pseudoStyleContext, nsnull, containerFrame);
// Mark the frame as being associated with generated content
@ -882,8 +896,6 @@ nsCSSFrameConstructor::CreateGeneratedContentFrame(nsIPresShell* aPresShe
// Now create content objects (and child frames) for each value of the
// 'content' property
nsCOMPtr<nsIDocument> document;
aContent->GetDocument(*getter_AddRefs(document));
for (PRUint32 contentIndex = 0; contentIndex < contentCount; contentIndex++) {
nsIFrame* frame;

Просмотреть файл

@ -320,6 +320,12 @@ NS_IMETHODIMP nsCaret::NotifySelectionChanged()
return NS_OK;
}
NS_IMETHODIMP nsCaret::TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset)
{
//stub
return NS_OK;
}
#ifdef XP_MAC
#pragma mark -
#endif

Просмотреть файл

@ -58,6 +58,7 @@ class nsCaret : public nsICaret,
//nsIDOMSelectionListener interface
NS_IMETHOD NotifySelectionChanged();
NS_IMETHOD TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset);
static void CaretBlinkCallback(nsITimer *aTimer, void *aClosure);

Просмотреть файл

@ -1609,3 +1609,10 @@ NS_IMETHODIMP DocumentViewerImpl::NotifySelectionChanged(void)
// to the right nsIDOMXULCommandDispatcher yet.
return NS_OK;
}
NS_IMETHODIMP DocumentViewerImpl::TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset)
{
//stub
return NS_OK;
}

Просмотреть файл

@ -142,9 +142,10 @@ public:
* cannot coexist with aContinueSelection
* @param aHint will tell the selection which direction geometrically to actually show the caret on.
* 1 = end of this line 0 = beggining of this line
* @param aIsCell will tell us if this range describes a Cell.
*/
NS_IMETHOD HandleClick(nsIContent *aNewFocus, PRUint32 aContentOffset, PRUint32 aContentEndOffset ,
PRBool aContinueSelection, PRBool aMultipleSelection, PRBool aHint) = 0;
PRBool aContinueSelection, PRBool aMultipleSelection, PRBool aHint, PRBool aIsCell) = 0;
/** HandleDrag extends the selection to contain the frame closest to aPoint.
* @param aPresContext is the context to use when figuring out what frame contains the point.

Просмотреть файл

@ -25,6 +25,8 @@
#include "nsISupports.h"
class nsIFocusTracker;
class nsIContent;
class nsIDOMRange;
@ -32,6 +34,11 @@ class nsIDOMRange;
{0xa6cf90e4, 0x15b3, 0x11d2, \
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
// {B4BC9F63-D9BA-11d3-9938-00108301233C}
#define NS_IGENERATEDCONTENTITERTOR_IID \
{ 0xb4bc9f63, 0xd9ba, 0x11d3, \
{ 0x99, 0x38, 0x0, 0x10, 0x83, 0x1, 0x23, 0x3c } }
class nsIContentIterator : public nsISupports {
public:
@ -86,6 +93,16 @@ public:
};
class nsIGeneratedContentIterator : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IGENERATEDCONTENTITERTOR_IID; return iid; }
/* Initializes an iterator for the subtree rooted by the node aRoot
*/
NS_IMETHOD Init(nsIFocusTracker *aTracker, nsIDOMRange* aRange, PRBool aSelectBefore, PRBool aSelectAfter)=0;
};
#endif // __nsIContentIterator_h___

Просмотреть файл

@ -142,9 +142,10 @@ public:
* cannot coexist with aContinueSelection
* @param aHint will tell the selection which direction geometrically to actually show the caret on.
* 1 = end of this line 0 = beggining of this line
* @param aIsCell will tell us if this range describes a Cell.
*/
NS_IMETHOD HandleClick(nsIContent *aNewFocus, PRUint32 aContentOffset, PRUint32 aContentEndOffset ,
PRBool aContinueSelection, PRBool aMultipleSelection, PRBool aHint) = 0;
PRBool aContinueSelection, PRBool aMultipleSelection, PRBool aHint, PRBool aIsCell) = 0;
/** HandleDrag extends the selection to contain the frame closest to aPoint.
* @param aPresContext is the context to use when figuring out what frame contains the point.

Просмотреть файл

@ -320,6 +320,12 @@ NS_IMETHODIMP nsCaret::NotifySelectionChanged()
return NS_OK;
}
NS_IMETHODIMP nsCaret::TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset)
{
//stub
return NS_OK;
}
#ifdef XP_MAC
#pragma mark -
#endif

Просмотреть файл

@ -58,6 +58,7 @@ class nsCaret : public nsICaret,
//nsIDOMSelectionListener interface
NS_IMETHOD NotifySelectionChanged();
NS_IMETHOD TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset);
static void CaretBlinkCallback(nsITimer *aTimer, void *aClosure);

Просмотреть файл

@ -33,10 +33,15 @@
#include "nsIContent.h"
#include "nsIDOMText.h"
#include "nsISupportsArray.h"
#include "nsIFocusTracker.h"
#include "nsCOMPtr.h"
#include "nsIPresContext.h"
#include "nsIComponentManager.h"
#include "nsLayoutCID.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
static NS_DEFINE_IID(kCSubtreeIteratorCID, NS_SUBTREEITERATOR_CID);
// couple of utility static functs
@ -159,6 +164,65 @@ private:
};
nsresult NS_NewContentIterator(nsIContentIterator** aInstancePtrResult);
nsresult NS_NewGeneratedContentIterator(nsIGeneratedContentIterator** aInstancePtrResult);
class nsGeneratedContentIterator : public nsContentIterator, nsIGeneratedContentIterator
{
public:
NS_DECL_ISUPPORTS
nsGeneratedContentIterator();
virtual ~nsGeneratedContentIterator();
// nsIGeneratedContentIterator interface methods ------------------------------
NS_IMETHOD Init(nsIFocusTracker *aTracker, nsIDOMRange* aRange, PRBool aSelectBefore, PRBool aSelectAfter);
NS_IMETHOD First();
NS_IMETHOD Last();
NS_IMETHOD Next();
NS_IMETHOD Prev();
NS_IMETHOD CurrentNode(nsIContent **aNode);
protected:
PRBool mSelectBefore;//set at init time
PRBool mSelectAfter;
nsCOMPtr<nsIContentIterator> mGenIter;//reset for every before and after
nsIFocusTracker *mTracker;//weak reference
nsresult FillGenIter(PRInt8 aSide);
PRInt8 mCurSideOfContent; //-1= before, 0 = current, 1=next
};
nsGeneratedContentIterator::nsGeneratedContentIterator()
:mSelectBefore(0),mSelectAfter(0), mCurSideOfContent(-1)
{
}
nsGeneratedContentIterator::~nsGeneratedContentIterator()
{
}
NS_IMPL_ADDREF_INHERITED(nsGeneratedContentIterator, nsContentIterator)
NS_IMPL_RELEASE_INHERITED(nsGeneratedContentIterator, nsContentIterator)
NS_IMETHODIMP
nsGeneratedContentIterator::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (nsnull == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(nsIGeneratedContentIterator::GetIID())) {
*aInstancePtr = NS_STATIC_CAST(nsIGeneratedContentIterator *,this);
NS_ADDREF_THIS();
return NS_OK;
}
return nsContentIterator::QueryInterface(aIID,aInstancePtr);
}
/******************************************************
@ -173,6 +237,14 @@ nsresult NS_NewContentIterator(nsIContentIterator** aInstancePtrResult)
return NS_ERROR_OUT_OF_MEMORY;
}
nsresult NS_NewGeneratedContentIterator(nsIContentIterator** aInstancePtrResult)
{
nsGeneratedContentIterator * iter = new nsGeneratedContentIterator();
if (iter)
return iter->QueryInterface(NS_GET_IID(nsIContentIterator), (void**) aInstancePtrResult);
return NS_ERROR_OUT_OF_MEMORY;
}
/******************************************************
* XPCOM cruft
@ -1086,4 +1158,478 @@ nsresult nsContentSubtreeIterator::GetTopAncestorInRange(
return NS_ERROR_FAILURE;
}
/******************************************************
* nsGeneratedSubtreeIterator
******************************************************/
nsresult NS_NewGeneratedSubtreeIterator(nsIGeneratedContentIterator** aInstancePtrResult);
class nsGeneratedSubTreeIterator : public nsContentSubtreeIterator, nsIGeneratedContentIterator
{
public:
NS_DECL_ISUPPORTS
nsGeneratedSubTreeIterator();
virtual ~nsGeneratedSubTreeIterator();
// nsIGeneratedContentIterator interface methods ------------------------------
NS_IMETHOD Init(nsIFocusTracker *aTracker, nsIContent* aRange, PRBool aSelectBefore, PRBool aSelectAfter);
NS_IMETHOD First();
NS_IMETHOD Last();
NS_IMETHOD Next();
NS_IMETHOD Prev();
NS_IMETHOD CurrentNode(nsIContent **aNode);
protected:
PRBool mSelectBefore;//set at init time
PRBool mSelectAfter;
nsCOMPtr<nsIContentIterator> mGenIter;//reset for every before and after
nsIFocusTracker *mTracker;//weak reference
nsresult FillGenIter(PRInt8 aSide);
PRInt8 mCurSideOfContent; //-1= before, 0 = current, 1=next
};
nsGeneratedSubTreeIterator::nsGeneratedSubTreeIterator()
:mSelectBefore(0),mSelectAfter(0), mCurSideOfContent(-1)
{
}
nsGeneratedSubTreeIterator::~nsGeneratedSubTreeIterator()
{
}
NS_IMPL_ADDREF_INHERITED(nsGeneratedSubTreeIterator, nsContentIterator)
NS_IMPL_RELEASE_INHERITED(nsGeneratedSubTreeIterator, nsContentIterator)
NS_IMETHODIMP
nsGeneratedSubTreeIterator::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (nsnull == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(nsIGeneratedContentIterator::GetIID())) {
*aInstancePtr = NS_STATIC_CAST(nsIGeneratedContentIterator *,this);
NS_ADDREF_THIS();
return NS_OK;
}
return nsContentSubtreeIterator::QueryInterface(aIID,aInstancePtr);
}
/******************************************************
* nsGeneratedSubTreeIterator
******************************************************/
nsresult nsGeneratedSubTreeIterator::Init(nsIFocusTracker *aTracker, nsIContent* aContent, PRBool aSelectBefore, PRBool aSelectAfter)
{
mTracker = aTracker;
mSelectBefore = aSelectBefore;
mSelectAfter = aSelectAfter;
return nsContentSubtreeIterator::Init(aContent);
}
nsresult nsGeneratedSubTreeIterator::First()
{
nsContentSubtreeIterator::First();
if (!mFirst)
return NS_ERROR_FAILURE;
mIsDone = PR_FALSE;
mGenIter = 0;
if (mSelectBefore)
{
mCurSideOfContent = -1;//get generated from in FRONT of this node
FillGenIter(mCurSideOfContent);
}
if (!mGenIter)
mCurSideOfContent = 0;
return NS_OK;
}
nsresult nsGeneratedSubTreeIterator::Next()
{
if (mIsDone)
return NS_OK;
if (!mCurNode)
return NS_OK;
nsresult result = NS_OK;
if (mGenIter)
{
result = mGenIter->Next();
if (NS_FAILED(result) || (NS_SUCCEEDED(mGenIter->IsDone()) ))
{
mGenIter = 0;
}
else
return result;
}
if (mCurNode == mLast && !mGenIter)
{
mIsDone = PR_TRUE;
return NS_OK;
}
mCurSideOfContent ++;
if (mCurSideOfContent > 0)//current node currently
{
FillGenIter(mCurSideOfContent);
}
if (!mGenIter) //nothing after current node
{
mCurSideOfContent = -1;
result = nsContentSubtreeIterator::NextNode(&mCurNode);
FillGenIter(mCurSideOfContent);
if (!mGenIter)//nothing before new node.
mCurSideOfContent = 0;//advance to actual node
}
return result;
}
nsresult nsGeneratedSubTreeIterator::Prev()
{
if (mIsDone)
return NS_OK;
if (!mCurNode)
return NS_OK;
nsresult result = NS_OK;
if (mGenIter)
{
result = mGenIter->Prev();
if (NS_FAILED(result) || (NS_SUCCEEDED(mGenIter->IsDone()) ))
{
mGenIter = 0;
}
else
return result;
}
if (mCurNode == mFirst && !mGenIter)
{
mIsDone = PR_TRUE;
return NS_OK;
}
mCurSideOfContent --;
if (mCurSideOfContent < 0)//current node currently
{
FillGenIter(mCurSideOfContent);
}
if (!mGenIter) //nothing after current node
{
mCurSideOfContent = 1;
result = nsContentSubtreeIterator::PrevNode(&mCurNode);
FillGenIter(mCurSideOfContent);
if (!mGenIter)//nothing before new node.
mCurSideOfContent = 0;//advance to actual node
}
return result;
}
nsresult nsGeneratedSubTreeIterator::Last()
{
if (!mLast)
return NS_ERROR_FAILURE;
nsContentSubtreeIterator::Last();
mGenIter = 0;
mIsDone = PR_FALSE;
if (mSelectAfter)
{
mCurSideOfContent = 1;
FillGenIter(mCurSideOfContent);
}
if (!mGenIter)
mCurSideOfContent = 0;
return NS_OK;
}
nsresult
nsGeneratedSubTreeIterator::FillGenIter(PRInt8 aSide)
{
if (!mCurNode || !mTracker)
return NS_ERROR_NULL_POINTER;
nsresult result;
if (aSide == 0)
return NS_OK;
nsFrameState frameState;
nsIFrame *genFrame;
result = mTracker->GetPrimaryFrameFor(mCurNode, &genFrame);
if (NS_FAILED(result))
return result;
if (!genFrame)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIPresContext> context;
result = mTracker->GetPresContext(getter_AddRefs(context));
if (NS_FAILED(result) || !context)
return result?result:NS_ERROR_FAILURE;
result = genFrame->FirstChild(context,nsnull,&genFrame);
if (NS_FAILED(result) || !genFrame)
return NS_OK;//fine nothing to do here
if (aSide < 0)
{
//we SHOULD now have a generated content frame if one exists. we need to check the flag for gen content
result = genFrame->GetFrameState(&frameState);
if (NS_FAILED(result))
return result;
}
else if (aSide > 0)
{
nsIFrame *nextFrame = genFrame;
while(nextFrame)
{
result = nextFrame->GetNextSibling(&nextFrame);
if (NS_SUCCEEDED(result) && nextFrame)
genFrame = nextFrame;
else
nextFrame = nsnull;
}
}
if (frameState & NS_FRAME_GENERATED_CONTENT) {
nsCOMPtr<nsIContent> content;
result = genFrame->GetContent(getter_AddRefs(content));
if (NS_FAILED(result) || !content)
return result ? result:NS_ERROR_FAILURE;
result = nsComponentManager::CreateInstance(kCSubtreeIteratorCID, nsnull,
NS_GET_IID(nsIContentIterator),
getter_AddRefs(mGenIter));
if (NS_FAILED(result) || !mGenIter)
return result ? result:NS_ERROR_FAILURE;
mGenIter->Init(content);
if (aSide > 0)
mGenIter->Last();
}
return NS_OK;
}
nsresult nsGeneratedSubTreeIterator::CurrentNode(nsIContent **aNode)
{
if (!mCurNode)
return NS_ERROR_FAILURE;
if (mIsDone)
return NS_ERROR_FAILURE;
if (mGenIter)
return mGenIter->CurrentNode(aNode);
return mCurNode->QueryInterface(nsIContent::GetIID(), (void**) aNode);
}
/******************************************************
* nsGeneratedContentIterator
******************************************************/
nsresult nsGeneratedContentIterator::Init(nsIFocusTracker *aTracker, nsIDOMRange* aRange, PRBool aSelectBefore, PRBool aSelectAfter)
{
mTracker = aTracker;
mSelectBefore = aSelectBefore;
mSelectAfter = aSelectAfter;
return nsContentIterator::Init(aRange);
}
nsresult nsGeneratedContentIterator::First()
{
nsContentIterator::First();
if (!mFirst)
return NS_ERROR_FAILURE;
mIsDone = PR_FALSE;
mGenIter = 0;
if (mSelectBefore)
{
mCurSideOfContent = -1;//get generated from in FRONT of this node
FillGenIter(mCurSideOfContent);
}
if (!mGenIter)
mCurSideOfContent = 0;
return NS_OK;
}
nsresult nsGeneratedContentIterator::Next()
{
if (mIsDone)
return NS_OK;
if (!mCurNode)
return NS_OK;
nsresult result = NS_OK;
if (mGenIter)
{
result = mGenIter->Next();
if (NS_FAILED(result) || (NS_SUCCEEDED(mGenIter->IsDone()) ))
{
mGenIter = 0;
}
else
return result;
}
if (mCurNode == mLast && !mGenIter)
{
mIsDone = PR_TRUE;
return NS_OK;
}
mCurSideOfContent ++;
if (mCurSideOfContent > 0)//current node currently
{
FillGenIter(mCurSideOfContent);
}
if (!mGenIter) //nothing after current node
{
mCurSideOfContent = -1;
result = nsContentIterator::NextNode(&mCurNode);
FillGenIter(mCurSideOfContent);
if (!mGenIter)//nothing before new node.
mCurSideOfContent = 0;//advance to actual node
}
return result;
}
nsresult nsGeneratedContentIterator::Prev()
{
if (mIsDone)
return NS_OK;
if (!mCurNode)
return NS_OK;
nsresult result = NS_OK;
if (mGenIter)
{
result = mGenIter->Prev();
if (NS_FAILED(result) || (NS_SUCCEEDED(mGenIter->IsDone()) ))
{
mGenIter = 0;
}
else
return result;
}
if (mCurNode == mFirst && !mGenIter)
{
mIsDone = PR_TRUE;
return NS_OK;
}
mCurSideOfContent --;
if (mCurSideOfContent < 0)//current node currently
{
FillGenIter(mCurSideOfContent);
}
if (!mGenIter) //nothing after current node
{
mCurSideOfContent = 1;
result = nsContentIterator::PrevNode(&mCurNode);
FillGenIter(mCurSideOfContent);
if (!mGenIter)//nothing before new node.
mCurSideOfContent = 0;//advance to actual node
}
return result;
}
nsresult nsGeneratedContentIterator::Last()
{
nsContentIterator::Last();
if (!mLast)
return NS_ERROR_FAILURE;
mGenIter = 0;
mIsDone = PR_FALSE;
mCurNode = mLast;
mCurSideOfContent = 1;
FillGenIter(mCurSideOfContent);
if (!mGenIter)
mCurSideOfContent = 0;
return NS_OK;
}
nsresult
nsGeneratedContentIterator::FillGenIter(PRInt8 aSide)
{
if (!mCurNode || !mTracker)
return NS_ERROR_NULL_POINTER;
nsresult result;
if (aSide == 0)
return NS_OK;
nsFrameState frameState;
nsIFrame *genFrame;
result = mTracker->GetPrimaryFrameFor(mCurNode, &genFrame);
if (NS_FAILED(result))
return result;
if (!genFrame)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIPresContext> context;
result = mTracker->GetPresContext(getter_AddRefs(context));
if (NS_FAILED(result) || !context)
return result?result:NS_ERROR_FAILURE;
result = genFrame->FirstChild(context,nsnull,&genFrame);
if (NS_FAILED(result) || !genFrame)
return NS_OK;//fine nothing to do here
if (aSide < 0)
{
//we SHOULD now have a generated content frame if one exists. we need to check the flag for gen content
result = genFrame->GetFrameState(&frameState);
if (NS_FAILED(result))
return result;
}
else if (aSide > 0)
{
nsIFrame *nextFrame = genFrame;
while(nextFrame)
{
result = nextFrame->GetNextSibling(&nextFrame);
if (NS_SUCCEEDED(result) && nextFrame)
genFrame = nextFrame;
else
nextFrame = nsnull;
}
}
if (frameState & NS_FRAME_GENERATED_CONTENT) {
nsCOMPtr<nsIContent> content;
result = genFrame->GetContent(getter_AddRefs(content));
if (NS_FAILED(result) || !content)
return result ? result:NS_ERROR_FAILURE;
result = nsComponentManager::CreateInstance(kCSubtreeIteratorCID, nsnull,
NS_GET_IID(nsIContentIterator),
getter_AddRefs(mGenIter));
if (NS_FAILED(result) || !mGenIter)
return result ? result:NS_ERROR_FAILURE;
mGenIter->Init(content);
if (aSide > 0)
mGenIter->Last();
}
return NS_OK;
}
nsresult nsGeneratedContentIterator::CurrentNode(nsIContent **aNode)
{
if (!mCurNode)
return NS_ERROR_FAILURE;
if (mIsDone)
return NS_ERROR_FAILURE;
if (mGenIter)
return mGenIter->CurrentNode(aNode);
return mCurNode->QueryInterface(nsIContent::GetIID(), (void**) aNode);
}

Просмотреть файл

@ -1609,3 +1609,10 @@ NS_IMETHODIMP DocumentViewerImpl::NotifySelectionChanged(void)
// to the right nsIDOMXULCommandDispatcher yet.
return NS_OK;
}
NS_IMETHODIMP DocumentViewerImpl::TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset)
{
//stub
return NS_OK;
}

Просмотреть файл

@ -58,6 +58,7 @@ nsVoidArray* nsRange::mStartAncestorOffsets = nsnull;
nsVoidArray* nsRange::mEndAncestorOffsets = nsnull;
nsresult NS_NewContentIterator(nsIContentIterator** aInstancePtrResult);
nsresult NS_NewGeneratedContentIterator(nsIContentIterator** aInstancePtrResult);
/******************************************************
@ -1974,6 +1975,44 @@ nsRange::IsValidFragment(const nsString& aFragment, PRBool* aReturn)
return result;
}
NS_IMETHODIMP
nsRange::GetHasGeneratedBefore(PRBool *aBool)
{
NS_ENSURE_ARG_POINTER(aBool);
*aBool = mBeforeGenContent;
return NS_OK;
}
NS_IMETHODIMP
nsRange::GetHasGeneratedAfter(PRBool *aBool)
{
NS_ENSURE_ARG_POINTER(aBool);
*aBool = mAfterGenContent;
return NS_OK;
}
NS_IMETHODIMP
nsRange::SetHasGeneratedBefore(PRBool aBool)
{
mBeforeGenContent = aBool;
return NS_OK;
}
NS_IMETHODIMP
nsRange::SetHasGeneratedAfter(PRBool aBool)
{
mAfterGenContent = aBool;
return NS_OK;
}
NS_IMETHODIMP
nsRange::SetBeforeAndAfter(PRBool aBefore, PRBool aAfter)
{
mBeforeGenContent = aBefore;
mBeforeGenContent = aAfter;
return NS_OK;
}
// BEGIN nsIScriptObjectOwner interface implementations
NS_IMETHODIMP
nsRange::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)

Просмотреть файл

@ -94,12 +94,18 @@ public:
NS_IMETHOD CreateContextualFragment(const nsString& aFragment,
nsIDOMDocumentFragment** aReturn);
NS_IMETHOD IsValidFragment(const nsString& aFragment, PRBool* aReturn);
NS_IMETHOD GetHasGeneratedBefore(PRBool *aBool);
NS_IMETHOD GetHasGeneratedAfter(PRBool *aBool);
NS_IMETHOD SetHasGeneratedBefore(PRBool aBool);
NS_IMETHOD SetHasGeneratedAfter(PRBool aBool);
NS_IMETHOD SetBeforeAndAfter(PRBool aBefore, PRBool aAfter);
/*BEGIN nsIScriptObjectOwner interface implementations*/
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
/*END nsIScriptObjectOwner interface implementations*/
// nsRange interface extensions
static NS_METHOD OwnerGone(nsIContent* aParentNode);
@ -169,6 +175,8 @@ public:
protected:
void* mScriptObject;
PRBool mBeforeGenContent;
PRBool mAfterGenContent;
};

Просмотреть файл

@ -216,7 +216,7 @@ public:
NS_IMETHOD HandleTextEvent(nsGUIEvent *aGUIEvent);
NS_IMETHOD HandleKeyEvent(nsIPresContext* aPresContext, nsGUIEvent *aGuiEvent);
NS_IMETHOD HandleClick(nsIContent *aNewFocus, PRUint32 aContentOffset, PRUint32 aContentEndOffset,
PRBool aContinueSelection, PRBool aMultipleSelection,PRBool aHint);
PRBool aContinueSelection, PRBool aMultipleSelection,PRBool aHint, PRBool aIsCell);
NS_IMETHOD HandleDrag(nsIPresContext *aPresContext, nsIFrame *aFrame, nsPoint& aPoint);
NS_IMETHOD StartAutoScrollTimer(nsIPresContext *aPresContext, nsIFrame *aFrame, nsPoint& aPoint, PRUint32 aDelay);
NS_IMETHOD StopAutoScrollTimer();
@ -274,6 +274,8 @@ private:
void SetDirty(PRBool aDirty=PR_TRUE){if (mBatching) mChangesDuringBatching = aDirty;}
nsresult NotifySelectionListeners(); // add parameters to say collapsed etc?
nsresult NotifySelectionListeners(nsIDOMNode *aNode, PRUint32 aCellOffset);
nsDOMSelection *mDomSelections[NUM_SELECTIONTYPES];
@ -1348,10 +1350,15 @@ nsDOMSelection::ToString(nsString& aReturn)
NS_IMETHODIMP
nsRangeList::HandleClick(nsIContent *aNewFocus, PRUint32 aContentOffset,
PRUint32 aContentEndOffset, PRBool aContinueSelection,
PRBool aMultipleSelection, PRBool aHint)
PRBool aMultipleSelection, PRBool aHint, PRBool aIsCell)
{
InvalidateDesiredX();
mHint = HINT(aHint);
if (aIsCell)
{
nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(aNewFocus);
return NotifySelectionListeners(domNode, aContentOffset);
}
return TakeFocus(aNewFocus, aContentOffset, aContentEndOffset, aContinueSelection, aMultipleSelection);
}
@ -1390,7 +1397,7 @@ nsRangeList::HandleDrag(nsIPresContext *aPresContext, nsIFrame *aFrame, nsPoint&
startPos, contentOffsetEnd,beginOfContent);
if (NS_SUCCEEDED(result))
result = HandleClick(newContent, startPos, contentOffsetEnd , PR_TRUE, PR_FALSE,beginOfContent);
result = HandleClick(newContent, startPos, contentOffsetEnd , PR_TRUE, PR_FALSE,beginOfContent, PR_FALSE);
return result;
}
@ -1793,6 +1800,26 @@ nsRangeList::NotifySelectionListeners()
return NS_OK;
}
nsresult
nsRangeList::NotifySelectionListeners(nsIDOMNode *aNode, PRUint32 aCellOffset)
{
if (!mSelectionListeners)
return NS_ERROR_FAILURE;
PRUint32 cnt;
nsresult rv = mSelectionListeners->Count(&cnt);
if (NS_FAILED(rv)) return rv;
for (PRUint32 i = 0; i < cnt;i++)
{
nsCOMPtr<nsISupports> isupports(dont_AddRef(mSelectionListeners->ElementAt(i)));
nsCOMPtr<nsIDOMSelectionListener> thisListener = do_QueryInterface(isupports);
if (thisListener)
thisListener->TableCellNotification(aNode,aCellOffset);
}
return NS_OK;
}
//END nsIFrameSelection methods
#ifdef XP_MAC

Просмотреть файл

@ -58,6 +58,7 @@
#include "nsCOMPtr.h"
#include "nsStyleChangeList.h"
#include "nsIDOMRange.h"
#include "nsITableCellLayout.h"//selection neccesity
#define NORMAL_DRAG_HANDLING 1 // remove this to simulate a start-drag event.
@ -865,13 +866,40 @@ nsFrame::HandlePress(nsIPresContext* aPresContext,
nsCOMPtr<nsIFrameSelection> frameselection;
if (NS_SUCCEEDED(shell->GetFrameSelection(getter_AddRefs(frameselection))) && frameselection){
frameselection->SetMouseDownState(PR_TRUE);//not important if it fails here
PRBool doMultipleSelection;
PRBool doCellSelection;
#ifdef XP_MAC
doMultipleSelection = me->isMeta;
doCellSelection = me->isMeta;
#else
doMultipleSelection = me->isControl;
doCellSelection = me->isControl;
#endif
frameselection->HandleClick(newContent, startPos , contentOffsetEnd , me->isShift, doMultipleSelection, beginContent);
nsIFrame *cellFrame;
if (doCellSelection)
{
nsresult result = GrabContainingCell(&cellFrame);
if (NS_SUCCEEDED(result) && cellFrame)
{
nsIContent* cellContent;
result = cellFrame->GetContent(&cellContent);
if (NS_SUCCEEDED(result) && cellContent)
{
nsIContent* parentContent;
result = cellContent->GetParent(parentContent);
if (parentContent){
PRInt32 newIndex;
result = parentContent->IndexOf(cellContent, newIndex);
if (NS_SUCCEEDED(result) && newIndex >= 0)
{
frameselection->HandleClick(parentContent,newIndex, newIndex+1,me->isShift,PR_FALSE, beginContent, PR_TRUE);
}
NS_IF_RELEASE(parentContent);
}
NS_IF_RELEASE(cellContent);
}
}
}
else
frameselection->HandleClick(newContent, startPos , contentOffsetEnd , me->isShift, PR_FALSE, beginContent, PR_FALSE);
}
//no release
}
@ -2710,6 +2738,24 @@ nsFrame::GetFirstLeaf(nsIPresContext* aPresContext, nsIFrame **aFrame)
}
}
NS_IMETHODIMP
nsFrame::GrabContainingCell(nsIFrame **aCellFrame)
{
*aCellFrame = this;
nsresult result = NS_OK;
while (*aCellFrame && NS_SUCCEEDED(result))
{
nsITableCellLayout *cellelement;
result = (*aCellFrame)->QueryInterface(nsITableCellLayout::GetIID(), (void **)&cellelement);
if (NS_SUCCEEDED(result) && cellelement)
return NS_OK;
else
result = (*aCellFrame)->GetParent(aCellFrame);
}
return result?result:NS_ERROR_FAILURE;
}
nsresult nsFrame::CreateAndPostReflowCommand(nsIPresShell* aPresShell,
nsIFrame* aTargetFrame,
nsIReflowCommand::ReflowType aReflowType,

Просмотреть файл

@ -401,7 +401,8 @@ protected:
//given a frame five me the first/last leaf available
static void GetLastLeaf(nsIPresContext* aPresContext, nsIFrame **aFrame);
static void GetFirstLeaf(nsIPresContext* aPresContext, nsIFrame **aFrame);
//grab this as the closest cell or go up the chain till nothing or a cell
NS_IMETHOD GrabContainingCell(nsIFrame **aCellFrame);
static void XMLQuote(nsString& aString);
virtual PRBool ParentDisablesSelection() const;

Просмотреть файл

@ -58,6 +58,7 @@
#include "nsCOMPtr.h"
#include "nsStyleChangeList.h"
#include "nsIDOMRange.h"
#include "nsITableCellLayout.h"//selection neccesity
#define NORMAL_DRAG_HANDLING 1 // remove this to simulate a start-drag event.
@ -865,13 +866,40 @@ nsFrame::HandlePress(nsIPresContext* aPresContext,
nsCOMPtr<nsIFrameSelection> frameselection;
if (NS_SUCCEEDED(shell->GetFrameSelection(getter_AddRefs(frameselection))) && frameselection){
frameselection->SetMouseDownState(PR_TRUE);//not important if it fails here
PRBool doMultipleSelection;
PRBool doCellSelection;
#ifdef XP_MAC
doMultipleSelection = me->isMeta;
doCellSelection = me->isMeta;
#else
doMultipleSelection = me->isControl;
doCellSelection = me->isControl;
#endif
frameselection->HandleClick(newContent, startPos , contentOffsetEnd , me->isShift, doMultipleSelection, beginContent);
nsIFrame *cellFrame;
if (doCellSelection)
{
nsresult result = GrabContainingCell(&cellFrame);
if (NS_SUCCEEDED(result) && cellFrame)
{
nsIContent* cellContent;
result = cellFrame->GetContent(&cellContent);
if (NS_SUCCEEDED(result) && cellContent)
{
nsIContent* parentContent;
result = cellContent->GetParent(parentContent);
if (parentContent){
PRInt32 newIndex;
result = parentContent->IndexOf(cellContent, newIndex);
if (NS_SUCCEEDED(result) && newIndex >= 0)
{
frameselection->HandleClick(parentContent,newIndex, newIndex+1,me->isShift,PR_FALSE, beginContent, PR_TRUE);
}
NS_IF_RELEASE(parentContent);
}
NS_IF_RELEASE(cellContent);
}
}
}
else
frameselection->HandleClick(newContent, startPos , contentOffsetEnd , me->isShift, PR_FALSE, beginContent, PR_FALSE);
}
//no release
}
@ -2710,6 +2738,24 @@ nsFrame::GetFirstLeaf(nsIPresContext* aPresContext, nsIFrame **aFrame)
}
}
NS_IMETHODIMP
nsFrame::GrabContainingCell(nsIFrame **aCellFrame)
{
*aCellFrame = this;
nsresult result = NS_OK;
while (*aCellFrame && NS_SUCCEEDED(result))
{
nsITableCellLayout *cellelement;
result = (*aCellFrame)->QueryInterface(nsITableCellLayout::GetIID(), (void **)&cellelement);
if (NS_SUCCEEDED(result) && cellelement)
return NS_OK;
else
result = (*aCellFrame)->GetParent(aCellFrame);
}
return result?result:NS_ERROR_FAILURE;
}
nsresult nsFrame::CreateAndPostReflowCommand(nsIPresShell* aPresShell,
nsIFrame* aTargetFrame,
nsIReflowCommand::ReflowType aReflowType,

Просмотреть файл

@ -401,7 +401,8 @@ protected:
//given a frame five me the first/last leaf available
static void GetLastLeaf(nsIPresContext* aPresContext, nsIFrame **aFrame);
static void GetFirstLeaf(nsIPresContext* aPresContext, nsIFrame **aFrame);
//grab this as the closest cell or go up the chain till nothing or a cell
NS_IMETHOD GrabContainingCell(nsIFrame **aCellFrame);
static void XMLQuote(nsString& aString);
virtual PRBool ParentDisablesSelection() const;

Просмотреть файл

@ -35,6 +35,7 @@
class nsIHTMLTableCellElement : public nsISupports
{
public:
static const nsIID& GetIID() { static nsIID iid = NS_IHTMLTABLECELLELEMENT_IID; return iid; }
/** @return the starting column for this cell. Always >= 1 */
NS_IMETHOD GetColIndex (PRInt32* aColIndex) = 0;

Просмотреть файл

@ -4094,6 +4094,13 @@ nsEnderEventListener::NotifySelectionChanged()
return NS_OK;
}
NS_IMETHODIMP
nsEnderEventListener::TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset)
{
//stub
return NS_OK;
}
/*******************************************************************************

Просмотреть файл

@ -271,6 +271,7 @@ public:
* @see nsIDOMSelectionListener
*/
NS_IMETHOD NotifySelectionChanged();
NS_IMETHOD TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset);
/*END interfaces from nsIDOMSelectionListener*/
friend nsresult NS_NewEnderEventListener(nsIEnderEventListener ** aInstancePtrResult);

Просмотреть файл

@ -858,13 +858,27 @@ nsCSSFrameConstructor::CreateGeneratedContentFrame(nsIPresShell* aPresShe
// the 'display' property
nsIFrame* containerFrame;
nsFrameItems childFrames;
nsCOMPtr<nsIDOMElement>containerElement;
nsCOMPtr<nsIContent> containerContent;
nsCOMPtr<nsIDocument> document;
aContent->GetDocument(*getter_AddRefs(document));
nsCOMPtr<nsIDOMDocument> domdoc(do_QueryInterface(document));
nsresult result;
result = domdoc->CreateElement("SPAN",getter_AddRefs(containerElement));//is the literal the correct way?
if (NS_SUCCEEDED(result) && containerElement)
{
containerContent = do_QueryInterface(containerElement);
}
if (NS_STYLE_DISPLAY_BLOCK == displayValue) {
NS_NewBlockFrame(aPresShell, &containerFrame);
} else {
NS_NewInlineFrame(aPresShell, &containerFrame);
}
InitAndRestoreFrame(aPresContext, aState, aContent,
InitAndRestoreFrame(aPresContext, aState, containerContent?containerContent:aContent,
aFrame, pseudoStyleContext, nsnull, containerFrame);
// Mark the frame as being associated with generated content
@ -882,8 +896,6 @@ nsCSSFrameConstructor::CreateGeneratedContentFrame(nsIPresShell* aPresShe
// Now create content objects (and child frames) for each value of the
// 'content' property
nsCOMPtr<nsIDocument> document;
aContent->GetDocument(*getter_AddRefs(document));
for (PRUint32 contentIndex = 0; contentIndex < contentCount; contentIndex++) {
nsIFrame* frame;