A followup for bug 617528 - implement the HTML5 "context menu" feature (contextmenu attribute). Merged "generated" and "ident" XUL attribute into "generateditemid" and renamed PageMenu.init() to PageMenu.maybeBuildAndAttachMenu(). r=enn

This commit is contained in:
Jan Varga 2011-08-18 18:37:26 +02:00
parent d554403253
commit bd7b514f07
6 changed files with 50 additions and 53 deletions

View File

@ -79,7 +79,8 @@ nsContextMenu.prototype = {
this.hasPageMenu = false;
if (!aIsShift) {
this.hasPageMenu = PageMenu.init(this.target, aXulMenu);
this.hasPageMenu = PageMenu.maybeBuildAndAttachMenu(this.target,
aXulMenu);
}
this.isFrameImage = document.getElementById("isFrameImage");

View File

@ -49,9 +49,10 @@ function executeCopyCommand(command, expectedValue)
is(input.value, expectedValue, "paste for command " + command);
}
function invokeItemAction(ident)
function invokeItemAction(generatedItemId)
{
var item = contextMenu.getElementsByAttribute("ident", ident)[0];
var item = contextMenu.getElementsByAttribute("generateditemid",
generatedItemId)[0];
ok(item, "Got generated XUL menu item");
item.doCommand();
is(pagemenu.hasAttribute("hopeless"), false, "attribute got removed");
@ -69,7 +70,7 @@ function getVisibleMenuItems(aMenu, aData) {
if (key)
key = key.toLowerCase();
var isGenerated = item.hasAttribute("generated");
var isGenerated = item.hasAttribute("generateditemid");
if (item.nodeName == "menuitem") {
var isSpellSuggestion = item.className == "spell-suggestion";

View File

@ -43,7 +43,7 @@ interface nsIDOMDocumentFragment;
* and for triggering of menuitem actions with assigned identifiers.
*/
[scriptable, uuid(f0c35053-14cc-4e23-a9db-f9a68fae8375)]
[scriptable, uuid(eb6b42c0-2f1c-4760-b5ca-bdc9b3ec77d4)]
interface nsIXULContextMenuBuilder : nsISupports
{
@ -53,21 +53,17 @@ interface nsIXULContextMenuBuilder : nsISupports
* @param aDocumentFragment the fragment that will be used to append top
* level elements
*
* @param aGeneratedAttrName the name of the attribute that will be used
* to mark elements as generated.
*
* @param aIdentAttrName the name of the attribute that will be used for
* menuitem identification.
* @param aGeneratedItemIdAttrName the name of the attribute that will be
* used to mark elements as generated and for menuitem identification
*/
void init(in nsIDOMDocumentFragment aDocumentFragment,
in AString aGeneratedAttrName,
in AString aIdentAttrName);
in AString aGeneratedItemIdAttrName);
/**
* Invoke the action of the menuitem with assigned identifier aIdent.
* Invoke the action of the menuitem with assigned id aGeneratedItemId.
*
* @param aIdent the menuitem identifier
* @param aGeneratedItemId the menuitem id
*/
void click(in DOMString aIdent);
void click(in DOMString aGeneratedItemId);
};

View File

@ -41,7 +41,7 @@
nsXULContextMenuBuilder::nsXULContextMenuBuilder()
: mCurrentIdent(0)
: mCurrentGeneratedItemId(0)
{
}
@ -85,13 +85,14 @@ nsXULContextMenuBuilder::OpenContainer(const nsAString& aLabel)
mCurrentNode = mFragment;
} else {
nsCOMPtr<nsIContent> menu;
nsresult rv = CreateElement(nsGkAtoms::menu, getter_AddRefs(menu));
nsresult rv = CreateElement(nsGkAtoms::menu, nsnull, getter_AddRefs(menu));
NS_ENSURE_SUCCESS(rv, rv);
menu->SetAttr(kNameSpaceID_None, nsGkAtoms::label, aLabel, PR_FALSE);
nsCOMPtr<nsIContent> menuPopup;
rv = CreateElement(nsGkAtoms::menupopup, getter_AddRefs(menuPopup));
rv = CreateElement(nsGkAtoms::menupopup, nsnull,
getter_AddRefs(menuPopup));
NS_ENSURE_SUCCESS(rv, rv);
rv = menu->AppendChildTo(menuPopup, PR_FALSE);
@ -115,7 +116,8 @@ nsXULContextMenuBuilder::AddItemFor(nsIDOMHTMLMenuItemElement* aElement,
}
nsCOMPtr<nsIContent> menuitem;
nsresult rv = CreateElement(nsGkAtoms::menuitem, getter_AddRefs(menuitem));
nsresult rv = CreateElement(nsGkAtoms::menuitem, aElement,
getter_AddRefs(menuitem));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString type;
@ -154,17 +156,7 @@ nsXULContextMenuBuilder::AddItemFor(nsIDOMHTMLMenuItemElement* aElement,
NS_LITERAL_STRING("true"), PR_FALSE);
}
nsAutoString ident;
ident.AppendInt(mCurrentIdent++);
menuitem->SetAttr(kNameSpaceID_None, mIdentAttr, ident, PR_FALSE);
rv = mCurrentNode->AppendChildTo(menuitem, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
mElements.AppendObject(aElement);
return NS_OK;
return mCurrentNode->AppendChildTo(menuitem, PR_FALSE);
}
NS_IMETHODIMP
@ -175,7 +167,7 @@ nsXULContextMenuBuilder::AddSeparator()
}
nsCOMPtr<nsIContent> menuseparator;
nsresult rv = CreateElement(nsGkAtoms::menuseparator,
nsresult rv = CreateElement(nsGkAtoms::menuseparator, nsnull,
getter_AddRefs(menuseparator));
NS_ENSURE_SUCCESS(rv, rv);
@ -218,24 +210,22 @@ nsXULContextMenuBuilder::CloseContainer()
NS_IMETHODIMP
nsXULContextMenuBuilder::Init(nsIDOMDocumentFragment* aDocumentFragment,
const nsAString& aGeneratedAttrName,
const nsAString& aIdentAttrName)
const nsAString& aGeneratedItemIdAttrName)
{
NS_ENSURE_ARG_POINTER(aDocumentFragment);
mFragment = do_QueryInterface(aDocumentFragment);
mDocument = mFragment->GetOwnerDocument();
mGeneratedAttr = do_GetAtom(aGeneratedAttrName);
mIdentAttr = do_GetAtom(aIdentAttrName);
mGeneratedItemIdAttr = do_GetAtom(aGeneratedItemIdAttrName);
return NS_OK;
}
NS_IMETHODIMP
nsXULContextMenuBuilder::Click(const nsAString& aIdent)
nsXULContextMenuBuilder::Click(const nsAString& aGeneratedItemId)
{
PRInt32 rv;
PRInt32 idx = nsString(aIdent).ToInteger(&rv);
PRInt32 idx = nsString(aGeneratedItemId).ToInteger(&rv);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIDOMHTMLElement> element = mElements.SafeObjectAt(idx);
if (element) {
@ -247,7 +237,9 @@ nsXULContextMenuBuilder::Click(const nsAString& aIdent)
}
nsresult
nsXULContextMenuBuilder::CreateElement(nsIAtom* aTag, nsIContent** aResult)
nsXULContextMenuBuilder::CreateElement(nsIAtom* aTag,
nsIDOMHTMLElement* aHTMLElement,
nsIContent** aResult)
{
*aResult = nsnull;
@ -261,7 +253,14 @@ nsXULContextMenuBuilder::CreateElement(nsIAtom* aTag, nsIContent** aResult)
return rv;
}
(*aResult)->SetAttr(kNameSpaceID_None, mGeneratedAttr, EmptyString(),
nsAutoString generateditemid;
if (aHTMLElement) {
mElements.AppendObject(aHTMLElement);
generateditemid.AppendInt(mCurrentGeneratedItemId++);
}
(*aResult)->SetAttr(kNameSpaceID_None, mGeneratedItemIdAttr, generateditemid,
PR_FALSE);
return NS_OK;

View File

@ -57,15 +57,16 @@ public:
NS_DECL_NSIXULCONTEXTMENUBUILDER
protected:
nsresult CreateElement(nsIAtom* aTag, nsIContent** aResult);
nsresult CreateElement(nsIAtom* aTag,
nsIDOMHTMLElement* aHTMLElement,
nsIContent** aResult);
nsCOMPtr<nsIContent> mFragment;
nsCOMPtr<nsIDocument> mDocument;
nsCOMPtr<nsIAtom> mGeneratedAttr;
nsCOMPtr<nsIAtom> mIdentAttr;
nsCOMPtr<nsIAtom> mGeneratedItemIdAttr;
nsCOMPtr<nsIContent> mCurrentNode;
PRInt32 mCurrentIdent;
PRInt32 mCurrentGeneratedItemId;
nsCOMArray<nsIDOMHTMLElement> mElements;
};

View File

@ -40,13 +40,12 @@ function PageMenu() {
PageMenu.prototype = {
PAGEMENU_ATTR: "pagemenu",
GENERATED_ATTR: "generated",
IDENT_ATTR: "ident",
GENERATEDITEMID_ATTR: "generateditemid",
popup: null,
builder: null,
init: function(aTarget, aPopup) {
maybeBuildAndAttachMenu: function(aTarget, aPopup) {
var pageMenu = null;
var target = aTarget;
while (target) {
@ -78,16 +77,16 @@ PageMenu.prototype = {
return false;
}
builder.QueryInterface(Components.interfaces.nsIXULContextMenuBuilder);
builder.init(fragment, this.GENERATED_ATTR, this.IDENT_ATTR);
builder.init(fragment, this.GENERATEDITEMID_ATTR);
pageMenu.build(builder);
var pos = insertionPoint.getAttribute(this.PAGEMENU_ATTR);
if (pos == "end") {
insertionPoint.appendChild(fragment);
} else {
if (pos == "start") {
insertionPoint.insertBefore(fragment,
insertionPoint.firstChild);
} else {
insertionPoint.appendChild(fragment);
}
this.builder = builder;
@ -102,8 +101,8 @@ PageMenu.prototype = {
handleEvent: function(event) {
var type = event.type;
var target = event.target;
if (type == "command" && target.hasAttribute(this.GENERATED_ATTR)) {
this.builder.click(target.getAttribute(this.IDENT_ATTR));
if (type == "command" && target.hasAttribute(this.GENERATEDITEMID_ATTR)) {
this.builder.click(target.getAttribute(this.GENERATEDITEMID_ATTR));
} else if (type == "popuphidden" && this.popup == target) {
this.removeGeneratedContent(this.popup);
@ -160,7 +159,7 @@ PageMenu.prototype = {
var i = element.childNodes.length;
while (i-- > 0) {
var child = element.childNodes[i];
if (!child.hasAttribute(this.GENERATED_ATTR)) {
if (!child.hasAttribute(this.GENERATEDITEMID_ATTR)) {
ungenerated.push(child);
continue;
}