зеркало из https://github.com/mozilla/gecko-dev.git
Fixes for bugs: 18193, 13971, 23440, 18444, 21462, 21818, 22619, 23498, 24081, and 21972. r=just about everybody.
This commit is contained in:
Родитель
60e2eca42b
Коммит
0dfb94bf0a
|
@ -1794,6 +1794,19 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aParent, nsIContent* aCh
|
|||
disabled = PR_FALSE;
|
||||
}
|
||||
|
||||
// Get the primary frame for the widget. We don't tab into anything
|
||||
// that doesn't have a frame.
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
if (mPresContext) {
|
||||
nsresult rv = mPresContext->GetShell(getter_AddRefs(shell));
|
||||
if (NS_SUCCEEDED(rv) && shell){
|
||||
nsIFrame* potentialFrame;
|
||||
shell->GetPrimaryFrameFor(child, &potentialFrame);
|
||||
if (!potentialFrame)
|
||||
hidden = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
//TabIndex not set (-1) treated at same level as set to 0
|
||||
tabIndex = tabIndex < 0 ? 0 : tabIndex;
|
||||
|
||||
|
|
|
@ -55,6 +55,10 @@ public:
|
|||
|
||||
NS_IMETHOD GenerateAnonymousContent(nsIContent* aBoundElement) = 0;
|
||||
NS_IMETHOD InstallEventHandlers(nsIContent* aBoundElement) = 0;
|
||||
|
||||
// Called when an attribute changes on a binding.
|
||||
NS_IMETHOD AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag) = 0;
|
||||
|
||||
};
|
||||
|
||||
extern nsresult
|
||||
|
|
|
@ -24,6 +24,38 @@
|
|||
// Static IIDs/CIDs. Try to minimize these.
|
||||
// None
|
||||
|
||||
// Helper classes
|
||||
// {A2892B81-CED9-11d3-97FB-00400553EEF0}
|
||||
#define NS_IXBLATTR_IID \
|
||||
{ 0xa2892b81, 0xced9, 0x11d3, { 0x97, 0xfb, 0x0, 0x40, 0x5, 0x53, 0xee, 0xf0 } }
|
||||
|
||||
class nsIXBLAttributeEntry : public nsISupports {
|
||||
public:
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_IXBLATTR_IID; return iid; }
|
||||
|
||||
NS_IMETHOD GetAttribute(nsIAtom** aResult) = 0;
|
||||
NS_IMETHOD GetElement(nsIContent** aResult) = 0;
|
||||
};
|
||||
|
||||
|
||||
class nsXBLAttributeEntry : public nsIXBLAttributeEntry {
|
||||
public:
|
||||
NS_IMETHOD GetAttribute(nsIAtom** aResult) { *aResult = mAttribute; NS_IF_ADDREF(*aResult); return NS_OK; };
|
||||
NS_IMETHOD GetElement(nsIContent** aResult) { *aResult = mElement; NS_IF_ADDREF(*aResult); return NS_OK; };
|
||||
|
||||
nsCOMPtr<nsIContent> mElement;
|
||||
nsCOMPtr<nsIAtom> mAttribute;
|
||||
|
||||
nsXBLAttributeEntry(nsIAtom* aAtom, nsIContent* aContent) {
|
||||
NS_INIT_REFCNT(); mAttribute = aAtom; mElement = aContent;
|
||||
};
|
||||
|
||||
virtual ~nsXBLAttributeEntry() {};
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsXBLAttributeEntry, nsIXBLAttributeEntry)
|
||||
|
||||
class nsXBLBinding: public nsIXBLBinding
|
||||
{
|
||||
|
@ -41,6 +73,8 @@ class nsXBLBinding: public nsIXBLBinding
|
|||
NS_IMETHOD GenerateAnonymousContent(nsIContent* aBoundElement);
|
||||
NS_IMETHOD InstallEventHandlers(nsIContent* aBoundElement);
|
||||
|
||||
NS_IMETHOD AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag);
|
||||
|
||||
public:
|
||||
nsXBLBinding();
|
||||
virtual ~nsXBLBinding();
|
||||
|
@ -59,6 +93,8 @@ protected:
|
|||
void GetImmediateChild(nsIAtom* aTag, nsIContent** aResult);
|
||||
PRBool IsInExcludesList(nsIAtom* aTag, const nsString& aList);
|
||||
|
||||
NS_IMETHOD ConstructAttributeTable(nsIContent* aElement);
|
||||
|
||||
// MEMBER VARIABLES
|
||||
protected:
|
||||
nsCOMPtr<nsIContent> mBinding; // Strong. As long as we're around, the binding can't go away.
|
||||
|
@ -66,6 +102,7 @@ protected:
|
|||
nsCOMPtr<nsIXBLBinding> mNextBinding; // Strong. The derived binding owns the base class bindings.
|
||||
|
||||
nsIContent* mBoundElement; // [WEAK] We have a reference, but we don't own it.
|
||||
nsSupportsHashtable* mAttributeTable; // A table for attribute entries.
|
||||
};
|
||||
|
||||
// Static initialization
|
||||
|
@ -84,6 +121,7 @@ NS_IMPL_ISUPPORTS1(nsXBLBinding, nsIXBLBinding)
|
|||
|
||||
// Constructors/Destructors
|
||||
nsXBLBinding::nsXBLBinding(void)
|
||||
:mAttributeTable(nsnull)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
gRefCnt++;
|
||||
|
@ -156,6 +194,11 @@ nsXBLBinding::SetAnonymousContent(nsIContent* aParent)
|
|||
child->SetParent(mBoundElement);
|
||||
}
|
||||
|
||||
// (3) We need to insert entries into our attribute table for any elements
|
||||
// that are inheriting attributes. This table allows us to quickly determine
|
||||
// which elements in our anonymous content need to be updated when attributes change.
|
||||
ConstructAttributeTable(aParent);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -201,7 +244,7 @@ nsXBLBinding::GenerateAnonymousContent(nsIContent* aBoundElement)
|
|||
// in the excludes list.
|
||||
nsAutoString excludes;
|
||||
content->GetAttribute(kNameSpaceID_None, kExcludesAtom, excludes);
|
||||
if (excludes == "true") {
|
||||
if (excludes != "") {
|
||||
// Walk the children and ensure that all of them
|
||||
// are in the excludes array.
|
||||
for (PRInt32 i = 0; i < childCount; i++) {
|
||||
|
@ -242,6 +285,54 @@ nsXBLBinding::InstallEventHandlers(nsIContent* aBoundElement)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLBinding::AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag)
|
||||
{
|
||||
if (mNextBinding)
|
||||
mNextBinding->AttributeChanged(aAttribute, aNameSpaceID, aRemoveFlag);
|
||||
|
||||
if (!mAttributeTable)
|
||||
return NS_OK;
|
||||
|
||||
nsISupportsKey key(aAttribute);
|
||||
nsCOMPtr<nsISupports> supports = getter_AddRefs(NS_STATIC_CAST(nsISupports*,
|
||||
mAttributeTable->Get(&key)));
|
||||
|
||||
nsCOMPtr<nsISupportsArray> entry = do_QueryInterface(supports);
|
||||
if (!entry)
|
||||
return NS_OK;
|
||||
|
||||
// Iterate over the elements in the array.
|
||||
PRUint32 count;
|
||||
entry->Count(&count);
|
||||
|
||||
for (PRUint32 i=0; i<count; i++) {
|
||||
nsCOMPtr<nsISupports> item;
|
||||
entry->GetElementAt(i, getter_AddRefs(item));
|
||||
nsCOMPtr<nsIXBLAttributeEntry> xblAttr = do_QueryInterface(item);
|
||||
if (xblAttr) {
|
||||
nsCOMPtr<nsIContent> element;
|
||||
nsCOMPtr<nsIAtom> setAttr;
|
||||
xblAttr->GetElement(getter_AddRefs(element));
|
||||
xblAttr->GetAttribute(getter_AddRefs(setAttr));
|
||||
|
||||
if (aRemoveFlag)
|
||||
element->UnsetAttribute(aNameSpaceID, setAttr, PR_TRUE);
|
||||
else {
|
||||
nsAutoString value;
|
||||
nsresult result = mBoundElement->GetAttribute(aNameSpaceID, aAttribute, value);
|
||||
PRBool attrPresent = (result == NS_CONTENT_ATTR_NO_VALUE ||
|
||||
result == NS_CONTENT_ATTR_HAS_VALUE);
|
||||
|
||||
if (attrPresent)
|
||||
element->SetAttribute(aNameSpaceID, setAttr, value, PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Internal helper methods ////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
|
@ -296,6 +387,92 @@ nsXBLBinding::IsInExcludesList(nsIAtom* aTag, const nsString& aList)
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLBinding::ConstructAttributeTable(nsIContent* aElement)
|
||||
{
|
||||
// XXX This function still needs to deal with the
|
||||
// ability to map one attribute to another.
|
||||
nsAutoString inherits;
|
||||
aElement->GetAttribute(kNameSpaceID_None, kInheritsAtom, inherits);
|
||||
if (inherits != "") {
|
||||
if (!mAttributeTable) {
|
||||
mAttributeTable = new nsSupportsHashtable(8);
|
||||
}
|
||||
|
||||
// The user specified at least one attribute.
|
||||
char* str = inherits.ToNewCString();
|
||||
char* newStr;
|
||||
char* token = nsCRT::strtok( str, ", ", &newStr );
|
||||
while( token != NULL ) {
|
||||
// Build an atom out of this attribute.
|
||||
nsCOMPtr<nsIAtom> atom;
|
||||
nsCOMPtr<nsIAtom> attribute;
|
||||
|
||||
// Figure out if this token contains a :.
|
||||
nsAutoString attr(token);
|
||||
PRInt32 index = attr.Find(":", PR_TRUE);
|
||||
if (index != -1) {
|
||||
// This attribute maps to something different.
|
||||
nsAutoString left, right;
|
||||
attr.Left(left, index);
|
||||
attr.Right(right, attr.Length()-index-1);
|
||||
|
||||
atom = getter_AddRefs(NS_NewAtom(left));
|
||||
attribute = getter_AddRefs(NS_NewAtom(right));
|
||||
}
|
||||
else {
|
||||
atom = getter_AddRefs(NS_NewAtom(token));
|
||||
attribute = getter_AddRefs(NS_NewAtom(token));
|
||||
}
|
||||
|
||||
// Create an XBL attribute entry.
|
||||
nsXBLAttributeEntry* xblAttr = new nsXBLAttributeEntry(attribute, aElement);
|
||||
|
||||
// Now we should see if some element within our anonymous
|
||||
// content is already observing this attribute.
|
||||
nsISupportsKey key(atom);
|
||||
nsCOMPtr<nsISupports> supports = getter_AddRefs(NS_STATIC_CAST(nsISupports*,
|
||||
mAttributeTable->Get(&key)));
|
||||
|
||||
nsCOMPtr<nsISupportsArray> entry = do_QueryInterface(supports);
|
||||
if (!entry) {
|
||||
// Make a new entry.
|
||||
NS_NewISupportsArray(getter_AddRefs(entry));
|
||||
|
||||
// Put it in the table.
|
||||
mAttributeTable->Put(&key, entry);
|
||||
}
|
||||
|
||||
// Append ourselves to our entry.
|
||||
entry->AppendElement(xblAttr);
|
||||
|
||||
// Now make sure that this attribute is initially set.
|
||||
// XXX How to deal with NAMESPACES!!!?
|
||||
nsAutoString value;
|
||||
nsresult result = mBoundElement->GetAttribute(kNameSpaceID_None, atom, value);
|
||||
PRBool attrPresent = (result == NS_CONTENT_ATTR_NO_VALUE ||
|
||||
result == NS_CONTENT_ATTR_HAS_VALUE);
|
||||
|
||||
if (attrPresent)
|
||||
aElement->SetAttribute(kNameSpaceID_None, attribute, value, PR_TRUE);
|
||||
|
||||
token = nsCRT::strtok( newStr, ", ", &newStr );
|
||||
}
|
||||
|
||||
nsAllocator::Free(str);
|
||||
}
|
||||
|
||||
// Recur into our children.
|
||||
PRInt32 childCount;
|
||||
aElement->ChildCount(childCount);
|
||||
for (PRInt32 i = 0; i < childCount; i++) {
|
||||
nsCOMPtr<nsIContent> child;
|
||||
aElement->ChildAt(i, *getter_AddRefs(child));
|
||||
ConstructAttributeTable(child);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Creation Routine ///////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "nsXMLDocument.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsSupportsArray.h"
|
||||
#include "nsITextContent.h"
|
||||
|
||||
#include "nsIXBLBinding.h"
|
||||
|
||||
|
@ -110,6 +111,10 @@ public:
|
|||
// This method synchronously loads and parses an XBL file.
|
||||
NS_IMETHOD FetchBindingDocument(nsIURI* aURI, nsIDocument** aResult);
|
||||
|
||||
// This method walks a binding document and removes any text nodes
|
||||
// that contain only whitespace.
|
||||
NS_IMETHOD StripWhitespaceNodes(nsIContent* aContent);
|
||||
|
||||
protected:
|
||||
// This URIkey class is used to hash URLs into an XBL binding
|
||||
// cache.
|
||||
|
@ -272,9 +277,7 @@ nsXBLService::GetContentList(nsIContent* aContent, nsISupportsArray** aResult)
|
|||
if (!(*aResult))
|
||||
NS_NewISupportsArray(aResult); // This call addrefs the array.
|
||||
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(anonymousChild);
|
||||
if (element) // Don't let the extra text frames get generated.
|
||||
(*aResult)->AppendElement(anonymousChild);
|
||||
(*aResult)->AppendElement(anonymousChild);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -460,6 +463,42 @@ nsXBLService::FetchBindingDocument(nsIURI* aURI, nsIDocument** aResult)
|
|||
// Everything worked, so we can just hand this back now.
|
||||
*aResult = doc;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
|
||||
// The XML content sink produces a ridiculous # of content nodes.
|
||||
// It generates text nodes even for whitespace. The following
|
||||
// call walks the generated document tree and trims out these
|
||||
// nodes.
|
||||
nsCOMPtr<nsIContent> root = getter_AddRefs(doc->GetRootContent());
|
||||
if (root)
|
||||
StripWhitespaceNodes(root);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLService::StripWhitespaceNodes(nsIContent* aElement)
|
||||
{
|
||||
PRInt32 childCount;
|
||||
aElement->ChildCount(childCount);
|
||||
for (PRInt32 i = 0; i < childCount; i++) {
|
||||
nsCOMPtr<nsIContent> child;
|
||||
aElement->ChildAt(i, *getter_AddRefs(child));
|
||||
nsCOMPtr<nsITextContent> text = do_QueryInterface(child);
|
||||
if (text) {
|
||||
nsAutoString result;
|
||||
text->CopyText(result);
|
||||
result.StripWhitespace();
|
||||
if (result == "") {
|
||||
// This node contained nothing but whitespace.
|
||||
// Remove it from the content model.
|
||||
aElement->RemoveChildAt(i, PR_TRUE);
|
||||
i--; // Decrement our count, since we just removed this child.
|
||||
childCount--; // Also decrement our total count.
|
||||
}
|
||||
}
|
||||
else StripWhitespaceNodes(child);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -2307,14 +2307,14 @@ nsXULElement::SetAttribute(PRInt32 aNameSpaceID,
|
|||
|
||||
// Check to see if the CLASS attribute is being set. If so, we need to rebuild our
|
||||
// class list.
|
||||
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && (aName == kClassAtom)) {
|
||||
if ((aNameSpaceID == kNameSpaceID_None) && (aName == kClassAtom)) {
|
||||
Attributes()->UpdateClassList(aValue);
|
||||
}
|
||||
|
||||
// Check to see if the STYLE attribute is being set. If so, we need to create a new
|
||||
// style rule based off the value of this attribute, and we need to let the document
|
||||
// know about the StyleRule change.
|
||||
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && (aName == kStyleAtom)) {
|
||||
if ((aNameSpaceID == kNameSpaceID_None) && (aName == kStyleAtom)) {
|
||||
nsCOMPtr <nsIURI> docURL;
|
||||
mDocument->GetBaseURL(*getter_AddRefs(docURL));
|
||||
Attributes()->UpdateStyleRule(docURL, aValue);
|
||||
|
@ -2421,8 +2421,12 @@ nsXULElement::SetAttribute(PRInt32 aNameSpaceID,
|
|||
}
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv) && aNotify && ElementIsInDocument()) {
|
||||
mDocument->AttributeChanged(NS_STATIC_CAST(nsIStyledContent*, this), aNameSpaceID, aName, NS_STYLE_HINT_UNKNOWN);
|
||||
if (NS_SUCCEEDED(rv) && aNotify) {
|
||||
if (Binding())
|
||||
Binding()->AttributeChanged(aName, aNameSpaceID, PR_FALSE);
|
||||
|
||||
if (mDocument)
|
||||
mDocument->AttributeChanged(NS_STATIC_CAST(nsIStyledContent*, this), aNameSpaceID, aName, NS_STYLE_HINT_UNKNOWN);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -2613,6 +2617,9 @@ nsXULElement::UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, PRBool aNotif
|
|||
|
||||
// Notify document
|
||||
if (NS_SUCCEEDED(rv) && aNotify && (nsnull != mDocument)) {
|
||||
if (Binding())
|
||||
Binding()->AttributeChanged(aName, aNameSpaceID, PR_TRUE);
|
||||
|
||||
mDocument->AttributeChanged(NS_STATIC_CAST(nsIStyledContent*, this),
|
||||
aNameSpaceID, aName,
|
||||
NS_STYLE_HINT_UNKNOWN);
|
||||
|
@ -3644,7 +3651,55 @@ nsXULElement::IsAncestor(nsIDOMNode* aParentNode, nsIDOMNode* aChildNode)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULElement::Focus()
|
||||
{
|
||||
// Make sure we're focusable.
|
||||
nsCOMPtr<nsIFocusableContent> focusable = do_QueryInterface((nsIStyledContent*)this);
|
||||
if (!focusable)
|
||||
return NS_OK;
|
||||
|
||||
// Obtain a presentation context and then call SetFocus.
|
||||
PRInt32 count = mDocument->GetNumberOfShells();
|
||||
if (count == 0)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell = getter_AddRefs(mDocument->GetShellAt(0));
|
||||
|
||||
// Retrieve the context
|
||||
nsCOMPtr<nsIPresContext> aPresContext;
|
||||
shell->GetPresContext(getter_AddRefs(aPresContext));
|
||||
|
||||
// Set focus
|
||||
return SetFocus(aPresContext);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULElement::Blur()
|
||||
{
|
||||
// Make sure we're focusable.
|
||||
nsCOMPtr<nsIFocusableContent> focusable = do_QueryInterface((nsIStyledContent*)this);
|
||||
if (!focusable)
|
||||
return NS_OK;
|
||||
|
||||
// Obtain a presentation context and then call SetFocus.
|
||||
PRInt32 count = mDocument->GetNumberOfShells();
|
||||
if (count == 0)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell = getter_AddRefs(mDocument->GetShellAt(0));
|
||||
|
||||
// Retrieve the context
|
||||
nsCOMPtr<nsIPresContext> aPresContext;
|
||||
shell->GetPresContext(getter_AddRefs(aPresContext));
|
||||
|
||||
// Set focus
|
||||
return RemoveFocus(aPresContext);
|
||||
}
|
||||
|
||||
|
||||
// nsIFocusableContent interface and helpers
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULElement::SetFocus(nsIPresContext* aPresContext)
|
||||
{
|
||||
|
|
|
@ -36,14 +36,23 @@
|
|||
#include "nsIPresShell.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsITreeFrame.h"
|
||||
#include "nsIDOMRange.h"
|
||||
#include "nsIContentIterator.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsString.h"
|
||||
|
||||
static NS_DEFINE_CID(kCRangeCID, NS_RANGE_CID);
|
||||
static NS_DEFINE_IID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
|
||||
|
||||
nsIAtom* nsXULTreeElement::kSelectedAtom;
|
||||
nsIAtom* nsXULTreeElement::kOpenAtom;
|
||||
nsIAtom* nsXULTreeElement::kTreeRowAtom;
|
||||
nsIAtom* nsXULTreeElement::kTreeItemAtom;
|
||||
nsIAtom* nsXULTreeElement::kTreeChildrenAtom;
|
||||
nsIAtom* nsXULTreeElement::kCurrentAtom;
|
||||
int nsXULTreeElement::gRefCnt = 0;
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsXULTreeElement, nsXULAggregateElement);
|
||||
|
@ -79,7 +88,8 @@ nsXULTreeElement::nsXULTreeElement(nsIDOMXULElement* aOuter)
|
|||
kOpenAtom = NS_NewAtom("open");
|
||||
kTreeRowAtom = NS_NewAtom("treerow");
|
||||
kTreeItemAtom = NS_NewAtom("treeitem");
|
||||
kTreeChildrenAtom= NS_NewAtom("treeitem");
|
||||
kTreeChildrenAtom= NS_NewAtom("treechildren");
|
||||
kCurrentAtom = NS_NewAtom("current");
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
@ -97,6 +107,9 @@ nsXULTreeElement::nsXULTreeElement(nsIDOMXULElement* aOuter)
|
|||
if (NS_FAILED(rv)) return;
|
||||
|
||||
mSelectedCells = children;
|
||||
|
||||
mCurrentItem = nsnull;
|
||||
mCurrentCell = nsnull;
|
||||
}
|
||||
|
||||
nsXULTreeElement::~nsXULTreeElement()
|
||||
|
@ -111,6 +124,11 @@ nsXULTreeElement::~nsXULTreeElement()
|
|||
|
||||
if (--gRefCnt == 0) {
|
||||
NS_IF_RELEASE(kSelectedAtom);
|
||||
NS_IF_RELEASE(kTreeItemAtom);
|
||||
NS_IF_RELEASE(kTreeRowAtom);
|
||||
NS_IF_RELEASE(kTreeChildrenAtom);
|
||||
NS_IF_RELEASE(kOpenAtom);
|
||||
NS_IF_RELEASE(kCurrentAtom);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,6 +169,8 @@ nsXULTreeElement::SelectItem(nsIDOMXULElement* aTreeItem)
|
|||
// Now add ourselves to the selection by setting our selected attribute.
|
||||
AddItemToSelectionInternal(aTreeItem);
|
||||
|
||||
SetCurrentItem(aTreeItem);
|
||||
|
||||
FireOnSelectHandler();
|
||||
|
||||
return NS_OK;
|
||||
|
@ -177,6 +197,8 @@ nsXULTreeElement::SelectCell(nsIDOMXULElement* aTreeCell)
|
|||
// Now add ourselves to the selection by setting our selected attribute.
|
||||
AddCellToSelectionInternal(aTreeCell);
|
||||
|
||||
SetCurrentCell(aTreeCell);
|
||||
|
||||
FireOnSelectHandler();
|
||||
|
||||
return NS_OK;
|
||||
|
@ -299,6 +321,8 @@ nsXULTreeElement::ToggleItemSelection(nsIDOMXULElement* aTreeItem)
|
|||
RemoveItemFromSelectionInternal(aTreeItem);
|
||||
else AddItemToSelectionInternal(aTreeItem);
|
||||
|
||||
SetCurrentItem(aTreeItem);
|
||||
|
||||
FireOnSelectHandler();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -312,6 +336,8 @@ nsXULTreeElement::ToggleCellSelection(nsIDOMXULElement* aTreeCell)
|
|||
RemoveCellFromSelectionInternal(aTreeCell);
|
||||
else AddCellToSelectionInternal(aTreeCell);
|
||||
|
||||
SetCurrentCell(aTreeCell);
|
||||
|
||||
FireOnSelectHandler();
|
||||
|
||||
return NS_OK;
|
||||
|
@ -321,7 +347,93 @@ nsXULTreeElement::ToggleCellSelection(nsIDOMXULElement* aTreeCell)
|
|||
NS_IMETHODIMP
|
||||
nsXULTreeElement::SelectItemRange(nsIDOMXULElement* aStartItem, nsIDOMXULElement* aEndItem)
|
||||
{
|
||||
// XXX Fill in.
|
||||
nsCOMPtr<nsIDOMXULElement> startItem;
|
||||
if (aStartItem == nsnull) {
|
||||
// Continue the ranged selection based off the current item.
|
||||
startItem = mCurrentItem;
|
||||
}
|
||||
else startItem = aStartItem;
|
||||
|
||||
if (!startItem)
|
||||
startItem = aEndItem;
|
||||
|
||||
// First clear our selection out completely.
|
||||
ClearItemSelectionInternal();
|
||||
|
||||
// Get a range so we can create an iterator
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
nsresult result;
|
||||
result = nsComponentManager::CreateInstance(kCRangeCID, nsnull,
|
||||
nsIDOMRange::GetIID(), getter_AddRefs(range));
|
||||
|
||||
PRInt32 startIndex = 0;
|
||||
PRInt32 endIndex = 0;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> startParentNode;
|
||||
nsCOMPtr<nsIDOMNode> endParentNode;
|
||||
|
||||
startItem->GetParentNode(getter_AddRefs(startParentNode));
|
||||
aEndItem->GetParentNode(getter_AddRefs(endParentNode));
|
||||
|
||||
nsCOMPtr<nsIContent> startParent = do_QueryInterface(startParentNode);
|
||||
nsCOMPtr<nsIContent> endParent = do_QueryInterface(endParentNode);
|
||||
|
||||
nsCOMPtr<nsIContent> startItemContent = do_QueryInterface(startItem);
|
||||
nsCOMPtr<nsIContent> endItemContent = do_QueryInterface(aEndItem);
|
||||
startParent->IndexOf(startItemContent, startIndex);
|
||||
endParent->IndexOf(endItemContent, endIndex);
|
||||
|
||||
result = range->SetStart(startParentNode, startIndex);
|
||||
result = range->SetEnd(endParentNode, endIndex+1);
|
||||
if (NS_FAILED(result) ||
|
||||
((startParentNode.get() == endParentNode.get()) && (startIndex == endIndex+1)))
|
||||
{
|
||||
// Ranges need to be increasing, try reversing directions
|
||||
result = range->SetStart(endParentNode, endIndex);
|
||||
result = range->SetEnd(startParentNode, startIndex+1);
|
||||
if (NS_FAILED(result))
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Create the iterator
|
||||
nsCOMPtr<nsIContentIterator> iter;
|
||||
result = nsComponentManager::CreateInstance(kCContentIteratorCID, nsnull,
|
||||
nsIContentIterator::GetIID(),
|
||||
getter_AddRefs(iter));
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
|
||||
// Iterate and select
|
||||
nsAutoString trueString("true", 4);
|
||||
nsCOMPtr<nsIContent> content;
|
||||
nsCOMPtr<nsIAtom> tag;
|
||||
|
||||
iter->Init(range);
|
||||
result = iter->First();
|
||||
while (NS_SUCCEEDED(result) && NS_ENUMERATOR_FALSE == iter->IsDone())
|
||||
{
|
||||
result = iter->CurrentNode(getter_AddRefs(content));
|
||||
if (NS_FAILED(result) || !content)
|
||||
return result; // result;
|
||||
|
||||
// If tag==item, Do selection stuff
|
||||
content->GetTag(*getter_AddRefs(tag));
|
||||
if (tag && tag == kTreeItemAtom)
|
||||
{
|
||||
// Only select if we aren't already selected.
|
||||
content->SetAttribute(kNameSpaceID_None, kSelectedAtom,
|
||||
trueString, /*aNotify*/ PR_TRUE);
|
||||
}
|
||||
|
||||
result = iter->Next();
|
||||
// XXX Deal with closed nodes here
|
||||
// XXX Also had strangeness where parent of selected subrange was selected even
|
||||
// though it wasn't in the range.
|
||||
}
|
||||
|
||||
SetCurrentItem(aEndItem);
|
||||
FireOnSelectHandler();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -335,8 +447,28 @@ nsXULTreeElement::SelectCellRange(nsIDOMXULElement* aStartItem, nsIDOMXULElement
|
|||
NS_IMETHODIMP
|
||||
nsXULTreeElement::SelectAll()
|
||||
{
|
||||
// XXX Select anything that isn't selected.
|
||||
// Write later.
|
||||
nsIDOMXULElement* oldItem = mCurrentItem;
|
||||
|
||||
PRInt32 childCount;
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(mOuter);
|
||||
content->ChildCount(childCount);
|
||||
if (childCount == 0)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIContent> startContent;
|
||||
content->ChildAt(0, *getter_AddRefs(startContent));
|
||||
nsCOMPtr<nsIContent> endContent;
|
||||
content->ChildAt(childCount-1, *getter_AddRefs(endContent));
|
||||
|
||||
nsCOMPtr<nsIDOMXULElement> startElement = do_QueryInterface(startContent);
|
||||
nsCOMPtr<nsIDOMXULElement> endElement = do_QueryInterface(endContent);
|
||||
|
||||
// Select the whole range.
|
||||
SelectItemRange(startElement, endElement);
|
||||
|
||||
// We shouldn't move the active item.
|
||||
mCurrentItem = oldItem;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -607,3 +739,36 @@ nsXULTreeElement::IndexOfContent(nsIContent* aRoot,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeElement::GetCurrentItem(nsIDOMXULElement** aResult)
|
||||
{
|
||||
*aResult = mCurrentItem;
|
||||
NS_IF_ADDREF(mCurrentItem);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeElement::GetCurrentCell(nsIDOMXULElement** aResult)
|
||||
{
|
||||
*aResult = mCurrentCell;
|
||||
NS_IF_ADDREF(mCurrentCell);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsXULTreeElement::SetCurrentItem(nsIDOMXULElement* aCurrentItem)
|
||||
{
|
||||
mCurrentItem = aCurrentItem;
|
||||
nsCOMPtr<nsIContent> current = do_QueryInterface(mCurrentItem);
|
||||
current->SetAttribute(kNameSpaceID_None, kCurrentAtom, "true", PR_TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
nsXULTreeElement::SetCurrentCell(nsIDOMXULElement* aCurrentCell)
|
||||
{
|
||||
mCurrentCell = aCurrentCell;
|
||||
nsCOMPtr<nsIContent> current = do_QueryInterface(mCurrentCell);
|
||||
current->SetAttribute(kNameSpaceID_None, kCurrentAtom, "true", PR_TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@ public:
|
|||
static nsIAtom* kTreeRowAtom;
|
||||
static nsIAtom* kTreeItemAtom;
|
||||
static nsIAtom* kTreeChildrenAtom;
|
||||
static nsIAtom* kCurrentAtom;
|
||||
|
||||
static int gRefCnt;
|
||||
|
||||
protected:
|
||||
|
@ -75,6 +77,9 @@ protected:
|
|||
void AddCellToSelectionInternal(nsIDOMXULElement* aTreeCell);
|
||||
void RemoveCellFromSelectionInternal(nsIDOMXULElement* aTreeCell);
|
||||
|
||||
void SetCurrentItem(nsIDOMXULElement* aElement);
|
||||
void SetCurrentCell(nsIDOMXULElement* aCell);
|
||||
|
||||
static nsresult IndexOfContent(nsIContent *aRoot, nsIContent *aContent,
|
||||
PRBool aDescendIntoRows,
|
||||
PRBool aParentIsOpen,
|
||||
|
@ -82,6 +87,8 @@ protected:
|
|||
protected:
|
||||
nsRDFDOMNodeList* mSelectedItems;
|
||||
nsRDFDOMNodeList* mSelectedCells;
|
||||
nsIDOMXULElement* mCurrentItem;
|
||||
nsIDOMXULElement* mCurrentCell;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -13,5 +13,8 @@ interface XULElement : Element {
|
|||
void removeBroadcastListener(in DOMString attr, in Element element);
|
||||
void doCommand();
|
||||
|
||||
void focus();
|
||||
void blur();
|
||||
|
||||
NodeList getElementsByAttribute(in DOMString name, in DOMString value);
|
||||
};
|
||||
|
|
|
@ -3,6 +3,9 @@ interface XULTreeElement : XULElement {
|
|||
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} } */
|
||||
readonly attribute NodeList selectedItems;
|
||||
readonly attribute NodeList selectedCells;
|
||||
|
||||
readonly attribute XULElement currentItem;
|
||||
readonly attribute XULElement currentCell;
|
||||
|
||||
void selectItem(in XULElement treeItem);
|
||||
void selectCell(in XULElement treeCell);
|
||||
|
|
|
@ -887,10 +887,12 @@ enum nsDOMProp {
|
|||
NS_DOM_PROP_XULDOCUMENT_TOOLTIPNODE,
|
||||
NS_DOM_PROP_XULEDITORELEMENT_EDITORSHELL,
|
||||
NS_DOM_PROP_XULELEMENT_ADDBROADCASTLISTENER,
|
||||
NS_DOM_PROP_XULELEMENT_BLUR,
|
||||
NS_DOM_PROP_XULELEMENT_CLASSNAME,
|
||||
NS_DOM_PROP_XULELEMENT_CONTROLLERS,
|
||||
NS_DOM_PROP_XULELEMENT_DATABASE,
|
||||
NS_DOM_PROP_XULELEMENT_DOCOMMAND,
|
||||
NS_DOM_PROP_XULELEMENT_FOCUS,
|
||||
NS_DOM_PROP_XULELEMENT_GETELEMENTSBYATTRIBUTE,
|
||||
NS_DOM_PROP_XULELEMENT_ID,
|
||||
NS_DOM_PROP_XULELEMENT_REMOVEBROADCASTLISTENER,
|
||||
|
@ -908,6 +910,8 @@ enum nsDOMProp {
|
|||
NS_DOM_PROP_XULTREEELEMENT_SELECTCELLRANGE,
|
||||
NS_DOM_PROP_XULTREEELEMENT_SELECTEDCELLS,
|
||||
NS_DOM_PROP_XULTREEELEMENT_SELECTEDITEMS,
|
||||
NS_DOM_PROP_XULTREEELEMENT_CURRENTITEM,
|
||||
NS_DOM_PROP_XULTREEELEMENT_CURRENTCELL,
|
||||
NS_DOM_PROP_XULTREEELEMENT_SELECTITEM,
|
||||
NS_DOM_PROP_XULTREEELEMENT_SELECTITEMRANGE,
|
||||
NS_DOM_PROP_XULTREEELEMENT_TOGGLECELLSELECTION,
|
||||
|
|
|
@ -886,10 +886,12 @@
|
|||
"xuldocument.tooltipnode", \
|
||||
"xuleditorelement.editorshell", \
|
||||
"xulelement.addbroadcastlistener", \
|
||||
"xulelement.blur", \
|
||||
"xulelement.classname", \
|
||||
"xulelement.controllers", \
|
||||
"xulelement.database", \
|
||||
"xulelement.docommand", \
|
||||
"xulelement.focus", \
|
||||
"xulelement.getelementsbyattribute", \
|
||||
"xulelement.id", \
|
||||
"xulelement.removebroadcastlistener", \
|
||||
|
@ -907,6 +909,8 @@
|
|||
"xultreeelement.selectcellrange", \
|
||||
"xultreeelement.selectedcells", \
|
||||
"xultreeelement.selecteditems", \
|
||||
"xultreeelement.currentitem", \
|
||||
"xultreeelement.currentcell", \
|
||||
"xultreeelement.selectitem", \
|
||||
"xultreeelement.selectitemrange", \
|
||||
"xultreeelement.togglecellselection", \
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
/* AUTO-GENERATED. DO NOT EDIT!!! */
|
||||
|
||||
|
|
|
@ -65,6 +65,10 @@ public:
|
|||
|
||||
NS_IMETHOD DoCommand()=0;
|
||||
|
||||
NS_IMETHOD Focus()=0;
|
||||
|
||||
NS_IMETHOD Blur()=0;
|
||||
|
||||
NS_IMETHOD GetElementsByAttribute(const nsString& aName, const nsString& aValue, nsIDOMNodeList** aReturn)=0;
|
||||
};
|
||||
|
||||
|
@ -82,6 +86,8 @@ public:
|
|||
NS_IMETHOD AddBroadcastListener(const nsString& aAttr, nsIDOMElement* aElement); \
|
||||
NS_IMETHOD RemoveBroadcastListener(const nsString& aAttr, nsIDOMElement* aElement); \
|
||||
NS_IMETHOD DoCommand(); \
|
||||
NS_IMETHOD Focus(); \
|
||||
NS_IMETHOD Blur(); \
|
||||
NS_IMETHOD GetElementsByAttribute(const nsString& aName, const nsString& aValue, nsIDOMNodeList** aReturn); \
|
||||
|
||||
|
||||
|
@ -99,6 +105,8 @@ public:
|
|||
NS_IMETHOD AddBroadcastListener(const nsString& aAttr, nsIDOMElement* aElement) { return _to AddBroadcastListener(aAttr, aElement); } \
|
||||
NS_IMETHOD RemoveBroadcastListener(const nsString& aAttr, nsIDOMElement* aElement) { return _to RemoveBroadcastListener(aAttr, aElement); } \
|
||||
NS_IMETHOD DoCommand() { return _to DoCommand(); } \
|
||||
NS_IMETHOD Focus() { return _to Focus(); } \
|
||||
NS_IMETHOD Blur() { return _to Blur(); } \
|
||||
NS_IMETHOD GetElementsByAttribute(const nsString& aName, const nsString& aValue, nsIDOMNodeList** aReturn) { return _to GetElementsByAttribute(aName, aValue, aReturn); } \
|
||||
|
||||
|
||||
|
|
|
@ -44,6 +44,10 @@ public:
|
|||
|
||||
NS_IMETHOD GetSelectedCells(nsIDOMNodeList** aSelectedCells)=0;
|
||||
|
||||
NS_IMETHOD GetCurrentItem(nsIDOMXULElement** aCurrentItem)=0;
|
||||
|
||||
NS_IMETHOD GetCurrentCell(nsIDOMXULElement** aCurrentCell)=0;
|
||||
|
||||
NS_IMETHOD SelectItem(nsIDOMXULElement* aTreeItem)=0;
|
||||
|
||||
NS_IMETHOD SelectCell(nsIDOMXULElement* aTreeCell)=0;
|
||||
|
@ -81,6 +85,8 @@ public:
|
|||
#define NS_DECL_IDOMXULTREEELEMENT \
|
||||
NS_IMETHOD GetSelectedItems(nsIDOMNodeList** aSelectedItems); \
|
||||
NS_IMETHOD GetSelectedCells(nsIDOMNodeList** aSelectedCells); \
|
||||
NS_IMETHOD GetCurrentItem(nsIDOMXULElement** aCurrentItem); \
|
||||
NS_IMETHOD GetCurrentCell(nsIDOMXULElement** aCurrentCell); \
|
||||
NS_IMETHOD SelectItem(nsIDOMXULElement* aTreeItem); \
|
||||
NS_IMETHOD SelectCell(nsIDOMXULElement* aTreeCell); \
|
||||
NS_IMETHOD ClearItemSelection(); \
|
||||
|
@ -103,6 +109,8 @@ public:
|
|||
#define NS_FORWARD_IDOMXULTREEELEMENT(_to) \
|
||||
NS_IMETHOD GetSelectedItems(nsIDOMNodeList** aSelectedItems) { return _to GetSelectedItems(aSelectedItems); } \
|
||||
NS_IMETHOD GetSelectedCells(nsIDOMNodeList** aSelectedCells) { return _to GetSelectedCells(aSelectedCells); } \
|
||||
NS_IMETHOD GetCurrentItem(nsIDOMXULElement** aCurrentItem) { return _to GetCurrentItem(aCurrentItem); } \
|
||||
NS_IMETHOD GetCurrentCell(nsIDOMXULElement** aCurrentCell) { return _to GetCurrentCell(aCurrentCell); } \
|
||||
NS_IMETHOD SelectItem(nsIDOMXULElement* aTreeItem) { return _to SelectItem(aTreeItem); } \
|
||||
NS_IMETHOD SelectCell(nsIDOMXULElement* aTreeCell) { return _to SelectCell(aTreeCell); } \
|
||||
NS_IMETHOD ClearItemSelection() { return _to ClearItemSelection(); } \
|
||||
|
|
|
@ -440,7 +440,7 @@ XULCommandDispatcherGetControllerForCommand(JSContext *cx, JSObject *obj, uintN
|
|||
}
|
||||
|
||||
// n.b., this will release nativeRet
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(nativeRet, nsIController::GetIID(), cx, obj, rval);
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(nativeRet, NS_GET_IID(nsIController), cx, obj, rval);
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
|
@ -486,7 +486,7 @@ XULCommandDispatcherGetControllers(JSContext *cx, JSObject *obj, uintN argc, jsv
|
|||
}
|
||||
|
||||
// n.b., this will release nativeRet
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(nativeRet, nsIControllers::GetIID(), cx, obj, rval);
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(nativeRet, NS_GET_IID(nsIControllers), cx, obj, rval);
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
/* AUTO-GENERATED. DO NOT EDIT!!! */
|
||||
|
||||
|
|
|
@ -155,7 +155,7 @@ GetXULElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
result = a->GetDatabase(&prop);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
// get the js object; n.b., this will do a release on 'prop'
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(prop, nsIRDFCompositeDataSource::GetIID(), cx, obj, vp);
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(prop, NS_GET_IID(nsIRDFCompositeDataSource), cx, obj, vp);
|
||||
}
|
||||
else {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
|
@ -174,7 +174,7 @@ GetXULElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
result = a->GetResource(&prop);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
// get the js object; n.b., this will do a release on 'prop'
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(prop, nsIRDFResource::GetIID(), cx, obj, vp);
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(prop, NS_GET_IID(nsIRDFResource), cx, obj, vp);
|
||||
}
|
||||
else {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
|
@ -193,7 +193,7 @@ GetXULElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
result = a->GetControllers(&prop);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
// get the js object; n.b., this will do a release on 'prop'
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(prop, nsIControllers::GetIID(), cx, obj, vp);
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(prop, NS_GET_IID(nsIControllers), cx, obj, vp);
|
||||
}
|
||||
else {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
|
@ -480,6 +480,94 @@ XULElementDoCommand(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval
|
|||
}
|
||||
|
||||
|
||||
//
|
||||
// Native method Focus
|
||||
//
|
||||
PR_STATIC_CALLBACK(JSBool)
|
||||
XULElementFocus(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
nsIDOMXULElement *nativeThis = (nsIDOMXULElement*)nsJSUtils::nsGetNativeThis(cx, obj);
|
||||
nsresult result = NS_OK;
|
||||
// If there's no private data, this must be the prototype, so ignore
|
||||
if (nsnull == nativeThis) {
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
*rval = JSVAL_NULL;
|
||||
|
||||
{
|
||||
PRBool ok;
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIScriptSecurityManager, secMan,
|
||||
NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECMAN_ERR);
|
||||
}
|
||||
secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULELEMENT_FOCUS, PR_FALSE, &ok);
|
||||
if (!ok) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECURITY_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
result = nativeThis->Focus();
|
||||
if (NS_FAILED(result)) {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
}
|
||||
|
||||
*rval = JSVAL_VOID;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Native method Blur
|
||||
//
|
||||
PR_STATIC_CALLBACK(JSBool)
|
||||
XULElementBlur(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
nsIDOMXULElement *nativeThis = (nsIDOMXULElement*)nsJSUtils::nsGetNativeThis(cx, obj);
|
||||
nsresult result = NS_OK;
|
||||
// If there's no private data, this must be the prototype, so ignore
|
||||
if (nsnull == nativeThis) {
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
*rval = JSVAL_NULL;
|
||||
|
||||
{
|
||||
PRBool ok;
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIScriptSecurityManager, secMan,
|
||||
NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECMAN_ERR);
|
||||
}
|
||||
secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULELEMENT_BLUR, PR_FALSE, &ok);
|
||||
if (!ok) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECURITY_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
result = nativeThis->Blur();
|
||||
if (NS_FAILED(result)) {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
}
|
||||
|
||||
*rval = JSVAL_VOID;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Native method GetElementsByAttribute
|
||||
//
|
||||
|
@ -574,6 +662,8 @@ static JSFunctionSpec XULElementMethods[] =
|
|||
{"addBroadcastListener", XULElementAddBroadcastListener, 2},
|
||||
{"removeBroadcastListener", XULElementRemoveBroadcastListener, 2},
|
||||
{"doCommand", XULElementDoCommand, 0},
|
||||
{"focus", XULElementFocus, 0},
|
||||
{"blur", XULElementBlur, 0},
|
||||
{"getElementsByAttribute", XULElementGetElementsByAttribute, 2},
|
||||
{0}
|
||||
};
|
||||
|
|
|
@ -51,7 +51,9 @@ static NS_DEFINE_IID(kINodeListIID, NS_IDOMNODELIST_IID);
|
|||
//
|
||||
enum XULTreeElement_slots {
|
||||
XULTREEELEMENT_SELECTEDITEMS = -1,
|
||||
XULTREEELEMENT_SELECTEDCELLS = -2
|
||||
XULTREEELEMENT_SELECTEDCELLS = -2,
|
||||
XULTREEELEMENT_CURRENTITEM = -3,
|
||||
XULTREEELEMENT_CURRENTCELL = -4
|
||||
};
|
||||
|
||||
/***********************************************************************/
|
||||
|
@ -114,6 +116,44 @@ GetXULTreeElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case XULTREEELEMENT_CURRENTITEM:
|
||||
{
|
||||
PRBool ok = PR_FALSE;
|
||||
secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULTREEELEMENT_CURRENTITEM, PR_FALSE, &ok);
|
||||
if (!ok) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECURITY_ERR);
|
||||
}
|
||||
nsIDOMXULElement* prop;
|
||||
nsresult result = NS_OK;
|
||||
result = a->GetCurrentItem(&prop);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
// get the js object
|
||||
nsJSUtils::nsConvertObjectToJSVal((nsISupports *)prop, cx, obj, vp);
|
||||
}
|
||||
else {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XULTREEELEMENT_CURRENTCELL:
|
||||
{
|
||||
PRBool ok = PR_FALSE;
|
||||
secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULTREEELEMENT_CURRENTCELL, PR_FALSE, &ok);
|
||||
if (!ok) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECURITY_ERR);
|
||||
}
|
||||
nsIDOMXULElement* prop;
|
||||
nsresult result = NS_OK;
|
||||
result = a->GetCurrentCell(&prop);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
// get the js object
|
||||
nsJSUtils::nsConvertObjectToJSVal((nsISupports *)prop, cx, obj, vp);
|
||||
}
|
||||
else {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return nsJSUtils::nsCallJSScriptObjectGetProperty(a, cx, obj, id, vp);
|
||||
}
|
||||
|
@ -1080,6 +1120,8 @@ static JSPropertySpec XULTreeElementProperties[] =
|
|||
{
|
||||
{"selectedItems", XULTREEELEMENT_SELECTEDITEMS, JSPROP_ENUMERATE | JSPROP_READONLY},
|
||||
{"selectedCells", XULTREEELEMENT_SELECTEDCELLS, JSPROP_ENUMERATE | JSPROP_READONLY},
|
||||
{"currentItem", XULTREEELEMENT_CURRENTITEM, JSPROP_ENUMERATE | JSPROP_READONLY},
|
||||
{"currentCell", XULTREEELEMENT_CURRENTCELL, JSPROP_ENUMERATE | JSPROP_READONLY},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
|
|
@ -5930,7 +5930,17 @@ nsCSSFrameConstructor::ContentAppended(nsIPresContext* aPresContext,
|
|||
aContainer,
|
||||
aNewIndexInContainer);
|
||||
|
||||
if (prevSibling || innerFrame) {
|
||||
// This needs to really be a previous sibling.
|
||||
if (prevSibling && aNewIndexInContainer > 0) {
|
||||
nsCOMPtr<nsIContent> prevContent;
|
||||
nsCOMPtr<nsIContent> frameContent;
|
||||
aContainer->ChildAt(aNewIndexInContainer-1, *getter_AddRefs(prevContent));
|
||||
prevSibling->GetContent(getter_AddRefs(frameContent));
|
||||
if (frameContent.get() != prevContent.get())
|
||||
prevSibling = nsnull;
|
||||
}
|
||||
|
||||
if (prevSibling || (innerFrame && aNewIndexInContainer == 0)) {
|
||||
// We're onscreen. Make sure a full reflow happens.
|
||||
treeRowGroup->OnContentAdded(aPresContext);
|
||||
}
|
||||
|
|
|
@ -124,8 +124,8 @@ nsLayoutHistoryState::AddState(PRUint32 aContentID,
|
|||
* the intended behavior
|
||||
*/
|
||||
if (res) {
|
||||
printf("nsLayoutHistoryState::AddState OOPS!. There was already a state in the hash table for the key\n");
|
||||
rv = NS_ERROR_UNEXPECTED;
|
||||
//printf("nsLayoutHistoryState::AddState OOPS!. There was already a state in the hash table for the key\n");
|
||||
rv = NS_OK;
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -144,9 +144,9 @@ nsLayoutHistoryState::GetState(PRUint32 aContentID,
|
|||
*aState = (nsIPresState *)state;
|
||||
}
|
||||
else {
|
||||
printf("nsLayoutHistoryState::GetState, ERROR getting History state for the key\n");
|
||||
// printf("nsLayoutHistoryState::GetState, ERROR getting History state for the key\n");
|
||||
*aState = nsnull;
|
||||
rv = NS_ERROR_NULL_POINTER;
|
||||
rv = NS_OK;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -124,8 +124,8 @@ nsLayoutHistoryState::AddState(PRUint32 aContentID,
|
|||
* the intended behavior
|
||||
*/
|
||||
if (res) {
|
||||
printf("nsLayoutHistoryState::AddState OOPS!. There was already a state in the hash table for the key\n");
|
||||
rv = NS_ERROR_UNEXPECTED;
|
||||
//printf("nsLayoutHistoryState::AddState OOPS!. There was already a state in the hash table for the key\n");
|
||||
rv = NS_OK;
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -144,9 +144,9 @@ nsLayoutHistoryState::GetState(PRUint32 aContentID,
|
|||
*aState = (nsIPresState *)state;
|
||||
}
|
||||
else {
|
||||
printf("nsLayoutHistoryState::GetState, ERROR getting History state for the key\n");
|
||||
// printf("nsLayoutHistoryState::GetState, ERROR getting History state for the key\n");
|
||||
*aState = nsnull;
|
||||
rv = NS_ERROR_NULL_POINTER;
|
||||
rv = NS_OK;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -1794,6 +1794,19 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aParent, nsIContent* aCh
|
|||
disabled = PR_FALSE;
|
||||
}
|
||||
|
||||
// Get the primary frame for the widget. We don't tab into anything
|
||||
// that doesn't have a frame.
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
if (mPresContext) {
|
||||
nsresult rv = mPresContext->GetShell(getter_AddRefs(shell));
|
||||
if (NS_SUCCEEDED(rv) && shell){
|
||||
nsIFrame* potentialFrame;
|
||||
shell->GetPrimaryFrameFor(child, &potentialFrame);
|
||||
if (!potentialFrame)
|
||||
hidden = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
//TabIndex not set (-1) treated at same level as set to 0
|
||||
tabIndex = tabIndex < 0 ? 0 : tabIndex;
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "nsIDeviceContext.h"
|
||||
#include "nsPageFrame.h"
|
||||
#include "nsViewsCID.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIView.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsHTMLContainerFrame.h"
|
||||
|
@ -46,6 +47,7 @@
|
|||
#include "nsIDocumentObserver.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIScrollPositionListener.h"
|
||||
#include "nsIElementFactory.h"
|
||||
|
||||
static NS_DEFINE_IID(kWidgetCID, NS_CHILD_CID);
|
||||
static NS_DEFINE_IID(kScrollingViewCID, NS_SCROLLING_VIEW_CID);
|
||||
|
@ -317,37 +319,22 @@ NS_IMETHODIMP
|
|||
nsGfxScrollFrame::CreateAnonymousContent(nsIPresContext* aPresContext,
|
||||
nsISupportsArray& aAnonymousChildren)
|
||||
{
|
||||
|
||||
/*
|
||||
nsCOMPtr<nsIDocument> idocument;
|
||||
mContent->GetDocument(*getter_AddRefs(idocument));
|
||||
|
||||
// create horzontal scrollbar
|
||||
nsCOMPtr<nsIXMLContent> content;
|
||||
nsresult rv = NS_NewXMLElement(getter_AddRefs(content), nsXULAtoms::titledbutton);
|
||||
content->SetDocument(idocument, PR_FALSE);
|
||||
content->SetNameSpaceID(nsXULAtoms::nameSpaceID);
|
||||
content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::value, "foo", PR_FALSE);
|
||||
aAnonymousChildren.AppendElement(content);
|
||||
nsCAutoString progID = NS_ELEMENT_FACTORY_PROGID_PREFIX;
|
||||
progID += "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIElementFactory, elementFactory, progID, &rv);
|
||||
if (!elementFactory)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// create horzontal scrollbar
|
||||
rv = NS_NewXMLElement(getter_AddRefs(content), nsXULAtoms::titledbutton);
|
||||
content->SetDocument(idocument, PR_FALSE);
|
||||
content->SetNameSpaceID(nsXULAtoms::nameSpaceID);
|
||||
content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::value, "foo", PR_FALSE);
|
||||
aAnonymousChildren.AppendElement(content);
|
||||
*/
|
||||
|
||||
/* Comment this in to enable GFX scrollbars */
|
||||
|
||||
// create horzontal scrollbar
|
||||
nsCOMPtr<nsIContent> content;
|
||||
NS_CreateAnonymousNode(mContent, nsXULAtoms::scrollbar, nsXULAtoms::nameSpaceID, content);
|
||||
elementFactory->CreateInstanceByTag("scrollbar", getter_AddRefs(content));
|
||||
content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::align, "horizontal", PR_FALSE);
|
||||
aAnonymousChildren.AppendElement(content);
|
||||
|
||||
// create vertical scrollbar
|
||||
NS_CreateAnonymousNode(mContent, nsXULAtoms::scrollbar, nsXULAtoms::nameSpaceID, content);
|
||||
content = nsnull;
|
||||
elementFactory->CreateInstanceByTag("scrollbar", getter_AddRefs(content));
|
||||
content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::align, "vertical", PR_FALSE);
|
||||
aAnonymousChildren.AppendElement(content);
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "nsIDeviceContext.h"
|
||||
#include "nsPageFrame.h"
|
||||
#include "nsViewsCID.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIView.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsHTMLContainerFrame.h"
|
||||
|
@ -46,6 +47,7 @@
|
|||
#include "nsIDocumentObserver.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIScrollPositionListener.h"
|
||||
#include "nsIElementFactory.h"
|
||||
|
||||
static NS_DEFINE_IID(kWidgetCID, NS_CHILD_CID);
|
||||
static NS_DEFINE_IID(kScrollingViewCID, NS_SCROLLING_VIEW_CID);
|
||||
|
@ -317,37 +319,22 @@ NS_IMETHODIMP
|
|||
nsGfxScrollFrame::CreateAnonymousContent(nsIPresContext* aPresContext,
|
||||
nsISupportsArray& aAnonymousChildren)
|
||||
{
|
||||
|
||||
/*
|
||||
nsCOMPtr<nsIDocument> idocument;
|
||||
mContent->GetDocument(*getter_AddRefs(idocument));
|
||||
|
||||
// create horzontal scrollbar
|
||||
nsCOMPtr<nsIXMLContent> content;
|
||||
nsresult rv = NS_NewXMLElement(getter_AddRefs(content), nsXULAtoms::titledbutton);
|
||||
content->SetDocument(idocument, PR_FALSE);
|
||||
content->SetNameSpaceID(nsXULAtoms::nameSpaceID);
|
||||
content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::value, "foo", PR_FALSE);
|
||||
aAnonymousChildren.AppendElement(content);
|
||||
nsCAutoString progID = NS_ELEMENT_FACTORY_PROGID_PREFIX;
|
||||
progID += "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIElementFactory, elementFactory, progID, &rv);
|
||||
if (!elementFactory)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// create horzontal scrollbar
|
||||
rv = NS_NewXMLElement(getter_AddRefs(content), nsXULAtoms::titledbutton);
|
||||
content->SetDocument(idocument, PR_FALSE);
|
||||
content->SetNameSpaceID(nsXULAtoms::nameSpaceID);
|
||||
content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::value, "foo", PR_FALSE);
|
||||
aAnonymousChildren.AppendElement(content);
|
||||
*/
|
||||
|
||||
/* Comment this in to enable GFX scrollbars */
|
||||
|
||||
// create horzontal scrollbar
|
||||
nsCOMPtr<nsIContent> content;
|
||||
NS_CreateAnonymousNode(mContent, nsXULAtoms::scrollbar, nsXULAtoms::nameSpaceID, content);
|
||||
elementFactory->CreateInstanceByTag("scrollbar", getter_AddRefs(content));
|
||||
content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::align, "horizontal", PR_FALSE);
|
||||
aAnonymousChildren.AppendElement(content);
|
||||
|
||||
// create vertical scrollbar
|
||||
NS_CreateAnonymousNode(mContent, nsXULAtoms::scrollbar, nsXULAtoms::nameSpaceID, content);
|
||||
content = nsnull;
|
||||
elementFactory->CreateInstanceByTag("scrollbar", getter_AddRefs(content));
|
||||
content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::align, "vertical", PR_FALSE);
|
||||
aAnonymousChildren.AppendElement(content);
|
||||
|
||||
|
|
|
@ -5930,7 +5930,17 @@ nsCSSFrameConstructor::ContentAppended(nsIPresContext* aPresContext,
|
|||
aContainer,
|
||||
aNewIndexInContainer);
|
||||
|
||||
if (prevSibling || innerFrame) {
|
||||
// This needs to really be a previous sibling.
|
||||
if (prevSibling && aNewIndexInContainer > 0) {
|
||||
nsCOMPtr<nsIContent> prevContent;
|
||||
nsCOMPtr<nsIContent> frameContent;
|
||||
aContainer->ChildAt(aNewIndexInContainer-1, *getter_AddRefs(prevContent));
|
||||
prevSibling->GetContent(getter_AddRefs(frameContent));
|
||||
if (frameContent.get() != prevContent.get())
|
||||
prevSibling = nsnull;
|
||||
}
|
||||
|
||||
if (prevSibling || (innerFrame && aNewIndexInContainer == 0)) {
|
||||
// We're onscreen. Make sure a full reflow happens.
|
||||
treeRowGroup->OnContentAdded(aPresContext);
|
||||
}
|
||||
|
|
|
@ -55,6 +55,10 @@ public:
|
|||
|
||||
NS_IMETHOD GenerateAnonymousContent(nsIContent* aBoundElement) = 0;
|
||||
NS_IMETHOD InstallEventHandlers(nsIContent* aBoundElement) = 0;
|
||||
|
||||
// Called when an attribute changes on a binding.
|
||||
NS_IMETHOD AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag) = 0;
|
||||
|
||||
};
|
||||
|
||||
extern nsresult
|
||||
|
|
|
@ -24,6 +24,38 @@
|
|||
// Static IIDs/CIDs. Try to minimize these.
|
||||
// None
|
||||
|
||||
// Helper classes
|
||||
// {A2892B81-CED9-11d3-97FB-00400553EEF0}
|
||||
#define NS_IXBLATTR_IID \
|
||||
{ 0xa2892b81, 0xced9, 0x11d3, { 0x97, 0xfb, 0x0, 0x40, 0x5, 0x53, 0xee, 0xf0 } }
|
||||
|
||||
class nsIXBLAttributeEntry : public nsISupports {
|
||||
public:
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_IXBLATTR_IID; return iid; }
|
||||
|
||||
NS_IMETHOD GetAttribute(nsIAtom** aResult) = 0;
|
||||
NS_IMETHOD GetElement(nsIContent** aResult) = 0;
|
||||
};
|
||||
|
||||
|
||||
class nsXBLAttributeEntry : public nsIXBLAttributeEntry {
|
||||
public:
|
||||
NS_IMETHOD GetAttribute(nsIAtom** aResult) { *aResult = mAttribute; NS_IF_ADDREF(*aResult); return NS_OK; };
|
||||
NS_IMETHOD GetElement(nsIContent** aResult) { *aResult = mElement; NS_IF_ADDREF(*aResult); return NS_OK; };
|
||||
|
||||
nsCOMPtr<nsIContent> mElement;
|
||||
nsCOMPtr<nsIAtom> mAttribute;
|
||||
|
||||
nsXBLAttributeEntry(nsIAtom* aAtom, nsIContent* aContent) {
|
||||
NS_INIT_REFCNT(); mAttribute = aAtom; mElement = aContent;
|
||||
};
|
||||
|
||||
virtual ~nsXBLAttributeEntry() {};
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsXBLAttributeEntry, nsIXBLAttributeEntry)
|
||||
|
||||
class nsXBLBinding: public nsIXBLBinding
|
||||
{
|
||||
|
@ -41,6 +73,8 @@ class nsXBLBinding: public nsIXBLBinding
|
|||
NS_IMETHOD GenerateAnonymousContent(nsIContent* aBoundElement);
|
||||
NS_IMETHOD InstallEventHandlers(nsIContent* aBoundElement);
|
||||
|
||||
NS_IMETHOD AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag);
|
||||
|
||||
public:
|
||||
nsXBLBinding();
|
||||
virtual ~nsXBLBinding();
|
||||
|
@ -59,6 +93,8 @@ protected:
|
|||
void GetImmediateChild(nsIAtom* aTag, nsIContent** aResult);
|
||||
PRBool IsInExcludesList(nsIAtom* aTag, const nsString& aList);
|
||||
|
||||
NS_IMETHOD ConstructAttributeTable(nsIContent* aElement);
|
||||
|
||||
// MEMBER VARIABLES
|
||||
protected:
|
||||
nsCOMPtr<nsIContent> mBinding; // Strong. As long as we're around, the binding can't go away.
|
||||
|
@ -66,6 +102,7 @@ protected:
|
|||
nsCOMPtr<nsIXBLBinding> mNextBinding; // Strong. The derived binding owns the base class bindings.
|
||||
|
||||
nsIContent* mBoundElement; // [WEAK] We have a reference, but we don't own it.
|
||||
nsSupportsHashtable* mAttributeTable; // A table for attribute entries.
|
||||
};
|
||||
|
||||
// Static initialization
|
||||
|
@ -84,6 +121,7 @@ NS_IMPL_ISUPPORTS1(nsXBLBinding, nsIXBLBinding)
|
|||
|
||||
// Constructors/Destructors
|
||||
nsXBLBinding::nsXBLBinding(void)
|
||||
:mAttributeTable(nsnull)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
gRefCnt++;
|
||||
|
@ -156,6 +194,11 @@ nsXBLBinding::SetAnonymousContent(nsIContent* aParent)
|
|||
child->SetParent(mBoundElement);
|
||||
}
|
||||
|
||||
// (3) We need to insert entries into our attribute table for any elements
|
||||
// that are inheriting attributes. This table allows us to quickly determine
|
||||
// which elements in our anonymous content need to be updated when attributes change.
|
||||
ConstructAttributeTable(aParent);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -201,7 +244,7 @@ nsXBLBinding::GenerateAnonymousContent(nsIContent* aBoundElement)
|
|||
// in the excludes list.
|
||||
nsAutoString excludes;
|
||||
content->GetAttribute(kNameSpaceID_None, kExcludesAtom, excludes);
|
||||
if (excludes == "true") {
|
||||
if (excludes != "") {
|
||||
// Walk the children and ensure that all of them
|
||||
// are in the excludes array.
|
||||
for (PRInt32 i = 0; i < childCount; i++) {
|
||||
|
@ -242,6 +285,54 @@ nsXBLBinding::InstallEventHandlers(nsIContent* aBoundElement)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLBinding::AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag)
|
||||
{
|
||||
if (mNextBinding)
|
||||
mNextBinding->AttributeChanged(aAttribute, aNameSpaceID, aRemoveFlag);
|
||||
|
||||
if (!mAttributeTable)
|
||||
return NS_OK;
|
||||
|
||||
nsISupportsKey key(aAttribute);
|
||||
nsCOMPtr<nsISupports> supports = getter_AddRefs(NS_STATIC_CAST(nsISupports*,
|
||||
mAttributeTable->Get(&key)));
|
||||
|
||||
nsCOMPtr<nsISupportsArray> entry = do_QueryInterface(supports);
|
||||
if (!entry)
|
||||
return NS_OK;
|
||||
|
||||
// Iterate over the elements in the array.
|
||||
PRUint32 count;
|
||||
entry->Count(&count);
|
||||
|
||||
for (PRUint32 i=0; i<count; i++) {
|
||||
nsCOMPtr<nsISupports> item;
|
||||
entry->GetElementAt(i, getter_AddRefs(item));
|
||||
nsCOMPtr<nsIXBLAttributeEntry> xblAttr = do_QueryInterface(item);
|
||||
if (xblAttr) {
|
||||
nsCOMPtr<nsIContent> element;
|
||||
nsCOMPtr<nsIAtom> setAttr;
|
||||
xblAttr->GetElement(getter_AddRefs(element));
|
||||
xblAttr->GetAttribute(getter_AddRefs(setAttr));
|
||||
|
||||
if (aRemoveFlag)
|
||||
element->UnsetAttribute(aNameSpaceID, setAttr, PR_TRUE);
|
||||
else {
|
||||
nsAutoString value;
|
||||
nsresult result = mBoundElement->GetAttribute(aNameSpaceID, aAttribute, value);
|
||||
PRBool attrPresent = (result == NS_CONTENT_ATTR_NO_VALUE ||
|
||||
result == NS_CONTENT_ATTR_HAS_VALUE);
|
||||
|
||||
if (attrPresent)
|
||||
element->SetAttribute(aNameSpaceID, setAttr, value, PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Internal helper methods ////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
|
@ -296,6 +387,92 @@ nsXBLBinding::IsInExcludesList(nsIAtom* aTag, const nsString& aList)
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLBinding::ConstructAttributeTable(nsIContent* aElement)
|
||||
{
|
||||
// XXX This function still needs to deal with the
|
||||
// ability to map one attribute to another.
|
||||
nsAutoString inherits;
|
||||
aElement->GetAttribute(kNameSpaceID_None, kInheritsAtom, inherits);
|
||||
if (inherits != "") {
|
||||
if (!mAttributeTable) {
|
||||
mAttributeTable = new nsSupportsHashtable(8);
|
||||
}
|
||||
|
||||
// The user specified at least one attribute.
|
||||
char* str = inherits.ToNewCString();
|
||||
char* newStr;
|
||||
char* token = nsCRT::strtok( str, ", ", &newStr );
|
||||
while( token != NULL ) {
|
||||
// Build an atom out of this attribute.
|
||||
nsCOMPtr<nsIAtom> atom;
|
||||
nsCOMPtr<nsIAtom> attribute;
|
||||
|
||||
// Figure out if this token contains a :.
|
||||
nsAutoString attr(token);
|
||||
PRInt32 index = attr.Find(":", PR_TRUE);
|
||||
if (index != -1) {
|
||||
// This attribute maps to something different.
|
||||
nsAutoString left, right;
|
||||
attr.Left(left, index);
|
||||
attr.Right(right, attr.Length()-index-1);
|
||||
|
||||
atom = getter_AddRefs(NS_NewAtom(left));
|
||||
attribute = getter_AddRefs(NS_NewAtom(right));
|
||||
}
|
||||
else {
|
||||
atom = getter_AddRefs(NS_NewAtom(token));
|
||||
attribute = getter_AddRefs(NS_NewAtom(token));
|
||||
}
|
||||
|
||||
// Create an XBL attribute entry.
|
||||
nsXBLAttributeEntry* xblAttr = new nsXBLAttributeEntry(attribute, aElement);
|
||||
|
||||
// Now we should see if some element within our anonymous
|
||||
// content is already observing this attribute.
|
||||
nsISupportsKey key(atom);
|
||||
nsCOMPtr<nsISupports> supports = getter_AddRefs(NS_STATIC_CAST(nsISupports*,
|
||||
mAttributeTable->Get(&key)));
|
||||
|
||||
nsCOMPtr<nsISupportsArray> entry = do_QueryInterface(supports);
|
||||
if (!entry) {
|
||||
// Make a new entry.
|
||||
NS_NewISupportsArray(getter_AddRefs(entry));
|
||||
|
||||
// Put it in the table.
|
||||
mAttributeTable->Put(&key, entry);
|
||||
}
|
||||
|
||||
// Append ourselves to our entry.
|
||||
entry->AppendElement(xblAttr);
|
||||
|
||||
// Now make sure that this attribute is initially set.
|
||||
// XXX How to deal with NAMESPACES!!!?
|
||||
nsAutoString value;
|
||||
nsresult result = mBoundElement->GetAttribute(kNameSpaceID_None, atom, value);
|
||||
PRBool attrPresent = (result == NS_CONTENT_ATTR_NO_VALUE ||
|
||||
result == NS_CONTENT_ATTR_HAS_VALUE);
|
||||
|
||||
if (attrPresent)
|
||||
aElement->SetAttribute(kNameSpaceID_None, attribute, value, PR_TRUE);
|
||||
|
||||
token = nsCRT::strtok( newStr, ", ", &newStr );
|
||||
}
|
||||
|
||||
nsAllocator::Free(str);
|
||||
}
|
||||
|
||||
// Recur into our children.
|
||||
PRInt32 childCount;
|
||||
aElement->ChildCount(childCount);
|
||||
for (PRInt32 i = 0; i < childCount; i++) {
|
||||
nsCOMPtr<nsIContent> child;
|
||||
aElement->ChildAt(i, *getter_AddRefs(child));
|
||||
ConstructAttributeTable(child);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Creation Routine ///////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "nsXMLDocument.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsSupportsArray.h"
|
||||
#include "nsITextContent.h"
|
||||
|
||||
#include "nsIXBLBinding.h"
|
||||
|
||||
|
@ -110,6 +111,10 @@ public:
|
|||
// This method synchronously loads and parses an XBL file.
|
||||
NS_IMETHOD FetchBindingDocument(nsIURI* aURI, nsIDocument** aResult);
|
||||
|
||||
// This method walks a binding document and removes any text nodes
|
||||
// that contain only whitespace.
|
||||
NS_IMETHOD StripWhitespaceNodes(nsIContent* aContent);
|
||||
|
||||
protected:
|
||||
// This URIkey class is used to hash URLs into an XBL binding
|
||||
// cache.
|
||||
|
@ -272,9 +277,7 @@ nsXBLService::GetContentList(nsIContent* aContent, nsISupportsArray** aResult)
|
|||
if (!(*aResult))
|
||||
NS_NewISupportsArray(aResult); // This call addrefs the array.
|
||||
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(anonymousChild);
|
||||
if (element) // Don't let the extra text frames get generated.
|
||||
(*aResult)->AppendElement(anonymousChild);
|
||||
(*aResult)->AppendElement(anonymousChild);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -460,6 +463,42 @@ nsXBLService::FetchBindingDocument(nsIURI* aURI, nsIDocument** aResult)
|
|||
// Everything worked, so we can just hand this back now.
|
||||
*aResult = doc;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
|
||||
// The XML content sink produces a ridiculous # of content nodes.
|
||||
// It generates text nodes even for whitespace. The following
|
||||
// call walks the generated document tree and trims out these
|
||||
// nodes.
|
||||
nsCOMPtr<nsIContent> root = getter_AddRefs(doc->GetRootContent());
|
||||
if (root)
|
||||
StripWhitespaceNodes(root);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLService::StripWhitespaceNodes(nsIContent* aElement)
|
||||
{
|
||||
PRInt32 childCount;
|
||||
aElement->ChildCount(childCount);
|
||||
for (PRInt32 i = 0; i < childCount; i++) {
|
||||
nsCOMPtr<nsIContent> child;
|
||||
aElement->ChildAt(i, *getter_AddRefs(child));
|
||||
nsCOMPtr<nsITextContent> text = do_QueryInterface(child);
|
||||
if (text) {
|
||||
nsAutoString result;
|
||||
text->CopyText(result);
|
||||
result.StripWhitespace();
|
||||
if (result == "") {
|
||||
// This node contained nothing but whitespace.
|
||||
// Remove it from the content model.
|
||||
aElement->RemoveChildAt(i, PR_TRUE);
|
||||
i--; // Decrement our count, since we just removed this child.
|
||||
childCount--; // Also decrement our total count.
|
||||
}
|
||||
}
|
||||
else StripWhitespaceNodes(child);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,6 @@ NS_INTERFACE_MAP_BEGIN(nsMenuFrame)
|
|||
nsMenuFrame::nsMenuFrame()
|
||||
: mIsMenu(PR_FALSE),
|
||||
mMenuOpen(PR_FALSE),
|
||||
mHasAnonymousContent(PR_FALSE),
|
||||
mChecked(PR_FALSE),
|
||||
mType(eMenuType_Normal),
|
||||
mMenuParent(nsnull),
|
||||
|
@ -150,6 +149,13 @@ nsMenuFrame::Init(nsIPresContext* aPresContext,
|
|||
// Set our menu parent.
|
||||
nsCOMPtr<nsIMenuParent> menuparent = do_QueryInterface(aParent);
|
||||
mMenuParent = menuparent.get();
|
||||
|
||||
// Do the type="checkbox" magic
|
||||
UpdateMenuType();
|
||||
|
||||
nsAutoString accelString;
|
||||
BuildAcceleratorText(accelString);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -457,38 +463,24 @@ nsMenuFrame::AttributeChanged(nsIPresContext* aPresContext,
|
|||
UpdateMenuType(aPresContext);
|
||||
}
|
||||
|
||||
if (mHasAnonymousContent) {
|
||||
if (aAttribute == nsXULAtoms::accesskey ||
|
||||
aAttribute == nsHTMLAtoms::value) {
|
||||
/* update accesskey or value on menu-left */
|
||||
aChild->GetAttribute(kNameSpaceID_None, aAttribute, value);
|
||||
mMenuText->SetAttribute(kNameSpaceID_None, aAttribute, value, PR_TRUE);
|
||||
} else if (aAttribute == nsXULAtoms::acceltext) {
|
||||
/* update content in accel-text */
|
||||
aChild->GetAttribute(kNameSpaceID_None, aAttribute, value);
|
||||
mAccelText->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::value, value,
|
||||
PR_TRUE);
|
||||
}
|
||||
/* we need to reflow, if these change */
|
||||
if (aAttribute == nsHTMLAtoms::value ||
|
||||
aAttribute == nsXULAtoms::acceltext ||
|
||||
aAttribute == nsHTMLAtoms::type ||
|
||||
aAttribute == nsHTMLAtoms::checked) {
|
||||
|
||||
/* we need to reflow, if these change */
|
||||
if (aAttribute == nsHTMLAtoms::value ||
|
||||
aAttribute == nsXULAtoms::acceltext ||
|
||||
aAttribute == nsHTMLAtoms::type ||
|
||||
aAttribute == nsHTMLAtoms::checked) {
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
nsresult rv = aPresContext->GetShell(getter_AddRefs(shell));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
nsresult rv = aPresContext->GetShell(getter_AddRefs(shell));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
nsCOMPtr<nsIReflowCommand> reflowCmd;
|
||||
rv = NS_NewHTMLReflowCommand(getter_AddRefs(reflowCmd), this,
|
||||
nsIReflowCommand::StyleChanged);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIReflowCommand> reflowCmd;
|
||||
rv = NS_NewHTMLReflowCommand(getter_AddRefs(reflowCmd), this,
|
||||
nsIReflowCommand::StyleChanged);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
shell->AppendReflowCommand(reflowCmd);
|
||||
}
|
||||
shell->AppendReflowCommand(reflowCmd);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -990,149 +982,9 @@ nsMenuFrame::UpdateMenuSpecialState(nsIPresContext* aPresContext) {
|
|||
NS_IMETHODIMP
|
||||
nsMenuFrame::CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aAnonymousChildren)
|
||||
{
|
||||
// Create anonymous children only if the menu has no children or
|
||||
// only has a menuchildren as its child.
|
||||
nsCOMPtr<nsIDOMNode> dummyResult;
|
||||
|
||||
PRInt32 childCount;
|
||||
mContent->ChildCount(childCount);
|
||||
mHasAnonymousContent = PR_TRUE;
|
||||
for (PRInt32 i = 0; i < childCount; i++) {
|
||||
// XXX Should optimize this to look for a display type of none.
|
||||
// Not sure how to do this. For now screen out some known tags.
|
||||
nsCOMPtr<nsIContent> childContent;
|
||||
mContent->ChildAt(i, *getter_AddRefs(childContent));
|
||||
nsCOMPtr<nsIAtom> tag;
|
||||
childContent->GetTag(*getter_AddRefs(tag));
|
||||
if (tag.get() != nsXULAtoms::menupopup &&
|
||||
tag.get() != nsXULAtoms::templateAtom &&
|
||||
tag.get() != nsXULAtoms::observes) {
|
||||
mHasAnonymousContent = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mHasAnonymousContent)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDocument> idocument;
|
||||
mContent->GetDocument(*getter_AddRefs(idocument));
|
||||
nsCOMPtr<nsIDOMNSDocument> nsDocument(do_QueryInterface(idocument));
|
||||
nsCOMPtr<nsIDOMDocument> document(do_QueryInterface(idocument));
|
||||
|
||||
nsAutoString xulNamespace("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
|
||||
nsAutoString htmlNamespace("http://www.w3.org/TR/REC-html40");
|
||||
nsCOMPtr<nsIAtom> classAtom = dont_AddRef(NS_NewAtom("class"));
|
||||
|
||||
nsCOMPtr<nsIDOMElement> node;
|
||||
nsCOMPtr<nsIContent> content;
|
||||
|
||||
PRBool onMenuBar = PR_FALSE;
|
||||
if (mMenuParent)
|
||||
mMenuParent->IsMenuBar(onMenuBar);
|
||||
|
||||
/* Create .menu-left (.menubar-left) titledbutton for icon. */
|
||||
nsDocument->CreateElementWithNameSpace("titledbutton", xulNamespace,
|
||||
getter_AddRefs(node));
|
||||
content = do_QueryInterface(node);
|
||||
content->SetAttribute(kNameSpaceID_None, classAtom,
|
||||
onMenuBar ? "menubar-left" : "menu-left" , PR_FALSE);
|
||||
aAnonymousChildren.AppendElement(content);
|
||||
|
||||
/*
|
||||
* Create the .menu-text titledbutton, and propagate crop, accesskey and
|
||||
* value attributes. If we're a menubar, make the class menubar-text
|
||||
* instead.
|
||||
*/
|
||||
nsDocument->CreateElementWithNameSpace("titledbutton", xulNamespace,
|
||||
getter_AddRefs(node));
|
||||
content = do_QueryInterface(node);
|
||||
content->SetAttribute(kNameSpaceID_None, classAtom,
|
||||
onMenuBar ? "menubar-text" : "menu-text", PR_FALSE);
|
||||
nsAutoString accessKey, value, crop;
|
||||
|
||||
mMenuText = content;
|
||||
mContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::value, value);
|
||||
content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::value, value, PR_FALSE);
|
||||
mContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::accesskey, accessKey);
|
||||
content->SetAttribute(kNameSpaceID_None, nsXULAtoms::accesskey, accessKey,
|
||||
PR_FALSE);
|
||||
|
||||
mContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::crop, crop);
|
||||
if (crop == "")
|
||||
crop = "right";
|
||||
content->SetAttribute(kNameSpaceID_None, nsXULAtoms::crop, crop, PR_FALSE);
|
||||
// XXX Causes menu items to disappear.
|
||||
// content->SetAttribute(kNameSpaceID_None, nsXULAtoms::flex, "1", PR_FALSE);
|
||||
|
||||
// append now, after we've set all the attributes
|
||||
aAnonymousChildren.AppendElement(content);
|
||||
|
||||
// Do the type="checkbox" magic
|
||||
UpdateMenuType(aPresContext);
|
||||
|
||||
// Create a spring that serves as padding between the text and the
|
||||
// accelerator.
|
||||
if (!onMenuBar) {
|
||||
nsDocument->CreateElementWithNameSpace("spring", xulNamespace, getter_AddRefs(node));
|
||||
content = do_QueryInterface(node);
|
||||
content->SetAttribute(kNameSpaceID_None, classAtom, "menu-spring",
|
||||
PR_FALSE);
|
||||
content->SetAttribute(kNameSpaceID_None, nsXULAtoms::flex, "100000",
|
||||
PR_FALSE);
|
||||
aAnonymousChildren.AppendElement(content);
|
||||
|
||||
// Build the accelerator out of the corresponding key node.
|
||||
nsAutoString accelString;
|
||||
BuildAcceleratorText(accelString);
|
||||
if (accelString != "") {
|
||||
// Create the accelerator (a titledbutton)
|
||||
nsDocument->CreateElementWithNameSpace("titledbutton", xulNamespace,
|
||||
getter_AddRefs(node));
|
||||
content = do_QueryInterface(node);
|
||||
mAccelText = content;
|
||||
content->SetAttribute(kNameSpaceID_None, classAtom, "menu-accel",
|
||||
PR_FALSE);
|
||||
content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::value, accelString,
|
||||
PR_FALSE);
|
||||
aAnonymousChildren.AppendElement(content);
|
||||
|
||||
}
|
||||
|
||||
// Create the "menu-right" object. It's a titledbutton.
|
||||
// XXX Maybe we should make one for a .menubar-right class so that the option exists
|
||||
nsDocument->CreateElementWithNameSpace("titledbutton", xulNamespace, getter_AddRefs(node));
|
||||
content = do_QueryInterface(node);
|
||||
content->SetAttribute(kNameSpaceID_None, classAtom, "menu-right", PR_FALSE);
|
||||
aAnonymousChildren.AppendElement(content);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsMenuFrame::SplitOnShortcut(nsString& aBeforeString, nsString& aAccessString, nsString& aAfterString)
|
||||
{
|
||||
nsString value;
|
||||
nsString accessKey;
|
||||
aBeforeString = value;
|
||||
aAccessString = "";
|
||||
aAfterString = "";
|
||||
|
||||
if (accessKey == "") // Nothing to do.
|
||||
return;
|
||||
|
||||
// Find the index of the first occurrence of the accessKey
|
||||
PRInt32 indx = value.Find(accessKey, PR_TRUE);
|
||||
|
||||
if (indx == -1) // Wasn't in there. Just return.
|
||||
return;
|
||||
|
||||
// It was in the value string. Split based on the indx.
|
||||
value.Left(aBeforeString, indx);
|
||||
value.Mid(aAccessString, indx, 1);
|
||||
value.Right(aAfterString, value.Length()-indx-1);
|
||||
}
|
||||
|
||||
void
|
||||
nsMenuFrame::BuildAcceleratorText(nsString& aAccelString)
|
||||
|
@ -1227,6 +1079,9 @@ nsMenuFrame::BuildAcceleratorText(nsString& aAccelString)
|
|||
prependPlus = PR_TRUE;
|
||||
aAccelString += keyChar;
|
||||
}
|
||||
|
||||
if (aAccelString != "")
|
||||
mContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::acceltext, aAccelString, PR_FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -161,9 +161,6 @@ protected:
|
|||
void OpenMenuInternal(PRBool aActivateFlag);
|
||||
void GetMenuChildrenElement(nsIContent** aResult);
|
||||
|
||||
// Called to split the accesskey attribute up based on the specified string.
|
||||
void SplitOnShortcut(nsString& aBeforeString, nsString& aAccessString, nsString& aAfterString);
|
||||
|
||||
// Examines the key node and builds the accelerator.
|
||||
void BuildAcceleratorText(nsString& aAccelString);
|
||||
|
||||
|
@ -186,7 +183,6 @@ protected:
|
|||
nsFrameList mPopupFrames;
|
||||
PRPackedBool mIsMenu; // Whether or not we can even have children or not.
|
||||
PRPackedBool mMenuOpen;
|
||||
PRPackedBool mHasAnonymousContent; // Do we have anonymous content frames?
|
||||
PRPackedBool mChecked; // if so, are we checked?
|
||||
nsMenuType mType;
|
||||
|
||||
|
|
|
@ -350,7 +350,7 @@ nsScrollbarFrame::AttributeChanged(nsIPresContext* aPresContext,
|
|||
{
|
||||
nsresult rv = nsBoxFrame::AttributeChanged(aPresContext, aChild,
|
||||
aNameSpaceID, aAttribute, aHint);
|
||||
// if the current position changes
|
||||
/*// if the current position changes
|
||||
if ( aAttribute == nsXULAtoms::curpos ||
|
||||
aAttribute == nsXULAtoms::maxpos ||
|
||||
aAttribute == nsXULAtoms::pageincrement ||
|
||||
|
@ -362,6 +362,7 @@ nsScrollbarFrame::AttributeChanged(nsIPresContext* aPresContext,
|
|||
if (slider)
|
||||
slider->AttributeChanged(aPresContext, aChild, aNameSpaceID, aAttribute, aHint);
|
||||
}
|
||||
*/
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -46,9 +46,6 @@
|
|||
#include "nsIComponentManager.h"
|
||||
|
||||
#include "nsLayoutCID.h"
|
||||
static NS_DEFINE_CID(kCRangeCID, NS_RANGE_CID);
|
||||
#include "nsIContentIterator.h"
|
||||
static NS_DEFINE_IID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
|
||||
#include "nsLayoutAtoms.h"
|
||||
|
||||
//
|
||||
|
@ -154,10 +151,10 @@ void nsTreeFrame::ToggleSelection(nsIPresContext* aPresContext, nsTreeCellFrame*
|
|||
treeElement->ToggleCellSelection(cellElement);
|
||||
}
|
||||
|
||||
void nsTreeFrame::RangedSelection(nsIPresContext* aPresContext, nsTreeCellFrame* pEndFrame)
|
||||
void nsTreeFrame::RangedSelection(nsIPresContext* aPresContext, nsTreeCellFrame* aEndFrame)
|
||||
{
|
||||
nsCOMPtr<nsIContent> endCellContent;
|
||||
pEndFrame->GetContent(getter_AddRefs(endCellContent));
|
||||
aEndFrame->GetContent(getter_AddRefs(endCellContent));
|
||||
if (!endCellContent)
|
||||
return;
|
||||
|
||||
|
@ -171,92 +168,10 @@ void nsTreeFrame::RangedSelection(nsIPresContext* aPresContext, nsTreeCellFrame*
|
|||
if (!endItemContent)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIContent> endParent;
|
||||
endItemContent->GetParent(*getter_AddRefs(endParent));
|
||||
if (!endParent)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDOMXULTreeElement> treeElement = do_QueryInterface(mContent);
|
||||
nsIDOMNodeList* selectedItems;
|
||||
treeElement->GetSelectedItems(&selectedItems);
|
||||
if (!selectedItems)
|
||||
return;
|
||||
nsCOMPtr<nsIDOMXULElement> endElement = do_QueryInterface(endItemContent);
|
||||
|
||||
PRUint32 length;
|
||||
selectedItems->GetLength(&length);
|
||||
if (length < 1)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> domNode;
|
||||
selectedItems->Item(0, getter_AddRefs(domNode));
|
||||
nsCOMPtr<nsIContent> startItemContent = do_QueryInterface(domNode);
|
||||
|
||||
nsCOMPtr<nsIContent> startParent;
|
||||
startItemContent->GetParent(*getter_AddRefs(startParent));
|
||||
if (!startParent)
|
||||
return;
|
||||
|
||||
// Get a range so we can create an iterator
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
nsresult result;
|
||||
result = nsComponentManager::CreateInstance(kCRangeCID, nsnull,
|
||||
nsIDOMRange::GetIID(), getter_AddRefs(range));
|
||||
|
||||
PRInt32 startIndex = 0;
|
||||
PRInt32 endIndex = 0;
|
||||
startParent->IndexOf(startItemContent, startIndex);
|
||||
endParent->IndexOf(endItemContent, endIndex);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> startDOMNode = do_QueryInterface(startParent);
|
||||
nsCOMPtr<nsIDOMNode> endDOMNode = do_QueryInterface(endParent);
|
||||
result = range->SetStart(startDOMNode, startIndex);
|
||||
result = range->SetEnd(endDOMNode, endIndex+1);
|
||||
if (NS_FAILED(result))
|
||||
{
|
||||
// Ranges need to be increasing, try reversing directions
|
||||
result = range->SetStart(endDOMNode, endIndex);
|
||||
result = range->SetEnd(startDOMNode, startIndex+1);
|
||||
if (NS_FAILED(result))
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the iterator
|
||||
nsCOMPtr<nsIContentIterator> iter;
|
||||
result = nsComponentManager::CreateInstance(kCContentIteratorCID, nsnull,
|
||||
nsIContentIterator::GetIID(),
|
||||
getter_AddRefs(iter));
|
||||
if (NS_FAILED(result))
|
||||
return; // result;
|
||||
|
||||
// Iterate and select
|
||||
nsCOMPtr<nsIAtom> treeItemAtom = dont_AddRef(NS_NewAtom("treeitem"));
|
||||
nsCOMPtr<nsIAtom> selectedAtom = dont_AddRef(NS_NewAtom("selected"));
|
||||
nsCOMPtr<nsIAtom> suppressSelectAtom = dont_AddRef(NS_NewAtom("suppressonselect"));
|
||||
nsAutoString trueString("true", 4);
|
||||
nsCOMPtr<nsIContent> content = nsnull;
|
||||
nsCOMPtr<nsIAtom> tag;
|
||||
|
||||
iter->Init(range);
|
||||
result = iter->First();
|
||||
while (NS_SUCCEEDED(result) && NS_ENUMERATOR_FALSE == iter->IsDone())
|
||||
{
|
||||
result = iter->CurrentNode(getter_AddRefs(content));
|
||||
if (NS_FAILED(result) || !content)
|
||||
return; // result;
|
||||
|
||||
// If tag==item, Do selection stuff
|
||||
content->GetTag(*getter_AddRefs(tag));
|
||||
if (tag && tag == treeItemAtom)
|
||||
{
|
||||
content->SetAttribute(kNameSpaceID_None, selectedAtom,
|
||||
trueString, /*aNotify*/ PR_TRUE);
|
||||
}
|
||||
|
||||
result = iter->Next();
|
||||
// Deal with closed nodes here
|
||||
// Also had strangeness where parent of selected subrange was selected even
|
||||
// though it wasn't in the range.
|
||||
}
|
||||
treeElement->SelectItemRange(nsnull, endElement);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -540,34 +455,6 @@ nsTreeFrame::DidReflow(nsIPresContext* aPresContext,
|
|||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeFrame::MarkForDirtyReflow(nsIPresContext* aPresContext)
|
||||
{
|
||||
mSuppressReflow = PR_FALSE;
|
||||
InvalidateFirstPassCache();
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
nsFrameState frameState;
|
||||
nsIFrame* tableParentFrame;
|
||||
nsIReflowCommand* reflowCmd;
|
||||
|
||||
// Mark the table frame as dirty
|
||||
GetFrameState(&frameState);
|
||||
frameState |= NS_FRAME_IS_DIRTY;
|
||||
SetFrameState(frameState);
|
||||
|
||||
// Target the reflow comamnd at its parent frame
|
||||
GetParent(&tableParentFrame);
|
||||
nsresult rv = NS_NewHTMLReflowCommand(&reflowCmd, tableParentFrame,
|
||||
nsIReflowCommand::ReflowDirty);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Add the reflow command
|
||||
rv = shell->AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeFrame::Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
|
|
|
@ -85,8 +85,6 @@ public:
|
|||
|
||||
PRBool ContainsFlexibleColumn(PRInt32 aStartIndex, PRInt32 aEndIndex, nsTableColFrame** aResult);
|
||||
|
||||
NS_IMETHOD MarkForDirtyReflow(nsIPresContext* aPresContext);
|
||||
|
||||
void SuppressReflow() { mSuppressReflow = PR_TRUE; };
|
||||
void UnsuppressReflow() { mSuppressReflow = PR_FALSE; };
|
||||
|
||||
|
|
|
@ -413,9 +413,6 @@ nsTreeRowFrame::HandleHeaderDragEvent(nsIPresContext* aPresContext,
|
|||
nsAutoString propColWidth(ch);
|
||||
flexContent->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::width, propColWidth,
|
||||
PR_TRUE); // NOW we send the notification that causes the reflow.
|
||||
|
||||
// Do a dirty table reflow.
|
||||
//treeFrame->MarkForDirtyReflow(aPresContext);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -1018,59 +1018,7 @@ nsTreeRowGroupFrame::ReflowAfterRowLayout(nsIPresContext* aPresContext,
|
|||
nsReflowReason aReason)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
PRInt32 count = 0;
|
||||
ComputeTotalRowCount(count, mContent); // XXX This sucks! Needs to be cheap!
|
||||
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
nsTreeFrame* treeFrame = (nsTreeFrame*)tableFrame;
|
||||
|
||||
// Our page size is the # of rows instantiated.
|
||||
PRInt32 pageRowCount;
|
||||
GetRowCount(pageRowCount);
|
||||
|
||||
if (mScrollbar) {
|
||||
PRBool nukeScrollbar=PR_FALSE;
|
||||
nsAutoString value;
|
||||
|
||||
nsCOMPtr<nsIContent> scrollbarContent;
|
||||
mScrollbar->GetContent(getter_AddRefs(scrollbarContent));
|
||||
|
||||
if (count < pageRowCount) {
|
||||
// first set the position to 0 so that all visible content
|
||||
// scrolls into view
|
||||
value.Append(0);
|
||||
scrollbarContent->SetAttribute(kNameSpaceID_None,
|
||||
nsXULAtoms::curpos,
|
||||
value, PR_TRUE);
|
||||
// now force nuking the scrollbar
|
||||
// (otherwise it takes a bunch of reflows to actually make it go away)
|
||||
nukeScrollbar=PR_TRUE;
|
||||
}
|
||||
|
||||
else {
|
||||
scrollbarContent->GetAttribute(kNameSpaceID_None,
|
||||
nsXULAtoms::curpos, value);
|
||||
}
|
||||
|
||||
if (nukeScrollbar || (value == "0" && !mIsFull)) {
|
||||
|
||||
// clear the scrollbar out of the event state manager so that the
|
||||
// event manager doesn't send events to the destroyed scrollbar frames
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
ClearFrameRefs(aPresContext, shell, mScrollbar);
|
||||
|
||||
// Nuke the scrollbar.
|
||||
mFrameConstructor->RemoveMappingsForFrameSubtree(aPresContext, mScrollbar, nsnull);
|
||||
mScrollbarList.DestroyFrames(aPresContext);
|
||||
mScrollbar = nsnull;
|
||||
|
||||
// Dirty the tree for another reflow.
|
||||
MarkTreeAsDirty(aPresContext, treeFrame);
|
||||
}
|
||||
}
|
||||
ReflowScrollbar(aPresContext);
|
||||
|
||||
if ((mOuterFrame == this) && (mRowGroupHeight != NS_UNCONSTRAINEDSIZE) &&
|
||||
(mIsFull || mScrollbar)) {
|
||||
|
@ -1083,41 +1031,6 @@ nsTreeRowGroupFrame::ReflowAfterRowLayout(nsIPresContext* aPresContext,
|
|||
createdScrollbar = PR_TRUE;
|
||||
}
|
||||
|
||||
// Set the maxpos of the scrollbar.
|
||||
nsCOMPtr<nsIContent> scrollbarContent;
|
||||
mScrollbar->GetContent(getter_AddRefs(scrollbarContent));
|
||||
|
||||
PRInt32 rowCount = count-1;
|
||||
if (rowCount < 0)
|
||||
rowCount = 0;
|
||||
|
||||
// Subtract one from our maxpos if we're a fixed row height.
|
||||
PRInt32 rowSize = treeFrame->GetFixedRowSize();
|
||||
if (rowSize != -1) {
|
||||
rowCount--;
|
||||
}
|
||||
|
||||
nsAutoString maxpos;
|
||||
if (!mIsFull) {
|
||||
// We are not full. This means that we are not allowed to scroll any further. We are
|
||||
// at the max position right now.
|
||||
scrollbarContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::curpos, maxpos);
|
||||
}
|
||||
else {
|
||||
|
||||
if (pageRowCount < 2)
|
||||
pageRowCount = 2;
|
||||
|
||||
rowCount -= (pageRowCount-2);
|
||||
|
||||
char ch[100];
|
||||
sprintf(ch,"%d", rowCount);
|
||||
maxpos = ch;
|
||||
}
|
||||
|
||||
// Make sure our position is accurate.
|
||||
scrollbarContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::maxpos, maxpos, PR_FALSE);
|
||||
|
||||
// We must be constrained, or a scrollbar makes no sense.
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
|
@ -1162,10 +1075,7 @@ nsTreeRowGroupFrame::ReflowAfterRowLayout(nsIPresContext* aPresContext,
|
|||
|
||||
MarkTreeAsDirty(aPresContext, (nsTreeFrame*)tableFrame);
|
||||
}
|
||||
}
|
||||
|
||||
mRowCount = count;
|
||||
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1613,9 +1523,100 @@ void nsTreeRowGroupFrame::OnContentRemoved(nsIPresContext* aPresContext,
|
|||
void
|
||||
nsTreeRowGroupFrame::ReflowScrollbar(nsIPresContext* aPresContext)
|
||||
{
|
||||
PRInt32 count = 0;
|
||||
ComputeTotalRowCount(count, mContent); // XXX This sucks! Needs to be cheap!
|
||||
mRowCount = count;
|
||||
|
||||
if (!mScrollbar)
|
||||
return;
|
||||
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
nsTreeFrame* treeFrame = (nsTreeFrame*)tableFrame;
|
||||
|
||||
// Our page size is the # of rows instantiated.
|
||||
PRInt32 pageRowCount;
|
||||
GetRowCount(pageRowCount);
|
||||
|
||||
if (mScrollbar) {
|
||||
PRBool nukeScrollbar=PR_FALSE;
|
||||
nsAutoString value;
|
||||
|
||||
nsCOMPtr<nsIContent> scrollbarContent;
|
||||
mScrollbar->GetContent(getter_AddRefs(scrollbarContent));
|
||||
|
||||
if (count < pageRowCount) {
|
||||
// first set the position to 0 so that all visible content
|
||||
// scrolls into view
|
||||
value.Append(0);
|
||||
scrollbarContent->SetAttribute(kNameSpaceID_None,
|
||||
nsXULAtoms::curpos,
|
||||
value, PR_TRUE);
|
||||
// now force nuking the scrollbar
|
||||
// (otherwise it takes a bunch of reflows to actually make it go away)
|
||||
nukeScrollbar=PR_TRUE;
|
||||
}
|
||||
|
||||
else {
|
||||
scrollbarContent->GetAttribute(kNameSpaceID_None,
|
||||
nsXULAtoms::curpos, value);
|
||||
}
|
||||
|
||||
if (nukeScrollbar || (value == "0" && !mIsFull)) {
|
||||
|
||||
// clear the scrollbar out of the event state manager so that the
|
||||
// event manager doesn't send events to the destroyed scrollbar frames
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
ClearFrameRefs(shell, mScrollbar);
|
||||
|
||||
// Nuke the scrollbar.
|
||||
mFrameConstructor->RemoveMappingsForFrameSubtree(aPresContext, mScrollbar, nsnull);
|
||||
mScrollbarList.DestroyFrames(aPresContext);
|
||||
mScrollbar = nsnull;
|
||||
|
||||
// Dirty the tree for another reflow.
|
||||
MarkTreeAsDirty(aPresContext, treeFrame);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mScrollbar)
|
||||
return;
|
||||
|
||||
// Set the maxpos of the scrollbar.
|
||||
nsCOMPtr<nsIContent> scrollbarContent;
|
||||
mScrollbar->GetContent(getter_AddRefs(scrollbarContent));
|
||||
|
||||
PRInt32 rowCount = count-1;
|
||||
if (rowCount < 0)
|
||||
rowCount = 0;
|
||||
|
||||
// Subtract one from our maxpos if we're a fixed row height.
|
||||
PRInt32 rowSize = treeFrame->GetFixedRowSize();
|
||||
if (rowSize != -1) {
|
||||
rowCount--;
|
||||
}
|
||||
|
||||
nsAutoString maxpos;
|
||||
if (!mIsFull) {
|
||||
// We are not full. This means that we are not allowed to scroll any further. We are
|
||||
// at the max position right now.
|
||||
scrollbarContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::curpos, maxpos);
|
||||
}
|
||||
else {
|
||||
|
||||
if (pageRowCount < 2)
|
||||
pageRowCount = 2;
|
||||
|
||||
rowCount -= (pageRowCount-2);
|
||||
|
||||
char ch[100];
|
||||
sprintf(ch,"%d", rowCount);
|
||||
maxpos = ch;
|
||||
}
|
||||
|
||||
// Make sure our position is accurate.
|
||||
scrollbarContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::maxpos, maxpos, PR_TRUE);
|
||||
}
|
||||
|
||||
void nsTreeRowGroupFrame::SetContentChain(nsISupportsArray* aContentChain)
|
||||
|
|
|
@ -13,5 +13,8 @@ interface XULElement : Element {
|
|||
void removeBroadcastListener(in DOMString attr, in Element element);
|
||||
void doCommand();
|
||||
|
||||
void focus();
|
||||
void blur();
|
||||
|
||||
NodeList getElementsByAttribute(in DOMString name, in DOMString value);
|
||||
};
|
||||
|
|
|
@ -3,6 +3,9 @@ interface XULTreeElement : XULElement {
|
|||
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} } */
|
||||
readonly attribute NodeList selectedItems;
|
||||
readonly attribute NodeList selectedCells;
|
||||
|
||||
readonly attribute XULElement currentItem;
|
||||
readonly attribute XULElement currentCell;
|
||||
|
||||
void selectItem(in XULElement treeItem);
|
||||
void selectCell(in XULElement treeCell);
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
/* AUTO-GENERATED. DO NOT EDIT!!! */
|
||||
|
||||
|
|
|
@ -65,6 +65,10 @@ public:
|
|||
|
||||
NS_IMETHOD DoCommand()=0;
|
||||
|
||||
NS_IMETHOD Focus()=0;
|
||||
|
||||
NS_IMETHOD Blur()=0;
|
||||
|
||||
NS_IMETHOD GetElementsByAttribute(const nsString& aName, const nsString& aValue, nsIDOMNodeList** aReturn)=0;
|
||||
};
|
||||
|
||||
|
@ -82,6 +86,8 @@ public:
|
|||
NS_IMETHOD AddBroadcastListener(const nsString& aAttr, nsIDOMElement* aElement); \
|
||||
NS_IMETHOD RemoveBroadcastListener(const nsString& aAttr, nsIDOMElement* aElement); \
|
||||
NS_IMETHOD DoCommand(); \
|
||||
NS_IMETHOD Focus(); \
|
||||
NS_IMETHOD Blur(); \
|
||||
NS_IMETHOD GetElementsByAttribute(const nsString& aName, const nsString& aValue, nsIDOMNodeList** aReturn); \
|
||||
|
||||
|
||||
|
@ -99,6 +105,8 @@ public:
|
|||
NS_IMETHOD AddBroadcastListener(const nsString& aAttr, nsIDOMElement* aElement) { return _to AddBroadcastListener(aAttr, aElement); } \
|
||||
NS_IMETHOD RemoveBroadcastListener(const nsString& aAttr, nsIDOMElement* aElement) { return _to RemoveBroadcastListener(aAttr, aElement); } \
|
||||
NS_IMETHOD DoCommand() { return _to DoCommand(); } \
|
||||
NS_IMETHOD Focus() { return _to Focus(); } \
|
||||
NS_IMETHOD Blur() { return _to Blur(); } \
|
||||
NS_IMETHOD GetElementsByAttribute(const nsString& aName, const nsString& aValue, nsIDOMNodeList** aReturn) { return _to GetElementsByAttribute(aName, aValue, aReturn); } \
|
||||
|
||||
|
||||
|
|
|
@ -44,6 +44,10 @@ public:
|
|||
|
||||
NS_IMETHOD GetSelectedCells(nsIDOMNodeList** aSelectedCells)=0;
|
||||
|
||||
NS_IMETHOD GetCurrentItem(nsIDOMXULElement** aCurrentItem)=0;
|
||||
|
||||
NS_IMETHOD GetCurrentCell(nsIDOMXULElement** aCurrentCell)=0;
|
||||
|
||||
NS_IMETHOD SelectItem(nsIDOMXULElement* aTreeItem)=0;
|
||||
|
||||
NS_IMETHOD SelectCell(nsIDOMXULElement* aTreeCell)=0;
|
||||
|
@ -81,6 +85,8 @@ public:
|
|||
#define NS_DECL_IDOMXULTREEELEMENT \
|
||||
NS_IMETHOD GetSelectedItems(nsIDOMNodeList** aSelectedItems); \
|
||||
NS_IMETHOD GetSelectedCells(nsIDOMNodeList** aSelectedCells); \
|
||||
NS_IMETHOD GetCurrentItem(nsIDOMXULElement** aCurrentItem); \
|
||||
NS_IMETHOD GetCurrentCell(nsIDOMXULElement** aCurrentCell); \
|
||||
NS_IMETHOD SelectItem(nsIDOMXULElement* aTreeItem); \
|
||||
NS_IMETHOD SelectCell(nsIDOMXULElement* aTreeCell); \
|
||||
NS_IMETHOD ClearItemSelection(); \
|
||||
|
@ -103,6 +109,8 @@ public:
|
|||
#define NS_FORWARD_IDOMXULTREEELEMENT(_to) \
|
||||
NS_IMETHOD GetSelectedItems(nsIDOMNodeList** aSelectedItems) { return _to GetSelectedItems(aSelectedItems); } \
|
||||
NS_IMETHOD GetSelectedCells(nsIDOMNodeList** aSelectedCells) { return _to GetSelectedCells(aSelectedCells); } \
|
||||
NS_IMETHOD GetCurrentItem(nsIDOMXULElement** aCurrentItem) { return _to GetCurrentItem(aCurrentItem); } \
|
||||
NS_IMETHOD GetCurrentCell(nsIDOMXULElement** aCurrentCell) { return _to GetCurrentCell(aCurrentCell); } \
|
||||
NS_IMETHOD SelectItem(nsIDOMXULElement* aTreeItem) { return _to SelectItem(aTreeItem); } \
|
||||
NS_IMETHOD SelectCell(nsIDOMXULElement* aTreeCell) { return _to SelectCell(aTreeCell); } \
|
||||
NS_IMETHOD ClearItemSelection() { return _to ClearItemSelection(); } \
|
||||
|
|
|
@ -440,7 +440,7 @@ XULCommandDispatcherGetControllerForCommand(JSContext *cx, JSObject *obj, uintN
|
|||
}
|
||||
|
||||
// n.b., this will release nativeRet
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(nativeRet, nsIController::GetIID(), cx, obj, rval);
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(nativeRet, NS_GET_IID(nsIController), cx, obj, rval);
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
|
@ -486,7 +486,7 @@ XULCommandDispatcherGetControllers(JSContext *cx, JSObject *obj, uintN argc, jsv
|
|||
}
|
||||
|
||||
// n.b., this will release nativeRet
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(nativeRet, nsIControllers::GetIID(), cx, obj, rval);
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(nativeRet, NS_GET_IID(nsIControllers), cx, obj, rval);
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
/* AUTO-GENERATED. DO NOT EDIT!!! */
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ GetXULEditorElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
result = a->GetEditorShell(&prop);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
// get the js object; n.b., this will do a release on 'prop'
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(prop, nsIEditorShell::GetIID(), cx, obj, vp);
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(prop, NS_GET_IID(nsIEditorShell), cx, obj, vp);
|
||||
}
|
||||
else {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
|
|
|
@ -155,7 +155,7 @@ GetXULElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
result = a->GetDatabase(&prop);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
// get the js object; n.b., this will do a release on 'prop'
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(prop, nsIRDFCompositeDataSource::GetIID(), cx, obj, vp);
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(prop, NS_GET_IID(nsIRDFCompositeDataSource), cx, obj, vp);
|
||||
}
|
||||
else {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
|
@ -174,7 +174,7 @@ GetXULElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
result = a->GetResource(&prop);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
// get the js object; n.b., this will do a release on 'prop'
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(prop, nsIRDFResource::GetIID(), cx, obj, vp);
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(prop, NS_GET_IID(nsIRDFResource), cx, obj, vp);
|
||||
}
|
||||
else {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
|
@ -193,7 +193,7 @@ GetXULElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
result = a->GetControllers(&prop);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
// get the js object; n.b., this will do a release on 'prop'
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(prop, nsIControllers::GetIID(), cx, obj, vp);
|
||||
nsJSUtils::nsConvertXPCObjectToJSVal(prop, NS_GET_IID(nsIControllers), cx, obj, vp);
|
||||
}
|
||||
else {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
|
@ -480,6 +480,94 @@ XULElementDoCommand(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval
|
|||
}
|
||||
|
||||
|
||||
//
|
||||
// Native method Focus
|
||||
//
|
||||
PR_STATIC_CALLBACK(JSBool)
|
||||
XULElementFocus(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
nsIDOMXULElement *nativeThis = (nsIDOMXULElement*)nsJSUtils::nsGetNativeThis(cx, obj);
|
||||
nsresult result = NS_OK;
|
||||
// If there's no private data, this must be the prototype, so ignore
|
||||
if (nsnull == nativeThis) {
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
*rval = JSVAL_NULL;
|
||||
|
||||
{
|
||||
PRBool ok;
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIScriptSecurityManager, secMan,
|
||||
NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECMAN_ERR);
|
||||
}
|
||||
secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULELEMENT_FOCUS, PR_FALSE, &ok);
|
||||
if (!ok) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECURITY_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
result = nativeThis->Focus();
|
||||
if (NS_FAILED(result)) {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
}
|
||||
|
||||
*rval = JSVAL_VOID;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Native method Blur
|
||||
//
|
||||
PR_STATIC_CALLBACK(JSBool)
|
||||
XULElementBlur(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
nsIDOMXULElement *nativeThis = (nsIDOMXULElement*)nsJSUtils::nsGetNativeThis(cx, obj);
|
||||
nsresult result = NS_OK;
|
||||
// If there's no private data, this must be the prototype, so ignore
|
||||
if (nsnull == nativeThis) {
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
*rval = JSVAL_NULL;
|
||||
|
||||
{
|
||||
PRBool ok;
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIScriptSecurityManager, secMan,
|
||||
NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECMAN_ERR);
|
||||
}
|
||||
secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULELEMENT_BLUR, PR_FALSE, &ok);
|
||||
if (!ok) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECURITY_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
result = nativeThis->Blur();
|
||||
if (NS_FAILED(result)) {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
}
|
||||
|
||||
*rval = JSVAL_VOID;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Native method GetElementsByAttribute
|
||||
//
|
||||
|
@ -574,6 +662,8 @@ static JSFunctionSpec XULElementMethods[] =
|
|||
{"addBroadcastListener", XULElementAddBroadcastListener, 2},
|
||||
{"removeBroadcastListener", XULElementRemoveBroadcastListener, 2},
|
||||
{"doCommand", XULElementDoCommand, 0},
|
||||
{"focus", XULElementFocus, 0},
|
||||
{"blur", XULElementBlur, 0},
|
||||
{"getElementsByAttribute", XULElementGetElementsByAttribute, 2},
|
||||
{0}
|
||||
};
|
||||
|
|
|
@ -51,7 +51,9 @@ static NS_DEFINE_IID(kINodeListIID, NS_IDOMNODELIST_IID);
|
|||
//
|
||||
enum XULTreeElement_slots {
|
||||
XULTREEELEMENT_SELECTEDITEMS = -1,
|
||||
XULTREEELEMENT_SELECTEDCELLS = -2
|
||||
XULTREEELEMENT_SELECTEDCELLS = -2,
|
||||
XULTREEELEMENT_CURRENTITEM = -3,
|
||||
XULTREEELEMENT_CURRENTCELL = -4
|
||||
};
|
||||
|
||||
/***********************************************************************/
|
||||
|
@ -114,6 +116,44 @@ GetXULTreeElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case XULTREEELEMENT_CURRENTITEM:
|
||||
{
|
||||
PRBool ok = PR_FALSE;
|
||||
secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULTREEELEMENT_CURRENTITEM, PR_FALSE, &ok);
|
||||
if (!ok) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECURITY_ERR);
|
||||
}
|
||||
nsIDOMXULElement* prop;
|
||||
nsresult result = NS_OK;
|
||||
result = a->GetCurrentItem(&prop);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
// get the js object
|
||||
nsJSUtils::nsConvertObjectToJSVal((nsISupports *)prop, cx, obj, vp);
|
||||
}
|
||||
else {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XULTREEELEMENT_CURRENTCELL:
|
||||
{
|
||||
PRBool ok = PR_FALSE;
|
||||
secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULTREEELEMENT_CURRENTCELL, PR_FALSE, &ok);
|
||||
if (!ok) {
|
||||
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECURITY_ERR);
|
||||
}
|
||||
nsIDOMXULElement* prop;
|
||||
nsresult result = NS_OK;
|
||||
result = a->GetCurrentCell(&prop);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
// get the js object
|
||||
nsJSUtils::nsConvertObjectToJSVal((nsISupports *)prop, cx, obj, vp);
|
||||
}
|
||||
else {
|
||||
return nsJSUtils::nsReportError(cx, obj, result);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return nsJSUtils::nsCallJSScriptObjectGetProperty(a, cx, obj, id, vp);
|
||||
}
|
||||
|
@ -1080,6 +1120,8 @@ static JSPropertySpec XULTreeElementProperties[] =
|
|||
{
|
||||
{"selectedItems", XULTREEELEMENT_SELECTEDITEMS, JSPROP_ENUMERATE | JSPROP_READONLY},
|
||||
{"selectedCells", XULTREEELEMENT_SELECTEDCELLS, JSPROP_ENUMERATE | JSPROP_READONLY},
|
||||
{"currentItem", XULTREEELEMENT_CURRENTITEM, JSPROP_ENUMERATE | JSPROP_READONLY},
|
||||
{"currentCell", XULTREEELEMENT_CURRENTCELL, JSPROP_ENUMERATE | JSPROP_READONLY},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
|
|
@ -2307,14 +2307,14 @@ nsXULElement::SetAttribute(PRInt32 aNameSpaceID,
|
|||
|
||||
// Check to see if the CLASS attribute is being set. If so, we need to rebuild our
|
||||
// class list.
|
||||
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && (aName == kClassAtom)) {
|
||||
if ((aNameSpaceID == kNameSpaceID_None) && (aName == kClassAtom)) {
|
||||
Attributes()->UpdateClassList(aValue);
|
||||
}
|
||||
|
||||
// Check to see if the STYLE attribute is being set. If so, we need to create a new
|
||||
// style rule based off the value of this attribute, and we need to let the document
|
||||
// know about the StyleRule change.
|
||||
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && (aName == kStyleAtom)) {
|
||||
if ((aNameSpaceID == kNameSpaceID_None) && (aName == kStyleAtom)) {
|
||||
nsCOMPtr <nsIURI> docURL;
|
||||
mDocument->GetBaseURL(*getter_AddRefs(docURL));
|
||||
Attributes()->UpdateStyleRule(docURL, aValue);
|
||||
|
@ -2421,8 +2421,12 @@ nsXULElement::SetAttribute(PRInt32 aNameSpaceID,
|
|||
}
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv) && aNotify && ElementIsInDocument()) {
|
||||
mDocument->AttributeChanged(NS_STATIC_CAST(nsIStyledContent*, this), aNameSpaceID, aName, NS_STYLE_HINT_UNKNOWN);
|
||||
if (NS_SUCCEEDED(rv) && aNotify) {
|
||||
if (Binding())
|
||||
Binding()->AttributeChanged(aName, aNameSpaceID, PR_FALSE);
|
||||
|
||||
if (mDocument)
|
||||
mDocument->AttributeChanged(NS_STATIC_CAST(nsIStyledContent*, this), aNameSpaceID, aName, NS_STYLE_HINT_UNKNOWN);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -2613,6 +2617,9 @@ nsXULElement::UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, PRBool aNotif
|
|||
|
||||
// Notify document
|
||||
if (NS_SUCCEEDED(rv) && aNotify && (nsnull != mDocument)) {
|
||||
if (Binding())
|
||||
Binding()->AttributeChanged(aName, aNameSpaceID, PR_TRUE);
|
||||
|
||||
mDocument->AttributeChanged(NS_STATIC_CAST(nsIStyledContent*, this),
|
||||
aNameSpaceID, aName,
|
||||
NS_STYLE_HINT_UNKNOWN);
|
||||
|
@ -3644,7 +3651,55 @@ nsXULElement::IsAncestor(nsIDOMNode* aParentNode, nsIDOMNode* aChildNode)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULElement::Focus()
|
||||
{
|
||||
// Make sure we're focusable.
|
||||
nsCOMPtr<nsIFocusableContent> focusable = do_QueryInterface((nsIStyledContent*)this);
|
||||
if (!focusable)
|
||||
return NS_OK;
|
||||
|
||||
// Obtain a presentation context and then call SetFocus.
|
||||
PRInt32 count = mDocument->GetNumberOfShells();
|
||||
if (count == 0)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell = getter_AddRefs(mDocument->GetShellAt(0));
|
||||
|
||||
// Retrieve the context
|
||||
nsCOMPtr<nsIPresContext> aPresContext;
|
||||
shell->GetPresContext(getter_AddRefs(aPresContext));
|
||||
|
||||
// Set focus
|
||||
return SetFocus(aPresContext);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULElement::Blur()
|
||||
{
|
||||
// Make sure we're focusable.
|
||||
nsCOMPtr<nsIFocusableContent> focusable = do_QueryInterface((nsIStyledContent*)this);
|
||||
if (!focusable)
|
||||
return NS_OK;
|
||||
|
||||
// Obtain a presentation context and then call SetFocus.
|
||||
PRInt32 count = mDocument->GetNumberOfShells();
|
||||
if (count == 0)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell = getter_AddRefs(mDocument->GetShellAt(0));
|
||||
|
||||
// Retrieve the context
|
||||
nsCOMPtr<nsIPresContext> aPresContext;
|
||||
shell->GetPresContext(getter_AddRefs(aPresContext));
|
||||
|
||||
// Set focus
|
||||
return RemoveFocus(aPresContext);
|
||||
}
|
||||
|
||||
|
||||
// nsIFocusableContent interface and helpers
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULElement::SetFocus(nsIPresContext* aPresContext)
|
||||
{
|
||||
|
|
|
@ -36,14 +36,23 @@
|
|||
#include "nsIPresShell.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsITreeFrame.h"
|
||||
#include "nsIDOMRange.h"
|
||||
#include "nsIContentIterator.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsString.h"
|
||||
|
||||
static NS_DEFINE_CID(kCRangeCID, NS_RANGE_CID);
|
||||
static NS_DEFINE_IID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
|
||||
|
||||
nsIAtom* nsXULTreeElement::kSelectedAtom;
|
||||
nsIAtom* nsXULTreeElement::kOpenAtom;
|
||||
nsIAtom* nsXULTreeElement::kTreeRowAtom;
|
||||
nsIAtom* nsXULTreeElement::kTreeItemAtom;
|
||||
nsIAtom* nsXULTreeElement::kTreeChildrenAtom;
|
||||
nsIAtom* nsXULTreeElement::kCurrentAtom;
|
||||
int nsXULTreeElement::gRefCnt = 0;
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsXULTreeElement, nsXULAggregateElement);
|
||||
|
@ -79,7 +88,8 @@ nsXULTreeElement::nsXULTreeElement(nsIDOMXULElement* aOuter)
|
|||
kOpenAtom = NS_NewAtom("open");
|
||||
kTreeRowAtom = NS_NewAtom("treerow");
|
||||
kTreeItemAtom = NS_NewAtom("treeitem");
|
||||
kTreeChildrenAtom= NS_NewAtom("treeitem");
|
||||
kTreeChildrenAtom= NS_NewAtom("treechildren");
|
||||
kCurrentAtom = NS_NewAtom("current");
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
@ -97,6 +107,9 @@ nsXULTreeElement::nsXULTreeElement(nsIDOMXULElement* aOuter)
|
|||
if (NS_FAILED(rv)) return;
|
||||
|
||||
mSelectedCells = children;
|
||||
|
||||
mCurrentItem = nsnull;
|
||||
mCurrentCell = nsnull;
|
||||
}
|
||||
|
||||
nsXULTreeElement::~nsXULTreeElement()
|
||||
|
@ -111,6 +124,11 @@ nsXULTreeElement::~nsXULTreeElement()
|
|||
|
||||
if (--gRefCnt == 0) {
|
||||
NS_IF_RELEASE(kSelectedAtom);
|
||||
NS_IF_RELEASE(kTreeItemAtom);
|
||||
NS_IF_RELEASE(kTreeRowAtom);
|
||||
NS_IF_RELEASE(kTreeChildrenAtom);
|
||||
NS_IF_RELEASE(kOpenAtom);
|
||||
NS_IF_RELEASE(kCurrentAtom);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,6 +169,8 @@ nsXULTreeElement::SelectItem(nsIDOMXULElement* aTreeItem)
|
|||
// Now add ourselves to the selection by setting our selected attribute.
|
||||
AddItemToSelectionInternal(aTreeItem);
|
||||
|
||||
SetCurrentItem(aTreeItem);
|
||||
|
||||
FireOnSelectHandler();
|
||||
|
||||
return NS_OK;
|
||||
|
@ -177,6 +197,8 @@ nsXULTreeElement::SelectCell(nsIDOMXULElement* aTreeCell)
|
|||
// Now add ourselves to the selection by setting our selected attribute.
|
||||
AddCellToSelectionInternal(aTreeCell);
|
||||
|
||||
SetCurrentCell(aTreeCell);
|
||||
|
||||
FireOnSelectHandler();
|
||||
|
||||
return NS_OK;
|
||||
|
@ -299,6 +321,8 @@ nsXULTreeElement::ToggleItemSelection(nsIDOMXULElement* aTreeItem)
|
|||
RemoveItemFromSelectionInternal(aTreeItem);
|
||||
else AddItemToSelectionInternal(aTreeItem);
|
||||
|
||||
SetCurrentItem(aTreeItem);
|
||||
|
||||
FireOnSelectHandler();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -312,6 +336,8 @@ nsXULTreeElement::ToggleCellSelection(nsIDOMXULElement* aTreeCell)
|
|||
RemoveCellFromSelectionInternal(aTreeCell);
|
||||
else AddCellToSelectionInternal(aTreeCell);
|
||||
|
||||
SetCurrentCell(aTreeCell);
|
||||
|
||||
FireOnSelectHandler();
|
||||
|
||||
return NS_OK;
|
||||
|
@ -321,7 +347,93 @@ nsXULTreeElement::ToggleCellSelection(nsIDOMXULElement* aTreeCell)
|
|||
NS_IMETHODIMP
|
||||
nsXULTreeElement::SelectItemRange(nsIDOMXULElement* aStartItem, nsIDOMXULElement* aEndItem)
|
||||
{
|
||||
// XXX Fill in.
|
||||
nsCOMPtr<nsIDOMXULElement> startItem;
|
||||
if (aStartItem == nsnull) {
|
||||
// Continue the ranged selection based off the current item.
|
||||
startItem = mCurrentItem;
|
||||
}
|
||||
else startItem = aStartItem;
|
||||
|
||||
if (!startItem)
|
||||
startItem = aEndItem;
|
||||
|
||||
// First clear our selection out completely.
|
||||
ClearItemSelectionInternal();
|
||||
|
||||
// Get a range so we can create an iterator
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
nsresult result;
|
||||
result = nsComponentManager::CreateInstance(kCRangeCID, nsnull,
|
||||
nsIDOMRange::GetIID(), getter_AddRefs(range));
|
||||
|
||||
PRInt32 startIndex = 0;
|
||||
PRInt32 endIndex = 0;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> startParentNode;
|
||||
nsCOMPtr<nsIDOMNode> endParentNode;
|
||||
|
||||
startItem->GetParentNode(getter_AddRefs(startParentNode));
|
||||
aEndItem->GetParentNode(getter_AddRefs(endParentNode));
|
||||
|
||||
nsCOMPtr<nsIContent> startParent = do_QueryInterface(startParentNode);
|
||||
nsCOMPtr<nsIContent> endParent = do_QueryInterface(endParentNode);
|
||||
|
||||
nsCOMPtr<nsIContent> startItemContent = do_QueryInterface(startItem);
|
||||
nsCOMPtr<nsIContent> endItemContent = do_QueryInterface(aEndItem);
|
||||
startParent->IndexOf(startItemContent, startIndex);
|
||||
endParent->IndexOf(endItemContent, endIndex);
|
||||
|
||||
result = range->SetStart(startParentNode, startIndex);
|
||||
result = range->SetEnd(endParentNode, endIndex+1);
|
||||
if (NS_FAILED(result) ||
|
||||
((startParentNode.get() == endParentNode.get()) && (startIndex == endIndex+1)))
|
||||
{
|
||||
// Ranges need to be increasing, try reversing directions
|
||||
result = range->SetStart(endParentNode, endIndex);
|
||||
result = range->SetEnd(startParentNode, startIndex+1);
|
||||
if (NS_FAILED(result))
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Create the iterator
|
||||
nsCOMPtr<nsIContentIterator> iter;
|
||||
result = nsComponentManager::CreateInstance(kCContentIteratorCID, nsnull,
|
||||
nsIContentIterator::GetIID(),
|
||||
getter_AddRefs(iter));
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
|
||||
// Iterate and select
|
||||
nsAutoString trueString("true", 4);
|
||||
nsCOMPtr<nsIContent> content;
|
||||
nsCOMPtr<nsIAtom> tag;
|
||||
|
||||
iter->Init(range);
|
||||
result = iter->First();
|
||||
while (NS_SUCCEEDED(result) && NS_ENUMERATOR_FALSE == iter->IsDone())
|
||||
{
|
||||
result = iter->CurrentNode(getter_AddRefs(content));
|
||||
if (NS_FAILED(result) || !content)
|
||||
return result; // result;
|
||||
|
||||
// If tag==item, Do selection stuff
|
||||
content->GetTag(*getter_AddRefs(tag));
|
||||
if (tag && tag == kTreeItemAtom)
|
||||
{
|
||||
// Only select if we aren't already selected.
|
||||
content->SetAttribute(kNameSpaceID_None, kSelectedAtom,
|
||||
trueString, /*aNotify*/ PR_TRUE);
|
||||
}
|
||||
|
||||
result = iter->Next();
|
||||
// XXX Deal with closed nodes here
|
||||
// XXX Also had strangeness where parent of selected subrange was selected even
|
||||
// though it wasn't in the range.
|
||||
}
|
||||
|
||||
SetCurrentItem(aEndItem);
|
||||
FireOnSelectHandler();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -335,8 +447,28 @@ nsXULTreeElement::SelectCellRange(nsIDOMXULElement* aStartItem, nsIDOMXULElement
|
|||
NS_IMETHODIMP
|
||||
nsXULTreeElement::SelectAll()
|
||||
{
|
||||
// XXX Select anything that isn't selected.
|
||||
// Write later.
|
||||
nsIDOMXULElement* oldItem = mCurrentItem;
|
||||
|
||||
PRInt32 childCount;
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(mOuter);
|
||||
content->ChildCount(childCount);
|
||||
if (childCount == 0)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIContent> startContent;
|
||||
content->ChildAt(0, *getter_AddRefs(startContent));
|
||||
nsCOMPtr<nsIContent> endContent;
|
||||
content->ChildAt(childCount-1, *getter_AddRefs(endContent));
|
||||
|
||||
nsCOMPtr<nsIDOMXULElement> startElement = do_QueryInterface(startContent);
|
||||
nsCOMPtr<nsIDOMXULElement> endElement = do_QueryInterface(endContent);
|
||||
|
||||
// Select the whole range.
|
||||
SelectItemRange(startElement, endElement);
|
||||
|
||||
// We shouldn't move the active item.
|
||||
mCurrentItem = oldItem;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -607,3 +739,36 @@ nsXULTreeElement::IndexOfContent(nsIContent* aRoot,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeElement::GetCurrentItem(nsIDOMXULElement** aResult)
|
||||
{
|
||||
*aResult = mCurrentItem;
|
||||
NS_IF_ADDREF(mCurrentItem);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeElement::GetCurrentCell(nsIDOMXULElement** aResult)
|
||||
{
|
||||
*aResult = mCurrentCell;
|
||||
NS_IF_ADDREF(mCurrentCell);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsXULTreeElement::SetCurrentItem(nsIDOMXULElement* aCurrentItem)
|
||||
{
|
||||
mCurrentItem = aCurrentItem;
|
||||
nsCOMPtr<nsIContent> current = do_QueryInterface(mCurrentItem);
|
||||
current->SetAttribute(kNameSpaceID_None, kCurrentAtom, "true", PR_TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
nsXULTreeElement::SetCurrentCell(nsIDOMXULElement* aCurrentCell)
|
||||
{
|
||||
mCurrentCell = aCurrentCell;
|
||||
nsCOMPtr<nsIContent> current = do_QueryInterface(mCurrentCell);
|
||||
current->SetAttribute(kNameSpaceID_None, kCurrentAtom, "true", PR_TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@ public:
|
|||
static nsIAtom* kTreeRowAtom;
|
||||
static nsIAtom* kTreeItemAtom;
|
||||
static nsIAtom* kTreeChildrenAtom;
|
||||
static nsIAtom* kCurrentAtom;
|
||||
|
||||
static int gRefCnt;
|
||||
|
||||
protected:
|
||||
|
@ -75,6 +77,9 @@ protected:
|
|||
void AddCellToSelectionInternal(nsIDOMXULElement* aTreeCell);
|
||||
void RemoveCellFromSelectionInternal(nsIDOMXULElement* aTreeCell);
|
||||
|
||||
void SetCurrentItem(nsIDOMXULElement* aElement);
|
||||
void SetCurrentCell(nsIDOMXULElement* aCell);
|
||||
|
||||
static nsresult IndexOfContent(nsIContent *aRoot, nsIContent *aContent,
|
||||
PRBool aDescendIntoRows,
|
||||
PRBool aParentIsOpen,
|
||||
|
@ -82,6 +87,8 @@ protected:
|
|||
protected:
|
||||
nsRDFDOMNodeList* mSelectedItems;
|
||||
nsRDFDOMNodeList* mSelectedCells;
|
||||
nsIDOMXULElement* mCurrentItem;
|
||||
nsIDOMXULElement* mCurrentCell;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -234,7 +234,7 @@ Contributor(s): ______________________________________. -->
|
|||
<!-- Recursive rules for nested folders -->
|
||||
<rule iscontainer="true">
|
||||
<menupopup>
|
||||
<menu class="standard" uri="rdf:*" crop="right" flex="1" align="left"
|
||||
<menu class="standard" uri="rdf:*"
|
||||
value="rdf:http://home.netscape.com/NC-rdf#Name" >
|
||||
<menupopup class="standard"/>
|
||||
</menu>
|
||||
|
@ -247,7 +247,7 @@ Contributor(s): ______________________________________. -->
|
|||
</rule>
|
||||
<rule>
|
||||
<menupopup>
|
||||
<menuitem class="standard" align="left" uri="rdf:*"
|
||||
<menuitem class="standard" uri="rdf:*"
|
||||
value="rdf:http://home.netscape.com/NC-rdf#Name"
|
||||
oncommand="OpenBookmarkURL(event.target, document.getElementById('PersonalMenu').database)"/>
|
||||
</menupopup>
|
||||
|
@ -289,7 +289,7 @@ Contributor(s): ______________________________________. -->
|
|||
<!-- Recursive rules for nested folders -->
|
||||
<rule iscontainer="true">
|
||||
<menupopup class="standard">
|
||||
<menu class="standard" uri="rdf:*" crop="right" flex="1" align="left"
|
||||
<menu class="standard" uri="rdf:*"
|
||||
value="rdf:http://home.netscape.com/NC-rdf#Name" >
|
||||
<menupopup class="standard"/>
|
||||
</menu>
|
||||
|
@ -302,7 +302,7 @@ Contributor(s): ______________________________________. -->
|
|||
</rule>
|
||||
<rule>
|
||||
<menupopup>
|
||||
<menuitem class="standard" align="left" uri="..."
|
||||
<menuitem class="standard" uri="..."
|
||||
value="rdf:http://home.netscape.com/NC-rdf#Name"
|
||||
oncommand="OpenBookmarkURL(event.target, document.getElementById('innermostBox').database)"/>
|
||||
</menupopup>
|
||||
|
|
|
@ -101,18 +101,19 @@ menubar[hidden="true"] {
|
|||
display:none;
|
||||
}
|
||||
|
||||
menu {
|
||||
menubar > menu {
|
||||
behavior: url("resource:/chrome/xulBindings.xml#menusOnMenuBar");
|
||||
}
|
||||
|
||||
menu,menuitem {
|
||||
display: block;
|
||||
behavior: url("resource:/chrome/xulBindings.xml#menus");
|
||||
}
|
||||
|
||||
menu[hidden="true"] {
|
||||
display:none;
|
||||
}
|
||||
|
||||
menuitem {
|
||||
display: block;
|
||||
}
|
||||
|
||||
menuitem[hidden="true"] {
|
||||
display:none;
|
||||
}
|
||||
|
|
|
@ -7,9 +7,27 @@
|
|||
<binding name="scrollbar">
|
||||
<content>
|
||||
<xul:scrollbarbutton type="decrement"/>
|
||||
<xul:slider flex="1"/>
|
||||
<xul:slider flex="1" inherits="curpos,maxpos,pageincrement,increment"/>
|
||||
<xul:scrollbarbutton type="increment"/>
|
||||
</content>
|
||||
</binding>
|
||||
|
||||
<binding name="menusOnMenuBar">
|
||||
<content excludes="template,observes,menupopup">
|
||||
<xul:titledbutton class="menubar-left"/>
|
||||
<xul:titledbutton class="menubar-text" inherits="value,accesskey,crop" crop="right"/>
|
||||
</content>
|
||||
</binding>
|
||||
|
||||
<binding name="menus">
|
||||
<content excludes="template,observes,menupopup">
|
||||
<xul:titledbutton class="menu-left"/>
|
||||
<xul:titledbutton class="menu-text" inherits="value,accesskey,crop" crop="right"/>
|
||||
<xul:spring class="menu-spring" flex="1"/>
|
||||
<xul:titledbutton class="menu-accel" inherits="acceltext:value"/>
|
||||
<xul:titledbutton class="menu-right"/>
|
||||
</content>
|
||||
</binding>
|
||||
|
||||
|
||||
</bindings>
|
||||
|
|
Загрузка…
Ссылка в новой задаче