OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2007 Google Inc. All Rights Reserved. | 2 * Copyright 2007 Google Inc. All Rights Reserved. |
3 * | 3 * |
4 * Portions Copyright (C) 2006 Apple Computer, Inc. All rights reserved. | 4 * Portions Copyright (C) 2006 Apple Computer, Inc. All rights reserved. |
5 * | 5 * |
6 * ***** BEGIN LICENSE BLOCK ***** | 6 * ***** BEGIN LICENSE BLOCK ***** |
7 * | 7 * |
8 * Redistribution and use in source and binary forms, with or without | 8 * Redistribution and use in source and binary forms, with or without |
9 * modification, are permitted provided that the following conditions | 9 * modification, are permitted provided that the following conditions |
10 * are met: | 10 * are met: |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 | 373 |
374 page_->backForwardList()->setClient(&back_forward_list_client_impl_); | 374 page_->backForwardList()->setClient(&back_forward_list_client_impl_); |
375 | 375 |
376 // The group name identifies a namespace of pages. I'm not sure how it's | 376 // The group name identifies a namespace of pages. I'm not sure how it's |
377 // intended to be used, but keeping all pages in the same group works for us. | 377 // intended to be used, but keeping all pages in the same group works for us. |
378 page_->setGroupName("default"); | 378 page_->setGroupName("default"); |
379 } | 379 } |
380 | 380 |
381 WebViewImpl::~WebViewImpl() { | 381 WebViewImpl::~WebViewImpl() { |
382 DCHECK(page_ == NULL); | 382 DCHECK(page_ == NULL); |
383 ReleaseFocusReferences(); | |
384 for (std::set<ImageResourceFetcher*>::iterator i = image_fetchers_.begin(); | 383 for (std::set<ImageResourceFetcher*>::iterator i = image_fetchers_.begin(); |
385 i != image_fetchers_.end(); ++i) { | 384 i != image_fetchers_.end(); ++i) { |
386 delete *i; | 385 delete *i; |
387 } | 386 } |
388 } | 387 } |
389 | 388 |
390 RenderTheme* WebViewImpl::theme() const { | 389 RenderTheme* WebViewImpl::theme() const { |
391 return page_.get() ? page_->theme() : RenderTheme::defaultTheme().get(); | 390 return page_.get() ? page_->theme() : RenderTheme::defaultTheme().get(); |
392 } | 391 } |
393 | 392 |
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1091 | 1090 |
1092 void WebViewImpl::StopLoading() { | 1091 void WebViewImpl::StopLoading() { |
1093 main_frame()->StopLoading(); | 1092 main_frame()->StopLoading(); |
1094 } | 1093 } |
1095 | 1094 |
1096 void WebViewImpl::SetBackForwardListSize(int size) { | 1095 void WebViewImpl::SetBackForwardListSize(int size) { |
1097 page_->backForwardList()->setCapacity(size); | 1096 page_->backForwardList()->setCapacity(size); |
1098 } | 1097 } |
1099 | 1098 |
1100 void WebViewImpl::ClearFocusedNode() { | 1099 void WebViewImpl::ClearFocusedNode() { |
1101 // Get the last focused frame or the mainframe. | 1100 if (!page_.get()) |
1102 RefPtr<Frame> frame = last_focused_frame_; | 1101 return; |
1103 if (!frame.get() && page_.get()) | 1102 |
1104 frame = page_->mainFrame(); | 1103 RefPtr<Frame> frame = page_->mainFrame(); |
1105 if (!frame.get()) | 1104 if (!frame.get()) |
1106 return; | 1105 return; |
1107 | 1106 |
1108 RefPtr<Document> document = frame->document(); | 1107 RefPtr<Document> document = frame->document(); |
1109 if (!document.get()) | 1108 if (!document.get()) |
1110 return; | 1109 return; |
1111 | 1110 |
1112 RefPtr<Node> old_focused_node = document->focusedNode(); | 1111 RefPtr<Node> old_focused_node = document->focusedNode(); |
1113 | 1112 |
1114 // Clear the focused node. | 1113 // Clear the focused node. |
1115 document->setFocusedNode(NULL); | 1114 document->setFocusedNode(NULL); |
1116 | 1115 |
1117 if (!old_focused_node.get()) | 1116 if (!old_focused_node.get()) |
1118 return; | 1117 return; |
1119 | 1118 |
1120 // If a text field has focus, we need to make sure the selection controller | 1119 // If a text field has focus, we need to make sure the selection controller |
1121 // knows to remove selection from it. Otherwise, the text field is still | 1120 // knows to remove selection from it. Otherwise, the text field is still |
1122 // processing keyboard events even though focus has been moved to the page and | 1121 // processing keyboard events even though focus has been moved to the page and |
1123 // keystrokes get eaten as a result. | 1122 // keystrokes get eaten as a result. |
1124 if (old_focused_node->hasTagName(HTMLNames::textareaTag) || | 1123 if (old_focused_node->hasTagName(HTMLNames::textareaTag) || |
1125 (old_focused_node->hasTagName(HTMLNames::inputTag) && | 1124 (old_focused_node->hasTagName(HTMLNames::inputTag) && |
1126 static_cast<HTMLInputElement*>(old_focused_node.get())->isTextField())) { | 1125 static_cast<HTMLInputElement*>(old_focused_node.get())->isTextField())) { |
1127 // Clear the selection. | 1126 // Clear the selection. |
1128 SelectionController* selection = frame->selection(); | 1127 SelectionController* selection = frame->selection(); |
1129 selection->clear(); | 1128 selection->clear(); |
1130 } | 1129 } |
1131 } | 1130 } |
1132 | 1131 |
1133 void WebViewImpl::SetFocus(bool enable) { | 1132 void WebViewImpl::SetFocus(bool enable) { |
| 1133 page_->focusController()->setFocused(enable); |
1134 if (enable) { | 1134 if (enable) { |
1135 // Getting the focused frame will have the side-effect of setting the main | 1135 // Note that we don't call setActive() when disabled as this cause extra |
1136 // frame as the focused frame if it is not already focused. Otherwise, if | 1136 // focus/blur events to be dispatched. |
1137 // there is already a focused frame, then this does nothing. | 1137 page_->focusController()->setActive(true); |
1138 GetFocusedFrame(); | |
1139 if (page_.get() && page_->mainFrame()) { | |
1140 Frame* frame = page_->mainFrame(); | |
1141 if (!frame->selection()->isFocusedAndActive()) { | |
1142 // No one has focus yet, try to restore focus. | |
1143 RestoreFocus(); | |
1144 page_->focusController()->setActive(true); | |
1145 } | |
1146 Frame* focused_frame = page_->focusController()->focusedOrMainFrame(); | |
1147 frame->selection()->setFocused(frame == focused_frame); | |
1148 } | |
1149 ime_accept_events_ = true; | 1138 ime_accept_events_ = true; |
1150 } else { | 1139 } else { |
1151 HideAutoCompletePopup(); | 1140 HideAutoCompletePopup(); |
1152 | 1141 |
1153 // Clear out who last had focus. If someone has focus, the refs will be | |
1154 // updated below. | |
1155 ReleaseFocusReferences(); | |
1156 | |
1157 // Clear focus on the currently focused frame if any. | 1142 // Clear focus on the currently focused frame if any. |
1158 if (!page_.get()) | 1143 if (!page_.get()) |
1159 return; | 1144 return; |
1160 | 1145 |
1161 Frame* frame = page_->mainFrame(); | 1146 Frame* frame = page_->mainFrame(); |
1162 if (!frame) | 1147 if (!frame) |
1163 return; | 1148 return; |
1164 | 1149 |
1165 RefPtr<Frame> focused = page_->focusController()->focusedFrame(); | 1150 RefPtr<Frame> focused_frame = page_->focusController()->focusedFrame(); |
1166 if (focused.get()) { | 1151 if (focused_frame.get()) { |
1167 // Update the focus refs, this way we can give focus back appropriately. | |
1168 // It's entirely possible to have a focused document, but not a focused | |
1169 // node. | |
1170 RefPtr<Document> document = focused->document(); | |
1171 last_focused_frame_ = focused; | |
1172 if (document.get()) { | |
1173 RefPtr<Node> focused_node = document->focusedNode(); | |
1174 if (focused_node.get()) { | |
1175 // To workaround bug #792423, we do not blur the focused node. This | |
1176 // should be reenabled when we merge a WebKit that has the fix for | |
1177 // http://bugs.webkit.org/show_bug.cgi?id=16928. | |
1178 // last_focused_node_ = focused_node; | |
1179 // document->setFocusedNode(NULL); | |
1180 } | |
1181 } | |
1182 page_->focusController()->setFocusedFrame(0); | |
1183 | |
1184 // Finish an ongoing composition to delete the composition node. | 1152 // Finish an ongoing composition to delete the composition node. |
1185 Editor* editor = focused->editor(); | 1153 Editor* editor = focused_frame->editor(); |
1186 if (editor && editor->hasComposition()) | 1154 if (editor && editor->hasComposition()) |
1187 editor->confirmComposition(); | 1155 editor->confirmComposition(); |
1188 ime_accept_events_ = false; | 1156 ime_accept_events_ = false; |
1189 } | 1157 } |
1190 // Make sure the main frame doesn't think it has focus. | |
1191 if (frame != focused.get()) | |
1192 frame->selection()->setFocused(false); | |
1193 } | |
1194 } | |
1195 | |
1196 // TODO(jcampan): http://b/issue?id=1157486 this is needed to work-around | |
1197 // issues caused by the fix for bug #792423 and should be removed when that | |
1198 // bug is fixed. | |
1199 void WebViewImpl::StoreFocusForFrame(WebFrame* frame) { | |
1200 DCHECK(frame); | |
1201 | |
1202 // We only want to store focus info if we are the focused frame and if we have | |
1203 // not stored it already. | |
1204 WebCore::Frame* webcore_frame = static_cast<WebFrameImpl*>(frame)->frame(); | |
1205 if (last_focused_frame_.get() != webcore_frame || last_focused_node_.get()) | |
1206 return; | |
1207 | |
1208 // Clear out who last had focus. If someone has focus, the refs will be | |
1209 // updated below. | |
1210 ReleaseFocusReferences(); | |
1211 | |
1212 last_focused_frame_ = webcore_frame; | |
1213 RefPtr<Document> document = last_focused_frame_->document(); | |
1214 if (document.get()) { | |
1215 RefPtr<Node> focused_node = document->focusedNode(); | |
1216 if (focused_node.get()) { | |
1217 last_focused_node_ = focused_node; | |
1218 document->setFocusedNode(NULL); | |
1219 } | |
1220 } | 1158 } |
1221 } | 1159 } |
1222 | 1160 |
1223 bool WebViewImpl::ImeSetComposition(int string_type, | 1161 bool WebViewImpl::ImeSetComposition(int string_type, |
1224 int cursor_position, | 1162 int cursor_position, |
1225 int target_start, | 1163 int target_start, |
1226 int target_end, | 1164 int target_end, |
1227 const std::wstring& ime_string) { | 1165 const std::wstring& ime_string) { |
1228 Frame* focused = GetFocusedWebCoreFrame(); | 1166 Frame* focused = GetFocusedWebCoreFrame(); |
1229 if (!focused || !ime_accept_events_) { | 1167 if (!focused || !ime_accept_events_) { |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1363 case WEB_TEXT_DIRECTION_RTL: | 1301 case WEB_TEXT_DIRECTION_RTL: |
1364 editor->setBaseWritingDirection(WebCore::RightToLeftWritingDirection); | 1302 editor->setBaseWritingDirection(WebCore::RightToLeftWritingDirection); |
1365 break; | 1303 break; |
1366 | 1304 |
1367 default: | 1305 default: |
1368 NOTIMPLEMENTED(); | 1306 NOTIMPLEMENTED(); |
1369 break; | 1307 break; |
1370 } | 1308 } |
1371 } | 1309 } |
1372 | 1310 |
1373 void WebViewImpl::RestoreFocus() { | |
1374 if (last_focused_frame_.get()) { | |
1375 if (last_focused_frame_->page()) { | |
1376 // last_focused_frame_ can be detached from the frame tree, thus, | |
1377 // its page can be null. | |
1378 last_focused_frame_->page()->focusController()->setFocusedFrame( | |
1379 last_focused_frame_.get()); | |
1380 } | |
1381 if (last_focused_node_.get()) { | |
1382 // last_focused_node_ may be null, make sure it's valid before trying to | |
1383 // focus it. | |
1384 static_cast<Element*>(last_focused_node_.get())->focus(); | |
1385 } | |
1386 // And clear out the refs. | |
1387 ReleaseFocusReferences(); | |
1388 } | |
1389 } | |
1390 | |
1391 void WebViewImpl::SetInitialFocus(bool reverse) { | 1311 void WebViewImpl::SetInitialFocus(bool reverse) { |
1392 if (page_.get()) { | 1312 if (page_.get()) { |
1393 // So RestoreFocus does not focus anything when it is called. | |
1394 ReleaseFocusReferences(); | |
1395 | |
1396 // Since we don't have a keyboard event, we'll create one. | 1313 // Since we don't have a keyboard event, we'll create one. |
1397 WebKeyboardEvent keyboard_event; | 1314 WebKeyboardEvent keyboard_event; |
1398 keyboard_event.type = WebInputEvent::RawKeyDown; | 1315 keyboard_event.type = WebInputEvent::RawKeyDown; |
1399 if (reverse) | 1316 if (reverse) |
1400 keyboard_event.modifiers = WebInputEvent::ShiftKey; | 1317 keyboard_event.modifiers = WebInputEvent::ShiftKey; |
1401 // VK_TAB which is only defined on Windows. | 1318 // VK_TAB which is only defined on Windows. |
1402 keyboard_event.windowsKeyCode = 0x09; | 1319 keyboard_event.windowsKeyCode = 0x09; |
1403 MakePlatformKeyboardEvent platform_event(keyboard_event); | 1320 MakePlatformKeyboardEvent platform_event(keyboard_event); |
1404 RefPtr<KeyboardEvent> webkit_event = | 1321 RefPtr<KeyboardEvent> webkit_event = |
1405 KeyboardEvent::create(platform_event, NULL); | 1322 KeyboardEvent::create(platform_event, NULL); |
1406 page()->focusController()->setInitialFocus( | 1323 page()->focusController()->setInitialFocus( |
1407 reverse ? WebCore::FocusDirectionBackward : | 1324 reverse ? WebCore::FocusDirectionBackward : |
1408 WebCore::FocusDirectionForward, | 1325 WebCore::FocusDirectionForward, |
1409 webkit_event.get()); | 1326 webkit_event.get()); |
1410 } | 1327 } |
1411 } | 1328 } |
1412 | 1329 |
1413 // Releases references used to restore focus. | |
1414 void WebViewImpl::ReleaseFocusReferences() { | |
1415 if (last_focused_frame_.get()) { | |
1416 last_focused_frame_.release(); | |
1417 last_focused_node_.release(); | |
1418 } | |
1419 } | |
1420 | |
1421 bool WebViewImpl::DownloadImage(int id, const GURL& image_url, int image_size) { | 1330 bool WebViewImpl::DownloadImage(int id, const GURL& image_url, int image_size) { |
1422 if (!page_.get()) | 1331 if (!page_.get()) |
1423 return false; | 1332 return false; |
1424 image_fetchers_.insert( | 1333 image_fetchers_.insert( |
1425 new ImageResourceFetcher(this, id, image_url, image_size)); | 1334 new ImageResourceFetcher(this, id, image_url, image_size)); |
1426 return true; | 1335 return true; |
1427 } | 1336 } |
1428 | 1337 |
1429 void WebViewImpl::SetPreferences(const WebPreferences& preferences) { | 1338 void WebViewImpl::SetPreferences(const WebPreferences& preferences) { |
1430 if (!page_.get()) | 1339 if (!page_.get()) |
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1941 | 1850 |
1942 return document->focusedNode(); | 1851 return document->focusedNode(); |
1943 } | 1852 } |
1944 | 1853 |
1945 HitTestResult WebViewImpl::HitTestResultForWindowPos(const IntPoint& pos) { | 1854 HitTestResult WebViewImpl::HitTestResultForWindowPos(const IntPoint& pos) { |
1946 IntPoint doc_point( | 1855 IntPoint doc_point( |
1947 page_->mainFrame()->view()->windowToContents(pos)); | 1856 page_->mainFrame()->view()->windowToContents(pos)); |
1948 return page_->mainFrame()->eventHandler()-> | 1857 return page_->mainFrame()->eventHandler()-> |
1949 hitTestResultAtPoint(doc_point, false); | 1858 hitTestResultAtPoint(doc_point, false); |
1950 } | 1859 } |
OLD | NEW |