diff options
Diffstat (limited to 'WebKit/chromium/src/WebFrameImpl.cpp')
| -rw-r--r-- | WebKit/chromium/src/WebFrameImpl.cpp | 372 |
1 files changed, 281 insertions, 91 deletions
diff --git a/WebKit/chromium/src/WebFrameImpl.cpp b/WebKit/chromium/src/WebFrameImpl.cpp index 2f911f1..f1c30e2 100644 --- a/WebKit/chromium/src/WebFrameImpl.cpp +++ b/WebKit/chromium/src/WebFrameImpl.cpp @@ -75,21 +75,20 @@ #include "ChromiumBridge.h" #include "ClipboardUtilitiesChromium.h" #include "Console.h" +#include "DOMUtilitiesPrivate.h" +#include "DOMWindow.h" #include "Document.h" #include "DocumentFragment.h" // Only needed for ReplaceSelectionCommand.h :( #include "DocumentLoader.h" #include "DocumentMarker.h" -#include "DOMUtilitiesPrivate.h" -#include "DOMWindow.h" #include "Editor.h" #include "EventHandler.h" #include "FormState.h" -#include "FrameLoader.h" #include "FrameLoadRequest.h" +#include "FrameLoader.h" #include "FrameTree.h" #include "FrameView.h" #include "GraphicsContext.h" -#include "HistoryItem.h" #include "HTMLCollection.h" #include "HTMLFormElement.h" #include "HTMLFrameOwnerElement.h" @@ -97,10 +96,11 @@ #include "HTMLInputElement.h" #include "HTMLLinkElement.h" #include "HTMLNames.h" +#include "HistoryItem.h" #include "InspectorController.h" -#include "markup.h" #include "Page.h" #include "PlatformContextSkia.h" +#include "PluginDocument.h" #include "PrintContext.h" #include "RenderFrame.h" #include "RenderTreeAsText.h" @@ -112,8 +112,8 @@ #include "ScriptController.h" #include "ScriptSourceCode.h" #include "ScriptValue.h" -#include "ScrollbarTheme.h" #include "ScrollTypes.h" +#include "ScrollbarTheme.h" #include "SelectionController.h" #include "Settings.h" #include "SkiaUtils.h" @@ -130,6 +130,8 @@ #include "WebHistoryItem.h" #include "WebInputElement.h" #include "WebPasswordAutocompleteListener.h" +#include "WebPlugin.h" +#include "WebPluginContainerImpl.h" #include "WebRange.h" #include "WebRect.h" #include "WebScriptSource.h" @@ -139,6 +141,7 @@ #include "WebVector.h" #include "WebViewImpl.h" #include "XPathResult.h" +#include "markup.h" #include <algorithm> #include <wtf/CurrentTime.h> @@ -246,7 +249,18 @@ static void frameContentAsPlainText(size_t maxChars, Frame* frame, } } -// Simple class to override some of PrintContext behavior. +WebPluginContainerImpl* WebFrameImpl::pluginContainerFromFrame(Frame* frame) +{ + if (!frame) + return 0; + if (!frame->document() || !frame->document()->isPluginDocument()) + return 0; + PluginDocument* pluginDocument = static_cast<PluginDocument*>(frame->document()); + return static_cast<WebPluginContainerImpl *>(pluginDocument->pluginWidget()); +} + +// Simple class to override some of PrintContext behavior. Some of the methods +// made virtual so that they can be overriden by ChromePluginPrintContext. class ChromePrintContext : public PrintContext, public Noncopyable { public: ChromePrintContext(Frame* frame) @@ -255,28 +269,38 @@ public: { } - void begin(float width) + virtual void begin(float width) { ASSERT(!m_printedPageWidth); m_printedPageWidth = width; PrintContext::begin(m_printedPageWidth); } - float getPageShrink(int pageNumber) const + virtual void end() + { + PrintContext::end(); + } + + virtual float getPageShrink(int pageNumber) const { IntRect pageRect = m_pageRects[pageNumber]; return m_printedPageWidth / pageRect.width(); } - // Spools the printed page, a subrect of m_frame. Skip the scale step. + // Spools the printed page, a subrect of m_frame. Skip the scale step. // NativeTheme doesn't play well with scaling. Scaling is done browser side - // instead. Returns the scale to be applied. - float spoolPage(GraphicsContext& ctx, int pageNumber) + // instead. Returns the scale to be applied. + // On Linux, we don't have the problem with NativeTheme, hence we let WebKit + // do the scaling and ignore the return value. + virtual float spoolPage(GraphicsContext& ctx, int pageNumber) { IntRect pageRect = m_pageRects[pageNumber]; float scale = m_printedPageWidth / pageRect.width(); ctx.save(); +#if OS(LINUX) + ctx.scale(WebCore::FloatSize(scale, scale)); +#endif ctx.translate(static_cast<float>(-pageRect.x()), static_cast<float>(-pageRect.y())); ctx.clip(pageRect); @@ -285,11 +309,95 @@ public: return scale; } + virtual void computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight) + { + return PrintContext::computePageRects(printRect, headerHeight, footerHeight, userScaleFactor, outPageHeight); + } + + virtual int pageCount() const + { + return PrintContext::pageCount(); + } + + virtual bool shouldUseBrowserOverlays() const + { + return true; + } + private: // Set when printing. float m_printedPageWidth; }; +// Simple class to override some of PrintContext behavior. This is used when +// the frame hosts a plugin that supports custom printing. In this case, we +// want to delegate all printing related calls to the plugin. +class ChromePluginPrintContext : public ChromePrintContext { +public: + ChromePluginPrintContext(Frame* frame, int printerDPI) + : ChromePrintContext(frame), m_pageCount(0), m_printerDPI(printerDPI) + { + // This HAS to be a frame hosting a full-mode plugin + ASSERT(frame->document()->isPluginDocument()); + } + + virtual void begin(float width) + { + } + + virtual void end() + { + WebPluginContainerImpl* pluginContainer = WebFrameImpl::pluginContainerFromFrame(m_frame); + if (pluginContainer && pluginContainer->supportsPaginatedPrint()) + pluginContainer->printEnd(); + else + ASSERT_NOT_REACHED(); + } + + virtual float getPageShrink(int pageNumber) const + { + // We don't shrink the page (maybe we should ask the widget ??) + return 1.0; + } + + virtual void computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight) + { + WebPluginContainerImpl* pluginContainer = WebFrameImpl::pluginContainerFromFrame(m_frame); + if (pluginContainer && pluginContainer->supportsPaginatedPrint()) + m_pageCount = pluginContainer->printBegin(IntRect(printRect), m_printerDPI); + else + ASSERT_NOT_REACHED(); + } + + virtual int pageCount() const + { + return m_pageCount; + } + + // Spools the printed page, a subrect of m_frame. Skip the scale step. + // NativeTheme doesn't play well with scaling. Scaling is done browser side + // instead. Returns the scale to be applied. + virtual float spoolPage(GraphicsContext& ctx, int pageNumber) + { + WebPluginContainerImpl* pluginContainer = WebFrameImpl::pluginContainerFromFrame(m_frame); + if (pluginContainer && pluginContainer->supportsPaginatedPrint()) + pluginContainer->printPage(pageNumber, &ctx); + else + ASSERT_NOT_REACHED(); + return 1.0; + } + + virtual bool shouldUseBrowserOverlays() const + { + return false; + } + +private: + // Set when printing. + int m_pageCount; + int m_printerDPI; +}; + static WebDataSource* DataSourceForDocLoader(DocumentLoader* loader) { return loader ? WebDataSourceImpl::fromDocumentLoader(loader) : 0; @@ -363,9 +471,9 @@ WebString WebFrameImpl::name() const return m_frame->tree()->name(); } -void WebFrameImpl::clearName() +void WebFrameImpl::setName(const WebString& name) { - m_frame->tree()->clearName(); + m_frame->tree()->setName(name); } WebURL WebFrameImpl::url() const @@ -413,7 +521,7 @@ WebURL WebFrameImpl::openSearchDescriptionURL() const WebString WebFrameImpl::encoding() const { - return frame()->loader()->encoding(); + return frame()->loader()->writer()->encoding(); } WebSize WebFrameImpl::scrollOffset() const @@ -553,13 +661,18 @@ void WebFrameImpl::forms(WebVector<WebFormElement>& results) const return; RefPtr<HTMLCollection> forms = m_frame->document()->forms(); - size_t formCount = forms->length(); + size_t formCount = 0; + for (size_t i = 0; i < forms->length(); ++i) { + Node* node = forms->item(i); + if (node && node->isHTMLElement()) + ++formCount; + } WebVector<WebFormElement> temp(formCount); for (size_t i = 0; i < formCount; ++i) { Node* node = forms->item(i); // Strange but true, sometimes item can be 0. - if (node) + if (node && node->isHTMLElement()) temp[i] = static_cast<HTMLFormElement*>(node); } results.swap(temp); @@ -596,7 +709,7 @@ NPObject* WebFrameImpl::windowObject() const void WebFrameImpl::bindToWindowObject(const WebString& name, NPObject* object) { ASSERT(m_frame); - if (!m_frame || !m_frame->script()->canExecuteScripts()) + if (!m_frame || !m_frame->script()->canExecuteScripts(NotAboutToExecuteScript)) return; String key = name; @@ -670,6 +783,13 @@ void WebFrameImpl::collectGarbage() } #if USE(V8) +v8::Handle<v8::Value> WebFrameImpl::executeScriptAndReturnValue( + const WebScriptSource& source) +{ + return m_frame->script()->executeScript( + ScriptSourceCode(source.code, source.url, source.startLine)).v8Value(); +} + // Returns the V8 context for this frame, or an empty handle if there is none. v8::Local<v8::Context> WebFrameImpl::mainWorldScriptContext() const { @@ -713,12 +833,10 @@ bool WebFrameImpl::insertStyleText( return success; } -void WebFrameImpl::reload() +void WebFrameImpl::reload(bool ignoreCache) { m_frame->loader()->history()->saveDocumentAndScrollState(); - - stopLoading(); // Make sure existing activity stops. - m_frame->loader()->reload(); + m_frame->loader()->reload(ignoreCache); } void WebFrameImpl::loadRequest(const WebURLRequest& request) @@ -731,7 +849,6 @@ void WebFrameImpl::loadRequest(const WebURLRequest& request) return; } - stopLoading(); // Make sure existing activity stops. m_frame->loader()->load(resourceRequest, false); } @@ -740,8 +857,6 @@ void WebFrameImpl::loadHistoryItem(const WebHistoryItem& item) RefPtr<HistoryItem> historyItem = PassRefPtr<HistoryItem>(item); ASSERT(historyItem.get()); - stopLoading(); // Make sure existing activity stops. - // If there is no currentItem, 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. @@ -778,8 +893,6 @@ void WebFrameImpl::loadData(const WebData& data, request = m_frame->loader()->originalRequest(); request.setURL(baseURL); - stopLoading(); // Make sure existing activity stops. - m_frame->loader()->load(request, substData, false); if (replace) { // Do this to force WebKit to treat the load as replacing the currently @@ -847,7 +960,12 @@ WebHistoryItem WebFrameImpl::previousHistoryItem() const WebHistoryItem WebFrameImpl::currentHistoryItem() const { - m_frame->loader()->history()->saveDocumentAndScrollState(); + // If we are still loading, then we don't want to clobber the current + // history item as this could cause us to lose the scroll position and + // document state. However, it is OK for new navigations. + if (m_frame->loader()->loadType() == FrameLoadTypeStandard + || !m_frame->loader()->activeDocumentLoader()->isLoadingInAPISense()) + m_frame->loader()->history()->saveDocumentAndScrollState(); return WebHistoryItem(m_frame->page()->backForwardList()->currentItem()); } @@ -897,7 +1015,7 @@ void WebFrameImpl::commitDocumentData(const char* data, size_t dataLen) userChosen = false; encoding = documentLoader->response().textEncodingName(); } - m_frame->loader()->setEncoding(encoding, userChosen); + m_frame->loader()->writer()->setEncoding(encoding, userChosen); // NOTE: mac only does this if there is a document m_frame->loader()->addData(data, dataLen); @@ -975,17 +1093,25 @@ bool WebFrameImpl::executeCommand(const WebString& name) if (command[command.length() - 1] == UChar(':')) command = command.substring(0, command.length() - 1); + if (command == "Copy") { + WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame()); + if (pluginContainer) { + pluginContainer->copy(); + return true; + } + } + bool rv = true; // Specially handling commands that Editor::execCommand does not directly // support. if (command == "DeleteToEndOfParagraph") { Editor* editor = frame()->editor(); - if (!editor->deleteWithDirection(SelectionController::FORWARD, + if (!editor->deleteWithDirection(SelectionController::DirectionForward, ParagraphBoundary, true, false)) { - editor->deleteWithDirection(SelectionController::FORWARD, + editor->deleteWithDirection(SelectionController::DirectionForward, CharacterGranularity, true, false); @@ -1045,6 +1171,10 @@ bool WebFrameImpl::isContinuousSpellCheckingEnabled() const bool WebFrameImpl::hasSelection() const { + WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame()); + if (pluginContainer) + return pluginContainer->plugin()->hasSelection(); + // frame()->selection()->isNone() never returns true. return (frame()->selection()->start() != frame()->selection()->end()); } @@ -1056,6 +1186,10 @@ WebRange WebFrameImpl::selectionRange() const WebString WebFrameImpl::selectionAsText() const { + WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame()); + if (pluginContainer) + return pluginContainer->plugin()->selectionAsText(); + RefPtr<Range> range = frame()->selection()->toNormalizedRange(); if (!range.get()) return WebString(); @@ -1070,6 +1204,10 @@ WebString WebFrameImpl::selectionAsText() const WebString WebFrameImpl::selectionAsMarkup() const { + WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame()); + if (pluginContainer) + return pluginContainer->plugin()->selectionAsMarkup(); + RefPtr<Range> range = frame()->selection()->toNormalizedRange(); if (!range.get()) return WebString(); @@ -1082,11 +1220,10 @@ void WebFrameImpl::selectWordAroundPosition(Frame* frame, VisiblePosition pos) VisibleSelection selection(pos); selection.expandUsingGranularity(WordGranularity); - if (selection.isRange()) - frame->setSelectionGranularity(WordGranularity); - - if (frame->shouldChangeSelection(selection)) - frame->selection()->setSelection(selection); + if (frame->shouldChangeSelection(selection)) { + TextGranularity granularity = selection.isRange() ? WordGranularity : CharacterGranularity; + frame->selection()->setSelection(selection, granularity); + } } bool WebFrameImpl::selectWordAroundCaret() @@ -1099,11 +1236,17 @@ bool WebFrameImpl::selectWordAroundCaret() return true; } -int WebFrameImpl::printBegin(const WebSize& pageSize) +int WebFrameImpl::printBegin(const WebSize& pageSize, int printerDPI, bool *useBrowserOverlays) { ASSERT(!frame()->document()->isFrameSet()); + // If this is a plugin document, check if the plugin supports its own + // printing. If it does, we will delegate all printing to that. + WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame()); + if (pluginContainer && pluginContainer->supportsPaginatedPrint()) + m_printContext.set(new ChromePluginPrintContext(frame(), printerDPI)); + else + m_printContext.set(new ChromePrintContext(frame())); - m_printContext.set(new ChromePrintContext(frame())); FloatRect rect(0, 0, static_cast<float>(pageSize.width), static_cast<float>(pageSize.height)); m_printContext->begin(rect.width()); @@ -1111,6 +1254,9 @@ int WebFrameImpl::printBegin(const WebSize& pageSize) // We ignore the overlays calculation for now since they are generated in the // browser. pageHeight is actually an output parameter. m_printContext->computePageRects(rect, 0, 0, 1.0, pageHeight); + if (useBrowserOverlays) + *useBrowserOverlays = m_printContext->shouldUseBrowserOverlays(); + return m_printContext->pageCount(); } @@ -1133,7 +1279,7 @@ float WebFrameImpl::printPage(int page, WebCanvas* canvas) return 0; } -#if OS(WINDOWS) || OS(LINUX) || OS(FREEBSD) +#if OS(WINDOWS) || OS(LINUX) || OS(FREEBSD) || OS(SOLARIS) PlatformContextSkia context(canvas); GraphicsContext spool(&context); #elif OS(DARWIN) @@ -1152,6 +1298,28 @@ void WebFrameImpl::printEnd() m_printContext.clear(); } +bool WebFrameImpl::isPageBoxVisible(int pageIndex) +{ + return frame()->document()->isPageBoxVisible(pageIndex); +} + +void WebFrameImpl::pageSizeAndMarginsInPixels(int pageIndex, + WebSize& pageSize, + int& marginTop, + int& marginRight, + int& marginBottom, + int& marginLeft) +{ + IntSize size(pageSize.width, pageSize.height); + frame()->document()->pageSizeAndMarginsInPixels(pageIndex, + size, + marginTop, + marginRight, + marginBottom, + marginLeft); + pageSize = size; +} + bool WebFrameImpl::find(int identifier, const WebString& searchText, const WebFindOptions& options, @@ -1163,7 +1331,7 @@ bool WebFrameImpl::find(int identifier, if (!options.findNext) frame()->page()->unmarkAllTextMatches(); else - setMarkerActive(m_activeMatch.get(), false); // Active match is changing. + setMarkerActive(m_activeMatch.get(), false); // Active match is changing. // Starts the search from the current selection. bool startInSelection = true; @@ -1203,11 +1371,14 @@ bool WebFrameImpl::find(int identifier, else { m_activeMatch = newSelection.toNormalizedRange(); currSelectionRect = m_activeMatch->boundingBox(); - setMarkerActive(m_activeMatch.get(), true); // Active. + setMarkerActive(m_activeMatch.get(), true); // Active. // WebKit draws the highlighting for all matches. executeCommand(WebString::fromUTF8("Unselect")); } + // Make sure no node is focused. See http://crbug.com/38700. + frame()->document()->setFocusedNode(0); + if (!options.findNext || activeSelection) { // This is either a Find operation or a Find-next from a new start point // due to a selection, so we set the flag to ask the scoping effort @@ -1295,7 +1466,7 @@ void WebFrameImpl::scopeStringMatches(int identifier, identifier, searchText, options, - false); // false=we just reset, so don't do it again. + false); // false=we just reset, so don't do it again. return; } @@ -1309,7 +1480,7 @@ void WebFrameImpl::scopeStringMatches(int identifier, m_resumeScopingFromRange->startOffset(ec2) + 1, ec); if (ec || ec2) { - if (ec2) // A non-zero |ec| happens when navigating during search. + if (ec2) // A non-zero |ec| happens when navigating during search. ASSERT_NOT_REACHED(); return; } @@ -1318,7 +1489,7 @@ void WebFrameImpl::scopeStringMatches(int identifier, // This timeout controls how long we scope before releasing control. This // value does not prevent us from running for longer than this, but it is // periodically checked to see if we have exceeded our allocated time. - const double maxScopingDuration = 0.1; // seconds + const double maxScopingDuration = 0.1; // seconds int matchCount = 0; bool timedOut = false; @@ -1425,8 +1596,8 @@ void WebFrameImpl::scopeStringMatches(int identifier, identifier, searchText, options, - false); // don't reset. - return; // Done for now, resume work later. + false); // don't reset. + return; // Done for now, resume work later. } // This frame has no further scoping left, so it is done. Other frames might, @@ -1478,14 +1649,6 @@ void WebFrameImpl::resetMatchCount() m_framesScopingCount = 0; } -WebURL WebFrameImpl::completeURL(const WebString& url) const -{ - if (!m_frame || !m_frame->document()) - return WebURL(); - - return m_frame->document()->completeURL(url); -} - WebString WebFrameImpl::contentAsText(size_t maxChars) const { if (!m_frame) @@ -1533,6 +1696,14 @@ int WebFrameImpl::pageNumberForElementById(const WebString& id, return PrintContext::pageNumberForElement(element, pageSize); } +WebRect WebFrameImpl::selectionBoundsRect() const +{ + if (hasSelection()) + return IntRect(frame()->selectionBounds(false)); + + return WebRect(); +} + // WebFrameImpl public --------------------------------------------------------- PassRefPtr<WebFrameImpl> WebFrameImpl::create(WebFrameClient* client) @@ -1608,7 +1779,7 @@ PassRefPtr<Frame> WebFrameImpl::createChildFrame( // it is necessary to check the value after calling init() and // return without loading URL. // (b:791612) - childFrame->init(); // create an empty document + childFrame->init(); // create an empty document if (!childFrame->tree()->parent()) return 0; @@ -1634,11 +1805,23 @@ void WebFrameImpl::layout() view->layoutIfNeededRecursive(); } +void WebFrameImpl::paintWithContext(GraphicsContext& gc, const WebRect& rect) +{ + IntRect dirtyRect(rect); + gc.save(); + if (m_frame->document() && frameView()) { + gc.clip(dirtyRect); + frameView()->paint(&gc, dirtyRect); + m_frame->page()->inspectorController()->drawNodeHighlight(gc); + } else + gc.fillRect(dirtyRect, Color::white, DeviceColorSpace); + gc.restore(); +} + void WebFrameImpl::paint(WebCanvas* canvas, const WebRect& rect) { if (rect.isEmpty()) return; - IntRect dirtyRect(rect); #if WEBKIT_USING_CG GraphicsContext gc(canvas); LocalCurrentGraphicsContext localContext(&gc); @@ -1650,14 +1833,7 @@ void WebFrameImpl::paint(WebCanvas* canvas, const WebRect& rect) #else notImplemented(); #endif - gc.save(); - if (m_frame->document() && frameView()) { - gc.clip(dirtyRect); - frameView()->paint(&gc, dirtyRect); - m_frame->page()->inspectorController()->drawNodeHighlight(gc); - } else - gc.fillRect(dirtyRect, Color::white, DeviceColorSpace); - gc.restore(); + paintWithContext(gc, rect); } void WebFrameImpl::createFrameView() @@ -1719,7 +1895,7 @@ WebFrameImpl* WebFrameImpl::fromFrameOwnerElement(Element* element) static_cast<HTMLFrameOwnerElement*>(element); return fromFrame(frameElement->contentFrame()); } - + WebViewImpl* WebFrameImpl::viewImpl() const { if (!m_frame) @@ -1794,24 +1970,38 @@ void WebFrameImpl::didFail(const ResourceError& error, bool wasProvisional) client()->didFailLoad(this, webError); } -void WebFrameImpl::setAllowsScrolling(bool flag) +void WebFrameImpl::setCanHaveScrollbars(bool canHaveScrollbars) { - m_frame->view()->setCanHaveScrollbars(flag); + m_frame->view()->setCanHaveScrollbars(canHaveScrollbars); } -void WebFrameImpl::registerPasswordListener( +bool WebFrameImpl::registerPasswordListener( WebInputElement inputElement, WebPasswordAutocompleteListener* listener) { - RefPtr<HTMLInputElement> element = inputElement.operator PassRefPtr<HTMLInputElement>(); - ASSERT(m_passwordListeners.find(element) == m_passwordListeners.end()); - m_passwordListeners.set(element, listener); + RefPtr<HTMLInputElement> element(inputElement.unwrap<HTMLInputElement>()); + if (!m_passwordListeners.add(element, listener).second) { + delete listener; + return false; + } + return true; +} + +void WebFrameImpl::notifiyPasswordListenerOfAutocomplete( + const WebInputElement& inputElement) +{ + const HTMLInputElement* element = inputElement.constUnwrap<HTMLInputElement>(); + WebPasswordAutocompleteListener* listener = getPasswordListener(element); + // Password listeners need to autocomplete other fields that depend on the + // input element with autofill suggestions. + if (listener) + listener->performInlineAutocomplete(element->value(), false, false); } WebPasswordAutocompleteListener* WebFrameImpl::getPasswordListener( - HTMLInputElement* inputElement) + const HTMLInputElement* inputElement) { - return m_passwordListeners.get(RefPtr<HTMLInputElement>(inputElement)); + return m_passwordListeners.get(RefPtr<HTMLInputElement>(const_cast<HTMLInputElement*>(inputElement))); } // WebFrameImpl private -------------------------------------------------------- @@ -1832,6 +2022,8 @@ void WebFrameImpl::invalidateArea(AreaToInvalidate area) if ((area & InvalidateContentArea) == InvalidateContentArea) { IntRect contentArea( view->x(), view->y(), view->visibleWidth(), view->visibleHeight()); + IntRect frameRect = view->frameRect(); + contentArea.move(-frameRect.topLeft().x(), -frameRect.topLeft().y()); view->invalidateRect(contentArea); } @@ -1841,6 +2033,8 @@ void WebFrameImpl::invalidateArea(AreaToInvalidate area) view->x() + view->visibleWidth(), view->y(), ScrollbarTheme::nativeTheme()->scrollbarThickness(), view->visibleHeight()); + IntRect frameRect = view->frameRect(); + scrollBarVert.move(-frameRect.topLeft().x(), -frameRect.topLeft().y()); view->invalidateRect(scrollBarVert); } } @@ -1883,7 +2077,8 @@ void WebFrameImpl::addMarker(Range* range, bool activeMatch) void WebFrameImpl::setMarkerActive(Range* range, bool active) { - if (!range) + WebCore::ExceptionCode ec; + if (!range || range->collapsed(ec)) return; frame()->document()->setMarkersActive(range, active); @@ -1906,9 +2101,9 @@ int WebFrameImpl::ordinalOfFirstMatchForFrame(WebFrameImpl* frame) const bool WebFrameImpl::shouldScopeMatches(const String& searchText) { - // Don't scope if we can't find a frame or if the frame is not visible. + // Don't scope if we can't find a frame or a view or if the frame is not visible. // The user may have closed the tab/application, so abort. - if (!frame() || !hasVisibleContent()) + if (!frame() || !frame()->view() || !hasVisibleContent()) return false; ASSERT(frame()->document() && frame()->view()); @@ -1922,7 +2117,7 @@ bool WebFrameImpl::shouldScopeMatches(const String& searchText) searchText.substring(0, m_lastSearchString.length()); if (previousSearchPrefix == m_lastSearchString) - return false; // Don't search this frame, it will be fruitless. + return false; // Don't search this frame, it will be fruitless. } return true; @@ -1974,12 +2169,13 @@ void WebFrameImpl::clearPasswordListeners() void WebFrameImpl::loadJavaScriptURL(const KURL& url) { - // This is copied from FrameLoader::executeIfJavaScriptURL. Unfortunately, - // we cannot just use that method since it is private, and it also doesn't - // quite behave as we require it to for bookmarklets. The key difference is - // that we need to suppress loading the string result from evaluating the JS - // URL if executing the JS URL resulted in a location change. We also allow - // a JS URL to be loaded even if scripts on the page are otherwise disabled. + // This is copied from ScriptController::executeIfJavaScriptURL. + // Unfortunately, we cannot just use that method since it is private, and + // it also doesn't quite behave as we require it to for bookmarklets. The + // key difference is that we need to suppress loading the string result + // from evaluating the JS URL if executing the JS URL resulted in a + // location change. We also allow a JS URL to be loaded even if scripts on + // the page are otherwise disabled. if (!m_frame->document() || !m_frame->page()) return; @@ -1991,14 +2187,8 @@ void WebFrameImpl::loadJavaScriptURL(const KURL& url) if (!result.getString(scriptResult)) return; - SecurityOrigin* securityOrigin = m_frame->document()->securityOrigin(); - - if (!m_frame->redirectScheduler()->locationChangePending()) { - m_frame->loader()->stopAllLoaders(); - m_frame->loader()->begin(m_frame->loader()->url(), true, securityOrigin); - m_frame->loader()->write(scriptResult); - m_frame->loader()->end(); - } + if (!m_frame->redirectScheduler()->locationChangePending()) + m_frame->loader()->writer()->replaceDocument(scriptResult); } } // namespace WebKit |
