| OLD | NEW |
| 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 | 6 |
| 7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 | 8 |
| 9 MSVC_PUSH_WARNING_LEVEL(0); | 9 MSVC_PUSH_WARNING_LEVEL(0); |
| 10 #include "ContextMenu.h" | 10 #include "ContextMenu.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 } // namespace | 117 } // namespace |
| 118 | 118 |
| 119 ContextMenuClientImpl::~ContextMenuClientImpl() { | 119 ContextMenuClientImpl::~ContextMenuClientImpl() { |
| 120 } | 120 } |
| 121 | 121 |
| 122 void ContextMenuClientImpl::contextMenuDestroyed() { | 122 void ContextMenuClientImpl::contextMenuDestroyed() { |
| 123 delete this; | 123 delete this; |
| 124 } | 124 } |
| 125 | 125 |
| 126 // Figure out the URL of a page or subframe. Returns |page_type| as the type, | 126 // Figure out the URL of a page or subframe. Returns |page_type| as the type, |
| 127 // which indicates page or subframe, or ContextNode::NONE if the URL could not | 127 // which indicates page or subframe, or ContextNodeType::NONE if the URL could n
ot |
| 128 // be determined for some reason. | 128 // be determined for some reason. |
| 129 static ContextNode GetTypeAndURLFromFrame(WebCore::Frame* frame, | 129 static ContextNodeType GetTypeAndURLFromFrame( |
| 130 GURL* url, | 130 WebCore::Frame* frame, |
| 131 ContextNode page_node) { | 131 GURL* url, |
| 132 ContextNode node; | 132 ContextNodeType page_node_type) { |
| 133 ContextNodeType node_type; |
| 133 if (frame) { | 134 if (frame) { |
| 134 WebCore::DocumentLoader* dl = frame->loader()->documentLoader(); | 135 WebCore::DocumentLoader* dl = frame->loader()->documentLoader(); |
| 135 if (dl) { | 136 if (dl) { |
| 136 WebDataSource* ds = WebDataSourceImpl::FromLoader(dl); | 137 WebDataSource* ds = WebDataSourceImpl::FromLoader(dl); |
| 137 if (ds) { | 138 if (ds) { |
| 138 node = page_node; | 139 node_type = page_node_type; |
| 139 *url = ds->hasUnreachableURL() ? ds->unreachableURL() | 140 *url = ds->hasUnreachableURL() ? ds->unreachableURL() |
| 140 : ds->request().url(); | 141 : ds->request().url(); |
| 141 } | 142 } |
| 142 } | 143 } |
| 143 } | 144 } |
| 144 return node; | 145 return node_type; |
| 145 } | 146 } |
| 146 | 147 |
| 147 WebCore::PlatformMenuDescription | 148 WebCore::PlatformMenuDescription |
| 148 ContextMenuClientImpl::getCustomMenuFromDefaultItems( | 149 ContextMenuClientImpl::getCustomMenuFromDefaultItems( |
| 149 WebCore::ContextMenu* default_menu) { | 150 WebCore::ContextMenu* default_menu) { |
| 150 // Displaying the context menu in this function is a big hack as we don't | 151 // Displaying the context menu in this function is a big hack as we don't |
| 151 // have context, i.e. whether this is being invoked via a script or in | 152 // have context, i.e. whether this is being invoked via a script or in |
| 152 // response to user input (Mouse event WM_RBUTTONDOWN, | 153 // response to user input (Mouse event WM_RBUTTONDOWN, |
| 153 // Keyboard events KeyVK_APPS, Shift+F10). Check if this is being invoked | 154 // Keyboard events KeyVK_APPS, Shift+F10). Check if this is being invoked |
| 154 // in response to the above input events before popping up the context menu. | 155 // in response to the above input events before popping up the context menu. |
| 155 if (!webview_->context_menu_allowed()) | 156 if (!webview_->context_menu_allowed()) |
| 156 return NULL; | 157 return NULL; |
| 157 | 158 |
| 158 WebCore::HitTestResult r = default_menu->hitTestResult(); | 159 WebCore::HitTestResult r = default_menu->hitTestResult(); |
| 159 WebCore::Frame* selected_frame = r.innerNonSharedNode()->document()->frame(); | 160 WebCore::Frame* selected_frame = r.innerNonSharedNode()->document()->frame(); |
| 160 | 161 |
| 161 WebCore::IntPoint menu_point = | 162 WebCore::IntPoint menu_point = |
| 162 selected_frame->view()->contentsToWindow(r.point()); | 163 selected_frame->view()->contentsToWindow(r.point()); |
| 163 | 164 |
| 164 ContextNode node; | 165 ContextNodeType node_type; |
| 165 | 166 |
| 166 // Links, Images, Media tags, and Image/Media-Links take preference over | 167 // Links, Images, Media tags, and Image/Media-Links take preference over |
| 167 // all else. | 168 // all else. |
| 168 WebCore::KURL link_url = r.absoluteLinkURL(); | 169 WebCore::KURL link_url = r.absoluteLinkURL(); |
| 169 if (!link_url.isEmpty()) { | 170 if (!link_url.isEmpty()) { |
| 170 node.type |= ContextNode::LINK; | 171 node_type.type |= ContextNodeType::LINK; |
| 171 } | 172 } |
| 172 | 173 |
| 173 WebCore::KURL src_url; | 174 WebCore::KURL src_url; |
| 174 | 175 |
| 175 ContextMenuMediaParams media_params; | 176 ContextMenuMediaParams media_params; |
| 176 | 177 |
| 177 if (!r.absoluteImageURL().isEmpty()) { | 178 if (!r.absoluteImageURL().isEmpty()) { |
| 178 src_url = r.absoluteImageURL(); | 179 src_url = r.absoluteImageURL(); |
| 179 node.type |= ContextNode::IMAGE; | 180 node_type.type |= ContextNodeType::IMAGE; |
| 180 } else if (!r.absoluteMediaURL().isEmpty()) { | 181 } else if (!r.absoluteMediaURL().isEmpty()) { |
| 181 src_url = r.absoluteMediaURL(); | 182 src_url = r.absoluteMediaURL(); |
| 182 | 183 |
| 183 // We know that if absoluteMediaURL() is not empty, then this is a media | 184 // We know that if absoluteMediaURL() is not empty, then this is a media |
| 184 // element. | 185 // element. |
| 185 WebCore::HTMLMediaElement* media_element = | 186 WebCore::HTMLMediaElement* media_element = |
| 186 static_cast<WebCore::HTMLMediaElement*>(r.innerNonSharedNode()); | 187 static_cast<WebCore::HTMLMediaElement*>(r.innerNonSharedNode()); |
| 187 if (media_element->hasTagName(WebCore::HTMLNames::videoTag)) { | 188 if (media_element->hasTagName(WebCore::HTMLNames::videoTag)) { |
| 188 node.type |= ContextNode::VIDEO; | 189 node_type.type |= ContextNodeType::VIDEO; |
| 189 } else if (media_element->hasTagName(WebCore::HTMLNames::audioTag)) { | 190 } else if (media_element->hasTagName(WebCore::HTMLNames::audioTag)) { |
| 190 node.type |= ContextNode::AUDIO; | 191 node_type.type |= ContextNodeType::AUDIO; |
| 191 } | 192 } |
| 192 | 193 |
| 193 media_params.playback_rate = media_element->playbackRate(); | 194 media_params.playback_rate = media_element->playbackRate(); |
| 194 | 195 |
| 195 if (media_element->paused()) { | 196 if (media_element->paused()) { |
| 196 media_params.player_state |= ContextMenuMediaParams::PLAYER_PAUSED; | 197 media_params.player_state |= ContextMenuMediaParams::PAUSED; |
| 197 } | 198 } |
| 198 if (media_element->muted()) { | 199 if (media_element->muted()) { |
| 199 media_params.player_state |= ContextMenuMediaParams::PLAYER_MUTED; | 200 media_params.player_state |= ContextMenuMediaParams::MUTED; |
| 200 } | 201 } |
| 201 if (media_element->loop()) { | 202 if (media_element->loop()) { |
| 202 media_params.player_state |= ContextMenuMediaParams::PLAYER_LOOP; | 203 media_params.player_state |= ContextMenuMediaParams::LOOP; |
| 203 } | 204 } |
| 204 if (media_element->supportsSave()) { | 205 if (media_element->supportsSave()) { |
| 205 media_params.player_state |= ContextMenuMediaParams::PLAYER_CAN_SAVE; | 206 media_params.player_state |= ContextMenuMediaParams::CAN_SAVE; |
| 206 } | 207 } |
| 208 // TODO(ajwong): Report error states in the media player. |
| 207 } | 209 } |
| 208 | 210 |
| 209 // If it's not a link, an image, a media element, or an image/media link, | 211 // If it's not a link, an image, a media element, or an image/media link, |
| 210 // show a selection menu or a more generic page menu. | 212 // show a selection menu or a more generic page menu. |
| 211 std::wstring selection_text_string; | 213 std::wstring selection_text_string; |
| 212 std::wstring misspelled_word_string; | 214 std::wstring misspelled_word_string; |
| 213 GURL frame_url; | 215 GURL frame_url; |
| 214 GURL page_url; | 216 GURL page_url; |
| 215 std::string security_info; | 217 std::string security_info; |
| 216 | 218 |
| 217 std::string frame_charset = WideToASCII( | 219 std::string frame_charset = WideToASCII( |
| 218 webkit_glue::StringToStdWString(selected_frame->loader()->encoding())); | 220 webkit_glue::StringToStdWString(selected_frame->loader()->encoding())); |
| 219 // Send the frame and page URLs in any case. | 221 // Send the frame and page URLs in any case. |
| 220 ContextNode frame_node = ContextNode(ContextNode::NONE); | 222 ContextNodeType frame_node = ContextNodeType(ContextNodeType::NONE); |
| 221 ContextNode page_node = | 223 ContextNodeType page_node = |
| 222 GetTypeAndURLFromFrame(webview_->main_frame()->frame(), | 224 GetTypeAndURLFromFrame(webview_->main_frame()->frame(), |
| 223 &page_url, | 225 &page_url, |
| 224 ContextNode(ContextNode::PAGE)); | 226 ContextNodeType(ContextNodeType::PAGE)); |
| 225 if (selected_frame != webview_->main_frame()->frame()) { | 227 if (selected_frame != webview_->main_frame()->frame()) { |
| 226 frame_node = GetTypeAndURLFromFrame(selected_frame, | 228 frame_node = |
| 227 &frame_url, | 229 GetTypeAndURLFromFrame(selected_frame, |
| 228 ContextNode(ContextNode::FRAME)); | 230 &frame_url, |
| 231 ContextNodeType(ContextNodeType::FRAME)); |
| 229 } | 232 } |
| 230 | 233 |
| 231 if (r.isSelected()) { | 234 if (r.isSelected()) { |
| 232 node.type |= ContextNode::SELECTION; | 235 node_type.type |= ContextNodeType::SELECTION; |
| 233 selection_text_string = CollapseWhitespace( | 236 selection_text_string = CollapseWhitespace( |
| 234 webkit_glue::StringToStdWString(selected_frame->selectedText()), | 237 webkit_glue::StringToStdWString(selected_frame->selectedText()), |
| 235 false); | 238 false); |
| 236 } | 239 } |
| 237 | 240 |
| 238 if (r.isContentEditable()) { | 241 if (r.isContentEditable()) { |
| 239 node.type |= ContextNode::EDITABLE; | 242 node_type.type |= ContextNodeType::EDITABLE; |
| 240 if (webview_->GetFocusedWebCoreFrame()->editor()-> | 243 if (webview_->GetFocusedWebCoreFrame()->editor()-> |
| 241 isContinuousSpellCheckingEnabled()) { | 244 isContinuousSpellCheckingEnabled()) { |
| 242 misspelled_word_string = GetMisspelledWord(default_menu, | 245 misspelled_word_string = GetMisspelledWord(default_menu, |
| 243 selected_frame); | 246 selected_frame); |
| 244 } | 247 } |
| 245 } | 248 } |
| 246 | 249 |
| 247 if (node.type == ContextNode::NONE) { | 250 if (node_type.type == ContextNodeType::NONE) { |
| 248 if (selected_frame != webview_->main_frame()->frame()) { | 251 if (selected_frame != webview_->main_frame()->frame()) { |
| 249 node = frame_node; | 252 node_type = frame_node; |
| 250 } else { | 253 } else { |
| 251 node = page_node; | 254 node_type = page_node; |
| 252 } | 255 } |
| 253 } | 256 } |
| 254 | 257 |
| 255 // Now retrieve the security info. | 258 // Now retrieve the security info. |
| 256 WebCore::DocumentLoader* dl = selected_frame->loader()->documentLoader(); | 259 WebCore::DocumentLoader* dl = selected_frame->loader()->documentLoader(); |
| 257 WebDataSource* ds = WebDataSourceImpl::FromLoader(dl); | 260 WebDataSource* ds = WebDataSourceImpl::FromLoader(dl); |
| 258 if (ds) | 261 if (ds) |
| 259 security_info = ds->response().securityInfo(); | 262 security_info = ds->response().securityInfo(); |
| 260 | 263 |
| 261 int edit_flags = ContextNode::CAN_DO_NONE; | 264 int edit_flags = ContextNodeType::CAN_DO_NONE; |
| 262 if (webview_->GetFocusedWebCoreFrame()->editor()->canUndo()) | 265 if (webview_->GetFocusedWebCoreFrame()->editor()->canUndo()) |
| 263 edit_flags |= ContextNode::CAN_UNDO; | 266 edit_flags |= ContextNodeType::CAN_UNDO; |
| 264 if (webview_->GetFocusedWebCoreFrame()->editor()->canRedo()) | 267 if (webview_->GetFocusedWebCoreFrame()->editor()->canRedo()) |
| 265 edit_flags |= ContextNode::CAN_REDO; | 268 edit_flags |= ContextNodeType::CAN_REDO; |
| 266 if (webview_->GetFocusedWebCoreFrame()->editor()->canCut()) | 269 if (webview_->GetFocusedWebCoreFrame()->editor()->canCut()) |
| 267 edit_flags |= ContextNode::CAN_CUT; | 270 edit_flags |= ContextNodeType::CAN_CUT; |
| 268 if (webview_->GetFocusedWebCoreFrame()->editor()->canCopy()) | 271 if (webview_->GetFocusedWebCoreFrame()->editor()->canCopy()) |
| 269 edit_flags |= ContextNode::CAN_COPY; | 272 edit_flags |= ContextNodeType::CAN_COPY; |
| 270 if (webview_->GetFocusedWebCoreFrame()->editor()->canPaste()) | 273 if (webview_->GetFocusedWebCoreFrame()->editor()->canPaste()) |
| 271 edit_flags |= ContextNode::CAN_PASTE; | 274 edit_flags |= ContextNodeType::CAN_PASTE; |
| 272 if (webview_->GetFocusedWebCoreFrame()->editor()->canDelete()) | 275 if (webview_->GetFocusedWebCoreFrame()->editor()->canDelete()) |
| 273 edit_flags |= ContextNode::CAN_DELETE; | 276 edit_flags |= ContextNodeType::CAN_DELETE; |
| 274 // We can always select all... | 277 // We can always select all... |
| 275 edit_flags |= ContextNode::CAN_SELECT_ALL; | 278 edit_flags |= ContextNodeType::CAN_SELECT_ALL; |
| 276 | 279 |
| 277 WebViewDelegate* d = webview_->delegate(); | 280 WebViewDelegate* d = webview_->delegate(); |
| 278 if (d) { | 281 if (d) { |
| 279 d->ShowContextMenu(webview_, | 282 d->ShowContextMenu(webview_, |
| 280 node, | 283 node_type, |
| 281 menu_point.x(), | 284 menu_point.x(), |
| 282 menu_point.y(), | 285 menu_point.y(), |
| 283 webkit_glue::KURLToGURL(link_url), | 286 webkit_glue::KURLToGURL(link_url), |
| 284 webkit_glue::KURLToGURL(src_url), | 287 webkit_glue::KURLToGURL(src_url), |
| 285 page_url, | 288 page_url, |
| 286 frame_url, | 289 frame_url, |
| 287 media_params, | 290 media_params, |
| 288 selection_text_string, | 291 selection_text_string, |
| 289 misspelled_word_string, | 292 misspelled_word_string, |
| 290 edit_flags, | 293 edit_flags, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 | 325 |
| 323 bool ContextMenuClientImpl::shouldIncludeInspectElementItem() { | 326 bool ContextMenuClientImpl::shouldIncludeInspectElementItem() { |
| 324 return false; // TODO(jackson): Eventually include the inspector context me
nu item | 327 return false; // TODO(jackson): Eventually include the inspector context me
nu item |
| 325 } | 328 } |
| 326 | 329 |
| 327 #if defined(OS_MACOSX) | 330 #if defined(OS_MACOSX) |
| 328 void ContextMenuClientImpl::searchWithSpotlight() { | 331 void ContextMenuClientImpl::searchWithSpotlight() { |
| 329 // TODO(pinkerton): write this | 332 // TODO(pinkerton): write this |
| 330 } | 333 } |
| 331 #endif | 334 #endif |
| OLD | NEW |