summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authordarin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-10 17:35:35 +0000
committerdarin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-10 17:35:35 +0000
commit0486c5a53a330f342a3473e246f954484e25c341 (patch)
tree0bff802884a06658566ccb30f4d98828be202416 /webkit
parent5549f04ad33f5e19a93913158e88830ef54157ec (diff)
downloadchromium_src-0486c5a53a330f342a3473e246f954484e25c341.zip
chromium_src-0486c5a53a330f342a3473e246f954484e25c341.tar.gz
chromium_src-0486c5a53a330f342a3473e246f954484e25c341.tar.bz2
Correct the order of the methods in webframe_impl.cc to match how they are
declared in webframe_impl.h. The methods were quite jumbled up making it hard to know where to add new methods and making the code harder to read. This patch only involved shifting methods around in the files. There are not substantive changes in this CL. R=dglazkov BUG=none TEST=none Review URL: http://codereview.chromium.org/164244 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@22922 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/glue/webframe_impl.cc1598
-rw-r--r--webkit/glue/webframe_impl.h29
2 files changed, 809 insertions, 818 deletions
diff --git a/webkit/glue/webframe_impl.cc b/webkit/glue/webframe_impl.cc
index 4f784f2..2c4eb12 100644
--- a/webkit/glue/webframe_impl.cc
+++ b/webkit/glue/webframe_impl.cc
@@ -359,9 +359,11 @@ class ChromePrintContext : public WebCore::PrintContext {
DISALLOW_COPY_AND_ASSIGN(ChromePrintContext);
};
-// WebFrameImpl ----------------------------------------------------------------
+static WebDataSource* DataSourceForDocLoader(DocumentLoader* loader) {
+ return loader ? WebDataSourceImpl::FromLoader(loader) : NULL;
+}
-int WebFrameImpl::live_object_count_ = 0;
+// WebFrame -------------------------------------------------------------------
// static
WebFrame* WebFrame::frameForEnteredContext() {
@@ -383,123 +385,8 @@ WebFrame* WebFrame::frameForCurrentContext() {
return NULL;
}
-WebFrameImpl::WebFrameImpl()
- : ALLOW_THIS_IN_INITIALIZER_LIST(frame_loader_client_(this)),
- ALLOW_THIS_IN_INITIALIZER_LIST(scope_matches_factory_(this)),
- plugin_delegate_(NULL),
- active_match_frame_(NULL),
- active_match_index_(-1),
- locating_active_rect_(false),
- resume_scoping_from_range_(NULL),
- last_match_count_(-1),
- total_matchcount_(-1),
- frames_scoping_count_(-1),
- scoping_complete_(false),
- next_invalidate_after_(0) {
- StatsCounter(kWebFrameActiveCount).Increment();
- live_object_count_++;
-}
-
-WebFrameImpl::~WebFrameImpl() {
- StatsCounter(kWebFrameActiveCount).Decrement();
- live_object_count_--;
-
- cancelPendingScopingEffort();
- ClearPasswordListeners();
-}
-
-// WebFrame -------------------------------------------------------------------
-
-void WebFrameImpl::InitMainFrame(WebViewImpl* webview_impl) {
- RefPtr<Frame> frame =
- Frame::create(webview_impl->page(), 0, &frame_loader_client_);
- frame_ = frame.get();
-
- // Add reference on behalf of FrameLoader. See comments in
- // WebFrameLoaderClient::frameLoaderDestroyed for more info.
- AddRef();
-
- // We must call init() after frame_ is assigned because it is referenced
- // during init().
- frame_->init();
-}
-
-void WebFrameImpl::reload() {
- frame_->loader()->saveDocumentAndScrollState();
-
- stopLoading(); // Make sure existing activity stops.
- frame_->loader()->reload();
-}
-
-void WebFrameImpl::loadRequest(const WebURLRequest& request) {
- const ResourceRequest* resource_request =
- webkit_glue::WebURLRequestToResourceRequest(&request);
- DCHECK(resource_request);
-
- if (resource_request->url().protocolIs("javascript")) {
- LoadJavaScriptURL(resource_request->url());
- return;
- }
-
- stopLoading(); // Make sure existing activity stops.
- frame_->loader()->load(*resource_request, false);
-}
-
-void WebFrameImpl::loadHistoryItem(const WebHistoryItem& item) {
- RefPtr<HistoryItem> history_item =
- webkit_glue::WebHistoryItemToHistoryItem(item);
- DCHECK(history_item.get());
-
- stopLoading(); // Make sure existing activity stops.
-
- // If there is no current_item, which happens when we are navigating in
- // session history after a crash, we need to manufacture one otherwise WebKit
- // hoarks. This is probably the wrong thing to do, but it seems to work.
- RefPtr<HistoryItem> current_item = frame_->loader()->currentHistoryItem();
- if (!current_item) {
- current_item = HistoryItem::create();
- current_item->setLastVisitWasFailure(true);
- frame_->loader()->setCurrentHistoryItem(current_item);
- GetWebViewImpl()->SetCurrentHistoryItem(current_item.get());
- }
-
- frame_->loader()->goToItem(history_item.get(),
- WebCore::FrameLoadTypeIndexedBackForward);
-}
-
-void WebFrameImpl::loadData(const WebData& data,
- const WebString& mime_type,
- const WebString& text_encoding,
- const WebURL& base_url,
- const WebURL& unreachable_url,
- bool replace) {
- SubstituteData subst_data(
- webkit_glue::WebDataToSharedBuffer(data),
- webkit_glue::WebStringToString(mime_type),
- webkit_glue::WebStringToString(text_encoding),
- webkit_glue::WebURLToKURL(unreachable_url));
- DCHECK(subst_data.isValid());
-
- stopLoading(); // Make sure existing activity stops.
- frame_->loader()->load(ResourceRequest(webkit_glue::WebURLToKURL(base_url)),
- subst_data, false);
- if (replace) {
- // Do this to force WebKit to treat the load as replacing the currently
- // loaded page.
- frame_->loader()->setReplacing();
- }
-}
-
-void WebFrameImpl::loadHTMLString(const WebData& data,
- const WebURL& base_url,
- const WebURL& unreachable_url,
- bool replace) {
- loadData(data,
- WebString::fromUTF8("text/html"),
- WebString::fromUTF8("UTF-8"),
- base_url,
- unreachable_url,
- replace);
+WebString WebFrameImpl::name() const {
+ return webkit_glue::StringToWebString(frame_->tree()->name());
}
WebURL WebFrameImpl::url() const {
@@ -544,6 +431,18 @@ WebURL WebFrameImpl::openSearchDescriptionURL() const {
return WebURL();
}
+WebSize WebFrameImpl::scrollOffset() const {
+ WebCore::FrameView* view = frameview();
+ if (view)
+ return webkit_glue::IntSizeToWebSize(view->scrollOffset());
+
+ return WebSize();
+}
+
+WebSize WebFrameImpl::contentsSize() const {
+ return webkit_glue::IntSizeToWebSize(frame()->view()->contentsSize());
+}
+
int WebFrameImpl::contentsPreferredWidth() const {
if ((frame_->document() != NULL) &&
(frame_->document()->renderView() != NULL)) {
@@ -553,63 +452,13 @@ int WebFrameImpl::contentsPreferredWidth() const {
}
}
-WebHistoryItem WebFrameImpl::previousHistoryItem() const {
- // We use the previous item here because documentState (filled-out forms)
- // only get saved to history when it becomes the previous item. The caller
- // is expected to query the history item after a navigation occurs, after
- // the desired history item has become the previous entry.
- return webkit_glue::HistoryItemToWebHistoryItem(
- GetWebViewImpl()->GetPreviousHistoryItem());
-}
-
-WebHistoryItem WebFrameImpl::currentHistoryItem() const {
- frame_->loader()->saveDocumentAndScrollState();
-
- return webkit_glue::HistoryItemToWebHistoryItem(
- frame_->page()->backForwardList()->currentItem());
-}
-
-static WebDataSource* DataSourceForDocLoader(DocumentLoader* loader) {
- return loader ? WebDataSourceImpl::FromLoader(loader) : NULL;
-}
-
-WebDataSource* WebFrameImpl::dataSource() const {
- return DataSourceForDocLoader(frame_->loader()->documentLoader());
-}
-
-WebDataSourceImpl* WebFrameImpl::GetDataSourceImpl() const {
- return static_cast<WebDataSourceImpl*>(dataSource());
-}
-
-WebDataSource* WebFrameImpl::provisionalDataSource() const {
- FrameLoader* frame_loader = frame_->loader();
-
- // We regard the policy document loader as still provisional.
- DocumentLoader* doc_loader = frame_loader->provisionalDocumentLoader();
- if (!doc_loader)
- doc_loader = frame_loader->policyDocumentLoader();
-
- return DataSourceForDocLoader(doc_loader);
-}
-
-WebDataSourceImpl* WebFrameImpl::GetProvisionalDataSourceImpl() const {
- return static_cast<WebDataSourceImpl*>(provisionalDataSource());
-}
-
-void WebFrameImpl::stopLoading() {
- if (!frame_)
- return;
-
- // TODO(darin): Figure out what we should really do here. It seems like a
- // bug that FrameLoader::stopLoading doesn't call stopAllLoaders.
- frame_->loader()->stopAllLoaders();
- frame_->loader()->stopLoading(false);
+bool WebFrameImpl::hasVisibleContent() const {
+ return frame()->view()->visibleWidth() > 0 &&
+ frame()->view()->visibleHeight() > 0;
}
-bool WebFrameImpl::isLoading() const {
- if (!frame_)
- return false;
- return frame_->loader()->isLoading();
+WebView* WebFrameImpl::view() const {
+ return GetWebViewImpl();
}
WebFrame* WebFrameImpl::opener() const {
@@ -637,20 +486,60 @@ WebFrame* WebFrameImpl::top() const {
return NULL;
}
-void WebFrameImpl::enableViewSourceMode(bool enable) {
- if (frame_)
- frame_->setInViewSourceMode(enable);
+WebFrame* WebFrameImpl::firstChild() const {
+ return FromFrame(frame()->tree()->firstChild());
}
-bool WebFrameImpl::isViewSourceModeEnabled() const {
- if (frame_)
- return frame_->inViewSourceMode();
+WebFrame* WebFrameImpl::lastChild() const {
+ return FromFrame(frame()->tree()->lastChild());
+}
- return false;
+WebFrame* WebFrameImpl::nextSibling() const {
+ return FromFrame(frame()->tree()->nextSibling());
}
-WebView* WebFrameImpl::view() const {
- return GetWebViewImpl();
+WebFrame* WebFrameImpl::previousSibling() const {
+ return FromFrame(frame()->tree()->previousSibling());
+}
+
+WebFrame* WebFrameImpl::traverseNext(bool wrap) const {
+ return FromFrame(frame()->tree()->traverseNextWithWrap(wrap));
+}
+
+WebFrame* WebFrameImpl::traversePrevious(bool wrap) const {
+ return FromFrame(frame()->tree()->traversePreviousWithWrap(wrap));
+}
+
+WebFrame* WebFrameImpl::findChildByName(const WebKit::WebString& name) const {
+ return FromFrame(frame()->tree()->child(
+ webkit_glue::WebStringToString(name)));
+}
+
+WebFrame* WebFrameImpl::findChildByExpression(
+ const WebKit::WebString& xpath) const {
+ if (xpath.isEmpty())
+ return NULL;
+
+ Document* document = frame_->document();
+
+ ExceptionCode ec = 0;
+ PassRefPtr<XPathResult> xpath_result =
+ document->evaluate(webkit_glue::WebStringToString(xpath),
+ document,
+ NULL, /* namespace */
+ XPathResult::ORDERED_NODE_ITERATOR_TYPE,
+ NULL, /* XPathResult object */
+ ec);
+ if (!xpath_result.get())
+ return NULL;
+
+ Node* node = xpath_result->iterateNext(ec);
+
+ if (!node || !node->isFrameOwnerElement())
+ return NULL;
+ HTMLFrameOwnerElement* frame_element =
+ static_cast<HTMLFrameOwnerElement*>(node);
+ return FromFrame(frame_element->contentFrame());
}
void WebFrameImpl::forms(WebVector<WebForm>& results) const {
@@ -681,6 +570,20 @@ WebString WebFrameImpl::securityOrigin() const {
return WebString::fromUTF8("null");
}
+void WebFrameImpl::grantUniversalAccess() {
+ DCHECK(frame_ && frame_->document());
+ if (frame_ && frame_->document()) {
+ frame_->document()->securityOrigin()->grantUniversalAccess();
+ }
+}
+
+NPObject* WebFrameImpl::windowObject() const {
+ if (!frame_)
+ return NULL;
+
+ return frame_->script()->windowScriptNPObject();
+}
+
void WebFrameImpl::bindToWindowObject(const WebString& name,
NPObject* object) {
DCHECK(frame_);
@@ -707,8 +610,72 @@ void WebFrameImpl::bindToWindowObject(const WebString& name,
#endif
}
+void WebFrameImpl::executeScript(const WebScriptSource& source) {
+ frame_->loader()->executeScript(
+ WebCore::ScriptSourceCode(
+ webkit_glue::WebStringToString(source.code),
+ webkit_glue::WebURLToKURL(source.url),
+ source.startLine));
+}
+
+void WebFrameImpl::executeScriptInNewContext(
+ const WebScriptSource* sources_in, unsigned num_sources,
+ int extension_group) {
+ Vector<WebCore::ScriptSourceCode> sources;
+
+ for (unsigned i = 0; i < num_sources; ++i) {
+ sources.append(WebCore::ScriptSourceCode(
+ webkit_glue::WebStringToString(sources_in[i].code),
+ webkit_glue::WebURLToKURL(sources_in[i].url),
+ sources_in[i].startLine));
+ }
+
+ frame_->script()->evaluateInNewContext(sources, extension_group);
+}
+
+void WebFrameImpl::executeScriptInNewWorld(
+ const WebScriptSource* sources_in, unsigned num_sources,
+ int extension_group) {
+ Vector<WebCore::ScriptSourceCode> sources;
+
+ for (unsigned i = 0; i < num_sources; ++i) {
+ sources.append(WebCore::ScriptSourceCode(
+ webkit_glue::WebStringToString(sources_in[i].code),
+ webkit_glue::WebURLToKURL(sources_in[i].url),
+ sources_in[i].startLine));
+ }
+
+ frame_->script()->evaluateInNewWorld(sources, extension_group);
+}
+
+void WebFrameImpl::addMessageToConsole(const WebConsoleMessage& message) {
+ ASSERT(frame());
+
+ WebCore::MessageLevel webcore_message_level;
+ switch (message.level) {
+ case WebConsoleMessage::LevelTip:
+ webcore_message_level = WebCore::TipMessageLevel;
+ break;
+ case WebConsoleMessage::LevelLog:
+ webcore_message_level = WebCore::LogMessageLevel;
+ break;
+ case WebConsoleMessage::LevelWarning:
+ webcore_message_level = WebCore::WarningMessageLevel;
+ break;
+ case WebConsoleMessage::LevelError:
+ webcore_message_level = WebCore::ErrorMessageLevel;
+ break;
+ default:
+ NOTREACHED();
+ return;
+ }
+
+ frame()->domWindow()->console()->addMessage(
+ WebCore::OtherMessageSource, WebCore::LogMessageType,
+ webcore_message_level, webkit_glue::WebStringToString(message.text),
+ 1, String());
+}
-// Call JavaScript garbage collection.
void WebFrameImpl::collectGarbage() {
if (!frame_)
return;
@@ -720,96 +687,388 @@ void WebFrameImpl::collectGarbage() {
#endif
}
-void WebFrameImpl::grantUniversalAccess() {
- DCHECK(frame_ && frame_->document());
- if (frame_ && frame_->document()) {
- frame_->document()->securityOrigin()->grantUniversalAccess();
+#if USE(V8)
+ // Returns the V8 context for this frame, or an empty handle if there is
+ // none.
+v8::Local<v8::Context> WebFrameImpl::mainWorldScriptContext() const {
+ if (!frame_)
+ return v8::Local<v8::Context>();
+
+ return WebCore::V8Proxy::mainWorldContext(frame_);
+}
+#endif
+
+bool WebFrameImpl::insertStyleText(const WebString& css) {
+ Document* document = frame()->document();
+ if (!document)
+ return false;
+ WebCore::Element* document_element = document->documentElement();
+ if (!document_element)
+ return false;
+
+ RefPtr<WebCore::Element> stylesheet = document->createElement(
+ WebCore::HTMLNames::styleTag, false);
+ ExceptionCode err = 0;
+ stylesheet->setTextContent(webkit_glue::WebStringToString(css), err);
+ DCHECK(!err) << "Failed to set style element content";
+ WebCore::Node* first = document_element->firstChild();
+ bool success = document_element->insertBefore(stylesheet, first, err);
+ DCHECK(success) << "Failed to insert stylesheet";
+ return success;
+}
+
+void WebFrameImpl::reload() {
+ frame_->loader()->saveDocumentAndScrollState();
+
+ stopLoading(); // Make sure existing activity stops.
+ frame_->loader()->reload();
+}
+
+void WebFrameImpl::loadRequest(const WebURLRequest& request) {
+ const ResourceRequest* resource_request =
+ webkit_glue::WebURLRequestToResourceRequest(&request);
+ DCHECK(resource_request);
+
+ if (resource_request->url().protocolIs("javascript")) {
+ LoadJavaScriptURL(resource_request->url());
+ return;
}
+
+ stopLoading(); // Make sure existing activity stops.
+ frame_->loader()->load(*resource_request, false);
}
-WebString WebFrameImpl::contentAsText(size_t max_chars) const {
- if (!frame_)
- return WebString();
+void WebFrameImpl::loadHistoryItem(const WebHistoryItem& item) {
+ RefPtr<HistoryItem> history_item =
+ webkit_glue::WebHistoryItemToHistoryItem(item);
+ DCHECK(history_item.get());
- std::wstring text;
- FrameContentAsPlainText(max_chars, frame_, &text);
- // TODO(darin): Too many string copies!!!
- return WideToUTF16Hack(text);
+ stopLoading(); // Make sure existing activity stops.
+
+ // If there is no current_item, which happens when we are navigating in
+ // session history after a crash, we need to manufacture one otherwise WebKit
+ // hoarks. This is probably the wrong thing to do, but it seems to work.
+ RefPtr<HistoryItem> current_item = frame_->loader()->currentHistoryItem();
+ if (!current_item) {
+ current_item = HistoryItem::create();
+ current_item->setLastVisitWasFailure(true);
+ frame_->loader()->setCurrentHistoryItem(current_item);
+ GetWebViewImpl()->SetCurrentHistoryItem(current_item.get());
+ }
+
+ frame_->loader()->goToItem(history_item.get(),
+ WebCore::FrameLoadTypeIndexedBackForward);
}
-NPObject* WebFrameImpl::windowObject() const {
- if (!frame_)
- return NULL;
+void WebFrameImpl::loadData(const WebData& data,
+ const WebString& mime_type,
+ const WebString& text_encoding,
+ const WebURL& base_url,
+ const WebURL& unreachable_url,
+ bool replace) {
+ SubstituteData subst_data(
+ webkit_glue::WebDataToSharedBuffer(data),
+ webkit_glue::WebStringToString(mime_type),
+ webkit_glue::WebStringToString(text_encoding),
+ webkit_glue::WebURLToKURL(unreachable_url));
+ DCHECK(subst_data.isValid());
- return frame_->script()->windowScriptNPObject();
+ stopLoading(); // Make sure existing activity stops.
+ frame_->loader()->load(ResourceRequest(webkit_glue::WebURLToKURL(base_url)),
+ subst_data, false);
+ if (replace) {
+ // Do this to force WebKit to treat the load as replacing the currently
+ // loaded page.
+ frame_->loader()->setReplacing();
+ }
}
-#if USE(V8)
- // Returns the V8 context for this frame, or an empty handle if there is
- // none.
-v8::Local<v8::Context> WebFrameImpl::mainWorldScriptContext() const {
+void WebFrameImpl::loadHTMLString(const WebData& data,
+ const WebURL& base_url,
+ const WebURL& unreachable_url,
+ bool replace) {
+ loadData(data,
+ WebString::fromUTF8("text/html"),
+ WebString::fromUTF8("UTF-8"),
+ base_url,
+ unreachable_url,
+ replace);
+}
+
+bool WebFrameImpl::isLoading() const {
if (!frame_)
- return v8::Local<v8::Context>();
+ return false;
+ return frame_->loader()->isLoading();
+}
- return WebCore::V8Proxy::mainWorldContext(frame_);
+void WebFrameImpl::stopLoading() {
+ if (!frame_)
+ return;
+
+ // TODO(darin): Figure out what we should really do here. It seems like a
+ // bug that FrameLoader::stopLoading doesn't call stopAllLoaders.
+ frame_->loader()->stopAllLoaders();
+ frame_->loader()->stopLoading(false);
}
-#endif
-void WebFrameImpl::InvalidateArea(AreaToInvalidate area) {
- ASSERT(frame() && frame()->view());
- FrameView* view = frame()->view();
+WebDataSource* WebFrameImpl::provisionalDataSource() const {
+ FrameLoader* frame_loader = frame_->loader();
- if ((area & INVALIDATE_ALL) == INVALIDATE_ALL) {
- view->invalidateRect(view->frameRect());
- } else {
- if ((area & INVALIDATE_CONTENT_AREA) == INVALIDATE_CONTENT_AREA) {
- IntRect content_area(
- view->x(), view->y(), view->visibleWidth(), view->visibleHeight());
- view->invalidateRect(content_area);
- }
+ // We regard the policy document loader as still provisional.
+ DocumentLoader* doc_loader = frame_loader->provisionalDocumentLoader();
+ if (!doc_loader)
+ doc_loader = frame_loader->policyDocumentLoader();
- if ((area & INVALIDATE_SCROLLBAR) == INVALIDATE_SCROLLBAR) {
- // Invalidate the vertical scroll bar region for the view.
- IntRect scroll_bar_vert(
- view->x() + view->visibleWidth(), view->y(),
- WebCore::ScrollbarTheme::nativeTheme()->scrollbarThickness(),
- view->visibleHeight());
- view->invalidateRect(scroll_bar_vert);
+ return DataSourceForDocLoader(doc_loader);
+}
+
+WebDataSource* WebFrameImpl::dataSource() const {
+ return DataSourceForDocLoader(frame_->loader()->documentLoader());
+}
+
+WebHistoryItem WebFrameImpl::previousHistoryItem() const {
+ // We use the previous item here because documentState (filled-out forms)
+ // only get saved to history when it becomes the previous item. The caller
+ // is expected to query the history item after a navigation occurs, after
+ // the desired history item has become the previous entry.
+ return webkit_glue::HistoryItemToWebHistoryItem(
+ GetWebViewImpl()->GetPreviousHistoryItem());
+}
+
+WebHistoryItem WebFrameImpl::currentHistoryItem() const {
+ frame_->loader()->saveDocumentAndScrollState();
+
+ return webkit_glue::HistoryItemToWebHistoryItem(
+ frame_->page()->backForwardList()->currentItem());
+}
+
+void WebFrameImpl::enableViewSourceMode(bool enable) {
+ if (frame_)
+ frame_->setInViewSourceMode(enable);
+}
+
+bool WebFrameImpl::isViewSourceModeEnabled() const {
+ if (frame_)
+ return frame_->inViewSourceMode();
+
+ return false;
+}
+
+void WebFrameImpl::dispatchWillSendRequest(WebURLRequest& request) {
+ ResourceResponse response;
+ frame_->loader()->client()->dispatchWillSendRequest(NULL, 0,
+ *webkit_glue::WebURLRequestToMutableResourceRequest(&request),
+ response);
+}
+
+void WebFrameImpl::commitDocumentData(const char* data, size_t data_len) {
+ DocumentLoader* document_loader = frame_->loader()->documentLoader();
+
+ // Set the text encoding. This calls begin() for us. It is safe to call
+ // this multiple times (Mac does: page/mac/WebCoreFrameBridge.mm).
+ bool user_chosen = true;
+ String encoding = document_loader->overrideEncoding();
+ if (encoding.isNull()) {
+ user_chosen = false;
+ encoding = document_loader->response().textEncodingName();
+ }
+ frame_->loader()->setEncoding(encoding, user_chosen);
+
+ // NOTE: mac only does this if there is a document
+ frame_->loader()->addData(data, data_len);
+}
+
+unsigned WebFrameImpl::unloadListenerCount() const {
+ return frame()->domWindow()->pendingUnloadEventListeners();
+}
+
+void WebFrameImpl::replaceSelection(const WebString& wtext) {
+ String text = webkit_glue::WebStringToString(wtext);
+ RefPtr<DocumentFragment> fragment = createFragmentFromText(
+ frame()->selection()->toNormalizedRange().get(), text);
+ WebCore::applyCommand(WebCore::ReplaceSelectionCommand::create(
+ frame()->document(), fragment.get(), false, true, true));
+}
+
+void WebFrameImpl::insertText(const WebString& text) {
+ frame()->editor()->insertText(webkit_glue::WebStringToString(text), NULL);
+}
+
+void WebFrameImpl::setMarkedText(
+ const WebString& text, unsigned location, unsigned length) {
+ WebCore::Editor* editor = frame()->editor();
+ WebCore::String str = webkit_glue::WebStringToString(text);
+
+ editor->confirmComposition(str);
+
+ WTF::Vector<WebCore::CompositionUnderline> decorations;
+ editor->setComposition(str, decorations, location, length);
+}
+
+void WebFrameImpl::unmarkText() {
+ frame()->editor()->confirmCompositionWithoutDisturbingSelection();
+}
+
+bool WebFrameImpl::hasMarkedText() const {
+ return frame()->editor()->hasComposition();
+}
+
+WebRange WebFrameImpl::markedRange() const {
+ return webkit_glue::RangeToWebRange(frame()->editor()->compositionRange());
+}
+
+bool WebFrameImpl::executeCommand(const WebString& name) {
+ ASSERT(frame());
+
+ if (name.length() <= 2)
+ return false;
+
+ // Since we don't have NSControl, we will convert the format of command
+ // string and call the function on Editor directly.
+ string16 command = name;
+
+ // Make sure the first letter is upper case.
+ command.replace(0, 1, 1, toupper(command.at(0)));
+
+ // Remove the trailing ':' if existing.
+ if (command.at(command.length() - 1) == ':')
+ command.erase(command.length() - 1, 1);
+
+ bool rv = true;
+
+ // Specially handling commands that Editor::execCommand does not directly
+ // support.
+ if (EqualsASCII(command, "DeleteToEndOfParagraph")) {
+ WebCore::Editor* editor = frame()->editor();
+ if (!editor->deleteWithDirection(WebCore::SelectionController::FORWARD,
+ WebCore::ParagraphBoundary,
+ true,
+ false)) {
+ editor->deleteWithDirection(WebCore::SelectionController::FORWARD,
+ WebCore::CharacterGranularity,
+ true,
+ false);
}
+ } else if (EqualsASCII(command, "Indent")) {
+ frame()->editor()->indent();
+ } else if (EqualsASCII(command, "Outdent")) {
+ frame()->editor()->outdent();
+ } else if (EqualsASCII(command, "DeleteBackward")) {
+ rv = frame()->editor()->command(AtomicString("BackwardDelete")).execute();
+ } else if (EqualsASCII(command, "DeleteForward")) {
+ rv = frame()->editor()->command(AtomicString("ForwardDelete")).execute();
+ } else {
+ rv = frame()->editor()->command(AtomicString(command.c_str())).execute();
}
+ return rv;
}
-void WebFrameImpl::increaseMatchCount(int count, int request_id) {
- // This function should only be called on the mainframe.
- DCHECK(!parent());
+bool WebFrameImpl::executeCommand(const WebString& name,
+ const WebString& value) {
+ ASSERT(frame());
+ return frame()->editor()->command(webkit_glue::WebStringToString(name)).
+ execute(webkit_glue::WebStringToString(value));
+}
- total_matchcount_ += count;
+bool WebFrameImpl::isCommandEnabled(const WebString& name) const {
+ ASSERT(frame());
+ return frame()->editor()->command(webkit_glue::WebStringToString(name)).
+ isEnabled();
+}
- // Update the UI with the latest findings.
- WebViewDelegate* webview_delegate = GetWebViewImpl()->GetDelegate();
- DCHECK(webview_delegate);
- if (webview_delegate)
- webview_delegate->ReportFindInPageMatchCount(total_matchcount_, request_id,
- frames_scoping_count_ == 0);
+void WebFrameImpl::enableContinuousSpellChecking(bool enable) {
+ if (enable == isContinuousSpellCheckingEnabled())
+ return;
+ frame()->editor()->toggleContinuousSpellChecking();
}
-void WebFrameImpl::reportFindInPageSelection(const WebRect& selection_rect,
- int active_match_ordinal,
- int request_id) {
- // Update the UI with the latest selection rect.
- WebViewDelegate* webview_delegate = GetWebViewImpl()->GetDelegate();
- DCHECK(webview_delegate);
- if (webview_delegate) {
- webview_delegate->ReportFindInPageSelection(
- request_id,
- OrdinalOfFirstMatchForFrame(this) + active_match_ordinal,
- selection_rect);
+bool WebFrameImpl::isContinuousSpellCheckingEnabled() const {
+ return frame()->editor()->isContinuousSpellCheckingEnabled();
+}
+
+void WebFrameImpl::selectAll() {
+ frame()->selection()->selectAll();
+
+ WebViewDelegate* d = GetWebViewImpl()->GetDelegate();
+ if (d)
+ d->UserMetricsRecordAction(L"SelectAll");
+}
+
+void WebFrameImpl::clearSelection() {
+ frame()->selection()->clear();
+}
+
+bool WebFrameImpl::hasSelection() const {
+ // frame()->selection()->isNone() never returns true.
+ return (frame()->selection()->start() != frame()->selection()->end());
+}
+
+WebRange WebFrameImpl::selectionRange() const {
+ return webkit_glue::RangeToWebRange(
+ frame()->selection()->toNormalizedRange());
+}
+
+WebString WebFrameImpl::selectionAsText() const {
+ RefPtr<Range> range = frame()->selection()->toNormalizedRange();
+ if (!range.get())
+ return WebString();
+
+ String text = range->text();
+#if defined(OS_WIN)
+ WebCore::replaceNewlinesWithWindowsStyleNewlines(text);
+#endif
+ WebCore::replaceNBSPWithSpace(text);
+ return webkit_glue::StringToWebString(text);
+}
+
+WebString WebFrameImpl::selectionAsMarkup() const {
+ RefPtr<Range> range = frame()->selection()->toNormalizedRange();
+ if (!range.get())
+ return WebString();
+
+ String markup = WebCore::createMarkup(range.get(), 0);
+ return webkit_glue::StringToWebString(markup);
+}
+
+int WebFrameImpl::printBegin(const WebSize& page_size) {
+ DCHECK_EQ(frame()->document()->isFrameSet(), false);
+
+ print_context_.reset(new ChromePrintContext(frame()));
+ WebCore::FloatRect rect(0, 0,
+ static_cast<float>(page_size.width),
+ static_cast<float>(page_size.height));
+ print_context_->begin(rect.width());
+ float page_height;
+ // We ignore the overlays calculation for now since they are generated in the
+ // browser. page_height is actually an output parameter.
+ print_context_->computePageRects(rect, 0, 0, 1.0, page_height);
+ return print_context_->pageCount();
+}
+
+float WebFrameImpl::printPage(int page, WebCanvas* canvas) {
+ // Ensure correct state.
+ if (!print_context_.get() || page < 0 || !frame() || !frame()->document()) {
+ NOTREACHED();
+ return 0;
}
+
+#if defined(OS_WIN) || defined(OS_LINUX)
+ PlatformContextSkia context(canvas);
+ GraphicsContext spool(&context);
+#elif defined(OS_MACOSX)
+ CGContextRef context = canvas->beginPlatformPaint();
+ GraphicsContext spool(context);
+ WebCore::LocalCurrentGraphicsContext localContext(&spool);
+#endif
+
+ return print_context_->spoolPage(spool, page);
}
-void WebFrameImpl::resetMatchCount() {
- total_matchcount_ = 0;
- frames_scoping_count_ = 0;
+void WebFrameImpl::printEnd() {
+ DCHECK(print_context_.get());
+ if (print_context_.get())
+ print_context_->end();
+ print_context_.reset(NULL);
}
bool WebFrameImpl::find(int request_id,
@@ -913,105 +1172,18 @@ bool WebFrameImpl::find(int request_id,
return found;
}
-int WebFrameImpl::OrdinalOfFirstMatchForFrame(WebFrameImpl* frame) const {
- int ordinal = 0;
- WebViewImpl* web_view = GetWebViewImpl();
- WebFrameImpl* const main_frame_impl = GetWebViewImpl()->main_frame();
- // Iterate from the main frame up to (but not including) |frame| and
- // add up the number of matches found so far.
- for (WebFrameImpl* it = main_frame_impl;
- it != frame;
- it = static_cast<WebFrameImpl*>(
- web_view->GetNextFrameAfter(it, true))) {
- if (it->last_match_count_ > 0)
- ordinal += it->last_match_count_;
- }
-
- return ordinal;
-}
-
-bool WebFrameImpl::ShouldScopeMatches(const string16& search_text) {
- // Don't scope if we can't find a frame or if the frame is not visible.
- // The user may have closed the tab/application, so abort.
- if (!frame() || !hasVisibleContent())
- return false;
-
- DCHECK(frame()->document() && frame()->view());
-
- // If the frame completed the scoping operation and found 0 matches the last
- // time it was searched, then we don't have to search it again if the user is
- // just adding to the search string or sending the same search string again.
- if (scoping_complete_ &&
- !last_search_string_.empty() && last_match_count_ == 0) {
- // Check to see if the search string prefixes match.
- string16 previous_search_prefix =
- search_text.substr(0, last_search_string_.length());
-
- if (previous_search_prefix == last_search_string_) {
- return false; // Don't search this frame, it will be fruitless.
- }
- }
-
- return true;
-}
-
-void WebFrameImpl::InvalidateIfNecessary() {
- if (last_match_count_ > next_invalidate_after_) {
- // TODO(finnur): (http://b/1088165) Optimize the drawing of the
- // tickmarks and remove this. This calculation sets a milestone for when
- // next to invalidate the scrollbar and the content area. We do this so that
- // we don't spend too much time drawing the scrollbar over and over again.
- // Basically, up until the first 500 matches there is no throttle. After the
- // first 500 matches, we set set the milestone further and further out (750,
- // 1125, 1688, 2K, 3K).
- static const int start_slowing_down_after = 500;
- static const int slowdown = 750;
- int i = (last_match_count_ / start_slowing_down_after);
- next_invalidate_after_ += i * slowdown;
-
- InvalidateArea(INVALIDATE_SCROLLBAR);
- }
-}
-
-void WebFrameImpl::AddMarker(WebCore::Range* range, bool active_match) {
- // Use a TextIterator to visit the potentially multiple nodes the range
- // covers.
- TextIterator markedText(range);
- for (; !markedText.atEnd(); markedText.advance()) {
- RefPtr<Range> textPiece = markedText.range();
- int exception = 0;
-
- WebCore::DocumentMarker marker = {
- WebCore::DocumentMarker::TextMatch,
- textPiece->startOffset(exception),
- textPiece->endOffset(exception),
- "",
- active_match };
-
- if (marker.endOffset > marker.startOffset) {
- // Find the node to add a marker to and add it.
- Node* node = textPiece->startContainer(exception);
- frame()->document()->addMarker(node, marker);
-
- // Rendered rects for markers in WebKit are not populated until each time
- // the markers are painted. However, we need it to happen sooner, because
- // the whole purpose of tickmarks on the scrollbar is to show where
- // matches off-screen are (that haven't been painted yet).
- Vector<WebCore::DocumentMarker> markers =
- frame()->document()->markersForNode(node);
- frame()->document()->setRenderedRectForMarker(
- textPiece->startContainer(exception),
- markers[markers.size() - 1],
- range->boundingBox());
- }
- }
-}
+void WebFrameImpl::stopFinding(bool clear_selection) {
+ if (!clear_selection)
+ SetFindEndstateFocusAndSelection();
+ cancelPendingScopingEffort();
-void WebFrameImpl::SetMarkerActive(WebCore::Range* range, bool active) {
- if (!range)
- return;
+ // Remove all markers for matches found and turn off the highlighting.
+ if (!parent())
+ frame()->document()->removeMarkers(WebCore::DocumentMarker::TextMatch);
+ frame()->setMarkedTextMatchesAreHighlighted(false);
- frame()->document()->setMarkersActive(range, active);
+ // Let the frame know that we don't want tickmarks or highlighting anymore.
+ InvalidateArea(INVALIDATE_ALL);
}
void WebFrameImpl::scopeStringMatches(int request_id,
@@ -1207,147 +1379,177 @@ void WebFrameImpl::cancelPendingScopingEffort() {
active_match_index_ = -1;
}
-void WebFrameImpl::SetFindEndstateFocusAndSelection() {
- WebFrameImpl* main_frame_impl = GetWebViewImpl()->main_frame();
+void WebFrameImpl::increaseMatchCount(int count, int request_id) {
+ // This function should only be called on the mainframe.
+ DCHECK(!parent());
- if (this == main_frame_impl->active_match_frame() &&
- active_match_.get()) {
- // If the user has set the selection since the match was found, we
- // don't focus anything.
- VisibleSelection selection(frame()->selection()->selection());
- if (!selection.isNone())
- return;
+ total_matchcount_ += count;
- // Try to find the first focusable node up the chain, which will, for
- // example, focus links if we have found text within the link.
- Node* node = active_match_->firstNode();
- while (node && !node->isFocusable() && node != frame()->document())
- node = node->parent();
+ // Update the UI with the latest findings.
+ WebViewDelegate* webview_delegate = GetWebViewImpl()->GetDelegate();
+ DCHECK(webview_delegate);
+ if (webview_delegate)
+ webview_delegate->ReportFindInPageMatchCount(total_matchcount_, request_id,
+ frames_scoping_count_ == 0);
+}
- if (node && node != frame()->document()) {
- // Found a focusable parent node. Set focus to it.
- frame()->document()->setFocusedNode(node);
- } else {
- // Iterate over all the nodes in the range until we find a focusable node.
- // This, for example, sets focus to the first link if you search for
- // text and text that is within one or more links.
- node = active_match_->firstNode();
- while (node && node != active_match_->pastLastNode()) {
- if (node->isFocusable()) {
- frame()->document()->setFocusedNode(node);
- break;
- }
- node = node->traverseNextNode();
- }
- }
+void WebFrameImpl::reportFindInPageSelection(const WebRect& selection_rect,
+ int active_match_ordinal,
+ int request_id) {
+ // Update the UI with the latest selection rect.
+ WebViewDelegate* webview_delegate = GetWebViewImpl()->GetDelegate();
+ DCHECK(webview_delegate);
+ if (webview_delegate) {
+ webview_delegate->ReportFindInPageSelection(
+ request_id,
+ OrdinalOfFirstMatchForFrame(this) + active_match_ordinal,
+ selection_rect);
}
}
-void WebFrameImpl::stopFinding(bool clear_selection) {
- if (!clear_selection)
- SetFindEndstateFocusAndSelection();
- cancelPendingScopingEffort();
-
- // Remove all markers for matches found and turn off the highlighting.
- if (!parent())
- frame()->document()->removeMarkers(WebCore::DocumentMarker::TextMatch);
- frame()->setMarkedTextMatchesAreHighlighted(false);
-
- // Let the frame know that we don't want tickmarks or highlighting anymore.
- InvalidateArea(INVALIDATE_ALL);
+void WebFrameImpl::resetMatchCount() {
+ total_matchcount_ = 0;
+ frames_scoping_count_ = 0;
}
-void WebFrameImpl::selectAll() {
- frame()->selection()->selectAll();
+WebString WebFrameImpl::contentAsText(size_t max_chars) const {
+ if (!frame_)
+ return WebString();
- WebViewDelegate* d = GetWebViewImpl()->GetDelegate();
- if (d)
- d->UserMetricsRecordAction(L"SelectAll");
+ std::wstring text;
+ FrameContentAsPlainText(max_chars, frame_, &text);
+ // TODO(darin): Too many string copies!!!
+ return WideToUTF16Hack(text);
}
-WebRange WebFrameImpl::selectionRange() const {
- return webkit_glue::RangeToWebRange(
- frame()->selection()->toNormalizedRange());
+WebString WebFrameImpl::contentAsMarkup() const {
+ return webkit_glue::StringToWebString(createFullMarkup(frame_->document()));
}
-WebString WebFrameImpl::selectionAsText() const {
- RefPtr<Range> range = frame()->selection()->toNormalizedRange();
- if (!range.get())
- return WebString();
+// WebFrameImpl public ---------------------------------------------------------
- String text = range->text();
-#if defined(OS_WIN)
- WebCore::replaceNewlinesWithWindowsStyleNewlines(text);
-#endif
- WebCore::replaceNBSPWithSpace(text);
- return webkit_glue::StringToWebString(text);
+int WebFrameImpl::live_object_count_ = 0;
+
+WebFrameImpl::WebFrameImpl()
+ : ALLOW_THIS_IN_INITIALIZER_LIST(frame_loader_client_(this)),
+ ALLOW_THIS_IN_INITIALIZER_LIST(scope_matches_factory_(this)),
+ plugin_delegate_(NULL),
+ active_match_frame_(NULL),
+ active_match_index_(-1),
+ locating_active_rect_(false),
+ resume_scoping_from_range_(NULL),
+ last_match_count_(-1),
+ total_matchcount_(-1),
+ frames_scoping_count_(-1),
+ scoping_complete_(false),
+ next_invalidate_after_(0) {
+ StatsCounter(kWebFrameActiveCount).Increment();
+ live_object_count_++;
}
-WebString WebFrameImpl::selectionAsMarkup() const {
- RefPtr<Range> range = frame()->selection()->toNormalizedRange();
- if (!range.get())
- return WebString();
+WebFrameImpl::~WebFrameImpl() {
+ StatsCounter(kWebFrameActiveCount).Decrement();
+ live_object_count_--;
- String markup = WebCore::createMarkup(range.get(), 0);
- return webkit_glue::StringToWebString(markup);
+ cancelPendingScopingEffort();
+ ClearPasswordListeners();
}
-void WebFrameImpl::replaceSelection(const WebString& wtext) {
- String text = webkit_glue::WebStringToString(wtext);
- RefPtr<DocumentFragment> fragment = createFragmentFromText(
- frame()->selection()->toNormalizedRange().get(), text);
- WebCore::applyCommand(WebCore::ReplaceSelectionCommand::create(
- frame()->document(), fragment.get(), false, true, true));
-}
+void WebFrameImpl::InitMainFrame(WebViewImpl* webview_impl) {
+ RefPtr<Frame> frame =
+ Frame::create(webview_impl->page(), 0, &frame_loader_client_);
+ frame_ = frame.get();
-void WebFrameImpl::insertText(const WebString& text) {
- frame()->editor()->insertText(webkit_glue::WebStringToString(text), NULL);
+ // Add reference on behalf of FrameLoader. See comments in
+ // WebFrameLoaderClient::frameLoaderDestroyed for more info.
+ AddRef();
+
+ // We must call init() after frame_ is assigned because it is referenced
+ // during init().
+ frame_->init();
}
-void WebFrameImpl::setMarkedText(
- const WebString& text, unsigned location, unsigned length) {
- WebCore::Editor* editor = frame()->editor();
- WebCore::String str = webkit_glue::WebStringToString(text);
+PassRefPtr<Frame> WebFrameImpl::CreateChildFrame(
+ const FrameLoadRequest& request, HTMLFrameOwnerElement* owner_element) {
+ // TODO(darin): share code with initWithName()
- editor->confirmComposition(str);
+ scoped_refptr<WebFrameImpl> webframe = new WebFrameImpl();
- WTF::Vector<WebCore::CompositionUnderline> decorations;
- editor->setComposition(str, decorations, location, length);
-}
+ // Add an extra ref on behalf of the Frame/FrameLoader, which references the
+ // WebFrame via the FrameLoaderClient interface. See the comment at the top
+ // of this file for more info.
+ webframe->AddRef();
-void WebFrameImpl::unmarkText() {
- frame()->editor()->confirmCompositionWithoutDisturbingSelection();
-}
+ RefPtr<Frame> child_frame = Frame::create(
+ frame_->page(), owner_element, &webframe->frame_loader_client_);
+ webframe->frame_ = child_frame.get();
-bool WebFrameImpl::hasMarkedText() const {
- return frame()->editor()->hasComposition();
-}
+ child_frame->tree()->setName(request.frameName());
-WebRange WebFrameImpl::markedRange() const {
- return webkit_glue::RangeToWebRange(frame()->editor()->compositionRange());
-}
+ frame_->tree()->appendChild(child_frame);
-void WebFrameImpl::enableContinuousSpellChecking(bool enable) {
- if (enable == isContinuousSpellCheckingEnabled())
- return;
- frame()->editor()->toggleContinuousSpellChecking();
-}
+ // Frame::init() can trigger onload event in the parent frame,
+ // which may detach this frame and trigger a null-pointer access
+ // in FrameTree::removeChild. Move init() after appendChild call
+ // so that webframe->frame_ is in the tree before triggering
+ // onload event handler.
+ // Because the event handler may set webframe->frame_ to null,
+ // it is necessary to check the value after calling init() and
+ // return without loading URL.
+ // (b:791612)
+ child_frame->init(); // create an empty document
+ if (!child_frame->tree()->parent())
+ return NULL;
-bool WebFrameImpl::isContinuousSpellCheckingEnabled() const {
- return frame()->editor()->isContinuousSpellCheckingEnabled();
-}
+ frame_->loader()->loadURLIntoChildFrame(
+ request.resourceRequest().url(),
+ request.resourceRequest().httpReferrer(),
+ child_frame.get());
-void WebFrameImpl::clearSelection() {
- frame()->selection()->clear();
+ // A synchronous navigation (about:blank) would have already processed
+ // onload, so it is possible for the frame to have already been destroyed by
+ // script in the page.
+ if (!child_frame->tree()->parent())
+ return NULL;
+
+ return child_frame.release();
}
-bool WebFrameImpl::hasSelection() const {
- // frame()->selection()->isNone() never returns true.
- return (frame()->selection()->start() != frame()->selection()->end());
+void WebFrameImpl::Layout() {
+ // layout this frame
+ FrameView* view = frame_->view();
+ if (view)
+ view->layout();
+
+ // recursively layout child frames
+ Frame* child = frame_->tree()->firstChild();
+ for (; child; child = child->tree()->nextSibling())
+ FromFrame(child)->Layout();
}
-WebString WebFrameImpl::contentAsMarkup() const {
- return webkit_glue::StringToWebString(createFullMarkup(frame_->document()));
+void WebFrameImpl::Paint(skia::PlatformCanvas* canvas, const WebRect& rect) {
+ static StatsRate rendering("WebFramePaintTime");
+ StatsScope<StatsRate> rendering_scope(rendering);
+
+ if (!rect.isEmpty()) {
+ IntRect dirty_rect(webkit_glue::WebRectToIntRect(rect));
+#if defined(OS_MACOSX)
+ CGContextRef context = canvas->getTopPlatformDevice().GetBitmapContext();
+ GraphicsContext gc(context);
+ WebCore::LocalCurrentGraphicsContext localContext(&gc);
+#else
+ PlatformContextSkia context(canvas);
+
+ // PlatformGraphicsContext is actually a pointer to PlatformContextSkia
+ GraphicsContext gc(reinterpret_cast<PlatformGraphicsContext*>(&context));
+#endif
+ if (frame_->document() && frameview()) {
+ frameview()->paint(&gc, dirty_rect);
+ frame_->page()->inspectorController()->drawNodeHighlight(gc);
+ } else {
+ gc.fillRect(dirty_rect, Color::white);
+ }
+ }
}
void WebFrameImpl::CreateFrameView() {
@@ -1412,49 +1614,50 @@ WebViewImpl* WebFrameImpl::GetWebViewImpl() const {
frame_->page()->chrome()->client())->webview();
}
-// WebFrame --------------------------------------------------------------------
-
-void WebFrameImpl::Layout() {
- // layout this frame
- FrameView* view = frame_->view();
- if (view)
- view->layout();
+WebDataSourceImpl* WebFrameImpl::GetDataSourceImpl() const {
+ return static_cast<WebDataSourceImpl*>(dataSource());
+}
- // recursively layout child frames
- Frame* child = frame_->tree()->firstChild();
- for (; child; child = child->tree()->nextSibling())
- FromFrame(child)->Layout();
+WebDataSourceImpl* WebFrameImpl::GetProvisionalDataSourceImpl() const {
+ return static_cast<WebDataSourceImpl*>(provisionalDataSource());
}
-void WebFrameImpl::Paint(skia::PlatformCanvas* canvas, const WebRect& rect) {
- static StatsRate rendering("WebFramePaintTime");
- StatsScope<StatsRate> rendering_scope(rendering);
+void WebFrameImpl::SetFindEndstateFocusAndSelection() {
+ WebFrameImpl* main_frame_impl = GetWebViewImpl()->main_frame();
- if (!rect.isEmpty()) {
- IntRect dirty_rect(webkit_glue::WebRectToIntRect(rect));
-#if defined(OS_MACOSX)
- CGContextRef context = canvas->getTopPlatformDevice().GetBitmapContext();
- GraphicsContext gc(context);
- WebCore::LocalCurrentGraphicsContext localContext(&gc);
-#else
- PlatformContextSkia context(canvas);
+ if (this == main_frame_impl->active_match_frame() &&
+ active_match_.get()) {
+ // If the user has set the selection since the match was found, we
+ // don't focus anything.
+ VisibleSelection selection(frame()->selection()->selection());
+ if (!selection.isNone())
+ return;
- // PlatformGraphicsContext is actually a pointer to PlatformContextSkia
- GraphicsContext gc(reinterpret_cast<PlatformGraphicsContext*>(&context));
-#endif
- if (frame_->document() && frameview()) {
- frameview()->paint(&gc, dirty_rect);
- frame_->page()->inspectorController()->drawNodeHighlight(gc);
+ // Try to find the first focusable node up the chain, which will, for
+ // example, focus links if we have found text within the link.
+ Node* node = active_match_->firstNode();
+ while (node && !node->isFocusable() && node != frame()->document())
+ node = node->parent();
+
+ if (node && node != frame()->document()) {
+ // Found a focusable parent node. Set focus to it.
+ frame()->document()->setFocusedNode(node);
} else {
- gc.fillRect(dirty_rect, Color::white);
+ // Iterate over all the nodes in the range until we find a focusable node.
+ // This, for example, sets focus to the first link if you search for
+ // text and text that is within one or more links.
+ node = active_match_->firstNode();
+ while (node && node != active_match_->pastLastNode()) {
+ if (node->isFocusable()) {
+ frame()->document()->setFocusedNode(node);
+ break;
+ }
+ node = node->traverseNextNode();
+ }
}
}
}
-void WebFrameImpl::Closing() {
- frame_ = NULL;
-}
-
void WebFrameImpl::DidFail(const ResourceError& error, bool was_provisional) {
WebViewImpl* web_view = GetWebViewImpl();
WebViewDelegate* delegate = web_view->delegate();
@@ -1469,357 +1672,154 @@ void WebFrameImpl::DidFail(const ResourceError& error, bool was_provisional) {
}
}
-void WebFrameImpl::dispatchWillSendRequest(WebURLRequest& request) {
- ResourceResponse response;
- frame_->loader()->client()->dispatchWillSendRequest(NULL, 0,
- *webkit_glue::WebURLRequestToMutableResourceRequest(&request),
- response);
+void WebFrameImpl::SetAllowsScrolling(bool flag) {
+ frame_->view()->setCanHaveScrollbars(flag);
}
-void WebFrameImpl::commitDocumentData(const char* data, size_t data_len) {
- DocumentLoader* document_loader = frame_->loader()->documentLoader();
-
- // Set the text encoding. This calls begin() for us. It is safe to call
- // this multiple times (Mac does: page/mac/WebCoreFrameBridge.mm).
- bool user_chosen = true;
- String encoding = document_loader->overrideEncoding();
- if (encoding.isNull()) {
- user_chosen = false;
- encoding = document_loader->response().textEncodingName();
- }
- frame_->loader()->setEncoding(encoding, user_chosen);
-
- // NOTE: mac only does this if there is a document
- frame_->loader()->addData(data, data_len);
+void WebFrameImpl::RegisterPasswordListener(
+ PassRefPtr<WebCore::HTMLInputElement> input_element,
+ webkit_glue::PasswordAutocompleteListener* listener) {
+ RefPtr<WebCore::HTMLInputElement> element = input_element;
+ DCHECK(password_listeners_.find(element) == password_listeners_.end());
+ password_listeners_.set(element, listener);
}
-void WebFrameImpl::executeScript(const WebScriptSource& source) {
- frame_->loader()->executeScript(
- WebCore::ScriptSourceCode(
- webkit_glue::WebStringToString(source.code),
- webkit_glue::WebURLToKURL(source.url),
- source.startLine));
+webkit_glue::PasswordAutocompleteListener* WebFrameImpl::GetPasswordListener(
+ WebCore::HTMLInputElement* input_element) {
+ return password_listeners_.get(input_element);
}
-bool WebFrameImpl::insertStyleText(const WebString& css) {
- Document* document = frame()->document();
- if (!document)
- return false;
- WebCore::Element* document_element = document->documentElement();
- if (!document_element)
- return false;
+// WebFrameImpl protected ------------------------------------------------------
- RefPtr<WebCore::Element> stylesheet = document->createElement(
- WebCore::HTMLNames::styleTag, false);
- ExceptionCode err = 0;
- stylesheet->setTextContent(webkit_glue::WebStringToString(css), err);
- DCHECK(!err) << "Failed to set style element content";
- WebCore::Node* first = document_element->firstChild();
- bool success = document_element->insertBefore(stylesheet, first, err);
- DCHECK(success) << "Failed to insert stylesheet";
- return success;
+void WebFrameImpl::Closing() {
+ frame_ = NULL;
}
-void WebFrameImpl::executeScriptInNewContext(
- const WebScriptSource* sources_in, unsigned num_sources,
- int extension_group) {
- Vector<WebCore::ScriptSourceCode> sources;
+// WebFrameImpl private --------------------------------------------------------
- for (unsigned i = 0; i < num_sources; ++i) {
- sources.append(WebCore::ScriptSourceCode(
- webkit_glue::WebStringToString(sources_in[i].code),
- webkit_glue::WebURLToKURL(sources_in[i].url),
- sources_in[i].startLine));
- }
-
- frame_->script()->evaluateInNewContext(sources, extension_group);
-}
+void WebFrameImpl::InvalidateArea(AreaToInvalidate area) {
+ ASSERT(frame() && frame()->view());
+ FrameView* view = frame()->view();
-void WebFrameImpl::executeScriptInNewWorld(
- const WebScriptSource* sources_in, unsigned num_sources,
- int extension_group) {
- Vector<WebCore::ScriptSourceCode> sources;
+ if ((area & INVALIDATE_ALL) == INVALIDATE_ALL) {
+ view->invalidateRect(view->frameRect());
+ } else {
+ if ((area & INVALIDATE_CONTENT_AREA) == INVALIDATE_CONTENT_AREA) {
+ IntRect content_area(
+ view->x(), view->y(), view->visibleWidth(), view->visibleHeight());
+ view->invalidateRect(content_area);
+ }
- for (unsigned i = 0; i < num_sources; ++i) {
- sources.append(WebCore::ScriptSourceCode(
- webkit_glue::WebStringToString(sources_in[i].code),
- webkit_glue::WebURLToKURL(sources_in[i].url),
- sources_in[i].startLine));
+ if ((area & INVALIDATE_SCROLLBAR) == INVALIDATE_SCROLLBAR) {
+ // Invalidate the vertical scroll bar region for the view.
+ IntRect scroll_bar_vert(
+ view->x() + view->visibleWidth(), view->y(),
+ WebCore::ScrollbarTheme::nativeTheme()->scrollbarThickness(),
+ view->visibleHeight());
+ view->invalidateRect(scroll_bar_vert);
+ }
}
-
- frame_->script()->evaluateInNewWorld(sources, extension_group);
-}
-
-WebString WebFrameImpl::name() const {
- return webkit_glue::StringToWebString(frame_->tree()->name());
-}
-
-bool WebFrameImpl::hasVisibleContent() const {
- return frame()->view()->visibleWidth() > 0 &&
- frame()->view()->visibleHeight() > 0;
}
-PassRefPtr<Frame> WebFrameImpl::CreateChildFrame(
- const FrameLoadRequest& request, HTMLFrameOwnerElement* owner_element) {
- // TODO(darin): share code with initWithName()
-
- scoped_refptr<WebFrameImpl> webframe = new WebFrameImpl();
-
- // Add an extra ref on behalf of the Frame/FrameLoader, which references the
- // WebFrame via the FrameLoaderClient interface. See the comment at the top
- // of this file for more info.
- webframe->AddRef();
-
- RefPtr<Frame> child_frame = Frame::create(
- frame_->page(), owner_element, &webframe->frame_loader_client_);
- webframe->frame_ = child_frame.get();
-
- child_frame->tree()->setName(request.frameName());
-
- frame_->tree()->appendChild(child_frame);
-
- // Frame::init() can trigger onload event in the parent frame,
- // which may detach this frame and trigger a null-pointer access
- // in FrameTree::removeChild. Move init() after appendChild call
- // so that webframe->frame_ is in the tree before triggering
- // onload event handler.
- // Because the event handler may set webframe->frame_ to null,
- // it is necessary to check the value after calling init() and
- // return without loading URL.
- // (b:791612)
- child_frame->init(); // create an empty document
- if (!child_frame->tree()->parent())
- return NULL;
-
- frame_->loader()->loadURLIntoChildFrame(
- request.resourceRequest().url(),
- request.resourceRequest().httpReferrer(),
- child_frame.get());
-
- // A synchronous navigation (about:blank) would have already processed
- // onload, so it is possible for the frame to have already been destroyed by
- // script in the page.
- if (!child_frame->tree()->parent())
- return NULL;
-
- return child_frame.release();
-}
-
-bool WebFrameImpl::executeCommand(const WebString& name) {
- ASSERT(frame());
-
- if (name.length() <= 2)
- return false;
-
- // Since we don't have NSControl, we will convert the format of command
- // string and call the function on Editor directly.
- string16 command = name;
-
- // Make sure the first letter is upper case.
- command.replace(0, 1, 1, toupper(command.at(0)));
+void WebFrameImpl::AddMarker(WebCore::Range* range, bool active_match) {
+ // Use a TextIterator to visit the potentially multiple nodes the range
+ // covers.
+ TextIterator markedText(range);
+ for (; !markedText.atEnd(); markedText.advance()) {
+ RefPtr<Range> textPiece = markedText.range();
+ int exception = 0;
- // Remove the trailing ':' if existing.
- if (command.at(command.length() - 1) == ':')
- command.erase(command.length() - 1, 1);
+ WebCore::DocumentMarker marker = {
+ WebCore::DocumentMarker::TextMatch,
+ textPiece->startOffset(exception),
+ textPiece->endOffset(exception),
+ "",
+ active_match };
- bool rv = true;
+ if (marker.endOffset > marker.startOffset) {
+ // Find the node to add a marker to and add it.
+ Node* node = textPiece->startContainer(exception);
+ frame()->document()->addMarker(node, marker);
- // Specially handling commands that Editor::execCommand does not directly
- // support.
- if (EqualsASCII(command, "DeleteToEndOfParagraph")) {
- WebCore::Editor* editor = frame()->editor();
- if (!editor->deleteWithDirection(WebCore::SelectionController::FORWARD,
- WebCore::ParagraphBoundary,
- true,
- false)) {
- editor->deleteWithDirection(WebCore::SelectionController::FORWARD,
- WebCore::CharacterGranularity,
- true,
- false);
+ // Rendered rects for markers in WebKit are not populated until each time
+ // the markers are painted. However, we need it to happen sooner, because
+ // the whole purpose of tickmarks on the scrollbar is to show where
+ // matches off-screen are (that haven't been painted yet).
+ Vector<WebCore::DocumentMarker> markers =
+ frame()->document()->markersForNode(node);
+ frame()->document()->setRenderedRectForMarker(
+ textPiece->startContainer(exception),
+ markers[markers.size() - 1],
+ range->boundingBox());
}
- } else if (EqualsASCII(command, "Indent")) {
- frame()->editor()->indent();
- } else if (EqualsASCII(command, "Outdent")) {
- frame()->editor()->outdent();
- } else if (EqualsASCII(command, "DeleteBackward")) {
- rv = frame()->editor()->command(AtomicString("BackwardDelete")).execute();
- } else if (EqualsASCII(command, "DeleteForward")) {
- rv = frame()->editor()->command(AtomicString("ForwardDelete")).execute();
- } else {
- rv = frame()->editor()->command(AtomicString(command.c_str())).execute();
}
- return rv;
}
-bool WebFrameImpl::executeCommand(const WebString& name,
- const WebString& value) {
- ASSERT(frame());
- return frame()->editor()->command(webkit_glue::WebStringToString(name)).
- execute(webkit_glue::WebStringToString(value));
-}
+void WebFrameImpl::SetMarkerActive(WebCore::Range* range, bool active) {
+ if (!range)
+ return;
-bool WebFrameImpl::isCommandEnabled(const WebString& name) const {
- ASSERT(frame());
- return frame()->editor()->command(webkit_glue::WebStringToString(name)).
- isEnabled();
+ frame()->document()->setMarkersActive(range, active);
}
-void WebFrameImpl::addMessageToConsole(const WebConsoleMessage& message) {
- ASSERT(frame());
-
- WebCore::MessageLevel webcore_message_level;
- switch (message.level) {
- case WebConsoleMessage::LevelTip:
- webcore_message_level = WebCore::TipMessageLevel;
- break;
- case WebConsoleMessage::LevelLog:
- webcore_message_level = WebCore::LogMessageLevel;
- break;
- case WebConsoleMessage::LevelWarning:
- webcore_message_level = WebCore::WarningMessageLevel;
- break;
- case WebConsoleMessage::LevelError:
- webcore_message_level = WebCore::ErrorMessageLevel;
- break;
- default:
- NOTREACHED();
- return;
+int WebFrameImpl::OrdinalOfFirstMatchForFrame(WebFrameImpl* frame) const {
+ int ordinal = 0;
+ WebViewImpl* web_view = GetWebViewImpl();
+ WebFrameImpl* const main_frame_impl = GetWebViewImpl()->main_frame();
+ // Iterate from the main frame up to (but not including) |frame| and
+ // add up the number of matches found so far.
+ for (WebFrameImpl* it = main_frame_impl;
+ it != frame;
+ it = static_cast<WebFrameImpl*>(
+ web_view->GetNextFrameAfter(it, true))) {
+ if (it->last_match_count_ > 0)
+ ordinal += it->last_match_count_;
}
- frame()->domWindow()->console()->addMessage(
- WebCore::OtherMessageSource, WebCore::LogMessageType,
- webcore_message_level, webkit_glue::WebStringToString(message.text),
- 1, String());
-}
-
-WebSize WebFrameImpl::scrollOffset() const {
- WebCore::FrameView* view = frameview();
- if (view)
- return webkit_glue::IntSizeToWebSize(view->scrollOffset());
-
- return WebSize();
-}
-
-WebSize WebFrameImpl::contentsSize() const {
- return webkit_glue::IntSizeToWebSize(frame()->view()->contentsSize());
-}
-
-WebFrame* WebFrameImpl::firstChild() const {
- return FromFrame(frame()->tree()->firstChild());
-}
-
-WebFrame* WebFrameImpl::lastChild() const {
- return FromFrame(frame()->tree()->lastChild());
-}
-
-WebFrame* WebFrameImpl::nextSibling() const {
- return FromFrame(frame()->tree()->nextSibling());
-}
-
-WebFrame* WebFrameImpl::previousSibling() const {
- return FromFrame(frame()->tree()->previousSibling());
-}
-
-WebFrame* WebFrameImpl::traverseNext(bool wrap) const {
- return FromFrame(frame()->tree()->traverseNextWithWrap(wrap));
-}
-
-WebFrame* WebFrameImpl::traversePrevious(bool wrap) const {
- return FromFrame(frame()->tree()->traversePreviousWithWrap(wrap));
-}
-
-WebFrame* WebFrameImpl::findChildByName(const WebKit::WebString& name) const {
- return FromFrame(frame()->tree()->child(
- webkit_glue::WebStringToString(name)));
-}
-
-WebFrame* WebFrameImpl::findChildByExpression(
- const WebKit::WebString& xpath) const {
- if (xpath.isEmpty())
- return NULL;
-
- Document* document = frame_->document();
-
- ExceptionCode ec = 0;
- PassRefPtr<XPathResult> xpath_result =
- document->evaluate(webkit_glue::WebStringToString(xpath),
- document,
- NULL, /* namespace */
- XPathResult::ORDERED_NODE_ITERATOR_TYPE,
- NULL, /* XPathResult object */
- ec);
- if (!xpath_result.get())
- return NULL;
-
- Node* node = xpath_result->iterateNext(ec);
-
- if (!node || !node->isFrameOwnerElement())
- return NULL;
- HTMLFrameOwnerElement* frame_element =
- static_cast<HTMLFrameOwnerElement*>(node);
- return FromFrame(frame_element->contentFrame());
+ return ordinal;
}
-void WebFrameImpl::SetAllowsScrolling(bool flag) {
- frame_->view()->setCanHaveScrollbars(flag);
-}
+bool WebFrameImpl::ShouldScopeMatches(const string16& search_text) {
+ // Don't scope if we can't find a frame or if the frame is not visible.
+ // The user may have closed the tab/application, so abort.
+ if (!frame() || !hasVisibleContent())
+ return false;
-int WebFrameImpl::printBegin(const WebSize& page_size) {
- DCHECK_EQ(frame()->document()->isFrameSet(), false);
+ DCHECK(frame()->document() && frame()->view());
- print_context_.reset(new ChromePrintContext(frame()));
- WebCore::FloatRect rect(0, 0,
- static_cast<float>(page_size.width),
- static_cast<float>(page_size.height));
- print_context_->begin(rect.width());
- float page_height;
- // We ignore the overlays calculation for now since they are generated in the
- // browser. page_height is actually an output parameter.
- print_context_->computePageRects(rect, 0, 0, 1.0, page_height);
- return print_context_->pageCount();
-}
+ // If the frame completed the scoping operation and found 0 matches the last
+ // time it was searched, then we don't have to search it again if the user is
+ // just adding to the search string or sending the same search string again.
+ if (scoping_complete_ &&
+ !last_search_string_.empty() && last_match_count_ == 0) {
+ // Check to see if the search string prefixes match.
+ string16 previous_search_prefix =
+ search_text.substr(0, last_search_string_.length());
-float WebFrameImpl::printPage(int page, WebCanvas* canvas) {
- // Ensure correct state.
- if (!print_context_.get() || page < 0 || !frame() || !frame()->document()) {
- NOTREACHED();
- return 0;
+ if (previous_search_prefix == last_search_string_) {
+ return false; // Don't search this frame, it will be fruitless.
+ }
}
-#if defined(OS_WIN) || defined(OS_LINUX)
- PlatformContextSkia context(canvas);
- GraphicsContext spool(&context);
-#elif defined(OS_MACOSX)
- CGContextRef context = canvas->beginPlatformPaint();
- GraphicsContext spool(context);
- WebCore::LocalCurrentGraphicsContext localContext(&spool);
-#endif
-
- return print_context_->spoolPage(spool, page);
-}
-
-void WebFrameImpl::printEnd() {
- DCHECK(print_context_.get());
- if (print_context_.get())
- print_context_->end();
- print_context_.reset(NULL);
-}
-
-unsigned WebFrameImpl::unloadListenerCount() const {
- return frame()->domWindow()->pendingUnloadEventListeners();
+ return true;
}
-void WebFrameImpl::RegisterPasswordListener(
- PassRefPtr<WebCore::HTMLInputElement> input_element,
- webkit_glue::PasswordAutocompleteListener* listener) {
- RefPtr<WebCore::HTMLInputElement> element = input_element;
- DCHECK(password_listeners_.find(element) == password_listeners_.end());
- password_listeners_.set(element, listener);
-}
+void WebFrameImpl::InvalidateIfNecessary() {
+ if (last_match_count_ > next_invalidate_after_) {
+ // TODO(finnur): (http://b/1088165) Optimize the drawing of the
+ // tickmarks and remove this. This calculation sets a milestone for when
+ // next to invalidate the scrollbar and the content area. We do this so that
+ // we don't spend too much time drawing the scrollbar over and over again.
+ // Basically, up until the first 500 matches there is no throttle. After the
+ // first 500 matches, we set set the milestone further and further out (750,
+ // 1125, 1688, 2K, 3K).
+ static const int start_slowing_down_after = 500;
+ static const int slowdown = 750;
+ int i = (last_match_count_ / start_slowing_down_after);
+ next_invalidate_after_ += i * slowdown;
-webkit_glue::PasswordAutocompleteListener* WebFrameImpl::GetPasswordListener(
- WebCore::HTMLInputElement* input_element) {
- return password_listeners_.get(input_element);
+ InvalidateArea(INVALIDATE_SCROLLBAR);
+ }
}
void WebFrameImpl::ClearPasswordListeners() {
diff --git a/webkit/glue/webframe_impl.h b/webkit/glue/webframe_impl.h
index 0749a61..db30142 100644
--- a/webkit/glue/webframe_impl.h
+++ b/webkit/glue/webframe_impl.h
@@ -64,16 +64,6 @@ struct WindowFeatures;
class WebFrameImpl : public WebKit::WebFrame,
public base::RefCounted<WebFrameImpl> {
public:
- WebFrameImpl();
- ~WebFrameImpl();
-
- static int live_object_count() {
- return live_object_count_;
- }
-
- // Called by the WebViewImpl to initialize its main frame:
- void InitMainFrame(WebViewImpl* webview_impl);
-
// WebFrame methods:
virtual WebKit::WebString name() const;
virtual WebKit::WebURL url() const;
@@ -175,11 +165,20 @@ class WebFrameImpl : public WebKit::WebFrame,
virtual WebKit::WebString contentAsText(size_t max_chars) const;
virtual WebKit::WebString contentAsMarkup() const;
+ WebFrameImpl();
+ ~WebFrameImpl();
+
+ static int live_object_count() {
+ return live_object_count_;
+ }
+
+ // Called by the WebViewImpl to initialize its main frame:
+ void InitMainFrame(WebViewImpl* webview_impl);
+
PassRefPtr<WebCore::Frame> CreateChildFrame(
const WebCore::FrameLoadRequest&,
WebCore::HTMLFrameOwnerElement* owner_element);
- // WebFrameImpl
void Layout();
void Paint(skia::PlatformCanvas* canvas, const WebKit::WebRect& rect);
@@ -352,9 +351,6 @@ class WebFrameImpl : public WebKit::WebFrame,
// was searched.
bool ShouldScopeMatches(const string16& search_text);
- // Only for test_shell
- int PendingFrameUnloadEventCount() const;
-
// Determines whether to invalidate the content area and scrollbar.
void InvalidateIfNecessary();
@@ -363,11 +359,6 @@ class WebFrameImpl : public WebKit::WebFrame,
void LoadJavaScriptURL(const WebCore::KURL& url);
- // Callback function for download of alternate error pages. If the server is
- // down or we take too long to download the page, |html| will be empty.
- void AltErrorPageFinished(const GURL& unreachable_url,
- const std::string& html);
-
// Valid between calls to BeginPrint() and EndPrint(). Containts the print
// information. Is used by PrintPage().
scoped_ptr<ChromePrintContext> print_context_;