// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "config.h"
#include "core/page/CustomContextMenuProvider.h"

#include "core/dom/Document.h"
#include "core/dom/ElementTraversal.h"
#include "core/events/EventDispatcher.h"
#include "core/events/MouseEvent.h"
#include "core/html/HTMLMenuElement.h"
#include "core/html/HTMLMenuItemElement.h"
#include "core/page/ContextMenuController.h"
#include "core/page/Page.h"
#include "platform/ContextMenu.h"

namespace blink {

using namespace HTMLNames;

CustomContextMenuProvider::CustomContextMenuProvider(HTMLMenuElement& menu, HTMLElement& subject)
    : m_menu(menu)
    , m_subjectElement(subject)
{
}

CustomContextMenuProvider::~CustomContextMenuProvider()
{
}

DEFINE_TRACE(CustomContextMenuProvider)
{
    visitor->trace(m_menu);
    visitor->trace(m_subjectElement);
    visitor->trace(m_menuItems);
    ContextMenuProvider::trace(visitor);
}

void CustomContextMenuProvider::populateContextMenu(ContextMenu* menu)
{
    populateContextMenuItems(*m_menu, *menu);
}

void CustomContextMenuProvider::contextMenuItemSelected(const ContextMenuItem* item)
{
    if (HTMLElement* element = menuItemAt(item->action())) {
        RefPtrWillBeRawPtr<MouseEvent> click = MouseEvent::create(EventTypeNames::click, m_menu->document().domWindow(), Event::create(), SimulatedClickCreationScope::FromUserAgent);
        click->setRelatedTarget(m_subjectElement.get());
        element->dispatchEvent(click.release());
    }
}

void CustomContextMenuProvider::contextMenuCleared()
{
    m_menuItems.clear();
    m_subjectElement = nullptr;
}

void CustomContextMenuProvider::appendSeparator(ContextMenu& contextMenu)
{
    // Avoid separators at the start of any menu and submenu.
    if (!contextMenu.items().size())
        return;

    // Collapse all sequences of two or more adjacent separators in the menu or
    // any submenus to a single separator.
    ContextMenuItem lastItem = contextMenu.items().last();
    if (lastItem.type() == SeparatorType)
        return;

    contextMenu.appendItem(ContextMenuItem(SeparatorType, ContextMenuItemCustomTagNoAction, String(), String()));
}

void CustomContextMenuProvider::appendMenuItem(HTMLMenuItemElement* menuItem, ContextMenu& contextMenu)
{
    // Avoid menuitems with no label.
    String labelString = menuItem->fastGetAttribute(labelAttr);
    if (labelString.isEmpty())
        return;

    m_menuItems.append(menuItem);

    bool enabled = !menuItem->fastHasAttribute(disabledAttr);
    String icon = menuItem->fastGetAttribute(iconAttr);
    if (!icon.isEmpty()) {
        // To obtain the absolute URL of the icon when the attribute's value is not the empty string,
        // the attribute's value must be resolved relative to the element.
        KURL iconURL = KURL(menuItem->baseURI(), icon);
        icon = iconURL.string();
    }
    ContextMenuAction action = static_cast<ContextMenuAction>(ContextMenuItemBaseCustomTag + m_menuItems.size() - 1);
    if (equalIgnoringCase(menuItem->fastGetAttribute(typeAttr), "checkbox") || equalIgnoringCase(menuItem->fastGetAttribute(typeAttr), "radio"))
        contextMenu.appendItem(ContextMenuItem(CheckableActionType, action, labelString, icon, enabled, menuItem->fastHasAttribute(checkedAttr)));
    else
        contextMenu.appendItem(ContextMenuItem(ActionType, action, labelString, icon, enabled, false));
}

void CustomContextMenuProvider::populateContextMenuItems(const HTMLMenuElement& menu, ContextMenu& contextMenu)
{
    HTMLElement* nextElement = Traversal<HTMLElement>::firstWithin(menu);
    while (nextElement) {
        if (isHTMLHRElement(*nextElement)) {
            appendSeparator(contextMenu);
            nextElement = Traversal<HTMLElement>::next(*nextElement, &menu);
        } else if (isHTMLMenuElement(*nextElement)) {
            ContextMenu subMenu;
            String labelString = nextElement->fastGetAttribute(labelAttr);
            if (labelString.isNull()) {
                appendSeparator(contextMenu);
                populateContextMenuItems(*toHTMLMenuElement(nextElement), contextMenu);
                appendSeparator(contextMenu);
            } else if (!labelString.isEmpty()) {
                populateContextMenuItems(*toHTMLMenuElement(nextElement), subMenu);
                contextMenu.appendItem(ContextMenuItem(SubmenuType, ContextMenuItemCustomTagNoAction, labelString, String(), &subMenu));
            }
            nextElement = Traversal<HTMLElement>::nextSibling(*nextElement);
        } else if (isHTMLMenuItemElement(*nextElement)) {
            appendMenuItem(toHTMLMenuItemElement(nextElement), contextMenu);
            if (ContextMenuItemBaseCustomTag + m_menuItems.size() >= ContextMenuItemLastCustomTag)
                break;
            nextElement = Traversal<HTMLElement>::next(*nextElement, &menu);
        } else {
            nextElement = Traversal<HTMLElement>::next(*nextElement, &menu);
        }
    }

    // Remove separators at the end of the menu and any submenus.
    while (contextMenu.items().size() && contextMenu.items().last().type() == SeparatorType)
        contextMenu.removeLastItem();
}

HTMLElement* CustomContextMenuProvider::menuItemAt(unsigned menuId)
{
    int itemIndex = menuId - ContextMenuItemBaseCustomTag;
    if (itemIndex < 0 || static_cast<unsigned long>(itemIndex) >= m_menuItems.size())
        return nullptr;
    return m_menuItems[itemIndex].get();
}

} // namespace blink
