Fixes for bugs: 18193, 13971, 23440, 18444, 21462, 21818, 22619, 23498, 24081, and 21972. r=just about everybody.

This commit is contained in:
hyatt%netscape.com 2000-01-25 06:35:27 +00:00
Родитель 60e2eca42b
Коммит 0dfb94bf0a
51 изменённых файлов: 1486 добавлений и 494 удалений

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

@ -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>