static bool populateContextMenuItems(v8::Isolate* isolate, const v8::Local<v8::Array>& itemArray, ContextMenu& menu) { v8::Local<v8::Context> context = isolate->GetCurrentContext(); for (size_t i = 0; i < itemArray->Length(); ++i) { v8::Local<v8::Object> item = itemArray->Get(context, i).ToLocalChecked().As<v8::Object>(); v8::Local<v8::Value> type; v8::Local<v8::Value> id; v8::Local<v8::Value> label; v8::Local<v8::Value> enabled; v8::Local<v8::Value> checked; v8::Local<v8::Value> subItems; if (!item->Get(context, v8AtomicString(isolate, "type")).ToLocal(&type) || !item->Get(context, v8AtomicString(isolate, "id")).ToLocal(&id) || !item->Get(context, v8AtomicString(isolate, "label")).ToLocal(&label) || !item->Get(context, v8AtomicString(isolate, "enabled")) .ToLocal(&enabled) || !item->Get(context, v8AtomicString(isolate, "checked")) .ToLocal(&checked) || !item->Get(context, v8AtomicString(isolate, "subItems")) .ToLocal(&subItems)) return false; if (!type->IsString()) continue; String typeString = toCoreStringWithNullCheck(type.As<v8::String>()); if (typeString == "separator") { ContextMenuItem item(ContextMenuItem( SeparatorType, ContextMenuItemCustomTagNoAction, String(), String())); menu.appendItem(item); } else if (typeString == "subMenu" && subItems->IsArray()) { ContextMenu subMenu; v8::Local<v8::Array> subItemsArray = v8::Local<v8::Array>::Cast(subItems); if (!populateContextMenuItems(isolate, subItemsArray, subMenu)) return false; TOSTRING_DEFAULT(V8StringResource<TreatNullAsNullString>, labelString, label, false); ContextMenuItem item(SubmenuType, ContextMenuItemCustomTagNoAction, labelString, String(), &subMenu); menu.appendItem(item); } else { int32_t int32Id; if (!v8Call(id->Int32Value(context), int32Id)) return false; ContextMenuAction typedId = static_cast<ContextMenuAction>( ContextMenuItemBaseCustomTag + int32Id); TOSTRING_DEFAULT(V8StringResource<TreatNullAsNullString>, labelString, label, false); ContextMenuItem menuItem( (typeString == "checkbox" ? CheckableActionType : ActionType), typedId, labelString, String()); if (checked->IsBoolean()) menuItem.setChecked(checked.As<v8::Boolean>()->Value()); if (enabled->IsBoolean()) menuItem.setEnabled(enabled.As<v8::Boolean>()->Value()); menu.appendItem(menuItem); } } return true; }
static void populateContextMenuItems(ExecState* exec, JSArray* array, ContextMenu& menu) { for (size_t i = 0; i < array->length(); ++i) { JSObject* item = asObject(array->getIndex(exec, i)); JSValue label = item->get(exec, Identifier::fromString(exec, "label")); JSValue type = item->get(exec, Identifier::fromString(exec, "type")); JSValue id = item->get(exec, Identifier::fromString(exec, "id")); JSValue enabled = item->get(exec, Identifier::fromString(exec, "enabled")); JSValue checked = item->get(exec, Identifier::fromString(exec, "checked")); JSValue subItems = item->get(exec, Identifier::fromString(exec, "subItems")); if (!type.isString()) continue; String typeString = type.toWTFString(exec); if (typeString == "separator") { ContextMenuItem item(SeparatorType, ContextMenuItemTagNoAction, String()); menu.appendItem(item); } else if (typeString == "subMenu" && subItems.inherits(JSArray::info())) { ContextMenu subMenu; JSArray* subItemsArray = asArray(subItems); populateContextMenuItems(exec, subItemsArray, subMenu); ContextMenuItem item(SubmenuType, ContextMenuItemTagNoAction, label.toWTFString(exec), &subMenu); menu.appendItem(item); } else { ContextMenuAction typedId = static_cast<ContextMenuAction>(ContextMenuItemBaseCustomTag + id.toInt32(exec)); ContextMenuItem menuItem((typeString == "checkbox" ? CheckableActionType : ActionType), typedId, label.toWTFString(exec)); if (!enabled.isUndefined()) menuItem.setEnabled(enabled.toBoolean(exec)); if (!checked.isUndefined()) menuItem.setChecked(checked.toBoolean(exec)); menu.appendItem(menuItem); } } }
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.getString(); } 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(); }
static bool populateContextMenuItems(v8::Local<v8::Array>& itemArray, ContextMenu& menu, v8::Isolate* isolate) { for (size_t i = 0; i < itemArray->Length(); ++i) { v8::Local<v8::Object> item = v8::Local<v8::Object>::Cast(itemArray->Get(i)); v8::Local<v8::Value> type = item->Get(v8AtomicString(isolate, "type")); v8::Local<v8::Value> id = item->Get(v8AtomicString(isolate, "id")); v8::Local<v8::Value> label = item->Get(v8AtomicString(isolate, "label")); v8::Local<v8::Value> enabled = item->Get(v8AtomicString(isolate, "enabled")); v8::Local<v8::Value> checked = item->Get(v8AtomicString(isolate, "checked")); v8::Local<v8::Value> subItems = item->Get(v8AtomicString(isolate, "subItems")); if (!type->IsString()) continue; String typeString = toCoreStringWithNullCheck(type.As<v8::String>()); if (typeString == "separator") { ContextMenuItem item(ContextMenuItem(SeparatorType, ContextMenuItemCustomTagNoAction, String())); menu.appendItem(item); } else if (typeString == "subMenu" && subItems->IsArray()) { ContextMenu subMenu; v8::Local<v8::Array> subItemsArray = v8::Local<v8::Array>::Cast(subItems); if (!populateContextMenuItems(subItemsArray, subMenu, isolate)) return false; V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<WithNullCheck>, labelString, label, false); ContextMenuItem item(SubmenuType, ContextMenuItemCustomTagNoAction, labelString, &subMenu); menu.appendItem(item); } else { ContextMenuAction typedId = static_cast<ContextMenuAction>(ContextMenuItemBaseCustomTag + id->ToInt32()->Value()); V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<WithNullCheck>, labelString, label, false); ContextMenuItem menuItem((typeString == "checkbox" ? CheckableActionType : ActionType), typedId, labelString); if (checked->IsBoolean()) menuItem.setChecked(checked->ToBoolean()->Value()); if (enabled->IsBoolean()) menuItem.setEnabled(enabled->ToBoolean()->Value()); menu.appendItem(menuItem); } } return true; }
static void populateContextMenuItems(v8::Local<v8::Array>& itemArray, ContextMenu& menu) { for (size_t i = 0; i < itemArray->Length(); ++i) { v8::Local<v8::Object> item = v8::Local<v8::Object>::Cast(itemArray->Get(i)); v8::Local<v8::Value> type = item->Get(v8::String::New("type")); v8::Local<v8::Value> id = item->Get(v8::String::New("id")); v8::Local<v8::Value> label = item->Get(v8::String::New("label")); v8::Local<v8::Value> enabled = item->Get(v8::String::New("enabled")); v8::Local<v8::Value> checked = item->Get(v8::String::New("checked")); v8::Local<v8::Value> subItems = item->Get(v8::String::New("subItems")); if (!type->IsString()) continue; String typeString = toWebCoreStringWithNullCheck(type); if (typeString == "separator") { ContextMenuItem item(ContextMenuItem(SeparatorType, ContextMenuItemCustomTagNoAction, String())); menu.appendItem(item); } else if (typeString == "subMenu" && subItems->IsArray()) { ContextMenu subMenu; v8::Local<v8::Array> subItemsArray = v8::Local<v8::Array>::Cast(subItems); populateContextMenuItems(subItemsArray, subMenu); ContextMenuItem item(SubmenuType, ContextMenuItemCustomTagNoAction, toWebCoreStringWithNullCheck(label), &subMenu); menu.appendItem(item); } else { ContextMenuAction typedId = static_cast<ContextMenuAction>(ContextMenuItemBaseCustomTag + id->ToInt32()->Value()); ContextMenuItem menuItem((typeString == "checkbox" ? CheckableActionType : ActionType), typedId, toWebCoreStringWithNullCheck(label)); if (checked->IsBoolean()) menuItem.setChecked(checked->ToBoolean()->Value()); if (enabled->IsBoolean()) menuItem.setEnabled(enabled->ToBoolean()->Value()); menu.appendItem(menuItem); } } }
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())); }