diff options
Diffstat (limited to 'WebCore/platform/android')
93 files changed, 517 insertions, 22773 deletions
diff --git a/WebCore/platform/android/AndroidLog.cpp b/WebCore/platform/android/AndroidLog.cpp deleted file mode 100644 index aec7491..0000000 --- a/WebCore/platform/android/AndroidLog.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - ** - ** Copyright 2008, The Android Open Source Project - ** - ** Licensed under the Apache License, Version 2.0 (the "License"); - ** you may not use this file except in compliance with the License. - ** You may obtain a copy of the License at - ** - ** http://www.apache.org/licenses/LICENSE-2.0 - ** - ** Unless required by applicable law or agreed to in writing, software - ** distributed under the License is distributed on an "AS IS" BASIS, - ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ** See the License for the specific language governing permissions and - ** limitations under the License. - */ - -#include "config.h" -#include "AndroidLog.h" -#include <stdio.h> - -#define LOG_TAG "WebCore" -#undef LOG -#include <utils/Log.h> - -namespace WebCore { - -#define BUF_SIZE 1024 - -void ANDROID_LOGD(const char *fmt, ...) { - va_list ap; - char buf[BUF_SIZE]; - - va_start(ap, fmt); - vsnprintf(buf, BUF_SIZE, fmt, ap); - va_end(ap); - - LOGD(buf); -} - -void ANDROID_LOGW(const char *fmt, ...) { - va_list ap; - char buf[BUF_SIZE]; - - va_start(ap, fmt); - vsnprintf(buf, BUF_SIZE, fmt, ap); - va_end(ap); - - LOGW(buf); -} - -void ANDROID_LOGV(const char *fmt, ...) { - va_list ap; - char buf[BUF_SIZE]; - - va_start(ap, fmt); - vsnprintf(buf, BUF_SIZE, fmt, ap); - va_end(ap); - - LOGV(buf); -} -} diff --git a/WebCore/platform/android/ChromeClientAndroid.cpp b/WebCore/platform/android/ChromeClientAndroid.cpp deleted file mode 100644 index 25cbf95..0000000 --- a/WebCore/platform/android/ChromeClientAndroid.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "config.h" - -#include "ChromeClientAndroid.h" -#include "CString.h" -#include "Document.h" -#include "PlatformString.h" -#include "FloatRect.h" -#include "Frame.h" -#include "FrameAndroid.h" -#include "FrameLoader.h" -#include "FrameView.h" -#include "kjs_proxy.h" -#include "Page.h" -#include "Screen.h" -#include "WebCoreViewBridge.h" -#include "WindowFeatures.h" -#include "Settings.h" - -#define LOG_TAG "WebCore" -#undef LOG -#include <utils/Log.h> - -namespace WebCore { - -void ChromeClientAndroid::chromeDestroyed() -{ - delete this; -} - -void ChromeClientAndroid::setWindowRect(const FloatRect&) { notImplemented(); } - -static WebCoreViewBridge* rootViewForFrame(const Frame* frame) -{ - if (!frame) - return NULL; - FrameView* frameView = frame->view(); - return frameView ? frameView->getWebCoreViewBridge() : NULL; -} - -FloatRect ChromeClientAndroid::windowRect() { - ASSERT(m_frame); - WebCoreViewBridge* view = rootViewForFrame(m_frame); - if (!view) - return FloatRect(); - const WebCore::IntRect& rect = view->getBounds(); - FloatRect fRect(rect.x(), rect.y(), rect.width(), rect.height()); - return fRect; -} - -FloatRect ChromeClientAndroid::pageRect() { notImplemented(); return FloatRect(); } - -float ChromeClientAndroid::scaleFactor() -{ - // only seems to be used for dashboard regions, so just return 1 - return 1; -} - -void ChromeClientAndroid::focus() { - ASSERT(m_frame); - // Ask the application to focus this WebView. - m_frame->bridge()->requestFocus(); -} -void ChromeClientAndroid::unfocus() { notImplemented(); } - -bool ChromeClientAndroid::canTakeFocus(FocusDirection) { notImplemented(); return false; } -void ChromeClientAndroid::takeFocus(FocusDirection) { notImplemented(); } - -Page* ChromeClientAndroid::createWindow(Frame* frame, const FrameLoadRequest&, - const WindowFeatures& features) -{ - ASSERT(frame); - if (!(frame->settings()->supportMultipleWindows())) - // If the client doesn't support multiple windows, just return the current page - return frame->page(); - - FrameAndroid* frameAndroid = (FrameAndroid*) frame; - WebCore::Screen screen(frame); - bool dialog = features.dialog || !features.resizable - || (features.heightSet && features.height < screen.height() - && features.widthSet && features.width < screen.width()) - || (!features.menuBarVisible && !features.statusBarVisible - && !features.toolBarVisible && !features.locationBarVisible - && !features.scrollbarsVisible); - // fullscreen definitely means no dialog - if (features.fullscreen) - dialog = false; - WebCore::Frame* newFrame = frameAndroid->bridge()->createWindow(dialog, - frame->scriptProxy()->processingUserGesture()); - if (newFrame) { - WebCore::Page* page = newFrame->page(); - page->setGroupName(frameAndroid->page()->groupName()); - return page; - } - return NULL; -} - -Page* ChromeClientAndroid::createModalDialog(Frame* , const FrameLoadRequest&) { notImplemented(); return 0; } -void ChromeClientAndroid::show() { notImplemented(); } - -bool ChromeClientAndroid::canRunModal() { notImplemented(); return false; } -void ChromeClientAndroid::runModal() { notImplemented(); } - -void ChromeClientAndroid::setToolbarsVisible(bool) { notImplemented(); } -bool ChromeClientAndroid::toolbarsVisible() { notImplemented(); return false; } - -void ChromeClientAndroid::setStatusbarVisible(bool) { notImplemented(); } -bool ChromeClientAndroid::statusbarVisible() { notImplemented(); return false; } - -void ChromeClientAndroid::setScrollbarsVisible(bool) { notImplemented(); } -bool ChromeClientAndroid::scrollbarsVisible() { notImplemented(); return false; } - -void ChromeClientAndroid::setMenubarVisible(bool) { notImplemented(); } -bool ChromeClientAndroid::menubarVisible() { notImplemented(); return false; } - -void ChromeClientAndroid::setResizable(bool) { notImplemented(); } - -// This function is called by the JavaScript bindings to print usually an error to -// a message console. -void ChromeClientAndroid::addMessageToConsole(const String& message, unsigned int lineNumber, const String& sourceID) { - notImplemented(); - LOGD("Console: %s line: %d source: %s\n", message.latin1().data(), lineNumber, sourceID.latin1().data()); -} - -bool ChromeClientAndroid::canRunBeforeUnloadConfirmPanel() { return true; } -bool ChromeClientAndroid::runBeforeUnloadConfirmPanel(const String& message, Frame* frame) { - String url = frame->document()->documentURI(); - return frame->view()->getWebCoreViewBridge()->jsUnload(url, message); -} - -void ChromeClientAndroid::closeWindowSoon() -{ - ASSERT(m_frame); - // This will prevent javascript cross-scripting during unload - m_frame->page()->setGroupName(String()); - // Stop loading but do not send the unload event - m_frame->loader()->stopLoading(false); - // Cancel all pending loaders - m_frame->loader()->stopAllLoaders(); - // Remove all event listeners so that no javascript can execute as a result - // of mouse/keyboard events. - m_frame->document()->removeAllEventListenersFromAllNodes(); - // Close the window. - m_frame->bridge()->closeWindow(m_frame->view()->getWebCoreViewBridge()); -} - -void ChromeClientAndroid::runJavaScriptAlert(Frame* frame, const String& message) -{ - String url = frame->document()->documentURI(); - - frame->view()->getWebCoreViewBridge()->jsAlert(url, message); -} - -bool ChromeClientAndroid::runJavaScriptConfirm(Frame* frame, const String& message) -{ - String url = frame->document()->documentURI(); - - return frame->view()->getWebCoreViewBridge()->jsConfirm(url, message); -} - -/* This function is called for the javascript method Window.prompt(). A dialog should be shown on - * the screen with an input put box. First param is the text, the second is the default value for - * the input box, third is return param. If the function returns true, the value set in the third parameter - * is provided to javascript, else null is returned to the script. - */ -bool ChromeClientAndroid::runJavaScriptPrompt(Frame* frame, const String& message, const String& defaultValue, String& result) -{ - String url = frame->document()->documentURI(); - - return frame->view()->getWebCoreViewBridge()->jsPrompt(url, message, defaultValue, result); -} -void ChromeClientAndroid::setStatusbarText(const String&) { notImplemented(); } - -// This is called by the JavaScript interpreter when a script has been running for a long -// time. A dialog should be shown to the user asking them if they would like to cancel the -// Javascript. If true is returned, the script is cancelled. -// To make a device more responsive, we default to return true to disallow long running script. -// This implies that some of scripts will not be completed. -bool ChromeClientAndroid::shouldInterruptJavaScript() { return true; } - -// functions new to Jun-07 tip of tree merge: -void ChromeClientAndroid::addToDirtyRegion(IntRect const&) {} -void ChromeClientAndroid::scrollBackingStore(int, int, IntRect const&, IntRect const&) {} -void ChromeClientAndroid::updateBackingStore() {} -bool ChromeClientAndroid::tabsToLinks() const { return false; } -IntRect ChromeClientAndroid::windowResizerRect() const { return IntRect(0, 0, 0, 0); } - -// functions new to the Nov-16-08 tip of tree merge: -void ChromeClientAndroid::mouseDidMoveOverElement(const HitTestResult&, unsigned int) {} -void ChromeClientAndroid::setToolTip(const String&) {} -void ChromeClientAndroid::print(Frame*) {} -bool ChromeClientAndroid::runDatabaseSizeLimitPrompt(Frame*, const String&) { return false; } - -// functions new to Feb-19 tip of tree merge: -void ChromeClientAndroid::exceededDatabaseQuota(Frame*, const String&) {} - -} diff --git a/WebCore/platform/android/ChromeClientAndroid.h b/WebCore/platform/android/ChromeClientAndroid.h deleted file mode 100644 index 5f1dd0b..0000000 --- a/WebCore/platform/android/ChromeClientAndroid.h +++ /dev/null @@ -1,101 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef ChromeClientAndroid_h -#define ChromeClientAndroid_h - -#include "ChromeClient.h" - -namespace WebCore { - -class FrameAndroid; - class ChromeClientAndroid : public ChromeClient { - public: - ChromeClientAndroid() : m_frame(NULL) {} - virtual void chromeDestroyed(); - - virtual void setWindowRect(const FloatRect&); - virtual FloatRect windowRect(); - - virtual FloatRect pageRect(); - - virtual float scaleFactor(); - - virtual void focus(); - virtual void unfocus(); - - virtual bool canTakeFocus(FocusDirection); - virtual void takeFocus(FocusDirection); - - // The Frame pointer provides the ChromeClient with context about which - // Frame wants to create the new Page. Also, the newly created window - // should not be shown to the user until the ChromeClient of the newly - // created Page has its show method called. - virtual Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&); - virtual Page* createModalDialog(Frame*, const FrameLoadRequest&); - virtual void show(); - - virtual bool canRunModal(); - virtual void runModal(); - - virtual void setToolbarsVisible(bool); - virtual bool toolbarsVisible(); - - virtual void setStatusbarVisible(bool); - virtual bool statusbarVisible(); - - virtual void setScrollbarsVisible(bool); - virtual bool scrollbarsVisible(); - - virtual void setMenubarVisible(bool); - virtual bool menubarVisible(); - - virtual void setResizable(bool); - - virtual void addMessageToConsole(const String& message, unsigned int lineNumber, const String& sourceID); - - virtual bool canRunBeforeUnloadConfirmPanel(); - virtual bool runBeforeUnloadConfirmPanel(const String& message, Frame* frame); - - virtual void closeWindowSoon(); - - virtual void runJavaScriptAlert(Frame*, const String&); - virtual bool runJavaScriptConfirm(Frame*, const String&); - virtual bool runJavaScriptPrompt(Frame*, const String& message, const String& defaultValue, String& result); - - virtual void setStatusbarText(const String&); - virtual bool shouldInterruptJavaScript(); - virtual bool tabsToLinks() const; - - virtual IntRect windowResizerRect() const; - virtual void addToDirtyRegion(const IntRect&); - virtual void scrollBackingStore(int dx, int dy, const IntRect& scrollViewRect, const IntRect& clipRect); - virtual void updateBackingStore(); - virtual void mouseDidMoveOverElement(const HitTestResult&, unsigned int); - virtual void setToolTip(const String&); - virtual void print(Frame*); - virtual bool runDatabaseSizeLimitPrompt(Frame*, const String&); - virtual void exceededDatabaseQuota(Frame*, const String&); - // Android-specific - void setFrame(FrameAndroid* frame) { m_frame = frame; } - private: - FrameAndroid* m_frame; - }; - -} - -#endif diff --git a/WebCore/platform/android/ClipboardAndroid.cpp b/WebCore/platform/android/ClipboardAndroid.cpp index d4bf734..f23b4c7 100644 --- a/WebCore/platform/android/ClipboardAndroid.cpp +++ b/WebCore/platform/android/ClipboardAndroid.cpp @@ -29,7 +29,6 @@ #include "CachedImage.h" #include "CSSHelper.h" #include "CString.h" -#include "DeprecatedString.h" #include "Document.h" #include "DragData.h" #include "Element.h" @@ -138,7 +137,7 @@ bool ClipboardAndroid::setData(const String &type, const String &data) ClipboardDataType platformType = clipboardTypeFromMIMEType(type); if (platformType == ClipboardDataTypeURL) { - KURL url = data.deprecatedString(); + KURL url = KURL(data); #if 0 && defined ANDROID // FIXME HACK : KURL no longer defines a public method isValid() if (!url.isValid()) return false; @@ -167,10 +166,10 @@ void ClipboardAndroid::setDragImage(CachedImage* image, Node *node, const IntPoi return; if (m_dragImage) - m_dragImage->deref(this); + m_dragImage->removeClient(this); m_dragImage = image; if (m_dragImage) - m_dragImage->ref(this); + m_dragImage->addClient(this); m_dragLoc = loc; m_dragImageElement = node; diff --git a/WebCore/platform/android/ContextMenuClientAndroid.cpp b/WebCore/platform/android/ContextMenuClientAndroid.cpp index cc7252f..cb429ee 100644 --- a/WebCore/platform/android/ContextMenuClientAndroid.cpp +++ b/WebCore/platform/android/ContextMenuClientAndroid.cpp @@ -17,10 +17,9 @@ #include "config.h" #include "ContextMenuClientAndroid.h" +#include "NotImplemented.h" #include "wtf/Assertions.h" -#define notImplemented() ASSERT(0) - namespace WebCore { void ContextMenuClientAndroid::contextMenuDestroyed() { delete this; } diff --git a/WebCore/platform/android/Cookie.cpp b/WebCore/platform/android/Cookie.cpp deleted file mode 100644 index eeaa4ce..0000000 --- a/WebCore/platform/android/Cookie.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "config.h" -#include "JavaSharedClient.h" -#include "CookieClient.h" - -#define LOG_TAG "Cookies" -#undef LOG -#include "utils/Log.h" - -namespace WebCore { - - class Document; - - void setCookies(Document* , const KURL& url, const KURL& policyBaseURL, const String& value) - { - if (JavaSharedClient::GetCookieClient()) - JavaSharedClient::GetCookieClient()->setCookies(url, policyBaseURL, value); - } - - String cookies(const Document* , const KURL& url) - { - if (JavaSharedClient::GetCookieClient()) - return JavaSharedClient::GetCookieClient()->cookies(url); - return String(); - } - - bool cookiesEnabled(const Document* ) - { - if (JavaSharedClient::GetCookieClient()) - return JavaSharedClient::GetCookieClient()->cookiesEnabled(); - return false; - } - -} - diff --git a/WebCore/platform/android/CookieClient.h b/WebCore/platform/android/CookieClient.h deleted file mode 100644 index 0b76932..0000000 --- a/WebCore/platform/android/CookieClient.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef COOKIE_CLIENT_H -#define COOKIE_CLIENT_H - -#include "KURL.h" -#include "PlatformString.h" - -namespace WebCore { - - class CookieClient - { - public: - virtual ~CookieClient() {} - virtual void setCookies(const KURL& url, const KURL& docURL, const String& value) = 0; - virtual String cookies(const KURL& url) = 0; - virtual bool cookiesEnabled() = 0; - }; - -} -#endif - diff --git a/WebCore/platform/android/CursorAndroid.cpp b/WebCore/platform/android/CursorAndroid.cpp index e3a2562..82ba811 100644 --- a/WebCore/platform/android/CursorAndroid.cpp +++ b/WebCore/platform/android/CursorAndroid.cpp @@ -22,18 +22,14 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#define LOG_TAG "WebCore" #include "config.h" #include "Cursor.h" - -#define LOG_TAG "WebCore" -#undef LOG -#include "utils/Log.h" +#include "NotImplemented.h" namespace WebCore { -static void notImplemented() { LOGV("Cursor: NotYetImplemented"); } - Cursor::Cursor(Image* image, const IntPoint& ) { notImplemented(); @@ -258,4 +254,72 @@ const Cursor& noneCursor() return c; } + // new as of SVN change 36269, Sept 8, 2008 +const Cursor& middlePanningCursor() +{ + notImplemented(); + static Cursor c; + return c; +} + +const Cursor& eastPanningCursor() +{ + notImplemented(); + static Cursor c; + return c; +} + +const Cursor& northPanningCursor() +{ + notImplemented(); + static Cursor c; + return c; +} + +const Cursor& northEastPanningCursor() +{ + notImplemented(); + static Cursor c; + return c; +} + +const Cursor& northWestPanningCursor() +{ + notImplemented(); + static Cursor c; + return c; +} + +const Cursor& southPanningCursor() +{ + notImplemented(); + static Cursor c; + return c; +} + +const Cursor& southEastPanningCursor() +{ + notImplemented(); + static Cursor c; + return c; +} + +const Cursor& southWestPanningCursor() +{ + notImplemented(); + static Cursor c; + return c; +} + +const Cursor& westPanningCursor() +{ + notImplemented(); + static Cursor c; + return c; +} + + // new as of SVN change 38068, Nov 5, 2008 +const Cursor& grabCursor() {} +const Cursor& grabbingCursor() {} + } diff --git a/WebCore/platform/android/DragClientAndroid.cpp b/WebCore/platform/android/DragClientAndroid.cpp deleted file mode 100644 index 6a9aef1..0000000 --- a/WebCore/platform/android/DragClientAndroid.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "config.h" -#include "DragClientAndroid.h" -#include "wtf/Assertions.h" - -#define LOG_TAG "WebCore" -#undef LOG -#include <utils/Log.h> - -//#define notImplemented() ASSERT(0) -#define notImplemented() LOGV("%s\n", __PRETTY_FUNCTION__); - -namespace WebCore { - -void DragClientAndroid::dragControllerDestroyed() { notImplemented(); delete this; } - -void DragClientAndroid::willPerformDragDestinationAction(DragDestinationAction, DragData*) { notImplemented(); } - -DragDestinationAction DragClientAndroid::actionMaskForDrag(DragData*) { notImplemented(); return DragDestinationActionNone; } - -DragSourceAction DragClientAndroid::dragSourceActionMaskForPoint(const IntPoint&) { notImplemented(); return DragSourceActionNone; } - -void* DragClientAndroid::createDragImageForLink(KURL&, String const&, Frame*) { return NULL; } -void DragClientAndroid::willPerformDragSourceAction(DragSourceAction, IntPoint const&, Clipboard*) {} -void DragClientAndroid::startDrag(void*, IntPoint const&, IntPoint const&, Clipboard*, Frame*, bool) {} - -} diff --git a/WebCore/platform/android/DragClientAndroid.h b/WebCore/platform/android/DragClientAndroid.h deleted file mode 100644 index fd699e0..0000000 --- a/WebCore/platform/android/DragClientAndroid.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef DragClientAndroid_h -#define DragClientAndroid_h - -#include "DragClient.h" - -namespace WebCore { - - class DragClientAndroid : public WebCore::DragClient { - public: - virtual void willPerformDragDestinationAction(DragDestinationAction, DragData*); - virtual void willPerformDragSourceAction(DragSourceAction, const IntPoint&, Clipboard*); - virtual DragDestinationAction actionMaskForDrag(DragData*); - //We work in window rather than view coordinates here - virtual DragSourceAction dragSourceActionMaskForPoint(const IntPoint&); - - virtual void startDrag(DragImageRef dragImage, const IntPoint& dragImageOrigin, const IntPoint& eventPos, Clipboard*, Frame*, bool linkDrag = false); - virtual DragImageRef createDragImageForLink(KURL&, const String& label, Frame*); - - virtual void dragControllerDestroyed(); - }; - -} - -#endif diff --git a/WebCore/platform/android/DragDataAndroid.cpp b/WebCore/platform/android/DragDataAndroid.cpp index cac3c4a..504acbd 100644 --- a/WebCore/platform/android/DragDataAndroid.cpp +++ b/WebCore/platform/android/DragDataAndroid.cpp @@ -55,10 +55,12 @@ Color DragData::asColor() const { return Color(); } + +class Clipboard : public RefCounted<Clipboard> {}; -Clipboard* DragData::createClipboard(ClipboardAccessPolicy) const +PassRefPtr<Clipboard> DragData::createClipboard(ClipboardAccessPolicy) const { - return 0; + return PassRefPtr<Clipboard>(NULL); } bool DragData::containsCompatibleContent() const diff --git a/WebCore/platform/android/EditorAndroid.cpp b/WebCore/platform/android/EditorAndroid.cpp deleted file mode 100644 index 204b23c..0000000 --- a/WebCore/platform/android/EditorAndroid.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "Editor.h" -#include "EditorClient.h" - -#include "ClipboardAndroid.h" -#include "Document.h" -#include "Element.h" -#include "htmlediting.h" -#include "NotImplemented.h" -#include "TextIterator.h" -#include "visible_units.h" - -namespace WebCore { - -PassRefPtr<Clipboard> Editor::newGeneralClipboard(ClipboardAccessPolicy policy) -{ - return new ClipboardAndroid(policy, false); -} - -} // namespace WebCore diff --git a/WebCore/platform/android/EditorClientAndroid.cpp b/WebCore/platform/android/EditorClientAndroid.cpp deleted file mode 100644 index b38c542..0000000 --- a/WebCore/platform/android/EditorClientAndroid.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "config.h" -#include "Editor.h" -#include "EditorClientAndroid.h" -#include "Event.h" -#include "EventNames.h" -#include "FocusController.h" -#include "Frame.h" -#include "KeyboardCodes.h" -#include "KeyboardEvent.h" -#include "PlatformKeyboardEvent.h" -#include "PlatformString.h" -#include "wtf/Assertions.h" - -#include <assert.h> - -#define LOG_TAG "WebCore" -#undef LOG -#include <utils/Log.h> - -#define notImplemented() LOGV("%s\n", __PRETTY_FUNCTION__) -#define lowPriority_notImplemented() //printf("%s\n", __PRETTY_FUNCTION__) - -namespace WebCore { - -void EditorClientAndroid::pageDestroyed() { - delete this; -} - -bool EditorClientAndroid::shouldDeleteRange(Range*) { return true; } -bool EditorClientAndroid::shouldShowDeleteInterface(HTMLElement*) { notImplemented(); return false; } -bool EditorClientAndroid::smartInsertDeleteEnabled() { notImplemented(); return false; } -bool EditorClientAndroid::isContinuousSpellCheckingEnabled() { notImplemented(); return false; } -void EditorClientAndroid::toggleContinuousSpellChecking() { notImplemented(); } -bool EditorClientAndroid::isGrammarCheckingEnabled() { notImplemented(); return false; } -void EditorClientAndroid::toggleGrammarChecking() { notImplemented(); } -int EditorClientAndroid::spellCheckerDocumentTag() { notImplemented(); return -1; } - -bool EditorClientAndroid::isEditable() { notImplemented(); return false; } - -// Following Qt's implementation. For shouldBeginEditing and shouldEndEditing. -// Returning true for these fixes issue http://b/issue?id=735185 -bool EditorClientAndroid::shouldBeginEditing(Range*) -{ - return true; -} - -bool EditorClientAndroid::shouldEndEditing(Range*) -{ - return true; -} - -bool EditorClientAndroid::shouldInsertNode(Node*, Range*, EditorInsertAction) { notImplemented(); return true; } -bool EditorClientAndroid::shouldInsertText(String, Range*, EditorInsertAction) { return true; } -bool EditorClientAndroid::shouldApplyStyle(CSSStyleDeclaration*, Range*) { notImplemented(); return true; } - -void EditorClientAndroid::didBeginEditing() { notImplemented(); } - -// This function is called so that the platform can handle changes to content. It is called -// after the contents have been edited or unedited (ie undo) -void EditorClientAndroid::respondToChangedContents() { notImplemented(); } - -void EditorClientAndroid::didEndEditing() { notImplemented(); } -void EditorClientAndroid::didWriteSelectionToPasteboard() { notImplemented(); } -void EditorClientAndroid::didSetSelectionTypesForPasteboard() { notImplemented(); } - -// Copied from the Window's port of WebKit. -static const unsigned AltKey = 1 << 0; -static const unsigned ShiftKey = 1 << 1; - -struct KeyDownEntry { - unsigned virtualKey; - unsigned modifiers; - const char* name; -}; - -struct KeyPressEntry { - unsigned charCode; - unsigned modifiers; - const char* name; -}; - -static const KeyDownEntry keyDownEntries[] = { - { VK_LEFT, 0, "MoveLeft" }, - { VK_LEFT, ShiftKey, "MoveLeftAndModifySelection" }, - { VK_LEFT, AltKey, "MoveWordLeft" }, - { VK_LEFT, AltKey | ShiftKey, "MoveWordLeftAndModifySelection" }, - { VK_RIGHT, 0, "MoveRight" }, - { VK_RIGHT, ShiftKey, "MoveRightAndModifySelection" }, - { VK_RIGHT, AltKey, "MoveWordRight" }, - { VK_RIGHT, AltKey | ShiftKey, "MoveWordRightAndModifySelection" }, - { VK_UP, 0, "MoveUp" }, - { VK_UP, ShiftKey, "MoveUpAndModifySelection" }, - { VK_DOWN, 0, "MoveDown" }, - { VK_DOWN, ShiftKey, "MoveDownAndModifySelection" }, - - { VK_BACK, 0, "BackwardDelete" }, - { VK_BACK, ShiftKey, "ForwardDelete" }, - { VK_BACK, AltKey, "DeleteWordBackward" }, - { VK_BACK, AltKey | ShiftKey, "DeleteWordForward" }, - - { VK_ESCAPE, 0, "Cancel" }, - { VK_TAB, 0, "InsertTab" }, - { VK_TAB, ShiftKey, "InsertBacktab" }, - { VK_RETURN, 0, "InsertNewline" }, - { VK_RETURN, AltKey, "InsertNewline" }, - { VK_RETURN, AltKey | ShiftKey, "InsertNewline" } -}; - -static const KeyPressEntry keyPressEntries[] = { - { '\t', 0, "InsertTab" }, - { '\t', ShiftKey, "InsertBackTab" }, - { '\r', 0, "InsertNewline" }, - { '\r', AltKey, "InsertNewline" }, - { '\r', AltKey | ShiftKey, "InsertNewline" } -}; - -static const char* interpretKeyEvent(const KeyboardEvent* evt) -{ - const PlatformKeyboardEvent* keyEvent = evt->keyEvent(); - - static HashMap<int, const char*>* keyDownCommandsMap = 0; - static HashMap<int, const char*>* keyPressCommandsMap = 0; - - if (!keyDownCommandsMap) { - keyDownCommandsMap = new HashMap<int, const char*>; - keyPressCommandsMap = new HashMap<int, const char*>; - - for (unsigned i = 0; i < sizeof(keyDownEntries)/sizeof(KeyDownEntry); i++) - keyDownCommandsMap->set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].name); - - for (unsigned i = 0; i < sizeof(keyPressEntries)/sizeof(KeyPressEntry); i++) - keyPressCommandsMap->set(keyPressEntries[i].modifiers << 16 | keyPressEntries[i].charCode, keyPressEntries[i].name); - } - - unsigned modifiers = 0; - if (keyEvent->shiftKey()) - modifiers |= ShiftKey; - if (keyEvent->altKey()) - modifiers |= AltKey; - - if (evt->type() == EventNames::keydownEvent) { - int mapKey = modifiers << 16 | evt->keyCode(); - return mapKey ? keyDownCommandsMap->get(mapKey) : 0; - } - - int mapKey = modifiers << 16 | evt->charCode(); - return mapKey ? keyPressCommandsMap->get(mapKey) : 0; -} - -void EditorClientAndroid::handleKeyboardEvent(KeyboardEvent* event) { - assert(m_page); - Frame* frame = m_page->focusController()->focusedOrMainFrame(); - if (!frame) - return; - - const PlatformKeyboardEvent* keyEvent = event->keyEvent(); - // TODO: If the event is not coming from Android Java, e.g. from JavaScript, - // PlatformKeyboardEvent is null. We should support this later. - if (!keyEvent) - return; - - Editor::Command command = frame->editor()->command(interpretKeyEvent(event)); - if (keyEvent->type() == PlatformKeyboardEvent::RawKeyDown) { - if (!command.isTextInsertion() && command.execute(event)) { - // This function mimics the Windows version. However, calling event->setDefaultHandled() - // prevents the javascript key events for the delete key from happening. - // Update: Safari doesn't send delete key events to javascript so - // we will mimic that behavior. - event->setDefaultHandled(); - } - return; - } - - if (command.execute(event)) { - event->setDefaultHandled(); - return; - } - - // Don't insert null or control characters as they can result in unexpected behaviour - if (event->charCode() < ' ') - return; - - if (frame->editor()->insertText(keyEvent->text(), event)) - event->setDefaultHandled(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////// -// we just don't support Undo/Redo at the moment - -void EditorClientAndroid::registerCommandForUndo(PassRefPtr<EditCommand>) {} -void EditorClientAndroid::registerCommandForRedo(PassRefPtr<EditCommand>) {} -void EditorClientAndroid::clearUndoRedoOperations() {} -bool EditorClientAndroid::canUndo() const { return false; } -bool EditorClientAndroid::canRedo() const { return false; } -void EditorClientAndroid::undo() {} -void EditorClientAndroid::redo() {} - -// functions new to Jun-07 tip of tree merge: -void EditorClientAndroid::showSpellingUI(bool) {} -void EditorClientAndroid::getGuessesForWord(String const&, Vector<String>&) {} -bool EditorClientAndroid::spellingUIIsShowing() { return false; } -void EditorClientAndroid::checkGrammarOfString(unsigned short const*, int, Vector<GrammarDetail>&, int*, int*) {} -void EditorClientAndroid::checkSpellingOfString(unsigned short const*, int, int*, int*) {} -void EditorClientAndroid::textFieldDidEndEditing(Element*) {} -void EditorClientAndroid::textDidChangeInTextArea(Element*) {} -void EditorClientAndroid::textDidChangeInTextField(Element*) {} -void EditorClientAndroid::textFieldDidBeginEditing(Element*) {} -void EditorClientAndroid::ignoreWordInSpellDocument(String const&) {} -void EditorClientAndroid::respondToChangedSelection() {} -bool EditorClientAndroid::shouldChangeSelectedRange(Range*, Range*, EAffinity, bool) { return m_notFromClick; } -bool EditorClientAndroid::doTextFieldCommandFromEvent(Element*, KeyboardEvent*) { return false; } -void EditorClientAndroid::textWillBeDeletedInTextField(Element*) {} -void EditorClientAndroid::updateSpellingUIWithGrammarString(String const&, GrammarDetail const&) {} -void EditorClientAndroid::updateSpellingUIWithMisspelledWord(String const&) {} -void EditorClientAndroid::learnWord(String const&) {} - -// functions new to the Nov-16-08 tip of tree merge: -bool EditorClientAndroid::shouldMoveRangeAfterDelete(Range*, Range*) { return true; } -void EditorClientAndroid::setInputMethodState(bool) {} - -// functions new to Feb-19 tip of tree merge: -void EditorClientAndroid::handleInputMethodKeydown(KeyboardEvent*) {} - -} diff --git a/WebCore/platform/android/EditorClientAndroid.h b/WebCore/platform/android/EditorClientAndroid.h deleted file mode 100644 index 1bfd7e6..0000000 --- a/WebCore/platform/android/EditorClientAndroid.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef EditorClientAndroid_h -#define EditorClientAndroid_h - -#include "EditorClient.h" -#include "Page.h" - -namespace WebCore { - -class EditorClientAndroid : public EditorClient { -public: - EditorClientAndroid() { m_notFromClick = true; } - virtual void pageDestroyed(); - - virtual bool shouldDeleteRange(Range*); - virtual bool shouldShowDeleteInterface(HTMLElement*); - virtual bool smartInsertDeleteEnabled(); - virtual bool isContinuousSpellCheckingEnabled(); - virtual void toggleContinuousSpellChecking(); - virtual bool isGrammarCheckingEnabled(); - virtual void toggleGrammarChecking(); - virtual int spellCheckerDocumentTag(); - - virtual bool isEditable(); - - virtual bool shouldBeginEditing(Range*); - virtual bool shouldEndEditing(Range*); - virtual bool shouldInsertNode(Node*, Range*, EditorInsertAction); - virtual bool shouldInsertText(String, Range*, EditorInsertAction); - virtual bool shouldChangeSelectedRange(Range* fromRange, Range* toRange, EAffinity, bool stillSelecting); - - virtual bool shouldApplyStyle(CSSStyleDeclaration*, Range*); -// virtual bool shouldChangeTypingStyle(CSSStyleDeclaration* fromStyle, CSSStyleDeclaration* toStyle); -// virtual bool doCommandBySelector(SEL selector); - - virtual void didBeginEditing(); - virtual void respondToChangedContents(); - virtual void respondToChangedSelection(); - virtual void didEndEditing(); - virtual void didWriteSelectionToPasteboard(); - virtual void didSetSelectionTypesForPasteboard(); -// virtual void didChangeTypingStyle:(NSNotification *)notification; -// virtual void didChangeSelection:(NSNotification *)notification; -// virtual NSUndoManager* undoManager:(WebView *)webView; - - virtual void registerCommandForUndo(PassRefPtr<EditCommand>); - virtual void registerCommandForRedo(PassRefPtr<EditCommand>); - virtual void clearUndoRedoOperations(); - - virtual bool canUndo() const; - virtual bool canRedo() const; - - virtual void undo(); - virtual void redo(); - - virtual void textFieldDidBeginEditing(Element*); - virtual void textFieldDidEndEditing(Element*); - virtual void textDidChangeInTextField(Element*); - virtual bool doTextFieldCommandFromEvent(Element*, KeyboardEvent*); - virtual void textWillBeDeletedInTextField(Element*); - virtual void textDidChangeInTextArea(Element*); - - virtual void ignoreWordInSpellDocument(const String&); - virtual void learnWord(const String&); - virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength); - virtual void checkGrammarOfString(const UChar*, int length, Vector<GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength); - virtual void updateSpellingUIWithGrammarString(const String&, const GrammarDetail& detail); - virtual void updateSpellingUIWithMisspelledWord(const String&); - virtual void showSpellingUI(bool show); - virtual bool spellingUIIsShowing(); - virtual void getGuessesForWord(const String&, Vector<String>& guesses); - virtual bool shouldMoveRangeAfterDelete(Range*, Range*); - virtual void setInputMethodState(bool); - - virtual void handleKeyboardEvent(KeyboardEvent*); - virtual void handleInputMethodKeydown(KeyboardEvent*); - // Android specific: - void setPage(Page* page) { m_page = page; } - void setFromClick(bool fromClick) { m_notFromClick = !fromClick; } -private: - Page* m_page; - bool m_notFromClick; -}; - -} - -#endif diff --git a/WebCore/platform/android/AndroidLog.h b/WebCore/platform/android/EventLoopAndroid.cpp index f191ebf..8d9b051 100644 --- a/WebCore/platform/android/AndroidLog.h +++ b/WebCore/platform/android/EventLoopAndroid.cpp @@ -15,15 +15,15 @@ ** limitations under the License. */ -#ifndef ANDROIDLOG_H_ -#define ANDROIDLOG_H_ +#include "config.h" +#include "EventLoop.h" +#include "NotImplemented.h" namespace WebCore { - void ANDROID_LOGD(const char *fmt, ...); - - void ANDROID_LOGW(const char *fmt, ...); - - void ANDROID_LOGV(const char *fmt, ...); +void EventLoop::cycle() +{ + notImplemented(); } -#endif /*ANDROIDLOG_H_*/ + +} // namespace WebCore diff --git a/WebCore/platform/android/FileChooserAndroid.cpp b/WebCore/platform/android/FileChooserAndroid.cpp index e613115..2169cc3 100644 --- a/WebCore/platform/android/FileChooserAndroid.cpp +++ b/WebCore/platform/android/FileChooserAndroid.cpp @@ -24,30 +24,11 @@ namespace WebCore { -FileChooser::FileChooser(FileChooserClient* client, const String& initialFilename) -{ - m_client = client; - if (initialFilename.length() == 0) - m_filename = fileButtonNoFileSelectedLabel(); - else - m_filename = initialFilename; -} - -FileChooser::~FileChooser() -{ -} - -void FileChooser::openFileChooser(Document* doc) -{ - // FIXME: NEED TO OPEN A FILE CHOOSER OF SOME SORT!! - // When it's chosen, set m_filename, call chooseFile(m_filename) and call chooseIcon(m_filename) -} - String FileChooser::basenameForWidth(const Font& font, int width) const { // FIXME: This could be a lot faster, but assuming the data will not often be // much longer than the provided width, this may be fast enough. - String output = m_filename.copy(); + String output = m_filenames[0].copy(); while (font.width(TextRun(output.impl())) > width && output.length() > 4) { output = output.replace(output.length() - 4, 4, String("...")); } diff --git a/WebCore/platform/android/FileSystemAndroid.cpp b/WebCore/platform/android/FileSystemAndroid.cpp index 1aa8843..572a9c2 100644 --- a/WebCore/platform/android/FileSystemAndroid.cpp +++ b/WebCore/platform/android/FileSystemAndroid.cpp @@ -29,11 +29,73 @@ #include "FileSystem.h" #include "PlatformString.h" #include "CString.h" +#include <dlfcn.h> +#include <errno.h> +#include <sys/stat.h> +#include "cutils/log.h" namespace WebCore { +// Global static used to store the base to the plugin path. +// This is set in WebSettings.cpp +String sPluginPath; + CString fileSystemRepresentation(const String& path) { return path.utf8(); } +CString openTemporaryFile(const char* prefix, PlatformFileHandle& handle) +{ + int number = rand() % 10000 + 1; + CString filename; + do { + String path = sPluginPath; + path.append("/"); + path.append(prefix); + path.append(String::number(number)); + filename = path.utf8(); + const char *fstr = filename.data(); + handle = open(filename.data(), O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); + number++; + } while (handle == -1 && errno == EEXIST); + + if (handle != -1) { + return filename; + } + return CString(); +} + +bool unloadModule(PlatformModule module) +{ + return dlclose(module) == 0; +} + +void closeFile(PlatformFileHandle& handle) +{ + if (isHandleValid(handle)) { + close(handle); + handle = invalidPlatformFileHandle; + } +} + +int writeToFile(PlatformFileHandle handle, const char* data, int length) +{ + int totalBytesWritten = 0; + while (totalBytesWritten < length) { + int bytesWritten = write(handle, data, length - totalBytesWritten); + if (bytesWritten < 0 && errno != EINTR) + return -1; + else if (bytesWritten > 0) + totalBytesWritten += bytesWritten; + } + + return totalBytesWritten; +} + + // new as of SVN change 36269, Sept 8, 2008 +String homeDirectoryPath() +{ + return sPluginPath; +} + } diff --git a/WebCore/platform/android/FrameLoaderClientAndroid.cpp b/WebCore/platform/android/FrameLoaderClientAndroid.cpp deleted file mode 100644 index 2319bd8..0000000 --- a/WebCore/platform/android/FrameLoaderClientAndroid.cpp +++ /dev/null @@ -1,1173 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "config.h" - -#include "android_graphics.h" -#include "CString.h" -#include "DocumentLoader.h" -#include "FrameAndroid.h" -#include "FrameLoader.h" -#include "FrameLoaderClientAndroid.h" -#include "FrameTree.h" -#include "GraphicsContext.h" -// HTMLFormElement needed for a bad include -#include "HTMLFormElement.h" -#include "HTMLFrameOwnerElement.h" -#include "IconDatabase.h" -#include "Page.h" -#include "PlatformGraphicsContext.h" -#include "PlatformString.h" -#include "PluginInfoStore.h" -#include "PluginDatabaseAndroid.h" -#include "PluginViewAndroid.h" -#include "ProgressTracker.h" -#include "RenderPart.h" -#include "ResourceError.h" -#include "SelectionController.h" -#include "SkCanvas.h" -#include "SkRect.h" -#include "Document.h" -#include "FrameView.h" -#include "WebCoreViewBridge.h" -#include "HistoryItem.h" -#include "ResourceHandle.h" -#include "ResourceHandleInternal.h" -#include "WebCoreResourceLoader.h" -#include "WebCoreViewBridge.h" -#include "WebHistory.h" -#include "WebIconDatabase.h" -#include "Settings.h" - -#define LOG_TAG "WebCore" -#undef LOG -#include <utils/Log.h> -#include <utils/AssetManager.h> - -//#define notImplemented() LOGV("%s\n", __PRETTY_FUNCTION__) -#define lowPriority_notImplemented() //printf("%s\n", __PRETTY_FUNCTION__) -#define verifiedOk() // not a problem that it's not implemented -static inline void needsBridge(const char name[]) {LOGV("<%s> needs bridge", name);} - -extern android::AssetManager* gGlobalAssetMgr; - -namespace WebCore { - -static const int EXTRA_LAYOUT_DELAY = 1000; - -// FIXME: Need some data for how big this should be. -#define MAX_SESSION_HISTORY 50 -static Vector<KURL> gSessionHistory; - -bool historyContains(const UChar* chars, unsigned len) { - const KURL url(DeprecatedString(reinterpret_cast<const DeprecatedChar*>(chars), len)); - Vector<KURL>::const_iterator end = gSessionHistory.end(); - for (Vector<KURL>::const_iterator i = gSessionHistory.begin(); i != end; ++i) { - if (equalIgnoringRef(url, *i)) - return true; - } - return false; -} - -void FrameLoaderClientAndroid::frameLoaderDestroyed() { - registerForIconNotification(false); - m_frame = 0; - delete this; -} - -bool FrameLoaderClientAndroid::hasWebView() const { - // FIXME, - // there is one web view per page, or top frame. - // as android's view is created from Java side, it is always there. - return true; -} - -bool FrameLoaderClientAndroid::hasFrameView() const { - // FIXME, - // need to revisit for sub-frame case - return true; -} - -bool FrameLoaderClientAndroid::privateBrowsingEnabled() const { - // FIXME, are we going to support private browsing? - notImplemented(); - return false; -} - -void FrameLoaderClientAndroid::makeRepresentation(DocumentLoader*) { - // don't use representation - verifiedOk(); -} - -void FrameLoaderClientAndroid::forceLayout() { - ASSERT(m_frame); - m_frame->forceLayout(); - // FIXME, should we adjust view size here? - m_frame->view()->adjustViewSize(); -} - -void FrameLoaderClientAndroid::forceLayoutForNonHTML() { - notImplemented(); -} - -void FrameLoaderClientAndroid::setCopiesOnScroll() { - // this is a hint about whether we need to force redraws, or can - // just copy the scrolled content. Since we always force a redraw - // anyways, we can ignore this call. - verifiedOk(); -} - -void FrameLoaderClientAndroid::detachedFromParent2() { - // FIXME, ready to detach frame from view -} - -void FrameLoaderClientAndroid::detachedFromParent3() { - // FIXME, ready to release view - notImplemented(); -} - -void FrameLoaderClientAndroid::detachedFromParent4() { - // FIXME, ready to release view - notImplemented(); -} - -void FrameLoaderClientAndroid::loadedFromPageCache() { - // don't support page cache - verifiedOk(); -} - -// This function is responsible for associating the "id" with a given -// subresource load. The following functions that accept an "id" are -// called for each subresource, so they should not be dispatched to the m_frame. -void FrameLoaderClientAndroid::assignIdentifierToInitialRequest(unsigned long id, - DocumentLoader*, const ResourceRequest&) { - lowPriority_notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchWillSendRequest(DocumentLoader*, unsigned long id, - ResourceRequest&, const ResourceResponse&) { - lowPriority_notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, - unsigned long id, const AuthenticationChallenge&) { - lowPriority_notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, - unsigned long id, const AuthenticationChallenge&) { - lowPriority_notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidReceiveResponse(DocumentLoader*, - unsigned long id, const ResourceResponse&) { - lowPriority_notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidReceiveContentLength(DocumentLoader*, - unsigned long id, int lengthReceived) { - lowPriority_notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidFinishLoading(DocumentLoader*, - unsigned long id) { - lowPriority_notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidFailLoading(DocumentLoader* docLoader, - unsigned long id, const ResourceError&) { - lowPriority_notImplemented(); -} - -bool FrameLoaderClientAndroid::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, - const ResourceRequest&, const ResourceResponse&, int length) { - notImplemented(); - return false; -} - -void FrameLoaderClientAndroid::dispatchDidHandleOnloadEvents() { -} - -void FrameLoaderClientAndroid::dispatchDidReceiveServerRedirectForProvisionalLoad() { - ASSERT(m_frame); - // Tell the load it was a redirect. - m_frame->bridge()->loadStarted(m_frame); -} - -void FrameLoaderClientAndroid::dispatchDidCancelClientRedirect() { - notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchWillPerformClientRedirect(const KURL&, - double interval, double fireDate) { - notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidChangeLocationWithinPage() { - notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchWillClose() { - notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidReceiveIcon() { - ASSERT(m_frame); - if (m_frame->tree() && m_frame->tree()->parent()) - return; - WebCore::String url(m_frame->loader()->url().string()); - WebCore::Image* icon = WebCore::iconDatabase()->iconForPageURL(url, WebCore::IntSize(16,16)); - // There is a bug in webkit where cancelling an icon load is treated as a - // failure. When this is fixed, we can ASSERT again that we have an icon. - if (icon) { - m_frame->bridge()->didReceiveIcon(icon); - LOGV("Received icon (%p) for %s", icon, - m_frame->loader()->url().deprecatedString().ascii()); - } -} - -void FrameLoaderClientAndroid::dispatchDidStartProvisionalLoad() { - notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidReceiveTitle(const String& title) { - ASSERT(m_frame); - // Used to check for FrameLoadTypeStandard but we only want to send the title for - // the top frame and not sub-frames. - if (!m_frame->tree() || !m_frame->tree()->parent()) { - m_frame->bridge()->setTitle(title); - } -} - -void FrameLoaderClientAndroid::dispatchDidCommitLoad() { - ASSERT(m_frame); - m_frame->view()->getWebCoreViewBridge()->updateFrameGeneration(m_frame); -} - -void FrameLoaderClientAndroid::dispatchDidFailProvisionalLoad(const ResourceError& error) { - ASSERT(m_frame); - // Ignore ErrorInterrupted since it is due to a policy interruption. This - // is caused by a decision to download the main resource rather than - // display it. - if (error.errorCode() == InternalErrorInterrupted - || error.errorCode() == InternalErrorCancelled) - return; - - if (!gGlobalAssetMgr) { - gGlobalAssetMgr = new android::AssetManager(); - gGlobalAssetMgr->addDefaultAssets(); - } - - // Check to see if the error code was not generated internally - const char* errorPage = "webkit/nodomain.html"; - if ((error.errorCode() == ErrorFile || - error.errorCode() == ErrorFileNotFound) && - (!error.localizedDescription().isEmpty())) { - errorPage = "webkit/loaderror.html"; - } - - // Grab the error page from the asset manager - android::Asset* a = gGlobalAssetMgr->open(errorPage, - android::Asset::ACCESS_BUFFER); - if (!a) - return; - - // Take the failing url and encode html entities so javascript urls are not - // executed. - CString failingUrl = error.failingURL().utf8(); - Vector<char> url; - int len = failingUrl.length(); - const char* data = failingUrl.data(); - for (int i = 0; i < len; i++) { - char c = data[i]; - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') - || (c >= '0' && c <= '9')) - url.append(c); - else { - char buf[16]; - int res = sprintf(buf, "&#%d;", c); - buf[res] = 0; - url.append(buf, res); - } - } - - // Replace all occurances of %s with the failing url. - String s = String((const char*)a->getBuffer(false), a->getLength()); - s = s.replace("%s", String(url.data(), url.size())); - - // Replace all occurances of %e with the error text - s = s.replace("%e", error.localizedDescription()); - - // Create the request and the substitute data and tell the FrameLoader to - // load with the replacement data. - ResourceRequest request(error.failingURL()); - CString cstr = s.utf8(); - RefPtr<SharedBuffer> buf = new SharedBuffer(cstr.data(), cstr.length()); - SubstituteData subData(buf, String("text/html"), String("utf-8"), - request.url()); - m_frame->loader()->load(request, subData); - - // Delete the asset. - delete a; -} - -void FrameLoaderClientAndroid::dispatchDidFailLoad(const ResourceError&) { - // called when page is completed with error - lowPriority_notImplemented(); - ASSERT(m_frame); - m_frame->document()->setExtraLayoutDelay(0); -} - -void FrameLoaderClientAndroid::dispatchDidFinishDocumentLoad() { - // called when finishedParsing - lowPriority_notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidFinishLoad() { - ASSERT(m_frame); - m_frame->document()->setExtraLayoutDelay(0); - m_frame->bridge()->didFinishLoad(m_frame); -} - -void FrameLoaderClientAndroid::dispatchDidFirstLayout() { - ASSERT(m_frame); - m_frame->document()->setExtraLayoutDelay(EXTRA_LAYOUT_DELAY); - // FIXME: Need to figure out if we need didLayout or didFirstLayout - // see WebViewCore::didLayout - m_frame->view()->getWebCoreViewBridge()->didFirstLayout(); -} - -Frame* FrameLoaderClientAndroid::dispatchCreatePage() { - ASSERT(m_frame); - if (m_frame->settings()->supportMultipleWindows()) - // Always a user gesture since window.open maps to - // ChromeClientAndroid::createWindow - return m_frame->bridge()->createWindow(false, true); - else - // If the client doesn't support multiple windows, just replace the - // current frame's contents. - return m_frame; -} - -void FrameLoaderClientAndroid::dispatchShow() { - ASSERT(m_frame); - m_frame->view()->invalidate(); -} - - -static bool TreatAsAttachment(const String& content_disposition) { - // Some broken sites just send - // Content-Disposition: ; filename="file" - // screen those out here. - if (content_disposition.startsWith(";")) - return false; - - if (content_disposition.startsWith("inline", false)) - return false; - - // Some broken sites just send - // Content-Disposition: filename="file" - // without a disposition token... screen those out. - if (content_disposition.startsWith("filename", false)) - return false; - - // Also in use is Content-Disposition: name="file" - if (content_disposition.startsWith("name", false)) - return false; - - // We have a content-disposition of "attachment" or unknown. - // RFC 2183, section 2.8 says that an unknown disposition - // value should be treated as "attachment" - return true; -} - -void FrameLoaderClientAndroid::dispatchDecidePolicyForMIMEType(FramePolicyFunction func, - const String& MIMEType, const ResourceRequest&) { - ASSERT(m_frame); - ASSERT(func); - // Default to Use (display internally). - PolicyAction action = PolicyUse; - // Check if we should Download instead. - const ResourceResponse& response = m_frame->loader()->activeDocumentLoader()->response(); - const String& content_disposition = response.httpHeaderField("Content-Disposition"); - if (!content_disposition.isEmpty()) { - // Server wants to override our normal policy. - if (TreatAsAttachment(content_disposition)) { - // Check to see if we are a sub frame (main frame has no owner element) - if (m_frame->ownerElement() != 0) - action = PolicyIgnore; - else - action = PolicyDownload; - } - } else { - // Ask if it can be handled internally. - if (!canShowMIMEType(MIMEType)) { - // Check to see if we are a sub frame (main frame has no owner element) - if (m_frame->ownerElement() != 0) - action = PolicyIgnore; - else - action = PolicyDownload; - } - } - // A status code of 204 indicates no content change. Ignore the result. - WebCore::DocumentLoader* docLoader = m_frame->loader()->activeDocumentLoader(); - if (docLoader->response().httpStatusCode() == 204) - action = PolicyIgnore; - (m_frame->loader()->*func)(action); -} - -void FrameLoaderClientAndroid::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction func, - const NavigationAction&, const ResourceRequest& req, const String& frameName) { - ASSERT(m_frame); - // If we get to this point it means that a link has a target that was not - // found by the frame tree. Instead of creating a new frame, return the - // current frame in dispatchCreatePage. - if (canHandleRequest(req)) - (m_frame->loader()->*func)(PolicyUse); - else - (m_frame->loader()->*func)(PolicyIgnore); -} - -void FrameLoaderClientAndroid::cancelPolicyCheck() { - lowPriority_notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchUnableToImplementPolicy(const ResourceError&) { - notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDecidePolicyForNavigationAction(FramePolicyFunction func, - const NavigationAction& action, const ResourceRequest& request) { - ASSERT(m_frame); - ASSERT(func); - if (action.type() == NavigationTypeFormResubmitted) { - m_frame->bridge()->decidePolicyForFormResubmission(func); - return; - } else { - (m_frame->loader()->*func)(PolicyUse); - } -} - -void FrameLoaderClientAndroid::dispatchWillSubmitForm(FramePolicyFunction func, PassRefPtr<FormState>) { - ASSERT(m_frame); - ASSERT(func); - (m_frame->loader()->*func)(PolicyUse); -} - -void FrameLoaderClientAndroid::dispatchDidLoadMainResource(DocumentLoader*) { - notImplemented(); -} - -void FrameLoaderClientAndroid::revertToProvisionalState(DocumentLoader*) { - notImplemented(); -} - -void FrameLoaderClientAndroid::setMainDocumentError(DocumentLoader* docLoader, const ResourceError& error) { - ASSERT(m_frame); - if (!error.isNull() && error.errorCode() >= InternalErrorLast) - m_frame->bridge()->reportError(error.errorCode(), - error.localizedDescription(), error.failingURL()); -} - -void FrameLoaderClientAndroid::clearUnarchivingState(DocumentLoader*) { - notImplemented(); -} - -// This function is called right before the progress is updated. -void FrameLoaderClientAndroid::willChangeEstimatedProgress() { - verifiedOk(); -} - -// This function is called after the progress has been updated. The bad part -// about this is that when a page is completed, this function is called after -// the progress has been reset to 0. -void FrameLoaderClientAndroid::didChangeEstimatedProgress() { - verifiedOk(); -} - -// This will give us the initial estimate when the page first starts to load. -void FrameLoaderClientAndroid::postProgressStartedNotification() { - ASSERT(m_frame); - if (m_frame->page()) - m_frame->bridge()->setProgress(m_frame->page()->progress()->estimatedProgress()); -} - -// This will give us any updated progress including the final progress. -void FrameLoaderClientAndroid::postProgressEstimateChangedNotification() { - ASSERT(m_frame); - if (m_frame->page()) - m_frame->bridge()->setProgress(m_frame->page()->progress()->estimatedProgress()); -} - -// This is just a notification that the progress has finished. Don't call -// setProgress(1) because postProgressEstimateChangedNotification will do so. -void FrameLoaderClientAndroid::postProgressFinishedNotification() { - m_frame->view()->getWebCoreViewBridge()->notifyProgressFinished(); -} - -void FrameLoaderClientAndroid::setMainFrameDocumentReady(bool) { - // this is only interesting once we provide an external API for the DOM - notImplemented(); -} - -void FrameLoaderClientAndroid::startDownload(const ResourceRequest&) { - notImplemented(); -} - -void FrameLoaderClientAndroid::willChangeTitle(DocumentLoader*) { - verifiedOk(); -} - -void FrameLoaderClientAndroid::didChangeTitle(DocumentLoader* loader) { - verifiedOk(); -} - -void FrameLoaderClientAndroid::finishedLoading(DocumentLoader* docLoader) { - // Telling the frame we received some data and passing 0 as the data is our - // way to get work done that is normally done when the first bit of data is - // received, even for the case of a document with no data (like about:blank) - committedLoad(docLoader, 0, 0); -} - -void FrameLoaderClientAndroid::finalSetupForReplace(DocumentLoader*) { - notImplemented(); -} - -void FrameLoaderClientAndroid::updateGlobalHistoryForStandardLoad(const KURL& url) { - ASSERT(m_frame); - const DeprecatedString dStr = url.deprecatedString(); - if (!historyContains(reinterpret_cast<const UChar*>(dStr.unicode()), dStr.length())) { - if (gSessionHistory.size() == MAX_SESSION_HISTORY) - gSessionHistory.remove(0); - gSessionHistory.append(url); - } - m_frame->bridge()->updateVisitedHistory(url, false); -} - -void FrameLoaderClientAndroid::updateGlobalHistoryForReload(const KURL& url) { - ASSERT(m_frame); - m_frame->bridge()->updateVisitedHistory(url, true); -} - -bool FrameLoaderClientAndroid::shouldGoToHistoryItem(HistoryItem* item) const { - // hmmm, seems like we might do a more thoughtful check - ASSERT(m_frame); - return item != NULL; -} - -void FrameLoaderClientAndroid::committedLoad(DocumentLoader* loader, const char* data, int length) { - ASSERT(m_frame); - String encoding = loader->overrideEncoding(); - bool userChosen = !encoding.isNull(); - if (encoding.isNull()) - encoding = loader->response().textEncodingName(); - loader->frameLoader()->setEncoding(encoding, userChosen); - Document *doc = m_frame->document(); - if (doc) { - loader->frameLoader()->addData(data, length); - } -} - -ResourceError FrameLoaderClientAndroid::cancelledError(const ResourceRequest& request) { - return ResourceError(String(), InternalErrorCancelled, String(), String()); -} - -ResourceError FrameLoaderClientAndroid::cannotShowURLError(const ResourceRequest& request) { - return ResourceError(String(), InternalErrorCannotShowUrl, String(), String()); -} - -ResourceError FrameLoaderClientAndroid::interruptForPolicyChangeError(const ResourceRequest& request) { - return ResourceError(String(), InternalErrorInterrupted, String(), String()); -} - -ResourceError FrameLoaderClientAndroid::cannotShowMIMETypeError(const ResourceResponse& request) { - return ResourceError(String(), InternalErrorCannotShowMimeType, String(), String()); -} - -ResourceError FrameLoaderClientAndroid::fileDoesNotExistError(const ResourceResponse& request) { - return ResourceError(String(), InternalErrorFileDoesNotExist, String(), String()); -} - -bool FrameLoaderClientAndroid::shouldFallBack(const ResourceError&) { - notImplemented(); - return false; -} - -void FrameLoaderClientAndroid::setDefersLoading(bool) { - notImplemented(); -} - -bool FrameLoaderClientAndroid::willUseArchive(ResourceLoader*, const ResourceRequest&, - const KURL& originalURL) const { - lowPriority_notImplemented(); - return false; -} - -bool FrameLoaderClientAndroid::isArchiveLoadPending(ResourceLoader*) const { - lowPriority_notImplemented(); - return false; -} - -void FrameLoaderClientAndroid::cancelPendingArchiveLoad(ResourceLoader*) { - notImplemented(); -} - -void FrameLoaderClientAndroid::clearArchivedResources() { - notImplemented(); -} - -bool FrameLoaderClientAndroid::canHandleRequest(const ResourceRequest& request) const { - ASSERT(m_frame); - // Don't allow hijacking of intrapage navigation - if (WebCore::equalIgnoringRef(request.url(), m_frame->loader()->url())) - return true; - - // Don't allow hijacking of iframe urls that are http or https - if (request.url().protocol().startsWith("http", false) && - m_frame->tree() && m_frame->tree()->parent()) - return true; - - if (m_frame->bridge()->canHandleRequest(request)) { -#ifdef ANDROID_META_SUPPORT - // reset metadata settings for the top frame as they are not preserved cross page - if (!m_frame->tree()->parent()) - m_frame->settings()->resetMetadataSettings(); -#endif - return true; - } - return false; -} - -bool FrameLoaderClientAndroid::canShowMIMEType(const String& mimeType) const { - // FIXME: This looks like it has to do with whether or not a type can be - // shown "internally" (i.e. inside the browser) regardless of whether - // or not the browser is doing the rendering, e.g. a full page plugin. - if (mimeType.startsWith("text/plain", false) || - mimeType.startsWith("image/jpeg", false) || // Be specific with supported image formats - mimeType.startsWith("image/gif", false) || - mimeType.startsWith("image/png", false) || - mimeType.startsWith("image/bmp", false) || - mimeType.startsWith("image/x-icon", false) || - mimeType.startsWith("image/ico", false) || - mimeType.endsWith("/xml", false) || // text/xml & application/xml - mimeType.endsWith("xhtml+xml", false) || // application/xhtml+xml - // Checked Safari impl, it seems that the HTTP stack returns - // multiple responses, the initial response, and then one for - // multipart segment. Each response is sent to the same ResourceLoader - // so for us to support this we would need to do the same. - // mimeType.startsWith("multipart/x-mixed-replace", false) || - mimeType.endsWith("html", false)) - return true; - return false; -} - -bool FrameLoaderClientAndroid::representationExistsForURLScheme(const String&) const { - // don't use representation - verifiedOk(); - return false; -} - -String FrameLoaderClientAndroid::generatedMIMETypeForURLScheme(const String& URLScheme) const { - // FIXME, copy from Apple's port - String mimetype("x-apple-web-kit/"); - mimetype.append(URLScheme.lower()); - return mimetype; -} - -void FrameLoaderClientAndroid::frameLoadCompleted() { - // copied from Apple port, without this back with sub-frame will trigger ASSERT - ASSERT(m_frame); - m_frame->loader()->setPreviousHistoryItem(0); -} - -void FrameLoaderClientAndroid::saveViewStateToItem(HistoryItem* item) { -#ifdef ANDROID_HISTORY_CLIENT - ASSERT(m_frame); - ASSERT(item); - // We should have added a bridge when the child item was added to its - // parent. - android::WebHistoryItem* bridge = item->bridge(); - ASSERT(bridge); - // store the current scale - bridge->setScale(m_frame->view()->getWebCoreViewBridge()->scale()); - - // Store the location of the focus, based on how many traversals it - // takes to reach the focus from the document. - WebCore::Document* doc = m_frame->document(); - WebCore::Node* focus = doc->focusedNode(); - if (focus) { - int focusNum = 0; - WebCore::Node* node = doc; - while (node != focus) { - node = node->traverseNextNode(doc); - ASSERT(node); - focusNum++; - } - bridge->setTraversals(focusNum); - DEBUG_NAV_UI_LOGD("%s focus=%p traversals=%d", __FUNCTION__, focus, focusNum); - } else { - bridge->setTraversals(-1); - DEBUG_NAV_UI_LOGD("%s focus=NULL traversals=-1", __FUNCTION__); - } - WebCore::notifyHistoryItemChanged(item); -#endif -} - -void FrameLoaderClientAndroid::restoreViewState() { -#ifdef ANDROID_HISTORY_CLIENT - HistoryItem* item = m_frame->loader()->currentHistoryItem(); - // restore the scale - m_frame->view()->getWebCoreViewBridge()->restoreScale(item->bridge()->scale()); - // restore the focus - if (m_frame->loader()->firstLayoutDone() == false) - return; - int traversals = item->bridge()->traversals(); - if (traversals < 0) - return; - WebCore::Document* doc = m_frame->document(); - WebCore::Node* node = doc; - while (--traversals >= 0) { - if ((node = node->traverseNextNode(doc)) == NULL) - return; - } - if (doc->focusedNode() == node) - return; - DEBUG_NAV_UI_LOGD("%s focus=%p", __FUNCTION__, node); - doc->setFocusedNode(node); - m_frame->view()->getWebCoreViewBridge()->notifyFocusSet(); -#endif -} - -#ifdef ANDROID_HISTORY_CLIENT -void FrameLoaderClientAndroid::dispatchDidAddHistoryItem(HistoryItem* item) const { - ASSERT(m_frame); - m_frame->bridge()->addHistoryItem(item); -} - -void FrameLoaderClientAndroid::dispatchDidRemoveHistoryItem(HistoryItem* item, int index) const { - ASSERT(m_frame); - m_frame->bridge()->removeHistoryItem(index); -} - -void FrameLoaderClientAndroid::dispatchDidChangeHistoryIndex( - BackForwardList* list) const { - ASSERT(m_frame); - m_frame->bridge()->updateHistoryIndex(list->backListCount()); -} -#endif - -void FrameLoaderClientAndroid::provisionalLoadStarted() { - ASSERT(m_frame); - m_frame->bridge()->loadStarted(m_frame); -} - -void FrameLoaderClientAndroid::didFinishLoad() { - ASSERT(m_frame); - m_frame->bridge()->didFinishLoad(m_frame); -} - -void FrameLoaderClientAndroid::prepareForDataSourceReplacement() { - ASSERT(m_frame); - m_frame->loader()->detachChildren(); -} - -PassRefPtr<DocumentLoader> FrameLoaderClientAndroid::createDocumentLoader( - const ResourceRequest& request, const SubstituteData& data) { - RefPtr<DocumentLoader> loader = new DocumentLoader(request, data); - return loader.release(); -} - -void FrameLoaderClientAndroid::setTitle(const String& title, const KURL& url) { - // Not needed. dispatchDidReceiveTitle is called immediately after this. - // url is used to update the Apple port history items. - verifiedOk(); -} - -String FrameLoaderClientAndroid::userAgent(const KURL& u) { - ASSERT(m_frame); - return m_frame->bridge()->userAgentForURL(&u); -} - -bool FrameLoaderClientAndroid::canCachePage() const { - return true; -} - -void FrameLoaderClientAndroid::download(ResourceHandle* handle, const ResourceRequest&, - const ResourceRequest&, const ResourceResponse&) { - // Get the C++ side of the load listener and tell it to handle the download - android::WebCoreResourceLoader* loader = handle->getInternal()->m_loader; - loader->downloadFile(); -} - -class ChildFrameViewBridge : public WebCoreViewBridge -{ -public: - ChildFrameViewBridge(WebCoreViewBridge* parent, WebCore::FrameAndroid* frame) - : mFrame(frame) - { - setParent(parent); - mFrame->ref(); - } - - virtual ~ChildFrameViewBridge() - { - mFrame->deref(); - } - - virtual void draw(WebCore::GraphicsContext* ctx, - const WebCore::IntRect& rect, bool) - { - // Create a new translated rect from the given rectangle. - WebCore::IntRect transRect(rect); - - // Grab the intersection of transRect and the frame's bounds. - transRect.intersect(this->getBounds()); - - // Move the transRect into the frame's local coordinates. - transRect.move(-this->locX(), -this->locY()); - - // If the rect is non-empty, translate the canvas, add a clip and draw. - SkRect r; - android_setrect(&r, transRect); - if (r.isEmpty()) - return; - // In Frame::markAllMatchesForText(), it does a fake paint. So we need - // to handle the case where platformContext() is null. However, we still - // want to call paint, since WebKit must have called the paint for a reason. - SkCanvas* canvas = ctx->platformContext() ? ctx->platformContext()->mCanvas : NULL; - if (canvas) { - canvas->save(); - canvas->translate(SkIntToScalar(this->locX()), SkIntToScalar(this->locY())); - canvas->clipRect(r); - } - mFrame->paint(ctx, transRect); - if (canvas) - canvas->restore(); - } - - // Bubble up Javascript dialogs to the parent. The top level view will - // take care of displaying them to the user. - virtual void jsAlert(const WebCore::String& url, const WebCore::String& text) - { - getParent()->jsAlert(url, text); - } - virtual bool jsConfirm(const WebCore::String& url, const WebCore::String& text) - { - return getParent()->jsConfirm(url, text); - } - virtual bool jsPrompt(const WebCore::String& url, - const WebCore::String& message, - const WebCore::String& defaultValue, - WebCore::String& result) - { - return getParent()->jsPrompt(url, message, defaultValue, result); - } - -private: - WebCore::FrameAndroid* mFrame; - typedef WebCoreViewBridge INHERITED; -}; - -WTF::PassRefPtr<WebCore::Frame> FrameLoaderClientAndroid::createFrame(const KURL& url, const String& name, - HTMLFrameOwnerElement* ownerElement, const String& referrer, - bool allowsScrolling, int marginWidth, int marginHeight) -{ - Frame* parent = ownerElement->document()->frame(); - FrameLoaderClientAndroid* loaderC = new FrameLoaderClientAndroid; - WebCore::FrameAndroid* newFrame = new WebCore::FrameAndroid(parent->page(), ownerElement, loaderC); - loaderC->setFrame(newFrame); - // Append the subframe to the parent and set the name of the subframe. The name must be set after - // appending the child so that the name becomes unique. - parent->tree()->appendChild(newFrame); - newFrame->tree()->setName(name); - newFrame->setBridge(Android(parent)->bridge()); - // Create a new FrameView and bridge for the child frame to draw into. - WebCore::FrameView* frameView = new WebCore::FrameView(newFrame); - ChildFrameViewBridge* view = new ChildFrameViewBridge(parent->view()->getWebCoreViewBridge(), newFrame); - frameView->setWebCoreViewBridge(view); - // Unref the viewBridge so that frameView is the only reference holder. - Release(view); - newFrame->setView(frameView); - // Frames are initiliazed with a ref count of 1 but since our view bridge is holding onto the frame, deref - // it here. setView also refs the frameView so call deref on the frameView as well. - newFrame->deref(); - frameView->deref(); - newFrame->init(); - newFrame->selectionController()->setFocused(true); - LOGV("::WebCore:: createSubFrame returning %p", newFrame); - - HistoryItem* item = parent->loader()->currentHistoryItem(); - KURL childUrl = url; - FrameLoadType loadType = parent->loader()->loadType(); - FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedHistory; - // If we are moving in the back/forward list, we might want to replace the - // content of this child frame with whatever was there at that point. Reload - // will maintain the frame contents, LoadSame will not. - HistoryItem* childItem = NULL; - if (item && item->children().size() && - (isBackForwardLoadType(loadType) || - loadType == FrameLoadTypeReload || - loadType == FrameLoadTypeReloadAllowingStaleData)) { - childItem = item->childItemWithName(newFrame->tree()->name()); - if (childItem) { - // Use the original url to ensure we get all the side-effects, such - // as onLoad handlers or redirects. - childUrl = childItem->originalURL(); - childLoadType = loadType; - if (isBackForwardLoadType(loadType)) - // For back/forward, remember this item so we can traverse any - // child items as child frames load. - newFrame->loader()->setProvisionalHistoryItem(childItem); - else - // For reload, just reinstall the current item, since a new - // child frame was created but we won't be creating a new - // history item. - newFrame->loader()->setCurrentHistoryItem(childItem); - } - } - RefPtr<Frame> autoFrame = newFrame; -#ifdef ANDROID_FIX - if (childItem && childItem->originalFormData()) - autoFrame->loader()->postFromHistory(childUrl, childItem->originalFormData(), - childItem->originalFormContentType(), childItem->originalFormReferrer(), childLoadType); - else -#endif -#ifdef ANDROID_USER_GESTURE - autoFrame->loader()->load(childUrl, referrer, childLoadType, - String(), NULL, NULL, false); -#else - autoFrame->loader()->load(childUrl, referrer, childLoadType, - String(), NULL, NULL); -#endif - - // onLoad may cuase the frame to be removed from the document. Allow the RefPtr to delete the child frame. - if (!autoFrame->tree()->parent()) - return NULL; - - return autoFrame.release(); -} - -// YouTube flash url path starts with /v/ -static const char slash_v_slash[] = { '/', 'v', '/' }; - -static bool isValidYouTubeVideo(const DeprecatedString& path) -{ - if (!path.isAllASCII()) - return false; - unsigned int len = path.length(); - if (len <= sizeof(slash_v_slash)) // check for more than just /v/ - return false; - DeprecatedString str = path.lower(); - const char* data = str.ascii(); - if (memcmp(data, slash_v_slash, sizeof(slash_v_slash)) != 0) - return false; - // Start after /v/ - for (unsigned int i = sizeof(slash_v_slash); i < len; i++) { - char c = data[i]; - // Check for alpha-numeric characters only. - if (WTF::isASCIIAlphanumeric(c)) - continue; - // The url can have more parameters such as &hl=en after the video id. - // Once we start seeing extra parameters we can return true. - return c == '&' && i > sizeof(slash_v_slash); - } - return true; -} - -static bool isYouTubeUrl(const KURL& url, const String& mimeType) -{ - return url.host().endsWith("youtube.com") && isValidYouTubeVideo(url.path()) - && equalIgnoringCase(mimeType, "application/x-shockwave-flash"); -} - -Widget* FrameLoaderClientAndroid::createPlugin( - const IntSize& size, - Element* element, - const KURL& url, - const WTF::Vector<String, 0u>& names, - const WTF::Vector<String, 0u>& values, - const String& mimeType, - bool loadManually) { - // Create an iframe for youtube urls. - if (isYouTubeUrl(url, mimeType)) { - DeprecatedString str("file:///android_asset/webkit/youtube.html?v="); - str.append(url.path().mid(sizeof(slash_v_slash))); // grab everything after /v/ - RefPtr<Frame> frame = createFrame(KURL(str), String(), static_cast<HTMLFrameOwnerElement*>(element), - String(), false, 0, 0); - return frame ? frame->view() : NULL; - } - PluginViewAndroid* v = - PluginDatabaseAndroid::installedPlugins()->createPluginView( - m_frame, - size, - element, - url, - names, - values, - mimeType, - loadManually); - return v; -} - -void FrameLoaderClientAndroid::redirectDataToPlugin(Widget* pluginWidget) { - // don't support plugin yet - notImplemented(); -} - -Widget* FrameLoaderClientAndroid::createJavaAppletWidget(const IntSize&, Element*, - const KURL& baseURL, const Vector<String>& paramNames, - const Vector<String>& paramValues) { - // don't support widget yet - notImplemented(); - return 0; -} - -// This function is used by the <OBJECT> element to determine the type of -// the contents and work out if it can render it. -ObjectContentType FrameLoaderClientAndroid::objectContentType(const KURL& url, - const String& mimeType) { - if (mimeType.length() == 0) - { - // Guess the mimeType from the extension - if (url.hasPath()) - { - DeprecatedString path = url.path(); - const char* ascii = path.ascii(); - const char* lastIndex = strrchr(ascii, '.'); - static const String image("image/"); - if (lastIndex) - { - String mime(lastIndex + 1); - mime.insert(image, 0); - if (Image::supportsType(mime)) - return ObjectContentImage; - } - } - return ObjectContentFrame; - } - if (equalIgnoringCase(mimeType, "text/html") || - equalIgnoringCase(mimeType, "text/xml") || - equalIgnoringCase(mimeType, "text/") || - equalIgnoringCase(mimeType, "application/xml") || - equalIgnoringCase(mimeType, "application/xhtml+xml") || - equalIgnoringCase(mimeType, "application/x-javascript")) - return ObjectContentFrame; - if (Image::supportsType(mimeType)) - return ObjectContentImage; - return ObjectContentNone; -} - -// This function allows the application to set the correct CSS media -// style. Android could use it to set the media style 'handheld'. Safari -// may use it to set the media style to 'print' when the user wants to print -// a particular web page. -String FrameLoaderClientAndroid::overrideMediaType() const { - lowPriority_notImplemented(); - return String(); -} - -// This function is used to re-attach Javascript<->native code classes. -void FrameLoaderClientAndroid::windowObjectCleared() { - ASSERT(m_frame); - LOGV("::WebCore:: windowObjectCleared called on frame %p for %s\n", - m_frame, m_frame->loader()->url().string().ascii().data()); - m_frame->bridge()->windowObjectCleared(m_frame); -} - -// functions new to Jun-07 tip of tree merge: -ResourceError FrameLoaderClientAndroid::blockedError(ResourceRequest const& request) { - return ResourceError(String(), InternalErrorFileDoesNotExist, String(), String()); -} - -// functions new to Nov-07 tip of tree merge: -void FrameLoaderClientAndroid::didPerformFirstNavigation() const { - // This seems to be just a notification that the UI can listen to, to - // know if the user has performed first navigation action. - // It is called from - // void FrameLoader::addBackForwardItemClippedAtTarget(bool doClip) - // "Navigation" here means a transition from one page to another that - // ends up in the back/forward list. -} - -void FrameLoaderClientAndroid::registerForIconNotification(bool listen) { - if (listen) - android::WebIconDatabase::RegisterForIconNotification(this); - else - android::WebIconDatabase::UnregisterForIconNotification(this); -} - -// This is the WebIconDatabaseClient method for receiving a notification when we -// get the icon for the page. -void FrameLoaderClientAndroid::didAddIconForPageUrl(const String& pageUrl) { - registerForIconNotification(false); - KURL u(pageUrl.deprecatedString()); - if (equalIgnoringRef(u, m_frame->loader()->url())) { - dispatchDidReceiveIcon(); - } -} - -// functions new to Feb-19 tip of tree merge: -// According to the changelog: -// The very Mac-centric "makeDocumentView", "setDocumentViewFromCachedPage", -// and "saveDocumentViewToCachedPage" become "transitionToCommittedForNewPage", -// "transitionToCommittedFromCachedPage", and "savePlatformDataToCachedPage" -// accordingly -void FrameLoaderClientAndroid::savePlatformDataToCachedPage(CachedPage*) { - // don't support page cache - verifiedOk(); -} - -void FrameLoaderClientAndroid::transitionToCommittedFromCachedPage(CachedPage*) { - // don't support page cache - verifiedOk(); -} - -void FrameLoaderClientAndroid::transitionToCommittedForNewPage() { - ASSERT(m_frame); - if (!m_frame->page()->settings()->usesPageCache()) { - m_frame->bridge()->transitionToCommitted(m_frame); - return; - } - - // Remember the old bridge - WebCoreViewBridge* bridge = m_frame->view()->getWebCoreViewBridge(); - Retain(bridge); - - // Remove the old FrameView - m_frame->setView(NULL); - - // Create a new one and set the bridge - FrameView* view = new FrameView(m_frame); - view->setWebCoreViewBridge(bridge); - Release(bridge); - bridge->setView(view); - - // Give the new FrameView to the Frame - m_frame->setView(view); - - // Deref since FrameViews are created with a ref of 1 - view->deref(); - - if (m_frame->ownerRenderer()) - m_frame->ownerRenderer()->setWidget(view); - - m_frame->view()->initScrollbars(); - - m_frame->bridge()->transitionToCommitted(m_frame); -} - -} diff --git a/WebCore/platform/android/FrameLoaderClientAndroid.h b/WebCore/platform/android/FrameLoaderClientAndroid.h deleted file mode 100644 index df4657a..0000000 --- a/WebCore/platform/android/FrameLoaderClientAndroid.h +++ /dev/null @@ -1,216 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef FrameLoaderClientAndroid_h -#define FrameLoaderClientAndroid_h - -#include "FrameLoaderClient.h" -#include "ResourceResponse.h" -#include "WebIconDatabase.h" - -namespace WebCore { - class FrameAndroid; - - class FrameLoaderClientAndroid : public FrameLoaderClient, - android::WebIconDatabaseClient { - public: - FrameLoaderClientAndroid() : m_frame(NULL) {} - void setFrame(FrameAndroid* frame) { m_frame = frame; } - - virtual void frameLoaderDestroyed(); - - virtual bool hasWebView() const; // mainly for assertions - virtual bool hasFrameView() const; // ditto - - virtual bool privateBrowsingEnabled() const; - - virtual void makeRepresentation(DocumentLoader*); - virtual void forceLayout(); - virtual void forceLayoutForNonHTML(); - - virtual void setCopiesOnScroll(); - - virtual void detachedFromParent2(); - virtual void detachedFromParent3(); - virtual void detachedFromParent4(); - - virtual void loadedFromPageCache(); - - virtual void assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader*, const ResourceRequest&); - - virtual void dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse); - virtual void dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&); - virtual void dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&); - virtual void dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&); - virtual void dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int lengthReceived); - virtual void dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier); - virtual void dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError&); - virtual bool dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int length); - - virtual void dispatchDidHandleOnloadEvents(); - virtual void dispatchDidReceiveServerRedirectForProvisionalLoad(); - virtual void dispatchDidCancelClientRedirect(); - virtual void dispatchWillPerformClientRedirect(const KURL&, double interval, double fireDate); - virtual void dispatchDidChangeLocationWithinPage(); - virtual void dispatchWillClose(); - virtual void dispatchDidReceiveIcon(); - virtual void dispatchDidStartProvisionalLoad(); - virtual void dispatchDidReceiveTitle(const String& title); - virtual void dispatchDidCommitLoad(); - virtual void dispatchDidFailProvisionalLoad(const ResourceError&); - virtual void dispatchDidFailLoad(const ResourceError&); - virtual void dispatchDidFinishDocumentLoad(); - virtual void dispatchDidFinishLoad(); - virtual void dispatchDidFirstLayout(); - - virtual Frame* dispatchCreatePage(); - virtual void dispatchShow(); - - virtual void dispatchDecidePolicyForMIMEType(FramePolicyFunction, const String& MIMEType, const ResourceRequest&); - virtual void dispatchDecidePolicyForNewWindowAction(FramePolicyFunction, const NavigationAction&, const ResourceRequest&, const String& frameName); - virtual void dispatchDecidePolicyForNavigationAction(FramePolicyFunction, const NavigationAction&, const ResourceRequest&); - virtual void cancelPolicyCheck(); - - virtual void dispatchUnableToImplementPolicy(const ResourceError&); - - virtual void dispatchWillSubmitForm(FramePolicyFunction, PassRefPtr<FormState>); - - virtual void dispatchDidLoadMainResource(DocumentLoader*); - virtual void revertToProvisionalState(DocumentLoader*); - virtual void setMainDocumentError(DocumentLoader*, const ResourceError&); - virtual void clearUnarchivingState(DocumentLoader*); - - virtual void willChangeEstimatedProgress(); - virtual void didChangeEstimatedProgress(); - virtual void postProgressStartedNotification(); - virtual void postProgressEstimateChangedNotification(); - virtual void postProgressFinishedNotification(); - - virtual void setMainFrameDocumentReady(bool); - - virtual void startDownload(const ResourceRequest&); - - virtual void willChangeTitle(DocumentLoader*); - virtual void didChangeTitle(DocumentLoader*); - - virtual void committedLoad(DocumentLoader*, const char*, int); - virtual void finishedLoading(DocumentLoader*); - virtual void finalSetupForReplace(DocumentLoader*); - - virtual void updateGlobalHistoryForStandardLoad(const KURL&); - virtual void updateGlobalHistoryForReload(const KURL&); - virtual bool shouldGoToHistoryItem(HistoryItem*) const; -#ifdef ANDROID_HISTORY_CLIENT - virtual void dispatchDidAddHistoryItem(HistoryItem*) const; - virtual void dispatchDidRemoveHistoryItem(HistoryItem*, int) const; - virtual void dispatchDidChangeHistoryIndex(BackForwardList*) const; -#endif - - virtual ResourceError cancelledError(const ResourceRequest&); - virtual ResourceError blockedError(const ResourceRequest&); - virtual ResourceError cannotShowURLError(const ResourceRequest&); - virtual ResourceError interruptForPolicyChangeError(const ResourceRequest&); - - virtual ResourceError cannotShowMIMETypeError(const ResourceResponse&); - virtual ResourceError fileDoesNotExistError(const ResourceResponse&); - - virtual bool shouldFallBack(const ResourceError&); - - virtual void setDefersLoading(bool); - - virtual bool willUseArchive(ResourceLoader*, const ResourceRequest&, const KURL& originalURL) const; - virtual bool isArchiveLoadPending(ResourceLoader*) const; - virtual void cancelPendingArchiveLoad(ResourceLoader*); - virtual void clearArchivedResources(); - - virtual bool canHandleRequest(const ResourceRequest&) const; - virtual bool canShowMIMEType(const String& MIMEType) const; - virtual bool representationExistsForURLScheme(const String& URLScheme) const; - virtual String generatedMIMETypeForURLScheme(const String& URLScheme) const; - - virtual void frameLoadCompleted(); - virtual void saveViewStateToItem(HistoryItem*); - virtual void restoreViewState(); - virtual void provisionalLoadStarted(); - virtual void didFinishLoad(); - virtual void prepareForDataSourceReplacement(); - - virtual PassRefPtr<DocumentLoader> createDocumentLoader(const ResourceRequest&, const SubstituteData&); - virtual void setTitle(const String& title, const KURL&); - - virtual String userAgent(const KURL&); - - virtual bool canCachePage() const; - virtual void download(ResourceHandle*, const ResourceRequest&, const ResourceRequest&, const ResourceResponse&); - - virtual WTF::PassRefPtr<WebCore::Frame> createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, - const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight); - virtual Widget* createPlugin(const IntSize&, Element*, const KURL&, - const WTF::Vector<WebCore::String, 0u>&, const WTF::Vector<String, 0u>&, - const String&, bool); - virtual void redirectDataToPlugin(Widget* pluginWidget); - - virtual Widget* createJavaAppletWidget(const IntSize&, Element*, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues); - - virtual ObjectContentType objectContentType(const KURL& url, const String& mimeType); - virtual String overrideMediaType() const; - - virtual void windowObjectCleared(); - - virtual void didPerformFirstNavigation() const; - virtual void registerForIconNotification(bool); - - virtual void savePlatformDataToCachedPage(CachedPage*); - virtual void transitionToCommittedFromCachedPage(CachedPage*); - virtual void transitionToCommittedForNewPage(); - - // WebIconDatabaseClient api - virtual void didAddIconForPageUrl(const String& pageUrl); - private: - FrameAndroid* m_frame; - enum ResourceErrors { - InternalErrorCancelled = -99, - InternalErrorCannotShowUrl, - InternalErrorInterrupted, - InternalErrorCannotShowMimeType, - InternalErrorFileDoesNotExist, - InternalErrorLast - }; - - /* XXX: These must match android.net.http.EventHandler */ - enum EventHandlerErrors { - Error = -1, - ErrorLookup = -2, - ErrorUnsupportedAuthScheme = -3, - ErrorAuth = -4, - ErrorProxyAuth = -5, - ErrorConnect = -6, - ErrorIO = -7, - ErrorTimeout = -8, - ErrorRedirectLoop = -9, - ErrorUnsupportedScheme = -10, - ErrorFailedSslHandshake = -11, - ErrorBadUrl = -12, - ErrorFile = -13, - ErrorFileNotFound = -14, - ErrorTooManyRequests = -15 - }; - }; - -} - -#endif diff --git a/WebCore/platform/android/InspectorClientAndroid.h b/WebCore/platform/android/InspectorClientAndroid.h deleted file mode 100644 index fd1493a..0000000 --- a/WebCore/platform/android/InspectorClientAndroid.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef InspectorClientAndroid_h -#define InspectorClientAndroid_h - -#include "InspectorClient.h" - -namespace WebCore { - -class InspectorClientAndroid : public InspectorClient { -public: - virtual ~InspectorClientAndroid() { } - - virtual void inspectorDestroyed() {} - - virtual Page* createPage() { return NULL; } - - virtual void showWindow() {} - virtual void closeWindow() {} - - virtual void attachWindow() {} - virtual void detachWindow() {} - - virtual void highlight(Node*) {} - virtual void hideHighlight() {} - - virtual void inspectedURLChanged(const String& newURL) {} -// functions new to Feb-19 tip of tree merge: - virtual String localizedStringsURL() { return String(); } -}; - -} - -#endif diff --git a/WebCore/platform/android/JavaVM/jni.h b/WebCore/platform/android/JavaVM/jni.h deleted file mode 100644 index 429dbc3..0000000 --- a/WebCore/platform/android/JavaVM/jni.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef _JNI_COVER_H_ -#define _JNI_COVER_H_ - -#include "nativehelper/jni.h" -#define AttachCurrentThread(a, b) AttachCurrentThread((JNIEnv**) a, b) - -#endif diff --git a/WebCore/platform/android/KeyEventAndroid.cpp b/WebCore/platform/android/KeyEventAndroid.cpp index ede5ae5..6a59e58 100644 --- a/WebCore/platform/android/KeyEventAndroid.cpp +++ b/WebCore/platform/android/KeyEventAndroid.cpp @@ -16,7 +16,6 @@ */ #include "config.h" -#include "DeprecatedString.h" #include "KeyboardCodes.h" #include "NotImplemented.h" #include "PlatformKeyboardEvent.h" @@ -197,19 +196,24 @@ static inline String singleCharacterString(int c) return String(&n, 1); } -PlatformKeyboardEvent::PlatformKeyboardEvent(int keyCode, int keyValue, bool down, bool forceAutoRepeat, bool cap, bool fn, bool sym) - : m_type(down ? KeyDown : KeyUp) - , m_text(singleCharacterString(keyValue)) - , m_unmodifiedText(singleCharacterString(keyValue)) +PlatformKeyboardEvent::PlatformKeyboardEvent(int keyCode, UChar32 unichar, + Type type, int repeatCount, + ModifierKey mods) + : m_type(type) + , m_text(singleCharacterString(unichar)) + , m_unmodifiedText(singleCharacterString(unichar)) , m_keyIdentifier(keyIdentifierForAndroidKeyCode(keyCode)) - , m_autoRepeat(forceAutoRepeat) + , m_autoRepeat(repeatCount > 0) , m_windowsVirtualKeyCode(windowsKeyCodeForKeyEvent(keyCode)) , m_isKeypad(false) - , m_shiftKey(cap) -// FIXME: Mapping fn to alt and sym to ctrl. Is this the desired behavior? - , m_ctrlKey(sym) - , m_altKey(fn) - , m_metaKey(false) + , m_shiftKey((mods & ShiftKey) != 0) + , m_ctrlKey((mods & CtrlKey) != 0) + , m_altKey((mods & AltKey) != 0) + , m_metaKey((mods & MetaKey) != 0) + // added for android + , m_nativeVirtualKeyCode(keyCode) + , m_repeatCount(repeatCount) + , m_unichar(unichar) { // Copied from the mac port if (m_windowsVirtualKeyCode == '\r') { diff --git a/WebCore/platform/android/LocalizedStringsAndroid.cpp b/WebCore/platform/android/LocalizedStringsAndroid.cpp index 6c0255e..329eac9 100644 --- a/WebCore/platform/android/LocalizedStringsAndroid.cpp +++ b/WebCore/platform/android/LocalizedStringsAndroid.cpp @@ -29,6 +29,7 @@ #include "config.h" #include "LocalizedStrings.h" +#include "NotImplemented.h" #include "PlatformString.h" namespace WebCore { @@ -43,4 +44,10 @@ String unknownFileSizeText() return String::fromUTF8("Unknown"); } +String imageTitle(const String& filename, const IntSize& size) +{ + notImplemented(); + return String(); +} + } diff --git a/WebCore/platform/android/PlatformScrollBar.h b/WebCore/platform/android/PlatformScrollBar.h deleted file mode 100644 index e552c8b..0000000 --- a/WebCore/platform/android/PlatformScrollBar.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef PlatformScrollBar_h -#define PlatformScrollBar_h - -#include "Widget.h" -#include "ScrollBar.h" - -namespace WebCore { - -class PlatformScrollbar : public Widget, public Scrollbar { -public: - PlatformScrollbar(ScrollbarClient*, ScrollbarOrientation, ScrollbarControlSize); - virtual ~PlatformScrollbar(); - - virtual bool isWidget() const { return true; } - - virtual int width() const; - virtual int height() const; - virtual void setRect(const IntRect&); - virtual void setEnabled(bool); - virtual void paint(GraphicsContext*, const IntRect& damageRect); - - static int horizontalScrollbarHeight() { return 8; } - static int verticalScrollbarWidth() { return 8; } - -protected: - virtual void updateThumbPosition(); - virtual void updateThumbProportion(); - -}; - -} - -#endif // PlatformScrollBar_h diff --git a/WebCore/platform/android/PlatformScrollBarAndroid.cpp b/WebCore/platform/android/PlatformScrollBarAndroid.cpp deleted file mode 100644 index a087aed..0000000 --- a/WebCore/platform/android/PlatformScrollBarAndroid.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "config.h" -#include "Color.h" -#include "GraphicsContext.h" -#include "PlatformScrollBar.h" -#include "WebCoreViewBridge.h" - -#define MINIMUM_SCROLL_KNOB_HEIGHT 10 -#define SCROLL_BAR_ROUNDING 5 - -class ScrollBarView { -public: - -private: - int m_height; - int m_width; -}; - -namespace WebCore { - -PlatformScrollbar::PlatformScrollbar(ScrollbarClient* client, ScrollbarOrientation o, - ScrollbarControlSize s) : Scrollbar(client, o, s) -{ - -} - -PlatformScrollbar::~PlatformScrollbar() -{ - -} - -int PlatformScrollbar::width() const -{ - return 8; - -} - -int PlatformScrollbar::height() const { - return 8; - -} - -void PlatformScrollbar::setRect(const IntRect& r) -{ -} - -void PlatformScrollbar::setEnabled(bool) -{ - -} - -void PlatformScrollbar::paint(GraphicsContext* gc, const IntRect& damageRect) -{ -} - -void PlatformScrollbar::updateThumbPosition() -{ -} - -void PlatformScrollbar::updateThumbProportion() -{ -} - -} diff --git a/WebCore/platform/android/QLineEditAndroid.cpp b/WebCore/platform/android/QLineEditAndroid.cpp deleted file mode 100644 index b31baf5..0000000 --- a/WebCore/platform/android/QLineEditAndroid.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "config.h" - -#include "KWQLineEdit.h" -#include "IntPoint.h" - -#define LOG_TAG "WebCore" -#undef LOG -#include <utils/Log.h> - -using namespace WebCore; - -class KWQTextFieldController { -public: - int m_maxLength; - int m_cursorPosition; - bool m_edited; - String m_placeholderString; - String m_text; -}; - -QLineEdit::QLineEdit(Type type) : m_type(type) -{ - printf("============ QLineEdit %d\n", type); - - m_controller = new KWQTextFieldController; - - m_controller->m_maxLength = 32; // ??? - m_controller->m_cursorPosition = 0; - m_controller->m_edited = false; -} - -QLineEdit::~QLineEdit() -{ - delete m_controller; -} - -int QLineEdit::maxLength() const -{ - return m_controller->m_maxLength; -} - -void QLineEdit::setMaxLength(int ml) -{ - m_controller->m_maxLength = ml; -} - -String QLineEdit::text() const -{ - return m_controller->m_text; -} - -void QLineEdit::setText(String const& text) -{ - m_controller->m_text = text; -} - -int QLineEdit::cursorPosition() const -{ - return m_controller->m_cursorPosition; -} - -void QLineEdit::setCursorPosition(int cp) -{ - m_controller->m_cursorPosition = cp; -} - -void QLineEdit::setPlaceholderString(String const& ph) -{ - m_controller->m_placeholderString = ph; -} - -bool QLineEdit::edited() const -{ - return m_controller->m_edited; -} - -void QLineEdit::setEdited(bool edited) -{ - m_controller->m_edited = edited; -} - -void QLineEdit::setFont(Font const&) { } -void QLineEdit::setAlignment(HorizontalAlignment) { } -void QLineEdit::setWritingDirection(TextDirection) { } -void QLineEdit::setReadOnly(bool) { } -void QLineEdit::setColors(Color const&, Color const&) { } -IntSize QLineEdit::sizeForCharacterWidth(int) const { return IntSize(); } -int QLineEdit::baselinePosition(int) const { return 0; } -void QLineEdit::setLiveSearch(bool) { } - -#define notImplemented() { LOGV("%s: Not Implemented", __FUNCTION__); } - -void QLineEdit::selectAll() { notImplemented(); } -void QLineEdit::addSearchResult() { notImplemented(); } -int QLineEdit::selectionStart() const { notImplemented(); return 0; } -bool QLineEdit::hasSelectedText() const { notImplemented(); return 0; } -String QLineEdit::selectedText() const { notImplemented(); return String(); } -void QLineEdit::setAutoSaveName(String const&) { notImplemented(); } -bool QLineEdit::checksDescendantsForFocus() const { notImplemented(); return false; } -void QLineEdit::setSelection(int,int) { notImplemented(); } -void QLineEdit::setMaxResults(int) { notImplemented(); } - -Widget::FocusPolicy QLineEdit::focusPolicy() const { notImplemented(); return NoFocus; } diff --git a/WebCore/platform/android/RenderSkinAndroid.cpp b/WebCore/platform/android/RenderSkinAndroid.cpp deleted file mode 100644 index fc256d2..0000000 --- a/WebCore/platform/android/RenderSkinAndroid.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* libs/WebKitLib/WebKit/WebCore/rendering/RenderSkinAndroid.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "config.h" -#include "RenderSkinAndroid.h" -#include "RenderSkinButton.h" -#include "RenderSkinCombo.h" -#include "RenderSkinRadio.h" -#include "SkImageDecoder.h" - -#define LOG_TAG "WebCore" -#undef LOG -#include "utils/Log.h" -#include "utils/AssetManager.h" -#include "utils/Asset.h" - -namespace WebCore { - -RenderSkinAndroid::RenderSkinAndroid() - : m_height(0) - , m_width(0) -{} - -void RenderSkinAndroid::Init(android::AssetManager* am) -{ - RenderSkinButton::Init(am); - RenderSkinCombo::Init(am); - RenderSkinRadio::Init(am); -} - -bool RenderSkinAndroid::DecodeBitmap(android::AssetManager* am, const char* fileName, SkBitmap* bitmap) -{ - android::Asset* asset = am->open(fileName, android::Asset::ACCESS_BUFFER); - if (!asset) { - asset = am->openNonAsset(fileName, android::Asset::ACCESS_BUFFER); - if (!asset) { - LOGD("RenderSkinAndroid: File \"%s\" not found.\n", fileName); - return false; - } - } - - bool success = SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(), bitmap); - if (!success) { - LOGD("RenderSkinAndroid: Failed to decode %s\n", fileName); - } - - delete asset; - return success; -} - -} // namespace WebCore diff --git a/WebCore/platform/android/RenderSkinAndroid.h b/WebCore/platform/android/RenderSkinAndroid.h deleted file mode 100644 index 2226e7f..0000000 --- a/WebCore/platform/android/RenderSkinAndroid.h +++ /dev/null @@ -1,83 +0,0 @@ -/* libs/WebKitLib/WebKit/WebCore/rendering/RenderSkinAndroid.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef RenderSkinAndroid_h -#define RenderSkinAndroid_h - -namespace android { - class AssetManager; -} - -class SkBitmap; - -namespace WebCore { -class Node; -class PlatformGraphicsContext; - -/* RenderSkinAndroid is the base class for all RenderSkins. Form elements each have a - * subclass for drawing themselves. - */ -class RenderSkinAndroid -{ -public: - RenderSkinAndroid(); - virtual ~RenderSkinAndroid() {} - - enum State { - kDisabled, - kNormal, - kFocused, - - kNumStates - }; - - /** - * Initialize the Android skinning system. The AssetManager may be used to find resources used - * in rendering. - */ - static void Init(android::AssetManager*); - - /* DecodeBitmap determines which file to use, with the given fileName of the form - * "images/bitmap.png", and uses the asset manager to select the exact one. It - * returns true if it successfully decoded the bitmap, false otherwise. - */ - static bool DecodeBitmap(android::AssetManager* am, const char* fileName, SkBitmap* bitmap); - - /* draw() tells the skin to draw itself, and returns true if the skin needs - * a redraw to animations, false otherwise - */ - virtual bool draw(PlatformGraphicsContext*) { return false; } - - /* notifyState() checks to see if the element is checked, focused, and enabled - * it must be implemented in the subclass - */ - virtual void notifyState(Node* element) { } - - /* setDim() tells the skin its width and height - */ - virtual void setDim(int width, int height) { m_width = width; m_height = height; } - -protected: - int m_height; - int m_width; - -}; - -} // WebCore - -#endif - diff --git a/WebCore/platform/android/RenderSkinButton.cpp b/WebCore/platform/android/RenderSkinButton.cpp deleted file mode 100644 index 73e6ea0..0000000 --- a/WebCore/platform/android/RenderSkinButton.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2006, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "config.h" -#include "AndroidLog.h" -#include "android_graphics.h" -#include "Document.h" -#include "IntRect.h" -#include "Node.h" -#include "RenderSkinButton.h" -#include "SkCanvas.h" -#include "SkNinePatch.h" -#include "SkRect.h" -#include "utils/Debug.h" - -struct PatchData { - const char* name; - int8_t outset, margin; -}; - -static const PatchData gFiles[] = - { - { "res/drawable/btn_default_normal_disable.9.png", 2, 7 }, - { "res/drawable/btn_default_normal.9.png", 2, 7 }, - { "res/drawable/btn_default_selected.9.png", 2, 7 } - }; - -static SkBitmap gButton[sizeof(gFiles)/sizeof(gFiles[0])]; -static bool gDecoded; - -namespace WebCore { - -void RenderSkinButton::Init(android::AssetManager* am) -{ - static bool gInited; - if (gInited) - return; - - gInited = true; - gDecoded = true; - for (size_t i = 0; i < sizeof(gFiles)/sizeof(gFiles[0]); i++) { - if (!RenderSkinAndroid::DecodeBitmap(am, gFiles[i].name, &gButton[i])) { - gDecoded = false; - ANDROID_LOGD("RenderSkinButton::Init: button assets failed to decode\n\tBrowser buttons will not draw"); - break; - } - } - - // Ensure our enums properly line up with our arrays. - android::CompileTimeAssert<(RenderSkinAndroid::kDisabled == 0)> a1; - android::CompileTimeAssert<(RenderSkinAndroid::kNormal == 1)> a2; - android::CompileTimeAssert<(RenderSkinAndroid::kFocused == 2)> a3; -} - -void RenderSkinButton::Draw(SkCanvas* canvas, const IntRect& r, RenderSkinAndroid::State newState) -{ - // If we failed to decode, do nothing. This way the browser still works, - // and webkit will still draw the label and layout space for us. - if (!gDecoded) { - return; - } - - // Ensure that the state is within the valid range of our array. - SkASSERT(newState < RenderSkinAndroid::kNumStates && newState >= 0); - - // Set up the ninepatch information for drawing. - SkRect bounds; - android_setrect(&bounds, r); - const PatchData& pd = gFiles[newState]; - int marginValue = pd.margin + pd.outset; - - SkIRect margin; - - margin.set(marginValue, marginValue, marginValue, marginValue); - - // Draw to the canvas. - SkNinePatch::DrawNine(canvas, bounds, gButton[newState], margin); -} - -} //WebCore - diff --git a/WebCore/platform/android/RenderSkinButton.h b/WebCore/platform/android/RenderSkinButton.h deleted file mode 100644 index 3089a0b..0000000 --- a/WebCore/platform/android/RenderSkinButton.h +++ /dev/null @@ -1,44 +0,0 @@ -/* libs/WebKitLib/WebKit/WebCore/platform/android/RenderSkinButton.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef RenderSkinButton_h -#define RenderSkinButton_h - -#include "RenderSkinAndroid.h" - -class SkCanvas; - -namespace WebCore { -class IntRect; -class RenderSkinButton -{ -public: - /** - * Initialize the class before use. Uses the AssetManager to initialize any - * bitmaps the class may use. - */ - static void Init(android::AssetManager*); - /** - * Draw the skin to the canvas, using the rectangle for its bounds and the - * State to determine which skin to use, i.e. focused or not focused. - */ - static void Draw(SkCanvas* , const IntRect& , RenderSkinAndroid::State); -}; - -} // WebCore -#endif - diff --git a/WebCore/platform/android/RenderSkinCombo.cpp b/WebCore/platform/android/RenderSkinCombo.cpp deleted file mode 100644 index 527cb10..0000000 --- a/WebCore/platform/android/RenderSkinCombo.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* libs/WebKitLib/WebKit/WebCore/platform/android/RenderSkinCombo.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "config.h" -#include "Document.h" -#include "Node.h" -#include "PlatformGraphicsContext.h" -#include "RenderSkinCombo.h" -#include "SkCanvas.h" -#include "SkNinePatch.h" - -namespace WebCore { - -static const int margin = 2; -static const SkIRect mar = { margin, margin, RenderSkinCombo::extraWidth(), margin }; - -SkBitmap RenderSkinCombo::m_bitmap[2]; -bool RenderSkinCombo::m_decoded; - -RenderSkinCombo::RenderSkinCombo() -{ - m_height = 20; - m_width = 75; - m_state = kNormal; - m_bounds.set(0, 0, SkIntToScalar(m_width), SkIntToScalar(m_height)); -} - -void RenderSkinCombo::Init(android::AssetManager* am) -{ - if (m_decoded) - return; - // Maybe short circuiting is fine, since I don't even draw if one state is not decoded properly - // but is that necessary in the final version? - m_decoded = RenderSkinAndroid::DecodeBitmap(am, "images/combobox-noHighlight.png", &m_bitmap[kNormal]); - m_decoded = RenderSkinAndroid::DecodeBitmap(am, "images/combobox-disabled.png", &m_bitmap[kDisabled]) && m_decoded; -} - - -bool RenderSkinCombo::draw(PlatformGraphicsContext *p) -{ - // The text is drawn right next to the left side - should I draw the box slightly to the left? - if (!m_decoded) - return false; - SkCanvas* canvas = p->mCanvas; - SkNinePatch::DrawNine(canvas, m_bounds, m_bitmap[m_state], mar); - return false; -} - -void RenderSkinCombo::notifyState(Node* element) -{ - m_state = kDisabled; - if (!element) - return; - if (element->isEnabled()) - m_state = kNormal; -} - -void RenderSkinCombo::setDim(int width, int height) -{ - if (width != m_width || height != m_height) { - m_width = width; - if (height < (margin<<1) + 1) - height = (margin<<1) + 1; - else - m_height = height; - m_bounds.set(0, 0, SkIntToScalar(m_width), SkIntToScalar(m_height)); - } -} - -} //WebCore diff --git a/WebCore/platform/android/RenderSkinCombo.h b/WebCore/platform/android/RenderSkinCombo.h deleted file mode 100644 index f962fcc..0000000 --- a/WebCore/platform/android/RenderSkinCombo.h +++ /dev/null @@ -1,61 +0,0 @@ -/* libs/WebKitLib/WebKit/WebCore/platform/android/RenderSkinCombo.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef RenderSkinCombo_h -#define RenderSkinCombo_h - -#include "RenderSkinAndroid.h" -#include "SkBitmap.h" -#include "SkPaint.h" -#include "SkRect.h" - -namespace WebCore { - -// This is very similar to RenderSkinButton - maybe they should be the same class? -class RenderSkinCombo : public RenderSkinAndroid -{ -public: - RenderSkinCombo(); - virtual ~RenderSkinCombo() {} - - /** - * Initialize the class before use. Uses the AssetManager to initialize any bitmaps the class may use. - */ - static void Init(android::AssetManager*); - - virtual bool draw(PlatformGraphicsContext*); - virtual void notifyState(Node* element); - virtual void setDim(int width, int height); - - // The image is an extra 30 pixels wider than the RenderObject, so this accounts for that. - static int extraWidth() { return arrowMargin; } - -private: - SkRect m_bounds; // Maybe this should become a protected member of RenderSkinAndroid... - static SkBitmap m_bitmap[2]; // Collection of assets for a combo box - static bool m_decoded; // True if all assets were decoded - SkPaint m_paint; - // Could probably move m_state into RenderSkinAndroid... - // Although notice that the state for RenderSkinRadio is just an integer, and it behaves differently - State m_state; - - static const int arrowMargin = 30; -}; - -} // WebCore - -#endif diff --git a/WebCore/platform/android/RenderSkinRadio.cpp b/WebCore/platform/android/RenderSkinRadio.cpp deleted file mode 100644 index d610fa7..0000000 --- a/WebCore/platform/android/RenderSkinRadio.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* libs/WebKitLib/WebKit/WebCore/platform/android/RenderSkinRadio.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "config.h" -#include "Document.h" -#include "Node.h" -#include "PlatformGraphicsContext.h" -#include "RenderSkinRadio.h" -#include "SkCanvas.h" - -static const char* checks[] = { "res/drawable/checkbox_off_background.png", "res/drawable/checkbox_on_background.png", - "res/drawable/radiobutton_off_background.png", "res/drawable/radiobutton_on_background.png"}; -static const SkScalar SIZE = SkIntToScalar(19); // Default height and width - corresponds with the bitmap - perhaps we should query the bitmap. - -namespace WebCore { - -SkBitmap RenderSkinRadio::m_bitmap[4]; -bool RenderSkinRadio::m_decoded; - -RenderSkinRadio::RenderSkinRadio(bool isCheckBox) -{ - m_checked = false; - m_enabled = true; - m_isCheckBox = isCheckBox; -} - -void RenderSkinRadio::Init(android::AssetManager* am) -{ - if (m_decoded) - return; - m_decoded = RenderSkinAndroid::DecodeBitmap(am, checks[0], &m_bitmap[0]); - m_decoded = RenderSkinAndroid::DecodeBitmap(am, checks[1], &m_bitmap[1]) && m_decoded; - m_decoded = RenderSkinAndroid::DecodeBitmap(am, checks[2], &m_bitmap[2]) && m_decoded; - m_decoded = RenderSkinAndroid::DecodeBitmap(am, checks[3], &m_bitmap[3]) && m_decoded; -} - - -bool RenderSkinRadio::draw(PlatformGraphicsContext* pgc) -{ - if (!m_decoded) // Seems like an unnecessary slowdown, since it should always decode - return false; - SkCanvas* canvas = pgc->mCanvas; - if (!m_enabled) { - SkRect r; - r.set(0, 0, m_size, m_size); - canvas->saveLayerAlpha(&r, 0x80); - } else { - canvas->save(); - } - if (SIZE != m_size) { - SkScalar scale = SkScalarDiv(m_size, SIZE); - canvas->scale(scale, scale); - } - canvas->drawBitmap(m_bitmap[m_checked + 2*(!m_isCheckBox)], 0, 0, &m_paint); - canvas->restore(); - return false; // True if we need to redraw -} - -void RenderSkinRadio::notifyState(Node* element) -{ - if (!element) { - return; - } - m_checked = element->isChecked(); - m_enabled = element->isEnabled(); -} - -} //WebCore - diff --git a/WebCore/platform/android/RenderSkinRadio.h b/WebCore/platform/android/RenderSkinRadio.h deleted file mode 100644 index 918cdf5..0000000 --- a/WebCore/platform/android/RenderSkinRadio.h +++ /dev/null @@ -1,59 +0,0 @@ -/* libs/WebKitLib/WebKit/WebCore/platform/android/RenderSkinRadio.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef RenderSkinRadio_h -#define RenderSkinRadio_h - -#include "RenderSkinAndroid.h" -#include "SkBitmap.h" -#include "SkPaint.h" -#include "SkRect.h" - -namespace WebCore { - -class Node; - -/* RenderSkin for a radio button or a checkbox - */ -class RenderSkinRadio : public RenderSkinAndroid -{ -public: - /* This skin represents a checkbox if isCheckBox is true, otherwise it is a radio button */ - RenderSkinRadio(bool isCheckBox); - virtual ~RenderSkinRadio() {} - - /** - * Initialize the class before use. Uses the AssetManager to initialize any bitmaps the class may use. - */ - static void Init(android::AssetManager*); - - virtual bool draw(PlatformGraphicsContext*); - virtual void notifyState(Node* element); - virtual void setDim(int width, int height) { RenderSkinAndroid::setDim(width, height); m_size = SkIntToScalar(height); } - -protected: - static SkBitmap m_bitmap[4]; // Bitmaps representing all states - static bool m_decoded; // True if all assets were decoded. - bool m_isCheckBox; - bool m_checked; - bool m_enabled; - SkPaint m_paint; - SkScalar m_size; -}; - -} // WebCore -#endif diff --git a/WebCore/platform/android/RenderThemeAndroid.cpp b/WebCore/platform/android/RenderThemeAndroid.cpp index 2e8cb86..77dd0c2 100644 --- a/WebCore/platform/android/RenderThemeAndroid.cpp +++ b/WebCore/platform/android/RenderThemeAndroid.cpp @@ -34,6 +34,11 @@ // so that our button images are large enough to properly fit the text. #define BUTTON_PADDING 18 +// Add padding to the fontSize of ListBoxes to get their maximum sizes. +// Listboxes often have a specified size. Since we change them into dropdowns, +// we want a much smaller height, which encompasses the text. +#define LISTBOX_PADDING 5 + namespace WebCore { static SkCanvas* getCanvasFromInfo(const RenderObject::PaintInfo& info) { @@ -120,7 +125,7 @@ Color RenderThemeAndroid::platformTextSearchHighlightColor() const return Color(192, 192, 192); } -short RenderThemeAndroid::baselinePosition(const RenderObject* obj) const +int RenderThemeAndroid::baselinePosition(const RenderObject* obj) const { // From the description of this function in RenderTheme.h: // A method to obtain the baseline position for a "leaf" control. This will only be used if a baseline @@ -156,12 +161,12 @@ void RenderThemeAndroid::addIntrinsicMargins(RenderStyle* style) const } } -bool RenderThemeAndroid::supportsFocus(EAppearance appearance) +bool RenderThemeAndroid::supportsFocus(ControlPart appearance) { switch (appearance) { - case PushButtonAppearance: - case ButtonAppearance: - case TextFieldAppearance: + case PushButtonPart: + case ButtonPart: + case TextFieldPart: return true; default: return false; @@ -174,7 +179,7 @@ void RenderThemeAndroid::adjustButtonStyle(CSSStyleSelector* selector, RenderSty { // Padding code is taken from RenderThemeSafari.cpp // It makes sure we have enough space for the button text. - const int padding = 12; + const int padding = 8; style->setPaddingLeft(Length(padding, Fixed)); style->setPaddingRight(Length(padding, Fixed)); style->setMinHeight(Length(style->fontSize() + BUTTON_PADDING, Fixed)); @@ -249,6 +254,13 @@ bool RenderThemeAndroid::paintSearchField(RenderObject* o, const RenderObject::P return true; } +void RenderThemeAndroid::adjustListboxStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +{ + style->setPaddingRight(Length(RenderSkinCombo::extraWidth(), Fixed)); + style->setMaxHeight(Length(style->fontSize() + LISTBOX_PADDING, Fixed)); + addIntrinsicMargins(style); +} + void RenderThemeAndroid::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const { style->setPaddingRight(Length(RenderSkinCombo::extraWidth(), Fixed)); @@ -296,17 +308,17 @@ bool RenderThemeAndroid::paintMenuListButton(RenderObject* o, const RenderObject bool RenderThemeAndroid::supportsFocusRing(const RenderStyle* style) const { return (style->opacity() > 0 && style->hasAppearance() - && style->appearance() != TextFieldAppearance - && style->appearance() != SearchFieldAppearance - && style->appearance() != TextAreaAppearance - && style->appearance() != CheckboxAppearance - && style->appearance() != RadioAppearance - && style->appearance() != PushButtonAppearance - && style->appearance() != SquareButtonAppearance - && style->appearance() != ButtonAppearance - && style->appearance() != ButtonBevelAppearance - && style->appearance() != MenulistAppearance - && style->appearance() != MenulistButtonAppearance + && style->appearance() != TextFieldPart + && style->appearance() != SearchFieldPart + && style->appearance() != TextAreaPart + && style->appearance() != CheckboxPart + && style->appearance() != RadioPart + && style->appearance() != PushButtonPart + && style->appearance() != SquareButtonPart + && style->appearance() != ButtonPart + && style->appearance() != ButtonBevelPart + && style->appearance() != MenulistPart + && style->appearance() != MenulistButtonPart ); } diff --git a/WebCore/platform/android/RenderThemeAndroid.h b/WebCore/platform/android/RenderThemeAndroid.h index 4233f6f..e1a8f48 100644 --- a/WebCore/platform/android/RenderThemeAndroid.h +++ b/WebCore/platform/android/RenderThemeAndroid.h @@ -45,7 +45,7 @@ public: // A method asking if the theme's controls actually care about redrawing when hovered. virtual bool supportsHover(const RenderStyle* style) const { return style->affectedByHoverRules(); } - virtual short baselinePosition(const RenderObject*) const; + virtual int baselinePosition(const RenderObject*) const; virtual Color platformActiveSelectionBackgroundColor() const; virtual Color platformInactiveSelectionBackgroundColor() const; @@ -75,6 +75,7 @@ protected: bool paintCombo(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& ir); + virtual void adjustListboxStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const; virtual void adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const; virtual bool paintMenuList(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r); @@ -89,7 +90,7 @@ private: void addIntrinsicMargins(RenderStyle* style) const; void close(); - bool supportsFocus(EAppearance appearance); + bool supportsFocus(ControlPart appearance); // FIXME: There should be a way to use one RenderSkinRadio for both radio and checkbox RenderSkinRadio* m_radio; RenderSkinRadio* m_checkbox; diff --git a/WebCore/platform/android/ScreenAndroid.cpp b/WebCore/platform/android/ScreenAndroid.cpp index 6cf8bc9..ebf1a85 100644 --- a/WebCore/platform/android/ScreenAndroid.cpp +++ b/WebCore/platform/android/ScreenAndroid.cpp @@ -23,13 +23,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#define LOG_TAG "WebCore" #include "config.h" #include "Screen.h" #include "FloatRect.h" #include "Widget.h" -#define LOG_TAG "WebCore" +#undef LOG // FIXME: Still have to do this to get the log to show up #include "utils/Log.h" #include "ui/SurfaceComposerClient.h" @@ -61,8 +62,25 @@ bool screenIsMonochrome(Widget* page) int Screen::orientation() const { android::DisplayInfo info; - android::SurfaceComposerClient::getDisplayInfo(android::DisplayID(0), &info); - return info.orientation; + android::SurfaceComposerClient::getDisplayInfo( + android::DisplayID(0), &info); + // getDisplayInfo returns an enum describing the orientation. Map the enum + // to the values described here + // (http://developer.apple.com/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/chapter_8_section_6.html) + switch (info.orientation) { + case android::ISurfaceComposer::eOrientationDefault: + return 0; + case android::ISurfaceComposer::eOrientation90: + return 90; + case android::ISurfaceComposer::eOrientation180: + return 180; + case android::ISurfaceComposer::eOrientation270: + return -90; + default: + LOGE("Bad orientation returned from getDisplayIndo %d", + info.orientation); + return 0; + } } #endif diff --git a/WebCore/platform/android/ScrollViewAndroid.cpp b/WebCore/platform/android/ScrollViewAndroid.cpp index 1ac819d..812428c 100644 --- a/WebCore/platform/android/ScrollViewAndroid.cpp +++ b/WebCore/platform/android/ScrollViewAndroid.cpp @@ -14,27 +14,20 @@ ** See the License for the specific language governing permissions and ** limitations under the License. */ +#define LOG_TAG "WebCore" #include "config.h" #include "ScrollView.h" #include "FloatRect.h" +#include "Frame.h" +#include "FrameView.h" +#include "HostWindow.h" #include "IntRect.h" - +#include "NotImplemented.h" +#include "WebCoreFrameBridge.h" #include "WebCoreViewBridge.h" - -#define LOG_TAG "WebCore" -#undef LOG -#include "utils/Log.h" - -/* hack to allow the DOM to communicate how to interpret inval requests, since - it doesn't have the notion of distinguishing between the screen and the DOM - but we do, since we have a copy of the display in our picture, and we don't - want to rebuild the picture unless the DOM has actually been changed. -*/ -bool gAndroid_treatInvalForScreen; - -#define verifiedOk() // no need to do anything in this function +#include "WebViewCore.h" /* This class implementation does NOT actually emulate the Qt ScrollView. @@ -53,282 +46,55 @@ bool gAndroid_treatInvalForScreen; namespace WebCore { -struct ScrollView::ScrollViewPrivate -{ -public: - ScrollViewPrivate() : - hasStaticBackground(false), ignoreUpdateContents(false), - vScrollbarMode(ScrollbarAuto), - hScrollbarMode(ScrollbarAuto) {} - IntSize contentsSize; - bool hasStaticBackground; - bool ignoreUpdateContents; - ScrollbarMode vScrollbarMode; - ScrollbarMode hScrollbarMode; -}; - -ScrollView::ScrollView() -{ - m_data = new ScrollViewPrivate; -} - -ScrollView::~ScrollView() +IntRect ScrollView::platformVisibleContentRect(bool includeScrollbars) const { - delete m_data; + IntRect rect = platformWidget()->getBounds(); + // This makes subframes draw correctly, since subframes cannot scroll. + if (parent()) + return IntRect(0, 0, rect.width(), rect.height()); + return rect; } -int ScrollView::visibleWidth() const +IntSize ScrollView::platformContentsSize() const { - LOG_ASSERT(this->getWebCoreViewBridge(), "ScrollView does not have a WebCoreViewBridge"); - return this->getWebCoreViewBridge()->width(); + return m_contentsSize; } -int ScrollView::visibleHeight() const +void ScrollView::platformSetScrollPosition(const WebCore::IntPoint& pt) { - LOG_ASSERT(this->getWebCoreViewBridge(), "ScrollView does not have a WebCoreViewBridge"); - return this->getWebCoreViewBridge()->height(); -} - -FloatRect ScrollView::visibleContentRect() const -{ - LOG_ASSERT(this->getWebCoreViewBridge(), "ScrollView does not have a WebCoreViewBridge"); - IntRect rect = this->getWebCoreViewBridge()->getBounds(); - // FIXME: This is a hack to get subframes drawing correctly. Since subframes cannot - // scroll, we know that if this view has a parent, the visible rect is (0, 0, w, h) - if (this->getWebCoreViewBridge()->getParent()) - return FloatRect(0, 0, rect.width(), rect.height()); - return FloatRect(rect.x(), rect.y(), rect.width(), rect.height()); -} - -int ScrollView::contentsWidth() const -{ - return m_data->contentsSize.width(); -} - -int ScrollView::contentsHeight() const -{ - return m_data->contentsSize.height(); -} - -int ScrollView::contentsX() const -{ - return scrollOffset().width(); -} - -int ScrollView::contentsY() const -{ - return scrollOffset().height(); -} - -IntSize ScrollView::scrollOffset() const -{ - LOG_ASSERT(this->getWebCoreViewBridge(), "ScrollView does not have a WebCoreViewBridge"); - WebCoreViewBridge* bridge = this->getWebCoreViewBridge(); - // FIXME: This is a hack to get subframes drawing correctly. Since subframes cannot - // scroll, we know that if this view has a parent, the scroll offset is always (0, 0) - if (bridge->getParent()) - return IntSize(0, 0); - return IntSize(bridge->locX(), bridge->locY()); -} - -void ScrollView::scrollBy(int dx, int dy) -{ - LOG_ASSERT(this->getWebCoreViewBridge(), "ScrollView does not have a WebCoreViewBridge"); - this->getWebCoreViewBridge()->scrollBy(dx, dy); -} - -void WebCore::ScrollView::update() -{ - LOG_ASSERT(this->getWebCoreViewBridge(), "ScrollView does not have a WebCoreViewBridge"); - this->getWebCoreViewBridge()->contentInvalidate(); -} - -void WebCore::ScrollView::scrollRectIntoViewRecursively(WebCore::IntRect const& r) -{ - LOG_ASSERT(this->getWebCoreViewBridge(), "ScrollView does not have a WebCoreViewBridge"); - int x = r.x(); - int y = r.y(); - IntPoint p(x > 0 ? x : 0, y > 0 ? y : 0); - ScrollView* view = this; - while (view) { - view->setContentsPos(p.x(), p.y()); - p.move(view->x() - view->scrollOffset().width(), view->y() - view->scrollOffset().height()); - if (view->getWebCoreViewBridge()->getParent()) - view = static_cast<ScrollView*>(view->getWebCoreViewBridge()->getParent()->widget()); - else - view = NULL; - } -} - -WebCore::FloatRect WebCore::ScrollView::visibleContentRectConsideringExternalScrollers() const { - return FloatRect(contentsX(), contentsY(), contentsWidth(), contentsHeight()); -} - -void ScrollView::setContentsPos(int x, int y) -{ - LOG_ASSERT(this->getWebCoreViewBridge(), "ScrollView does not have a WebCoreViewBridge"); - this->getWebCoreViewBridge()->scrollTo(x, y); -} - -//--------------------------------------------------------------------- -// Scroll bar methods -// -// These methods are largely unimplemented meaning that the -// state of the scroll bars in the only data maintained. If -// a scroll bar is needed, the set(V|H)ScrollbarMode methods -// need to update the scroll bar widget through the java -// layer and display the new scroll bars. -// -//--------------------------------------------------------------------- - -void ScrollView::setVScrollbarMode(ScrollbarMode vMode) -{ - m_data->vScrollbarMode = vMode; -} - -void ScrollView::setHScrollbarMode(ScrollbarMode hMode) -{ - m_data->hScrollbarMode = hMode; -} - -void ScrollView::setScrollbarsMode(ScrollbarMode mode) -{ - m_data->hScrollbarMode = mode; - m_data->vScrollbarMode = mode; -} - -ScrollbarMode ScrollView::vScrollbarMode() const -{ - return m_data->vScrollbarMode; -} - -ScrollbarMode ScrollView::hScrollbarMode() const -{ - return m_data->hScrollbarMode; -} - -void ScrollView::suppressScrollbars(bool suppressed, bool repaintOnUnsuppress) -{ - verifiedOk(); -} - -//--------------------------------------------------------------------- -// End Scroll bar methods -//--------------------------------------------------------------------- - -void ScrollView::addChild(Widget* child) -{ - LOG_ASSERT(this->getWebCoreViewBridge(), "ScrollView does not have a WebCoreViewBridge"); - WebCoreViewBridge* childBridge = child->getWebCoreViewBridge(); - // FIXME: For now just check this, it should be an assert down the road. - if (!childBridge) - { - LOGV("childBridge is not set"); + if (parent()) // don't attempt to scroll subframes; they're fully visible return; - } - LOG_ASSERT(child != this, "Child has no view bridge or child == this!"); - WebCoreViewBridge* thisBridge = this->getWebCoreViewBridge(); - LOG_ASSERT(thisBridge && thisBridge != childBridge, "Our bridge is not set or thisBridge == childBridge!"); - LOGV("Adding parent"); - childBridge->setParent(thisBridge); + android::WebViewCore::getWebViewCore(this)->scrollTo(pt.x(), pt.y()); } -void ScrollView::ignoreUpdateContents(bool ignore) +void ScrollView::platformScrollbarModes(ScrollbarMode& h, ScrollbarMode& v) const { - m_data->ignoreUpdateContents = ignore; + h = v = ScrollbarAlwaysOff; } -void ScrollView::removeChild(Widget* child) +bool ScrollView::platformProhibitsScrolling() { - // FIXME: Make this only an assert once all widgets have views - if (!child->getWebCoreViewBridge()) - { - LOGV("child has no bridge"); - return; - } - LOG_ASSERT(child->getWebCoreViewBridge(), "Child has no view bridge"); - child->getWebCoreViewBridge()->setParent(NULL); -} - -void ScrollView::resizeContents(int w, int h) -{ - LOG_ASSERT(this->getWebCoreViewBridge(), "ScrollView does not have a WebCoreViewBridge"); - if (w < 0) - w = 0; - if (h < 0) - h = 0; - - IntSize newSize(w, h); - m_data->contentsSize = newSize; -} - -void ScrollView::updateContents(const IntRect &rect, bool now) -{ - LOG_ASSERT(this->getWebCoreViewBridge(), - "ScrollView does not have a WebCoreViewBridge"); - - WebCoreViewBridge* bridge = this->getWebCoreViewBridge(); - - if (gAndroid_treatInvalForScreen) { -// SkDebugf("------ contentInvalidate sent to viewInvalidate [%d %d]\n", rect.width(), rect.height()); - bridge->viewInvalidate(); - } else if (m_data->ignoreUpdateContents == false) { - bridge->contentInvalidate(rect); - } -} - -IntPoint ScrollView::windowToContents(const IntPoint& contentsPoint) const -{ - WebCoreViewBridge* bridge = this->getWebCoreViewBridge(); - WebCoreViewBridge* parent = bridge->getParent(); - int x = 0, y= 0; - while (parent) { - x += bridge->locX(); - y += bridge->locY(); - bridge = parent; - parent = bridge->getParent(); - } - return IntPoint(contentsPoint.x() - x, contentsPoint.y() - y); + if (!isFrameView()) + return false; + FrameView* view = static_cast<FrameView*>(this); + // We want to ignore requests to scroll that were not initiated by the user. An + // example of this is when text is inserted into a textfield/area, which results in + // a scroll. We ignore this because we now how to do this ourselves in the UI thread. + // An example of it being initiated by the user is if the user clicks an anchor + // element which simply scrolls the page. + return !android::WebFrame::getWebFrame(view->frame())->userInitiatedClick(); } -IntPoint ScrollView::contentsToWindow(const IntPoint& viewportPoint) const +void ScrollView::platformRepaintContentRectangle(const IntRect &rect, bool now) { - WebCoreViewBridge* bridge = this->getWebCoreViewBridge(); - WebCoreViewBridge* parent = bridge->getParent(); - int x = 0, y= 0; - while (parent) { - x += bridge->locX(); - y += bridge->locY(); - bridge = parent; - parent = bridge->getParent(); - } - return IntPoint(viewportPoint.x() + x, viewportPoint.y() + y); + android::WebViewCore::getWebViewCore(this)->contentInvalidate(rect); } -void ScrollView::setStaticBackground(bool) +#ifdef ANDROID_CAPTURE_OFFSCREEN_PAINTS +void ScrollView::platformOffscreenContentRectangle(const IntRect& rect) { - // we don't have any optimizations for this - verifiedOk(); + android::WebViewCore::getWebViewCore(this)->offInvalidate(rect); } - -bool ScrollView::inWindow() const -{ - LOGV("inWindow Unimplemented"); -#if 0 - return [getView() window]; #endif - return true; -} - -void ScrollView::wheelEvent(PlatformWheelEvent&) -{ - verifiedOk(); -} - -PlatformScrollbar* ScrollView::scrollbarUnderMouse(const PlatformMouseEvent& mouseEvent) -{ - verifiedOk(); - return NULL; -} } diff --git a/WebCore/platform/android/SharedTimerAndroid.cpp b/WebCore/platform/android/SharedTimerAndroid.cpp index 756d636..d454fbe 100644 --- a/WebCore/platform/android/SharedTimerAndroid.cpp +++ b/WebCore/platform/android/SharedTimerAndroid.cpp @@ -14,15 +14,14 @@ ** See the License for the specific language governing permissions and ** limitations under the License. */ +#define LOG_TAG "Timers" #include "config.h" #include "SharedTimer.h" #include "SystemTime.h" #include "JavaSharedClient.h" #include "TimerClient.h" -#define LOG_TAG "Timers" -#undef LOG -#include "utils/Log.h" +#include <utils/Log.h> namespace WebCore { diff --git a/WebCore/platform/android/SystemTimeAndroid.cpp b/WebCore/platform/android/SystemTimeAndroid.cpp index 3dfc433..0d1d465 100644 --- a/WebCore/platform/android/SystemTimeAndroid.cpp +++ b/WebCore/platform/android/SystemTimeAndroid.cpp @@ -31,7 +31,6 @@ double currentTime() return now; } -#ifdef ANDROID_INSTRUMENT uint32_t get_thread_msec() { #if defined(HAVE_POSIX_CLOCKS) @@ -47,6 +46,5 @@ uint32_t get_thread_msec() return tv.tv_sec * 1000LL + tv.tv_usec / 1000; #endif } -#endif } diff --git a/WebCore/platform/android/TemporaryLinkStubs.cpp b/WebCore/platform/android/TemporaryLinkStubs.cpp index 74712f5..958574f 100644 --- a/WebCore/platform/android/TemporaryLinkStubs.cpp +++ b/WebCore/platform/android/TemporaryLinkStubs.cpp @@ -14,6 +14,7 @@ ** See the License for the specific language governing permissions and ** limitations under the License. */ +#define LOG_TAG "WebCore" #include "config.h" @@ -25,16 +26,22 @@ #include "CachedPage.h" #include "CachedResource.h" #include "CookieJar.h" +#include "Console.h" #include "ContextMenu.h" #include "ContextMenuItem.h" #include "Clipboard.h" #include "CString.h" #include "Cursor.h" +#include "Database.h" +//#include "DebuggerCallFrame.h" #include "DocumentFragment.h" #include "DocumentLoader.h" #include "EditCommand.h" #include "Editor.h" +#include "File.h" +#include "FileList.h" #include "Font.h" +#include "Frame.h" #include "FrameLoader.h" #include "FrameLoadRequest.h" #include "FrameView.h" @@ -46,6 +53,12 @@ #include "IconDatabase.h" #include "IconLoader.h" #include "IntPoint.h" +#include "JavaScriptCallFrame.h" +#include "JavaScriptDebugServer.h" +#include "API/JSClassRef.h" +#include "JavaScriptCallFrame.h" +#include "JavaScriptProfile.h" +#include "jni_utility.h" #include "KURL.h" #include "Language.h" #include "loader.h" @@ -53,29 +66,22 @@ #include "MainResourceLoader.h" #include "MIMETypeRegistry.h" #include "Node.h" +#include "NotImplemented.h" #include "PageCache.h" #include "Pasteboard.h" #include "Path.h" -#include "PlatformScrollBar.h" #include "PluginInfoStore.h" #include "ResourceError.h" #include "ResourceHandle.h" #include "ResourceLoader.h" #include "Screen.h" -#include "ScrollBar.h" +#include "Scrollbar.h" +#include "ScrollbarTheme.h" #include "SmartReplace.h" #include "Widget.h" -#undef LOG -#define LOG_TAG "WebCore" -#include "utils/Log.h" - using namespace WebCore; -//static inline void notImplemented() { LOGV("LinkStubs: Not Implemented %s\n", __PRETTY_FUNCTION__); } -//static inline void notImplemented(const char name[]) { LOGV("LinkStubs: Not Implemented %s\n", name); } -static inline void verifiedOk() { } // not a problem that it's not implemented - // This function is called when the frame view has changed the state of it's border. // iFrames, which are have a FrameView, are drawn with a 1px left/right border and 2px top/bottom border // Check function _shouldDrawBorder in WebFrameView.mm @@ -88,8 +94,6 @@ static inline void verifiedOk() { } // not a problem that it's not implemented /********************************************************/ /* Completely empty stubs (mostly to allow DRT to run): */ /********************************************************/ -// This value turns on or off the Mac specific Accessibility support. -// bool AXObjectCache::gAccessibilityEnabled = false; // This function is used by Javascript to find out what the default language // the user has selected. It is used by the JS object Navigator.language @@ -123,9 +127,8 @@ void CheckCacheObjectStatus(DocLoader*, CachedResource*) { ASSERT(0); notImpleme // therefore relates to the above. When a file has been selected, an icon // representing the file type can be rendered next to the filename on the // web page. The icon for the file is encapsulated within this class. -Icon::Icon() { notImplemented(); } +//Icon::Icon() { notImplemented(); } Icon::~Icon() { } -PassRefPtr<Icon> Icon::newIconForFile(const String& filename){ notImplemented(); return PassRefPtr<Icon>(new Icon()); } void Icon::paint(GraphicsContext*, const IntRect&) { } // *** The following strings should be localized *** // @@ -154,11 +157,6 @@ String searchableIndexIntroduction() { verifiedOk(); return String("Enter search // It is also related to the CSS property outline-color: Color WebCore::focusRingColor() { verifiedOk(); return 0xFF0000FF; } -// The following functions are used on the Mac to register for and handle -// platform colour changes. The later function simply tells the view to -// reapply style and relayout. -void WebCore::setFocusRingColorChangeFunction(void (*)()) { verifiedOk(); } - // LocalizedStrings String WebCore::contextMenuItemTagOpenLinkInNewWindow() { ASSERT(0); return String(); } String WebCore::contextMenuItemTagDownloadLinkToDisk() { ASSERT(0); return String(); } @@ -243,7 +241,7 @@ void systemBeep() { notImplemented(); } //void WebCore::Frame::print() {} // void WebCore::Frame::issueTransposeCommand() {} //void WebCore::Frame::cleanupPlatformScriptObjects() {} -void WebCore::Frame::dashboardRegionsChanged() {} +// void WebCore::Frame::dashboardRegionsChanged() {} //bool WebCore::Frame::isCharacterSmartReplaceExempt(unsigned short, bool) { return false; } void* WebCore::Frame::dragImageForSelection() { return NULL; } @@ -273,9 +271,9 @@ String signedPublicKeyAndChallengeString(unsigned int, String const&, WebCore::K } // added for Nov-16-07 ToT integration -namespace WebCore { -void Frame::clearPlatformScriptObjects() { notImplemented(); } -} +//namespace WebCore { +//void Frame::clearPlatformScriptObjects() { notImplemented(); } +//} // functions new to Feb-19 tip of tree merge: namespace WebCore { @@ -288,3 +286,188 @@ int MakeDataExecutable; // functions new to Mar-2 tip of tree merge: String KURL::fileSystemPath() const { notImplemented(); return String(); } + +// functions new to Jun-1 tip of tree merge: +PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String&) { notImplemented(); return 0; } + +namespace JSC { +namespace Bindings { +bool dispatchJNICall(ExecState*, void const*, _jobject*, bool, JNIType, + _jmethodID*, jvalue*, jvalue&, char const*, JSValue*&) { + notImplemented(); + return false; +} +} +} + +char* dirname(const char*) { notImplemented(); return NULL; } + + // new as of SVN change 36269, Sept 8, 2008 +const String& Database::databaseInfoTableName() +{ + notImplemented(); + static const String dummy; + return dummy; +} + + // new as of SVN change 38068, Nov 5, 2008 +namespace WebCore { +void prefetchDNS(const String& hostname) { notImplemented(); } +void getSupportedKeySizes(Vector<String>&) { notImplemented(); } +PassRefPtr<Icon> Icon::createIconForFile(const String& filename) { notImplemented(); return 0; } +PassRefPtr<Icon> Icon::createIconForFiles(const Vector<String>& filenames) { notImplemented(); return 0; } +// ScrollbarTheme::nativeTheme() is called by RenderTextControl::calcPrefWidths() +// like this: scrollbarSize = ScrollbarTheme::nativeTheme()->scrollbarThickness(); +// with this comment: +// // FIXME: We should get the size of the scrollbar from the RenderTheme instead. +// since our text control doesn't have scrollbars, the default size of 0 width should be +// ok. notImplemented() is commented out below so that we can find other unresolved +// unimplemented functions. +ScrollbarTheme* ScrollbarTheme::nativeTheme() { /* notImplemented(); */ static ScrollbarTheme theme; return &theme; } +JSC::JSValue* toJS(JSC::ExecState* , JSC::Profile* ) { notImplemented(); return NULL; } +} + +FileList::FileList() +{ + notImplemented(); +} + +File* FileList::item(unsigned index) const +{ + notImplemented(); + return NULL; +} + +AXObjectCache::~AXObjectCache() +{ + notImplemented(); +} + +// This value turns on or off the Mac specific Accessibility support. +bool AXObjectCache::gAccessibilityEnabled = false; +bool AXObjectCache::gAccessibilityEnhancedUserInterfaceEnabled = false; + +void AXObjectCache::childrenChanged(RenderObject* renderer) +{ + notImplemented(); +} + +void AXObjectCache::remove(RenderObject* renderer) +{ + notImplemented(); +} + +using namespace JSC; + + +OpaqueJSClass::~OpaqueJSClass() +{ + notImplemented(); +} + +OpaqueJSClassContextData::~OpaqueJSClassContextData() +{ + notImplemented(); +} + +namespace WebCore { +JSC::JSValue* JavaScriptCallFrame::evaluate(JSC::UString const&, JSC::JSValue*&) const +{ + notImplemented(); + return NULL; +} + +const JSC::ScopeChainNode* JavaScriptCallFrame::scopeChain() const +{ + notImplemented(); + return NULL; +} + +JSC::JSObject* JavaScriptCallFrame::thisObject() const +{ + notImplemented(); + return NULL; +} + +JSC::DebuggerCallFrame::Type JavaScriptCallFrame::type() const +{ + notImplemented(); + return (JSC::DebuggerCallFrame::Type) 0; +} + +JavaScriptCallFrame* JavaScriptCallFrame::caller() +{ + notImplemented(); + return NULL; +} + +String JavaScriptCallFrame::functionName() const +{ + notImplemented(); + return String(); +} +} + +JavaScriptDebugServer::JavaScriptDebugServer() : + m_recompileTimer(this, NULL) +{ + notImplemented(); +} + +JavaScriptDebugServer::~JavaScriptDebugServer() +{ + notImplemented(); +} + +JavaScriptDebugServer& JavaScriptDebugServer::shared() +{ + static JavaScriptDebugServer server; + notImplemented(); + return server; +} + +void JavaScriptDebugServer::atStatement(const DebuggerCallFrame& debuggerCallFrame, int sourceID, int lineNumber) +{ + notImplemented(); +} + +void JavaScriptDebugServer::callEvent(const DebuggerCallFrame& debuggerCallFrame, int sourceID, int lineNumber) +{ + notImplemented(); +} + +void JavaScriptDebugServer::didExecuteProgram(const DebuggerCallFrame& debuggerCallFrame, int sourceID, int lineNumber) +{ + notImplemented(); +} + +void JavaScriptDebugServer::didReachBreakpoint(const DebuggerCallFrame& debuggerCallFrame, int sourceID, int lineNumber) +{ + notImplemented(); +} + +void JavaScriptDebugServer::exception(const DebuggerCallFrame& debuggerCallFrame, int sourceID, int lineNumber) +{ + notImplemented(); +} + +void JavaScriptDebugServer::sourceParsed(ExecState* exec, const SourceCode&, + int sourceID, const UString& sourceURL) +{ + notImplemented(); +} + +void JavaScriptDebugServer::pageCreated(Page* page) +{ + notImplemented(); +} + +void JavaScriptDebugServer::returnEvent(const DebuggerCallFrame& debuggerCallFrame, int sourceID, int lineNumber) +{ + notImplemented(); +} + +void JavaScriptDebugServer::willExecuteProgram(const DebuggerCallFrame& debuggerCallFrame, int sourceID, int lineNumber) +{ + notImplemented(); +} diff --git a/WebCore/platform/android/TextEditAndroid.cpp b/WebCore/platform/android/TextEditAndroid.cpp deleted file mode 100644 index a946465..0000000 --- a/WebCore/platform/android/TextEditAndroid.cpp +++ /dev/null @@ -1,377 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "config.h" -#include "KWQTextEdit.h" -#include "Font.h" -#include "IntSize.h" -#include "WebCoreViewBridge.h" -#include "GraphicsContext.h" -#include "PlatformGraphicsContext.h" - -#include "SkCanvas.h" -#include "SkString.h" -#include "SkUtils.h" -#include "SkPaint.h" - -#undef LOG -#define LOG_TAG "WebCore" -#undef LOGI -#undef LOG -#include "utils/Log.h" - -static void setstr(SkString* dst, const WebCore::String& src) -{ - if (src.length()) { - const uint16_t* uni = (const uint16_t*)src.characters(); - size_t size = SkUTF16_ToUTF8(uni, src.length(), 0); - - dst->resize(size); - SkUTF16_ToUTF8(uni, src.length(), dst->writable_str()); - } -} - -class TextEditViewBridge : public WebCoreViewBridge { -public: - TextEditViewBridge(QTextEdit* te); - - virtual void draw(WebCore::GraphicsContext* ctx, const IntRect& rect); - virtual bool isEnabled() const; - virtual void setEnabled(bool); - virtual bool hasFocus() const; - virtual void setFocus(bool); - -private: - QTextEdit* m_te; - bool m_enabled; - bool m_focused; -}; - -TextEditViewBridge::TextEditViewBridge(QTextEdit* te) -{ - m_te = te; - this->setBounds(0,0,0,0); - m_enabled = true; - m_focused = false; -} - -void TextEditViewBridge::draw(WebCore::GraphicsContext* ctx, const IntRect& rect) -{ - SkCanvas* canvas = ctx->platformContext()->mCanvas; - SkPaint paint; - SkRect r; - - paint.setColor(m_focused ? SK_ColorGREEN : SK_ColorBLUE); - r.set( SkIntToScalar(rect.x()), SkIntToScalar(rect.y()), - SkIntToScalar(rect.right()), SkIntToScalar(rect.bottom())); - canvas->drawRect(r, paint); -} - -bool TextEditViewBridge::isEnabled() const { return m_enabled; } -void TextEditViewBridge::setEnabled(bool e) { m_enabled = e; } - -bool TextEditViewBridge::hasFocus() const { return m_focused; } -void TextEditViewBridge::setFocus(bool f) { m_focused = f; } - -///////////////////////////////////////////////////////////////////////////////////////////////////// - -using namespace WebCore; - -QTextEdit::QTextEdit(Widget *parent) -{ - this->setWebCoreViewBridge(new TextEditViewBridge(this)); - -#if 0 - BEGIN_BLOCK_OBJC_EXCEPTIONS; - WebCoreTextArea *textView = [[WebCoreTextArea alloc] initWithQTextEdit:this]; - setView(textView); - [textView release]; - END_BLOCK_OBJC_EXCEPTIONS; -#endif -} - -QTextEdit::~QTextEdit() -{ - delete this->getWebCoreViewBridge(); - -#if 0 - WebCoreTextArea *textArea = (WebCoreTextArea *)getView(); - [textArea detachQTextEdit]; -#endif -} - -void QTextEdit::setText(const String& string) -{ - SkString str; - - setstr(&str, string); - LOGI("%p QTextEdit::setText(%s)\n", this, str.c_str()); -} - -String QTextEdit::text() const -{ - return String("ATextEdit::text"); -} - -String QTextEdit::textWithHardLineBreaks() const -{ - return String("ATextEdit::textWithHardLineBreaks"); -} - -void QTextEdit::getCursorPosition(int *paragraph, int *index) const -{ -// WebCoreTextArea *textView = (WebCoreTextArea *)getView(); - if (index) - *index = 0; - if (paragraph) - *paragraph = 0; -} - -void QTextEdit::setCursorPosition(int paragraph, int index) -{ -LOGI("QTextEdit::setCursorPosition(%d, %d)\n", paragraph, index); -} - -QTextEdit::WrapStyle QTextEdit::wordWrap() const -{ -// return [textView wordWrap] ? WidgetWidth : NoWrap; - return NoWrap; -} - -void QTextEdit::setWordWrap(WrapStyle style) -{ -} - -void QTextEdit::setScrollBarModes(ScrollBarMode hMode, ScrollBarMode vMode) -{ -#if 0 - WebCoreTextArea *textView = (WebCoreTextArea *)getView(); - - BEGIN_BLOCK_OBJC_EXCEPTIONS; - - // this declaration must be inside the BEGIN_BLOCK_OBJC_EXCEPTIONS block or the deployment build fails - bool autohides = hMode == ScrollBarAuto || vMode == ScrollBarAuto; - - ASSERT(!autohides || hMode != ScrollBarAlwaysOn); - ASSERT(!autohides || vMode != ScrollBarAlwaysOn); - - [textView setHasHorizontalScroller:hMode != ScrollBarAlwaysOff]; - [textView setHasVerticalScroller:vMode != ScrollBarAlwaysOff]; - [textView setAutohidesScrollers:autohides]; - - END_BLOCK_OBJC_EXCEPTIONS; -#endif -} - -bool QTextEdit::isReadOnly() const -{ - return false; -} - -void QTextEdit::setReadOnly(bool flag) -{ -} - -bool QTextEdit::isDisabled() const -{ - return false; -} - -void QTextEdit::setDisabled(bool flag) -{ -} - -int QTextEdit::selectionStart() -{ - return 0; -} - -int QTextEdit::selectionEnd() -{ - return 0; -} - -void QTextEdit::setSelectionStart(int start) -{ -#if 0 - WebCoreTextArea *textView = (WebCoreTextArea *)getView(); - - BEGIN_BLOCK_OBJC_EXCEPTIONS; - NSRange range = [textView selectedRange]; - if (range.location == NSNotFound) { - range.location = 0; - range.length = 0; - } - - // coerce start to a valid value - int maxLength = [[textView text] length]; - int newStart = start; - if (newStart < 0) - newStart = 0; - if (newStart > maxLength) - newStart = maxLength; - - if ((unsigned)newStart < range.location + range.length) { - // If we're expanding or contracting, but not collapsing the selection - range.length += range.location - newStart; - range.location = newStart; - } else { - // ok, we're collapsing the selection - range.location = newStart; - range.length = 0; - } - - [textView setSelectedRange:range]; - END_BLOCK_OBJC_EXCEPTIONS; -#endif -} - -void QTextEdit::setSelectionEnd(int end) -{ -#if 0 - WebCoreTextArea *textView = (WebCoreTextArea *)getView(); - - BEGIN_BLOCK_OBJC_EXCEPTIONS; - NSRange range = [textView selectedRange]; - if (range.location == NSNotFound) { - range.location = 0; - range.length = 0; - } - - // coerce end to a valid value - int maxLength = [[textView text] length]; - int newEnd = end; - if (newEnd < 0) - newEnd = 0; - if (newEnd > maxLength) - newEnd = maxLength; - - if ((unsigned)newEnd >= range.location) { - // If we're just changing the selection length, but not location.. - range.length = newEnd - range.location; - } else { - // ok, we've collapsed the selection and are moving it - range.location = newEnd; - range.length = 0; - } - - [textView setSelectedRange:range]; - END_BLOCK_OBJC_EXCEPTIONS; -#endif -} - -bool QTextEdit::hasSelectedText() const -{ - return false; -} - -void QTextEdit::selectAll() -{ -} - -void QTextEdit::setSelectionRange(int start, int length) -{ -#if 0 - WebCoreTextArea *textView = (WebCoreTextArea *)getView(); - - BEGIN_BLOCK_OBJC_EXCEPTIONS; - int newStart = start; - int newLength = length; - if (newStart < 0) { - // truncate the length by the negative start - newLength = length + newStart; - newStart = 0; - } - if (newLength < 0) { - newLength = 0; - } - int maxlen = [[textView text] length]; - if (newStart > maxlen) { - newStart = maxlen; - } - if (newStart + newLength > maxlen) { - newLength = maxlen - newStart; - } - NSRange tempRange = {newStart, newLength}; // 4213314 - [textView setSelectedRange:tempRange]; - END_BLOCK_OBJC_EXCEPTIONS; -#endif -} - -void QTextEdit::setFont(const Font& font) -{ - Widget::setFont(font); -#if 0 - WebCoreTextArea *textView = (WebCoreTextArea *)getView(); - - BEGIN_BLOCK_OBJC_EXCEPTIONS; - [textView setFont:font.getNSFont()]; - END_BLOCK_OBJC_EXCEPTIONS; -#endif -} - -void QTextEdit::setAlignment(HorizontalAlignment alignment) -{ -} - -void QTextEdit::setLineHeight(int lineHeight) -{ -} - -void QTextEdit::setWritingDirection(TextDirection direction) -{ -#if 0 - BEGIN_BLOCK_OBJC_EXCEPTIONS; - - WebCoreTextArea *textArea = static_cast<WebCoreTextArea *>(getView()); - [textArea setBaseWritingDirection:(direction == RTL ? NSWritingDirectionRightToLeft : NSWritingDirectionLeftToRight)]; - - END_BLOCK_OBJC_EXCEPTIONS; -#endif -} - -IntSize QTextEdit::sizeWithColumnsAndRows(int numColumns, int numRows) const -{ -#if 0 - WebCoreTextArea *textArea = static_cast<WebCoreTextArea *>(getView()); - NSSize size = {0,0}; - - BEGIN_BLOCK_OBJC_EXCEPTIONS; - size = [textArea sizeWithColumns:numColumns rows:numRows]; - END_BLOCK_OBJC_EXCEPTIONS; - - return IntSize((int)ceil(size.width), (int)ceil(size.height)); -#else - return IntSize(0, 0); -#endif -} - -Widget::FocusPolicy QTextEdit::focusPolicy() const -{ - FocusPolicy policy = ScrollView::focusPolicy(); - return policy == TabFocus ? StrongFocus : policy; -} - -bool QTextEdit::checksDescendantsForFocus() const -{ - return true; -} - -void QTextEdit::setColors(const Color& background, const Color& foreground) -{ -} - diff --git a/WebCore/platform/android/ThreadingAndroid.cpp b/WebCore/platform/android/ThreadingAndroid.cpp deleted file mode 100644 index 6317dab..0000000 --- a/WebCore/platform/android/ThreadingAndroid.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2007 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "Threading.h" -#include "JavaSharedClient.h" -#include "TimerClient.h" - -namespace WebCore { - -void callOnMainThread(void (*function)(void* ), void* context) -{ - // Through some investigation, this method is used to notify the frame - // loader that the favicon load decision has been made. This is not - // necessary as the frame loader will always attempt to the load the favicon - // at the end of the load. - // The other use for this function is to call a DatabaseCallback - // implementation which we do not implement. -} - -} diff --git a/WebCore/platform/android/TimerClient.h b/WebCore/platform/android/TimerClient.h deleted file mode 100644 index e4f36a0..0000000 --- a/WebCore/platform/android/TimerClient.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef TIMER_CLIENT_H -#define TIMER_CLIENT_H - -namespace WebCore { - - class TimerClient - { - public: - virtual ~TimerClient() {} - virtual void setSharedTimerCallback(void(*f)()) = 0; - virtual void setSharedTimer(long long timemillis) = 0; - virtual void stopSharedTimer() = 0; - }; - -} -#endif - diff --git a/WebCore/platform/android/WidgetAndroid.cpp b/WebCore/platform/android/WidgetAndroid.cpp index 3ed3abc..baf2a0a 100644 --- a/WebCore/platform/android/WidgetAndroid.cpp +++ b/WebCore/platform/android/WidgetAndroid.cpp @@ -17,78 +17,68 @@ #include "config.h" #include "Widget.h" -#include "WebCoreViewBridge.h" -#include "WidgetClient.h" -#include "Font.h" -#include "IntRect.h" -#include "GraphicsContext.h" -#include "FrameAndroid.h" -#include "WebCoreFrameBridge.h" + #include "Document.h" #include "Element.h" +#include "Font.h" +#include "FrameView.h" +#include "GraphicsContext.h" +#include "HostWindow.h" +#include "NotImplemented.h" -#define LOG_TAG "WebCore" -#undef LOG -#include "utils/Log.h" +#include "WebCoreFrameBridge.h" +#include "WebCoreViewBridge.h" +#include "WebViewCore.h" namespace WebCore { -#define notImplemented() LOGV("WidgetAndroid: NotYetImplemented") - class WidgetPrivate { public: Font m_font; - WebCoreViewBridge* m_viewbridge; // we point to this, but don't delete it (unless we had refcounting...) - WidgetClient* m_client; - bool m_visible; }; - Widget::Widget() : data(new WidgetPrivate) + Widget::Widget(PlatformWidget widget) : m_data(new WidgetPrivate) { - data->m_viewbridge = NULL; - data->m_client = NULL; - data->m_visible = false; + init(widget); } Widget::~Widget() { - Release(data->m_viewbridge); - delete data; + ASSERT(!parent()); + releasePlatformWidget(); + delete m_data; } - void Widget::setEnabled(bool enabled) + IntRect Widget::frameRect() const { - WebCoreViewBridge* view = data->m_viewbridge; - ASSERT(data->m_viewbridge); - if (view) - view->setEnabled(enabled); + // FIXME: use m_frame instead? + if (!platformWidget()) + return IntRect(0, 0, 0, 0); + return platformWidget()->getBounds(); } - bool Widget::isEnabled() const + void Widget::setFocus() { - ASSERT(data->m_viewbridge); - return data->m_viewbridge->isEnabled(); + notImplemented(); } - IntRect Widget::frameGeometry() const + void Widget::paint(GraphicsContext* ctx, const IntRect& r) { - ASSERT(data->m_viewbridge); - return data->m_viewbridge->getBounds(); + // FIXME: in what case, will this be called for the top frame? + if (!platformWidget()) + return; + platformWidget()->draw(ctx, r); } - void Widget::setFocus() + void Widget::releasePlatformWidget() { - ASSERT(data->m_viewbridge); - data->m_viewbridge->setFocus(true); + Release(platformWidget()); } - void Widget::paint(GraphicsContext* ctx, const IntRect& r) + void Widget::retainPlatformWidget() { - WebCoreViewBridge* viewBridge = data->m_viewbridge; - ASSERT(viewBridge); - viewBridge->layout(); - viewBridge->draw(ctx, r, true); + Retain(platformWidget()); } void Widget::setCursor(const Cursor& cursor) @@ -98,21 +88,22 @@ namespace WebCore { void Widget::show() { - if (!data || data->m_visible) - return; - - data->m_visible = true; + notImplemented(); } void Widget::hide() { - notImplemented(); + notImplemented(); } - void Widget::setFrameGeometry(const IntRect& rect) + void Widget::setFrameRect(const IntRect& rect) { - ASSERT(data->m_viewbridge); - data->m_viewbridge->setBounds(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height()); + // FIXME: set m_frame instead? + // platformWidget() is NULL when called from Scrollbar + if (!platformWidget()) + return; + platformWidget()->setLocation(rect.x(), rect.y()); + platformWidget()->setSize(rect.width(), rect.height()); } void Widget::setIsSelected(bool isSelected) @@ -120,42 +111,19 @@ namespace WebCore { notImplemented(); } - void Widget::invalidate() - { - notImplemented(); - } - - void Widget::invalidateRect(const IntRect&) - { - notImplemented(); - } - - void Widget::removeFromParent() - { - notImplemented(); - } - - void Widget::setClient(WidgetClient* c) - { - data->m_client = c; - } - - WidgetClient* Widget::client() const + int Widget::screenWidth() const { - return data->m_client; - } + const Widget* widget = this; + while (!widget->isFrameView()) { + widget = widget->parent(); + if (!widget) + break; + } + if (!widget) + return 0; - WebCoreViewBridge* Widget::getWebCoreViewBridge() const - { - return data->m_viewbridge; - } - - void Widget::setWebCoreViewBridge(WebCoreViewBridge* view) - { - Release(data->m_viewbridge); - data->m_viewbridge = view; - view->setWidget(this); - Retain(data->m_viewbridge); + return android::WebViewCore::getWebViewCore( + static_cast<const ScrollView*>(widget))->screenWidth(); } } // WebCore namepsace diff --git a/WebCore/platform/android/android-encodings.txt b/WebCore/platform/android/android-encodings.txt deleted file mode 100644 index 0cc346d..0000000 --- a/WebCore/platform/android/android-encodings.txt +++ /dev/null @@ -1,44 +0,0 @@ -## -## Copyright 2007, The Android Open Source Project -## -## Licensed under the Apache License, Version 2.0 (the "License"); -## you may not use this file except in compliance with the License. -## You may obtain a copy of the License at -## -## http://www.apache.org/licenses/LICENSE-2.0 -## -## Unless required by applicable law or agreed to in writing, software -## distributed under the License is distributed on an "AS IS" BASIS, -## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -## See the License for the specific language governing permissions and -## limitations under the License. -# - -# The items on the left are names of TextEncodingID values -# The items on the right are IANA character set names. Names listed in character-sets.txt are not -# repeated here; mentioning any one character set from a group in there pulls in all the aliases in -# that group. - -# XXX: This needs to be kept in sync with AndroidUnicode.h in utils. -# XXX: These are not the supported encodings, they are just the available encodings -# that WebCore will recognize. Support is determined by carriers. - -ASCII: US-ASCII, isoir6us -ISO_8859_1: ISO-8859-1, 88591 -ISO_8859_5: ISO-8859-5 -ISO_8859_8: ISO-8859-8-I, iso88598 -UTF8: UTF-8 -UTF16: UTF-16 -SHIFT_JIS: Shift_JIS, sjis, xsjis -BIG5: Big5, xxbig5 -EUC_JP: EUC-JP, xeuc, xeucjp -EUC_CN: EUC-CN, gb2312, gb231280, gbk, xeuccn, xgbk -WINDOWS_1251: windows-1251, cp1251 -WINDOWS_1252: windows-1252 -WINDOWS_1255: windows-1255 -KOI8_R: KOI8-R -KOI8_U: KOI8-U -NEXT_STEP: x-nextstep -MACINTOSH: macintosh -THAI: TIS-620, cp874, iso885911, windows874 -INVALID: cp864, iso2022jp, windows1250, windows1253, windows1254, windows1256, windows1257, windows1258 diff --git a/WebCore/platform/android/jni/JavaBridge.cpp b/WebCore/platform/android/jni/JavaBridge.cpp deleted file mode 100644 index 27b2bb2..0000000 --- a/WebCore/platform/android/jni/JavaBridge.cpp +++ /dev/null @@ -1,332 +0,0 @@ -/* -** Copyright 2006-2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#define LOG_TAG "webcoreglue" - -#include <config.h> -#include <wtf/Platform.h> - -#include "Cache.h" -#include "CookieClient.h" -#include "JavaSharedClient.h" -#include "KURL.h" -#include "Timer.h" -#include "TimerClient.h" - -#ifdef ANDROID_INSTRUMENT -#include "Frame.h" -#include "SystemTime.h" -#endif - -#undef LOG -#include <jni.h> -#include <JNIHelp.h> -#include <SkImageRef_GlobalPool.h> -#include <SkUtils.h> -#include <utils/Log.h> -#include <utils/misc.h> - -// maximum bytes used to cache decoded images -// (not including big images using ashmem) -#define IMAGE_POOL_BUDGET (512 * 1024) - -#ifdef ANDROID_INSTRUMENT -static uint32_t sTotalTimeUsed = 0; - -namespace WebCore { -void Frame::resetSharedTimerTimeCounter() -{ - sTotalTimeUsed = 0; -} - -void Frame::reportSharedTimerTimeCounter() -{ - LOG(LOG_DEBUG, "WebCore", "*-* Total native 2 (shared timer) time: %d ms\n", - sTotalTimeUsed); -} -} -#endif - -namespace android { - -// ---------------------------------------------------------------------------- - -static jfieldID gJavaBridge_ObjectID; - -static bool checkException(JNIEnv* env) -{ - if (env->ExceptionCheck() != 0) - { - LOGE("*** Uncaught exception returned from Java call!\n"); - env->ExceptionDescribe(); - return true; - } - return false; -} - -// ---------------------------------------------------------------------------- - -extern JavaVM* jnienv_to_javavm(JNIEnv* env); -extern JNIEnv* javavm_to_jnienv(JavaVM* vm); - -// ---------------------------------------------------------------------------- - -class JavaBridge : public WebCore::TimerClient, public WebCore::CookieClient -{ -public: - JavaBridge(JNIEnv* env, jobject obj); - virtual ~JavaBridge(); - - /* - * WebCore -> Java API - */ - virtual void setSharedTimer(long long timemillis); - virtual void stopSharedTimer(); - - virtual void setCookies(WebCore::KURL const& url, WebCore::KURL const& docURL, WebCore::String const& value); - virtual WebCore::String cookies(WebCore::KURL const& url); - virtual bool cookiesEnabled(); - - //////////////////////////////////////////// - - virtual void setSharedTimerCallback(void (*f)()); - - //////////////////////////////////////////// - - void signalServiceFuncPtrQueue(); - - // jni functions - static void Constructor(JNIEnv* env, jobject obj); - static void Finalize(JNIEnv* env, jobject obj); - static void SharedTimerFired(JNIEnv* env, jobject); - static void SetCacheSize(JNIEnv* env, jobject obj, jint bytes); - static void SetDeferringTimers(JNIEnv* env, jobject obj, jboolean defer); - static void ServiceFuncPtrQueue(JNIEnv*); - -private: - JavaVM* mJvm; - jobject mJavaObject; - jmethodID mSetSharedTimer; - jmethodID mStopSharedTimer; - jmethodID mSetCookies; - jmethodID mCookies; - jmethodID mCookiesEnabled; - jmethodID mSignalFuncPtrQueue; -}; - -static void (*sSharedTimerFiredCallback)(); -static JavaBridge* gJavaBridge; - -JavaBridge::JavaBridge(JNIEnv* env, jobject obj) -{ - mJvm = jnienv_to_javavm(env); - mJavaObject = env->NewGlobalRef(obj); - jclass clazz = env->GetObjectClass(obj); - - mSetSharedTimer = env->GetMethodID(clazz, "setSharedTimer", "(J)V"); - mStopSharedTimer = env->GetMethodID(clazz, "stopSharedTimer", "()V"); - mSetCookies = env->GetMethodID(clazz, "setCookies", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); - mCookies = env->GetMethodID(clazz, "cookies", "(Ljava/lang/String;)Ljava/lang/String;"); - mCookiesEnabled = env->GetMethodID(clazz, "cookiesEnabled", "()Z"); - mSignalFuncPtrQueue = env->GetMethodID(clazz, "signalServiceFuncPtrQueue", "()V"); - - LOG_ASSERT(mSetSharedTimer, "Could not find method setSharedTimer"); - LOG_ASSERT(mStopSharedTimer, "Could not find method stopSharedTimer"); - LOG_ASSERT(mSetCookies, "Could not find method setCookies"); - LOG_ASSERT(mCookies, "Could not find method cookies"); - LOG_ASSERT(mCookiesEnabled, "Could not find method cookiesEnabled"); - - WebCore::JavaSharedClient::SetTimerClient(this); - WebCore::JavaSharedClient::SetCookieClient(this); - gJavaBridge = this; -} - -JavaBridge::~JavaBridge() -{ - if (mJavaObject) { - JNIEnv* env = javavm_to_jnienv(mJvm); - env->DeleteGlobalRef(mJavaObject); - mJavaObject = 0; - } - - WebCore::JavaSharedClient::SetTimerClient(NULL); - WebCore::JavaSharedClient::SetCookieClient(NULL); -} - -void -JavaBridge::setSharedTimer(long long timemillis) -{ - JNIEnv* env = javavm_to_jnienv(mJvm); - env->CallVoidMethod(mJavaObject, mSetSharedTimer, timemillis); -} - -void -JavaBridge::stopSharedTimer() -{ - JNIEnv* env = javavm_to_jnienv(mJvm); - env->CallVoidMethod(mJavaObject, mStopSharedTimer); -} - -void -JavaBridge::setCookies(WebCore::KURL const& url, WebCore::KURL const& docUrl, WebCore::String const& value) -{ - JNIEnv* env = javavm_to_jnienv(mJvm); - const WebCore::DeprecatedString& urlStr = url.deprecatedString(); - jstring jUrlStr = env->NewString((unsigned short *)urlStr.unicode(), urlStr.length()); - const WebCore::DeprecatedString& docUrlStr = docUrl.deprecatedString(); - jstring jDocUrlStr = env->NewString((unsigned short *)docUrlStr.unicode(), docUrlStr.length()); - jstring jValueStr = env->NewString((unsigned short *)value.characters(), value.length()); - - env->CallVoidMethod(mJavaObject, mSetCookies, jUrlStr, jDocUrlStr, jValueStr); - env->DeleteLocalRef(jUrlStr); - env->DeleteLocalRef(jDocUrlStr); - env->DeleteLocalRef(jValueStr); -} - -WebCore::String -JavaBridge::cookies(WebCore::KURL const& url) -{ - JNIEnv* env = javavm_to_jnienv(mJvm); - const WebCore::DeprecatedString& urlStr = url.deprecatedString(); - jstring jUrlStr = env->NewString((unsigned short *)urlStr.unicode(), urlStr.length()); - - jstring string = (jstring)(env->CallObjectMethod(mJavaObject, mCookies, jUrlStr)); - - if (string == NULL || checkException(env)) - return WebCore::String(); - - const jchar* str = env->GetStringChars(string, NULL); - WebCore::String ret = WebCore::String((const UChar*)str, env->GetStringLength(string)); - env->ReleaseStringChars(string, str); - env->DeleteLocalRef(jUrlStr); - env->DeleteLocalRef(string); - return ret; -} - -bool -JavaBridge::cookiesEnabled() -{ - JNIEnv* env = javavm_to_jnienv(mJvm); - jboolean ret = env->CallBooleanMethod(mJavaObject, mCookiesEnabled); - return (ret != 0); -} - -void -JavaBridge::setSharedTimerCallback(void (*f)()) -{ - LOG_ASSERT(!sSharedTimerFiredCallback || sSharedTimerFiredCallback==f, - "Shared timer callback may already be set or null!"); - - sSharedTimerFiredCallback = f; -} - -void JavaBridge::signalServiceFuncPtrQueue() -{ - javavm_to_jnienv(mJvm)->CallVoidMethod(mJavaObject, mSignalFuncPtrQueue); -} - -// ---------------------------------------------------------------------------- - -// visible to Shared -void AndroidSignalServiceFuncPtrQueue() -{ - gJavaBridge->signalServiceFuncPtrQueue(); -} - -// ---------------------------------------------------------------------------- - -void JavaBridge::Constructor(JNIEnv* env, jobject obj) -{ - JavaBridge* javaBridge = new JavaBridge(env, obj); - env->SetIntField(obj, gJavaBridge_ObjectID, (jint)javaBridge); -} - -void JavaBridge::Finalize(JNIEnv* env, jobject obj) -{ - JavaBridge* javaBridge = (JavaBridge*) - (env->GetIntField(obj, gJavaBridge_ObjectID)); - LOG_ASSERT(javaBridge, "Finalize should not be called twice for the same java bridge!"); - LOGV("webcore_javabridge::nativeFinalize(%p)\n", javaBridge); - delete javaBridge; - env->SetIntField(obj, gJavaBridge_ObjectID, 0); -} - -// we don't use the java bridge object, as we're just looking at a global -void JavaBridge::SharedTimerFired(JNIEnv* env, jobject) -{ - if (sSharedTimerFiredCallback) - { -#ifdef ANDROID_INSTRUMENT - uint32_t startTime = WebCore::get_thread_msec(); -#endif - SkAutoMemoryUsageProbe mup("JavaBridge::sharedTimerFired"); - sSharedTimerFiredCallback(); -#ifdef ANDROID_INSTRUMENT - sTotalTimeUsed += WebCore::get_thread_msec() - startTime; -#endif - } -} - -void JavaBridge::SetCacheSize(JNIEnv* env, jobject obj, jint bytes) -{ - WebCore::cache()->setCapacities(0, bytes/2, bytes); - SkImageRef_GlobalPool::SetRAMBudget(IMAGE_POOL_BUDGET); - LOGV("--- set ImageRef budget %d\n", SkImageRef_GlobalPool::GetRAMBudget()); -} - -void JavaBridge::SetDeferringTimers(JNIEnv* env, jobject obj, jboolean defer) -{ - WebCore::setDeferringTimers(defer); -} - -void JavaBridge::ServiceFuncPtrQueue(JNIEnv*) -{ - WebCore::JavaSharedClient::ServiceFunctionPtrQueue(); -} - -// ---------------------------------------------------------------------------- - -/* - * JNI registration. - */ -static JNINativeMethod gWebCoreJavaBridgeMethods[] = { - /* name, signature, funcPtr */ - { "nativeConstructor", "()V", - (void*) JavaBridge::Constructor }, - { "nativeFinalize", "()V", - (void*) JavaBridge::Finalize }, - { "sharedTimerFired", "()V", - (void*) JavaBridge::SharedTimerFired }, - { "setCacheSize", "(I)V", - (void*) JavaBridge::SetCacheSize }, - { "setDeferringTimers", "(Z)V", - (void*) JavaBridge::SetDeferringTimers }, - { "nativeServiceFuncPtrQueue", "()V", - (void*) JavaBridge::ServiceFuncPtrQueue }, -}; - -int register_javabridge(JNIEnv* env) -{ - jclass javaBridge = env->FindClass("android/webkit/JWebCoreJavaBridge"); - LOG_FATAL_IF(javaBridge == NULL, "Unable to find class android/webkit/JWebCoreJavaBridge"); - gJavaBridge_ObjectID = env->GetFieldID(javaBridge, "mNativeBridge", "I"); - LOG_FATAL_IF(gJavaBridge_ObjectID == NULL, "Unable to find android/webkit/JWebCoreJavaBridge.mNativeBridge"); - - return jniRegisterNativeMethods(env, "android/webkit/JWebCoreJavaBridge", - gWebCoreJavaBridgeMethods, NELEM(gWebCoreJavaBridgeMethods)); -} - -} /* namespace android */ diff --git a/WebCore/platform/android/jni/JavaSharedClient.cpp b/WebCore/platform/android/jni/JavaSharedClient.cpp deleted file mode 100644 index aaefd72..0000000 --- a/WebCore/platform/android/jni/JavaSharedClient.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "config.h" -#include "JavaSharedClient.h" -#define LOG_TAG "JavaSharedClient" -#include "utils/Log.h" -#include "SkDeque.h" -#include "SkThread.h" - -namespace android { - void AndroidSignalServiceFuncPtrQueue(); -} - -namespace WebCore { - - TimerClient* JavaSharedClient::GetTimerClient() - { - //LOG_ASSERT(gTimerClient != NULL, "gTimerClient not initialized!!!"); - return gTimerClient; - } - - CookieClient* JavaSharedClient::GetCookieClient() - { - //LOG_ASSERT(gCookieClient != NULL, "gCookieClient not initialized!!!"); - return gCookieClient; - } - - void JavaSharedClient::SetTimerClient(TimerClient* client) - { - //LOG_ASSERT(gTimerClient == NULL || client == NULL, "gTimerClient already set, aborting..."); - gTimerClient = client; - } - - void JavaSharedClient::SetCookieClient(CookieClient* client) - { - //LOG_ASSERT(gCookieClient == NULL || client == NULL, "gCookieClient already set, aborting..."); - gCookieClient = client; - } - - TimerClient* JavaSharedClient::gTimerClient = NULL; - CookieClient* JavaSharedClient::gCookieClient = NULL; - - /////////////////////////////////////////////////////////////////////////// - - struct FuncPtrRec { - void (*fProc)(void* payload); - void* fPayload; - }; - - static SkMutex gFuncPtrQMutex; - static SkDeque gFuncPtrQ(sizeof(FuncPtrRec)); - - void JavaSharedClient::EnqueueFunctionPtr(void (*proc)(void* payload), - void* payload) - { - gFuncPtrQMutex.acquire(); - - FuncPtrRec* rec = (FuncPtrRec*)gFuncPtrQ.push_back(); - rec->fProc = proc; - rec->fPayload = payload; - - gFuncPtrQMutex.release(); - - android::AndroidSignalServiceFuncPtrQueue(); - } - - void JavaSharedClient::ServiceFunctionPtrQueue() - { - for (;;) { - void (*proc)(void*); - void* payload; - const FuncPtrRec* rec; - - // we have to copy the proc/payload (if present). we do this so we - // don't call the proc inside the mutex (possible deadlock!) - gFuncPtrQMutex.acquire(); - rec = (const FuncPtrRec*)gFuncPtrQ.front(); - if (NULL != rec) { - proc = rec->fProc; - payload = rec->fPayload; - gFuncPtrQ.pop_front(); - } - gFuncPtrQMutex.release(); - - if (NULL == rec) { - break; - } - proc(payload); - } - } -} diff --git a/WebCore/platform/android/jni/JavaSharedClient.h b/WebCore/platform/android/jni/JavaSharedClient.h deleted file mode 100644 index 470c4dd..0000000 --- a/WebCore/platform/android/jni/JavaSharedClient.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef JAVA_SHARED_CLIENT_H -#define JAVA_SHARED_CLIENT_H - -namespace WebCore { - - class TimerClient; - class CookieClient; - - class JavaSharedClient - { - public: - static TimerClient* GetTimerClient(); - static CookieClient* GetCookieClient(); - - static void SetTimerClient(TimerClient* client); - static void SetCookieClient(CookieClient* client); - - // can be called from any thread, to be executed in webkit thread - static void EnqueueFunctionPtr(void (*proc)(void*), void* payload); - // only call this from webkit thread - static void ServiceFunctionPtrQueue(); - - private: - static TimerClient* gTimerClient; - static CookieClient* gCookieClient; - }; -} -#endif diff --git a/WebCore/platform/android/jni/WebCoreFrameBridge.cpp b/WebCore/platform/android/jni/WebCoreFrameBridge.cpp deleted file mode 100644 index 55c9c88..0000000 --- a/WebCore/platform/android/jni/WebCoreFrameBridge.cpp +++ /dev/null @@ -1,1249 +0,0 @@ -/* -** Copyright 2006-2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#define LOG_TAG "webcoreglue" - -#include <config.h> -#include <wtf/Platform.h> - -#include "android_graphics.h" -#include "Arena.h" -#include "AtomicString.h" -#include "Cache.h" -#include "ChromeClientAndroid.h" -#include "ContextMenuClientAndroid.h" -#include "DeprecatedString.h" -#include "Document.h" -#include "DocumentLoader.h" -#include "DragClientAndroid.h" -#include "EditorClientAndroid.h" -#include "Element.h" -#include "Font.h" -#include "FrameAndroid.h" -#include "FrameLoader.h" -#include "FrameLoaderClientAndroid.h" -#include "FrameTree.h" -#include "FrameView.h" -#include "GCController.h" -#include "GraphicsContext.h" -#include "HistoryItem.h" -#include "HTMLElement.h" -#include "HTMLFormElement.h" -#include "HTMLInputElement.h" -#include "HTMLNames.h" -#include "IconDatabase.h" -#include "Image.h" -#include "InspectorClientAndroid.h" -#include "KURL.h" -#include "Page.h" -#include "PageCache.h" -#include "PlatformString.h" -#include "RenderPart.h" -#include "RenderSkinAndroid.h" -#include "RenderTreeAsText.h" -#include "ResourceHandle.h" -#include "SelectionController.h" -#include "Settings.h" -#include "SubstituteData.h" -#include "WebCoreFrameBridge.h" -#include "WebCoreResourceLoader.h" -#include "WebHistory.h" -#include "WebIconDatabase.h" -#include "WebViewCore.h" - -#ifdef LOG -#undef LOG -#endif - -#include <JNIHelp.h> -#include <SkGraphics.h> -#include <SkImageRef_GlobalPool.h> -#include <utils/Log.h> -#include <utils/misc.h> -#include <utils/AssetManager.h> -#include <android_runtime/android_util_AssetManager.h> - -#ifdef ANDROID_INSTRUMENT -#include "SystemTime.h" - -static uint32_t sTotalJavaTimeUsed = 0; -static uint32_t sTotalNativeTimeUsed = 0; - -namespace WebCore { -void Frame::resetFramebridgeTimeCounter() -{ - sTotalJavaTimeUsed = 0; - sTotalNativeTimeUsed = 0; -} - -void Frame::reportFramebridgeTimeCounter() -{ - LOG(LOG_DEBUG, "WebCore", "*-* Total Java callback (frame bridge) time: %d ms\n", - sTotalJavaTimeUsed); - LOG(LOG_DEBUG, "WebCore", "*-* Total native 1 (frame bridge) time: %d ms\n", - sTotalNativeTimeUsed); -} -} -#endif - -namespace android { - -#ifdef ANDROID_INSTRUMENT -class TimeCounterFB { -public: - TimeCounterFB(bool native = false) { - mNative = native; - mStartTime = WebCore::get_thread_msec(); - } - - ~TimeCounterFB() { - if (mNative) - sTotalNativeTimeUsed += WebCore::get_thread_msec() - mStartTime; - else - sTotalJavaTimeUsed += WebCore::get_thread_msec() - mStartTime; - } -private: - bool mNative; - uint32_t mStartTime; -}; -#endif - -// ---------------------------------------------------------------------------- - -#define WEBCORE_MEMORY_CAP 15 * 1024 * 1024 - -// ---------------------------------------------------------------------------- - -JavaVM* jnienv_to_javavm(JNIEnv* env) -{ - JavaVM* vm; - return env->GetJavaVM(&vm) >= 0 ? vm : NULL; -} - -JNIEnv* javavm_to_jnienv(JavaVM* vm) -{ - JNIEnv* env; - return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL; -} - -// ---------------------------------------------------------------------------- - -struct WebCoreFrameBridge::JavaBrowserFrame -{ - JavaVM* mJVM; - jobject mObj; - jobject mHistoryList; // WebBackForwardList object - jmethodID mStartLoadingResource; - jmethodID mLoadStarted; - jmethodID mTransitionToCommitted; - jmethodID mLoadFinished; - jmethodID mReportError; - jmethodID mSetTitle; - jmethodID mWindowObjectCleared; - jmethodID mSetProgress; - jmethodID mDidReceiveIcon; - jmethodID mUpdateVisitedHistory; - jmethodID mHandleUrl; - jmethodID mCreateWindow; - jmethodID mCloseWindow; - jmethodID mDecidePolicyForFormResubmission; - jmethodID mRequestFocus; -}; - -static jfieldID gFrameAndroidField; -#define GET_NATIVE_FRAME(env, obj) ((WebCore::FrameAndroid*)env->GetIntField(obj, gFrameAndroidField)) -#define SET_NATIVE_FRAME(env, obj, frame) (env->SetIntField(obj, gFrameAndroidField, frame)) - -// ---------------------------------------------------------------------------- - -/** - * Helper method for checking java exceptions - * @return true if an exception occurred. - */ -static bool checkException(JNIEnv* env) -{ - if (env->ExceptionCheck() != 0) - { - LOGE("*** Uncaught exception returned from Java call!\n"); - env->ExceptionDescribe(); - return true; - } - return false; -} - -// ---------------------------------------------------------------------------- - -WebCoreFrameBridge::WebCoreFrameBridge(JNIEnv* env, jobject obj, jobject historyList) -{ - jclass clazz = env->GetObjectClass(obj); - mJavaFrame = new JavaBrowserFrame; - mJavaFrame->mJVM = jnienv_to_javavm(env); - mJavaFrame->mObj = env->NewGlobalRef(obj); - mJavaFrame->mHistoryList = env->NewGlobalRef(historyList); - mJavaFrame->mStartLoadingResource = env->GetMethodID(clazz, "startLoadingResource", - "(ILjava/lang/String;Ljava/lang/String;Ljava/util/HashMap;Ljava/lang/String;IZZ)Landroid/webkit/LoadListener;"); - mJavaFrame->mLoadStarted = env->GetMethodID(clazz, "loadStarted", - "(Ljava/lang/String;Landroid/graphics/Bitmap;IZ)V"); - mJavaFrame->mTransitionToCommitted = env->GetMethodID(clazz, "transitionToCommitted", - "(IZ)V"); - mJavaFrame->mLoadFinished = env->GetMethodID(clazz, "loadFinished", - "(Ljava/lang/String;IZ)V"); - mJavaFrame->mReportError = env->GetMethodID(clazz, "reportError", - "(ILjava/lang/String;Ljava/lang/String;)V"); - mJavaFrame->mSetTitle = env->GetMethodID(clazz, "setTitle", - "(Ljava/lang/String;)V"); - mJavaFrame->mWindowObjectCleared = env->GetMethodID(clazz, "windowObjectCleared", - "(I)V"); - mJavaFrame->mSetProgress = env->GetMethodID(clazz, "setProgress", - "(I)V"); - mJavaFrame->mDidReceiveIcon = env->GetMethodID(clazz, "didReceiveIcon", - "(Landroid/graphics/Bitmap;)V"); - mJavaFrame->mUpdateVisitedHistory = env->GetMethodID(clazz, "updateVisitedHistory", - "(Ljava/lang/String;Z)V"); - mJavaFrame->mHandleUrl = env->GetMethodID(clazz, "handleUrl", - "(Ljava/lang/String;)Z"); - mJavaFrame->mCreateWindow = env->GetMethodID(clazz, "createWindow", - "(ZZ)Landroid/webkit/BrowserFrame;"); - mJavaFrame->mCloseWindow = env->GetMethodID(clazz, "closeWindow", - "(Landroid/webkit/WebViewCore;)V"); - mJavaFrame->mDecidePolicyForFormResubmission = env->GetMethodID(clazz, - "decidePolicyForFormResubmission", "(I)V"); - mJavaFrame->mRequestFocus = env->GetMethodID(clazz, "requestFocus", - "()V"); - - LOG_ASSERT(mJavaFrame->mStartLoadingResource, "Could not find method startLoadingResource"); - LOG_ASSERT(mJavaFrame->mLoadStarted, "Could not find method loadStarted"); - LOG_ASSERT(mJavaFrame->mTransitionToCommitted, "Could not find method transitionToCommitted"); - LOG_ASSERT(mJavaFrame->mLoadFinished, "Could not find method loadFinished"); - LOG_ASSERT(mJavaFrame->mReportError, "Could not find method reportError"); - LOG_ASSERT(mJavaFrame->mSetTitle, "Could not find method setTitle"); - LOG_ASSERT(mJavaFrame->mWindowObjectCleared, "Could not find method windowObjectCleared"); - LOG_ASSERT(mJavaFrame->mSetProgress, "Could not find method setProgress"); - LOG_ASSERT(mJavaFrame->mDidReceiveIcon, "Could not find method didReceiveIcon"); - LOG_ASSERT(mJavaFrame->mUpdateVisitedHistory, "Could not find method updateVisitedHistory"); - LOG_ASSERT(mJavaFrame->mHandleUrl, "Could not find method handleUrl"); - LOG_ASSERT(mJavaFrame->mCreateWindow, "Could not find method createWindow"); - LOG_ASSERT(mJavaFrame->mCloseWindow, "Could not find method closeWindow"); - LOG_ASSERT(mJavaFrame->mDecidePolicyForFormResubmission, "Could not find method decidePolicyForFormResubmission"); - LOG_ASSERT(mJavaFrame->mRequestFocus, "Could not find method requestFocus"); - - mUserAgent = WebCore::String(); - mInKeyHandler = false; -} - -WebCoreFrameBridge::~WebCoreFrameBridge() -{ - if (mJavaFrame->mObj) { - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - env->DeleteGlobalRef(mJavaFrame->mObj); - env->DeleteGlobalRef(mJavaFrame->mHistoryList); - mJavaFrame->mObj = 0; - } - delete mJavaFrame; -} - -static jobject createJavaMapFromHTTPHeaders(JNIEnv* env, const WebCore::HTTPHeaderMap& map) -{ - jclass mapClass = env->FindClass("java/util/HashMap"); - LOG_ASSERT(mapClass, "Could not find HashMap class!"); - jmethodID init = env->GetMethodID(mapClass, "<init>", "(I)V"); - LOG_ASSERT(init, "Could not find constructor for HashMap"); - jobject hashMap = env->NewObject(mapClass, init, map.size()); - LOG_ASSERT(hashMap, "Could not create a new HashMap"); - jmethodID put = env->GetMethodID(mapClass, "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); - LOG_ASSERT(put, "Could not find put method on HashMap"); - - WebCore::HTTPHeaderMap::const_iterator end = map.end(); - for (WebCore::HTTPHeaderMap::const_iterator i = map.begin(); i != end; ++i) { - jstring key = env->NewString((unsigned short *)i->first.characters(), i->first.length()); - jstring val = env->NewString((unsigned short *)i->second.characters(), i->second.length()); - if (key && val) { - env->CallObjectMethod(hashMap, put, key, val); - env->DeleteLocalRef(key); - env->DeleteLocalRef(val); - } - } - env->DeleteLocalRef(mapClass); - - return hashMap; -} - -WebCoreResourceLoader* -WebCoreFrameBridge::startLoadingResource(WebCore::ResourceHandle* loader, - const WebCore::ResourceRequest& request, - bool isHighPriority, bool synchronous) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - LOGV("::WebCore:: startLoadingResource(%p, %s)", - loader, request.url().string().ascii().data()); - - WebCore::String method = request.httpMethod(); - WebCore::String postData; - if (request.httpBody()) - postData = request.httpBody()->flattenToString(); - WebCore::HTTPHeaderMap headers = request.httpHeaderFields(); - - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - WebCore::DeprecatedString urlStr = request.url().deprecatedString(); - jstring jUrlStr = env->NewString((unsigned short *)urlStr.unicode(), urlStr.length()); - jstring jMethodStr = NULL; - if (!method.isEmpty()) - jMethodStr = env->NewString((unsigned short *)method.characters(), method.length()); - jstring jPostDataStr = NULL; - if (!postData.isEmpty()) - jPostDataStr = - env->NewString((unsigned short *)postData.characters(), postData.length()); - - jobject jHeaderMap = createJavaMapFromHTTPHeaders(env, headers); - - // Convert the WebCore Cache Policy to a WebView Cache Policy. - int cacheMode = 0; // WebView.LOAD_NORMAL - switch (request.cachePolicy()) { - case WebCore::ReloadIgnoringCacheData: - cacheMode = 2; // WebView.LOAD_NO_CACHE - break; - case WebCore::ReturnCacheDataDontLoad: - cacheMode = 3; // WebView.LOAD_CACHE_ONLY - break; - case WebCore::ReturnCacheDataElseLoad: - cacheMode = 1; // WebView.LOAD_CACHE_ELSE_NETWORK - break; - case WebCore::UseProtocolCachePolicy: - default: - break; - } - - LOGV("::WebCore:: startLoadingResource %s with cacheMode %d", urlStr.ascii(), cacheMode); - - - jobject jLoadListener = - env->CallObjectMethod(mJavaFrame->mObj, mJavaFrame->mStartLoadingResource, - (int)loader, jUrlStr, jMethodStr, jHeaderMap, - jPostDataStr, cacheMode, isHighPriority, synchronous); - - env->DeleteLocalRef(jUrlStr); - env->DeleteLocalRef(jMethodStr); - env->DeleteLocalRef(jPostDataStr); - env->DeleteLocalRef(jHeaderMap); - if (checkException(env)) - return NULL; - - WebCoreResourceLoader* h = NULL; - if (jLoadListener) - h = new WebCoreResourceLoader(env, jLoadListener); - env->DeleteLocalRef(jLoadListener); - return h; -} - -void -WebCoreFrameBridge::reportError(int errorCode, const WebCore::String& description, - const WebCore::String& failingUrl) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - LOGV("::WebCore:: reportError(%d, %s)", errorCode, description.ascii().data()); - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - - jstring descStr = env->NewString((unsigned short*)description.characters(), description.length()); - jstring failUrl = env->NewString((unsigned short*)failingUrl.characters(), failingUrl.length()); - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mReportError, errorCode, descStr, failUrl); - env->DeleteLocalRef(descStr); - env->DeleteLocalRef(failUrl); -} - -void -WebCoreFrameBridge::loadStarted(WebCore::FrameAndroid* frame) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - const WebCore::KURL& url = frame->loader()->activeDocumentLoader()->url(); - if (url.isEmpty()) - return; - LOGV("::WebCore:: loadStarted %s", url.string().ascii().data()); - - bool isMainFrame = (!frame->tree() || !frame->tree()->parent()); - WebCore::FrameLoadType loadType = frame->loader()->loadType(); - - if (loadType == WebCore::FrameLoadTypeReplace || - loadType == WebCore::FrameLoadTypeSame || - (loadType == WebCore::FrameLoadTypeRedirectWithLockedHistory && - !isMainFrame)) - return; - - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - WebCore::String urlString(url.string()); - // If this is the main frame and we already have a favicon in the database, - // send it along with the page started notification. - jobject favicon = NULL; - if (isMainFrame) { - WebCore::Image* icon = WebCore::iconDatabase()->iconForPageURL(urlString, WebCore::IntSize(16, 16)); - if (icon) - favicon = webcoreImageToJavaBitmap(env, icon); - LOGV("favicons", "Starting load with icon %p for %s", icon, url.deprecatedString().ascii()); - } - jstring urlStr = env->NewString((unsigned short*)urlString.characters(), urlString.length()); - - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mLoadStarted, urlStr, favicon, - (int)loadType, isMainFrame); - checkException(env); - env->DeleteLocalRef(urlStr); - if (favicon) - env->DeleteLocalRef(favicon); -} - -void -WebCoreFrameBridge::transitionToCommitted(WebCore::Frame* frame) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - WebCore::FrameLoadType loadType = frame->loader()->loadType(); - bool isMainFrame = (!frame->tree() || !frame->tree()->parent()); - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mTransitionToCommitted, - (int)loadType, isMainFrame); - checkException(env); -} - -void -WebCoreFrameBridge::didFinishLoad(WebCore::Frame* frame) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - WebCore::FrameLoader* loader = frame->loader(); - const WebCore::KURL& url = loader->activeDocumentLoader()->url(); - if (url.isEmpty()) - return; - LOGV("::WebCore:: didFinishLoad %s", url.string().ascii().data()); - - bool isMainFrame = (!frame->tree() || !frame->tree()->parent()); - WebCore::FrameLoadType loadType = loader->loadType(); - WebCore::String urlString(url.string()); - jstring urlStr = env->NewString((unsigned short*)urlString.characters(), urlString.length()); - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mLoadFinished, urlStr, - (int)loadType, isMainFrame); - checkException(env); - env->DeleteLocalRef(urlStr); -} - -void -WebCoreFrameBridge::addHistoryItem(WebCore::HistoryItem* item) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - LOGV("::WebCore:: addHistoryItem"); - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - WebHistory::AddItem(env, mJavaFrame->mHistoryList, item); -} - -void -WebCoreFrameBridge::removeHistoryItem(int index) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - LOGV("::WebCore:: removeHistoryItem at %d", index); - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - WebHistory::RemoveItem(env, mJavaFrame->mHistoryList, index); -} - -void -WebCoreFrameBridge::updateHistoryIndex(int newIndex) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - LOGV("::WebCore:: updateHistoryIndex to %d", newIndex); - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - WebHistory::UpdateHistoryIndex(env, mJavaFrame->mHistoryList, newIndex); -} - -void -WebCoreFrameBridge::setTitle(const WebCore::String& title) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif -#ifndef NDEBUG - LOGV("setTitle(%s)", title.ascii().data()); -#endif - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - jstring jTitleStr = env->NewString((unsigned short *)title.characters(), title.length()); - - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mSetTitle, - jTitleStr); - checkException(env); - env->DeleteLocalRef(jTitleStr); -} - -void -WebCoreFrameBridge::windowObjectCleared(WebCore::FrameAndroid* frame) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - LOGV("::WebCore:: windowObjectCleared"); - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mWindowObjectCleared, (int)frame); - checkException(env); -} - -void -WebCoreFrameBridge::setProgress(float newProgress) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - int progress = (int) (100 * newProgress); - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mSetProgress, progress); - checkException(env); -} - -const WebCore::String -WebCoreFrameBridge::userAgentForURL(const WebCore::KURL* url) -{ - return mUserAgent; -} - -void -WebCoreFrameBridge::didReceiveIcon(WebCore::Image* icon) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - LOG_ASSERT(icon, "DidReceiveIcon called without an image!"); - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - jobject bitmap = webcoreImageToJavaBitmap(env, icon); - if (!bitmap) - return; - - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mDidReceiveIcon, bitmap); - env->DeleteLocalRef(bitmap); - checkException(env); -} - -void -WebCoreFrameBridge::updateVisitedHistory(const WebCore::KURL& url, bool reload) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - WebCore::String urlStr(url.string()); - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - jstring jUrlStr = env->NewString((unsigned short*)urlStr.characters(), urlStr.length()); - - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mUpdateVisitedHistory, jUrlStr, reload); - checkException(env); -} - -bool -WebCoreFrameBridge::canHandleRequest(const WebCore::ResourceRequest& request) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - // Internal loads are ok but any request that is due to a user hitting a key - // should be checked. - bool userGesture = false; -#ifdef ANDROID_USER_GESTURE - userGesture = request.userGesture(); -#endif - WebCore::KURL requestUrl = request.url(); - if (!mInKeyHandler && !userGesture && - (requestUrl.protocolIs("http") || requestUrl.protocolIs("https") || - requestUrl.protocolIs("file") || requestUrl.protocolIs("about") || - requestUrl.protocolIs("javascript"))) - return true; - WebCore::String url(request.url().string()); - // Empty urls should not be sent to java - if (url.isEmpty()) - return true; - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length()); - - // check to see whether browser app wants to hijack url loading. - // if browser app handles the url, we will return false to bail out WebCore loading - jboolean ret = env->CallBooleanMethod(mJavaFrame->mObj, mJavaFrame->mHandleUrl, jUrlStr); - checkException(env); - return (ret == 0); -} - -WebCore::Frame* -WebCoreFrameBridge::createWindow(bool dialog, bool userGesture) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - jobject obj = env->CallObjectMethod(mJavaFrame->mObj, - mJavaFrame->mCreateWindow, dialog, userGesture); - if (obj) { - WebCore::FrameAndroid* frame = GET_NATIVE_FRAME(env, obj); - return frame; - } - return NULL; -} - -void -WebCoreFrameBridge::requestFocus() const -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mRequestFocus); - checkException(env); -} - -void -WebCoreFrameBridge::closeWindow(WebCoreViewBridge* viewBridge) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - assert(viewBridge); - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - // TODO: This is a hack until WebCoreViewBridge is no longer an interface. - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mCloseWindow, - ((WebViewCore*)viewBridge)->getJavaObject()); -} - -struct PolicyFunctionWrapper { - WebCore::FramePolicyFunction func; -}; - -void -WebCoreFrameBridge::decidePolicyForFormResubmission(WebCore::FramePolicyFunction func) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter; -#endif - JNIEnv* env = javavm_to_jnienv(mJavaFrame->mJVM); - PolicyFunctionWrapper* p = new PolicyFunctionWrapper; - p->func = func; - env->CallVoidMethod(mJavaFrame->mObj, mJavaFrame->mDecidePolicyForFormResubmission, p); -} - -// ---------------------------------------------------------------------------- -static void CallPolicyFunction(JNIEnv* env, jobject obj, jint func, jint decision) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeCallPolicyFunction must take a valid frame pointer!"); - PolicyFunctionWrapper* pFunc = (PolicyFunctionWrapper*)func; - LOG_ASSERT(pFunc, "nativeCallPolicyFunction must take a valid function pointer!"); - - (pFrame->loader()->*(pFunc->func))((WebCore::PolicyAction)decision); -} - -static void CreateFrame(JNIEnv* env, jobject obj, jobject jAssetManager, jobject historyList) -{ - // Register this thread as the main thread. - KJS::Collector::registerAsMainThread(); -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::ChromeClientAndroid* chromeC = new WebCore::ChromeClientAndroid; - WebCore::EditorClientAndroid* editorC = new WebCore::EditorClientAndroid; - WebCore::ContextMenuClient* contextMenuC = new WebCore::ContextMenuClientAndroid; - WebCore::DragClient* dragC = new WebCore::DragClientAndroid; - WebCore::FrameLoaderClientAndroid* loaderC = new WebCore::FrameLoaderClientAndroid; - WebCore::InspectorClientAndroid* inspectorC = new WebCore::InspectorClientAndroid; - // Create a new page - WebCore::Page* page = new WebCore::Page(chromeC, contextMenuC, editorC, dragC, inspectorC); - /* TODO: Don't turn on PageCache until we can restore the ScrollView State. - * This caused bug http://b/issue?id=1202983 - page->settings()->setUsesPageCache(true); - // 10 is a random number chosen because it is small enough to give the user - // a good back/forward page cache without allowing the page cache to get too - // big. - WebCore::pageCache()->setCapacity(10); - */ - editorC->setPage(page); - page->setGroupName("com.android.browser"); - // Frames are automatically refed to 1, keep this ref because BrowserFrame will - // maintain a native frame pointer. - WebCore::FrameAndroid* frame = new WebCore::FrameAndroid(page, NULL, loaderC); - chromeC->setFrame(frame); - loaderC->setFrame(frame); - - // Create one instance of WebCoreFrameBridge for calling into Java from WebCore - WebCoreFrameBridge* frameBridge = new WebCoreFrameBridge(env, obj, historyList); - - // Pass the bridge to the frame and release our ownership. - frame->setBridge(frameBridge); - Release(frameBridge); - - LOGV("::WebCore:: createFrame %p", frame); - - // Set the mNativeFrame field in Frame - SET_NATIVE_FRAME(env, obj, (int)frame); - - // Setup the asset manager. - AssetManager* am = assetManagerForJavaObject(env, jAssetManager); - // Initialize our skinning classes - WebCore::RenderSkinAndroid::Init(am); -} - -static void DestroyFrame(JNIEnv* env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeDestroyFrame must take a valid frame pointer!"); - - LOGV("::WebCore:: deleting frame %p", pFrame); - - WebCore::FrameView* view = pFrame->view(); - // detachFromParent will cause the page to be closed. - WebCore::FrameLoader* fl = pFrame->loader(); - // retain a pointer because detachFromParent will set the page to null. - WebCore::Page* page = pFrame->page(); - if (fl) - fl->detachFromParent(); - delete page; - view->deref(); - - SET_NATIVE_FRAME(env, obj, 0); -} - -static void CreateView(JNIEnv *env, jobject obj, jobject widget) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeCreateView must take a valid frame pointer!"); - - // Create a new FrameView and attach an initial WebViewCore. FrameView begins with an initial ref - // of 1 and that ref is in WebViewCore. - WebCore::FrameView* view = new WebCore::FrameView(pFrame); - // The viewBridge will make a java call to maintain a pointer to the view. - WebViewCore* viewBridge = new WebViewCore(env, widget, view); - view->setWebCoreViewBridge(viewBridge); - view->deref(); - Release(viewBridge); - - // Attach the view to the frame. - pFrame->setView(view); - - // Set the frame to active to turn on keyboard focus. - pFrame->init(); - pFrame->selectionController()->setFocused(true); - - LOGV("::WebCore:: created view %p with bridge %p", view, viewBridge); -} - -static void DetachView(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeDetachView must take a valid frame pointer!"); - LOGV("::WebCore:: detaching view from frame %p", pFrame); - - WebCore::FrameView* view = pFrame->view(); - LOG_ASSERT(view, "cannot detach a null view!"); - - // Remove keyboard focus - pFrame->selectionController()->setFocused(false); - - // Remove the FrameView from the frame. - pFrame->setView(NULL); - -} - -static jboolean LoadUrl(JNIEnv *env, jobject obj, jstring url) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeLoadUrl must take a valid frame pointer!"); - - const char* urlStr = env->GetStringUTFChars(url, NULL); - WebCore::String webcoreUrl(urlStr); - WebCore::ResourceRequest request(webcoreUrl); - WebCore::DeprecatedString protocol = request.url().protocol(); - // If the url is http(s) and doesn't have a host, it is a bad url. - if ((WebCore::equalIgnoringCase(protocol, "http") || - WebCore::equalIgnoringCase(protocol, "https")) && - request.url().host().isEmpty()) { - env->ReleaseStringUTFChars(url, urlStr); - return false; - } - - pFrame->loader()->load(request); - env->ReleaseStringUTFChars(url, urlStr); - return true; -} - - -static void LoadData(JNIEnv *env, jobject obj, jstring baseUrl, jstring data, - jstring mimeType, jstring encoding, jstring failUrl) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeLoadData must take a valid frame pointer!"); - - // Setup the resource request - const char* baseUrlStr = env->GetStringUTFChars(baseUrl, NULL); - WebCore::String baseUrlString(baseUrlStr); - WebCore::ResourceRequest request(baseUrlString); - - // Setup the substituteData - const char* dataStr = env->GetStringUTFChars(data, NULL); - WTF::RefPtr<WebCore::SharedBuffer> sharedBuffer = - new WebCore::SharedBuffer(); - LOG_ASSERT(dataStr, "nativeLoadData has a null data string."); - sharedBuffer->append(dataStr, strlen(dataStr)); - const char* mimeTypeStr = env->GetStringUTFChars(mimeType, NULL); - WebCore::String mimeTypeString(mimeTypeStr); - const char* encodingStr = env->GetStringUTFChars(encoding, NULL); - WebCore::String encodingString(encodingStr); - const char* failUrlStr = env->GetStringUTFChars(failUrl, NULL); - WebCore::KURL failURL(failUrlStr); - WebCore::SubstituteData substituteData(sharedBuffer, mimeTypeString, - encodingString, failURL); - - // Perform the load - pFrame->loader()->load(request, substituteData); - - // Release the Java strings - env->ReleaseStringUTFChars(baseUrl, baseUrlStr); - env->ReleaseStringUTFChars(data, dataStr); - env->ReleaseStringUTFChars(mimeType, mimeTypeStr); - env->ReleaseStringUTFChars(encoding, encodingStr); - env->ReleaseStringUTFChars(failUrl, failUrlStr); -} - -static void StopLoading(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeStopLoading must take a valid frame pointer!"); - LOGV("::WebCore:: stopLoading %p", pFrame); - - // Stop loading the page and do not send an unload event - pFrame->loader()->stopForUserCancel(); -} - -static jstring ExternalRepresentation(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "android_webcore_nativeExternalRepresentation must take a valid frame pointer!"); - - // Request external representation of the render tree - WebCore::DeprecatedString renderDump = externalRepresentation(pFrame->renderer()); - unsigned len = renderDump.length(); - if (!len) - return NULL; - return env->NewString((unsigned short*)renderDump.unicode(), len); -} - -static jstring DocumentAsText(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "android_webcore_nativeDocumentAsText must take a valid frame pointer!"); - - WebCore::Element *documentElement = pFrame->document()->documentElement(); - WebCore::String renderDump = ((WebCore::HTMLElement*)documentElement)->innerText(); - renderDump.append("\n"); - unsigned len = renderDump.length(); - if (!len) - return NULL; - return env->NewString((unsigned short*)renderDump.characters(), len); -} - -static void Reload(JNIEnv *env, jobject obj, jboolean allowStale) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeReload must take a valid frame pointer!"); - - WebCore::FrameLoader* loader = pFrame->loader(); - if (allowStale) - loader->reloadAllowingStaleData(loader->documentLoader()->overrideEncoding()); - else - loader->reload(); -} - -static void GoBackOrForward(JNIEnv *env, jobject obj, jint pos) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeGoBackOrForward must take a valid frame pointer!"); - - if (pos == 1) - pFrame->page()->goForward(); - else if (pos == -1) - pFrame->page()->goBack(); - else - pFrame->loader()->goBackOrForward(pos); -} - -static jobject StringByEvaluatingJavaScriptFromString(JNIEnv *env, jobject obj, jstring script) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "stringByEvaluatingJavaScriptFromString must take a valid frame pointer!"); - - const char* scriptStr = env->GetStringUTFChars(script, NULL); - WebCore::String result = pFrame->stringByEvaluatingJavaScriptFromString(scriptStr); - env->ReleaseStringUTFChars(script, scriptStr); - - unsigned len = result.length(); - if (len == 0) - return NULL; - return env->NewString((unsigned short*)result.characters(), len); -} - -static void AddJavascriptInterface(JNIEnv *env, jobject obj, jint nativeFramePointer, - jobject javascriptObj, jstring interfaceName) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = (WebCore::FrameAndroid*)nativeFramePointer; - LOG_ASSERT(pFrame, "nativeAddJavascriptInterface must take a valid frame pointer!"); - - const char* interfaceNameStr = env->GetStringUTFChars(interfaceName, NULL); - JavaVM* vm; - env->GetJavaVM(&vm); - LOGV("::WebCore:: addJSInterface: %p", pFrame); - pFrame->addJavascriptInterface((void*)(vm), javascriptObj, interfaceNameStr); - - env->ReleaseStringUTFChars(interfaceName, interfaceNameStr); -} - -static void SetCacheDisabled(JNIEnv *env, jobject obj, jboolean disabled) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::cache()->setDisabled(disabled); -} - -static jboolean CacheDisabled(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - return WebCore::cache()->disabled(); -} - -static void ClearCache(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - if (!WebCore::cache()->disabled()) { - // Disabling the cache will remove all resources from the cache. They may - // still live on if they are referenced by some Web page though. - WebCore::cache()->setDisabled(true); - WebCore::cache()->setDisabled(false); - } - // force JavaScript to GC when clear cache - WebCore::gcController().garbageCollectSoon(); - // clear image cache - SkImageRef_GlobalPool::SetRAMUsed(0); -} - -static jboolean DocumentHasImages(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "DocumentHasImages must take a valid frame pointer!"); - - return pFrame->document()->images()->length() > 0; -} - -static jboolean HasPasswordField(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "HasPasswordField must take a valid frame pointer!"); - - bool found = false; - WTF::PassRefPtr<WebCore::HTMLCollection> form = pFrame->document()->forms(); - WebCore::Node* node = form->firstItem(); - while (node && !found) { - WTF::Vector<WebCore::HTMLGenericFormElement*> elements = - ((WebCore::HTMLFormElement*)node)->formElements; - size_t size = elements.size(); - for (size_t i = 0; i< size && !found; i++) { - WebCore::HTMLGenericFormElement* e = elements[i]; - if (e->hasLocalName(WebCore::HTMLNames::inputTag)) { - if (((WebCore::HTMLInputElement*)e)->inputType() == - WebCore::HTMLInputElement::PASSWORD) - found = true; - } - } - node = form->nextItem(); - } - return found; -} - -static jobjectArray GetUsernamePassword(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "GetUsernamePassword must take a valid frame pointer!"); - jobjectArray strArray = NULL; - - WebCore::String username, password; - bool found = false; - WTF::PassRefPtr<WebCore::HTMLCollection> form = pFrame->document()->forms(); - WebCore::Node* node = form->firstItem(); - while (node && !found) { - WTF::Vector<WebCore::HTMLGenericFormElement*> elements = - ((WebCore::HTMLFormElement*)node)->formElements; - size_t size = elements.size(); - for (size_t i = 0; i< size && !found; i++) { - WebCore::HTMLGenericFormElement* e = elements[i]; - if (e->hasLocalName(WebCore::HTMLNames::inputTag)) { - WebCore::HTMLInputElement* input = (WebCore::HTMLInputElement*)e; - if (input->autoComplete() == false) - continue; - if (input->inputType() == WebCore::HTMLInputElement::PASSWORD) - password = input->value(); - else if (input->inputType() == WebCore::HTMLInputElement::TEXT) - username = input->value(); - if (!username.isNull() && !password.isNull()) - found = true; - } - } - node = form->nextItem(); - } - if (found) { - jclass stringClass = env->FindClass("java/lang/String"); - strArray = env->NewObjectArray(2, stringClass, NULL); - env->SetObjectArrayElement(strArray, 0, env->NewString((unsigned short *) - username.characters(), username.length())); - env->SetObjectArrayElement(strArray, 1, env->NewString((unsigned short *) - password.characters(), password.length())); - } - return strArray; -} - -static void SetUsernamePassword(JNIEnv *env, jobject obj, - jstring username, jstring password) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "SetUsernamePassword must take a valid frame pointer!"); - - WebCore::HTMLInputElement* usernameEle = NULL; - WebCore::HTMLInputElement* passwordEle = NULL; - bool found = false; - WTF::PassRefPtr<WebCore::HTMLCollection> form = pFrame->document()->forms(); - WebCore::Node* node = form->firstItem(); - while (node && !found) { - WTF::Vector<WebCore::HTMLGenericFormElement*> elements = - ((WebCore::HTMLFormElement*)node)->formElements; - size_t size = elements.size(); - for (size_t i = 0; i< size && !found; i++) { - WebCore::HTMLGenericFormElement* e = elements[i]; - if (e->hasLocalName(WebCore::HTMLNames::inputTag)) { - WebCore::HTMLInputElement* input = (WebCore::HTMLInputElement*)e; - if (input->autoComplete() == false) - continue; - if (input->inputType() == WebCore::HTMLInputElement::PASSWORD) - passwordEle = input; - else if (input->inputType() == WebCore::HTMLInputElement::TEXT) - usernameEle = input; - if (usernameEle != NULL && passwordEle != NULL) - found = true; - } - } - node = form->nextItem(); - } - if (found) { - const char* usernameStr = env->GetStringUTFChars(username, NULL); - const char* passwordStr = env->GetStringUTFChars(password, NULL); - usernameEle->setValue(usernameStr); - passwordEle->setValue(passwordStr); - env->ReleaseStringUTFChars(username, usernameStr); - env->ReleaseStringUTFChars(password, passwordStr); - } -} - -static jobject GetFormTextData(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterFB counter(true); -#endif - WebCore::FrameAndroid* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "GetFormTextData must take a valid frame pointer!"); - jobject hashMap = NULL; - - WTF::PassRefPtr<WebCore::HTMLCollection> collection = pFrame->document()->forms(); - if (collection->length() > 0) { - jclass mapClass = env->FindClass("java/util/HashMap"); - LOG_ASSERT(mapClass, "Could not find HashMap class!"); - jmethodID init = env->GetMethodID(mapClass, "<init>", "(I)V"); - LOG_ASSERT(init, "Could not find constructor for HashMap"); - hashMap = env->NewObject(mapClass, init, 1); - LOG_ASSERT(hashMap, "Could not create a new HashMap"); - jmethodID put = env->GetMethodID(mapClass, "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); - LOG_ASSERT(put, "Could not find put method on HashMap"); - - static const WebCore::AtomicString text("text"); - static const WebCore::AtomicString off("off"); - - WebCore::HTMLFormElement* form; - WebCore::HTMLInputElement* input; - for (WebCore::Node* node = collection->firstItem(); node; node = collection->nextItem()) { - form = static_cast<WebCore::HTMLFormElement*>(node); - if (form->autoComplete()) { - WTF::Vector<WebCore::HTMLGenericFormElement*> elements = form->formElements; - size_t size = elements.size(); - for (size_t i = 0; i < size; i++) { - WebCore::HTMLGenericFormElement* e = elements[i]; - if (e->type() == text) { - if (e->hasAttribute(WebCore::HTMLNames::autocompleteAttr)) { - const WebCore::AtomicString& attr = e->getAttribute(WebCore::HTMLNames::autocompleteAttr); - if (attr == off) - continue; - } - input = (WebCore::HTMLInputElement*) e; - WebCore::String value = input->value(); - int len = value.length(); - if (len) { - const WebCore::AtomicString& name = input->name(); - jstring key = env->NewString((jchar *)name.characters(), name.length()); - jstring val = env->NewString((jchar *)value.characters(), len); - LOG_ASSERT(key && val, "name or value not set"); - env->CallObjectMethod(hashMap, put, key, val); - env->DeleteLocalRef(key); - env->DeleteLocalRef(val); - } - } - } - } - } - env->DeleteLocalRef(mapClass); - - } - return hashMap; -} - -// ---------------------------------------------------------------------------- - -/* - * JNI registration. - */ -static JNINativeMethod gBrowserFrameNativeMethods[] = { - /* name, signature, funcPtr */ - { "nativeCallPolicyFunction", "(II)V", - (void*) CallPolicyFunction }, - { "nativeCreateFrame", "(Landroid/content/res/AssetManager;Landroid/webkit/WebBackForwardList;)V", - (void*) CreateFrame }, - { "nativeCreateView", "(Landroid/webkit/WebViewCore;)V", - (void*) CreateView }, - { "nativeDestroyFrame", "()V", - (void*) DestroyFrame }, - { "nativeDetachView", "()V", - (void*) DetachView }, - { "stopLoading", "()V", - (void*) StopLoading }, - { "nativeLoadUrl", "(Ljava/lang/String;)Z", - (void*) LoadUrl }, - { "nativeLoadData", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", - (void*) LoadData }, - { "externalRepresentation", "()Ljava/lang/String;", - (void*) ExternalRepresentation }, - { "documentAsText", "()Ljava/lang/String;", - (void*) DocumentAsText }, - { "reload", "(Z)V", - (void*) Reload }, - { "goBackOrForward", "(I)V", - (void*) GoBackOrForward }, - { "nativeAddJavascriptInterface", "(ILjava/lang/Object;Ljava/lang/String;)V", - (void*) AddJavascriptInterface }, - { "stringByEvaluatingJavaScriptFromString", - "(Ljava/lang/String;)Ljava/lang/String;", - (void*) StringByEvaluatingJavaScriptFromString }, - { "setCacheDisabled", "(Z)V", - (void*) SetCacheDisabled }, - { "cacheDisabled", "()Z", - (void*) CacheDisabled }, - { "clearCache", "()V", - (void*) ClearCache }, - { "documentHasImages", "()Z", - (void*) DocumentHasImages }, - { "hasPasswordField", "()Z", - (void*) HasPasswordField }, - { "getUsernamePassword", "()[Ljava/lang/String;", - (void*) GetUsernamePassword }, - { "setUsernamePassword", "(Ljava/lang/String;Ljava/lang/String;)V", - (void*) SetUsernamePassword }, - { "getFormTextData", "()Ljava/util/HashMap;", - (void*) GetFormTextData } -}; - -int register_webcoreframebridge(JNIEnv* env) -{ - jclass clazz = env->FindClass("android/webkit/BrowserFrame"); - LOG_ASSERT(clazz, "Cannot find BrowserFrame"); - gFrameAndroidField = env->GetFieldID(clazz, "mNativeFrame", "I"); - LOG_ASSERT(gFrameAndroidField, "Cannot find mNativeFrame on BrowserFrame"); - - return jniRegisterNativeMethods(env, "android/webkit/BrowserFrame", - gBrowserFrameNativeMethods, NELEM(gBrowserFrameNativeMethods)); -} - -} /* namespace android */ - diff --git a/WebCore/platform/android/jni/WebCoreFrameBridge.h b/WebCore/platform/android/jni/WebCoreFrameBridge.h deleted file mode 100644 index ba89f19..0000000 --- a/WebCore/platform/android/jni/WebCoreFrameBridge.h +++ /dev/null @@ -1,106 +0,0 @@ -/* -** Copyright 2006-2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef WEBCOREFRAMEBRIDGE_H -#define WEBCOREFRAMEBRIDGE_H - -#include "FrameLoaderClient.h" -#include "PlatformString.h" -#include "WebCoreRefObject.h" -#include <jni.h> - -namespace WebCore { - class FrameAndroid; - class HistoryItem; - class Image; - class RenderPart; - class ResourceHandle; - class ResourceRequest; -} - -class WebCoreViewBridge; - -namespace android { - -class WebCoreResourceLoader; - -class WebCoreFrameBridge : public WebCoreRefObject { - public: - WebCoreFrameBridge(JNIEnv* env, jobject obj, jobject historyList); - ~WebCoreFrameBridge(); - - WebCoreResourceLoader* startLoadingResource(WebCore::ResourceHandle*, - const WebCore::ResourceRequest& request, - bool isHighPriority, - bool synchronous); - - void reportError(int errorCode, const WebCore::String& description, - const WebCore::String& failingUrl); - - void loadStarted(WebCore::FrameAndroid* frame); - - void transitionToCommitted(WebCore::Frame* frame); - - void didFinishLoad(WebCore::Frame* frame); - - void addHistoryItem(WebCore::HistoryItem* item); - - void removeHistoryItem(int index); - - void updateHistoryIndex(int newIndex); - - void setTitle(const WebCore::String& title); - - void windowObjectCleared(WebCore::FrameAndroid* frame); - - void setProgress(float newProgress); - - const WebCore::String userAgentForURL(const WebCore::KURL* url); - - void didReceiveIcon(WebCore::Image* icon); - - void updateVisitedHistory(const WebCore::KURL& url, bool reload); - - bool canHandleRequest(const WebCore::ResourceRequest& request); - - WebCore::Frame* createWindow(bool dialog, bool userGesture); - - void requestFocus() const; - - void closeWindow(WebCoreViewBridge* viewBridge); - - void decidePolicyForFormResubmission(WebCore::FramePolicyFunction func); - - void setUserAgent(WebCore::String userAgent) { mUserAgent = userAgent; } - - /** - * This function is called during a key event so that canHandleRequest can - * avoid asking the application to override the url loading. If a load is - * due to a key event, then we ask the application if it wants to override - * the load. Otherwise, we attempt to load the resource internally. - */ - void setInKeyHandler(bool inKeyHandler) { mInKeyHandler = inKeyHandler; } - - private: - struct JavaBrowserFrame; - JavaBrowserFrame* mJavaFrame; - WebCore::String mUserAgent; - bool mInKeyHandler; -}; - -} // namespace android - -#endif // WEBCOREFRAMEBRIDGE_H diff --git a/WebCore/platform/android/jni/WebCoreJni.cpp b/WebCore/platform/android/jni/WebCoreJni.cpp deleted file mode 100644 index 8ba3d0b..0000000 --- a/WebCore/platform/android/jni/WebCoreJni.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "WebCoreJni.h" -#include <jni.h> - -#ifdef LOG -#undef LOG -#endif -#define LOG_TAG "webcoreglue" -#include <utils/Log.h> - -namespace android { - -JavaVM* WebCoreJni::mJavaVM; - -extern int register_webcoreframebridge(JNIEnv*); -extern int register_javabridge(JNIEnv*); -extern int register_resource_loader(JNIEnv*); -extern int register_webviewcore(JNIEnv*); -extern int register_webhistory(JNIEnv*); -extern int register_webicondatabase(JNIEnv*); -extern int register_websettings(JNIEnv*); -extern int register_webview(JNIEnv*); - -} - -struct RegistrationMethod { - const char* name; - int (*func)(JNIEnv*); -}; - -static RegistrationMethod gWebCoreRegMethods[] = { - { "JavaBridge", android::register_javabridge }, - { "WebCoreFrameBridge", android::register_webcoreframebridge }, - { "WebCoreResourceLoader", android::register_resource_loader }, - { "WebViewCore", android::register_webviewcore }, - { "WebHistory", android::register_webhistory }, - { "WebIconDatabase", android::register_webicondatabase }, - { "WebSettings", android::register_websettings }, - { "WebView", android::register_webview } -}; - -EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) -{ - // Save the JavaVM pointer for use globally. - android::WebCoreJni::setJavaVM(vm); - - JNIEnv* env = NULL; - jint result = -1; - - if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { - LOGE("GetEnv failed!"); - return result; - } - LOG_ASSERT(env, "Could not retrieve the env!"); - - const RegistrationMethod* method = gWebCoreRegMethods; - const RegistrationMethod* end = method + sizeof(gWebCoreRegMethods)/sizeof(RegistrationMethod); - while (method != end) { - if (method->func(env) < 0) { - LOGE("%s registration failed!", method->name); - return result; - } - method++; - } - - return JNI_VERSION_1_4; -} diff --git a/WebCore/platform/android/jni/WebCoreJni.h b/WebCore/platform/android/jni/WebCoreJni.h deleted file mode 100644 index 4031d43..0000000 --- a/WebCore/platform/android/jni/WebCoreJni.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright 2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef WEBCOREJNI_H -#define WEBCOREJNI_H - -#include <jni.h> - -namespace android { - -class WebCoreJni { - static JavaVM *mJavaVM; - public: - static void setJavaVM(JavaVM *vm) { mJavaVM = vm; } - static JavaVM *getJavaVM() { return mJavaVM; } -}; - -} // namespace android - -#endif // WEBCOREJNI_H diff --git a/WebCore/platform/android/jni/WebCoreRefObject.h b/WebCore/platform/android/jni/WebCoreRefObject.h deleted file mode 100644 index 7e96191..0000000 --- a/WebCore/platform/android/jni/WebCoreRefObject.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef WEBCORE_FOUNDATION_h -#define WEBCORE_FOUNDATION_h - -#include "SkRefCnt.h" - -typedef SkRefCnt WebCoreRefObject; - -static inline WebCoreRefObject* Retain(WebCoreRefObject* obj) -{ - if (obj) - obj->ref(); - return obj; -} - -static inline void Release(WebCoreRefObject* obj) -{ - if (obj) - obj->unref(); -} - -#endif // WEBCORE_FOUNDATION_h diff --git a/WebCore/platform/android/jni/WebCoreResourceLoader.cpp b/WebCore/platform/android/jni/WebCoreResourceLoader.cpp deleted file mode 100644 index 3807a2a..0000000 --- a/WebCore/platform/android/jni/WebCoreResourceLoader.cpp +++ /dev/null @@ -1,395 +0,0 @@ -/* -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#define LOG_TAG "webcoreglue" - -#include <config.h> -#include <wtf/Platform.h> - -#include "WebCoreResourceLoader.h" -#include "SkUtils.h" -#include "WebCoreJni.h" - -#include "ResourceError.h" -#include "ResourceHandle.h" -#include "ResourceHandleClient.h" -#include "ResourceHandleInternal.h" -#include "ResourceResponse.h" - -#ifdef ANDROID_INSTRUMENT -#include "Frame.h" -#include "SystemTime.h" -#endif - -#undef LOG -#include <utils/Log.h> -#include <utils/misc.h> -#include <JNIHelp.h> -#include <SkTypes.h> -#include <stdlib.h> - -#ifdef ANDROID_INSTRUMENT -static uint32_t sTotalTimeUsed = 0; - -namespace WebCore { -void Frame::resetResourceLoadTimeCounter() -{ - sTotalTimeUsed = 0; -} - -void Frame::reportResourceLoadTimeCounter() -{ - LOG(LOG_DEBUG, "WebCore", "*-* Total native 3 (resource load) time: %d ms\n", - sTotalTimeUsed); -} -} -#endif - -namespace android { - -#ifdef ANDROID_INSTRUMENT -class TimeCounterRC { -public: - TimeCounterRC() { - mStartTime = WebCore::get_thread_msec(); - } - - ~TimeCounterRC() { - sTotalTimeUsed += WebCore::get_thread_msec() - mStartTime; - } - -private: - uint32_t mStartTime; -}; -#endif - -// ---------------------------------------------------------------------------- - -static struct resourceloader_t { - jfieldID mObject; - jmethodID mCancelMethodID; - jmethodID mDownloadFileMethodID; - jmethodID mWillLoadFromCacheMethodID; -} gResourceLoader; - -// ---------------------------------------------------------------------------- - -/** - * Helper method for checking java exceptions - * @return true if an exception occurred. - */ -static bool checkException(JNIEnv* env) -{ - if (env->ExceptionCheck() != 0) - { - LOGE("*** Uncaught exception returned from Java call!\n"); - env->ExceptionDescribe(); - return true; - } - return false; -} - -// ---------------------------------------------------------------------------- - -extern JavaVM* jnienv_to_javavm(JNIEnv* env); -extern JNIEnv* javavm_to_jnienv(JavaVM* vm); - -//----------------------------------------------------------------------------- - -#define GET_NATIVE_HANDLE(env, obj) ((WebCore::ResourceHandle*)env->GetIntField(obj, gResourceLoader.mObject)) -#define SET_NATIVE_HANDLE(env, obj, handle) (env->SetIntField(obj, gResourceLoader.mObject, handle)) - -//----------------------------------------------------------------------------- -// ResourceLoadHandler - -WebCoreResourceLoader::WebCoreResourceLoader(JNIEnv *env, jobject jLoadListener) -{ - mJvm = jnienv_to_javavm(env); - mJLoader = env->NewGlobalRef(jLoadListener); -} - -WebCoreResourceLoader::~WebCoreResourceLoader() -{ - JNIEnv* env = javavm_to_jnienv(mJvm); - SET_NATIVE_HANDLE(env, mJLoader, 0); - env->DeleteGlobalRef(mJLoader); - mJLoader = 0; -} - -void WebCoreResourceLoader::cancel() -{ - JNIEnv* env = javavm_to_jnienv(mJvm); - env->CallVoidMethod(mJLoader, gResourceLoader.mCancelMethodID); - SET_NATIVE_HANDLE(env, mJLoader, 0); - checkException(env); -} - -void WebCoreResourceLoader::downloadFile() -{ - JNIEnv* env = javavm_to_jnienv(mJvm); - env->CallVoidMethod(mJLoader, gResourceLoader.mDownloadFileMethodID); - checkException(env); -} - -/* -* This static method is called to check to see if a POST response is in -* the cache. This may be slow, but is only used during a navigation to -* a POST response. -*/ -bool WebCoreResourceLoader::willLoadFromCache(const WebCore::KURL& url) -{ - JNIEnv* env = javavm_to_jnienv(android::WebCoreJni::getJavaVM()); - WebCore::DeprecatedString urlStr = url.deprecatedString(); - jstring jUrlStr = env->NewString((unsigned short *)urlStr.unicode(), urlStr.length()); - jclass resourceLoader = env->FindClass("android/webkit/LoadListener"); - bool val = env->CallStaticBooleanMethod(resourceLoader, - gResourceLoader.mWillLoadFromCacheMethodID, jUrlStr); - checkException(env); - env->DeleteLocalRef(jUrlStr); - - return val; -} - -// ---------------------------------------------------------------------------- -void WebCoreResourceLoader::SetResponseHeader(JNIEnv* env, jobject obj, jint nativeResponse, jstring key, jstring val) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterRC counter; -#endif - - WebCore::ResourceResponse* response = (WebCore::ResourceResponse*)nativeResponse; - LOG_ASSERT(response, "nativeSetResponseHeader must take a valid response pointer!"); - - LOG_ASSERT(key, "How did a null value become a key?"); - if (val) { - const char* keyStr = env->GetStringUTFChars(key, NULL); - const char* valStr = env->GetStringUTFChars(val, NULL); - if (valStr) - response->setHTTPHeaderField(keyStr, valStr); - - env->ReleaseStringUTFChars(key, keyStr); - env->ReleaseStringUTFChars(val, valStr); - } -} - -jint WebCoreResourceLoader::CreateResponse(JNIEnv* env, jobject obj, jstring url, jint statusCode, - jstring statusText, jstring mimeType, jlong expectedLength, - jstring encoding, jlong expireTime) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterRC counter; -#endif - LOG_ASSERT(url, "Must have a url in the response!"); - const char* urlStr = env->GetStringUTFChars(url, NULL); - const char* encodingStr = NULL; - const char* mimeTypeStr = NULL; - if (mimeType) { - mimeTypeStr = env->GetStringUTFChars(mimeType, NULL); - LOGV("Response setMIMEType: %s", mimeTypeStr); - } - if (encoding) { - encodingStr = env->GetStringUTFChars(encoding, NULL); - LOGV("Response setTextEncodingName: %s", encodingStr); - } - WebCore::ResourceResponse* response = new WebCore::ResourceResponse(WebCore::KURL(urlStr), - mimeTypeStr, (long long)expectedLength, encodingStr, WebCore::String()); - response->setHTTPStatusCode(statusCode); - if (statusText) { - const char* statusStr = env->GetStringUTFChars(statusText, NULL); - response->setHTTPStatusText(statusStr); - LOGV("Response setStatusText: %s", statusStr); - env->ReleaseStringUTFChars(statusText, statusStr); - } - // FIXME: This assumes that time_t is a long and that long is the same size as int. - if ((unsigned long)expireTime > INT_MAX) - expireTime = INT_MAX; - response->setExpirationDate((time_t)expireTime); - if (encoding) - env->ReleaseStringUTFChars(encoding, encodingStr); - if (mimeType) - env->ReleaseStringUTFChars(mimeType, mimeTypeStr); - env->ReleaseStringUTFChars(url, urlStr); - return (int)response; -} - -void WebCoreResourceLoader::ReceivedResponse(JNIEnv* env, jobject obj, jint nativeResponse) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterRC counter; -#endif - WebCore::ResourceHandle* handle = GET_NATIVE_HANDLE(env, obj); - LOG_ASSERT(handle, "nativeReceivedResponse must take a valid handle!"); - // ResourceLoader::didFail() can set handle to be NULL, we need to check - if (!handle) - return; - - WebCore::ResourceResponse* response = (WebCore::ResourceResponse*)nativeResponse; - LOG_ASSERT(response, "nativeReceivedResponse must take a valid resource pointer!"); - handle->client()->didReceiveResponse(handle, *response); - // As the client makes a copy of the response, delete it here. - delete response; -} - -void WebCoreResourceLoader::AddData(JNIEnv* env, jobject obj, jbyteArray dataArray, jint length) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterRC counter; -#endif - LOGV("webcore_resourceloader data(%d)", length); - - WebCore::ResourceHandle* handle = GET_NATIVE_HANDLE(env, obj); - LOG_ASSERT(handle, "nativeAddData must take a valid handle!"); - // ResourceLoader::didFail() can set handle to be NULL, we need to check - if (!handle) - return; - - SkAutoMemoryUsageProbe mup("android_webcore_resourceloader_nativeAddData"); - - bool result = false; - jbyte * data = env->GetByteArrayElements(dataArray, NULL); - - LOG_ASSERT(handle->client(), "Why do we not have a client?"); - handle->client()->didReceiveData(handle, (const char *)data, length, length); - env->ReleaseByteArrayElements(dataArray, data, JNI_ABORT); -} - -void WebCoreResourceLoader::Finished(JNIEnv* env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterRC counter; -#endif - LOGV("webcore_resourceloader finished"); - WebCore::ResourceHandle* handle = GET_NATIVE_HANDLE(env, obj); - LOG_ASSERT(handle, "nativeFinished must take a valid handle!"); - // ResourceLoader::didFail() can set handle to be NULL, we need to check - if (!handle) - return; - - LOG_ASSERT(handle->client(), "Why do we not have a client?"); - handle->client()->didFinishLoading(handle); -} - -jstring WebCoreResourceLoader::RedirectedToUrl(JNIEnv* env, jobject obj, - jstring baseUrl, jstring redirectTo, jint nativeResponse) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterRC counter; -#endif - LOGV("webcore_resourceloader redirectedToUrl"); - WebCore::ResourceHandle* handle = GET_NATIVE_HANDLE(env, obj); - LOG_ASSERT(handle, "nativeRedirectedToUrl must take a valid handle!"); - // ResourceLoader::didFail() can set handle to be NULL, we need to check - if (!handle) - return NULL; - - const char* baseStr = env->GetStringUTFChars(baseUrl, NULL); - const char* redirectStr = env->GetStringUTFChars(redirectTo, NULL); - LOG_ASSERT(handle->client(), "Why do we not have a client?"); - WebCore::ResourceRequest r = handle->request(); - WebCore::KURL url(baseStr, redirectStr); - r.setURL(url); - if (r.httpMethod() == "POST") - r.setHTTPMethod("GET"); - env->ReleaseStringUTFChars(baseUrl, baseStr); - env->ReleaseStringUTFChars(redirectTo, redirectStr); - WebCore::ResourceResponse* response = (WebCore::ResourceResponse*)nativeResponse; - // If the url fails to resolve the relative path, return null. - if (url.protocol().isEmpty()) { - delete response; - return NULL; - } - handle->client()->willSendRequest(handle, r, *response); - delete response; - WebCore::String s = url.string(); - return env->NewString((unsigned short*)s.characters(), s.length()); -} - -void WebCoreResourceLoader::Error(JNIEnv* env, jobject obj, jint id, jstring description, - jstring failingUrl) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterRC counter; -#endif - LOGV("webcore_resourceloader error"); - WebCore::ResourceHandle* handle = GET_NATIVE_HANDLE(env, obj); - LOG_ASSERT(handle, "nativeError must take a valid handle!"); - // ResourceLoader::didFail() can set handle to be NULL, we need to check - if (!handle) - return; - - const char* descStr = env->GetStringUTFChars(description, NULL); - const char* failUrl = env->GetStringUTFChars(failingUrl, NULL); - handle->client()->didFail(handle, WebCore::ResourceError("", id, - WebCore::String(failUrl), WebCore::String(descStr))); - env->ReleaseStringUTFChars(failingUrl, failUrl); - env->ReleaseStringUTFChars(description, descStr); -} - -// ---------------------------------------------------------------------------- - -/* - * JNI registration. - */ -static JNINativeMethod gResourceloaderMethods[] = { - /* name, signature, funcPtr */ - { "nativeSetResponseHeader", "(ILjava/lang/String;Ljava/lang/String;)V", - (void*) WebCoreResourceLoader::SetResponseHeader }, - { "nativeCreateResponse", "(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;JLjava/lang/String;J)I", - (void*) WebCoreResourceLoader::CreateResponse }, - { "nativeReceivedResponse", "(I)V", - (void*) WebCoreResourceLoader::ReceivedResponse }, - { "nativeAddData", "([BI)V", - (void*) WebCoreResourceLoader::AddData }, - { "nativeFinished", "()V", - (void*) WebCoreResourceLoader::Finished }, - { "nativeRedirectedToUrl", "(Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/String;", - (void*) WebCoreResourceLoader::RedirectedToUrl }, - { "nativeError", "(ILjava/lang/String;Ljava/lang/String;)V", - (void*) WebCoreResourceLoader::Error } -}; - -int register_resource_loader(JNIEnv* env) -{ - jclass resourceLoader = env->FindClass("android/webkit/LoadListener"); - LOG_FATAL_IF(resourceLoader == NULL, - "Unable to find class android/webkit/LoadListener"); - - gResourceLoader.mObject = - env->GetFieldID(resourceLoader, "mNativeLoader", "I"); - LOG_FATAL_IF(gResourceLoader.mObject == NULL, - "Unable to find android/webkit/LoadListener.mNativeLoader"); - - gResourceLoader.mCancelMethodID = - env->GetMethodID(resourceLoader, "cancel", "()V"); - LOG_FATAL_IF(gResourceLoader.mCancelMethodID == NULL, - "Could not find method cancel on LoadListener"); - - gResourceLoader.mDownloadFileMethodID = - env->GetMethodID(resourceLoader, "downloadFile", "()V"); - LOG_FATAL_IF(gResourceLoader.mDownloadFileMethodID == NULL, - "Could not find method downloadFile on LoadListener"); - - gResourceLoader.mWillLoadFromCacheMethodID = - env->GetStaticMethodID(resourceLoader, "willLoadFromCache", "(Ljava/lang/String;)Z"); - LOG_FATAL_IF(gResourceLoader.mWillLoadFromCacheMethodID == NULL, - "Could not find static method willLoadFromCache on LoadListener"); - - return jniRegisterNativeMethods(env, "android/webkit/LoadListener", - gResourceloaderMethods, NELEM(gResourceloaderMethods)); -} - -} /* namespace android */ - diff --git a/WebCore/platform/android/jni/WebCoreResourceLoader.h b/WebCore/platform/android/jni/WebCoreResourceLoader.h deleted file mode 100644 index e3b3cc7..0000000 --- a/WebCore/platform/android/jni/WebCoreResourceLoader.h +++ /dev/null @@ -1,67 +0,0 @@ -/* //device/libs/android_runtime/android_webcore_resource_loader.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef ANDROID_WEBKIT_RESOURCELOADLISTENER_H -#define ANDROID_WEBKIT_RESOURCELOADLISTENER_H - -#include "KURL.h" - -#include "WebCoreRefObject.h" -#include <jni.h> - -namespace android { - -class WebCoreResourceLoader : public WebCoreRefObject -{ -public: - WebCoreResourceLoader(JNIEnv *env, jobject jLoadListener); - virtual ~WebCoreResourceLoader(); - - /** - * Call to java to cancel the current load. - */ - void cancel(); - - /** - * Call to java to download the current load rather than feed it - * back to WebCore - */ - void downloadFile(); - - /** - * Call to java to find out if this URL is in the cache - */ - static bool willLoadFromCache(const WebCore::KURL& url); - - // Native jni functions - static void SetResponseHeader(JNIEnv*, jobject, jint, jstring, jstring); - static jint CreateResponse(JNIEnv*, jobject, jstring, jint, jstring, - jstring, jlong, jstring, jlong); - static void ReceivedResponse(JNIEnv*, jobject, jint); - static void AddData(JNIEnv*, jobject, jbyteArray, jint); - static void Finished(JNIEnv*, jobject); - static jstring RedirectedToUrl(JNIEnv*, jobject, jstring, jstring, jint); - static void Error(JNIEnv*, jobject, jint, jstring, jstring); - -private: - JavaVM* mJvm; - jobject mJLoader; -}; - -} // end namespace android - -#endif diff --git a/WebCore/platform/android/jni/WebCoreViewBridge.h b/WebCore/platform/android/jni/WebCoreViewBridge.h deleted file mode 100644 index 58aa953..0000000 --- a/WebCore/platform/android/jni/WebCoreViewBridge.h +++ /dev/null @@ -1,191 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef WEBCORE_VIEW_BRIDGE_H -#define WEBCORE_VIEW_BRIDGE_H - -#include "IntRect.h" -#include "SkTDArray.h" -#include "WebCoreRefObject.h" -#include "Widget.h" -#include <ui/KeycodeLabels.h> -#include <stdlib.h> -namespace WebCore -{ - class GraphicsContext; - class Node; - class StringImpl; - class String; - class RenderText; - class Frame; - class FrameView; -} - -class WebCoreReply : public WebCoreRefObject { -public: - virtual ~WebCoreReply() {} - - virtual void replyInt(int value) { - SkDEBUGF(("WebCoreReply::replyInt(%d) not handled\n", value)); - } - - virtual void replyIntArray(SkTDArray<int> array) { - SkDEBUGF(("WebCoreReply::replyIntArray() not handled\n")); - } - // add more replyFoo signatures as needed -}; - -class WebCoreViewBridge : public WebCoreRefObject { -public: - WebCoreViewBridge(): mBounds(0,0,0,0), mScreenWidth(0), mScale(100), - mWidget(NULL), mParent(NULL) {} - virtual ~WebCoreViewBridge() { Release(mParent); } - - virtual void setParent(WebCoreViewBridge* parent) {Release(mParent); mParent = parent; Retain(mParent); } - virtual WebCoreViewBridge* getParent() { return mParent; } - - // these are needed for WidgetAndroid.cpp - virtual void draw(WebCore::GraphicsContext* ctx, - const WebCore::IntRect& rect, bool invalCache) = 0; - virtual void layout() {} - virtual bool isEnabled() const { return true; } - virtual void setEnabled(bool) {} - virtual bool hasFocus() const { return true; } - virtual void setFocus(bool) {} - virtual void didFirstLayout() {} - virtual void restoreScale(int) {} - - // Used by the page cache - virtual void setView(WebCore::FrameView* view) {} - - const WebCore::IntRect& getBounds() const - { - return mBounds; - } - virtual void setBounds(int left, int top, int right, int bottom) - { - this->setLocation(left, top); - this->setSize(right - left, bottom - top); - } - virtual int getMaxXScroll() const { return width() >> 2; } - virtual int getMaxYScroll() const { return height() >> 2; } - virtual void notifyFocusSet() {} - virtual void notifyProgressFinished() {} - // Subclasses should implement this if they want to do something after being resized - virtual void onResize() {} - - // These are referenced by Scrollview (and others) - virtual bool scrollIntoView(WebCore::IntRect rect, bool force) { return false; } - virtual void scrollTo(int x, int y, bool animate=false) {} - virtual void scrollBy(int x, int y) {} - virtual void contentInvalidate(const WebCore::IntRect &rect) - { - if (mParent) - mParent->contentInvalidate(rect); - } - virtual void contentInvalidate() - { - if (mParent) - mParent->contentInvalidate(); - } - // invalidate the view/display, NOT the content/DOM - virtual void viewInvalidate() - { - if (mParent) - mParent->viewInvalidate(); - } - - // these need not be virtual - // - void setSize(int w, int h) - { - int ow = width(); - int oh = height(); - mBounds.setWidth(w); - mBounds.setHeight(h); - // Only call onResize if the new size is different. - if (w != ow || h != oh) - onResize(); - } - - // used by layout when it needs to wrap content column around screen - void setSizeScreenWidthAndScale(int w, int h, int screenWidth, int scale) - { - int ow = width(); - int oh = height(); - int osw = mScreenWidth; - mBounds.setWidth(w); - mBounds.setHeight(h); - mScreenWidth = screenWidth; - mScale = scale; - // Only call onResize if the new size is different. - if (w != ow || h != oh || screenWidth != osw) - onResize(); - } - - void setLocation(int x, int y) - { - mBounds.setX(x); - mBounds.setY(y); - } - - int width() const { return mBounds.width(); } - int height() const { return mBounds.height(); } - int locX() const { return mBounds.x(); } - int locY() const { return mBounds.y(); } - int screenWidth() const { return mParent ? mParent->screenWidth() : mScreenWidth; } - int scale() const { return mParent ? mParent->scale() : mScale; } - - // called by RenderPopupMenuAndroid - virtual void popupRequest(WebCoreReply* reply, - int currIndex, - const uint16_t** labels, // the first short is the length (number of following shorts) - size_t labelCount, // the number of label strings - const int enabled[], // bools telling which corresponding labels are selectable - size_t enabledCount) // length of the enabled array, which should equal labelCount - { - if (mParent) - mParent->popupRequest(reply, currIndex, labels, labelCount, enabled, enabledCount); - } - - //implemented in android_widget_htmlwidget - virtual void removeFrameGeneration(WebCore::Frame* ) {} - virtual void updateFrameGeneration(WebCore::Frame* ) {} - virtual void jsAlert(const WebCore::String& url, const WebCore::String& text) { } - virtual bool jsConfirm(const WebCore::String& url, const WebCore::String& text) { return false; } - virtual bool jsPrompt(const WebCore::String& url, const WebCore::String& message, const WebCore::String& defaultValue, WebCore::String& result) { return false;} - virtual bool jsUnload(const WebCore::String& url, const WebCore::String& message) { return false; } - - virtual void updateTextfield(WebCore::Node* pointer, bool changeToPassword, const WebCore::String& text) - { - if (mParent) - mParent->updateTextfield(pointer, changeToPassword, text); - } - - void setWidget(WebCore::Widget* w) { mWidget = w; } - WebCore::Widget* widget() { return mWidget; } - -private: - WebCore::IntRect mBounds; - int mScreenWidth; - int mScale; - WebCore::Widget* mWidget; -protected: - WebCoreViewBridge* mParent; -}; - -#endif // WEBCORE_VIEW_BRIDGE_H diff --git a/WebCore/platform/android/jni/WebHistory.cpp b/WebCore/platform/android/jni/WebHistory.cpp deleted file mode 100644 index 4248c68..0000000 --- a/WebCore/platform/android/jni/WebHistory.cpp +++ /dev/null @@ -1,969 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#define LOG_TAG "webhistory" - -#include <config.h> -#include <wtf/OwnPtr.h> -#include <wtf/Platform.h> - -#include "WebHistory.h" - -#include "BackForwardList.h" -#include "CString.h" -#include "DocumentLoader.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "FrameLoaderClientAndroid.h" -#include "FrameTree.h" -#include "HistoryItem.h" -#include "Page.h" -#include "TextEncoding.h" -#include "WebCoreFrameBridge.h" - -#undef LOG -#include <JNIHelp.h> -#include <SkUtils.h> -#include <utils/Log.h> -#include <utils/misc.h> - -namespace android { - -// Forward declarations -static void write_item(WTF::Vector<char>& v, WebCore::HistoryItem* item); -static void write_children_recursive(WTF::Vector<char>& v, WebCore::HistoryItem* parent); -static bool read_item_recursive(WebCore::HistoryItem* child, const char** pData, int length); - -// Field ids for WebHistoryItems -struct WebHistoryItemFields { - jmethodID mInit; - jmethodID mUpdate; - jfieldID mTitle; - jfieldID mUrl; -} gWebHistoryItem; - -struct WebBackForwardListFields { - jmethodID mAddHistoryItem; - jmethodID mRemoveHistoryItem; - jfieldID mCurrentIndex; -} gWebBackForwardList; - -//-------------------------------------------------------------------------- -// WebBackForwardList native methods. -//-------------------------------------------------------------------------- - -static void WebHistoryClose(JNIEnv* env, jobject obj, jint frame) -{ - LOG_ASSERT(frame, "Close needs a valid Frame pointer!"); - WebCore::Frame* pFrame = (WebCore::Frame*)frame; - - WebCore::BackForwardList* list = pFrame->page()->backForwardList(); - RefPtr<WebCore::HistoryItem> current = list->currentItem(); - // Remove each item instead of using close(). close() is intended to be used - // right before the list is deleted. - WebCore::HistoryItemVector& entries = list->entries(); - int size = entries.size(); - for (int i = size - 1; i >= 0; --i) - list->removeItem(entries[i].get()); - // Add the current item back to the list. - if (current) { - current->setBridge(NULL); - // addItem will update the children to match the newly created bridge - list->addItem(current); - - /* - * The Grand Prix site uses anchor navigations to change the display. - * WebKit tries to be smart and not load child frames that have the - * same history urls during an anchor navigation. This means that the - * current history item stored in the child frame's loader does not - * match the item found in the history tree. If we remove all the - * entries in the back/foward list, we have to restore the entire tree - * or else a HistoryItem might have a deleted parent. - * - * In order to restore the history tree correctly, we have to look up - * all the frames first and then look up the history item. We do this - * because the history item in the tree may be null at this point. - * Unfortunately, a HistoryItem can only search its immediately - * children so we do a breadth-first rebuild of the tree. - */ - - // Keep a small list of child frames to traverse. - WTF::Vector<WebCore::Frame*> frameQueue; - // Fix the top-level item. - pFrame->loader()->setCurrentHistoryItem(current); - WebCore::Frame* child = pFrame->tree()->firstChild(); - // Remember the parent history item so we can search for a child item. - RefPtr<WebCore::HistoryItem> parent = current; - while (child) { - // Use the old history item since the current one may have a - // deleted parent. - WebCore::HistoryItem* item = parent->childItemWithName(child->tree()->name()); - child->loader()->setCurrentHistoryItem(item); - // Append the first child to the queue if it exists. - if (WebCore::Frame* f = child->tree()->firstChild()) - frameQueue.append(f); - child = child->tree()->nextSibling(); - // If we don't have a sibling for this frame and the queue isn't - // empty, use the next entry in the queue. - if (!child && !frameQueue.isEmpty()) { - child = frameQueue.at(0); - frameQueue.remove(0); - // Figure out the parent history item used when searching for - // the history item to use. - parent = child->tree()->parent()->loader()->currentHistoryItem(); - } - } - } -} - -static void WebHistoryRestoreIndex(JNIEnv* env, jobject obj, jint frame, jint index) -{ - LOG_ASSERT(frame, "RestoreState needs a valid Frame pointer!"); - WebCore::Frame* pFrame = (WebCore::Frame*)frame; - - // Set the current index in the list. - WebCore::BackForwardList* list = pFrame->page()->backForwardList(); - WebCore::HistoryItem* currentItem = list->entries()[index].get(); - list->goToItem(currentItem); - - // Update the current and previous history item. - WebCore::FrameLoader* loader = pFrame->loader(); - loader->setCurrentHistoryItem(currentItem); - loader->setPreviousHistoryItem(list->backItem()); - - // Update the request with the current item's info. - WebCore::ResourceRequest& request = loader->documentLoader()->request(); - request.setURL(currentItem->url()); - request.setMainDocumentURL(currentItem->url()); - if (currentItem->originalFormData()) { - request.setHTTPMethod("POST"); - request.setHTTPContentType(currentItem->formContentType()); - request.setHTTPReferrer(currentItem->formReferrer()); - request.setHTTPBody(currentItem->formData()); - } - - // Reload the current page - loader->reloadAllowingStaleData(loader->documentLoader()->overrideEncoding()); -} - -static void WebHistoryInflate(JNIEnv* env, jobject obj, jint frame, jbyteArray data) -{ - LOG_ASSERT(frame, "Inflate needs a valid frame pointer!"); - LOG_ASSERT(data, "Inflate needs a valid data pointer!"); - - // Get the actual bytes and the length from the java array. - jbyte* bytes = env->GetByteArrayElements(data, NULL); - jsize size = env->GetArrayLength(data); - - // Inflate the history tree into one HistoryItem or null if the inflation - // failed. - WebCore::HistoryItem* newItem = new WebCore::HistoryItem(); -#ifdef ANDROID_HISTORY_CLIENT - RefPtr<WebHistoryItem> bridge = new WebHistoryItem(env, obj, newItem); - newItem->setBridge(bridge.get()); -#endif - // Inflate the item recursively. If it fails, that is ok. We'll have an - // incomplete HistoryItem but that is better than crashing due to a null - // item. - read_item_recursive(newItem, (const char**)&bytes, (int)size); -#ifdef ANDROID_HISTORY_CLIENT - bridge->setActive(); -#endif - - // Add the new item to the back/forward list. - WebCore::Frame* pFrame = (WebCore::Frame*)frame; - pFrame->page()->backForwardList()->addItem(newItem); - -#ifdef ANDROID_HISTORY_CLIENT - // Update the item. - bridge->updateHistoryItem(newItem); -#endif -} - -// 7 empty strings + no document state + children count = 9 unsigned values -// 1 char for isTargetItem -// ANDROID_HISTORY_CLIENT adds 2 ints for scale and traversals. -#ifdef ANDROID_HISTORY_CLIENT -#ifdef ANDROID_FIX -#define HISTORY_MIN_SIZE ((int)(sizeof(unsigned) * 14 + sizeof(char))) -#else -#define HISTORY_MIN_SIZE ((int)(sizeof(unsigned) * 11 + sizeof(char))) -#endif -#else -#ifdef ANDROID_FIX -#define HISTORY_MIN_SIZE ((int)(sizeof(unsigned) * 12 + sizeof(char))) -#else -#define HISTORY_MIN_SIZE ((int)(sizeof(unsigned) * 9 + sizeof(char))) -#endif -#endif - -jbyteArray WebHistory::Flatten(JNIEnv* env, WTF::Vector<char>& v, WebCore::HistoryItem* item) -{ - if (!item) - return NULL; - - // Reserve a vector of chars with an initial size of HISTORY_MIN_SIZE. - v.reserveCapacity(HISTORY_MIN_SIZE); - - // Write the top-level history item and then write all the children - // recursively. -#ifdef ANDROID_HISTORY_CLIENT - LOG_ASSERT(item->bridge(), "Why don't we have a bridge object here?"); -#endif - write_item(v, item); - write_children_recursive(v, item); - - // Try to create a new java byte array. - jbyteArray b = env->NewByteArray(v.size()); - if (!b) - return NULL; - - // Write our flattened data to the java array. - jbyte* bytes = env->GetByteArrayElements(b, NULL); - memcpy(bytes, v.data(), v.size()); - env->ReleaseByteArrayElements(b, bytes, 0); - return b; -} - -WebHistoryItem::WebHistoryItem(JNIEnv* env, jobject obj, - WebCore::HistoryItem* item) { - JavaVM* vm; - mJVM = env->GetJavaVM(&vm) >= 0 ? vm : NULL; - mObject = env->NewGlobalRef(obj); - mScale = 100; - mTraversals = -1; - mActive = false; - mParent = NULL; - mHistoryItem = item; -} - -WebHistoryItem::~WebHistoryItem() { - if (mObject) { - JNIEnv* env; - env = mJVM->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL; - if (!env) - return; - env->DeleteGlobalRef(mObject); - } -} - -void WebHistoryItem::updateHistoryItem(WebCore::HistoryItem* item) { -#ifdef ANDROID_HISTORY_CLIENT - // Do not want to update during inflation. - if (!mActive) - return; - WebHistoryItem* webItem = this; - // Now we need to update the top-most WebHistoryItem based on the top-most - // HistoryItem. - if (mParent) { - webItem = mParent.get(); - if (webItem->hasOneRef()) { - // if the parent only has one ref, it is from this WebHistoryItem. - // This means that the matching WebCore::HistoryItem has been freed. - // This can happen during clear(). - LOGW("Can't updateHistoryItem as the top HistoryItem is gone"); - return; - } - while (webItem->parent()) - webItem = webItem->parent(); - item = webItem->historyItem(); - } - JNIEnv* env; - env = webItem->mJVM->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL; - if (!env) - return; - const WebCore::String& urlString = item->urlString(); - jstring urlStr = NULL; - if (!urlString.isNull()) - urlStr = env->NewString((unsigned short*)urlString.characters(), urlString.length()); - const WebCore::String& titleString = item->title(); - jstring titleStr = NULL; - if (!titleString.isNull()) - titleStr = env->NewString((unsigned short*)titleString.characters(), titleString.length()); - - // Try to get the favicon from the history item. For some pages like Grand - // Prix, there are history items with anchors. If the icon fails for the - // item, try to get the icon using the url without the ref. - jobject favicon = NULL; - WebCore::String url = item->urlString(); - if (item->url().hasRef()) { - int refIndex = url.reverseFind('#'); - url = url.substring(0, refIndex); - } - WebCore::Image* icon = WebCore::iconDatabase()->iconForPageURL(url, - WebCore::IntSize(16, 16)); - - if (icon) - favicon = webcoreImageToJavaBitmap(env, icon); - - WTF::Vector<char> data; - jbyteArray array = WebHistory::Flatten(env, data, item); - env->CallVoidMethod(webItem->mObject, gWebHistoryItem.mUpdate, urlStr, titleStr, favicon, array); - env->DeleteLocalRef(urlStr); - env->DeleteLocalRef(titleStr); - if (favicon) - env->DeleteLocalRef(favicon); - env->DeleteLocalRef(array); -#endif -} - -static void historyItemChanged(WebCore::HistoryItem* item) { -#ifdef ANDROID_HISTORY_CLIENT - LOG_ASSERT(item, - "historyItemChanged called with a null item"); - if (item->bridge()) - item->bridge()->updateHistoryItem(item); -#endif -} - -void WebHistory::AddItem(JNIEnv* env, jobject list, WebCore::HistoryItem* item) -{ -#ifdef ANDROID_HISTORY_CLIENT - LOG_ASSERT(item, "newItem must take a valid HistoryItem!"); - // Item already added. Should only happen when we are inflating the list. - if (item->bridge()) - return; - - // Allocate a blank WebHistoryItem - jclass clazz = env->FindClass("android/webkit/WebHistoryItem"); - jobject newItem = env->NewObject(clazz, gWebHistoryItem.mInit); - - // Create the bridge, make it active, and attach it to the item. - WebHistoryItem* bridge = new WebHistoryItem(env, newItem, item); - bridge->setActive(); - item->setBridge(bridge); - - // Update the history item which will flatten the data and call update on - // the java item. - bridge->updateHistoryItem(item); - - // Add it to the list. - env->CallVoidMethod(list, gWebBackForwardList.mAddHistoryItem, newItem); - - // Delete our local reference. - env->DeleteLocalRef(newItem); -#endif -} - -void WebHistory::RemoveItem(JNIEnv* env, jobject list, int index) -{ - env->CallVoidMethod(list, gWebBackForwardList.mRemoveHistoryItem, index); -} - -void WebHistory::UpdateHistoryIndex(JNIEnv* env, jobject list, int newIndex) -{ - env->SetIntField(list, gWebBackForwardList.mCurrentIndex, newIndex); -} - -static void write_string(WTF::Vector<char>& v, const WebCore::String& str) -{ - unsigned strLen = str.length(); - // Only do work if the string has data. - if (strLen) { - // Determine how much to grow the vector. Use the worst case for utf8 to - // avoid reading the string twice. Add sizeof(unsigned) to hold the - // string length in utf8. - unsigned vectorLen = v.size() + sizeof(unsigned); - unsigned length = (strLen << 2) + vectorLen; - // Grow the vector. This will change the value of v.size() but we - // remember the original size above. - v.grow(length); - // Grab the position to write to. - char* data = v.begin() + vectorLen; - // Write the actual string - int l = SkUTF16_ToUTF8(str.characters(), strLen, data); - LOGV("Writing string %d %.*s", l, l, data); - // Go back and write the utf8 length. Subtract sizeof(unsigned) from - // data to get the position to write the length. - memcpy(data - sizeof(unsigned), (char*)&l, sizeof(unsigned)); - // Shrink the internal state of the vector so we match what was - // actually written. - v.shrink(vectorLen + l); - } else - v.append((char*)&strLen, sizeof(unsigned)); -} - -static void write_item(WTF::Vector<char>& v, WebCore::HistoryItem* item) -{ - // Original url - write_string(v, item->originalURLString()); - - // Url - write_string(v, item->urlString()); - - // Title - write_string(v, item->title()); - - // Form content type - write_string(v, item->formContentType()); - - // Form referrer - write_string(v, item->formReferrer()); - - // Form data - const WebCore::FormData* formData = item->formData(); - if (formData) - write_string(v, formData->flattenToString()); - else - write_string(v, WebCore::String()); // Empty constructor does not allocate a buffer. - -#ifdef ANDROID_FIX - // original form content type - write_string(v, item->originalFormContentType()); - - // original form referrer - write_string(v, item->originalFormReferrer()); - - // original form data - const WebCore::FormData* origformData = item->originalFormData(); - if (origformData) - write_string(v, origformData->flattenToString()); - else - write_string(v, WebCore::String()); // Empty constructor does not allocate a buffer. -#endif - - // Target - write_string(v, item->target()); - -#ifdef ANDROID_HISTORY_CLIENT - WebHistoryItem* bridge = item->bridge(); - LOG_ASSERT(bridge, "We should have a bridge here!"); - // Screen scale - int scale = bridge->scale(); - LOGV("Writing scale %d", scale); - v.append((char*)&scale, sizeof(int)); - - // Focus position - int traversals = bridge->traversals(); - LOGV("Writing traversals %d", traversals); - v.append((char*)&traversals, sizeof(int)); -#endif - - // Document state - const WTF::Vector<WebCore::String>& docState = item->documentState(); - WTF::Vector<WebCore::String>::const_iterator end = docState.end(); - unsigned stateSize = docState.size(); - LOGV("Writing docState %d", stateSize); - v.append((char*)&stateSize, sizeof(unsigned)); - for (WTF::Vector<WebCore::String>::const_iterator i = docState.begin(); i != end; ++i) { - write_string(v, *i); - } - - // Is target item - LOGV("Writing isTargetItem %d", item->isTargetItem()); - v.append((char)item->isTargetItem()); - - // Children count - unsigned childCount = item->children().size(); - LOGV("Writing childCount %d", childCount); - v.append((char*)&childCount, sizeof(unsigned)); -} - -static void write_children_recursive(WTF::Vector<char>& v, WebCore::HistoryItem* parent) -{ - const WebCore::HistoryItemVector& children = parent->children(); - WebCore::HistoryItemVector::const_iterator end = children.end(); - for (WebCore::HistoryItemVector::const_iterator i = children.begin(); i != end; ++i) { - WebCore::HistoryItem* item = (*i).get(); -#ifdef ANDROID_HISTORY_CLIENT - LOG_ASSERT(parent->bridge(), - "The parent item should have a bridge object!"); - if (!item->bridge()) { - WebHistoryItem* bridge = new WebHistoryItem(parent->bridge()); - item->setBridge(bridge); - bridge->setActive(); - } else { - // The only time this item's parent may not be the same as the - // parent's bridge is during history close. In that case, the - // parent must not have a parent bridge. - LOG_ASSERT(parent->bridge()->parent() == NULL || - item->bridge()->parent() == parent->bridge(), - "Somehow this item has an incorrect parent"); - item->bridge()->setParent(parent->bridge()); - } -#endif - write_item(v, item); - write_children_recursive(v, item); - } -} - -static bool read_item_recursive(WebCore::HistoryItem* newItem, - const char** pData, int length) -{ - if (!pData || length < HISTORY_MIN_SIZE) - return false; - - const WebCore::TextEncoding& e = WebCore::UTF8Encoding(); - const char* data = *pData; - const char* end = data + length; - int sizeofUnsigned = (int)sizeof(unsigned); - - // Read the original url - // Read the expected length of the string. - int l; - memcpy(&l, data, sizeofUnsigned); - // Increment data pointer by the size of an unsigned int. - data += sizeofUnsigned; - if (l) { - LOGV("Original url %d %.*s", l, l, data); - // If we have a length, check if that length exceeds the data length - // and return null if there is not enough data. - if (data + l < end) - newItem->setOriginalURLString(e.decode(data, l)); - else - return false; - // Increment the data pointer by the length of the string. - data += l; - } - // Check if we have enough data left to continue. - if (end - data < sizeofUnsigned) - return false; - - // Read the url - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Url %d %.*s", l, l, data); - if (data + l < end) - newItem->setURLString(e.decode(data, l)); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - - // Read the title - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Title %d %.*s", l, l, data); - if (data + l < end) - newItem->setTitle(e.decode(data, l)); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - - // Generate a new ResourceRequest object for populating form information. - WebCore::String formContentType; - WebCore::String formReferrer; - WebCore::FormData* formData = NULL; - - // Read the form content type - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Content type %d %.*s", l, l, data); - if (data + l < end) - formContentType = e.decode(data, l); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - - // Read the form referrer - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Referrer %d %.*s", l, l, data); - if (data + l < end) - formReferrer = e.decode(data, l); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - - // Read the form data - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Form data %d %.*s", l, l, data); - if (data + l < end) - formData = new WebCore::FormData(data, l); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - - // Set up the form info - if (formData != NULL) { - WebCore::ResourceRequest r; - r.setHTTPMethod("POST"); - r.setHTTPContentType(formContentType); - r.setHTTPReferrer(formReferrer); - r.setHTTPBody(formData); - newItem->setFormInfoFromRequest(r); - } - -#ifdef ANDROID_FIX - WebCore::String origformContentType; - WebCore::String origformReferrer; - WebCore::FormData* origformData = NULL; - - // Read the original form content type - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Original content type %d %.*s", l, l, data); - if (data + l < end) - origformContentType = e.decode(data, l); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - - // Read the original form referrer - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Original referrer %d %.*s", l, l, data); - if (data + l < end) - origformReferrer = e.decode(data, l); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - - // Read the original form data - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Original form data %d %.*s", l, l, data); - if (data + l < end) - origformData = new WebCore::FormData(data, l); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - - if (origformData) - newItem->setOriginalFormInfo(origformData, origformContentType, origformReferrer); -#endif - - // Read the target - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Target %d %.*s", l, l, data); - if (data + l < end) - newItem->setTarget(e.decode(data, l)); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - -#ifdef ANDROID_HISTORY_CLIENT - WebHistoryItem* bridge = newItem->bridge(); - LOG_ASSERT(bridge, "There should be a bridge object during inflate"); - // Read the screen scale - memcpy(&l, data, sizeofUnsigned); - LOGV("Screen scale %d", l); - bridge->setScale(l); - data += sizeofUnsigned; - if (end - data < (int)sizeof(int)) - return false; - - // Read the focus index - memcpy(&l, data, sizeof(int)); - LOGV("Traversals %d", l); - bridge->setTraversals(l); - data += sizeof(int); - if (end - data < sizeofUnsigned) - return false; -#endif - - // Read the document state - memcpy(&l, data, sizeofUnsigned); - LOGV("Document state %d", l); - data += sizeofUnsigned; - if (l) { - // Check if we have enough data to at least parse the sizes of each - // document state string. - if (data + l * sizeofUnsigned >= end) - return false; - // Create a new vector and reserve enough space for the document state. - WTF::Vector<WebCore::String> docState; - docState.reserveCapacity(l); - while (l--) { - // Check each time if we have enough to parse the length of the next - // string. - if (end - data < sizeofUnsigned) - return false; - int strLen; - memcpy(&strLen, data, sizeofUnsigned); - data += sizeofUnsigned; - if (data + strLen < end) - docState.append(e.decode(data, strLen)); - else - return false; - LOGV("\t\t%d %.*s", strLen, strLen, data); - data += strLen; - } - newItem->setDocumentState(docState); - } - // Check if we have enough to read the next byte - if (data >= end) - return false; - - // Read is target item - // Cast the value to unsigned char in order to make a negative value larger - // than 1. A value that is not 0 or 1 is a failure. - unsigned char c = (unsigned char)data[0]; - if (c > 1) - return false; - LOGV("Target item %d", c); - newItem->setIsTargetItem((bool)c); - data++; - if (end - data < sizeofUnsigned) - return false; - - // Read the child count - memcpy(&l, data, sizeofUnsigned); - LOGV("Child count %d", l); - data += sizeofUnsigned; - *pData = data; - if (l) { - // Check if we have the minimum amount need to parse l children. - if (data + l * HISTORY_MIN_SIZE >= end) - return false; - while (l--) { - // No need to check the length each time because read_item_recursive - // will return null if there isn't enough data left to parse. - WebCore::HistoryItem* child = new WebCore::HistoryItem(); -#ifdef ANDROID_HISTORY_CLIENT - // Set a bridge that will not call into java. - child->setBridge(new WebHistoryItem(bridge)); -#endif - // Read the child item. - if (!read_item_recursive(child, pData, end - data)) { - delete child; - return false; - } -#ifdef ANDROID_HISTORY_CLIENT - child->bridge()->setActive(); -#endif - newItem->addChildItem(child); - } - } - return true; -} - -#ifndef NDEBUG -static void unit_test() -{ - LOGD("Entering history unit test!"); - const char* test1 = new char[0]; - WebCore::HistoryItem* testItem = new WebCore::HistoryItem(); -#ifdef ANDROID_HISTORY_CLIENT - testItem->setBridge(new WebHistoryItem(NULL)); -#endif - LOG_ASSERT(!read_item_recursive(testItem, &test1, 0), "0 length array should fail!"); - delete[] test1; - const char* test2 = new char[2]; - LOG_ASSERT(!read_item_recursive(testItem, &test2, 2), "Small array should fail!"); - delete[] test2; - LOG_ASSERT(!read_item_recursive(testItem, NULL, HISTORY_MIN_SIZE), "Null data should fail!"); - // Original Url - char* test3 = new char[HISTORY_MIN_SIZE]; - const char* ptr = (const char*)test3; - memset(test3, 0, HISTORY_MIN_SIZE); - *(int*)test3 = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length originalUrl should fail!"); - // Url - int offset = 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length url should fail!"); - // Title - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length title should fail!"); - // Form content type - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length contentType should fail!"); - // Form referrer - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length referrer should fail!"); - // Form data - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length form data should fail!"); -#ifdef ANDROID_FIX - // Original form content type - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length contentType should fail!"); - // Original form referrer - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length referrer should fail!"); - // Original form data - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length form data should fail!"); -#endif - // Target - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length target should fail!"); -#ifdef ANDROID_HISTORY_CLIENT - offset += 4; // Scale - offset += 4; // traversals -#endif - // Document state - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length document state should fail!"); - // Is target item - offset += 1; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(char*)(test3 + offset) = '!'; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "IsTargetItem should fail with ! as the value!"); - // Child count - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 kids should fail!"); - -#ifdef ANDROID_HISTORY_CLIENT - offset = 36; -#else - offset = 28; -#endif -#ifdef ANDROID_FIX - offset += 12; -#endif - // Test document state - delete[] test3; - test3 = new char[HISTORY_MIN_SIZE + sizeof(unsigned)]; - memset(test3, 0, HISTORY_MIN_SIZE + sizeof(unsigned)); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 1; - *(int*)(test3 + offset + 4) = 20; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE + sizeof(unsigned)), "1 20 length document state string should fail!"); - delete[] test3; - test3 = new char[HISTORY_MIN_SIZE + 2 * sizeof(unsigned)]; - memset(test3, 0, HISTORY_MIN_SIZE + 2 * sizeof(unsigned)); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 2; - *(int*)(test3 + offset + 4) = 0; - *(int*)(test3 + offset + 8) = 20; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE + 2 * sizeof(unsigned) ), "2 20 length document state string should fail!"); - delete[] test3; - delete testItem; -} -#endif - -//--------------------------------------------------------- -// JNI registration -//--------------------------------------------------------- -static JNINativeMethod gWebBackForwardListMethods[] = { - { "nativeClose", "(I)V", - (void*) WebHistoryClose }, - { "restoreIndex", "(II)V", - (void*) WebHistoryRestoreIndex } -}; - -static JNINativeMethod gWebHistoryItemMethods[] = { - { "inflate", "(I[B)V", - (void*) WebHistoryInflate } -}; - -int register_webhistory(JNIEnv* env) -{ -#ifdef ANDROID_HISTORY_CLIENT - // Get notified of all changes to history items. - WebCore::notifyHistoryItemChanged = historyItemChanged; -#endif -#ifndef NDEBUG - unit_test(); -#endif - // Find WebHistoryItem, its constructor, and the update method. - jclass clazz = env->FindClass("android/webkit/WebHistoryItem"); - LOG_ASSERT(clazz, "Unable to find class android/webkit/WebHistoryItem"); - gWebHistoryItem.mInit = env->GetMethodID(clazz, "<init>", "()V"); - LOG_ASSERT(gWebHistoryItem.mInit, "Could not find WebHistoryItem constructor"); - gWebHistoryItem.mUpdate = env->GetMethodID(clazz, "update", - "(Ljava/lang/String;Ljava/lang/String;Landroid/graphics/Bitmap;[B)V"); - LOG_ASSERT(gWebHistoryItem.mUpdate, "Could not find method update in WebHistoryItem"); - - // Find the field ids for mTitle and mUrl. - gWebHistoryItem.mTitle = env->GetFieldID(clazz, "mTitle", "Ljava/lang/String;"); - LOG_ASSERT(gWebHistoryItem.mTitle, "Could not find field mTitle in WebHistoryItem"); - gWebHistoryItem.mUrl = env->GetFieldID(clazz, "mUrl", "Ljava/lang/String;"); - LOG_ASSERT(gWebHistoryItem.mUrl, "Could not find field mUrl in WebHistoryItem"); - - // Find the WebBackForwardList object, the addHistoryItem and - // removeHistoryItem methods and the mCurrentIndex field. - clazz = env->FindClass("android/webkit/WebBackForwardList"); - LOG_ASSERT(clazz, "Unable to find class android/webkit/WebBackForwardList"); - gWebBackForwardList.mAddHistoryItem = env->GetMethodID(clazz, "addHistoryItem", - "(Landroid/webkit/WebHistoryItem;)V"); - LOG_ASSERT(gWebBackForwardList.mAddHistoryItem, "Could not find method addHistoryItem"); - gWebBackForwardList.mRemoveHistoryItem = env->GetMethodID(clazz, "removeHistoryItem", - "(I)V"); - LOG_ASSERT(gWebBackForwardList.mRemoveHistoryItem, "Could not find method removeHistoryItem"); - gWebBackForwardList.mCurrentIndex = env->GetFieldID(clazz, "mCurrentIndex", "I"); - LOG_ASSERT(gWebBackForwardList.mCurrentIndex, "Could not find field mCurrentIndex"); - - int result = jniRegisterNativeMethods(env, "android/webkit/WebBackForwardList", - gWebBackForwardListMethods, NELEM(gWebBackForwardListMethods)); - return (result < 0) ? result : jniRegisterNativeMethods(env, "android/webkit/WebHistoryItem", - gWebHistoryItemMethods, NELEM(gWebHistoryItemMethods)); -} - -} /* namespace android */ diff --git a/WebCore/platform/android/jni/WebHistory.h b/WebCore/platform/android/jni/WebHistory.h deleted file mode 100644 index 62db099..0000000 --- a/WebCore/platform/android/jni/WebHistory.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2006, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_WEBKIT_WEBHISTORY_H -#define ANDROID_WEBKIT_WEBHISTORY_H - -#include <jni.h> -#include <wtf/RefCounted.h> -#include <wtf/Vector.h> - -namespace WebCore { - class HistoryItem; -} - -namespace android { - -class WebHistory { -public: - static jbyteArray Flatten(JNIEnv*, WTF::Vector<char>&, WebCore::HistoryItem*); - static void AddItem(JNIEnv*, jobject, WebCore::HistoryItem*); - static void RemoveItem(JNIEnv*, jobject, int); - static void UpdateHistoryIndex(JNIEnv*, jobject, int); -}; - -class WebHistoryItem : public WTF::RefCounted<WebHistoryItem> { -public: - WebHistoryItem(WebHistoryItem* parent) - : mParent(parent) - , mObject(NULL) - , mJVM(NULL) - , mScale(100) - , mTraversals(-1) - , mActive(false) - , mHistoryItem(NULL) {} - WebHistoryItem(JNIEnv*, jobject, WebCore::HistoryItem*); - ~WebHistoryItem(); - void updateHistoryItem(WebCore::HistoryItem* item); - void setScale(int s) { mScale = s; } - void setTraversals(int t) { mTraversals = t; } - void setActive() { mActive = true; } - void setParent(WebHistoryItem* parent) { mParent = parent; } - WebHistoryItem* parent() { return mParent.get(); } - int scale() { return mScale; } - int traversals() { return mTraversals; } - jobject object() { return mObject; } - WebCore::HistoryItem* historyItem() { return mHistoryItem; } -private: - RefPtr<WebHistoryItem> mParent; - jobject mObject; - JavaVM* mJVM; - int mScale; - int mTraversals; - bool mActive; - WebCore::HistoryItem* mHistoryItem; -}; - -}; - -#endif diff --git a/WebCore/platform/android/jni/WebIconDatabase.cpp b/WebCore/platform/android/jni/WebIconDatabase.cpp deleted file mode 100644 index 2d5c39c..0000000 --- a/WebCore/platform/android/jni/WebIconDatabase.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/* -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#define LOG_TAG "favicons" - -#include <config.h> -#include <wtf/Platform.h> - -#include "WebCoreJni.h" -#include "WebIconDatabase.h" - -#include "IconDatabase.h" -#include "Image.h" -#include "IntRect.h" -#include "JavaSharedClient.h" -#include "KURL.h" - -#include <pthread.h> -#include "GraphicsJNI.h" -#include <SkBitmap.h> -#include <SkImageDecoder.h> -#include <SkTemplates.h> -#undef LOG -#include <utils/Log.h> -#include <utils/misc.h> -#include <JNIHelp.h> - -namespace android { - -jobject webcoreImageToJavaBitmap(JNIEnv* env, WebCore::Image* icon) -{ - if (!icon) - return NULL; - SkBitmap bm; - WebCore::SharedBuffer* buffer = icon->data(); - if (!buffer || !SkImageDecoder::DecodeMemory(buffer->data(), buffer->size(), - &bm, SkBitmap::kNo_Config, - SkImageDecoder::kDecodePixels_Mode)) - return NULL; - - return GraphicsJNI::createBitmap(env, new SkBitmap(bm), false, NULL); -} - -static WebIconDatabase* gIconDatabaseClient = new WebIconDatabase(); - -// XXX: Called by the IconDatabase thread -void WebIconDatabase::dispatchDidAddIconForPageURL(const WebCore::String& pageURL) -{ - // Attempt to attach to the current vm. - JavaVM* vm = WebCoreJni::getJavaVM(); - JavaVMAttachArgs args; - - args.version = JNI_VERSION_1_4; - args.name = "IconDatabase"; - args.group = NULL; - - JNIEnv* env; - bool threadIsAttached = true; - if (vm->AttachCurrentThread(&env, (void*) &args) != JNI_OK) { - LOGE("Could not attach IconDatabase thread to the VM"); - threadIsAttached = false; - } - - mNotificationsMutex.lock(); - mNotifications.append(pageURL); - if (!mDeliveryRequested) { - if (threadIsAttached) { - mDeliveryRequested = true; - WebCore::JavaSharedClient::EnqueueFunctionPtr(DeliverNotifications, this); - } - } - mNotificationsMutex.unlock(); -} - -// Called in the WebCore thread -void WebIconDatabase::RegisterForIconNotification(WebIconDatabaseClient* client) -{ - gIconDatabaseClient->mClientsMutex.lock(); - gIconDatabaseClient->mClients.append(client); - gIconDatabaseClient->mClientsMutex.unlock(); -} - -// Called in the WebCore thread -void WebIconDatabase::UnregisterForIconNotification(WebIconDatabaseClient* client) -{ - WebIconDatabase* db = gIconDatabaseClient; - db->mClientsMutex.lock(); - for (unsigned i = 0; i < db->mClients.size(); ++i) { - if (db->mClients[i] == client) { - db->mClients.remove(i); - break; - } - } - db->mClientsMutex.unlock(); -} - -// Called in the WebCore thread -void WebIconDatabase::DeliverNotifications(void* v) -{ - ASSERT(v); - ((WebIconDatabase*)v)->deliverNotifications(); -} - -// Called in the WebCore thread -void WebIconDatabase::deliverNotifications() -{ - ASSERT(mDeliveryRequested); - - // Swap the notifications queue - Vector<WebCore::String> queue; - mNotificationsMutex.lock(); - queue.swap(mNotifications); - mDeliveryRequested = false; - mNotificationsMutex.unlock(); - - // Swap the clients queue - Vector<WebIconDatabaseClient*> clients; - mClientsMutex.lock(); - clients.swap(mClients); - mClientsMutex.unlock(); - - for (unsigned i = 0; i < queue.size(); ++i) { - for (unsigned j = 0; j < clients.size(); ++j) { - clients[j]->didAddIconForPageUrl(queue[i]); - } - } -} - -static void Open(JNIEnv* env, jobject obj, jstring path) -{ - WebCore::IconDatabase* iconDb = WebCore::iconDatabase(); - if (iconDb->isOpen()) - return; - iconDb->setEnabled(true); - iconDb->setClient(gIconDatabaseClient); - LOG_ASSERT(path, "No path given to nativeOpen"); - const char* pathStr = env->GetStringUTFChars(path, NULL); - LOG_ASSERT(pathStr, "GetStringUTFChars failed for the path"); - LOGV("Opening WebIconDatabase file '%s'", pathStr); - bool res = iconDb->open(pathStr); - if (!res) - LOGE("Open failed!"); - env->ReleaseStringUTFChars(path, pathStr); -} - -static void Close(JNIEnv* env, jobject obj) -{ - WebCore::iconDatabase()->close(); -} - -static void RemoveAllIcons(JNIEnv* env, jobject obj) -{ - LOGV("Removing all icons"); - WebCore::iconDatabase()->removeAllIcons(); -} - -static jobject IconForPageUrl(JNIEnv* env, jobject obj, jstring url) -{ - LOG_ASSERT(url, "No url given to iconForPageUrl"); - const char* urlStr = env->GetStringUTFChars(url, NULL); - LOG_ASSERT(urlStr, "GetStringUTFChars failed for url"); - - WebCore::Image* icon = WebCore::iconDatabase()->iconForPageURL(urlStr, - WebCore::IntSize(16, 16)); - LOGV("Retrieving icon for '%s' %p", urlStr, icon); - env->ReleaseStringUTFChars(url, urlStr); - return webcoreImageToJavaBitmap(env, icon); -} - -static void RetainIconForPageUrl(JNIEnv* env, jobject obj, jstring url) -{ - LOG_ASSERT(url, "No url given to retainIconForPageUrl"); - const char* urlStr = env->GetStringUTFChars(url, NULL); - LOG_ASSERT(urlStr, "GetStringUTFChars failed for url"); - - LOGV("Retaining icon for '%s'", urlStr); - WebCore::iconDatabase()->retainIconForPageURL(urlStr); - env->ReleaseStringUTFChars(url, urlStr); -} - -static void ReleaseIconForPageUrl(JNIEnv* env, jobject obj, jstring url) -{ - LOG_ASSERT(url, "No url given to releaseIconForPageUrl"); - const char* urlStr = env->GetStringUTFChars(url, NULL); - LOG_ASSERT(urlStr, "GetStringUTFChars failed for url"); - - LOGV("Releasing icon for '%s'", urlStr); - WebCore::iconDatabase()->releaseIconForPageURL(urlStr); - env->ReleaseStringUTFChars(url, urlStr); -} - -/* - * JNI registration - */ -static JNINativeMethod gWebIconDatabaseMethods[] = { - { "nativeOpen", "(Ljava/lang/String;)V", - (void*) Open }, - { "nativeClose", "()V", - (void*) Close }, - { "nativeRemoveAllIcons", "()V", - (void*) RemoveAllIcons }, - { "nativeIconForPageUrl", "(Ljava/lang/String;)Landroid/graphics/Bitmap;", - (void*) IconForPageUrl }, - { "nativeRetainIconForPageUrl", "(Ljava/lang/String;)V", - (void*) RetainIconForPageUrl }, - { "nativeReleaseIconForPageUrl", "(Ljava/lang/String;)V", - (void*) ReleaseIconForPageUrl } -}; - -int register_webicondatabase(JNIEnv* env) -{ - jclass webIconDB = env->FindClass("android/webkit/WebIconDatabase"); - LOG_ASSERT(webIconDB, "Unable to find class android.webkit.WebIconDatabase"); - - return jniRegisterNativeMethods(env, "android/webkit/WebIconDatabase", - gWebIconDatabaseMethods, NELEM(gWebIconDatabaseMethods)); -} - -} diff --git a/WebCore/platform/android/jni/WebIconDatabase.h b/WebCore/platform/android/jni/WebIconDatabase.h deleted file mode 100644 index eefe1f6..0000000 --- a/WebCore/platform/android/jni/WebIconDatabase.h +++ /dev/null @@ -1,69 +0,0 @@ -/* //device/libs/WebKitLib/WebKit/WebCore/platform/android/jni/android_webkit_webicondatabase.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef ANDROID_WEBKIT_WEBICONDATABASE_H -#define ANDROID_WEBKIT_WEBICONDATABASE_H - -#include "IconDatabaseClient.h" -#include "utils/threads.h" -#include "wtf/Vector.h" - -#include <jni.h> - -namespace WebCore { - class Image; - class String; -} - -namespace android { - - class WebIconDatabaseClient { - public: - virtual ~WebIconDatabaseClient() {} - virtual void didAddIconForPageUrl(const WebCore::String& pageUrl) = 0; - }; - - class WebIconDatabase : public WebCore::IconDatabaseClient { - public: - WebIconDatabase() : mDeliveryRequested(false) {} - // IconDatabaseClient method - virtual void dispatchDidAddIconForPageURL(const WebCore::String& pageURL); - - static void RegisterForIconNotification(WebIconDatabaseClient* client); - static void UnregisterForIconNotification(WebIconDatabaseClient* client); - static void DeliverNotifications(void*); - - private: - // Deliver all the icon notifications - void deliverNotifications(); - - // List of clients and a mutex to protect it. - Vector<WebIconDatabaseClient*> mClients; - android::Mutex mClientsMutex; - - // Queue of page urls that have received an icon. - Vector<WebCore::String> mNotifications; - android::Mutex mNotificationsMutex; - // Flag to indicate that we have requested a delivery of notifications. - bool mDeliveryRequested; - }; - - jobject webcoreImageToJavaBitmap(JNIEnv* env, WebCore::Image* icon); - -}; - -#endif diff --git a/WebCore/platform/android/jni/WebSettings.cpp b/WebCore/platform/android/jni/WebSettings.cpp deleted file mode 100644 index 8d9efc0..0000000 --- a/WebCore/platform/android/jni/WebSettings.cpp +++ /dev/null @@ -1,309 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#define LOG_TAG "websettings" - -#include <config.h> -#include <wtf/Platform.h> - -#include "Document.h" -#include "Frame.h" -#include "FrameAndroid.h" -#include "FrameLoader.h" -#include "FrameView.h" -#include "DocLoader.h" -#include "Page.h" -#ifdef ANDROID_PLUGINS -#include "PluginDatabaseAndroid.h" -#endif -#include "Settings.h" -#include "WebCoreFrameBridge.h" - -#undef LOG -#include <JNIHelp.h> -#include <utils/Log.h> -#include <utils/misc.h> - -namespace android { - -struct FieldIds { - FieldIds(JNIEnv* env, jclass clazz) { - mLayoutAlgorithm = env->GetFieldID(clazz, "mLayoutAlgorithm", - "Landroid/webkit/WebSettings$LayoutAlgorithm;"); - mTextSize = env->GetFieldID(clazz, "mTextSize", - "Landroid/webkit/WebSettings$TextSize;"); - mStandardFontFamily = env->GetFieldID(clazz, "mStandardFontFamily", - "Ljava/lang/String;"); - mFixedFontFamily = env->GetFieldID(clazz, "mFixedFontFamily", - "Ljava/lang/String;"); - mSansSerifFontFamily = env->GetFieldID(clazz, "mSansSerifFontFamily", - "Ljava/lang/String;"); - mSerifFontFamily = env->GetFieldID(clazz, "mSerifFontFamily", - "Ljava/lang/String;"); - mCursiveFontFamily = env->GetFieldID(clazz, "mCursiveFontFamily", - "Ljava/lang/String;"); - mFantasyFontFamily = env->GetFieldID(clazz, "mFantasyFontFamily", - "Ljava/lang/String;"); - mDefaultTextEncoding = env->GetFieldID(clazz, "mDefaultTextEncoding", - "Ljava/lang/String;"); - mUserAgent = env->GetFieldID(clazz, "mUserAgent", - "Ljava/lang/String;"); - mMinimumFontSize = env->GetFieldID(clazz, "mMinimumFontSize", "I"); - mMinimumLogicalFontSize = env->GetFieldID(clazz, "mMinimumLogicalFontSize", "I"); - mDefaultFontSize = env->GetFieldID(clazz, "mDefaultFontSize", "I"); - mDefaultFixedFontSize = env->GetFieldID(clazz, "mDefaultFixedFontSize", "I"); - mLoadsImagesAutomatically = env->GetFieldID(clazz, "mLoadsImagesAutomatically", "Z"); -#ifdef ANDROID_BLOCK_NETWORK_IMAGE - mBlockNetworkImage = env->GetFieldID(clazz, "mBlockNetworkImage", "Z"); -#endif - mJavaScriptEnabled = env->GetFieldID(clazz, "mJavaScriptEnabled", "Z"); - mPluginsEnabled = env->GetFieldID(clazz, "mPluginsEnabled", "Z"); -#ifdef ANDROID_PLUGINS - mPluginsPath = env->GetFieldID(clazz, "mPluginsPath", "Ljava/lang/String;"); -#endif - mJavaScriptCanOpenWindowsAutomatically = env->GetFieldID(clazz, - "mJavaScriptCanOpenWindowsAutomatically", "Z"); - mUseWideViewport = env->GetFieldID(clazz, "mUseWideViewport", "Z"); - mSupportMultipleWindows = env->GetFieldID(clazz, "mSupportMultipleWindows", "Z"); - mUseDoubleTree = env->GetFieldID(clazz, "mUseDoubleTree", "Z"); - - LOG_ASSERT(mLayoutAlgorithm, "Could not find field mLayoutAlgorithm"); - LOG_ASSERT(mTextSize, "Could not find field mTextSize"); - LOG_ASSERT(mStandardFontFamily, "Could not find field mStandardFontFamily"); - LOG_ASSERT(mFixedFontFamily, "Could not find field mFixedFontFamily"); - LOG_ASSERT(mSansSerifFontFamily, "Could not find field mSansSerifFontFamily"); - LOG_ASSERT(mSerifFontFamily, "Could not find field mSerifFontFamily"); - LOG_ASSERT(mCursiveFontFamily, "Could not find field mCursiveFontFamily"); - LOG_ASSERT(mFantasyFontFamily, "Could not find field mFantasyFontFamily"); - LOG_ASSERT(mDefaultTextEncoding, "Could not find field mDefaultTextEncoding"); - LOG_ASSERT(mUserAgent, "Could not find field mUserAgent"); - LOG_ASSERT(mMinimumFontSize, "Could not find field mMinimumFontSize"); - LOG_ASSERT(mMinimumLogicalFontSize, "Could not find field mMinimumLogicalFontSize"); - LOG_ASSERT(mDefaultFontSize, "Could not find field mDefaultFontSize"); - LOG_ASSERT(mDefaultFixedFontSize, "Could not find field mDefaultFixedFontSize"); - LOG_ASSERT(mLoadsImagesAutomatically, "Could not find field mLoadsImagesAutomatically"); -#ifdef ANDROID_BLOCK_NETWORK_IMAGE - LOG_ASSERT(mBlockNetworkImage, "Could not find field mBlockNetworkImage"); -#endif - LOG_ASSERT(mJavaScriptEnabled, "Could not find field mJavaScriptEnabled"); - LOG_ASSERT(mPluginsEnabled, "Could not find field mPluginsEnabled"); -#ifdef ANDROID_PLUGINS - LOG_ASSERT(mPluginsPath, "Could not find field mPluginsPath"); -#endif - LOG_ASSERT(mJavaScriptCanOpenWindowsAutomatically, - "Could not find field mJavaScriptCanOpenWindowsAutomatically"); - LOG_ASSERT(mUseWideViewport, "Could not find field mUseWideViewport"); - LOG_ASSERT(mSupportMultipleWindows, "Could not find field mSupportMultipleWindows"); - LOG_ASSERT(mUseDoubleTree, "Could not find field mUseDoubleTree"); - - jclass c = env->FindClass("java/lang/Enum"); - LOG_ASSERT(c, "Could not find Enum class!"); - mOrdinal = env->GetMethodID(c, "ordinal", "()I"); - LOG_ASSERT(mOrdinal, "Could not find method ordinal"); - c = env->FindClass("android/webkit/WebSettings$TextSize"); - LOG_ASSERT(c, "Could not find TextSize enum"); - mTextSizeValue = env->GetFieldID(c, "value", "I"); - } - - // Field ids - jfieldID mLayoutAlgorithm; - jfieldID mTextSize; - jfieldID mStandardFontFamily; - jfieldID mFixedFontFamily; - jfieldID mSansSerifFontFamily; - jfieldID mSerifFontFamily; - jfieldID mCursiveFontFamily; - jfieldID mFantasyFontFamily; - jfieldID mDefaultTextEncoding; - jfieldID mUserAgent; - jfieldID mMinimumFontSize; - jfieldID mMinimumLogicalFontSize; - jfieldID mDefaultFontSize; - jfieldID mDefaultFixedFontSize; - jfieldID mLoadsImagesAutomatically; -#ifdef ANDROID_BLOCK_NETWORK_IMAGE - jfieldID mBlockNetworkImage; -#endif - jfieldID mJavaScriptEnabled; - jfieldID mPluginsEnabled; -#ifdef ANDROID_PLUGINS - jfieldID mPluginsPath; -#endif - jfieldID mJavaScriptCanOpenWindowsAutomatically; - jfieldID mUseWideViewport; - jfieldID mSupportMultipleWindows; - jfieldID mUseDoubleTree; - - // Ordinal() method and value field for enums - jmethodID mOrdinal; - jfieldID mTextSizeValue; -}; - -static struct FieldIds* gFieldIds; - -class WebSettings { -public: - static void Sync(JNIEnv* env, jobject obj, jint frame) - { - WebCore::FrameAndroid* pFrame = (WebCore::FrameAndroid*)frame; - LOG_ASSERT(pFrame, "%s must take a valid frame pointer!", __FUNCTION__); - WebCore::Settings* s = pFrame->page()->settings(); - WebCore::DocLoader* docLoader = pFrame->document()->docLoader(); - -#ifdef ANDROID_LAYOUT - jobject layout = env->GetObjectField(obj, gFieldIds->mLayoutAlgorithm); - WebCore::Settings::LayoutAlgorithm l = (WebCore::Settings::LayoutAlgorithm) - env->CallIntMethod(layout, gFieldIds->mOrdinal); - if (s->layoutAlgorithm() != l) { - s->setLayoutAlgorithm(l); - if (pFrame->document()) { - pFrame->document()->updateStyleSelector(); - if (pFrame->document()->renderer()) { - pFrame->cleanupForFullLayout(pFrame->document()->renderer()); - LOG_ASSERT(pFrame->view(), "No view for this frame when trying to relayout"); - pFrame->view()->layout(); - // FIXME: This call used to scroll the page to put the focus into view. - // It worked on the WebViewCore, but now scrolling is done outside of the - // WebViewCore, on the UI side, so there needs to be a new way to do this. - //pFrame->makeFocusVisible(); - } - } - } -#endif - jobject textSize = env->GetObjectField(obj, gFieldIds->mTextSize); - jint zoomFactor = env->GetIntField(textSize, gFieldIds->mTextSizeValue); - if (pFrame->zoomFactor() != zoomFactor) - pFrame->setZoomFactor(zoomFactor); - - jstring str = (jstring)env->GetObjectField(obj, gFieldIds->mStandardFontFamily); - const char* font = env->GetStringUTFChars(str, NULL); - s->setStandardFontFamily(font); - env->ReleaseStringUTFChars(str, font); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mFixedFontFamily); - font = env->GetStringUTFChars(str, NULL); - s->setFixedFontFamily(font); - env->ReleaseStringUTFChars(str, font); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mSansSerifFontFamily); - font = env->GetStringUTFChars(str, NULL); - s->setSansSerifFontFamily(font); - env->ReleaseStringUTFChars(str, font); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mSerifFontFamily); - font = env->GetStringUTFChars(str, NULL); - s->setSerifFontFamily(font); - env->ReleaseStringUTFChars(str, font); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mCursiveFontFamily); - font = env->GetStringUTFChars(str, NULL); - s->setCursiveFontFamily(font); - env->ReleaseStringUTFChars(str, font); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mFantasyFontFamily); - font = env->GetStringUTFChars(str, NULL); - s->setFantasyFontFamily(font); - env->ReleaseStringUTFChars(str, font); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mDefaultTextEncoding); - const char* encoding = env->GetStringUTFChars(str, NULL); - s->setDefaultTextEncodingName(encoding); - env->ReleaseStringUTFChars(str, encoding); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mUserAgent); - const char* userAgentStr = env->GetStringUTFChars(str, NULL); - pFrame->bridge()->setUserAgent(userAgentStr); - env->ReleaseStringUTFChars(str, userAgentStr); - - jint size = env->GetIntField(obj, gFieldIds->mMinimumFontSize); - s->setMinimumFontSize(size); - - size = env->GetIntField(obj, gFieldIds->mMinimumLogicalFontSize); - s->setMinimumLogicalFontSize(size); - - size = env->GetIntField(obj, gFieldIds->mDefaultFontSize); - s->setDefaultFontSize(size); - - size = env->GetIntField(obj, gFieldIds->mDefaultFixedFontSize); - s->setDefaultFixedFontSize(size); - - jboolean flag = env->GetBooleanField(obj, gFieldIds->mLoadsImagesAutomatically); - s->setLoadsImagesAutomatically(flag); - if (flag) - docLoader->setAutoLoadImages(true); - -#ifdef ANDROID_BLOCK_NETWORK_IMAGE - flag = env->GetBooleanField(obj, gFieldIds->mBlockNetworkImage); - s->setBlockNetworkImage(flag); - if(!flag) - docLoader->setBlockNetworkImage(false); -#endif - - flag = env->GetBooleanField(obj, gFieldIds->mJavaScriptEnabled); - s->setJavaScriptEnabled(flag); - - flag = env->GetBooleanField(obj, gFieldIds->mPluginsEnabled); - s->setPluginsEnabled(flag); - -#ifdef ANDROID_PLUGINS - str = (jstring)env->GetObjectField(obj, gFieldIds->mPluginsPath); - if (str) { - const char* pluginsPathStr = env->GetStringUTFChars(str, NULL); - s->setPluginsPath(pluginsPathStr); - // Also sync PluginDatabaseAndroid with the new default path. - ::WebCore::PluginDatabaseAndroid::setDefaultPluginsPath(pluginsPathStr); - env->ReleaseStringUTFChars(str, pluginsPathStr); - } -#endif - - flag = env->GetBooleanField(obj, gFieldIds->mJavaScriptCanOpenWindowsAutomatically); - s->setJavaScriptCanOpenWindowsAutomatically(flag); - - flag = env->GetBooleanField(obj, gFieldIds->mUseWideViewport); - s->setUseWideViewport(flag); - -#ifdef ANDROID_MULTIPLE_WINDOWS - flag = env->GetBooleanField(obj, gFieldIds->mSupportMultipleWindows); - s->setSupportMultipleWindows(flag); -#endif - -#if USE(LOW_BANDWIDTH_DISPLAY) - flag = env->GetBooleanField(obj, gFieldIds->mUseDoubleTree); - pFrame->loader()->setUseLowBandwidthDisplay(flag); -#endif - } -}; - -//------------------------------------------------------------- -// JNI registration -//------------------------------------------------------------- - -static JNINativeMethod gWebSettingsMethods[] = { - { "nativeSync", "(I)V", - (void*) WebSettings::Sync } -}; - -int register_websettings(JNIEnv* env) -{ - jclass clazz = env->FindClass("android/webkit/WebSettings"); - LOG_ASSERT(clazz, "Unable to find class WebSettings!"); - gFieldIds = new FieldIds(env, clazz); - return jniRegisterNativeMethods(env, "android/webkit/WebSettings", - gWebSettingsMethods, NELEM(gWebSettingsMethods)); -} - -} diff --git a/WebCore/platform/android/jni/WebViewCore.cpp b/WebCore/platform/android/jni/WebViewCore.cpp deleted file mode 100644 index dc2cd48..0000000 --- a/WebCore/platform/android/jni/WebViewCore.cpp +++ /dev/null @@ -1,2211 +0,0 @@ -/* - * Copyright 2006, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "webcoreglue" - -#include <config.h> -#include <wtf/Platform.h> - -#include "android_graphics.h" -#include "GraphicsJNI.h" -#include "SkPicture.h" - -#include "AtomicString.h" -#include "CacheBuilder.h" -#include "CachedNode.h" -#include "CachedRoot.h" -#include "Color.h" -#include "Document.h" -#include "Element.h" -#include "Editor.h" -#include "EditorClientAndroid.h" -#include "EventHandler.h" -#include "EventNames.h" -#include "Font.h" -#include "FrameAndroid.h" -#include "FrameLoader.h" -#include "FrameTree.h" -#include "FrameView.h" -#include "GraphicsContext.h" -#include "HitTestResult.h" -#include "HTMLAnchorElement.h" -#include "HTMLAreaElement.h" -#include "HTMLElement.h" -#include "HTMLImageElement.h" -#include "HTMLInputElement.h" -#include "HTMLMapElement.h" -#include "HTMLNames.h" -#include "HTMLOptGroupElement.h" -#include "HTMLOptionElement.h" -#include "HTMLSelectElement.h" -#include "HTMLTextAreaElement.h" -#include "HTMLTextFieldInnerElement.h" -#include "InlineTextBox.h" -#include "KeyboardCodes.h" -#include "Node.h" -#include "Page.h" -#include "PlatformGraphicsContext.h" -#include "PlatformKeyboardEvent.h" -#include "PlatformString.h" -#include "PluginInfoStore.h" -#include "Position.h" -#include "RenderLayer.h" -#include "RenderText.h" -#include "RenderTextControl.h" -#include "RenderThemeAndroid.h" -#include "RenderView.h" -#include "ResourceRequest.h" -#include "SelectionController.h" -#include "Settings.h" -#include "StringImpl.h" -#include "Text.h" -#include "TypingCommand.h" -#include "WebCoreFrameBridge.h" -#include "WebViewCore.h" -#include "HistoryItem.h" - -#ifdef LOG -#undef LOG -#endif - -#include <ui/KeycodeLabels.h> -#include <utils/Log.h> -#include "SkTDArray.h" -#include "SkTime.h" -#include <SkTypes.h> -#include <SkCanvas.h> -#include <SkUtils.h> -#include <JNIHelp.h> - -#include "SystemTime.h" - -#ifdef ANDROID_INSTRUMENT -static uint32_t sTotalTimeUsed = 0; -static uint32_t sTotalPaintTimeUsed = 0; -static uint32_t sCounter = 0; - -namespace WebCore { -void Frame::resetWebViewCoreTimeCounter() -{ - sTotalTimeUsed = 0; -} - -void Frame::reportWebViewCoreTimeCounter() -{ - LOG(LOG_DEBUG, "WebCore", "*-* Total native 4 (webview core) time: %d ms\n", - sTotalTimeUsed); -} -// This should be in Frame.cpp, but android LOG is conflict with webcore LOG -void Frame::resetPaintTimeCounter() -{ - sTotalPaintTimeUsed = 0; - sCounter = 0; -} - -void Frame::reportPaintTimeCounter() -{ - LOG(LOG_DEBUG, "WebCore", "*-* Total draw time: %d ms called %d times\n", - sTotalPaintTimeUsed, sCounter); -} -} -#endif - -//////////////////////////////////////////////////////////////////////////////////////////////// - -namespace android { - -#ifdef ANDROID_INSTRUMENT -class TimeCounterWV { -public: - TimeCounterWV() { - mStartTime = WebCore::get_thread_msec(); - } - - ~TimeCounterWV() { - sTotalTimeUsed += WebCore::get_thread_msec() - mStartTime; - } - -private: - uint32_t mStartTime; -}; -#endif - -// ---------------------------------------------------------------------------- - -#define GET_NATIVE_VIEW(env, obj) ((WebViewCore*)env->GetIntField(obj, gWebViewCoreFields.mNativeClass)) - -// Field ids for WebViewCore -struct WebViewCoreFields { - jfieldID mNativeClass; - jfieldID mViewportWidth; - jfieldID mViewportHeight; - jfieldID mViewportInitialScale; - jfieldID mViewportMinimumScale; - jfieldID mViewportMaximumScale; - jfieldID mViewportUserScalable; - jfieldID mWebView; -} gWebViewCoreFields; - -// ---------------------------------------------------------------------------- - -extern JavaVM* jnienv_to_javavm(JNIEnv* env); -extern JNIEnv* javavm_to_jnienv(JavaVM* vm); - -// ---------------------------------------------------------------------------- - -/** - * Helper method for checking java exceptions - * @return true if an exception occurred. - */ -static bool checkException(JNIEnv *env) -{ - if (env->ExceptionCheck() != 0) - { - LOGE("*** Uncaught exception returned from Java call!\n"); - env->ExceptionDescribe(); - return true; - } - return false; -} - -// ---------------------------------------------------------------------------- - -struct WebViewCore::JavaGlue -{ - JavaVM* mJVM; - jobject mObj; - jmethodID mSpawnScrollTo; - jmethodID mScrollTo; - jmethodID mScrollBy; - jmethodID mContentInvalidate; - jmethodID mRequestListBox; - jmethodID mRequestSingleListBox; - jmethodID mJsAlert; - jmethodID mJsConfirm; - jmethodID mJsPrompt; - jmethodID mJsUnload; - jmethodID mDidFirstLayout; - jmethodID mSendMarkNodeInvalid; - jmethodID mSendNotifyFocusSet; - jmethodID mSendNotifyProgressFinished; - jmethodID mSendRecomputeFocus; - jmethodID mSendViewInvalidate; - jmethodID mUpdateTextfield; - jmethodID mRestoreScale; -}; - -/* - * WebViewCore Implementation - */ - -static jmethodID GetJMethod(JNIEnv* env, jclass clazz, const char name[], const char signature[]) -{ - jmethodID m = env->GetMethodID(clazz, name, signature); - LOG_ASSERT(m, "Could not find method %s", name); - return m; -} - -Mutex WebViewCore::gFrameCacheMutex; -Mutex WebViewCore::gFrameGenerationMutex; -Mutex WebViewCore::gRecomputeFocusMutex; -Mutex WebViewCore::gButtonMutex; - -WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::FrameView* view) - : mView(view) -{ - mFrame = (WebCore::FrameAndroid*)mView->frame(); - // This will be derefed in WebCoreFrameBridge during destroy. - mView->ref(); - - mPopupReply = NULL; - mBuildGeneration = 0; - mMoveGeneration = 0; - mGeneration = 0; - mLastGeneration = 0; - mTouchGeneration = 0; - mBlockTextfieldUpdates = false; - // just initial values. These should be set by client - mMaxXScroll = 320/4; - mMaxYScroll = 240/4; - mButtons = NULL; - mTextGeneration = 0; - - LOG_ASSERT(mFrame, "Uh oh, somehow a frameview was made without an initial frame!"); - - jclass clazz = env->GetObjectClass(javaWebViewCore); - mJavaGlue = new JavaGlue; - mJavaGlue->mJVM = jnienv_to_javavm(env); - mJavaGlue->mObj = env->NewGlobalRef(javaWebViewCore); - mJavaGlue->mSpawnScrollTo = GetJMethod(env, clazz, "contentSpawnScrollTo", "(II)V"); - mJavaGlue->mScrollTo = GetJMethod(env, clazz, "contentScrollTo", "(II)V"); - mJavaGlue->mScrollBy = GetJMethod(env, clazz, "contentScrollBy", "(II)V"); - mJavaGlue->mContentInvalidate = GetJMethod(env, clazz, "contentInvalidate", "()V"); - mJavaGlue->mRequestListBox = GetJMethod(env, clazz, "requestListBox", "([Ljava/lang/String;[Z[I)V"); - mJavaGlue->mRequestSingleListBox = GetJMethod(env, clazz, "requestListBox", "([Ljava/lang/String;[ZI)V"); - mJavaGlue->mJsAlert = GetJMethod(env, clazz, "jsAlert", "(Ljava/lang/String;Ljava/lang/String;)V"); - mJavaGlue->mJsConfirm = GetJMethod(env, clazz, "jsConfirm", "(Ljava/lang/String;Ljava/lang/String;)Z"); - mJavaGlue->mJsPrompt = GetJMethod(env, clazz, "jsPrompt", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); - mJavaGlue->mJsUnload = GetJMethod(env, clazz, "jsUnload", "(Ljava/lang/String;Ljava/lang/String;)Z"); - mJavaGlue->mDidFirstLayout = GetJMethod(env, clazz, "didFirstLayout", "(Ljava/lang/String;)V"); - mJavaGlue->mSendMarkNodeInvalid = GetJMethod(env, clazz, "sendMarkNodeInvalid", "(I)V"); - mJavaGlue->mSendNotifyFocusSet = GetJMethod(env, clazz, "sendNotifyFocusSet", "()V"); - mJavaGlue->mSendNotifyProgressFinished = GetJMethod(env, clazz, "sendNotifyProgressFinished", "()V"); - mJavaGlue->mSendRecomputeFocus = GetJMethod(env, clazz, "sendRecomputeFocus", "()V"); - mJavaGlue->mSendViewInvalidate = GetJMethod(env, clazz, "sendViewInvalidate", "()V"); - mJavaGlue->mUpdateTextfield = GetJMethod(env, clazz, "updateTextfield", "(IZLjava/lang/String;I)V"); - mJavaGlue->mRestoreScale = GetJMethod(env, clazz, "restoreScale", "(I)V"); - - env->SetIntField(javaWebViewCore, gWebViewCoreFields.mNativeClass, (jint)this); - - mVisibleRect.setWidth(0); - mVisibleRect.setHeight(0); - - reset(true); -} - -WebViewCore::~WebViewCore() -{ - // Release the focused view - Release(mPopupReply); - - if (mJavaGlue->mObj) { - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->DeleteGlobalRef(mJavaGlue->mObj); - mJavaGlue->mObj = 0; - } - delete mJavaGlue; - delete mFrameCacheKit; - delete mNavPictureKit; - if (mButtons != NULL) { - mButtons->deleteAll(); - delete mButtons; - } -} - -void WebViewCore::reset(bool fromConstructor) -{ - if (fromConstructor) { - mFrameCacheKit = NULL; - mNavPictureKit = NULL; - } else { - gFrameCacheMutex.lock(); - delete mFrameCacheKit; - delete mNavPictureKit; - mFrameCacheKit = NULL; - mNavPictureKit = NULL; - gFrameCacheMutex.unlock(); - } - - mLastFocused = NULL; - mLastFocusedBounds = WebCore::IntRect(0,0,0,0); - mUpdatedFrameCache = true; - mFrameCacheOutOfDate = true; - mBlockFocusChange = false; - mSnapAnchorNode = NULL; - mUseReplay = false; -} - -void WebViewCore::draw(WebCore::GraphicsContext* ctx, - const WebCore::IntRect& r, bool invalCache) -{ - LOG_ASSERT(mFrame, "%s has no frame for this view!", __FUNCTION__); - LOG_ASSERT(mFrame == mView->frame(), "Our frames do not match!"); -#ifdef ANDROID_INSTRUMENT - uint32_t startTime = WebCore::get_thread_msec(); -#endif - if (NULL == mFrame->renderer()) { - // We only do this if there is nothing else to draw. - // If there is a renderer, it will fill the bg itself, so we don't want to - // double-draw (slow) - SkCanvas* canvas = ctx->platformContext()->mCanvas; - canvas->drawColor(SK_ColorWHITE); - } - else { - mFrame->paint(ctx, r); - } - if (invalCache) { - WebCore::CacheBuilder& builder = mFrame->getCacheBuilder(); - WebCore::Node* oldFocusNode = builder.currentFocus(); - mFrameCacheOutOfDate = true; - WebCore::IntRect oldBounds = oldFocusNode ? - oldFocusNode->getRect() : WebCore::IntRect(0,0,0,0); - DBG_NAV_LOGD_ONCE("mLastFocused=%p oldFocusNode=%p" - " mLastFocusedBounds={%d,%d,%d,%d} oldBounds={%d,%d,%d,%d}", - mLastFocused, oldFocusNode, - mLastFocusedBounds.x(), mLastFocusedBounds.y(), mLastFocusedBounds.width(), mLastFocusedBounds.height(), - oldBounds.x(), oldBounds.y(), oldBounds.width(), oldBounds.height()); - if (mLastFocused != oldFocusNode || mLastFocusedBounds != oldBounds) { - mLastFocused = oldFocusNode; - mLastFocusedBounds = oldBounds; - DBG_NAV_LOG("call updateFrameCache"); - updateFrameCache(); - } - } -#ifdef ANDROID_INSTRUMENT - sTotalPaintTimeUsed += WebCore::get_thread_msec() - startTime; - sCounter++; -#endif -} - -void WebViewCore::recordPicture(SkPicture* picture, bool invalCache) -{ - // if there is no document yet, just return - if (!mFrame->document()) - return; - - // Call layout to ensure that the contentWidth and contentHeight are correct - WebCore::ScrollView* view = mFrame->view(); - view->ignoreUpdateContents(true); - layout(); - view->ignoreUpdateContents(false); - -#if USE(DOUBLE_TREE) - // if haveStylesheetsLoaded() is false, render is not created, so don't call draw. - // It can happen when we switch from fast display mode, new style sheets are requested, - // if we call draw, we will have blank screen. - if (mFrame->document() && !mFrame->loader()->isComplete() && - !mFrame->document()->haveStylesheetsLoaded()) { - LOGV("skip %s", __FUNCTION__); - return; - } -#endif - - // draw into the picture's recording canvas - SkAutoPictureRecord arp(picture, contentWidth(), contentHeight()); - SkAutoMemoryUsageProbe mup(__FUNCTION__); - - WebCore::PlatformGraphicsContext pgc(arp.getRecordingCanvas()); - WebCore::GraphicsContext gc(&pgc); - WebCore::IntRect r = WebCore::IntRect(0, 0, INT_MAX, INT_MAX); - draw(&gc, r, invalCache); - - // If this was done for the Java Picture that is being displayed, grab the - // info for the buttons, so the UI thread can grab them and update them - // according to their state. - if (invalCache) { - gButtonMutex.lock(); - if (mButtons != NULL) { - mButtons->deleteAll(); - delete mButtons; - } - mButtons = pgc.getAndClearButtonInfo(); - gButtonMutex.unlock(); - } -} - -void WebViewCore::onResize() -{ - LOGV("view is resized, notifying the frame to relayout..."); - LOG_ASSERT(mFrame == mView->frame(), "Our frames do not match!"); - // r could be NULL because our frame has not processed any data. This happens - // when an HTMLWidget is first created, attached and sizeChanged is called. - WebCore::RenderObject *r = mFrame->renderer(); - if (r) { - r->setNeedsLayoutAndPrefWidthsRecalc(); - mFrame->forceLayout(true); - } -} - -WebCore::RenderLayer* WebViewCore::getRenderLayer() -{ - LOG_ASSERT(mView, "A view was not associated with this view bridge!"); - LOG_ASSERT(mFrame, "A frame was not associated with our frame view!"); - LOG_ASSERT(mFrame == mView->frame(), "Our frames do not match!"); - WebCore::Document* doc = mFrame->document(); - if (doc == NULL) - return NULL; - WebCore::RenderObject* renderer = doc->renderer(); - return renderer->enclosingLayer(); -} - -bool WebViewCore::pinXToDocument(int* xPtr) -{ - WebCore::RenderLayer* layer = getRenderLayer(); - if (layer == NULL) - return false; - int docWidth = layer->width(); - int x = *xPtr; - if (x < 0 || docWidth <= this->width()) - x = 0; - else if (x + this->width() > docWidth) - x = docWidth - this->width(); - *xPtr = x; - return true; -} - -bool WebViewCore::pinYToDocument(int* yPtr) -{ - WebCore::RenderLayer* layer = getRenderLayer(); - if (layer == NULL) - return false; - int docHeight = layer->height(); - int y = *yPtr; - if (y < 0 || docHeight <= this->height()) - y = 0; - else if (y + this->height() > docHeight) - y = docHeight - this->height(); - *yPtr = y; - return true; -} - -void WebViewCore::scrollTo(int x, int y, bool animate) -{ - LOG_ASSERT(mParent == NULL, "Why do we have a parent"); - LOG_ASSERT(mJavaGlue->mObj, "A Java widget was not associated with this view bridge!"); - -// LOGD("WebViewCore::scrollTo(%d %d)\n", x, y); - - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->CallVoidMethod(mJavaGlue->mObj, animate ? mJavaGlue->mSpawnScrollTo : mJavaGlue->mScrollTo, x, y); - checkException(env); -} - -void WebViewCore::sendMarkNodeInvalid(WebCore::Node* node) -{ - LOG_ASSERT(mJavaGlue->mObj, "A Java widget was not associated with this view bridge!"); - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mSendMarkNodeInvalid, (int) node); - checkException(env); -} - -void WebViewCore::sendNotifyFocusSet() -{ - LOG_ASSERT(mJavaGlue->mObj, "A Java widget was not associated with this view bridge!"); - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mSendNotifyFocusSet); - checkException(env); -} - -void WebViewCore::sendNotifyProgressFinished() -{ - LOG_ASSERT(mJavaGlue->mObj, "A Java widget was not associated with this view bridge!"); - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mSendNotifyProgressFinished); - checkException(env); -} - -void WebViewCore::sendRecomputeFocus() -{ - LOG_ASSERT(mJavaGlue->mObj, "A Java widget was not associated with this view bridge!"); - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mSendRecomputeFocus); - checkException(env); -} - -void WebViewCore::sendViewInvalidate() -{ - LOG_ASSERT(mJavaGlue->mObj, "A Java widget was not associated with this view bridge!"); - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mSendViewInvalidate); - checkException(env); -} - -void WebViewCore::scrollBy(int dx, int dy) -{ - LOG_ASSERT(mParent == NULL, "Why do we have a parent"); - if ((dx | dy) == 0) - return; - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mScrollBy, dx, dy); - checkException(env); -} - -void WebViewCore::contentInvalidate(const WebCore::IntRect &rect) -{ -// DBG_NAV_LOGD("rect={%d,%d,%d,%d}", rect.x(), rect.y(), rect.width(), rect.height()); - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mContentInvalidate); - checkException(env); -} - -void WebViewCore::contentInvalidate() -{ -// DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mContentInvalidate); - checkException(env); -} - -static int pin_pos(int x, int width, int targetWidth) -{ - if (x + width > targetWidth) - x = targetWidth - width; - if (x < 0) - x = 0; - return x; -} - -void WebViewCore::didFirstLayout() -{ - LOG_ASSERT(mParent == NULL, "Why do we have a parent"); - - DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); - LOG_ASSERT(mJavaGlue->mObj, "A Java widget was not associated with this view bridge!"); - - const WebCore::KURL& url = mFrame->loader()->url(); - if (url.isEmpty()) - return; - LOGV("::WebCore:: didFirstLayout %s", url.string().ascii().data()); - - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - WebCore::String urlString(url.string()); - jstring urlStr = env->NewString((unsigned short*)urlString.characters(), urlString.length()); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mDidFirstLayout, urlStr); - checkException(env); - env->DeleteLocalRef(urlStr); - - DBG_NAV_LOG("call updateFrameCache"); - updateFrameCache(); - mHistory.setDidFirstLayout(true); -} - -void WebViewCore::restoreScale(int scale) -{ - LOG_ASSERT(mParent == NULL, "Why do we have a parent"); - - DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); - LOG_ASSERT(mJavaGlue->mObj, "A Java widget was not associated with this view bridge!"); - - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mRestoreScale, scale); - checkException(env); -} - -static void layoutIfNeededRecursive(WebCore::Frame* f) -{ - if (!f) - return; - - WebCore::FrameView* v = f->view(); - if (!v) - return; - - if (v->needsLayout()) - v->layout(); - - if (!f->tree()) - return; - - WebCore::Frame* child = f->tree()->firstChild(); - while (child) { - WebCore::FrameView* childView = child->view(); - if (childView) - layoutIfNeededRecursive(child); - if (!child->tree()) - break; - child = child->tree()->nextSibling(); - } -} - -void WebViewCore::layout() -{ - LOG_ASSERT(mParent == NULL, "Why do we have a parent"); - - SkASSERT(mView); - layoutIfNeededRecursive(mFrame); -} - -void WebViewCore::notifyFocusSet() -{ - sendNotifyFocusSet(); -} - -void WebViewCore::notifyProgressFinished() -{ - DBG_NAV_LOG("call updateFrameCache"); - updateFrameCache(); - sendNotifyProgressFinished(); -} - -void WebViewCore::doMaxScroll(WebCore::CacheBuilder::Direction dir) -{ - int dx = 0, dy = 0; - - switch (dir) { - case WebCore::CacheBuilder::LEFT: - dx = -this->getMaxXScroll(); - break; - case WebCore::CacheBuilder::UP: - dy = -this->getMaxXScroll(); - break; - case WebCore::CacheBuilder::RIGHT: - dx = this->getMaxYScroll(); - break; - case WebCore::CacheBuilder::DOWN: - dy = this->getMaxYScroll(); - break; - case WebCore::CacheBuilder::UNINITIALIZED: - default: - LOG_ASSERT(0, "unexpected focus selector"); - } - this->scrollBy(dx, dy); -} - -void WebViewCore::getVisibleRect(WebCore::IntRect* rect) const -{ - SkASSERT(rect); - *rect = mVisibleRect; -} - -void WebViewCore::setVisibleRect(const WebCore::IntRect& r) -{ - DBG_NAV_LOGD("{%d,%d,%d,%d}", r.x(), r.y(), r.width(), r.height()); - if (mVisibleRect != r) { - if (mVisibleRect.x() != r.x() || mVisibleRect.y() != r.y()) - mFrame->sendScrollEvent(); - mVisibleRect = r; - // The visible rect is located within our coordinate space so it - // contains the actual scroll position. Setting the location makes hit - // testing work correctly. - setLocation(r.x(), r.y()); - } -} - -void WebViewCore::dump() -{ -#if DUMP_NAV_CACHE - if (mFrame != NULL) - mFrame->getCacheBuilder().mDebug.print(); -#endif -} - -WebCore::String WebViewCore::retrieveHref(WebCore::Frame* frame, WebCore::Node* node) -{ - WebCore::CacheBuilder& builder = mFrame->getCacheBuilder(); - if (builder.validNode(frame, node) == false) - return WebCore::String(); - if (node->hasTagName(WebCore::HTMLNames::aTag) == false) - return WebCore::String(); - WebCore::HTMLAnchorElement* anchor = static_cast<WebCore::HTMLAnchorElement*>(node); - return anchor->href(); -} - -WebCore::String WebViewCore::retrieveImageRef(int x, int y) -{ - WebCore::IntPoint point(x,y); - WebCore::HitTestResult result = mFrame->eventHandler()->hitTestResultAtPoint(point, false); - WebCore::Node* node = result.innerNode(); - if (node == NULL || node->hasTagName(WebCore::HTMLNames::imgTag) == false) - return WebCore::String(); - WebCore::HTMLImageElement* img = static_cast<WebCore::HTMLImageElement*>(node); - return img->src(); -} - -bool WebViewCore::prepareFrameCache() -{ - if (mFrameCacheOutOfDate == false) { - DBG_NAV_LOG("mFrameCacheOutOfDate == false"); - return false; - } - mFrameCacheOutOfDate = false; -#if DEBUG_NAV_UI - DBG_NAV_LOG("mFrameCacheOutOfDate was true"); - mNow = SkTime::GetMSecs(); -#endif - mTemp = new CachedRoot(); - mTemp->init(mFrame, &mHistory); - mTemp->setGeneration(++mBuildGeneration); - WebCore::CacheBuilder& builder = mFrame->getCacheBuilder(); - WebCore::Settings* settings = frame()->page()->settings(); - builder.allowAllTextDetection(); - if (settings->formatDetectionAddress() == false) - builder.disallowAddressDetection(); - if (settings->formatDetectionEmail() == false) - builder.disallowEmailDetection(); - if (settings->formatDetectionTelephone() == false) - builder.disallowPhoneDetection(); - builder.buildCache(mTemp); - mTempPict = new SkPicture(); - recordPicture(mTempPict, false); - mTemp->setPicture(mTempPict); - mTemp->setTextGeneration(mTextGeneration); - return true; -} - -void WebViewCore::releaseFrameCache(bool newCache) -{ - if (newCache == false) { - DBG_NAV_LOG("newCache == false"); - return; - } - gFrameCacheMutex.lock(); - delete mFrameCacheKit; - delete mNavPictureKit; - mFrameCacheKit = mTemp; - mNavPictureKit = mTempPict; - mUpdatedFrameCache = true; -#if DEBUG_NAV_UI - const CachedNode* cachedFocusNode = mFrameCacheKit->currentFocus(); - DBG_NAV_LOGD("cachedFocusNode=%d (nodePointer=%p)", - cachedFocusNode ? cachedFocusNode->index() : 0, - cachedFocusNode ? cachedFocusNode->nodePointer() : NULL); -#endif - gFrameCacheMutex.unlock(); - notifyFocusSet(); - // it's tempting to send an invalidate here, but it's a bad idea - // the cache is now up to date, but the focus is not -- the event - // may need to be recomputed from the prior history. An invalidate - // will draw the stale location causing the ring to flash at the wrong place. -} - -void WebViewCore::updateFrameCache() -{ - mUseReplay = false; - releaseFrameCache(prepareFrameCache()); -} - -void WebViewCore::removeFrameGeneration(WebCore::Frame* frame) -{ - DBG_NAV_LOGD("frame=%p mGeneration=%d", frame, mGeneration); - gFrameGenerationMutex.lock(); - int last = mFrameGenerations.size() - 1; - for (int index = 0; index <= last; index++) { - if (mFrameGenerations[index].mFrame == frame) { - DBG_NAV_LOGD("index=%d last=%d", index, last); - if (index != last) - mFrameGenerations[index] = mFrameGenerations[last]; - mFrameGenerations.removeLast(); - break; - } - } - gFrameGenerationMutex.unlock(); -} - -void WebViewCore::updateFrameGeneration(WebCore::Frame* frame) -{ - DBG_NAV_LOGD("frame=%p mGeneration=%d", frame, mGeneration); - gFrameGenerationMutex.lock(); - ++mBuildGeneration; - for (size_t index = 0; index < mFrameGenerations.size(); index++) { - if (mFrameGenerations[index].mFrame == frame) { - DBG_NAV_LOG("replace"); - mFrameGenerations[index].mGeneration = mBuildGeneration; - goto done; - } - } - { - FrameGen frameGen = {frame, mBuildGeneration}; - mFrameGenerations.append(frameGen); - DBG_NAV_LOG("append"); - } -done: - gFrameGenerationMutex.unlock(); -} - -int WebViewCore::retrieveFrameGeneration(WebCore::Frame* frame) -{ - int result = INT_MAX; - gFrameGenerationMutex.lock(); - for (size_t index = 0; index < mFrameGenerations.size(); index++) { - if (mFrameGenerations[index].mFrame == frame) { - result = mFrameGenerations[index].mGeneration; - break; - } - } - gFrameGenerationMutex.unlock(); - DBG_NAV_LOGD("frame=%p mGeneration=%d result=%d", frame, mGeneration, result); - return result; -} - -void WebViewCore::setFinalFocus(WebCore::Frame* frame, WebCore::Node* node, - int x, int y, bool block) -{ - DBG_NAV_LOGD("frame=%p node=%p x=%d y=%d", frame, node, x, y); - bool result = finalKitFocus(frame, node, x, y); - if (block) { - mBlockFocusChange = true; - if (result == false && node != NULL) - touchUp(mTouchGeneration, 0, NULL, NULL, x, y, 0, true, true); - } -} - -void WebViewCore::setKitFocus(int moveGeneration, int buildGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y, - bool ignoreNullFocus) -{ - DBG_NAV_LOGD("mMoveGeneration=%d moveGeneration=%d" - " buildGeneration=%d frame=%p node=%p x=%d y=%d", - mMoveGeneration, moveGeneration, buildGeneration, frame, node, x, y); - if (mBlockFocusChange) { - DBG_NAV_LOG("mBlockFocusChange"); - return; - } - if (mMoveGeneration > moveGeneration) { - DBG_NAV_LOGD("mMoveGeneration=%d > moveGeneration=%d", - mMoveGeneration, moveGeneration); - return; // short-circuit if a newer move has already been generated - } - if (commonKitFocus(moveGeneration, buildGeneration, frame, node, x, y, - ignoreNullFocus) == false) - return; - mLastGeneration = moveGeneration; -} - -bool WebViewCore::commonKitFocus(int generation, int buildGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y, - bool ignoreNullFocus) -{ - DBG_NAV_LOGD("generation=%d buildGeneration=%d frame=%p" - " node=%p x=%d y=%d", generation, buildGeneration, frame, node, x, y); - mUseReplay = true; - bool newCache = prepareFrameCache(); // must wait for possible recompute before using - if (mMoveGeneration > generation) { - DBG_NAV_LOGD("mMoveGeneration=%d > generation=%d", - mMoveGeneration, generation); - releaseFrameCache(newCache); - return false; // short-circuit if a newer move has already been generated - } - // if the nav cache has been rebuilt since this focus request was generated, - // send a request back to the UI side to recompute the kit-side focus - if (mBuildGeneration > buildGeneration || (node != NULL && mFrame->getCacheBuilder().validNode(frame, node) == false)) { - DBG_NAV_LOGD("mBuildGeneration=%d > buildGeneration=%d", - mBuildGeneration, buildGeneration); - gRecomputeFocusMutex.lock(); - bool first = mRecomputeEvents.size() == 0; - mRecomputeEvents.append(generation); - gRecomputeFocusMutex.unlock(); - releaseFrameCache(newCache); - if (first) - sendRecomputeFocus(); - return false; - } - releaseFrameCache(newCache); - if (node == NULL && ignoreNullFocus) - return true; - finalKitFocus(frame, node, x, y); - return true; -} - -bool WebViewCore::finalKitFocus(WebCore::Frame* frame, WebCore::Node* node, - int x, int y) -{ - if (NULL == frame) - frame = mFrame; - WebCore::CacheBuilder& builder = mFrame->getCacheBuilder(); - WebCore::Node* oldFocusNode = builder.currentFocus(); - mMousePos = WebCore::IntPoint(x, y); - // validNode will still return true if the node is null, as long as we have - // a valid frame. Do not want to make a call on frame unless it is valid. - bool valid = builder.validNode(frame, node); - if (valid) { - WebCore::PlatformMouseEvent mouseEvent(mMousePos, mMousePos, WebCore::NoButton, - WebCore::MouseEventMoved, 1, false, false, false, false, WebCore::currentTime()); - frame->eventHandler()->handleMouseMoveEvent(mouseEvent); - } - WebCore::Document* oldDoc = oldFocusNode ? oldFocusNode->document() : NULL; - if (node == NULL) { - if (oldFocusNode != NULL) - oldDoc->setFocusedNode(NULL); - return false; - } else if (valid == false) { - DBG_NAV_LOGD("sendMarkNodeInvalid node=%p", node); - sendMarkNodeInvalid(node); - if (oldFocusNode != NULL) - oldDoc->setFocusedNode(NULL); - return false; - } - // If we jump frames (docs), kill the focus on the old doc - builder.setLastFocus(node); - if (oldFocusNode != NULL && node->document() != oldDoc) { - oldDoc->setFocusedNode(NULL); - } - WebCore::RenderObject* renderer = node->renderer(); - /* <area> element doesn't have a renderer, but it can accept focus */ - LOG_ASSERT(!(renderer && renderer->isWidget()), "widgets unsupported"); - if (node->isTextNode() == false) - static_cast<WebCore::Element*>(node)->focus(false); - //setFocus on things that WebCore doesn't recognize as supporting focus - //for instance, if there is an onclick element that does not support focus - DBG_NAV_LOGD("setFocusedNode node=%p", node); - node->document()->setFocusedNode(node); - mLastFocused = node; - mLastFocusedBounds = node->getRect(); - return true; -} - -// helper function to find the frame that has focus -static WebCore::Frame* FocusedFrame(WebCore::FrameAndroid* frame) -{ - if (!frame) - return NULL; - WebCore::Node* focusNode = frame->getCacheBuilder().currentFocus(); - if (!focusNode) - return NULL; - WebCore::Document* doc = focusNode->document(); - if (!doc) - return NULL; - return doc->frame(); -} - -static WebCore::RenderTextControl* FocusedTextControl(WebCore::FrameAndroid* frame) -{ - WebCore::Node* focusNode = frame->getCacheBuilder().currentFocus(); - WebCore::RenderObject* renderer = focusNode->renderer(); - if (renderer && (renderer->isTextField() || renderer->isTextArea())) { - return static_cast<WebCore::RenderTextControl*>(renderer); - } - return NULL; -} - -WebCore::Frame* WebViewCore::changedKitFocus(WebCore::Frame* frame, - WebCore::Node* node, int x, int y) -{ - if (frame == NULL || node == NULL) - return mFrame; - WebCore::Node* current = mFrame->getCacheBuilder().currentFocus(); - if (current == node) - return frame; - return finalKitFocus(frame, node, x, y) ? frame : mFrame; -} - -static int findTextBoxIndex(WebCore::Node* node, const WebCore::IntPoint& pt) -{ - if (node->isTextNode() == false) { - DBG_NAV_LOGD("node=%p pt=(%d,%d) isText=false", node, pt.x(), pt.y()); - return -2; // error - } - WebCore::RenderText* renderText = (WebCore::RenderText*) node->renderer(); - if (renderText == NULL) { - DBG_NAV_LOGD("node=%p pt=(%d,%d) renderText=NULL", node, pt.x(), pt.y()); - return -3; // error - } - int renderX, renderY; - renderText->absolutePosition(renderX, renderY); - WebCore::InlineTextBox *textBox = renderText->firstTextBox(); - int globalX, globalY; - WebCore::CacheBuilder::GetGlobalOffset(node, &globalX, &globalY); - int x = pt.x() - globalX; - int y = pt.y() - globalY; - do { - int textBoxStart = textBox->start(); - int textBoxEnd = textBoxStart + textBox->len(); - if (textBoxEnd <= textBoxStart) - continue; - WebCore::IntRect bounds = textBox->selectionRect(renderX, renderY, - textBoxStart, textBoxEnd); - if (bounds.contains(x, y) == false) - continue; - int offset = textBox->offsetForPosition(x - renderX); -#if DEBUG_NAV_UI - int prior = offset > 0 ? textBox->positionForOffset(offset - 1) : -1; - int current = textBox->positionForOffset(offset); - int next = textBox->positionForOffset(offset + 1); - DBG_NAV_LOGD( - "offset=%d pt.x=%d globalX=%d renderX=%d x=%d " - "textBox->x()=%d textBox->start()=%d prior=%d current=%d next=%d", - offset, pt.x(), globalX, renderX, x, - textBox->xPos(), textBox->start(), prior, current, next - ); -#endif - return textBox->start() + offset; - } while ((textBox = textBox->nextTextBox()) != NULL); - return -1; // couldn't find point, may have walked off end -} - -static inline bool isSpace(UChar c) -{ - return c <= ' ' || WTF::Unicode::direction(c) == WTF::Unicode::WhiteSpaceNeutral; -} - -static int centerX(const SkIRect& rect) { return (rect.fLeft + rect.fRight) >> 1; } -static int centerY(const SkIRect& rect) { return (rect.fTop + rect.fBottom) >> 1; } - -WebCore::String WebViewCore::getSelection(SkRegion* selRgn) -{ - SkRegion::Iterator iter(*selRgn); - WebCore::String result; - for (; iter.done() == false; iter.next()) { - const SkIRect& rect = iter.rect(); - DBG_NAV_LOGD("rect=(%d, %d, %d, %d)", rect.fLeft, rect.fTop, - rect.fRight, rect.fBottom); - int cy = centerY(rect); - WebCore::IntPoint startPt = WebCore::IntPoint(rect.fLeft + 1, cy); - WebCore::HitTestResult hitTestResult = mFrame->eventHandler()-> - hitTestResultAtPoint(startPt, false); - WebCore::Node* node = hitTestResult.innerNode(); - if (node == NULL) { - DBG_NAV_LOG("node == NULL"); - return result; - } - WebCore::IntPoint endPt = WebCore::IntPoint(rect.fRight - 1, cy); - hitTestResult = mFrame->eventHandler()->hitTestResultAtPoint(endPt, false); - WebCore::Node* endNode = hitTestResult.innerNode(); - if (endNode == NULL) { - DBG_NAV_LOG("endNode == NULL"); - return result; - } - int start = findTextBoxIndex(node, startPt); - if (start < 0) - continue; - int end = findTextBoxIndex(endNode, endPt); - if (end < -1) // use node if endNode is not valid - endNode = node; - if (end <= 0) - end = static_cast<WebCore::Text*>(endNode)->string()->length(); - DBG_NAV_LOGD("node=%p start=%d endNode=%p end=%d", node, start, endNode, end); - do { - if (node->isTextNode() == false) - continue; - if (node->getRect().isEmpty()) - continue; - WebCore::Text* textNode = static_cast<WebCore::Text*>(node); - WebCore::StringImpl* string = textNode->string(); - if (string->length() == 0) - continue; - const UChar* chars = string->characters(); - int newLen = node == endNode ? end : string->length(); - int oldLen = result.length(); - if (oldLen == 0) { - if (newLen < start) { - DBG_NAV_LOGD("newLen=%d < start=%d", newLen, start); - return result; - } - result.append(chars + start, newLen - start); - continue; - } - if (isSpace(result.characters()[oldLen - 1]) == false && - isSpace(chars[0]) == false) { - result.append(" "); - } - result.append(chars, newLen); - } while (node != endNode && (node = node->traverseNextNode()) != NULL); - } -#if DUMP_NAV_CACHE - { - char buffer[256]; - WebCore::CacheBuilder::Debug debug; - debug.init(buffer, sizeof(buffer)); - debug.print("copy: "); - debug.wideString(result); - DUMP_NAV_LOGD("%s", buffer); - } -#endif - return result; -} - -WebCore::Frame* WebViewCore::setSelection(WebCore::Frame* frame, WebCore::Node* node, - int x, int y, int start, int end) -{ - // FIXME: Consider using a generation number to avoid doing this many more times than necessary. - frame = changedKitFocus(frame, node, x, y); - ((WebCore::FrameAndroid*) frame)->select(start, end); - return frame; -} - -WebCore::Frame* WebViewCore::deleteSelection(WebCore::Frame* frame, WebCore::Node* node, - int x, int y, int start, int end) -{ - frame = setSelection(frame, node, x, y, start, end); - if (start != end) { - WebCore::PlatformKeyboardEvent downEvent(kKeyCodeDel, WebCore::VK_BACK, true, false, false, false, false); - frame->eventHandler()->keyEvent(downEvent); - WebCore::PlatformKeyboardEvent upEvent(kKeyCodeDel, WebCore::VK_BACK, false, false, false, false, false); - frame->eventHandler()->keyEvent(upEvent); - } - return frame; -} - -void WebViewCore::replaceTextfieldText(WebCore::Frame* frame, WebCore::Node* node, int x, int y, - int oldStart, int oldEnd, jstring replace, int start, int end) -{ - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - const jchar* outputChars = NULL == replace ? NULL : env->GetStringChars(replace, NULL); - - WebCore::String webcoreString; - if (outputChars == NULL) { - webcoreString = WebCore::String(); - } - else { - webcoreString = WebCore::String((const UChar*) outputChars, env->GetStringLength(replace)); - } - frame = setSelection(frame, node, x, y, oldStart, oldEnd); - WebCore::TypingCommand::insertText(frame->document(), webcoreString, false); - ((WebCore::FrameAndroid*) frame)->select(start, end); - if (replace && outputChars) - env->ReleaseStringChars(replace, outputChars); - checkException(env); -} - -void WebViewCore::passToJs(WebCore::Frame* frame, WebCore::Node* node, int x, int y, int generation, - jstring currentText, int keyCode, int keyValue, bool down, bool cap, bool fn, bool sym) -{ - frame = changedKitFocus(frame, node, x, y); - WebCore::PlatformKeyboardEvent event(keyCode, keyValue, down, false, cap, fn, sym); - // Block text field updates during a key press. - mBlockTextfieldUpdates = true; - frame->eventHandler()->keyEvent(event); - mBlockTextfieldUpdates = false; - mTextGeneration = generation; - - WebCore::Node* currentFocus = mFrame->getCacheBuilder().currentFocus(); - // Make sure we have the same focus and it is a text field. - if (node == currentFocus && currentFocus) { - WebCore::RenderObject* renderer = currentFocus->renderer(); - if (renderer != NULL && (renderer->isTextField() || renderer->isTextArea())) { - WebCore::RenderTextControl* renderText = static_cast<WebCore::RenderTextControl*>(renderer); - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - const jchar* str = env->GetStringChars(currentText, NULL); - WebCore::String current = WebCore::String(str, env->GetStringLength(currentText)); - env->ReleaseStringChars(currentText, str); - WebCore::String test = renderText->text(); - // If the text changed during the key event, update the UI text field. - if (test != current) - updateTextfield(currentFocus, false, test); - } - } -} - -void WebViewCore::saveDocumentState(WebCore::Frame* frame, WebCore::Node* node, int x, int y) -{ - frame = changedKitFocus(frame, node, x, y); - WebCore::HistoryItem *item = frame->loader()->currentHistoryItem(); - - // item can be null when there is no offical URL for the current page. This happens - // when the content is loaded using with WebCoreFrameBridge::LoadData() and there - // is no failing URL (common case is when content is loaded using data: scheme) - if (item != 0) { - item->setDocumentState(frame->document()->formElementsState()); - } -} - -// Convert a WebCore::String into an array of characters where the first -// character represents the length, for easy conversion to java. -static uint16_t* stringConverter(const WebCore::String& text) -{ - size_t length = text.length(); - uint16_t* itemName = new uint16_t[length+1]; - itemName[0] = (uint16_t)length; - uint16_t* firstChar = &(itemName[1]); - memcpy((void*)firstChar, text.characters(), sizeof(UChar)*length); - return itemName; -} - -// Response to dropdown created for a listbox. -class ListBoxReply : public WebCoreReply { -public: - ListBoxReply(WebCore::HTMLSelectElement* select, WebCore::Frame* frame, WebViewCore* view) - : m_select(select) - , m_frame(frame) - , m_viewImpl(view) - {} - - // Response used if the listbox only allows single selection. - // index is listIndex of the selected item, or -1 if nothing is selected. - virtual void replyInt(int index) { - // If the select element no longer exists, do to a page change, etc, silently return. - if (!m_select || m_viewImpl->mFrame->getCacheBuilder().validNode(m_frame, m_select) == false) - return; - if (-1 == index) { - if (m_select->selectedIndex() != -1) { - m_select->deselectItems(); - m_select->onChange(); - m_viewImpl->contentInvalidate(); - } - return; - } - WebCore::HTMLOptionElement* option = static_cast<WebCore::HTMLOptionElement*>( - m_select->item(m_select->listToOptionIndex(index))); - if (!option->selected()) { - option->setSelected(true); - m_select->onChange(); - m_viewImpl->contentInvalidate(); - } - } - - // Response if the listbox allows multiple selection. array stores the listIndices - // of selected positions. - virtual void replyIntArray(SkTDArray<int> array) { - // If the select element no longer exists, do to a page change, etc, silently return. - if (!m_select || m_viewImpl->mFrame->getCacheBuilder().validNode(m_frame, m_select) == false) - return; - m_select->deselectItems(); - int count = array.count(); - WebCore::HTMLOptionElement* option; - for (int i = 0; i < count; i++) { - option = static_cast<WebCore::HTMLOptionElement*>( - m_select->item(array[m_select->listToOptionIndex(i)])); - option->setSelected(true); - } - m_viewImpl->contentInvalidate(); - } -private: - // The select element associated with this listbox. - WebCore::HTMLSelectElement* m_select; - // The frame of this select element, to verify that it is valid. - WebCore::Frame* m_frame; - // For calling invalidate. - WebViewCore* m_viewImpl; -}; - -// Create an array of java Strings. -static jobjectArray makeLabelArray(JNIEnv* env, const uint16_t** labels, size_t count) -{ - jclass stringClass = env->FindClass("java/lang/String"); - LOG_ASSERT(stringClass, "Could not find java/lang/String"); - jobjectArray array = env->NewObjectArray(count, stringClass, NULL); - LOG_ASSERT(array, "Could not create new string array"); - - for (size_t i = 0; i < count; i++) { - jobject newString = env->NewString(&labels[i][1], labels[i][0]); - env->SetObjectArrayElement(array, i, newString); - env->DeleteLocalRef(newString); - checkException(env); - } - env->DeleteLocalRef(stringClass); - return array; -} - -void WebViewCore::listBoxRequest(WebCoreReply* reply, const uint16_t** labels, size_t count, const int enabled[], size_t enabledCount, - bool multiple, const int selected[], size_t selectedCountOrSelection) { - // Reuse mPopupReply - Release(mPopupReply); - mPopupReply = NULL; - - LOG_ASSERT(mJavaGlue->mObj, "No java widget associated with this view!"); - - // Create an array of java Strings for the drop down. - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - jobjectArray labelArray = makeLabelArray(env, labels, count); - - // Create an array determining whether each item is enabled. - jbooleanArray enabledArray = env->NewBooleanArray(enabledCount); - checkException(env); - jboolean* ptrArray = env->GetBooleanArrayElements(enabledArray, NULL); - checkException(env); - for (size_t i = 0; i < enabledCount; i++) { - ptrArray[i] = enabled[i]; - } - env->ReleaseBooleanArrayElements(enabledArray, NULL, enabledCount); - checkException(env); - - if (multiple) { - // Pass up an array representing which items are selected. - jintArray selectedArray = env->NewIntArray(selectedCountOrSelection); - checkException(env); - jint* selArray = env->GetIntArrayElements(selectedArray, NULL); - checkException(env); - for (size_t i = 0; i < selectedCountOrSelection; i++) { - selArray[i] = selected[i]; - } - env->ReleaseIntArrayElements(selectedArray, NULL, selectedCountOrSelection); - - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mRequestListBox, labelArray, enabledArray, selectedArray); - env->DeleteLocalRef(selectedArray); - } else { - // Pass up the single selection. - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mRequestSingleListBox, labelArray, enabledArray, selectedCountOrSelection); - } - - env->DeleteLocalRef(labelArray); - env->DeleteLocalRef(enabledArray); - checkException(env); - - Retain(reply); - mPopupReply = reply; -} - -bool WebViewCore::keyUp(KeyCode keyCode, int keyVal) -{ - DBG_NAV_LOGD("keyCode=%d", keyCode); - bool keyHandled = false; - WebCore::Node* focusNode = mFrame->getCacheBuilder().currentFocus(); - if (focusNode != NULL) { - WebCore::FrameAndroid* focusFrame = Android(focusNode->document()->frame()); - - WebCoreFrameBridge* bridge = mFrame->bridge(); - switch (keyCode) { - case kKeyCodeNewline: - case kKeyCodeDpadCenter: { - focusFrame->loader()->resetMultipleFormSubmissionProtection(); - bridge->setInKeyHandler(true); - if ((focusNode->hasTagName(WebCore::HTMLNames::inputTag) && - ((WebCore::HTMLInputElement*)focusNode)->isTextField()) || - focusNode->hasTagName(WebCore::HTMLNames::textareaTag)) { - // Create the key down event. - WebCore::PlatformKeyboardEvent keydown(keyCode, keyVal, true, false, false, false, false); - // Create the key up event. - WebCore::PlatformKeyboardEvent keyup(keyCode, keyVal, false, false, false, false, false); - // Send both events. - keyHandled = focusFrame->eventHandler()->keyEvent(keydown); - keyHandled |= focusFrame->eventHandler()->keyEvent(keyup); - } else { - keyHandled = handleMouseClick(focusFrame, focusNode); - } - bridge->setInKeyHandler(false); - break; - } - default: - keyHandled = false; - } - } - mBlockFocusChange = false; - return keyHandled; -} - -void WebViewCore::touchUp(int touchGeneration, int buildGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y, int size, - bool isClick, bool retry) -{ - if (mTouchGeneration > touchGeneration) { - DBG_NAV_LOGD("mTouchGeneration=%d > touchGeneration=%d" - " x=%d y=%d", mTouchGeneration, touchGeneration, x, y); - return; // short circuit if a newer touch has been generated - } - if (retry) - finalKitFocus(frame, node, x, y); - else if (commonKitFocus(touchGeneration, buildGeneration, - frame, node, x, y, false) == false) { - return; - } - mLastGeneration = touchGeneration; - // If this is just a touch and not a click, we have already done the change in focus, - // so just leave the function now. - if (!isClick) - return; - WebCore::EditorClientAndroid* client = static_cast<WebCore::EditorClientAndroid*>(mFrame->editor()->client()); - client->setFromClick(true); - DBG_NAV_LOGD("touchGeneration=%d handleMouseClick frame=%p node=%p" - " x=%d y=%d", touchGeneration, frame, node, x, y); - handleMouseClick(frame, node); - client->setFromClick(false); -} - -bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr) { - if (framePtr != NULL && mFrame->getCacheBuilder().validNode(framePtr, nodePtr) == false) - return false; - WebCoreFrameBridge* bridge = mFrame->bridge(); - // Need to special case area tags because an image map could have an area element in the middle - // so when attempting to get the default, the point chosen would be follow the wrong link. - if (nodePtr != NULL && nodePtr->hasTagName(WebCore::HTMLNames::areaTag)) { - bridge->setInKeyHandler(true); - WebCore::EventTargetNodeCast(nodePtr)->dispatchSimulatedClick(0, true, true); - bridge->setInKeyHandler(false); - return true; - } - WebCore::RenderObject* renderer = nodePtr != NULL ? nodePtr->renderer() : NULL; - if (renderer) { - if (renderer->isMenuList()) { - WebCore::HTMLSelectElement* select = static_cast<WebCore::HTMLSelectElement*>(nodePtr); - const WTF::Vector<WebCore::HTMLElement*>& listItems = select->listItems(); - SkTDArray<const uint16_t*> names; - SkTDArray<int> enabledArray; - SkTDArray<int> selectedArray; - int size = listItems.size(); - bool multiple = select->multiple(); - for (int i = 0; i < size; i++) { - if (listItems[i]->hasTagName(WebCore::HTMLNames::optionTag)) { - WebCore::HTMLOptionElement* option = static_cast<WebCore::HTMLOptionElement*>(listItems[i]); - *names.append() = stringConverter(option->optionText()); - *enabledArray.append() = option->disabled() ? 0 : 1; - if (multiple && option->selected()) - *selectedArray.append() = i; - } else if (listItems[i]->hasTagName(WebCore::HTMLNames::optgroupTag)) { - WebCore::HTMLOptGroupElement* optGroup = static_cast<WebCore::HTMLOptGroupElement*>(listItems[i]); - *names.append() = stringConverter(optGroup->groupLabelText()); - *enabledArray.append() = 0; - if (multiple) - *selectedArray.append() = 0; - } - } - WebCoreReply* reply = new ListBoxReply(select, select->document()->frame(), this); - listBoxRequest(reply, names.begin(), size, enabledArray.begin(), enabledArray.count(), - multiple, selectedArray.begin(), multiple ? selectedArray.count() : - select->optionToListIndex(select->selectedIndex())); - return true; - } - } - if (NULL == framePtr) - framePtr = mFrame; - bridge->setInKeyHandler(true); - DBG_NAV_LOGD("mMousePos={%d,%d}", mMousePos.x(), mMousePos.y()); - WebCore::PlatformMouseEvent mouseDown(mMousePos, mMousePos, WebCore::LeftButton, - WebCore::MouseEventPressed, 1, false, false, false, false, - WebCore::currentTime()); - // ignore the return from as it will return true if the hit point can trigger selection change - framePtr->eventHandler()->handleMousePressEvent(mouseDown); - WebCore::PlatformMouseEvent mouseUp(mMousePos, mMousePos, WebCore::LeftButton, - WebCore::MouseEventReleased, 1, false, false, false, false, - WebCore::currentTime()); - bool handled = framePtr->eventHandler()->handleMouseReleaseEvent(mouseUp); - bridge->setInKeyHandler(false); - return handled; -} - -void WebViewCore::popupReply(int index) -{ - if (mPopupReply) { - mPopupReply->replyInt(index); - Release(mPopupReply); - mPopupReply = NULL; - } -} - -void WebViewCore::popupReply(SkTDArray<int> array) { - if (mPopupReply) { - mPopupReply->replyIntArray(array); - Release(mPopupReply); - mPopupReply = NULL; - } -} - -void WebViewCore::jsAlert(const WebCore::String& url, const WebCore::String& text) -{ - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - jstring jInputStr = env->NewString((unsigned short *)text.characters(), text.length()); - jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length()); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mJsAlert, jUrlStr, jInputStr); - env->DeleteLocalRef(jInputStr); - env->DeleteLocalRef(jUrlStr); - checkException(env); -} - -bool WebViewCore::jsConfirm(const WebCore::String& url, const WebCore::String& text) -{ - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - jstring jInputStr = env->NewString((unsigned short *)text.characters(), text.length()); - jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length()); - jboolean result = env->CallBooleanMethod(mJavaGlue->mObj, mJavaGlue->mJsConfirm, jUrlStr, jInputStr); - env->DeleteLocalRef(jInputStr); - env->DeleteLocalRef(jUrlStr); - checkException(env); - return result; -} - -bool WebViewCore::jsPrompt(const WebCore::String& url, const WebCore::String& text, const WebCore::String& defaultValue, WebCore::String& result) -{ - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - jstring jInputStr = env->NewString((unsigned short *)text.characters(), text.length()); - jstring jDefaultStr = env->NewString((unsigned short *)defaultValue.characters(), defaultValue.length()); - jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length()); - jstring returnVal = (jstring) env->CallObjectMethod(mJavaGlue->mObj, mJavaGlue->mJsPrompt, jUrlStr, jInputStr, jDefaultStr); - // If returnVal is null, it means that the user cancelled the dialog. - if (!returnVal) - return false; - - const jchar* outputChars = env->GetStringChars(returnVal, NULL); - if (outputChars == NULL) { - result = WebCore::String(); - } else { - result = WebCore::String((const UChar*) outputChars, env->GetStringLength(returnVal)); - } - env->ReleaseStringChars(returnVal, outputChars); - env->DeleteLocalRef(jInputStr); - env->DeleteLocalRef(jDefaultStr); - env->DeleteLocalRef(jUrlStr); - checkException(env); - return true; -} - -bool WebViewCore::jsUnload(const WebCore::String& url, const WebCore::String& message) -{ - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - jstring jInputStr = env->NewString((unsigned short *)message.characters(), message.length()); - jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length()); - jboolean result = env->CallBooleanMethod(mJavaGlue->mObj, mJavaGlue->mJsUnload, jUrlStr, jInputStr); - env->DeleteLocalRef(jInputStr); - env->DeleteLocalRef(jUrlStr); - checkException(env); - return result; -} - -WebCoreViewBridge* -WebViewCore::createBridgeForView(WebCore::FrameView* view) -{ - SkASSERT(view); - WebViewCore* viewBridge = new WebViewCore(javavm_to_jnienv(mJavaGlue->mJVM), mJavaGlue->mObj, view); - WebCore::IntRect r = getBounds(); - viewBridge->setBounds(r.x(), r.y(), r.right(), r.bottom()); - return viewBridge; -} - -jobject -WebViewCore::getJavaObject() -{ - return mJavaGlue->mObj; -} - -jobject -WebViewCore::getWebViewJavaObject() -{ - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - return env->GetObjectField(mJavaGlue->mObj, gWebViewCoreFields.mWebView); -} - -void WebViewCore::updateTextfield(WebCore::Node* ptr, bool changeToPassword, - const WebCore::String& text) -{ - if (mBlockTextfieldUpdates) - return; - JNIEnv* env = javavm_to_jnienv(mJavaGlue->mJVM); - if (changeToPassword) { - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mUpdateTextfield, - (int) ptr, true, NULL, mTextGeneration); - checkException(env); - return; - } - int length = text.length(); - jstring string = env->NewString((unsigned short *) text.characters(), length); - env->CallVoidMethod(mJavaGlue->mObj, mJavaGlue->mUpdateTextfield, - (int) ptr, false, string, mTextGeneration); - env->DeleteLocalRef(string); - checkException(env); -} - -void WebViewCore::setSnapAnchor(int x, int y) -{ - mSnapAnchorNode = NULL; - if (x == 0 && y == 0) { - return; - } - - WebCore::IntPoint point = WebCore::IntPoint(x, y); - WebCore::Node* node = mFrame->eventHandler()->hitTestResultAtPoint(point, false).innerNode(); - if (node) { -// LOGD("found focus node name: %s, type %d\n", node->nodeName().utf8().data(), node->nodeType()); - while (node) { - if (node->hasTagName(WebCore::HTMLNames::divTag) || - node->hasTagName(WebCore::HTMLNames::tableTag)) { - mSnapAnchorNode = node; - return; - } -// LOGD("parent node name: %s, type %d\n", node->nodeName().utf8().data(), node->nodeType()); - node = node->parentNode(); - } - } -} - -void WebViewCore::snapToAnchor() -{ - if (mSnapAnchorNode) { - if (mSnapAnchorNode->inDocument()) { - int rx, ry; - mSnapAnchorNode->renderer()->absolutePosition(rx, ry); - scrollTo(rx, ry); - } else { - mSnapAnchorNode = NULL; - } - } -} - -void WebViewCore::setBackgroundColor(SkColor c) -{ - WebCore::FrameView* view = mFrame->view(); - if (view == NULL) - return; - WebCore::Color bcolor(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c), - SkColorGetA(c)); - view->setBaseBackgroundColor(bcolor); -} - -//---------------------------------------------------------------------- -// Native JNI methods -//---------------------------------------------------------------------- -static jstring WebCoreStringToJString(JNIEnv *env, WebCore::String string) -{ - int length = string.length(); - if (0 == length) - return 0; - jstring ret = env->NewString((jchar *)string.characters(), length); - env->DeleteLocalRef(ret); - return ret; -} - -void WebViewCore::SetSize(JNIEnv *env, jobject obj, jint width, jint height, - jint screenWidth, jfloat scale) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOGV("webviewcore::nativeSetSize(%u %u)\n viewImpl: %p", (unsigned)width, (unsigned)height, viewImpl); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeSetSize"); - // convert the scale to an int - int s = (int) (scale * 100); - // a negative value indicates that we should not change the scale - if (scale < 0) - s = viewImpl->scale(); - - viewImpl->setSizeScreenWidthAndScale(width, height, screenWidth, s); -} - -void WebViewCore::SetVisibleRect(JNIEnv *env, jobject obj, - jint x, jint y, jint width, jint height) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "need viewImpl"); - - viewImpl->setVisibleRect(WebCore::IntRect(x, y, width, height)); -} - -jboolean WebViewCore::KeyUp(JNIEnv *env, jobject obj, jint key, jint val) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif -// LOGV("webviewcore::nativeKeyUp(%u)\n", (unsigned)key); - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeKeyUp"); - return viewImpl->keyUp((KeyCode)key, val); -} - -void WebViewCore::DeleteSelection(JNIEnv *env, jobject obj, - jint frame, jint node, jint x, jint y, jint start, jint end) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - LOGV("webviewcore::nativeDeleteSelection()\n"); - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeDeleteSelection"); - viewImpl->deleteSelection((WebCore::Frame*) frame, (WebCore::Node*) node, - x, y, start, end); -} - -void WebViewCore::SetSelection(JNIEnv *env, jobject obj, - jint frame, jint node, jint x, jint y, jint start, jint end) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - LOGV("webviewcore::nativeSetSelection()\n"); - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeDeleteSelection"); - viewImpl->setSelection((WebCore::Frame*) frame, (WebCore::Node*) node, - x, y, start, end); -} - - -void WebViewCore::ReplaceTextfieldText(JNIEnv *env, jobject obj, - jint framePtr, jint nodePtr, jint x, jint y, jint oldStart, jint oldEnd, - jstring replace, jint start, jint end) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - LOGV("webviewcore::nativeReplaceTextfieldText()\n"); - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeReplaceTextfieldText"); - viewImpl->replaceTextfieldText((WebCore::Frame*) framePtr, (WebCore::Node*) nodePtr, x, y, oldStart, - oldEnd, replace, start, end); -} - -void WebViewCore::PassToJs(JNIEnv *env, jobject obj, jint frame, jint node, - jint x, jint y, jint generation, jstring currentText, jint keyCode, - jint keyValue, jboolean down, jboolean cap, jboolean fn, jboolean sym) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - LOGV("webviewcore::nativePassToJs()\n"); - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativePassToJs"); - viewImpl->passToJs((WebCore::Frame*) frame, (WebCore::Node*) node, - x, y, generation, currentText, keyCode, keyValue, down, cap, fn, sym); -} - -void WebViewCore::SaveDocumentState(JNIEnv *env, jobject obj, jint frame, jint node, jint x, jint y) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - LOGV("webviewcore::nativeSaveDocumentState()\n"); - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeSaveDocumentState"); - viewImpl->saveDocumentState((WebCore::Frame*) frame, (WebCore::Node*) node, x, y); -} - -void WebViewCore::Draw(JNIEnv *env, jobject obj, jobject contentPict) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeDraw"); - LOG_ASSERT(contentPict, "need a valid java picture for nativeDraw"); - SkPicture* picture = GraphicsJNI::getNativePicture(env, contentPict); - LOG_ASSERT(picture, "need native picture in nativeDraw"); - viewImpl->recordPicture(picture, true); -} - -void WebViewCore::SendListBoxChoice(JNIEnv* env, jobject obj, jint choice) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeSendListBoxChoice"); - viewImpl->popupReply(choice); -} - -void WebViewCore::SendListBoxChoices(JNIEnv* env, jobject obj, jbooleanArray jArray, jint size) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeSendListBoxChoices"); - jboolean* ptrArray = env->GetBooleanArrayElements(jArray, NULL); - SkTDArray<int> array; - for (int i = 0; i < size; i++) { - if (ptrArray[i]) { - *array.append() = i; - } - } - viewImpl->popupReply(array); -} - -void WebViewCore::ClearMatches(JNIEnv *env, jobject obj) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeClearMatches"); - - WebCore::Frame* frame = viewImpl->frame(); - while (frame) { - if (frame->document()) - frame->document()->removeMarkers(); - WebCore::SelectionController* controller = frame->selectionController(); - if (controller->isRange()) { - WebCore::Position pos = controller->start(); - WebCore::Position end = controller->end(); - do { - if (pos.inRenderedText()) { - WebCore::RenderObject* renderer = pos.node()->renderer(); - if (renderer != NULL) { - renderer->setSelectionState(WebCore::RenderObject::SelectionNone); - } - } - pos = pos.next(); - } while (pos != end); - controller->clear(); - } - frame = frame->tree()->traverseNext(); - } -} - -jboolean WebViewCore::Find(JNIEnv *env, jobject obj, jstring find, - jboolean forward, jboolean fromSelection) { - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeFind"); - - if (NULL == find) - return false; - int length = env->GetStringLength(find); - if (0 == length) - return false; // perhaps we want to return true, in order to show the correct dialog - const jchar* findChars = env->GetStringChars(find, NULL); - // Will this ever return NULL if find is not NULL and its length is not zero? - if (NULL == findChars) - return false; - WebCore::String findString = WebCore::String((const UChar*) findChars, length); - env->ReleaseStringChars(find, findChars); - WebCore::Frame* mainFrame = viewImpl->frame(); - WebCore::Frame* frame = mainFrame; - bool found = false; - if (fromSelection) { - // Need to figure out which frame has a selection, then start from there - while (frame && frame->selectionController()->isNone()) { - frame = frame->tree()->traverseNext(); - } - if (!frame) { - // No selection, so start from the beginning. - frame = mainFrame; - } - // Now we have the frame with the selection. - WebCore::Frame* starterFrame = frame; - bool firstTimeThroughLoop = true; - if (forward) { - while (!(found = frame->findString(findString, true, false, false, true))) { - if (firstTimeThroughLoop) { - firstTimeThroughLoop = false; - // FIXME: Clearing the selection is necessary for the search to - // work properly. However, the invalidation does not remove - // the drawn rectangle from old frames. - frame->selectionController()->clear(); - } - frame = frame->tree()->traverseNextWithWrap(true); - if (frame == starterFrame) - break; - } - } else { - // Search backwards, searching the frames in reverse order as well. - while (!(found = frame->findString(findString, false, false, false, true))) { - if (firstTimeThroughLoop) { - firstTimeThroughLoop = false; - frame->selectionController()->clear(); - } - frame = frame->tree()->traversePreviousWithWrap(true); - if (frame == starterFrame) - break; - } - } - // In order to wrap to the beginning of the initial frame. - if (!found) { - found = frame->findString(findString, forward, false, false, true); - } - } else { - // Clear any old selections so find will work properly. - while (frame) { - frame->selectionController()->clear(); - frame->invalidateSelection(); - frame = frame->tree()->traverseNext(); - } - frame = mainFrame; - do { - found = frame->findString(findString, forward, false, false, false); - } while (!found && (frame = frame->tree()->traverseNext()) != NULL); - } - if (found) { - frame->view()->scrollRectIntoViewRecursively(frame->selectionController()->caretRect()); - return true; - } - return false; -} - -jstring WebViewCore::FindAddress(JNIEnv *env, jobject obj, jstring addr) -{ - if (NULL == addr) - return NULL; - int length = env->GetStringLength(addr); - if (0 == length) - return NULL; - const jchar* addrChars = env->GetStringChars(addr, NULL); - int start, end; - bool success = WebCore::CacheBuilder::FindAddress(addrChars, length, - &start, &end) == WebCore::CacheBuilder::FOUND_COMPLETE; - jstring ret = NULL; - if (success) { - ret = env->NewString((jchar*) addrChars + start, end - start); - env->DeleteLocalRef(ret); - } - env->ReleaseStringChars(addr, addrChars); - return ret; -} - -jint WebViewCore::FindAll(JNIEnv *env, jobject obj, jstring find) { - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeFindAll"); - if (NULL == find) - return 0; - int length = env->GetStringLength(find); - if (0 == length) - return 0; - const jchar* findChars = env->GetStringChars(find, NULL); - // Will this ever return NULL if find is not NULL and its length is not zero? - if (NULL == findChars) - return 0; - WebCore::String findString = WebCore::String((const UChar*) findChars, length); - env->ReleaseStringChars(find, findChars); - WebCore::Frame* frame = viewImpl->frame(); - int numFound = 0; - ClearMatches(env, obj); - while (frame) { - frame->selectionController()->clear(); - frame->invalidateSelection(); - if (frame->document()) - frame->document()->removeMarkers(); - frame->setMarkedTextMatchesAreHighlighted(true); - numFound += frame->markAllMatchesForText(findString, false, 0); - frame = frame->tree()->traverseNext(); - } - if (numFound > 0) - Find(env, obj, find, true, false); - return numFound; -} - -void WebViewCore::TouchUp(JNIEnv *env, jobject obj, jint touchGeneration, - jint buildGeneration, jint frame, jint node, jint x, jint y, jint size, - jboolean isClick, jboolean retry) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - viewImpl->touchUp(touchGeneration, buildGeneration, - (WebCore::Frame*) frame, (WebCore::Node*) node, x, y, size, isClick, retry); -} - -jstring WebViewCore::RetrieveHref(JNIEnv *env, jobject obj, jint frame, - jint node) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - WebCore::String result = viewImpl->retrieveHref((WebCore::Frame*) frame, - (WebCore::Node*) node); - if (!result.isEmpty()) - return WebCoreStringToJString(env, result); - return NULL; -} - -jstring WebViewCore::RetrieveImageRef(JNIEnv *env, jobject obj, jint x, jint y) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - WebCore::String result = viewImpl->retrieveImageRef(x, y); - if (!result.isEmpty()) - return WebCoreStringToJString(env, result); - return NULL; -} - -void WebViewCore::SetFinalFocus(JNIEnv *env, jobject obj, jint frame, jint node, - jint x, jint y, jboolean block) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - viewImpl->setFinalFocus((WebCore::Frame*) frame, (WebCore::Node*) node, x, - y, block); -} - -void WebViewCore::SetKitFocus(JNIEnv *env, jobject obj, jint moveGeneration, - jint buildGeneration, jint frame, jint node, jint x, jint y, - jboolean ignoreNullFocus) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterWV counter; -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - viewImpl->setKitFocus(moveGeneration, buildGeneration, - (WebCore::Frame*) frame, (WebCore::Node*) node, x, y, - ignoreNullFocus); -} - -void WebViewCore::UnblockFocus(JNIEnv *env, jobject obj) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - viewImpl->unblockFocus(); -} - -void WebViewCore::UpdateFrameCache(JNIEnv *env, jobject obj) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - viewImpl->updateFrameCache(); -} - -jint WebViewCore::GetContentMinPrefWidth(JNIEnv *env, jobject obj) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - - WebCore::Frame* frame = viewImpl->frame(); - if (frame) { - WebCore::Document* document = frame->document(); - if (document) { - WebCore::RenderObject* renderer = document->renderer(); - if (renderer && renderer->isRenderView()) { - return renderer->minPrefWidth(); - } - } - } - return 0; -} - -void WebViewCore::SetViewportSettingsFromNative(JNIEnv *env, jobject obj) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - - WebCore::Settings* s = viewImpl->frame()->page()->settings(); - if (s == NULL) - return; - - env->SetIntField(obj, gWebViewCoreFields.mViewportWidth, s->viewportWidth()); - env->SetIntField(obj, gWebViewCoreFields.mViewportHeight, s->viewportHeight()); - env->SetIntField(obj, gWebViewCoreFields.mViewportInitialScale, s->viewportInitialScale()); - env->SetIntField(obj, gWebViewCoreFields.mViewportMinimumScale, s->viewportMinimumScale()); - env->SetIntField(obj, gWebViewCoreFields.mViewportMaximumScale, s->viewportMaximumScale()); - env->SetBooleanField(obj, gWebViewCoreFields.mViewportUserScalable, s->viewportUserScalable()); -} - -void WebViewCore::SetSnapAnchor(JNIEnv *env, jobject obj, jint x, jint y) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - - viewImpl->setSnapAnchor(x, y); -} - -void WebViewCore::SnapToAnchor(JNIEnv *env, jobject obj) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - - viewImpl->snapToAnchor(); -} - -void WebViewCore::SetBackgroundColor(JNIEnv *env, jobject obj, jint color) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - - viewImpl->setBackgroundColor((SkColor) color); -} - -static void jrect_to_skirect(JNIEnv* env, jobject obj, SkIRect* result) -{ - int L, T, R, B; - GraphicsJNI::get_jrect(env, obj, &L, &T, &R, &B); - result->set(L, T, R, B); -} - -jstring WebViewCore::GetSelection(JNIEnv *env, jobject obj, jobject selRgn) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - SkRegion* selectionRegion = GraphicsJNI::getNativeRegion(env, selRgn); - WebCore::String result = viewImpl->getSelection(selectionRegion); - if (!result.isEmpty()) - return WebCoreStringToJString(env, result); - return NULL; -} - -void WebViewCore::Dump(JNIEnv *env, jobject obj) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - - viewImpl->dump(); -} - -void WebViewCore::RefreshPlugins(JNIEnv *env, - jobject obj, - jboolean reloadOpenPages) -{ - // Refresh the list of plugins, optionally reloading all open - // pages. - WebCore::refreshPlugins(reloadOpenPages); -} - -// ---------------------------------------------------------------------------- - -/* - * JNI registration. - */ -static JNINativeMethod gJavaWebViewCoreMethods[] = { - { "nativeClearMatches", "()V", - (void*) WebViewCore::ClearMatches } , - { "nativeDraw", "(Landroid/graphics/Picture;)V", - (void*) WebViewCore::Draw }, - { "nativeKeyUp", "(II)Z", - (void*) WebViewCore::KeyUp }, - { "nativeSendListBoxChoices", "([ZI)V", - (void*) WebViewCore::SendListBoxChoices }, - { "nativeSendListBoxChoice", "(I)V", - (void*) WebViewCore::SendListBoxChoice }, - { "nativeSetSize", "(IIIF)V", - (void*) WebViewCore::SetSize }, - { "nativeSetVisibleRect", "(IIII)V", - (void*) WebViewCore::SetVisibleRect }, - { "nativeSetSelection", "(IIIIII)V", - (void*) WebViewCore::SetSelection } , - { "nativeDeleteSelection", "(IIIIII)V", - (void*) WebViewCore::DeleteSelection } , - { "nativeReplaceTextfieldText", "(IIIIIILjava/lang/String;II)V", - (void*) WebViewCore::ReplaceTextfieldText } , - { "passToJs", "(IIIIILjava/lang/String;IIZZZZ)V", - (void*) WebViewCore::PassToJs } , - { "nativeSaveDocumentState", "(IIII)V", - (void*) WebViewCore::SaveDocumentState }, - { "nativeFind", "(Ljava/lang/String;ZZ)Z", - (void*) WebViewCore::Find } , - { "nativeFindAddress", "(Ljava/lang/String;)Ljava/lang/String;", - (void*) WebViewCore::FindAddress }, - { "nativeFindAll", "(Ljava/lang/String;)I", - (void*) WebViewCore::FindAll } , - { "nativeTouchUp", "(IIIIIIIZZ)V", - (void*) WebViewCore::TouchUp }, - { "nativeRetrieveImageRef", "(II)Ljava/lang/String;", - (void*) WebViewCore::RetrieveImageRef }, - { "nativeRetrieveHref", "(II)Ljava/lang/String;", - (void*) WebViewCore::RetrieveHref }, - { "nativeSetFinalFocus", "(IIIIZ)V", - (void*) WebViewCore::SetFinalFocus }, - { "nativeSetKitFocus", "(IIIIIIZ)V", - (void*) WebViewCore::SetKitFocus }, - { "nativeUnblockFocus", "()V", - (void*) WebViewCore::UnblockFocus }, - { "nativeUpdateFrameCache", "()V", - (void*) WebViewCore::UpdateFrameCache }, - { "nativeGetContentMinPrefWidth", "()I", - (void*) WebViewCore::GetContentMinPrefWidth }, - { "setViewportSettingsFromNative", "()V", - (void*) WebViewCore::SetViewportSettingsFromNative }, - { "nativeSetSnapAnchor", "(II)V", - (void*) WebViewCore::SetSnapAnchor }, - { "nativeSnapToAnchor", "()V", - (void*) WebViewCore::SnapToAnchor }, - { "nativeSetBackgroundColor", "(I)V", - (void*) WebViewCore::SetBackgroundColor }, - { "nativeGetSelection", - "(Landroid/graphics/Region;)Ljava/lang/String;", - (void*) WebViewCore::GetSelection }, - { "nativeRefreshPlugins", "(Z)V", - (void*) WebViewCore::RefreshPlugins }, - { "nativeDump", "()V", - (void*) WebViewCore::Dump } -}; - -int register_webviewcore(JNIEnv* env) -{ - jclass widget = env->FindClass("android/webkit/WebViewCore"); - LOG_ASSERT(widget != NULL, - "Unable to find class android/webkit/WebViewCore"); - gWebViewCoreFields.mNativeClass = env->GetFieldID(widget, "mNativeClass", - "I"); - LOG_ASSERT(gWebViewCoreFields.mNativeClass != NULL, - "Unable to find android/webkit/WebViewCore.mNativeClass"); - gWebViewCoreFields.mViewportWidth = env->GetFieldID(widget, - "mViewportWidth", "I"); - LOG_ASSERT(gWebViewCoreFields.mViewportWidth != NULL, - "Unable to find android/webkit/WebViewCore.mViewportWidth"); - gWebViewCoreFields.mViewportHeight = env->GetFieldID(widget, - "mViewportHeight", "I"); - LOG_ASSERT(gWebViewCoreFields.mViewportHeight != NULL, - "Unable to find android/webkit/WebViewCore.mViewportHeight"); - gWebViewCoreFields.mViewportInitialScale = env->GetFieldID(widget, - "mViewportInitialScale", "I"); - LOG_ASSERT(gWebViewCoreFields.mViewportInitialScale != NULL, - "Unable to find android/webkit/WebViewCore.mViewportInitialScale"); - gWebViewCoreFields.mViewportMinimumScale = env->GetFieldID(widget, - "mViewportMinimumScale", "I"); - LOG_ASSERT(gWebViewCoreFields.mViewportMinimumScale != NULL, - "Unable to find android/webkit/WebViewCore.mViewportMinimumScale"); - gWebViewCoreFields.mViewportMaximumScale = env->GetFieldID(widget, - "mViewportMaximumScale", "I"); - LOG_ASSERT(gWebViewCoreFields.mViewportMaximumScale != NULL, - "Unable to find android/webkit/WebViewCore.mViewportMaximumScale"); - gWebViewCoreFields.mViewportUserScalable = env->GetFieldID(widget, - "mViewportUserScalable", "Z"); - LOG_ASSERT(gWebViewCoreFields.mViewportUserScalable != NULL, - "Unable to find android/webkit/WebViewCore.mViewportUserScalable"); - gWebViewCoreFields.mWebView = env->GetFieldID(widget, - "mWebView", "Landroid/webkit/WebView;"); - LOG_ASSERT(gWebViewCoreFields.mWebView != NULL, - "Unable to find android/webkit/WebViewCore.mWebView"); - - return jniRegisterNativeMethods(env, "android/webkit/WebViewCore", - gJavaWebViewCoreMethods, NELEM(gJavaWebViewCoreMethods)); -} - -} /* namespace android */ diff --git a/WebCore/platform/android/jni/WebViewCore.h b/WebCore/platform/android/jni/WebViewCore.h deleted file mode 100644 index 1cb51b2..0000000 --- a/WebCore/platform/android/jni/WebViewCore.h +++ /dev/null @@ -1,400 +0,0 @@ -/* - * - * Copyright 2006, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_WIDGET_HTMLWIDGET_H -#define ANDROID_WIDGET_HTMLWIDGET_H - -#include "WebCoreViewBridge.h" -#include "CacheBuilder.h" -#include "CachedHistory.h" -#include "FrameView.h" -#include "SkColor.h" -#include "SkScalar.h" -#include "SkRegion.h" -#include <ui/Rect.h> -#include <jni.h> - -namespace WebCore { - class AtomicString; - class Color; - class GraphicsContext; - class HTMLSelectElement; - class RenderPart; - class RenderText; - class FrameAndroid; - class Node; - class RenderTextControl; -} - -class SkPicture; - -namespace android { - - class CachedRoot; - - class ListBoxReply; - - class WebViewCore : public WebCoreViewBridge - { - public: - /** - * Initialize the ViewBridge with a JNI environment, a native HTMLWidget object - * and an associated frame to perform actions on. - */ - WebViewCore(JNIEnv* env, jobject javaView, WebCore::FrameView* view); - virtual ~WebViewCore(); - - /** - * Set the scroll offset. - * @param x The x position of the new scroll offset. - * @param y The y position of the new scroll offset. - */ -// void setScrollOffset(int x, int y); - - // Inherited from WebCoreViewBridge - virtual void draw(WebCore::GraphicsContext* ctx, - const WebCore::IntRect& rect, bool invalCache); - - /** - * Layout our Frame if needed and recursively layout all child frames. - */ - virtual void layout(); - - /** - * Scroll to an absolute position. - * @param x The x coordinate. - * @param y The y coordinate. - * @param animate If it is true, animate to the new scroll position - * - * This method calls Java to trigger a gradual scroll event. - */ - virtual void scrollTo(int x, int y, bool animate = false); - - /** - * Scroll to the point x,y relative to the current position. - * @param x The relative x position. - * @param y The relative y position. - */ - virtual void scrollBy(int x, int y); - - /** - * Mark the display list as invalid, and post an event (once) to - * rebuild the display list by calling webcore to draw the dom - */ - virtual void contentInvalidate(); - virtual void contentInvalidate(const WebCore::IntRect &rect); - - // invalidate the view/display, NOT the content/DOM - virtual void viewInvalidate() { sendViewInvalidate(); } - - /** - * Called by webcore when the focus was set after returning to prior page - * used to rebuild and display any changes in focus - */ - virtual void notifyFocusSet(); - /** - * Called by webcore when the progress indicator is done - * used to rebuild and display any changes in focus - */ - virtual void notifyProgressFinished(); - - /** - * On resize is called after a setSize event on WebCoreViewBridge. onResize - * then tells the frame to relayout the contents due to the size change - */ - virtual void onResize(); - - /** - * Notify the view that WebCore did its first layout. - */ - virtual void didFirstLayout(); - - /** - * Notify the view to restore the screen width, which in turn restores - * the scale. - */ - virtual void restoreScale(int); - - /* Set the view and frame */ - virtual void setView(WebCore::FrameView* view) { - if (mView) - mView->deref(); - mView = view; - if (mView) { - mView->ref(); - mFrame = (WebCore::FrameAndroid*)mView->frame(); - reset(false); - } else - mFrame = NULL; - } - - // new methods for this subclass - - void reset(bool fromConstructor); - - WebCore::FrameAndroid* frame() const { return mFrame; } - WebCore::String retrieveHref(WebCore::Frame* frame, WebCore::Node* node); - - /** - * Return the url of the image located at (x,y) in content coordinates, or - * null if there is no image at that point. - * - * @param x x content ordinate - * @param y y content ordinate - * @return WebCore::String url of the image located at (x,y), or null if there is - * no image there. - */ - WebCore::String retrieveImageRef(int x, int y); - - WebCore::String getSelection(SkRegion* ); - void recordPicture(SkPicture* picture, bool invalCache); - void setFrameCacheOutOfDate(); - void setFinalFocus(WebCore::Frame* frame, WebCore::Node* node, - int x, int y, bool block); - void setKitFocus(int moveGeneration, int buildGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y, - bool ignoreNullFocus); - int getMaxXScroll() const { return mMaxXScroll; } - int getMaxYScroll() const { return mMaxYScroll; } - void setMaxXScroll(int maxx) { mMaxXScroll = maxx; } - void setMaxYScroll(int maxy) { mMaxYScroll = maxy; } - - int contentWidth() const { return mView->contentsWidth(); } - int contentHeight() const { return mView->contentsHeight(); } - - // the visible rect is in document coordinates, and describes the - // intersection of the document with the "window" in the UI. - void getVisibleRect(WebCore::IntRect* rect) const; - void setVisibleRect(const WebCore::IntRect& rect); - - WebCore::FrameView* getFrameView() { return mView; } - void listBoxRequest(WebCoreReply* reply, const uint16_t** labels, size_t count, const int enabled[], size_t enabledCount, - bool multiple, const int selected[], size_t selectedCountOrSelection); - - /** - * Handle keyDown events from Java. - * @param keyCode The key pressed. - * @return Whether keyCode was handled by this class. - */ - bool keyUp(KeyCode keyCode, int keyValue); - - /** - * Handle motionUp event from the UI thread (called touchUp in the - * WebCore thread). - */ - void touchUp(int touchGeneration, int buildGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y, - int size, bool isClick, bool retry); - - /** - * Return a new WebCoreViewBridge to interface with the passed in view. - */ - virtual WebCoreViewBridge* createBridgeForView(WebCore::FrameView* view); - - /** - * Sets the index of the label from a popup - */ - void popupReply(int index); - void popupReply(SkTDArray<int>array); - - virtual void jsAlert(const WebCore::String& url, const WebCore::String& text); - virtual bool jsConfirm(const WebCore::String& url, const WebCore::String& text); - virtual bool jsPrompt(const WebCore::String& url, const WebCore::String& message, const WebCore::String& defaultValue, WebCore::String& result); - virtual bool jsUnload(const WebCore::String& url, const WebCore::String& message); - - /** - * Delete text from start to end in the focused textfield. If there is no - * focus, or if start == end, silently fail, but set selection to that value. - * If start and end are out of order, swap them. - * Use the frame, node, x, and y to ensure that the correct node is focused. - * Return a frame. Convenience so replaceTextfieldText can use this function. - */ - WebCore::Frame* deleteSelection(WebCore::Frame* frame, WebCore::Node* node, int x, - int y,int start, int end); - - /** - * Set the selection of the currently focused textfield to (start, end). - * If start and end are out of order, swap them. - * Use the frame, node, x, and y to ensure that the correct node is focused. - * Return a frame. Convenience so deleteSelection can use this function. - */ - WebCore::Frame* setSelection(WebCore::Frame* frame, WebCore::Node* node, int x, - int y,int start, int end); - /** - * In the currenlty focused textfield, represented by frame, node, x, and y (which - * are used to ensure it has focus), replace the characters from oldStart to oldEnd - * (if oldStart == oldEnd, this will be an insert at that position) with replace, - * and set the selection to (start, end). - */ - void replaceTextfieldText(WebCore::Frame* frame, WebCore::Node* node, int x, int y, - int oldStart, int oldEnd, jstring replace, int start, int end); - void passToJs(WebCore::Frame* frame, WebCore::Node* node, int x, int y, int generation, - jstring currentText, int jKeyCode, int keyVal, bool down, bool cap, bool fn, bool sym); - - void saveDocumentState(WebCore::Frame* frame, WebCore::Node* node, int x, int y); - - // TODO: I don't like this hack but I need to access the java object in - // order to send it as a parameter to java - jobject getJavaObject(); - - // Return the parent WebView Java object associated with this - // WebViewCore. - jobject getWebViewJavaObject(); - - bool pinXToDocument(int* yPtr); - bool pinYToDocument(int* yPtr); - - WebCore::RenderLayer* getRenderLayer(); - - /** - * Tell the java side to update the focused textfield - * @param pointer Pointer to the node for the input field. - * @param changeToPassword If true, we are changing the textfield to - * a password field, and ignore the String - * @param text If changeToPassword is false, this is the new text that - * should go into the textfield. - */ - virtual void updateTextfield(WebCore::Node* pointer, - bool changeToPassword, const WebCore::String& text); - - virtual void removeFrameGeneration(WebCore::Frame* ); - virtual void updateFrameGeneration(WebCore::Frame* ); - - void setBackgroundColor(SkColor c); - void setSnapAnchor(int x, int y); - void snapToAnchor(); - void unblockFocus() { mBlockFocusChange = false; } - void updateFrameCache(); - void dump(); - - // jni methods - static void Destroy(JNIEnv*, jobject); - static void Dump(JNIEnv*, jobject); - static void RefreshPlugins(JNIEnv*, jobject, jboolean); - static void SetSize(JNIEnv*, jobject, jint, jint, jint, jfloat); - static void SetVisibleRect(JNIEnv*, jobject, jint, jint, jint, jint); - static jboolean KeyUp(JNIEnv*, jobject, jint, jint); - static void DeleteSelection(JNIEnv*, jobject, jint, jint, jint, jint, - jint, jint); - static void SetSelection(JNIEnv*, jobject, jint, jint, jint, jint, - jint, jint); - static void ReplaceTextfieldText(JNIEnv*, jobject, jint, jint, jint, - jint, jint, jint, jstring, jint, jint); - static void PassToJs(JNIEnv*, jobject, jint, jint, jint, jint, jint, - jstring, jint, jint, jboolean, jboolean, jboolean, jboolean); - static void SaveDocumentState(JNIEnv*, jobject, jint, jint, jint, jint); - static void Draw(JNIEnv*, jobject, jobject); - static void SendListBoxChoices(JNIEnv*, jobject, jbooleanArray, jint); - static void SendListBoxChoice(JNIEnv* env, jobject obj, jint choice); - static void ClearMatches(JNIEnv*, jobject); - static jboolean Find(JNIEnv*, jobject, jstring, jboolean, jboolean); - static jstring FindAddress(JNIEnv*, jobject, jstring); - static jint FindAll(JNIEnv*, jobject, jstring); - static void TouchUp(JNIEnv*, jobject, jint, jint, jint, jint, jint, - jint, jint, jboolean, jboolean); - static jstring RetrieveHref(JNIEnv*, jobject, jint, jint); - static jstring RetrieveImageRef(JNIEnv*, jobject, jint, jint); - static void SetFinalFocus(JNIEnv*, jobject, jint, jint, jint, jint, - jboolean); - static void SetKitFocus(JNIEnv*, jobject, jint, jint, jint, jint, jint, - jint, jboolean); - static void UnblockFocus(JNIEnv*, jobject); - static void UpdateFrameCache(JNIEnv*, jobject); - static jint GetContentMinPrefWidth(JNIEnv*, jobject); - static void SetViewportSettingsFromNative(JNIEnv*, jobject); - static void SetBackgroundColor(JNIEnv *env, jobject obj, jint color); - static void SetSnapAnchor(JNIEnv*, jobject, jint, jint); - static void SnapToAnchor(JNIEnv*, jobject); - static jstring GetSelection(JNIEnv*, jobject, jobject); - // end jni methods - - // these members are shared with webview.cpp - int retrieveFrameGeneration(WebCore::Frame* ); - static Mutex gFrameCacheMutex; - CachedRoot* mFrameCacheKit; // nav data being built by webcore - SkPicture* mNavPictureKit; - int mGeneration; // copy of the number bumped by WebViewNative - int mMoveGeneration; // copy of state in WebViewNative triggered by move - int mTouchGeneration; // copy of state in WebViewNative triggered by touch - int mLastGeneration; // last action using up to date cache - bool mUpdatedFrameCache; - bool mUseReplay; - static Mutex gRecomputeFocusMutex; - WTF::Vector<int> mRecomputeEvents; - // These two fields go together: we use the mutex to protect access to - // mButtons, so that we, and webview.cpp can look/modify the mButtons - // field safely from our respective threads - static Mutex gButtonMutex; - SkTDArray<Container*>* mButtons; - // end of shared members - private: - friend class ListBoxReply; - struct FrameGen { - const WebCore::Frame* mFrame; - int mGeneration; - }; - WTF::Vector<FrameGen> mFrameGenerations; - static Mutex gFrameGenerationMutex; - struct JavaGlue; - struct JavaGlue* mJavaGlue; - WebCore::FrameView* mView; - WebCore::FrameAndroid* mFrame; - WebCoreReply* mPopupReply; - WebCore::Node* mLastFocused; - WebCore::IntRect mLastFocusedBounds; - // Used in passToJS to avoid updating the UI text field until after the - // key event has been processed. - bool mBlockTextfieldUpdates; - // Passed in with key events to know when they were generated. Store it - // with the cache so that we can ignore stale text changes. - int mTextGeneration; - CachedRoot* mTemp; - SkPicture* mTempPict; - int mBuildGeneration; - int mMaxXScroll; - int mMaxYScroll; - WebCore::IntRect mVisibleRect; - WebCore::IntPoint mMousePos; - bool mFrameCacheOutOfDate; - bool mBlockFocusChange; - int mLastPassed; - int mLastVelocity; - CachedHistory mHistory; - WebCore::Node* mSnapAnchorNode; - WebCore::Frame* changedKitFocus(WebCore::Frame* frame, - WebCore::Node* node, int x, int y); - bool commonKitFocus(int generation, int buildGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y, - bool ignoreNullFocus); - bool finalKitFocus(WebCore::Frame* frame, WebCore::Node* node, int x, int y); - void doMaxScroll(WebCore::CacheBuilder::Direction dir); - void sendMarkNodeInvalid(WebCore::Node* ); - void sendNotifyFocusSet(); - void sendNotifyProgressFinished(); - void sendRecomputeFocus(); - void sendViewInvalidate(); - bool handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr); - bool prepareFrameCache(); - void releaseFrameCache(bool newCache); -#if DEBUG_NAV_UI - uint32_t mNow; -#endif - }; - -} // namespace android - -#endif // ANDROID_WIDGET_HTMLWIDGET_H diff --git a/WebCore/platform/android/nav/CacheBuilder.cpp b/WebCore/platform/android/nav/CacheBuilder.cpp deleted file mode 100644 index cee6ca7..0000000 --- a/WebCore/platform/android/nav/CacheBuilder.cpp +++ /dev/null @@ -1,2974 +0,0 @@ -/* - * Copyright 2006, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License.max - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "CachedPrefix.h" -#include "CachedNode.h" -#include "CachedRoot.h" -#include "Document.h" -#include "EventNames.h" -#include "EventTargetNode.h" -#include "Frame.h" -#include "FrameAndroid.h" -#include "FrameTree.h" -#include "FrameView.h" -//#include "GraphicsContext.h" -#include "HTMLAreaElement.h" -#include "HTMLImageElement.h" -#include "HTMLInputElement.h" -#include "HTMLNames.h" -#include "HTMLOptionElement.h" -#include "HTMLSelectElement.h" -#include "InlineTextBox.h" -#include "KURL.h" -#include "RenderImage.h" -#include "RenderInline.h" -#include "RenderListBox.h" -#include "RenderSkinCombo.h" -#include "RenderTextControl.h" -#include "RenderWidget.h" -#include "SkCanvas.h" -#include "SkPoint.h" -#include "Text.h" -#include "WebCoreFrameBridge.h" -#include "WebCoreViewBridge.h" -#include "Widget.h" -#include <wtf/unicode/Unicode.h> - -#ifdef DUMP_NAV_CACHE_USING_PRINTF - FILE* gNavCacheLogFile = NULL; - android::Mutex gWriteLogMutex; -#endif - -#include "CacheBuilder.h" - -#define MINIMUM_FOCUSABLE_WIDTH 3 -#define MINIMUM_FOCUSABLE_HEIGHT 3 -#define MAXIMUM_FOCUS_RING_COUNT 32 - -namespace WebCore { - -CacheBuilder* CacheBuilder::Builder(Frame* frame) { - return &Android(frame)->m_cacheBuilder; -} - -FrameAndroid* CacheBuilder::FrameAnd(CacheBuilder* cacheBuilder) { - return (FrameAndroid*) ((char*) cacheBuilder - OFFSETOF(FrameAndroid, m_cacheBuilder)); -} - -FrameAndroid* CacheBuilder::FrameAnd(const CacheBuilder* cacheBuilder) { - return (FrameAndroid*) ((char*) cacheBuilder - OFFSETOF(FrameAndroid, m_cacheBuilder)); -} - -#if DUMP_NAV_CACHE - -#define DEBUG_BUFFER_SIZE 256 -#define DEBUG_WRAP_SIZE 150 -#define DEBUG_WRAP_MAX 170 - -FrameAndroid* CacheBuilder::Debug::frameAnd() const { - CacheBuilder* nav = (CacheBuilder*) ((char*) this - OFFSETOF(CacheBuilder, mDebug)); - return CacheBuilder::FrameAnd(nav); -} - -void CacheBuilder::Debug::attr(const AtomicString& name, const AtomicString& value) { - if (name.isNull() || name.isEmpty() || value.isNull() || value.isEmpty()) - return; - uChar(name.characters(), name.length(), false); - print("="); - wideString(value.characters(), value.length(), false); - print(" "); -} - -void CacheBuilder::Debug::comma(const char* str) { - print(str); - print(", "); -} - -int CacheBuilder::Debug::flowBoxes(RenderFlow* flow, int ifIndex, int indent) { - char scratch[256]; - const InlineFlowBox* box = flow->firstLineBox(); - if (box == NULL) - return ifIndex; - do { - newLine(); - int i = snprintf(scratch, sizeof(scratch), "// render flow:%p" - " box:%p%.*s", flow, box, indent, " "); - for (; box; box = box->nextFlowBox()) { - i += snprintf(&scratch[i], sizeof(scratch) - i, - " [%d]:{%d, %d, %d, %d}", ++ifIndex, - box->xPos(), box->yPos(), box->width(), box->height()); - if (ifIndex % 4 == 0) - break; - } - print(scratch); - } while (box); - RenderObject const * const end = flow->lastChild(); - if (end == NULL) - return ifIndex; - indent += 2; - if (indent > 8) - indent = 8; - for (const RenderObject* renderer = flow->firstChild(); renderer != end; - renderer = renderer->nextSibling()) - { - if (renderer->isInlineFlow()) - ifIndex = flowBoxes((RenderFlow*) renderer, ifIndex, indent); - } - return ifIndex; -} - -void CacheBuilder::Debug::flush() { - int len; - do { - int limit = mIndex; - if (limit < DEBUG_WRAP_SIZE) - return; - if (limit < DEBUG_WRAP_MAX) - len = limit; - else { - limit = DEBUG_WRAP_MAX; - len = DEBUG_WRAP_SIZE; - while (len < limit) { - char test = mBuffer[len]; - if (test < '/' || (test > '9' && test < 'A') || (test > 'Z' && test < 'a') || test > 'z') - break; - len++; - } - while (mBuffer[len] == '\\' || mBuffer[len] == '"') - len++; - } - const char* prefix = mPrefix; - if (prefix[0] == '\"') { - // see if we're inside a quote - int quoteCount = 0; - for (int index = 0; index < len; index++) { - if (mBuffer[index] == '\\') { - index++; - continue; - } - if (mBuffer[index] == '\n') { - quoteCount = 0; - continue; - } - if (mBuffer[index] == '"') - quoteCount++; - } - if ((quoteCount & 1) == 0) - prefix = "\n"; - } - DUMP_NAV_LOGD("%.*s", len, mBuffer); - int copy = mIndex - len; - strcpy(mBuffer, prefix); - memcpy(&mBuffer[strlen(prefix)], &mBuffer[len], copy); - mIndex = strlen(prefix) + copy; - } while (true); -} - -void CacheBuilder::Debug::frameName(char*& namePtr, const char* max) const { - if (namePtr >= max) - return; - Frame* frame = frameAnd(); - Frame* parent = frame->tree()->parent(); - if (parent) - Builder(parent)->mDebug.frameName(namePtr, max); - const AtomicString& name = frame->tree()->name(); - if (name.length() == 0) - return; - unsigned index = 0; - if (name.startsWith(AtomicString("opener"))) - index = 6; - for (; index < name.length(); index++) { - char ch = name[index]; - if (ch <= ' ') - ch = '_'; - if (WTF::isASCIIAlphanumeric(ch) || ch == '_') - *namePtr++ = ch; - } -} - -void CacheBuilder::Debug::frames() { - FrameAndroid* frame = frameAnd(); - Document* doc = frame->document(); - if (doc == NULL) - return; - bool top = frame->tree()->parent() == NULL; - if (top) { -#ifdef DUMP_NAV_CACHE_USING_PRINTF - gWriteLogMutex.lock(); - ASSERT(gNavCacheLogFile == NULL); - gNavCacheLogFile = fopen(NAV_CACHE_LOG_FILE, "a"); -#endif - groups(); - } - Frame* child = frame->tree()->firstChild(); - bool hasChild = child != NULL; - if (top && hasChild) - DUMP_NAV_LOGD("\nnamespace TEST_SPACE {\n\n"); - while (child) { - Builder(child)->mDebug.frames(); - child = child->tree()->nextSibling(); - } - if (hasChild) { - child = frame->tree()->firstChild(); - while (child) { - char childName[256]; - char* childNamePtr = childName; - Builder(child)->mDebug.frameName(childNamePtr, childNamePtr + sizeof(childName) - 1); - *childNamePtr = '\0'; - if (child == frame->tree()->firstChild()) - DUMP_NAV_LOGD("DebugTestFrameGroup TEST%s_GROUP[] = {\n", childName); - Frame* next = child->tree()->nextSibling(); - Document* doc = child->document(); - if (doc != NULL) { - RenderObject* renderer = doc->renderer(); - if (renderer != NULL) { - RenderLayer* layer = renderer->enclosingLayer(); - if (layer != NULL) { - DUMP_NAV_LOGD("{ "); - DUMP_NAV_LOGD("TEST%s_RECTS, ", childName); - DUMP_NAV_LOGD("TEST%s_RECT_COUNT, ", childName); - DUMP_NAV_LOGD("TEST%s_RECTPARTS, ", childName); - DUMP_NAV_LOGD("TEST%s_BOUNDS,\n", childName); - DUMP_NAV_LOGD("TEST%s_WIDTH, ", childName); - DUMP_NAV_LOGD("TEST%s_HEIGHT,\n", childName); - DUMP_NAV_LOGD("0, 0, 0, 0,\n"); - DUMP_NAV_LOGD("TEST%s_FOCUS, ", childName); - Frame* grandChild = child->tree()->firstChild(); - if (grandChild) { - char grandChildName[256]; - char* grandChildNamePtr = grandChildName; - Builder(grandChild)->mDebug.frameName(grandChildNamePtr, - grandChildNamePtr + sizeof(grandChildName) - 1); - *grandChildNamePtr = '\0'; - DUMP_NAV_LOGD("TEST%s_GROUP, ", grandChildName); - DUMP_NAV_LOGD("sizeof(TEST%s_GROUP) / sizeof(DebugTestFrameGroup), ", grandChildName); - } else - DUMP_NAV_LOGD("NULL, 0, "); - DUMP_NAV_LOGD("\"%s\"\n", childName); - DUMP_NAV_LOGD("}%c\n", next ? ',' : ' '); - } - } - } - child = next; - } - DUMP_NAV_LOGD("};\n"); - } - if (top) { - if (hasChild) - DUMP_NAV_LOGD("\n} // end of namespace\n\n"); - char name[256]; - char* frameNamePtr = name; - frameName(frameNamePtr, frameNamePtr + sizeof(name) - 1); - *frameNamePtr = '\0'; - DUMP_NAV_LOGD("DebugTestFrameGroup TEST%s_GROUP = {\n", name); - DUMP_NAV_LOGD("TEST%s_RECTS, ", name); - DUMP_NAV_LOGD("TEST%s_RECT_COUNT, ", name); - DUMP_NAV_LOGD("TEST%s_RECTPARTS, ", name); - DUMP_NAV_LOGD("TEST%s_BOUNDS,\n", name); - DUMP_NAV_LOGD("TEST%s_WIDTH, ", name); - DUMP_NAV_LOGD("TEST%s_HEIGHT,\n", name); - DUMP_NAV_LOGD("TEST%s_MAX_H, ", name); - DUMP_NAV_LOGD("TEST%s_MIN_H, ", name); - DUMP_NAV_LOGD("TEST%s_MAX_V, ", name); - DUMP_NAV_LOGD("TEST%s_MIN_V,\n", name); - DUMP_NAV_LOGD("TEST%s_FOCUS, ", name); - if (hasChild) { - child = frame->tree()->firstChild(); - char childName[256]; - char* childNamePtr = childName; - Builder(child)->mDebug.frameName(childNamePtr, childNamePtr + sizeof(childName) - 1); - *childNamePtr = '\0'; - DUMP_NAV_LOGD("TEST_SPACE::TEST%s_GROUP, ", childName); - DUMP_NAV_LOGD("sizeof(TEST_SPACE::TEST%s_GROUP) / sizeof(DebugTestFrameGroup), \n" ,childName); - } else - DUMP_NAV_LOGD("NULL, 0, "); - DUMP_NAV_LOGD("\"%s\"\n", name); - DUMP_NAV_LOGD("};\n"); -#ifdef DUMP_NAV_CACHE_USING_PRINTF - if (gNavCacheLogFile) - fclose(gNavCacheLogFile); - gNavCacheLogFile = NULL; - gWriteLogMutex.unlock(); -#endif - } -} - -void CacheBuilder::Debug::init(char* buffer, size_t size) { - mBuffer = buffer; - mBufferSize = size; - mIndex = 0; - mPrefix = ""; -} - -void CacheBuilder::Debug::groups() { - FrameAndroid* frame = frameAnd(); - Frame* child = frame->tree()->firstChild(); - bool hasChild = child != NULL; - if (frame->tree()->parent() == NULL && hasChild) - DUMP_NAV_LOGD("namespace TEST_SPACE {\n\n"); - while (child) { - Builder(child)->mDebug.groups(); - child = child->tree()->nextSibling(); - } - if (frame->tree()->parent() == NULL && hasChild) - DUMP_NAV_LOGD("\n} // end of namespace\n\n"); - Document* doc = frame->document(); - char name[256]; - char* frameNamePtr = name; - frameName(frameNamePtr, frameNamePtr + sizeof(name) - 1); - *frameNamePtr = '\0'; - if (doc == NULL) { - DUMP_NAV_LOGD("// %s has no document\n", name); - return; - } - RenderObject* renderer = doc->renderer(); - if (renderer == NULL) { - DUMP_NAV_LOGD("// %s has no renderer\n", name); - return; - } - RenderLayer* layer = renderer->enclosingLayer(); - if (layer == NULL) { - DUMP_NAV_LOGD("// %s has no enclosingLayer\n", name); - return; - } - Node* node = doc; - Node* focus = doc->focusedNode(); - bool atLeastOne = false; - do { - if ((atLeastOne |= isFocusable(node)) != false) - break; - } while ((node = node->traverseNextNode()) != NULL); - int focusIndex = -1; - if (atLeastOne == false) { - DUMP_NAV_LOGD("#define TEST%s_RECTS NULL\n", name); - DUMP_NAV_LOGD("static int TEST%s_RECT_COUNT = 0; // no focusable nodes\n", name); - DUMP_NAV_LOGD("#define TEST%s_RECTPARTS NULL\n", name); - } else { - node = doc; - int count = 1; - DUMP_NAV_LOGD("static DebugTestNode TEST%s_RECTS[] = {\n", name); - do { - String properties; - EventTargetNode* elementTarget = node->isEventTargetNode() ? - (EventTargetNode*) node : NULL; - if (elementTarget) { - if (elementTarget->getEventListener(EventNames::clickEvent)) - properties.append("ONCLICK | "); - if (elementTarget->getEventListener(EventNames::mousedownEvent)) - properties.append("MOUSEDOWN | "); - if (elementTarget->getEventListener(EventNames::mouseupEvent)) - properties.append("MOUSEUP | "); - if (elementTarget->getEventListener(EventNames::mouseoverEvent)) - properties.append("MOUSEOVER | "); - if (elementTarget->getEventListener(EventNames::mouseoutEvent)) - properties.append("MOUSEOUT | "); - if (elementTarget->getEventListener(EventNames::keydownEvent)) - properties.append("KEYDOWN | "); - if (elementTarget->getEventListener(EventNames::keyupEvent)) - properties.append("KEYUP | "); - } - if (CacheBuilder::HasFrame(node)) - properties.append("FRAME | "); - if (focus == node) { - properties.append("FOCUS | "); - focusIndex = count; - } - if (node->isKeyboardFocusable(NULL)) - properties.append("KEYBOARD_FOCUSABLE | "); - if (node->isMouseFocusable()) - properties.append("MOUSE_FOCUSABLE | "); - if (node->isFocusable()) - properties.append("SIMPLE_FOCUSABLE | "); - if (properties.isEmpty()) - properties.append("0"); - else - properties.truncate(properties.length() - 3); - IntRect rect = node->getRect(); - if (node->hasTagName(HTMLNames::areaTag)) - rect = static_cast<HTMLAreaElement*>(node)->getAreaRect(); - char buffer[DEBUG_BUFFER_SIZE]; - memset(buffer, 0, sizeof(buffer)); - mBuffer = buffer; - mBufferSize = sizeof(buffer); - mPrefix = "\"\n\""; - mIndex = snprintf(buffer, sizeof(buffer), "{{%d, %d, %d, %d}, ", rect.x(), rect.y(), - rect.width(), rect.height()); - localName(node); - uChar(properties.characters(), properties.length(), false); - print(", "); - int parentIndex = ParentIndex(node, count, node->parentNode()); - char scratch[256]; - snprintf(scratch, sizeof(scratch), "%d", parentIndex); - comma(scratch); - Element* element = static_cast<Element*>(node); - if (node->isElementNode() && element->hasID()) - wideString(element->getIDAttribute()); - else if (node->isTextNode()) { - #if 01 // set to one to abbreviate text that can be omitted from the address detection code - if (rect.isEmpty() && node->textContent().length() > 100) { - wideString(node->textContent().characters(), 100, false); - snprintf(scratch, sizeof(scratch), "/* + %d bytes */", - node->textContent().length() - 100); - print(scratch); - } else - #endif - wideString(node->textContent().characters(), node->textContent().length(), true); - } else if (node->hasTagName(HTMLNames::aTag) || - node->hasTagName(HTMLNames::areaTag)) - { - HTMLAnchorElement* anchor = static_cast<HTMLAnchorElement*>(node); - wideString(anchor->href()); - } else if (node->hasTagName(HTMLNames::imgTag)) { - HTMLImageElement* image = static_cast<HTMLImageElement*>(node); - wideString(image->src()); - } else - print("\"\""); - RenderObject* renderer = node->renderer(); - if (renderer) { - const IntRect& absB = renderer->absoluteBoundingBoxRect(); - snprintf(scratch, sizeof(scratch), ", {%d, %d, %d, %d}, %s},", - absB.x(), absB.y(), absB.width(), absB.height(), - renderer->hasOverflowClip() ? "true" : "false"); - print(scratch); - } else - print(", {0, 0, 0, 0}, false},"); - flush(); - snprintf(scratch, sizeof(scratch), "// %d: ", count); - mPrefix = "\n// "; - print(scratch); - //print(renderer ? renderer->information().ascii() : "NO_RENDER_INFO"); - if (node->isElementNode()) { - Element* element = static_cast<Element*>(node); - NamedAttrMap* attrs = element->attributes(); - unsigned length = attrs->length(); - if (length > 0) { - newLine(); - print("// attr: "); - for (unsigned i = 0; i < length; i++) { - Attribute* a = attrs->attributeItem(i); - attr(a->localName(), a->value()); - } - } - } - if (renderer) - renderTree(renderer, 0, node, count); - count++; - newLine(); - } while ((node = node->traverseNextNode()) != NULL); - DUMP_NAV_LOGD("}; // focusables = %d\n", count - 1); - DUMP_NAV_LOGD("\n"); - DUMP_NAV_LOGD("static int TEST%s_RECT_COUNT = %d;\n\n", name, count - 1); - // look for rects with multiple parts - node = doc; - count = 1; - bool hasRectParts = false; - int globalOffsetX, globalOffsetY; - GetGlobalOffset(frame, &globalOffsetX, &globalOffsetY); - do { - IntRect rect; - bool _isFocusable = isFocusable(node) || (node->isTextNode() - && node->getRect().isEmpty() == false - ); - int nodeIndex = count++; - if (_isFocusable == false) - continue; - RenderObject* renderer = node->renderer(); - if (renderer == NULL) - continue; - WTF::Vector<IntRect> rects; - IntRect clipBounds = IntRect(0, 0, INT_MAX, INT_MAX); - IntRect focusBounds = IntRect(0, 0, INT_MAX, INT_MAX); - IntRect* rectPtr = &focusBounds; - if (node->isTextNode()) { - Text* textNode = (Text*) node; - if (CacheBuilder::ConstructTextRects(textNode, 0, textNode, - INT_MAX, globalOffsetX, globalOffsetY, rectPtr, - clipBounds, &rects) == false) - continue; - } else { - IntRect nodeBounds = node->getRect(); - if (CacheBuilder::ConstructPartRects(node, nodeBounds, rectPtr, - globalOffsetX, globalOffsetY, &rects) == false) - continue; - } - unsigned arraySize = rects.size(); - if (arraySize > 1 || (arraySize == 1 && (rectPtr->width() != rect.width())) || - rectPtr->height() != rect.height()) { - if (hasRectParts == false) { - DUMP_NAV_LOGD("static DebugTestRectPart TEST%s_RECTPARTS[] = {\n", name); - hasRectParts = true; - } - if (node->isTextNode() == false) { - unsigned rectIndex = 0; - for (; rectIndex < arraySize; rectIndex++) { - rectPtr = &rects.at(rectIndex); - DUMP_NAV_LOGD("{ %d, %d, %d, %d, %d }, // %d\n", nodeIndex, - rectPtr->x(), rectPtr->y(), rectPtr->width(), - rectPtr->height(), rectIndex + 1); - } - } else { - RenderText* renderText = (RenderText*) node->renderer(); - InlineTextBox* textBox = renderText->firstTextBox(); - unsigned rectIndex = 0; - while (textBox) { - int renderX, renderY; - renderText->absolutePosition(renderX, renderY); - IntRect rect = textBox->selectionRect(renderX, renderY, 0, INT_MAX); - mIndex = 0; - mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, "{ %d, %d, %d, %d, %d", - nodeIndex, rect.x(), rect.y(), rect.width(), rect.height()); - mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, ", %d, %d, %d", - textBox->len(), textBox->selectionHeight(), textBox->selectionTop()); - mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, ", %d, %d, %d", - textBox->spaceAdd(), textBox->start(), textBox->textPos()); - mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, ", %d, %d, %d, %d", - textBox->xPos(), textBox->yPos(), textBox->width(), textBox->height()); - mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, ", %d }, // %d ", - textBox->baseline(), ++rectIndex); - wideString(node->textContent().characters() + textBox->start(), textBox->len(), true); - DUMP_NAV_LOGD("%.*s\n", mIndex, mBuffer); - textBox = textBox->nextTextBox(); - } - } - } - } while ((node = node->traverseNextNode()) != NULL); - if (hasRectParts) - DUMP_NAV_LOGD("{0}\n};\n\n"); - else - DUMP_NAV_LOGD("static DebugTestRectPart* TEST%s_RECTPARTS = NULL;\n", name); - } - int contentsWidth = layer->width(); - int contentsHeight = layer->height(); - DUMP_NAV_LOGD("static int TEST%s_FOCUS = %d;\n", name, focusIndex); - DUMP_NAV_LOGD("static int TEST%s_WIDTH = %d;\n", name, contentsWidth); - DUMP_NAV_LOGD("static int TEST%s_HEIGHT = %d;\n", name, contentsHeight); -} - -bool CacheBuilder::Debug::isFocusable(Node* node) { - if (node->hasTagName(HTMLNames::areaTag)) - return true; - if (node->renderer() == false) - return false; - if (node->isKeyboardFocusable(NULL)) - return true; - if (node->isMouseFocusable()) - return true; - if (node->isFocusable()) - return true; - if (node->isEventTargetNode()) - return true; - if (CacheBuilder::AnyIsClick(node)) - return false; - if (CacheBuilder::HasTriggerEvent(node)) - return true; - return false; -} - -void CacheBuilder::Debug::localName(Node* node) { - const AtomicString& local = node->localName(); - if (node->isTextNode()) - print("\"#text\""); - else - wideString(local.characters(), local.length(), false); - print(", "); -} - -void CacheBuilder::Debug::newLine(int indent) { - if (mPrefix[0] != '\n') - print(&mPrefix[0], 1); - flush(); - int lastnewline = mIndex - 1; - while (lastnewline >= 0 && mBuffer[lastnewline] != '\n') - lastnewline--; - lastnewline++; - char* buffer = mBuffer; - if (lastnewline > 0) { - DUMP_NAV_LOGD("%.*s", lastnewline, buffer); - mIndex -= lastnewline; - buffer += lastnewline; - } - size_t prefixLen = strlen(mPrefix); - int minPrefix = prefixLen - 1; - while (minPrefix >= 0 && mPrefix[minPrefix] != '\n') - minPrefix--; - minPrefix = prefixLen - minPrefix - 1; - if (mIndex > minPrefix) - DUMP_NAV_LOGD("%.*s\n", mIndex, buffer); - mIndex = 0; - setIndent(indent); -} - -int CacheBuilder::Debug::ParentIndex(Node* node, int count, Node* parent) -{ - if (parent == NULL) - return -1; - ASSERT(node != parent); - int result = count; - Node* previous = node; - do { - result--; - previous = previous->traversePreviousNode(); - } while (previous && previous != parent); - if (previous != NULL) - return result; - result = count; - do { - result++; - } while ((node = node->traverseNextNode()) != NULL && node != parent); - if (node != NULL) - return result; - ASSERT(0); - return -1; -} - -void CacheBuilder::Debug::print(const char* name) { - print(name, strlen(name)); -} - -void CacheBuilder::Debug::print(const char* name, unsigned len) { - do { - if (mIndex + len >= DEBUG_BUFFER_SIZE) - flush(); - int copyLen = mIndex + len < DEBUG_BUFFER_SIZE ? - len : DEBUG_BUFFER_SIZE - mIndex; - memcpy(&mBuffer[mIndex], name, copyLen); - mIndex += copyLen; - name += copyLen; - len -= copyLen; - } while (len > 0); - mBuffer[mIndex] = '\0'; -} - -void CacheBuilder::Debug::setIndent(int indent) -{ - char scratch[64]; - snprintf(scratch, sizeof(scratch), "%.*s", indent, - " "); - print(scratch); -} - -void CacheBuilder::Debug::renderTree(RenderObject* renderer, int indent, - Node* child, int count) -{ - char scratch[256]; - Node* node = renderer->node(); - if (node != child) { - count = ParentIndex(child, count, node); - if (renderer->isRenderBlock() == false) - goto tryParent; - RenderBlock* renderBlock = (RenderBlock*) renderer; - if (renderBlock->hasColumns() == false) - goto tryParent; - Vector<IntRect>* rects = renderBlock->columnRects(); - newLine(indent); - snprintf(scratch, sizeof(scratch), "// render parent=%d", count); - print(scratch); - for (size_t x = 0; x < rects->size(); x++) { - const IntRect& rect = rects->at(x); - snprintf(scratch, sizeof(scratch), "(%d,%d,%d,%d) ", rect.x(), - rect.y(), rect.width(), rect.height()); - print(scratch); - } - } - { - newLine(indent); - RenderStyle* style = renderer->style(); - EVisibility vis = style->visibility(); - ASSERT(vis == VISIBLE || vis == HIDDEN || vis == COLLAPSE); - snprintf(scratch, sizeof(scratch), - "// render style visible:%s opacity:%g width:%d height:%d" - " hasBackground:%s isInlineFlow:%s isBlockFlow:%s" - " textOverflow:%s", - vis == VISIBLE ? "visible" : vis == HIDDEN ? "hidden" : "collapse", - style->opacity(), renderer->width(), renderer->height(), - style->hasBackground() ? "true" : "false", - renderer->isInlineFlow() ? "true" : "false", - renderer->isBlockFlow() ? "true" : "false", - style->textOverflow() ? "true" : "false" - ); - print(scratch); - newLine(indent); - const IntRect& oRect = renderer->overflowRect(true); - const IntRect& cRect = renderer->getOverflowClipRect(0,0); - snprintf(scratch, sizeof(scratch), - "// render xPos:%d yPos:%d overflowRect:{%d, %d, %d, %d} " - " getOverflowClipRect:{%d, %d, %d, %d} ", - renderer->xPos(), renderer->yPos(), - oRect.x(), oRect.y(), oRect.width(), oRect.height(), - cRect.x(), cRect.y(), cRect.width(), cRect.height() - ); - print(scratch); - if (renderer->isInlineFlow()) { - RenderFlow* renderFlow = (RenderFlow*) renderer; - int ifIndex = 0; - flowBoxes(renderFlow, ifIndex, 0); - } - } -tryParent: - RenderObject* parent = renderer->parent(); - if (parent) - renderTree(parent, indent + 2, node, count); -} - -void CacheBuilder::Debug::uChar(const UChar* name, unsigned len, bool hex) { - const UChar* end = name + len; - bool wroteHex = false; - while (name < end) { - unsigned ch = *name++; - if (ch == '\t' || ch == '\n' || ch == '\r' || ch == 0xa0) - ch = ' '; - if (ch < ' ' || ch == 0x7f) { - if (hex) { - mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, "\\x%02x", ch); - wroteHex = true; - } else - mBuffer[mIndex++] = '?'; - } else if (ch >= 0x80) { - if (hex) { - if (ch < 0x800) - mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, - "\\x%02x\\x%02x", ch >> 6 | 0xc0, (ch & 0x3f) | 0x80); - else - mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, - "\\x%02x\\x%02x\\x%02x", ch >> 12 | 0xe0, - (ch >> 6 & 0x3f) | 0x80, (ch & 0x3f) | 0x80); - wroteHex = true; - } else - mBuffer[mIndex++] = '?'; - } else { - if (wroteHex && WTF::isASCIIHexDigit((UChar) ch)) - mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, - "\" \""); - else if (ch == '"' || ch == '\\') - mBuffer[mIndex++] = '\\'; - mBuffer[mIndex++] = ch; - wroteHex = false; - } - if (mIndex + 1 >= DEBUG_BUFFER_SIZE) - flush(); - } - flush(); -} - -void CacheBuilder::Debug::validateFrame() { - FrameAndroid* frame = frameAnd(); - android::WebCoreFrameBridge* bridge = frame->bridge(); - ASSERT(bridge); - WebCoreViewBridge* vbridge = frame->view()->getWebCoreViewBridge(); - ASSERT(vbridge); - Page* page = frame->page(); - ASSERT(page); - ASSERT((int) page > 0x10000); - Frame* child = frame->tree()->firstChild(); - while (child) { - Builder(child)->mDebug.validateFrame(); - child = child->tree()->nextSibling(); - } -} - -void CacheBuilder::Debug::wideString(const UChar* chars, int length, bool hex) { - if (length == 0) - print("\"\""); - else { - print("\""); - uChar(chars, length, hex); - print("\""); - } -} - -void CacheBuilder::Debug::wideString(const String& str) { - wideString(str.characters(), str.length(), false); -} - -#endif // DUMP_NAV_CACHE - -CacheBuilder::CacheBuilder() -{ - mLastKnownFocus = NULL; - mAllowableTypes = android::ALL_CACHEDNODETYPES; -#ifdef DUMP_NAV_CACHE_USING_PRINTF - gNavCacheLogFile = NULL; -#endif -} - -void CacheBuilder::adjustForColumns(const ClipColumnTracker& track, - android::CachedNode* node, IntRect* bounds) -{ - int x = 0; - int y = 0; - int tx = track.mBounds.x(); - int ty = track.mBounds.y(); - int columnGap = track.mColumnGap; - size_t limit = track.mColumns->size(); - for (size_t index = 0; index < limit; index++) { - IntRect column = track.mColumns->at(index); - column.move(tx, ty); - IntRect test = *bounds; - test.move(x, y); - if (column.contains(test)) { - if ((x | y) == 0) - return; - *bounds = test; - node->move(x, y); - return; - } - int xOffset = column.width() + columnGap; - x += track.mDirection == LTR ? xOffset : -xOffset; - y -= column.height(); - } -} - -bool CacheBuilder::AnyChildIsClick(Node* node) -{ - Node* child = node->firstChild(); - while (child != NULL) { - if (child->isEventTargetNode()) { - EventTargetNode* target = (EventTargetNode*) child; - if (target->isFocusable() || - target->getEventListener(EventNames::clickEvent) || - target->getEventListener(EventNames::mousedownEvent) || - target->getEventListener(EventNames::mouseupEvent) || - target->getEventListener(EventNames::keydownEvent) || - target->getEventListener(EventNames::keyupEvent)) - return true; - } - if (AnyChildIsClick(child)) - return true; - child = child->nextSibling(); - } - return false; -} - -bool CacheBuilder::AnyIsClick(Node* node) -{ - if (node->hasTagName(HTMLNames::bodyTag)) - return AnyChildIsClick(node); - EventTargetNode* target = (EventTargetNode*) node; - if (target->getEventListener(EventNames::mouseoverEvent) == NULL && - target->getEventListener(EventNames::mouseoutEvent) == NULL && - target->getEventListener(EventNames::keydownEvent) == NULL && - target->getEventListener(EventNames::keyupEvent) == NULL) - return false; - if (target->getEventListener(EventNames::clickEvent)) - return false; - if (target->getEventListener(EventNames::mousedownEvent)) - return false; - if (target->getEventListener(EventNames::mouseupEvent)) - return false; - return AnyChildIsClick(node); -} - -void CacheBuilder::buildCache(android::CachedRoot* root) -{ - FrameAndroid* frame = FrameAnd(this); - mLastKnownFocus = NULL; - BuildFrame(frame, frame, root, (android::CachedFrame*) root); - root->finishInit(); // set up frame parent pointers, child pointers - setData((android::CachedFrame*) root); -} - -static Node* OneAfter(Node* node) -{ - Node* parent = node; - Node* sibling = NULL; - while ((parent = parent->parentNode()) != NULL) { - sibling = parent->nextSibling(); - if (sibling != NULL) - break; - } - return sibling; -} - -// when new focus is found, push it's parent on a stack - // as long as more focii are found with the same (grand) parent, note it - // (which only requires retrieving the last parent on the stack) -// when the parent's last child is found, pop the stack -// different from Tracker in that Tracker only pushes focii with children - -// making this work with focus - child focus - grandchild focus is tricky -// if I keep the generation number, I may be able to more quickly determine that -// a node is a grandchild of the focus's parent -// this additionally requires being able to find the grandchild's parent - -// keep nodes that are focusable -void CacheBuilder::BuildFrame(FrameAndroid* root, FrameAndroid* frame, - android::CachedRoot* cachedRoot, android::CachedFrame* cachedFrame) -{ - WTF::Vector<Tracker> tracker(1); - { - Tracker* baseTracker = tracker.data(); // sentinel - bzero(baseTracker, sizeof(Tracker)); - baseTracker->mCachedNodeIndex = -1; - } - WTF::Vector<ClipColumnTracker> clipTracker(1); - { - ClipColumnTracker* baseTracker = clipTracker.data(); // sentinel - bzero(baseTracker, sizeof(ClipColumnTracker)); - } -#if DUMP_NAV_CACHE - char* frameNamePtr = cachedFrame->mDebug.mFrameName; - Builder(frame)->mDebug.frameName(frameNamePtr, frameNamePtr + - sizeof(cachedFrame->mDebug.mFrameName) - 1); - *frameNamePtr = '\0'; - int nodeIndex = 1; -#endif - NodeWalk walk; - Document* doc = frame->document(); - Node* parent = doc; - android::CachedNode cachedParentNode; - cachedParentNode.init(cachedFrame, parent); -#if DUMP_NAV_CACHE - cachedParentNode.mDebug.mNodeIndex = nodeIndex; -#endif - cachedFrame->add(cachedParentNode); - Node* node = parent; - int cacheIndex = 1; - Node* focused = doc->focusedNode(); - if (focused) - setLastFocus(focused); - int globalOffsetX, globalOffsetY; - GetGlobalOffset(frame, &globalOffsetX, &globalOffsetY); - while (walk.mMore || (node = node->traverseNextNode()) != NULL) { -#if DUMP_NAV_CACHE - nodeIndex++; -#endif - Tracker* last = &tracker.last(); - int lastChildIndex = cachedFrame->size() - 1; - while (node == last->mLastChild) { - if (CleanUpContainedNodes(cachedFrame, last, lastChildIndex)) - cacheIndex--; - tracker.removeLast(); - lastChildIndex = last->mCachedNodeIndex; - last = &tracker.last(); - } - if (node == last->mParentLastChild) - last->mParentLastChild = NULL; - do { - const ClipColumnTracker* lastClip = &clipTracker.last(); - if (node != lastClip->mLastChild) - break; - clipTracker.removeLast(); - } while (true); - Frame* child = HasFrame(node); - android::CachedNode cachedNode; - if (child != NULL) { - if (child->document() == NULL) - continue; - RenderObject* nodeRenderer = node->renderer(); - if (nodeRenderer != NULL && nodeRenderer->style()->visibility() == HIDDEN) - continue; - android::CachedFrame cachedChild; - cachedChild.init(cachedRoot, cacheIndex, Android(child)); - int childFrameIndex = cachedFrame->childCount(); - cachedFrame->addFrame(cachedChild); - cachedNode.init(cachedFrame, node); - cachedNode.setIndex(cacheIndex++); - cachedNode.setChildFrameIndex(childFrameIndex); -#if DUMP_NAV_CACHE - cachedNode.mDebug.mNodeIndex = nodeIndex; - cachedNode.mDebug.mParentGroupIndex = Debug::ParentIndex( - node, nodeIndex, NULL); -#endif - cachedFrame->add(cachedNode); - android::CachedFrame* childPtr = cachedFrame->lastChild(); - BuildFrame(root, Android(child), cachedRoot, childPtr); - continue; - } - RenderObject* nodeRenderer = node->renderer(); - bool isTransparent = false; - bool hasFocusRing = true; - if (nodeRenderer != NULL) { - RenderStyle* style = nodeRenderer->style(); - if (style->visibility() == HIDDEN) - continue; - if (nodeRenderer->isImage()) { // set all the area elements to have a link to their images - RenderImage* image = static_cast<RenderImage*>(nodeRenderer); - image->setImageForAreaElements(); - } - isTransparent = style->hasBackground() == false; - hasFocusRing = style->tapHighlightColor().alpha() > 0; - } - bool more = walk.mMore; - walk.reset(); - // GetGlobalBounds(node, &bounds, false); - bool anchorHasSrcUrl = false; - bool computeFocusRings = false; - bool hasClip = false; - bool hasMouseOver = false; - bool isAnchor = false; - bool isArea = node->hasTagName(HTMLNames::areaTag); - bool isInput = false; - bool isPassword = false; - bool isTextArea = false; - bool isTextField = false; - bool isRtlText = false; - bool isUnclipped = false; - bool isFocus = node == focused; - bool takesFocus = false; - int maxLength = -1; - int textSize = 12; - int columnGap = 0; - TextDirection direction = LTR; - String name; - String exported; - android::CachedNodeType type = android::NORMAL_CACHEDNODETYPE; - IntRect bounds; - IntRect absBounds; - Node* lastChild = node->lastChild(); - WTF::Vector<IntRect>* columns = NULL; - if (isArea) { - HTMLAreaElement* area = static_cast<HTMLAreaElement*>(node); - bounds = area->getAreaRect(); - bounds.move(globalOffsetX, globalOffsetY); - absBounds = bounds; - isUnclipped = true; // FIXME: areamaps require more effort to detect - // assume areamaps are always visible for now - takesFocus = true; - goto keepNode; - } - if (nodeRenderer == NULL) - continue; - absBounds = nodeRenderer->absoluteBoundingBoxRect(); - absBounds.move(globalOffsetX, globalOffsetY); - hasClip = nodeRenderer->hasOverflowClip(); - if (nodeRenderer->isRenderBlock()) { - RenderBlock* renderBlock = (RenderBlock*) nodeRenderer; - if (renderBlock->hasColumns()) { - columns = renderBlock->columnRects(); - columnGap = renderBlock->columnGap(); - direction = renderBlock->style()->direction(); - } - } - if ((hasClip != false || columns != NULL) && lastChild) { - clipTracker.grow(clipTracker.size() + 1); - ClipColumnTracker& clip = clipTracker.last(); - clip.mBounds = absBounds; - clip.mLastChild = OneAfter(lastChild); - clip.mNode = node; - clip.mColumns = columns; - clip.mColumnGap = columnGap; - clip.mHasClip = hasClip; - clip.mDirection = direction; - if (columns != NULL) { - const IntRect& oRect = nodeRenderer->overflowRect(true); - clip.mBounds.move(oRect.x(), oRect.y()); - } - } - if (node->isTextNode() && mAllowableTypes != android::NORMAL_CACHEDNODETYPE) { - if (last->mSomeParentTakesFocus) // don't look at text inside focusable node - continue; - android::CachedNodeType checkType; - if (isFocusableText(&walk, more, node, &checkType, - &exported) == false) - continue; - #if DUMP_NAV_CACHE - { - char buffer[DEBUG_BUFFER_SIZE]; - mDebug.init(buffer, sizeof(buffer)); - mDebug.print("text link found: "); - mDebug.wideString(exported); - DUMP_NAV_LOGD("%s\n", buffer); - } - #endif - type = (android::CachedNodeType) checkType; - // !!! test ! is the following line correctly needed for frames to work? - cachedNode.init(cachedFrame, node); - const ClipColumnTracker& clipTrack = clipTracker.last(); - const IntRect& clip = clipTrack.mHasClip ? clipTrack.mBounds : - IntRect(0, 0, INT_MAX, INT_MAX); - if (ConstructTextRects((WebCore::Text*) node, walk.mStart, - (WebCore::Text*) walk.mFinalNode, walk.mEnd, globalOffsetX, - globalOffsetY, &bounds, clip, &cachedNode.focusRings()) == false) - continue; - cachedNode.setBounds(bounds); - if (bounds.width() < MINIMUM_FOCUSABLE_WIDTH) - continue; - if (bounds.height() < MINIMUM_FOCUSABLE_HEIGHT) - continue; - computeFocusRings = true; - isUnclipped = true; // FIXME: to hide or partially occlude synthesized links, each - // focus ring will also need the offset and length of characters - // used to produce it - goto keepTextNode; - } - if (node->hasTagName(WebCore::HTMLNames::inputTag)) { - HTMLInputElement* input = (HTMLInputElement*) node; - if (input->inputType() == HTMLInputElement::FILE) - continue; - isInput = true; - isTextField = input->isTextField(); - isPassword = input->inputType() == HTMLInputElement::PASSWORD; - maxLength = input->maxLength(); - name = String(input->name().domString()); - isUnclipped = isTransparent; // can't detect if this is drawn on top (example: deviant.com login parts) - } else if (node->hasTagName(HTMLNames::textareaTag)) - isTextArea = true; - else if (node->hasTagName(HTMLNames::aTag)) { - EventTargetNode* target = (EventTargetNode*) node; - hasMouseOver = target->getEventListener(EventNames::mouseoverEvent); - isAnchor = true; - String href = ((HTMLAnchorElement*) node)->href(); -#ifdef ANDROID_JAVASCRIPT_SECURITY - anchorHasSrcUrl = !href.isEmpty() && !WebCore::protocolIs(href, "javascript"); - // Set the exported string for protocols that we know will not be - // handled by WebCore. - if (WebCore::protocolIs(href, "mailto") || - WebCore::protocolIs(href, "tel") || - WebCore::protocolIs(href, "geo")) - exported = String(KURL::decode_string(href.deprecatedString())); -#endif - } - if (isTextField || isTextArea) { - RenderTextControl* renderText = - static_cast<RenderTextControl*>(nodeRenderer); - if (isFocus) - cachedRoot->setSelection(renderText->selectionStart(), renderText->selectionEnd()); - exported = String(renderText->text()); - // FIXME: Would it be better to use (float) size()? - // FIXME: Are we sure there will always be a style and font, and it's correct? - RenderStyle* style = nodeRenderer->style(); - if (style) { - textSize = style->fontSize(); - isRtlText = style->direction() == RTL; - } - } - takesFocus = true; - if (isAnchor) { - bounds = absBounds; - } else { - bool isFocusable = node->isKeyboardFocusable(NULL) || - node->isMouseFocusable() || node->isFocusable(); - if (isFocusable == false) { - if (node->isEventTargetNode() == false) - continue; - bool overOrOut = HasOverOrOut(node); - bool hasTrigger = HasTriggerEvent(node); - if (overOrOut == false && hasTrigger == false) - continue; - takesFocus = hasTrigger; - } - bounds = node->getRect(); - // For Bank of America site - if (isTextField && nodeRenderer->paddingLeft() > 100) { - int paddingLeft = nodeRenderer->paddingLeft(); - int paddingTop = nodeRenderer->paddingTop(); - int x = bounds.x() + paddingLeft; - int y = bounds.y() + paddingTop; - int width = bounds.width() - paddingLeft - nodeRenderer->paddingRight(); - int height = bounds.height() - paddingTop - nodeRenderer->paddingBottom(); - bounds.setLocation(IntPoint(x, y)); - bounds.setSize(IntSize(width, height)); - } - if (bounds.width() < MINIMUM_FOCUSABLE_WIDTH) - continue; - if (bounds.height() < MINIMUM_FOCUSABLE_HEIGHT) - continue; - bounds.move(globalOffsetX, globalOffsetY); - } - computeFocusRings = true; - keepNode: - cachedNode.init(cachedFrame, node); - if (computeFocusRings == false) { - cachedNode.setBounds(bounds); - cachedNode.focusRings().append(bounds); - } else if (ConstructPartRects(node, bounds, cachedNode.boundsPtr(), - globalOffsetX, globalOffsetY, &cachedNode.focusRings()) == false) - continue; - keepTextNode: - IntRect clip = hasClip ? bounds : absBounds; - size_t clipIndex = clipTracker.size(); - if (clipTracker.last().mNode == node) - clipIndex -= 1; - while (--clipIndex > 0) { - const ClipColumnTracker& clipTrack = clipTracker.at(clipIndex); - if (clipTrack.mHasClip == false) { - adjustForColumns(clipTrack, &cachedNode, &absBounds); - continue; - } - const IntRect& parentClip = clipTrack.mBounds; - if (hasClip == false && isAnchor) - clip = parentClip; - else - clip.intersect(parentClip); - hasClip = true; - DBG_NAV_LOGD("absBounds={%d,%d,%d,%d} parentClip={%d,%d,%d,%d}\n", - absBounds.x(), absBounds.y(), absBounds.width(), absBounds.height(), - parentClip.x(), parentClip.y(), parentClip.width(), parentClip.height()); - } - if (hasClip && cachedNode.clip(clip) == false) { - cachedNode.setBounds(clip); - cachedNode.focusRings().append(clip); - isUnclipped = true; - } - cachedNode.setNavableRects(); - cachedNode.setAnchorHasSrcUrl(anchorHasSrcUrl); - cachedNode.setChildFrameIndex(-1); - cachedNode.setExport(exported); - cachedNode.setHasFocusRing(hasFocusRing); - cachedNode.setHasMouseOver(hasMouseOver); - cachedNode.setHitBounds(absBounds); - cachedNode.setIndex(cacheIndex); - cachedNode.setIsAnchor(isAnchor); - cachedNode.setIsArea(isArea); - cachedNode.setIsFocus(isFocus); - cachedNode.setIsInput(isInput); - cachedNode.setIsPassword(isPassword); - cachedNode.setIsRtlText(isRtlText); - cachedNode.setIsTextArea(isTextArea); - cachedNode.setIsTextField(isTextField); - cachedNode.setIsTransparent(isTransparent); - cachedNode.setIsUnclipped(isUnclipped); - cachedNode.setMaxLength(maxLength); - cachedNode.setName(name); - cachedNode.setParentIndex(last->mCachedNodeIndex); - if (last->mParentLastChild == NULL) - last->mParentLastChild = OneAfter(node->parentNode()->lastChild()); - cachedNode.setParentGroup(last->mParentLastChild); - cachedNode.setTextSize(textSize); - cachedNode.setType(type); -#if DUMP_NAV_CACHE - cachedNode.mDebug.mNodeIndex = nodeIndex; - cachedNode.mDebug.mParentGroupIndex = Debug::ParentIndex( - node, nodeIndex, (Node*) cachedNode.parentGroup()); -#endif - cachedFrame->add(cachedNode); - { - int lastIndex = cachedFrame->size() - 1; - if (node == focused) { - android::CachedNode* cachedNodePtr = cachedFrame->getIndex(lastIndex); - cachedRoot->setCachedFocus(cachedFrame, cachedNodePtr); - } - if (lastChild != NULL) { - tracker.grow(tracker.size() + 1); - Tracker& working = tracker.last(); - working.mCachedNodeIndex = lastIndex; - working.mLastChild = OneAfter(lastChild); - working.mParentLastChild = OneAfter(node->parentNode()->lastChild()); - last = &tracker.at(tracker.size() - 2); - working.mSomeParentTakesFocus = last->mSomeParentTakesFocus | takesFocus; - } - } - cacheIndex++; -tryNextNode: - ; - } - while (tracker.size() > 1) { - Tracker* last = &tracker.last(); - int lastChildIndex = cachedFrame->size() - 1; - if (CleanUpContainedNodes(cachedFrame, last, lastChildIndex)) - cacheIndex--; - tracker.removeLast(); - } -} - -bool CacheBuilder::CleanUpContainedNodes(android::CachedFrame* cachedFrame, - const Tracker* last, int lastChildIndex) -{ - // if outer is body, disable outer - // or if there's more than one inner, disable outer - // or if inner is keyboard focusable, disable outer - // else disable inner by removing it - int childCount = lastChildIndex - last->mCachedNodeIndex; - if (childCount == 0) - return false; - android::CachedNode* lastCached = cachedFrame->getIndex(last->mCachedNodeIndex); - Node* lastNode = (Node*) lastCached->nodePointer(); - if ((childCount > 1 && lastNode->hasTagName(HTMLNames::selectTag) == false) || - lastNode->hasTagName(HTMLNames::bodyTag) || - lastNode->hasTagName(HTMLNames::formTag)) { - lastCached->setBounds(IntRect(0, 0, 0, 0)); - lastCached->focusRings().clear(); - lastCached->setNavableRects(); - return false; - } - android::CachedNode* onlyChildCached = cachedFrame->lastNode(); - Node* onlyChild = (Node*) onlyChildCached->nodePointer(); - bool outerIsMouseMoveOnly = - lastNode->isKeyboardFocusable(NULL) == false && - lastNode->isMouseFocusable() == false && - lastNode->isFocusable() == false && - lastNode->isEventTargetNode() == true && - HasOverOrOut(lastNode) == true && - HasTriggerEvent(lastNode) == false; - if (cachedFrame->focusIndex() == lastChildIndex) - cachedFrame->setFocusIndex(last->mCachedNodeIndex); - if (onlyChildCached->parent() == lastCached) - onlyChildCached->setParentIndex(lastCached->parentIndex()); - if (outerIsMouseMoveOnly || onlyChild->isKeyboardFocusable(NULL)) - *lastCached = *onlyChildCached; - cachedFrame->removeLast(); - return true; -} - -Node* CacheBuilder::currentFocus() const -{ - Frame* frame = FrameAnd(this); - Document* doc = frame->document(); - if (doc != NULL) { - Node* focus = doc->focusedNode(); - if (focus != NULL) - return focus; - } - Frame* child = frame->tree()->firstChild(); - while (child) { - CacheBuilder* cacheBuilder = Builder(child); - Node* focus = cacheBuilder->currentFocus(); - if (focus) - return focus; - child = child->tree()->nextSibling(); - } - return NULL; -} - -static bool strCharCmp(const char* matches, const UChar* test, int wordLength, - int wordCount) -{ - for (int index = 0; index < wordCount; index++) { - for (int inner = 0; inner < wordLength; inner++) { - if (matches[inner] != test[inner]) { - matches += wordLength; - goto next; - } - } - return true; -next: - ; - } - return false; -} - -static const int stateTwoLetter[] = { - 0x02060c00, // A followed by: [KLRSZ] - 0x00000000, // B - 0x00084001, // C followed by: [AOT] - 0x00000014, // D followed by: [CE] - 0x00000000, // E - 0x00001800, // F followed by: [LM] - 0x00100001, // G followed by: [AU] - 0x00000100, // H followed by: [I] - 0x00002809, // I followed by: [ADLN] - 0x00000000, // J - 0x01040000, // K followed by: [SY] - 0x00000001, // L followed by: [A] - 0x000ce199, // M followed by: [ADEHINOPST] - 0x0120129c, // N followed by: [CDEHJMVY] - 0x00020480, // O followed by: [HKR] - 0x00420001, // P followed by: [ARW] - 0x00000000, // Q - 0x00000100, // R followed by: [I] - 0x0000000c, // S followed by: [CD] - 0x00802000, // T followed by: [NX] - 0x00080000, // U followed by: [T] - 0x00080101, // V followed by: [AIT] - 0x01200101 // W followed by: [AIVY] -}; - -static const char firstIndex[] = { - 0, 5, 5, 8, 10, 10, 12, 14, - 15, 19, 19, 21, 22, 32, 40, 43, - 46, 46, 47, 49, 51, 52, 55, 59 -}; - -// from http://infolab.stanford.edu/~manku/bitcount/bitcount.html -#define TWO(c) (0x1u << (c)) -#define MASK(c) (((unsigned int)(-1)) / (TWO(TWO(c)) + 1u)) -#define COUNT(x,c) ((x) & MASK(c)) + (((x) >> (TWO(c))) & MASK(c)) - -int bitcount (unsigned int n) -{ - n = COUNT(n, 0); - n = COUNT(n, 1); - n = COUNT(n, 2); - n = COUNT(n, 3); - return COUNT(n, 4); -} - -#undef TWO -#undef MASK -#undef COUNT - -static bool isUnicodeSpace(UChar ch) -{ - return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == 0xa0; -} - -static bool validZip(int stateIndex, const UChar* zipPtr) -{ - static const struct { - char mLow; - char mHigh; - char mException1; - char mException2; - } zipRange[] = { - { 99, 99, -1, -1 }, // AK Alaska - { 35, 36, -1, -1 }, // AL Alabama - { 71, 72, -1, -1 }, // AR Arkansas - { 96, 96, -1, -1 }, // AS American Samoa - { 85, 86, -1, -1 }, // AZ Arizona - { 90, 96, -1, -1 }, // CA California - { 80, 81, -1, -1 }, // CO Colorado - { 6, 6, -1, -1 }, // CT Connecticut - { 20, 20, -1, -1 }, // DC District of Columbia - { 19, 19, -1, -1 }, // DE Delaware - { 32, 34, -1, -1 }, // FL Florida - { 96, 96, -1, -1 }, // FM Federated States of Micronesia - { 30, 31, -1, -1 }, // GA Georgia - { 96, 96, -1, -1 }, // GU Guam - { 96, 96, -1, -1 }, // HI Hawaii - { 50, 52, -1, -1 }, // IA Iowa - { 83, 83, -1, -1 }, // ID Idaho - { 60, 62, -1, -1 }, // IL Illinois - { 46, 47, -1, -1 }, // IN Indiana - { 66, 67, 73, -1 }, // KS Kansas - { 40, 42, -1, -1 }, // KY Kentucky - { 70, 71, -1, -1 }, // LA Louisiana - { 1, 2, -1, -1 }, // MA Massachusetts - { 20, 21, -1, -1 }, // MD Maryland - { 3, 4, -1, -1 }, // ME Maine - { 96, 96, -1, -1 }, // MH Marshall Islands - { 48, 49, -1, -1 }, // MI Michigan - { 55, 56, -1, -1 }, // MN Minnesota - { 63, 65, -1, -1 }, // MO Missouri - { 96, 96, -1, -1 }, // MP Northern Mariana Islands - { 38, 39, -1, -1 }, // MS Mississippi - { 55, 56, -1, -1 }, // MT Montana - { 27, 28, -1, -1 }, // NC North Carolina - { 58, 58, -1, -1 }, // ND North Dakota - { 68, 69, -1, -1 }, // NE Nebraska - { 3, 4, -1, -1 }, // NH New Hampshire - { 7, 8, -1, -1 }, // NJ New Jersey - { 87, 88, 86, -1 }, // NM New Mexico - { 88, 89, 96, -1 }, // NV Nevada - { 10, 14, 0, 6 }, // NY New York - { 43, 45, -1, -1 }, // OH Ohio - { 73, 74, -1, -1 }, // OK Oklahoma - { 97, 97, -1, -1 }, // OR Oregon - { 15, 19, -1, -1 }, // PA Pennsylvania - { 6, 6, 0, 9 }, // PR Puerto Rico - { 96, 96, -1, -1 }, // PW Palau - { 2, 2, -1, -1 }, // RI Rhode Island - { 29, 29, -1, -1 }, // SC South Carolina - { 57, 57, -1, -1 }, // SD South Dakota - { 37, 38, -1, -1 }, // TN Tennessee - { 75, 79, 87, 88 }, // TX Texas - { 84, 84, -1, -1 }, // UT Utah - { 22, 24, 20, -1 }, // VA Virginia - { 6, 9, -1, -1 }, // VI Virgin Islands - { 5, 5, -1, -1 }, // VT Vermont - { 98, 99, -1, -1 }, // WA Washington - { 53, 54, -1, -1 }, // WI Wisconsin - { 24, 26, -1, -1 }, // WV West Virginia - { 82, 83, -1, -1 } // WY Wyoming - }; - - int zip = zipPtr[0] - '0'; - zip *= 10; - zip += zipPtr[1] - '0'; - int low = zipRange[stateIndex].mLow; - int high = zipRange[stateIndex].mHigh; - if (zip >= low && zip <= high) - return true; - if (zip == zipRange[stateIndex].mException1) - return true; - if (zip == zipRange[stateIndex].mException2) - return true; - return false; -} - -CacheBuilder::FoundState CacheBuilder::FindAddress(const UChar* chars, unsigned length, int* start, int* end) -{ - FindState addressState; - FindReset(&addressState); - addressState.mWords[0] = addressState.mStarts[0] = chars; - FoundState state = FindPartialAddress(chars, chars, length, &addressState); - if (state == FOUND_PARTIAL && addressState.mProgress == ZIP_CODE && - addressState.mNumberCount == 0) { - addressState.mProgress = FIND_STREET; - state = FindPartialAddress(NULL, NULL, 0, &addressState); - } - *start = addressState.mStartResult; - *end = addressState.mEndResult; - return state; -} - -CacheBuilder::FoundState CacheBuilder::FindPartialAddress(const UChar* baseChars, - const UChar* chars, unsigned length, FindState* s) -{ - // lower case letters are optional; trailing asterisk is optional 's' - static char const* const longStreetNames[] = { - "\x04" "LleY" "\x04" "NneX" "\x05" "RCade" "\x05" "VEnue" "\x06" "LAMEDA", // A - "\x04" "aYoU" "\x04" "eaCH" "\x03" "eND" "\x05" "LuFf*" "\x05" "oTtoM" - "\x08" "ouLeVarD" "\x05" "Ranch" "\x05" "RidGe" "\x05" "RooK*" - "\x04" "urG*" "\x05" "YPass" "\x07" "roadWAY", // B - "\x05" "AMINO" - "\x03" "amP" "\x05" "anYoN" "\x03" "aPE" "\x07" "auSeWaY" "\x06" "enTeR*" - "\x06" "IRcle*" "\x05" "LiFf*" "\x03" "LuB" "\x05" "oMmoN" "\x06" "ORner*" - "\x05" "ouRSE" "\x05" "ourT*" "\x04" "oVe*" "\x04" "ReeK" "\x07" "REScent" - "\x04" "ReST" "\x07" "ROSSING" "\x08" "ROSSROAD" "\x04" "URVe" - "\x05" "AMINO" "\x06" "IRCULO" "\x07" "REScent", // C - "\x03" "aLe" "\x02" "aM" "\x05" "iVide" "\x05" "Rive*", // D - "\x06" "STate*" "\x09" "XPresswaY" "\x09" "XTension*", // E - "\x04" "ALL*" "\x04" "eRrY" "\x05" "ieLD*" "\x04" "LaT*" "\x04" "oRD*" - "\x05" "oReST" "\x05" "oRGe*" "\x04" "oRK*" "\x03" "orT" "\x06" "reeWaY", // F - "\x06" "arDeN*" "\x06" "aTeWaY" "\x04" "LeN*" "\x05" "ReeN*" "\x05" "RoVe*", // G - "\x06" "arBoR*" "\x04" "aVeN" "\x06" "eighTS" "\x06" "ighWaY" "\x04" "iLl*" - "\x05" "OLloW", // H - "\x04" "NLeT" "\x06" "Sland*" "\x03" "SLE", // I - "\x08" "unCTion*", // J - "\x03" "eY*" "\x05" "NoLl*", // K - "\x04" "aKe*" "\x03" "AND" "\x06" "aNDinG" "\x03" "aNe" "\x05" "iGhT*" - "\x03" "oaF" "\x04" "oCK*" "\x04" "oDGe" "\x03" "OOP", // L - "\x03" "ALL" "\x05" "aNoR*" "\x06" "eaDoW*" "\x03" "EWS" "\x04" "iLl*" - "\x06" "iSsioN" "\x07" "oTorWaY" "\x04" "ounT" "\x08" "ounTaiN*", // M - "\x03" "eCK", // N - "\x06" "RCHard" "\x03" "VAL" "\x07" "verPASs", // O - "\x04" "ARK*" "\x07" "arKWaY*" "\x03" "ASS" "\x06" "aSsaGE" "\x03" "ATH" - "\x03" "IKE" "\x04" "iNE*" "\x04" "Lace" "\x05" "LaiN*" "\x04" "LaZa" - "\x05" "oinT*" "\x04" "oRT*" "\x06" "Rairie" "\x06" "RIVADA", // P - NULL, - "\x05" "ADiaL" "\x03" "AMP" "\x04" "aNCH" "\x05" "aPiD*" - "\x03" "eST" - "\x05" "iDGe*" "\x04" "IVer" "\x04" "oaD*" "\x04" "ouTE" "\x02" "OW" - "\x02" "UE" "\x02" "UN", // R - "\x05" "HoaL*" "\x05" "HoRe*" "\x05" "KyWaY" "\x06" "PrinG*" "\x04" "PUR*" - "\x06" "Quare*" "\x06" "TAtion" "\x08" "TRAvenue" "\x05" "TReaM" - "\x06" "Treet*" "\x05" "uMmiT" "\x07" "PeeDWaY", // S - "\x06" "ERrace" "\x09" "hRoughWaY" "\x04" "RaCE" "\x04" "RAcK" "\x09" "RaFficwaY" - "\x04" "RaiL" "\x05" "UNneL" "\x07" "urnPiKE", // T - "\x08" "nderPASs" "\x05" "Nion*", // U - "\x06" "aLleY*" "\x06" "IAduct" "\x04" "ieW*" "\x07" "iLlaGe*" "\x04" "iLle" - "\x04" "ISta", // V - "\x04" "ALK*" "\x03" "ALL" "\x03" "AY*" "\x04" "eLl*", // W - "\x03" "ING" "\x02" "RD", // X - }; - - static char const* const longStateNames[] = { - "\x8e" "la" "\x85" "bama" "\x02" "\x84" "ska" "\x01" "\x8f" "merican Samoa" "\x04" - "\x91" "r" "\x86" "izona" "\x05" "\x87" "kansas" "\x03", - NULL, - "\x8b" "alifornia" "\x06" "\x95" "o" "\x87" "lorado" "\x07" "\x8a" "nnecticut" "\x08", - "\x89" "elaware" "\x0a" "\x95" "istrict of Columbia" "\x09", - NULL, - "\x9f" "ederated States of Micronesia" "\x0c" "\x88" "lorida" "\x0b", - "\x85" "uam" "\x0e" "\x88" "eorgia" "\x0d", - "\x87" "awaii" "\x0f", - "\x86" "daho" "\x11" "\x89" "llinois" "\x12" "\x88" "ndiana" "\x13" "\x85" - "owa" "\x10", - NULL, - "\x87" "ansas" "\x14" "\x89" "entucky" "\x15", - "\x8a" "ouisiana" "\x16", - "\x86" "aine" "\x19" "\x99" "ar" "\x8e" "shall Islands" "\x1a" "\x86" "yland" "\x18" - "\x8e" "assachusetts" "\x17" "\x93" "i" "\x87" "chigan" "\x1b" - "\x88" "nnesota" "\x1c" "\x93" "iss" "\x88" "issippi" "\x1f" "\x85" - "ouri" "\x1d" "\x88" "ontana" "\x20", - "\x90" "e" "\x87" "braska" "\x23" "\x85" "vada" "\x27" "\xa5" "ew " "\x8a" - "Hampshire" "\x24" "\x87" "Jersey" "\x25" "\x87" "Mexico" "\x26" - "\x85" "York" "\x28" "\x98" "orth " "\x89" "Carolina" "\x21" "\x87" - "Dakota" "\x22" "\x99" "orthern Mariana Islands" "\x1e", - "\x85" "hio" "\x29" "\x89" "klahoma" "\x2a" "\x87" "regon" "\x2b", - "\x86" "alau" "\x2e" "\x8d" "ennsylvania" "\x2c" "\x8c" "uerto Rico" "\x2d", - NULL, - "\x8d" "hode Island" "\x2f", - "\x98" "outh " "\x89" "Carolina" "\x30" "\x87" "Dakota" "\x31", - "\x90" "e" "\x88" "nnessee" "\x32" "\x84" "xas" "\x33", - "\x85" "tah" "\x34", - "\x88" "ermont" "\x37" "\x94" "irgin" "\x89" " Islands" "\x36" "\x83" "ia" "\x35", - "\x8b" "ashington" "\x38" "\x8e" "est Virginia" "\x3a" "\x8a" "isconsin" "\x39" - "\x88" "yoming" "\x3b" - }; - -#if 0 // DEBUG_NAV_UI - static char const* const progressNames[] = { - "NO_ADDRESS", - "SKIP_TO_SPACE", - "HOUSE_NUMBER", - "NUMBER_TRAILING_SPACE", - "ADDRESS_LINE", - "STATE_NAME", - "SECOND_HALF", - "ZIP_CODE", - "PLUS_4", - "FIND_STREET" - }; -#endif - // strategy: US only support at first - // look for a 1 - 5 digit number for a street number (no support for 'One Microsoft Way') - // ignore if preceded by '#', Suite, Ste, Rm - // look for two or more words (up to 5? North Frank Lloyd Wright Blvd) - // note: "The Circle at North Hills St." has six words, and a lower 'at' -- allow at, by, of, in, the, and, ... ? - // if a word starts with a lowercase letter, no match - // allow: , . - # / (for 1/2) ' " - // don't look for street name type yet - // look for one or two delimiters to represent possible 2nd addr line and city name - // look for either full state name, or state two letters, and/or zip code (5 or 9 digits) - // now look for street suffix, either in full or abbreviated form, with optional 's' if there's an asterisk - - s->mCurrentStart = chars; - s->mEnd = chars + length; - int candIndex = 0; - bool mustBeAllUpper = false; - bool secondHalf = false; - chars -= 1; - UChar ch = s->mCurrent; - while (++chars <= s->mEnd) { - UChar prior = ch; - ch = chars < s->mEnd ? *chars : ' '; - switch (s->mProgress) { - case NO_ADDRESS: - if (WTF::isASCIIDigit(ch) == false) { - if (ch != 'O') // letter 'O', not zero - continue; - if (s->mEnd - chars < 3) - continue; - prior = *++chars; - ch = *++chars; - if ((prior != 'n' || ch != 'e') && (prior != 'N' || ch != 'E')) - continue; - if (isUnicodeSpace(*++chars) == false) - continue; - s->mProgress = ADDRESS_LINE; - s->mStartResult = chars - 3 - s->mCurrentStart; - continue; - } - if (isUnicodeSpace(prior) == false) { - s->mProgress = SKIP_TO_SPACE; - continue; - } - s->mNumberCount = 1; - s->mProgress = HOUSE_NUMBER; - s->mStartResult = chars - s->mCurrentStart; - continue; - case SKIP_TO_SPACE: - if (isUnicodeSpace(ch) == false) - continue; - break; - case HOUSE_NUMBER: - if (WTF::isASCIIDigit(ch)) { - if (++s->mNumberCount >= 6) - s->mProgress = SKIP_TO_SPACE; - continue; - } - if (WTF::isASCIIUpper(ch)) { // allow one letter after house number, e.g. 12A SKOLFIELD PL, HARPSWELL, ME 04079 - if (WTF::isASCIIDigit(prior) == false) - s->mProgress = SKIP_TO_SPACE; - continue; - } - if (ch == '-') { - if (s->mNumberCount > 0) { // permit 21-23 ELM ST - ++s->mNumberCount; - continue; - } - } - s->mNumberCount = 0; - s->mProgress = NUMBER_TRAILING_SPACE; - case NUMBER_TRAILING_SPACE: - if (isUnicodeSpace(ch)) - continue; - if (0 && WTF::isASCIIDigit(ch)) { - s->mNumberCount = 1; - s->mProgress = HOUSE_NUMBER; - s->mStartResult = chars - s->mCurrentStart; - continue; - } - if (WTF::isASCIIDigit(ch) == false && WTF::isASCIIUpper(ch) == false) - break; - s->mProgress = ADDRESS_LINE; - case ADDRESS_LINE: - if (WTF::isASCIIAlpha(ch) || ch == '\'' || ch == '-' || ch == '&' || ch == '(' || ch == ')') { - if (++s->mLetterCount > 1) { - s->mNumberWords &= ~(1 << s->mWordCount); - continue; - } - if (s->mNumberCount >= 5) - break; -// FIXME: the test below was added to give up on a non-address, but it -// incorrectly discards addresses where the house number is in one node -// and the street name is in the next; I don't recall what the failing case -// is that suggested this fix. -// if (s->mWordCount == 0 && s->mContinuationNode) -// return FOUND_NONE; - s->mBases[s->mWordCount] = baseChars; - s->mWords[s->mWordCount] = chars - s->mNumberCount; - s->mStarts[s->mWordCount] = s->mCurrentStart; - if (WTF::isASCIILower(ch) && s->mNumberCount == 0) - s->mFirstLower = chars; - s->mNumberCount = 0; - if (WTF::isASCIILower(ch) || (WTF::isASCIIAlpha(ch) == false && ch != '-')) - s->mNumberWords &= ~(1 << s->mWordCount); - s->mUnparsed = true; - continue; - } else if (s->mFirstLower != NULL) { - size_t length = chars - s->mFirstLower; - if (length > 3) - break; - if (length == 3 && strCharCmp("and" "the", s->mFirstLower, 3, 2) == false) - break; - if (length == 2 && strCharCmp("at" "by" "el" "in" "of", s->mFirstLower, 2, 5) == false) - break; - goto resetWord; - } - if (ch == ',' || ch == '*') { // delimits lines - // asterisk as delimiter: http://www.sa.sc.edu/wellness/members.html - if (++s->mLineCount > 5) - break; - goto lookForState; - } - if (isUnicodeSpace(ch) || prior == '-') { - lookForState: - if (s->mUnparsed == false) - continue; - const UChar* candidate = s->mWords[s->mWordCount]; - UChar firstLetter = candidate[0]; - if (WTF::isASCIIUpper(firstLetter) == false && WTF::isASCIIDigit(firstLetter) == false) - goto resetWord; - s->mWordCount++; - if ((s->mWordCount == 2 && s->mNumberWords == 3 && WTF::isASCIIDigit(s->mWords[1][1])) || // choose second of 8888 333 Main - (s->mWordCount >= sizeof(s->mWords) / sizeof(s->mWords[0]) - 1)) { // subtract 1 since state names may have two parts - // search for simple number already stored since first potential house # didn't pan out - if (s->mNumberWords == 0) - break; - int shift = 0; - while ((s->mNumberWords & (1 << shift)) == 0) - shift++; - s->mNumberWords >>= ++shift; - if (s->mBases[0] != s->mBases[shift]) // if we're past the original node, bail - break; - memmove(s->mBases, &s->mBases[shift], (sizeof(s->mBases) / sizeof(s->mBases[0]) - shift) * sizeof(s->mBases[0])); - memmove(s->mWords, &s->mWords[shift], (sizeof(s->mWords) / sizeof(s->mWords[0]) - shift) * sizeof(s->mWords[0])); - memmove(s->mStarts, &s->mStarts[shift], (sizeof(s->mStarts) / sizeof(s->mStarts[0]) - shift) * sizeof(s->mStarts[0])); - s->mStartResult = s->mWords[0] - s->mStarts[0]; - s->mWordCount -= shift; - // FIXME: need to adjust lineCount to account for discarded delimiters - } - if (s->mWordCount < 4) - goto resetWord; - firstLetter -= 'A'; - if (firstLetter > 'W' - 'A') - goto resetWord; - UChar secondLetter = candidate[1]; - if (prior == '-') - s->mLetterCount--; // trim trailing dashes, to accept CA-94043 - if (s->mLetterCount == 2) { - secondLetter -= 'A'; - if (secondLetter > 'Z' - 'A') - goto resetWord; - if ((stateTwoLetter[firstLetter] & 1 << secondLetter) != 0) { - // special case to ignore 'et al' - if (strCharCmp("ET", s->mWords[s->mWordCount - 2], 2, 1) == false) { - s->mStateWord = s->mWordCount - 1; - s->mZipHint = firstIndex[firstLetter] + - bitcount(stateTwoLetter[firstLetter] & ((1 << secondLetter) - 1)); - goto foundStateName; - } - } - goto resetWord; - } - s->mStates = longStateNames[firstLetter]; - if (s->mStates == NULL) - goto resetWord; - mustBeAllUpper = false; - s->mProgress = STATE_NAME; - unsigned char section = s->mStates[0]; - ASSERT(section > 0x80); - s->mSectionLength = section & 0x7f; - candIndex = 1; - secondHalf = false; - s->mStateWord = s->mWordCount - 1; - goto stateName; - } - if (WTF::isASCIIDigit(ch)) { - if (s->mLetterCount == 0) { - if (++s->mNumberCount > 1) - continue; - if (s->mWordCount == 0 && s->mContinuationNode) - return FOUND_NONE; - s->mBases[s->mWordCount] = baseChars; - s->mWords[s->mWordCount] = chars; - s->mStarts[s->mWordCount] = s->mCurrentStart; - s->mNumberWords |= 1 << s->mWordCount; - s->mUnparsed = true; - } - continue; - } - if (ch == '.') { // optionally can follow letters - if (s->mLetterCount == 0) - break; - if (s->mNumberCount > 0) - break; - continue; - } - if (ch == '/') // between numbers (1/2) between words (12 Main / Ste 4d) - goto resetWord; - if (ch == '#') // can precede numbers, allow it to appear randomly - goto resetWord; - if (ch == '"') // sometimes parts of addresses are quoted (FIXME: cite an example here) - continue; - break; - case SECOND_HALF: - if (WTF::isASCIIAlpha(ch)) { - if (s->mLetterCount == 0) { - s->mBases[s->mWordCount] = baseChars; - s->mWords[s->mWordCount] = chars; - s->mStarts[s->mWordCount] = s->mCurrentStart; - s->mWordCount++; - } - s->mLetterCount++; - continue; - } - if (WTF::isASCIIDigit(ch) == false) { - if (s->mLetterCount > 0) { - s->mProgress = STATE_NAME; - candIndex = 0; - secondHalf = true; - goto stateName; - } - continue; - } - s->mProgress = ADDRESS_LINE; - goto resetState; - case STATE_NAME: - stateName: - // pick up length of first section - do { - int stateIndex = 1; - int skip = 0; - int prefix = 0; - bool subStr = false; - do { - unsigned char match = s->mStates[stateIndex]; - if (match >= 0x80) { - if (stateIndex == s->mSectionLength) - break; - subStr = true; - // if (skip > 0) - // goto foundStateName; - prefix = candIndex; - skip = match & 0x7f; - match = s->mStates[++stateIndex]; - } - UChar candChar = s->mWords[s->mWordCount - 1][candIndex]; - if (mustBeAllUpper && WTF::isASCIILower(candChar)) - goto skipToNext; - if (match != candChar) { - if (match != WTF::toASCIILower(candChar)) { - skipToNext: - if (subStr == false) - break; - if (stateIndex == s->mSectionLength) { - if (secondHalf) { - s->mProgress = ADDRESS_LINE; - goto resetState; - } - break; - } - stateIndex += skip; - skip = 0; - candIndex = prefix; - continue; // try next substring - } - mustBeAllUpper = true; - } - int nextindex = stateIndex + 1; - if (++candIndex >= s->mLetterCount && s->mStates[nextindex] == ' ') { - s->mProgress = SECOND_HALF; - s->mStates += nextindex; - s->mSectionLength -= nextindex; - goto resetWord; - } - if (nextindex + 1 == s->mSectionLength || skip == 2) { - s->mZipHint = s->mStates[nextindex] - 1; - goto foundStateName; - } - stateIndex += 1; - skip -= 1; - } while (true); - s->mStates += s->mSectionLength; - ASSERT(s->mStates[0] == 0 || (unsigned) s->mStates[0] > 0x80); - s->mSectionLength = s->mStates[0] & 0x7f; - candIndex = 1; - subStr = false; - } while (s->mSectionLength != 0); - s->mProgress = ADDRESS_LINE; - goto resetState; - foundStateName: - s->mEndResult = chars - s->mCurrentStart; - s->mEndWord = s->mWordCount - 1; - s->mProgress = ZIP_CODE; - // a couple of delimiters is an indication that the state name is good - // or, a non-space / non-alpha-digit is also good - s->mZipDelimiter = s->mLineCount > 2 || isUnicodeSpace(ch) == false; - if (WTF::isASCIIDigit(ch)) - s->mZipStart = chars; - goto resetState; - case ZIP_CODE: - if (WTF::isASCIIDigit(ch)) { - int count = ++s->mNumberCount; - if (count == 1) { - if (WTF::isASCIIDigit(prior)) - ++s->mNumberCount; - else - s->mZipStart = chars; - } - if (count <= 9) - continue; - } else if (isUnicodeSpace(ch)) { - if (s->mNumberCount == 0) { - s->mZipDelimiter = true; // two spaces delimit state name - continue; - } - } else if (ch == '-') { - if (s->mNumberCount == 5 && validZip(s->mZipHint, s->mZipStart)) { - s->mNumberCount = 0; - s->mProgress = PLUS_4; - continue; - } - if (s->mNumberCount == 0) - s->mZipDelimiter = true; - } else if (WTF::isASCIIAlpha(ch) == false) - s->mZipDelimiter = true; - if (s->mNumberCount == 5 || s->mNumberCount == 9) { - if (validZip(s->mZipHint, s->mZipStart) == false) - goto noZipMatch; - s->mEndResult = chars - s->mCurrentStart; - s->mEndWord = s->mWordCount - 1; - } else if (s->mZipDelimiter == false) { - noZipMatch: - --chars; - s->mProgress = ADDRESS_LINE; - continue; - } - s->mProgress = FIND_STREET; - goto findStreet; - case PLUS_4: - if (WTF::isASCIIDigit(ch)) { - if (++s->mNumberCount <= 4) - continue; - } - if (isUnicodeSpace(ch)) { - if (s->mNumberCount == 0) - continue; - } - if (s->mNumberCount == 4) { - if (WTF::isASCIIAlpha(ch) == false) { - s->mEndResult = chars - s->mCurrentStart; - s->mEndWord = s->mWordCount - 1; - } - } else if (s->mNumberCount != 0) - break; - s->mProgress = FIND_STREET; - case FIND_STREET: - findStreet: // minus two below skips city before state - for (int wordsIndex = s->mStateWord - 2; wordsIndex >= 0; --wordsIndex) { - const UChar* test = s->mWords[wordsIndex]; - UChar letter = test[0]; - letter -= 'A'; - if (letter > 'X' - 'A') - continue; - const char* names = longStreetNames[letter]; - if (names == NULL) - continue; - int offset; - while ((offset = *names++) != 0) { - int testIndex = 1; - bool abbr = false; - for (int idx = 0; idx < offset; idx++) { - char nameLetter = names[idx]; - char testUpper = WTF::toASCIIUpper(test[testIndex]); - if (nameLetter == '*') { - if (testUpper == 'S') - testIndex++; - break; - } - bool fullOnly = WTF::isASCIILower(nameLetter); - nameLetter = WTF::toASCIIUpper(nameLetter); - if (testUpper == nameLetter) { - if (abbr && fullOnly) - goto nextTest; - testIndex++; - continue; - } - if (fullOnly == false) - goto nextTest; - abbr = true; - } - letter = test[testIndex]; - if (WTF::isASCIIAlpha(letter) == false && WTF::isASCIIDigit(letter) == false) { - if (s->mNumberWords != 0) { - int shift = 0; - int wordReduction = -1; - do { - while ((s->mNumberWords & (1 << shift)) == 0) - shift++; - if (shift > wordsIndex) - break; - wordReduction = shift; - } while (s->mNumberWords >> ++shift != 0); - if (wordReduction >= 0) { - if (s->mContinuationNode) - return FOUND_NONE; - s->mStartResult = s->mWords[wordReduction] - s->mStarts[wordReduction]; - } - } - return FOUND_COMPLETE; - } - nextTest: - names += offset; - } - } - if (s->mNumberWords != 0) { - unsigned shift = 0; - while ((s->mNumberWords & (1 << shift)) == 0) - shift++; - s->mNumberWords >>= ++shift; - if (s->mBases[0] != s->mBases[shift]) - return FOUND_NONE; - memmove(s->mBases, &s->mBases[shift], (sizeof(s->mBases) / sizeof(s->mBases[0]) - shift) * sizeof(s->mBases[0])); - memmove(s->mWords, &s->mWords[shift], (sizeof(s->mWords) / sizeof(s->mWords[0]) - shift) * sizeof(s->mWords[0])); - memmove(s->mStarts, &s->mStarts[shift], (sizeof(s->mStarts) / sizeof(s->mStarts[0]) - shift) * sizeof(s->mStarts[0])); - s->mStartResult = s->mWords[0] - s->mStarts[0]; - s->mWordCount -= shift; - s->mProgress = ADDRESS_LINE; - --chars; - continue; - } - break; - } - if (s->mContinuationNode) - return FOUND_NONE; - s->mProgress = NO_ADDRESS; - s->mWordCount = s->mLineCount = 0; - s->mNumberWords = 0; - resetState: - s->mStates = NULL; - resetWord: - s->mNumberCount = s->mLetterCount = 0; - s->mFirstLower = NULL; - s->mUnparsed = false; - } - s->mCurrent = ch; - return s->mProgress == NO_ADDRESS ? FOUND_NONE : FOUND_PARTIAL; -} - -// Recogize common email patterns only. Currently has lots of state, walks text forwards and backwards -- will be -// a real challenge to adapt to walk text across multiple nodes, I imagine -// FIXME: it's too hard for the caller to call these incrementally -- it's probably best for this to -// either walk the node tree directly or make a callout to get the next or previous node, if there is one -// walking directly will avoid adding logic in caller to track the multiple partial or full nodes that compose this -// text pattern. -CacheBuilder::FoundState CacheBuilder::FindPartialEMail(const UChar* chars, unsigned length, - FindState* s) -{ - // the following tables were generated by tests/browser/focusNavigation/BrowserDebug.cpp - // hand-edit at your own risk - static const int domainTwoLetter[] = { - 0x02df797c, // a followed by: [cdefgilmnoqrstuwxz] - 0x036e73fb, // b followed by: [abdefghijmnorstvwyz] - 0x03b67ded, // c followed by: [acdfghiklmnorsuvxyz] - 0x02005610, // d followed by: [ejkmoz] - 0x001e00d4, // e followed by: [ceghrstu] - 0x00025700, // f followed by: [ijkmor] - 0x015fb9fb, // g followed by: [abdefghilmnpqrstuwy] - 0x001a3400, // h followed by: [kmnrtu] - 0x000f7818, // i followed by: [delmnoqrst] - 0x0000d010, // j followed by: [emop] - 0x0342b1d0, // k followed by: [eghimnprwyz] - 0x013e0507, // l followed by: [abcikrstuvy] - 0x03fffccd, // m followed by: [acdghklmnopqrstuvwxyz] - 0x0212c975, // n followed by: [acefgilopruz] - 0x00001000, // o followed by: [m] - 0x014e3cf1, // p followed by: [aefghklmnrstwy] - 0x00000001, // q followed by: [a] - 0x00504010, // r followed by: [eouw] - 0x032a7fdf, // s followed by: [abcdeghijklmnortvyz] - 0x026afeec, // t followed by: [cdfghjklmnoprtvwz] - 0x03041441, // u followed by: [agkmsyz] - 0x00102155, // v followed by: [aceginu] - 0x00040020, // w followed by: [fs] - 0x00000000, // x - 0x00180010, // y followed by: [etu] - 0x00401001, // z followed by: [amw] - }; - - static char const* const longDomainNames[] = { - "\x03" "ero" "\x03" "rpa", // aero, arpa - "\x02" "iz", // biz - "\x02" "at" "\x02" "om" "\x03" "oop", // cat, com, coop - NULL, // d - "\x02" "du", // edu - NULL, // f - "\x02" "ov", // gov - NULL, // h - "\x03" "nfo" "\x02" "nt", // info, int - "\x03" "obs", // jobs - NULL, // k - NULL, // l - "\x02" "il" "\x03" "obi" "\x05" "useum", // mil, mobi, museum - "\x03" "ame" "\x02" "et", // name, net - "\x02" "rg", // , org - "\x02" "ro", // pro - NULL, // q - NULL, // r - NULL, // s - "\x05" "ravel", // travel - NULL, // u - NULL, // v - NULL, // w - NULL, // x - NULL, // y - NULL, // z - }; - - const UChar* start = chars; - const UChar* end = chars + length; - while (chars < end) { - UChar ch = *chars++; - if (ch != '@') - continue; - const UChar* atLocation = chars - 1; - // search for domain - ch = *chars++ | 0x20; // convert uppercase to lower - if (ch < 'a' || ch > 'z') - continue; - while (chars < end) { - ch = *chars++; - if (IsDomainChar(ch) == false) - goto nextAt; - if (ch != '.') - continue; - UChar firstLetter = *chars++ | 0x20; // first letter of the domain - if (chars >= end) - return FOUND_NONE; // only one letter; must be at least two - firstLetter -= 'a'; - if (firstLetter > 'z' - 'a') - continue; // non-letter followed '.' - int secondLetterMask = domainTwoLetter[firstLetter]; - ch = *chars | 0x20; // second letter of the domain - ch -= 'a'; - if (ch >= 'z' - 'a') - continue; - bool secondMatch = (secondLetterMask & 1 << ch) != 0; - const char* wordMatch = longDomainNames[firstLetter]; - int wordIndex = 0; - while (wordMatch != NULL) { - int len = *wordMatch++; - char match; - do { - match = wordMatch[wordIndex]; - if (match < 0x20) - goto foundDomainStart; - if (chars[wordIndex] != match) - break; - wordIndex++; - } while (true); - wordMatch += len; - if (*wordMatch == '\0') - break; - wordIndex = 0; - } - if (secondMatch) { - wordIndex = 1; - foundDomainStart: - chars += wordIndex; - if (chars < end) { - ch = *chars; - if (ch != '.') { - if (IsDomainChar(ch)) - goto nextDot; - } else if (chars + 1 < end && IsDomainChar(chars[1])) - goto nextDot; - } - // found domain. Search backwards from '@' for beginning of email address - s->mEndResult = chars - start; - chars = atLocation; - if (chars <= start) - goto nextAt; - ch = *--chars; - if (ch == '.') - goto nextAt; // mailbox can't end in period - do { - if (IsMailboxChar(ch) == false) { - chars++; - break; - } - if (chars == start) - break; - ch = *--chars; - } while (true); - UChar firstChar = *chars; - if (firstChar == '.' || firstChar == '@') // mailbox can't start with period or be empty - goto nextAt; - s->mStartResult = chars - start; - return FOUND_COMPLETE; - } - nextDot: - ; - } -nextAt: - chars = atLocation + 1; - } - return FOUND_NONE; -} - -#define PHONE_PATTERN "(200) /-.\\ 100 -. 0000" // poor man's regex: parens optional, any one of punct, digit smallest allowed - -CacheBuilder::FoundState CacheBuilder::FindPartialNumber(const UChar* chars, unsigned length, - FindState* s) -{ - char* pattern = s->mPattern; - UChar* store = s->mStorePtr; - const UChar* start = chars; - const UChar* end = chars + length; - const UChar* lastDigit = NULL; - do { - bool initialized = s->mInitialized; - while (chars < end) { - if (initialized == false) { - s->mBackTwo = s->mBackOne; - s->mBackOne = s->mCurrent; - } - UChar ch = s->mCurrent = *chars; - do { - char patternChar = *pattern; - switch (patternChar) { - case '2': - if (initialized == false) { - s->mStartResult = chars - start; - initialized = true; - } - case '0': - case '1': - if (ch < patternChar || ch > '9') - goto resetPattern; - *store++ = ch; - pattern++; - lastDigit = chars; - goto nextChar; - case '\0': - if (WTF::isASCIIDigit(ch) == false) { - *store = '\0'; - goto checkMatch; - } - goto resetPattern; - case ' ': - if (ch == patternChar) - goto nextChar; - break; - case '(': - if (ch == patternChar) { - s->mStartResult = chars - start; - initialized = true; - s->mOpenParen = true; - } - goto commonPunctuation; - case ')': - if ((ch == patternChar) ^ s->mOpenParen) - goto resetPattern; - default: - commonPunctuation: - if (ch == patternChar) { - pattern++; - goto nextChar; - } - } - } while (++pattern); // never false - nextChar: - chars++; - } - break; -resetPattern: - if (s->mContinuationNode) - return FOUND_NONE; - FindResetNumber(s); - pattern = s->mPattern; - store = s->mStorePtr; - } while (++chars < end); -checkMatch: - if (WTF::isASCIIDigit(s->mBackOne != '1' ? s->mBackOne : s->mBackTwo)) - return FOUND_NONE; - *store = '\0'; - s->mStorePtr = store; - s->mPattern = pattern; - s->mEndResult = lastDigit - start + 1; - char pState = pattern[0]; - return pState == '\0' ? FOUND_COMPLETE : pState == '(' || (WTF::isASCIIDigit(pState) && WTF::isASCIIDigit(pattern[-1])) ? - FOUND_NONE : FOUND_PARTIAL; -} - -CacheBuilder::FoundState CacheBuilder::FindPhoneNumber(const UChar* chars, unsigned length, - int* start, int* end) -{ - FindState state; - FindReset(&state); - FoundState result = FindPartialNumber(chars, length, &state); - *start = state.mStartResult; - *end = state.mEndResult; - return result; -} - -void CacheBuilder::FindReset(FindState* state) -{ - memset(state, 0, sizeof(FindState)); - state->mCurrent = ' '; - FindResetNumber(state); -} - -void CacheBuilder::FindResetNumber(FindState* state) -{ - state->mOpenParen = false; - state->mPattern = (char*) PHONE_PATTERN; - state->mStorePtr = state->mStore; -} - -void CacheBuilder::GetGlobalOffset(Node* node, int* x, int * y) -{ - GetGlobalOffset(node->document()->frame(), x, y); -} - -void CacheBuilder::GetGlobalOffset(Frame* frame, int* x, int* y) -{ -// TIMER_PROBE(__FUNCTION__); - ASSERT(x); - ASSERT(y); - *x = 0; - *y = 0; - if (!frame->view()) - return; - WebCoreViewBridge* bridge = frame->view()->getWebCoreViewBridge(); - if (bridge == NULL) - return; - WebCoreViewBridge* parent; - while ((parent = bridge->getParent()) != NULL) { - const WebCore::IntRect& rect = bridge->getBounds(); - *x += rect.x(); - *y += rect.y(); - bridge = parent; - } - // TIMER_PROBE_END(); -} - -Frame* CacheBuilder::HasFrame(Node* node) -{ - RenderObject* renderer = node->renderer(); - if (renderer == NULL) - return NULL; - if (renderer->isWidget() == false) - return NULL; - Widget* widget = static_cast<RenderWidget*>(renderer)->widget(); - if (widget == NULL) - return NULL; - if (widget->isFrameView() == false) - return NULL; - return static_cast<FrameView*>(widget)->frame(); -} - -bool CacheBuilder::HasOverOrOut(Node* node) -{ - EventTargetNode* target = (EventTargetNode*) node; - return target->getEventListener(EventNames::mouseoverEvent) || - target->getEventListener(EventNames::mouseoutEvent); - -} - -bool CacheBuilder::HasTriggerEvent(Node* node) -{ - EventTargetNode* target = (EventTargetNode*) node; - return target->getEventListener(EventNames::clickEvent) || - target->getEventListener(EventNames::mousedownEvent) || - target->getEventListener(EventNames::mouseupEvent) || - target->getEventListener(EventNames::keydownEvent) || - target->getEventListener(EventNames::keyupEvent); -} - -// #define EMAIL_PATTERN "x@y.d" // where 'x' is letters, numbers, and '-', '.', '_' ; 'y' is 'x' without the underscore, and 'd' is a valid domain -// - 0x2D . 0x2E 0-9 0x30-39 A-Z 0x41-5A _ 0x5F a-z 0x61-7A - -bool CacheBuilder::IsDomainChar(UChar ch) -{ - static const unsigned body[] = {0x03ff6000, 0x07fffffe, 0x07fffffe}; // 0-9 . - A-Z a-z - ch -= 0x20; - if (ch > 'z' - 0x20) - return false; - return (body[ch >> 5] & 1 << (ch & 0x1f)) != 0; -} - -// does not find text to keep it fast -// (this assume text nodes are more rarely moved than other nodes) -Node* CacheBuilder::findByCenter(int x, int y) const -{ - DBG_NAV_LOGD("x=%d y=%d\n", x, y); - Frame* frame = FrameAnd(this); - Node* node = frame->document(); - ASSERT(node != NULL); - int globalOffsetX, globalOffsetY; - GetGlobalOffset(frame, &globalOffsetX, &globalOffsetY); - while ((node = node->traverseNextNode()) != NULL) { - Frame* child = HasFrame(node); - if (child != NULL) { - if (child->document() == NULL) - continue; - CacheBuilder* cacheBuilder = Builder(child); - // if (cacheBuilder->mViewBounds.isEmpty()) - // continue; - Node* result = cacheBuilder->findByCenter(x, y); - if (result != NULL) - return result; - } - if (node->isTextNode()) - continue; - IntRect bounds; - if (node->hasTagName(HTMLNames::areaTag)) { - HTMLAreaElement* area = static_cast<HTMLAreaElement*>(node); - bounds = area->getAreaRect(); - bounds.move(globalOffsetX, globalOffsetY); - } else - bounds = node->getRect(); - if (bounds.isEmpty()) - continue; - bounds.move(globalOffsetX, globalOffsetY); - if (x != bounds.x() + (bounds.width() >> 1)) - continue; - if (y != bounds.y() + (bounds.height() >> 1)) - continue; - if (node->isKeyboardFocusable(NULL)) - return node; - if (node->isMouseFocusable()) - return node; - if (node->isFocusable()) - return node; - if (node->isEventTargetNode() == false) - continue; - if (AnyIsClick(node)) - continue; - if (HasTriggerEvent(node) == false) - continue; - return node; - } - return NULL; -} - -bool CacheBuilder::isFocusableText(NodeWalk* walk, bool more, Node* node, - android::CachedNodeType* type, String* exported) const -{ - Text* textNode = static_cast<Text*>(node); - StringImpl* string = textNode->string(); - const UChar* baseChars = string->characters(); -// const UChar* originalBase = baseChars; - int length = string->length(); - int index = 0; - while (index < length && isUnicodeSpace(baseChars[index])) - index++; - if (index >= length) - return false; - if (more == false) { - walk->mStart = 0; - walk->mEnd = 0; - walk->mFinalNode = node; - walk->mLastInline = NULL; - } - // starting with this node, search forward for email, phone number, and address - // if any of the three is found, track it so that the remaining can be looked for later - FoundState state = FOUND_NONE; - RenderText* renderer = (RenderText*) node->renderer(); - bool foundBetter = false; - InlineTextBox* baseInline = walk->mLastInline != NULL ? walk->mLastInline : - renderer->firstTextBox(); - if (baseInline == NULL) - return false; - int start = walk->mEnd; - InlineTextBox* saveInline; - int baseStart, firstStart = start; - saveInline = baseInline; - baseStart = start; - for (android::CachedNodeType checkType = android::ADDRESS_CACHEDNODETYPE; - checkType <= android::PHONE_CACHEDNODETYPE; - checkType = (android::CachedNodeType) (checkType << 1)) - { - if ((checkType & mAllowableTypes) == 0) - continue; - InlineTextBox* inlineTextBox = baseInline; - FindState findState; - FindReset(&findState); - start = baseStart; - if (checkType == android::ADDRESS_CACHEDNODETYPE) { - findState.mBases[0] = baseChars; - findState.mWords[0] = baseChars + start; - findState.mStarts[0] = baseChars + start; - } - Node* lastPartialNode = NULL; - int lastPartialEnd = -1; - bool lastPartialMore = false; - bool firstPartial = true; - InlineTextBox* lastPartialInline = NULL; - do { - do { - const UChar* chars = baseChars + start; - length = inlineTextBox == NULL ? 0 : - inlineTextBox->end() - start + 1; - bool wasInitialized = findState.mInitialized; - switch (checkType) { - case android::ADDRESS_CACHEDNODETYPE: - state = FindPartialAddress(baseChars, chars, length, &findState); - break; - case android::EMAIL_CACHEDNODETYPE: - state = FindPartialEMail(chars, length, &findState); - break; - case android::PHONE_CACHEDNODETYPE: - state = FindPartialNumber(chars, length, &findState); - break; - default: - ASSERT(0); - } - findState.mInitialized = state != FOUND_NONE; - if (wasInitialized != findState.mInitialized) - firstStart = start; - if (state == FOUND_PARTIAL) { - lastPartialNode = node; - lastPartialEnd = findState.mEndResult + start; - lastPartialMore = firstPartial && - lastPartialEnd < (int) string->length(); - firstPartial = false; - lastPartialInline = inlineTextBox; - findState.mContinuationNode = true; - } else if (state == FOUND_COMPLETE) { - if (foundBetter == false || walk->mStart > findState.mStartResult) { - walk->mStart = findState.mStartResult + firstStart; - if (findState.mEndResult > 0) { - walk->mFinalNode = node; - walk->mEnd = findState.mEndResult + start; - walk->mMore = walk->mEnd < (int) string->length(); - walk->mLastInline = inlineTextBox; - } else { - walk->mFinalNode = lastPartialNode; - walk->mEnd = lastPartialEnd; - walk->mMore = lastPartialMore; - walk->mLastInline = lastPartialInline; - } - *type = checkType; - if (checkType == android::PHONE_CACHEDNODETYPE) { - const UChar* store = findState.mStore; - *exported = String(store); - } else { - Node* temp = textNode; - length = 1; - start = walk->mStart; - exported->truncate(0); - do { - Text* tempText = static_cast<Text*>(temp); - StringImpl* string = tempText->string(); - int end = tempText == walk->mFinalNode ? - walk->mEnd : string->length(); - exported->append(String(string->substring( - start, end - start))); - ASSERT(end > start); - length += end - start + 1; - if (temp == walk->mFinalNode) - break; - start = 0; - do { - temp = temp->traverseNextNode(); - ASSERT(temp); - } while (temp->isTextNode() == false); - // add a space in between text nodes to avoid - // words collapsing together - exported->append(" "); - } while (true); - } - foundBetter = true; - } - goto tryNextCheckType; - } else if (findState.mContinuationNode) - break; - if (inlineTextBox == NULL) - break; - inlineTextBox = inlineTextBox->nextTextBox(); - if (inlineTextBox == NULL) - break; - start = inlineTextBox->start(); - } while (true); - if (state == FOUND_NONE) - break; - // search for next text node, if any - Text* nextNode; - do { - do { - do { - node = node->traverseNextNode(); - if (node == NULL || node->hasTagName(HTMLNames::aTag)) { - if (state == FOUND_PARTIAL && - checkType == android::ADDRESS_CACHEDNODETYPE && - findState.mProgress == ZIP_CODE && - findState.mNumberCount == 0) { - baseChars = NULL; - inlineTextBox = NULL; - start = 0; - findState.mProgress = FIND_STREET; - goto finalNode; - } - goto tryNextCheckType; - } - } while (node->isTextNode() == false); - nextNode = static_cast<Text*>(node); - renderer = (RenderText*) nextNode->renderer(); - } while (renderer == NULL); - baseInline = renderer->firstTextBox(); - } while (baseInline == NULL); - string = nextNode->string(); - baseChars = string->characters(); - inlineTextBox = baseInline; - start = inlineTextBox->start(); - finalNode: - findState.mEndResult = 0; - } while (true); -tryNextCheckType: - node = textNode; - baseInline = saveInline; - string = textNode->string(); - baseChars = string->characters(); - } - if (foundBetter) { - android::CachedNodeType temp = *type; - switch (temp) { - case android::ADDRESS_CACHEDNODETYPE: { - static const char geoString[] = "geo:0,0?q="; - exported->insert(String(geoString), 0); - int index = sizeof(geoString) - 1; - String escapedComma("%2C"); - while ((index = exported->find(',', index)) >= 0) - exported->replace(index, 1, escapedComma); - } break; - case android::EMAIL_CACHEDNODETYPE: - exported->insert(WebCore::String("mailto:"), 0); - break; - case android::PHONE_CACHEDNODETYPE: - exported->insert(WebCore::String("tel:"), 0); - break; - default: - break; - } - return true; - } -noTextMatch: - walk->reset(); - return false; -} - -bool CacheBuilder::IsMailboxChar(UChar ch) -{ - static const unsigned body[] = {0x03ff6000, 0x87fffffe, 0x07fffffe}; // 0-9 . - A-Z _ a-z - ch -= 0x20; - if (ch > 'z' - 0x20) - return false; - return (body[ch >> 5] & 1 << (ch & 0x1f)) != 0; -} - -bool CacheBuilder::outOfDate() -{ - Node* kitFocusNode = currentFocus(); - if (mLastKnownFocus != kitFocusNode) { - DBG_NAV_LOGD("%s\n", "mLastKnownFocus != kitFocusNode"); - return true; - } - if (kitFocusNode == NULL) - return false; - IntRect kitBounds = kitFocusNode->getRect(); - bool result = kitBounds != mLastKnownFocusBounds; - if (result == true) - DBG_NAV_LOGD("%s\n", "kitBounds != mLastKnownFocusBounds"); - return result; -} - -void CacheBuilder::setLastFocus(Node* node) -{ - ASSERT(node); - mLastKnownFocus = node; - mLastKnownFocusBounds = node->getRect(); -} - -bool CacheBuilder::setData(android::CachedFrame* cachedFrame) -{ - FrameAndroid* frameAndroid = FrameAnd(this); - Document* doc = frameAndroid->document(); - if (doc == NULL) - return false; - RenderObject* renderer = doc->renderer(); - if (renderer == NULL) - return false; - RenderLayer* layer = renderer->enclosingLayer(); - if (layer == NULL) - return false; - if (layer->width() == 0 || layer->height() == 0) - return false; - if (!frameAndroid->view()) - return false; - WebCoreViewBridge* view = frameAndroid->view()->getWebCoreViewBridge(); - cachedFrame->setLocalViewBounds(view->getBounds()); - cachedFrame->setContentsSize(layer->width(), layer->height()); - if (cachedFrame->childCount() == 0) - return true; - android::CachedFrame* lastCachedFrame = cachedFrame->lastChild(); - cachedFrame = cachedFrame->firstChild(); - do { - CacheBuilder* cacheBuilder = Builder((Frame* )cachedFrame->framePointer()); - cacheBuilder->setData(cachedFrame); - } while (cachedFrame++ != lastCachedFrame); - return true; -} - -bool CacheBuilder::validNode(void* matchFrame, void* matchNode) const -{ - Frame* frame = FrameAnd(this); - if (matchFrame == frame) { - if (matchNode == NULL) - return true; - Node* node = frame->document(); - while (node != NULL) { - if (node == matchNode) { - const IntRect& rect = node->hasTagName(HTMLNames::areaTag) ? - static_cast<HTMLAreaElement*>(node)->getAreaRect() : node->getRect(); - // Consider nodes with empty rects that are not at the origin - // to be valid, since news.google.com has valid nodes like this - if (rect.x() == 0 && rect.y() == 0 && rect.isEmpty()) - return false; - return true; - } - node = node->traverseNextNode(); - } - DBG_NAV_LOGD("frame=%p valid node=%p invalid\n", matchFrame, matchNode); - return false; - } - Frame* child = frame->tree()->firstChild(); - while (child) { - bool result = Builder(child)->validNode(matchFrame, matchNode); - if (result) - return result; - child = child->tree()->nextSibling(); - } -#if DEBUG_NAV_UI - if (frame->tree()->parent() == NULL) - DBG_NAV_LOGD("frame=%p node=%p false\n", matchFrame, matchNode); -#endif - return false; -} - -static int Area(const IntRect& rect) -{ - return rect.width() * rect.height(); -} - -bool CacheBuilder::AddPartRect(IntRect& bounds, int x, int y, - WTF::Vector<IntRect>* result, IntRect* focusBounds) -{ - if (bounds.isEmpty()) - return true; - bounds.move(x, y); - if (bounds.right() <= 0 || bounds.bottom() <= 0) - return true; - IntRect* work = result->begin() - 1; - IntRect* end = result->end(); - while (++work < end) { - if (work->contains(bounds)) - return true; - if (bounds.contains(*work)) { - *work = bounds; - focusBounds->unite(bounds); - return true; - } - if ((bounds.x() != work->x() || bounds.width() != work->width()) && - (bounds.y() != work->y() || bounds.height() != work->height())) - continue; - IntRect test = *work; - test.unite(bounds); - if (Area(test) > Area(*work) + Area(bounds)) - continue; - *work = test; - focusBounds->unite(bounds); - return true; - } - if (result->size() >= MAXIMUM_FOCUS_RING_COUNT) - return false; - result->append(bounds); - if (focusBounds->isEmpty()) - *focusBounds = bounds; - else - focusBounds->unite(bounds); - return true; -} - -bool CacheBuilder::ConstructPartRects(Node* node, const IntRect& bounds, - IntRect* focusBounds, int x, int y, WTF::Vector<IntRect>* result) -{ - WTF::Vector<ClipColumnTracker> clipTracker(1); - ClipColumnTracker* baseTracker = clipTracker.data(); // sentinel - bzero(baseTracker, sizeof(ClipColumnTracker)); - if (node->hasChildNodes() && node->hasTagName(HTMLNames::buttonTag) == false - && node->hasTagName(HTMLNames::selectTag) == false) { - // collect all text rects from first to last child - Node* test = node->firstChild(); - Node* last = NULL; - Node* prior = node; - while ((prior = prior->lastChild()) != NULL) - last = prior; - ASSERT(last != NULL); - bool nodeIsAnchor = node->hasTagName(HTMLNames::aTag); - do { - do { - const ClipColumnTracker* lastClip = &clipTracker.last(); - if (test != lastClip->mLastChild) - break; - clipTracker.removeLast(); - } while (true); - RenderObject* renderer = test->renderer(); - if (renderer == NULL) - continue; - EVisibility vis = renderer->style()->visibility(); - if (vis == HIDDEN) - continue; - if (test->isTextNode()) { - RenderText* renderText = (RenderText*) renderer; - InlineTextBox *textBox = renderText->firstTextBox(); - if (textBox == NULL) - continue; - bool hasClip = renderer->hasOverflowClip(); - size_t clipIndex = clipTracker.size(); - IntRect clipBounds = IntRect(0, 0, INT_MAX, INT_MAX); - if (hasClip || --clipIndex > 0) { - clipBounds = hasClip ? renderer->absoluteBoundingBoxRect() : - clipTracker.at(clipIndex).mBounds; // x, y fixup done by ConstructTextRect - } - if (ConstructTextRect((Text*) test, textBox, 0, INT_MAX, - x, y, focusBounds, clipBounds, result) == false) { - return false; - } - continue; - } - if (test->hasTagName(HTMLNames::imgTag)) { - IntRect bounds = test->getRect(); - if (AddPartRect(bounds, x, y, result, focusBounds) == false) - return false; - continue; - } - if (renderer->hasOverflowClip() == false) { - if (nodeIsAnchor && test->hasTagName(HTMLNames::divTag)) { - IntRect bounds = renderer->absoluteBoundingBoxRect(); // x, y fixup done by AddPartRect - int left = bounds.x() + renderer->paddingLeft() - + renderer->borderLeft(); - int top = bounds.y() + renderer->paddingTop() - + renderer->borderTop(); - int right = bounds.right() - renderer->paddingRight() - - renderer->borderRight(); - int bottom = bounds.bottom() - renderer->paddingBottom() - - renderer->borderBottom(); - if (left >= right || top >= bottom) - continue; - bounds = IntRect(left, top, right - left, bottom - top); - if (AddPartRect(bounds, x, y, result, focusBounds) == false) - return false; - } - continue; - } - Node* lastChild = test->lastChild(); - if (lastChild == NULL) - continue; - clipTracker.grow(clipTracker.size() + 1); - ClipColumnTracker& clip = clipTracker.last(); - clip.mBounds = renderer->absoluteBoundingBoxRect(); // x, y fixup done by ConstructTextRect - clip.mLastChild = OneAfter(lastChild); - clip.mNode = test; - } while (test != last && (test = test->traverseNextNode()) != NULL); - } - if (result->size() == 0) { - if (bounds.width() < MINIMUM_FOCUSABLE_WIDTH) - return false; - if (bounds.height() < MINIMUM_FOCUSABLE_HEIGHT) - return false; - result->append(bounds); - *focusBounds = bounds; - } - return true; -} - -static inline bool isNotSpace(UChar c) -{ - return c <= 0x7F ? isUnicodeSpace(c) == false : - WTF::Unicode::direction(c) != WTF::Unicode::WhiteSpaceNeutral; -} - -bool CacheBuilder::ConstructTextRect(Text* textNode, - InlineTextBox* textBox, int start, int relEnd, int x, int y, - IntRect* focusBounds, const IntRect& clipBounds, WTF::Vector<IntRect>* result) -{ - RenderText* renderText = (RenderText*) textNode->renderer(); - EVisibility vis = renderText->style()->visibility(); - StringImpl* string = textNode->string(); - const UChar* chars = string->characters(); - int renderX, renderY; - renderText->absolutePosition(renderX, renderY); - do { - int textBoxStart = textBox->start(); - int textBoxEnd = textBoxStart + textBox->len(); - if (textBoxEnd <= start) - continue; - if (textBoxEnd > relEnd) - textBoxEnd = relEnd; - IntRect bounds = textBox->selectionRect(renderX, renderY, - start, textBoxEnd); - bounds.intersect(clipBounds); - if (bounds.isEmpty()) - continue; - bool drawable = false; - for (int index = start; index < textBoxEnd; index++) - if ((drawable |= isNotSpace(chars[index])) != false) - break; - if (drawable && vis != HIDDEN) { - if (AddPartRect(bounds, x, y, result, focusBounds) == false) - return false; - } - if (textBoxEnd == relEnd) - break; - } while ((textBox = textBox->nextTextBox()) != NULL); - return true; -} - -bool CacheBuilder::ConstructTextRects(Text* node, int start, - Text* last, int end, int x, int y, IntRect* focusBounds, - const IntRect& clipBounds, WTF::Vector<IntRect>* result) -{ - result->clear(); - *focusBounds = IntRect(0, 0, 0, 0); - do { - RenderText* renderText = (RenderText*) node->renderer(); - int relEnd = node == last ? end : renderText->textLength(); - InlineTextBox *textBox = renderText->firstTextBox(); - if (textBox != NULL) { - do { - if ((int) textBox->end() >= start) - break; - } while ((textBox = textBox->nextTextBox()) != NULL); - if (ConstructTextRect(node, textBox, start, relEnd, - x, y, focusBounds, clipBounds, result) == false) - return false; - } - start = 0; - do { - if (node == last) - return true; - node = (Text*) node->traverseNextNode(); - ASSERT(node != NULL); - } while (node->isTextNode() == false || node->renderer() == NULL); - } while (true); -} - -} diff --git a/WebCore/platform/android/nav/CacheBuilder.h b/WebCore/platform/android/nav/CacheBuilder.h deleted file mode 100644 index de5d153..0000000 --- a/WebCore/platform/android/nav/CacheBuilder.h +++ /dev/null @@ -1,251 +0,0 @@ -/* libs/WebKitLib/WebKit/platform/bridge/android/CacheBuilder.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef CacheBuilder_H -#define CacheBuilder_H - -#include "CachedDebug.h" -#include "CachedNodeType.h" -#include "IntRect.h" -#include "PlatformString.h" -#include "TextDirection.h" -#include "wtf/Vector.h" - -#define NAVIGATION_MAX_PHONE_LENGTH 14 - -namespace android { - class CachedFrame; - class CachedNode; - class CachedRoot; -} - -namespace WebCore { - -class Document; -class Frame; -class FrameAndroid; -class InlineTextBox; -class Node; -class PlatformGraphicsContext; -class RenderFlow; -class RenderObject; -class RenderLayer; -class Text; - -class CacheBuilder { -public: - enum Direction { - UNINITIALIZED = -1, - LEFT, - RIGHT, - UP, - DOWN, - DIRECTION_COUNT, - UP_DOWN = UP & DOWN, // mask and result - RIGHT_DOWN = RIGHT & DOWN, // mask and result - }; - enum FoundState { - FOUND_NONE, - FOUND_PARTIAL, - FOUND_COMPLETE - }; - CacheBuilder(); - void allowAllTextDetection() { mAllowableTypes = android::ALL_CACHEDNODETYPES; } - void buildCache(android::CachedRoot* root); - static bool ConstructPartRects(Node* node, const IntRect& bounds, - IntRect* focusBounds, int x, int y, WTF::Vector<IntRect>* result); - Node* currentFocus() const; - void disallowAddressDetection() { mAllowableTypes = (android::CachedNodeType) ( - mAllowableTypes & ~android::ADDRESS_CACHEDNODETYPE); } - void disallowEmailDetection() { mAllowableTypes = (android::CachedNodeType) ( - mAllowableTypes & ~android::EMAIL_CACHEDNODETYPE); } - void disallowPhoneDetection() { mAllowableTypes = (android::CachedNodeType) ( - mAllowableTypes & ~android::PHONE_CACHEDNODETYPE); } - static FoundState FindAddress(const UChar* , unsigned length, int* start, int* end); - Node* findByCenter(int x, int y) const; - static void GetGlobalOffset(Frame* , int* x, int * y); - static void GetGlobalOffset(Node* , int* x, int * y); - bool outOfDate(); - void setLastFocus(Node* ); - bool validNode(void* framePtr, void* nodePtr) const; -private: - enum AddressProgress { - NO_ADDRESS, - SKIP_TO_SPACE, - HOUSE_NUMBER, - NUMBER_TRAILING_SPACE, - ADDRESS_LINE, - STATE_NAME, - SECOND_HALF, - ZIP_CODE, - PLUS_4, - FIND_STREET - }; - struct NodeWalk { - NodeWalk() { reset(); } - int mStart; - int mEnd; - Node* mFinalNode; - InlineTextBox* mLastInline; - bool mMore; - void reset() { mMore = false; } - }; - struct BoundsPart { - IntRect mRect; - int mStart; - int mEnd; - }; - struct Bounds { - typedef bool (*FindText)(BoundsPart* result, InlineTextBox* , const String& match); - IntRect mNodeBounds; - BoundsPart mPart; - WTF::Vector<BoundsPart> mParts; - char mStore[NAVIGATION_MAX_PHONE_LENGTH + 1]; - android::CachedNodeType mStoreType; - int mPartIndex; - Node* mNode; - Node* mFinalNode; - void reset() { mNode = NULL; } - }; - struct FindState { - int mStartResult; - int mEndResult; - const UChar* mCurrentStart; - const UChar* mEnd; - AddressProgress mProgress; - int mNumberCount; - int mLetterCount; - unsigned mWordCount; - int mLineCount; - const UChar* mFirstLower; - const UChar* mZipStart; - const UChar* mBases[16]; // FIXME: random guess, maybe too small, maybe too big - const UChar* mWords[16]; - const UChar* mStarts[16]; // text is not necessarily contiguous - const char* mStates; - int mEndWord; - int mStateWord; - int mZipHint; - int mSectionLength; - unsigned mNumberWords; // must contain as many bits as mWords contains elements - char* mPattern; - UChar mStore[NAVIGATION_MAX_PHONE_LENGTH + 1]; - UChar* mStorePtr; - UChar mBackOne; - UChar mBackTwo; - UChar mCurrent; - bool mUnparsed; - bool mZipDelimiter; - bool mOpenParen; - bool mInitialized; - bool mContinuationNode; - }; - struct ClipColumnTracker { - IntRect mBounds; - Node* mLastChild; - Node* mNode; - WTF::Vector<IntRect>* mColumns; - int mColumnGap; - TextDirection mDirection; - bool mHasClip; - }; - struct Tracker { - int mCachedNodeIndex; - Node* mLastChild; - Node* mParentLastChild; - bool mSomeParentTakesFocus; - }; - void adjustForColumns(const ClipColumnTracker& track, - android::CachedNode* node, IntRect* bounds); - static bool AddPartRect(IntRect& bounds, int x, int y, - WTF::Vector<IntRect>* result, IntRect* focusBounds); - static bool AnyIsClick(Node* node); - static bool AnyChildIsClick(Node* node); - void BuildFrame(FrameAndroid* root, FrameAndroid* frame, - android::CachedRoot* cachedRoot, android::CachedFrame* cachedFrame); - bool CleanUpContainedNodes(android::CachedFrame* cachedFrame, - const Tracker* last, int lastChildIndex); - static bool ConstructTextRect(Text* textNode, - InlineTextBox* textBox, int start, int relEnd, int x, int y, - IntRect* focusBounds, const IntRect& clip, WTF::Vector<IntRect>* result); - static bool ConstructTextRects(Text* node, int start, - Text* last, int end, int x, int y, IntRect* focusBounds, - const IntRect& clip, WTF::Vector<IntRect>* result); - static FoundState FindPartialAddress(const UChar* , const UChar* , unsigned length, FindState* ); - static FoundState FindPartialEMail(const UChar* , unsigned length, FindState* ); - static FoundState FindPartialNumber(const UChar* , unsigned length, FindState* ); - static FoundState FindPhoneNumber(const UChar* chars, unsigned length, int* start, int* end); - static void FindReset(FindState* ); - static void FindResetNumber(FindState* ); - static FrameAndroid* FrameAnd(CacheBuilder* focusNav); - static FrameAndroid* FrameAnd(const CacheBuilder* focusNav); - static CacheBuilder* Builder(Frame* ); - static Frame* HasFrame(Node* ); - static bool HasOverOrOut(Node* ); - static bool HasTriggerEvent(Node* ); - static bool IsDomainChar(UChar ch); - bool isFocusableText(NodeWalk* , bool oldMore, Node* , android::CachedNodeType* type, - String* exported) const; //returns true if it is focusable - static bool IsMailboxChar(UChar ch); - static bool IsRealNode(Frame* , Node* ); - int overlap(int left, int right); // returns distance scale factor as 16.16 scalar - bool setData(android::CachedFrame* ); - Node* tryFocus(Direction direction); - Node* trySegment(Direction direction, int mainStart, int mainEnd); - Node* mLastKnownFocus; - IntRect mLastKnownFocusBounds; - android::CachedNodeType mAllowableTypes; -#if DUMP_NAV_CACHE -public: - class Debug { -public: - void frameName(char*& namePtr, const char* max) const; - void init(char* buffer, size_t size); - static int ParentIndex(Node* node, int count, Node* parent); - void print() { frames(); } - void print(const char* name); - void wideString(const String& str); -private: - void attr(const AtomicString& name, const AtomicString& value); - void comma(const char* str); - int flowBoxes(RenderFlow* flow, int ifIndex, int indent); - void flush(); - FrameAndroid* frameAnd() const; - void frames(); - void groups(); - bool isFocusable(Node* node); - void localName(Node* node); - void newLine(int indent = 0); - void print(const char* name, unsigned len); - void renderTree(RenderObject* , int indent, Node* , int count); - void setIndent(int ); - void uChar(const UChar* name, unsigned len, bool hex); - void validateFrame(); - void validateStringData(); - void wideString(const UChar* chars, int length, bool hex); - char* mBuffer; - size_t mBufferSize; - int mIndex; - const char* mPrefix; - int mMinPrefix; - } mDebug; -#endif -}; - -} - -#endif diff --git a/WebCore/platform/android/nav/CachedDebug.h b/WebCore/platform/android/nav/CachedDebug.h deleted file mode 100644 index 14b6fad..0000000 --- a/WebCore/platform/android/nav/CachedDebug.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef CachedDebug_H -#define CachedDebug_H - -#ifndef DUMP_NAV_CACHE -#ifdef NDEBUG -#define DUMP_NAV_CACHE 0 -#else -#define DUMP_NAV_CACHE 1 -#endif -#endif - -#ifndef DEBUG_NAV_UI -#ifdef NDEBUG -#define DEBUG_NAV_UI 0 -#else -#define DEBUG_NAV_UI 1 -#endif -#endif - -#if DEBUG_NAV_UI -#define DBG_NAV_LOG(message) LOGD("%s %s", __FUNCTION__, message) -#define DBG_NAV_LOGD(format, ...) LOGD("%s " format, __FUNCTION__, __VA_ARGS__) -#define DBG_NAV_LOGD_ONCE(format, ...) \ -do { \ - static uint32_t savedTime = 0; \ - uint32_t curTime = SkTime::GetMSecs(); \ - uint32_t tempSavedTime = savedTime; \ - savedTime = curTime; \ - if (curTime - tempSavedTime < 100) \ - break; \ - LOGD("%s " format, __FUNCTION__, __VA_ARGS__); \ -} while (false) -#define DEBUG_NAV_UI_LOGD(...) LOGD(__VA_ARGS__) -#else -#define DBG_NAV_LOG(message) ((void)0) -#define DBG_NAV_LOGD(format, ...) ((void)0) -#define DBG_NAV_LOGD_ONCE(format, ...) ((void)0) -#define DEBUG_NAV_UI_LOGD(...) ((void)0) -#endif - -#if DUMP_NAV_CACHE != 0 && !defined DUMP_NAV_CACHE_USING_PRINTF && defined NDEBUG -#define DUMP_NAV_CACHE_USING_PRINTF -#endif - -#if DUMP_NAV_CACHE -#ifdef DUMP_NAV_CACHE_USING_PRINTF -#include <stdio.h> -extern FILE* gNavCacheLogFile; -#define NAV_CACHE_LOG_FILE "/data/data/com.android.browser/navlog" -#define DUMP_NAV_LOGD(...) do { if (gNavCacheLogFile) \ - fprintf(gNavCacheLogFile, __VA_ARGS__); else LOGD(__VA_ARGS__); } while (false) -#else -#define DUMP_NAV_LOGD(...) LOGD(__VA_ARGS__) -#endif -#else -#define DUMP_NAV_LOGD(...) ((void)0) -#endif - -#endif diff --git a/WebCore/platform/android/nav/CachedFrame.cpp b/WebCore/platform/android/nav/CachedFrame.cpp deleted file mode 100644 index 657670d..0000000 --- a/WebCore/platform/android/nav/CachedFrame.cpp +++ /dev/null @@ -1,1303 +0,0 @@ -/* -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "CachedPrefix.h" -#include "CachedHistory.h" -#include "CachedNode.h" -#include "CachedRoot.h" - -#include "CachedFrame.h" - -#define OFFSETOF(type, field) ((char*)&(((type*)1)->field) - (char*)1) // avoids gnu warning - -#define MIN_OVERLAP 3 // if rects overlap by 2 pixels or fewer, treat them as non-intersecting - -namespace android { - -bool CachedFrame::CheckBetween(Direction direction, const WebCore::IntRect& bestRect, - const WebCore::IntRect& prior, WebCore::IntRect* result) -{ - int left, top, width, height; - if (direction & UP_DOWN) { - top = direction == UP ? bestRect.bottom() : prior.bottom(); - int bottom = direction == UP ? prior.y() : bestRect.y(); - height = bottom - top; - if (height < 0) - return false; - left = prior.x(); - int testLeft = bestRect.x(); - if (left > testLeft) - left = testLeft; - int right = prior.right(); - int testRight = bestRect.right(); - if (right < testRight) - right = testRight; - width = right - left; - } else { - left = direction == LEFT ? bestRect.right() : prior.right(); - int right = direction == LEFT ? prior.x() : bestRect.x(); - width = right - left; - if (width < 0) - return false; - top = prior.y(); - int testTop = bestRect.y(); - if (top > testTop) - top = testTop; - int bottom = prior.bottom(); - int testBottom = bestRect.bottom(); - if (bottom < testBottom) - bottom = testBottom; - height = bottom - top; - } - *result = WebCore::IntRect(left, top, width, height); - return true; -} - -bool CachedFrame::checkBetween(BestData* best, Direction direction) -{ - const WebCore::IntRect& bestRect = best->bounds(); - BestData test; - test.mDistance = INT_MAX; - test.mNode = NULL; - int index = direction; - int limit = index + DIRECTION_COUNT; - do { - WebCore::IntRect edges; - Direction check = (Direction) (index & DIRECTION_MASK); - if (CheckBetween(check, bestRect, - history()->priorBounds(), &edges) == false) - continue; - WebCore::IntRect clip = mRoot->scrolledBounds(); - clip.intersect(edges); - if (clip.isEmpty()) - continue; - findClosest(&test, direction, check, &clip); - if (test.mNode == NULL) - continue; - if (direction == check) - break; - } while (++index < limit); - if (test.mNode == NULL) - return false; - *best = test; - return true; -} - -bool CachedFrame::checkVisited(const CachedNode* node, Direction direction) const -{ - return history()->checkVisited(node, direction); -} - -void CachedFrame::clearFocus() -{ - if (mFocus < 0) - return; - CachedNode& focus = mCachedNodes[mFocus]; - focus.clearFocus(this); - mFocus = -1; -} - -// the thing that sucks is that when you're on a link, you want to navigate next door to a link just like this one, but can't make it -// so with all my other sucky compares, maybe there needs to be one that prefers links that are aligned with the current focus... - -// returns 0 if test is preferable to best, 1 if not preferable, or -1 if unknown -int CachedFrame::compare(BestData& testData, const BestData& bestData, const CachedNode* focus) const -{ -// start here; - // if the test minor axis line intersects the line segment between focus center and best center, choose it - // give more weight to exact major axis alignment (rows, columns) - if (testData.mInNav != bestData.mInNav) { - if (bestData.mInNav) { - testData.mNode->setCondition(CachedNode::IN_FOCUS); - return REJECT_TEST; - } - return TEST_IS_BEST; - } - if (testData.mInNav) { - if (bestData.mMajorDelta < testData.mMajorDelta) { - testData.mNode->setCondition(CachedNode::CLOSER_IN_FOCUS); - return REJECT_TEST; - } - if (testData.mMajorDelta < bestData.mMajorDelta) - return TEST_IS_BEST; - } - if (testData.mMajorDelta < 0 && bestData.mMajorDelta >= 0) { - testData.mNode->setCondition(CachedNode::FURTHER); - return REJECT_TEST; - } - if ((testData.mMajorDelta ^ bestData.mMajorDelta) < 0) // one above, one below (or one left, one right) - return TEST_IS_BEST; -// SkFixed focusMultiplier = SK_Fixed1; -// if (focus != NULL) { -// if (testData.mMajorDelta < bestData.mMajorDelta) { -// // use bestData.mMajorDelta, -// } else if (bestData.mMajorDelta < testData.mMajorDelta) { -// -// } - bool bestInWorking = bestData.inOrSubsumesWorking(); - bool testInWorking = testData.inOrSubsumesWorking(); - if (bestInWorking && testData.mWorkingOutside && testData.mNavOutside) { - testData.mNode->setCondition(CachedNode::IN_WORKING); - return REJECT_TEST; - } - if (testInWorking && bestData.mWorkingOutside && bestData.mNavOutside) - return TEST_IS_BEST; - bool bestInNav = directionChange() && bestData.inOrSubsumesNav(); - bool testInNav = directionChange() && testData.inOrSubsumesNav(); - if (bestInWorking == false && testInWorking == false) { - if (bestInNav && testData.mNavOutside) { - testData.mNode->setCondition(CachedNode::IN_UMBRA); - return REJECT_TEST; - } - if (testInNav && bestData.mNavOutside) - return TEST_IS_BEST; - } -#if 01 // hopefully butt test will remove need for this - if (testData.mFocusChild != bestData.mFocusChild) { - if (bestData.mFocusChild) { - testData.mNode->setCondition(CachedNode::IN_FOCUS_CHILDREN); - return REJECT_TEST; - } - return TEST_IS_BEST; - } -#endif - bool bestTestIn = (bestInWorking || bestInNav) && (testInWorking || testInNav); - bool testOverlap = bestTestIn || (testData.mWorkingOverlap != 0 && bestData.mWorkingOverlap == 0); - bool bestOverlap = bestTestIn || (testData.mWorkingOverlap == 0 && bestData.mWorkingOverlap != 0); -#if 01 // this isn't working? - if (testOverlap == bestOverlap) { - if (bestData.mMajorButt < 10 && testData.mMajorButt >= 40) { - testData.mNode->setCondition(CachedNode::BUTTED_UP); - return REJECT_TEST; - } - if (testData.mMajorButt < 10 && bestData.mMajorButt >= 40) - return TEST_IS_BEST; - } -#endif - if (bestOverlap && bestData.mMajorDelta < testData.mMajorDelta) { // choose closest major axis center - testData.mNode->setCondition(CachedNode::CLOSER); - return REJECT_TEST; - } - if (testOverlap && testData.mMajorDelta < bestData.mMajorDelta) - return TEST_IS_BEST; - if (bestOverlap && bestData.mMajorDelta2 < testData.mMajorDelta2) { - testData.mNode->setCondition(CachedNode::CLOSER_TOP); - return REJECT_TEST; - } - if (testOverlap && testData.mMajorDelta2 < bestData.mMajorDelta2) - return TEST_IS_BEST; -#if 01 - if (bestOverlap && ((bestData.mSideDistance <= 0 && testData.mSideDistance > 0) || - abs(bestData.mSideDistance) < abs(testData.mSideDistance))) { - testData.mNode->setCondition(CachedNode::LEFTMOST); - return REJECT_TEST; - } - if (testOverlap && ((testData.mSideDistance <= 0 && bestData.mSideDistance > 0) || - abs(testData.mSideDistance) < abs(bestData.mSideDistance))) - return TEST_IS_BEST; -// fix me : the following ASSERT fires -- not sure if this case should be handled or not -// ASSERT(bestOverlap == false && testOverlap == false); -#endif - SkFixed testMultiplier = testData.mWorkingOverlap > testData.mNavOverlap ? - testData.mWorkingOverlap : testData.mNavOverlap; - SkFixed bestMultiplier = bestData.mWorkingOverlap > bestData.mNavOverlap ? - bestData.mWorkingOverlap : bestData.mNavOverlap; - int testDistance = testData.mDistance; - int bestDistance = bestData.mDistance; -// start here; - // this fails if they're off by 1 - // try once again to implement sliding scale so that off by 1 is nearly like zero, - // and off by a lot causes sideDistance to have little or no effect - // try elliptical distance -- lengthen side contribution - // these ASSERTs should not fire, but do fire on mail.google.com - // can't debug yet, won't reproduce - ASSERT(testDistance >= 0); - ASSERT(bestDistance >= 0); - testDistance += testDistance; // multiply by 2 - testDistance *= testDistance; - bestDistance += bestDistance; // multiply by 2 - bestDistance *= bestDistance; - int side = testData.mSideDistance; - int negative = side < 0 && bestData.mSideDistance > 0; - side *= side; - if (negative) - side = -side; - testDistance += side; - side = bestData.mSideDistance; - negative = side < 0 && testData.mSideDistance > 0; - side *= side; - if (negative) - side = -side; - bestDistance += side; - if (testMultiplier > (SK_Fixed1 >> 1) || bestMultiplier > (SK_Fixed1 >> 1)) { // considerable working overlap? - testDistance = SkFixedMul(testDistance, bestMultiplier); - bestDistance = SkFixedMul(bestDistance, testMultiplier); - } - if (bestDistance < testDistance) { - testData.mNode->setCondition(CachedNode::CLOSER_OVERLAP); - return REJECT_TEST; - } - if (testDistance < bestDistance) - return TEST_IS_BEST; -#if 0 - int distance = testData.mDistance + testData.mSideDistance; - int best = bestData.mDistance + bestData.mSideDistance; - if (distance > best) { - testData.mNode->setCondition(CachedNode::CLOSER_RAW_DISTANCE); - return REJECT_TEST; - } - else if (distance < best) - return TEST_IS_BEST; - best = bestData.mSideDistance; - if (testData.mSideDistance > best) { - testData.mNode->setCondition(CachedNode::SIDE_DISTANCE); - return REJECT_TEST; - } - if (testData.mSideDistance < best) - return TEST_IS_BEST; -#endif - if (testData.mPreferred < bestData.mPreferred) { - testData.mNode->setCondition(CachedNode::PREFERRED); - return REJECT_TEST; - } - if (testData.mPreferred > bestData.mPreferred) - return TEST_IS_BEST; - return UNDECIDED; -} - -bool CachedFrame::containsFrame(const CachedFrame* test) const -{ - if (this == test) - return true; - for (const CachedFrame* frame = mCachedFrames.begin(); - frame != mCachedFrames.end(); frame++) { - if (frame->containsFrame(test)) - return true; - } - return false; -} - -const CachedNode* CachedFrame::currentFocus(const CachedFrame** framePtr) const -{ - if (framePtr) - *framePtr = this; - if (mFocus < 0) - return NULL; - const CachedNode* result = &mCachedNodes[mFocus]; - const CachedFrame* frame = hasFrame(result); - if (frame != NULL) - return frame->currentFocus(framePtr); - (const_cast<CachedNode*>(result))->fixUpFocusRects(); - return result; -} - -bool CachedFrame::directionChange() const -{ - return history()->directionChange(); -} - -#ifdef BROWSER_DEBUG -CachedNode* CachedFrame::find(WebCore::Node* node) // !!! probably debugging only -{ - for (CachedNode* test = mCachedNodes.begin(); test != mCachedNodes.end(); test++) - if (node == test->webCoreNode()) - return test; - for (CachedFrame* frame = mCachedFrames.begin(); frame != mCachedFrames.end(); - frame++) { - CachedNode* result = frame->find(node); - if (result != NULL) - return result; - } - return NULL; -} -#endif - -const CachedNode* CachedFrame::findBestAt(const WebCore::IntRect& rect, - int* best, const CachedNode** directHit, const CachedFrame** framePtr, int* x, int* y) const -{ - const CachedNode* result = NULL; - int rectWidth = rect.width(); - WebCore::IntPoint center = WebCore::IntPoint(rect.x() + (rectWidth >> 1), - rect.y() + (rect.height() >> 1)); - mRoot->setupScrolledBounds(); - for (const CachedNode* test = mCachedNodes.begin(); test != mCachedNodes.end(); test++) { - if (test->disabled()) - continue; - size_t parts = test->navableRects(); - BestData testData; - testData.mNode = test; - testData.mMouseBounds = testData.mNodeBounds = test->getBounds(); - bool checkForHidden = true; - for (size_t part = 0; part < parts; part++) { - if (test->focusRings().at(part).intersects(rect)) { - if (checkForHidden && mRoot->maskIfHidden(&testData) == true) - break; - checkForHidden = false; - WebCore::IntRect testRect = test->focusRings().at(part); - testRect.intersect(testData.mMouseBounds); - if (testRect.contains(center)) { - // We have a direct hit. - if (*directHit == NULL) { - *directHit = test; - *framePtr = this; - *x = center.x(); - *y = center.y(); - } else { - // We have hit another one before - const CachedNode* d = *directHit; - if (d->getBounds().contains(testRect)) { - // This rectangle is inside the other one, so it is - // the best one. - *directHit = test; - *framePtr = this; - } - } - } - if (NULL != *directHit) { - // If we have a direct hit already, there is no need to - // calculate the distances, or check the other focusring parts - break; - } - WebCore::IntRect both = rect; - int smaller = testRect.width() < testRect.height() ? - testRect.width() : testRect.height(); - smaller -= rectWidth; - int inset = smaller < rectWidth ? smaller : rectWidth; - inset >>= 1; // inflate doubles the width decrease - if (inset > 1) - both.inflate(1 - inset); - both.intersect(testRect); - if (both.isEmpty()) - continue; - WebCore::IntPoint testCenter = WebCore::IntPoint(testRect.x() + - (testRect.width() >> 1), testRect.y() + (testRect.height() >> 1)); - int dx = testCenter.x() - center.x(); - int dy = testCenter.y() - center.y(); - int distance = dx * dx + dy * dy; - if (*best > distance) { - *best = distance; - result = test; - *framePtr = this; - *x = both.x() + (both.width() >> 1); - *y = both.y() + (both.height() >> 1); - } - } - } - } - for (const CachedFrame* frame = mCachedFrames.begin(); - frame != mCachedFrames.end(); frame++) { - const CachedNode* frameResult = frame->findBestAt(rect, best, directHit, - framePtr, x, y); - if (NULL != frameResult) - result = frameResult; - } - if (NULL != *directHit) { - result = *directHit; - } - return result; -} - -const CachedFrame* CachedFrame::findBestFrameAt(int x, int y) const -{ - if (mLocalViewBounds.contains(x, y) == false) - return NULL; - const CachedFrame* result = this; - for (const CachedFrame* frame = mCachedFrames.begin(); - frame != mCachedFrames.end(); frame++) { - const CachedFrame* frameResult = frame->findBestFrameAt(x, y); - if (NULL != frameResult) - result = frameResult; - } - return result; -} - -const CachedNode* CachedFrame::findBestHitAt(const WebCore::IntRect& rect, - int* best, const CachedFrame** framePtr, int* x, int* y) const -{ - const CachedNode* result = NULL; - int rectWidth = rect.width(); - WebCore::IntPoint center = WebCore::IntPoint(rect.x() + (rectWidth >> 1), - rect.y() + (rect.height() >> 1)); - mRoot->setupScrolledBounds(); - for (const CachedNode* test = mCachedNodes.begin(); test != mCachedNodes.end(); test++) { - if (test->disabled()) - continue; - const WebCore::IntRect& testRect = test->hitBounds(); - if (testRect.intersects(rect) == false) - continue; - BestData testData; - testData.mNode = test; - testData.mMouseBounds = testData.mNodeBounds = testRect; - if (mRoot->maskIfHidden(&testData) == true) - continue; - const WebCore::IntRect& bounds = testData.mMouseBounds; - WebCore::IntPoint testCenter = WebCore::IntPoint(bounds.x() + - (bounds.width() >> 1), bounds.y() + (bounds.height() >> 1)); - int dx = testCenter.x() - center.x(); - int dy = testCenter.y() - center.y(); - int distance = dx * dx + dy * dy; - if (*best <= distance) - continue; - *best = distance; - result = test; - *framePtr = this; - const WebCore::IntRect& focusRect = test->focusRings().at(0); - *x = focusRect.x() + (focusRect.width() >> 1); - *y = focusRect.y() + (focusRect.height() >> 1); - } - for (const CachedFrame* frame = mCachedFrames.begin(); - frame != mCachedFrames.end(); frame++) { - const CachedNode* frameResult = frame->findBestHitAt(rect, best, - framePtr, x, y); - if (NULL != frameResult) - result = frameResult; - } - return result; -} - -void CachedFrame::findClosest(BestData* bestData, Direction originalDirection, - Direction direction, WebCore::IntRect* clip) const -{ - const CachedNode* test = mCachedNodes.begin(); - while ((test = test->traverseNextNode()) != NULL) { - const CachedFrame* child = hasFrame(test); - if (child != NULL) { - const CachedNode* childDoc = child->validDocument(); - if (childDoc == NULL) - continue; - child->findClosest(bestData, originalDirection, direction, clip); - } - if (test->noSecondChance()) - continue; - if (test->isFocusable(*clip) == false) - continue; - if (checkVisited(test, originalDirection) == false) - continue; - size_t partMax = test->navableRects(); - for (size_t part = 0; part < partMax; part++) { - WebCore::IntRect testBounds = test->focusRings().at(part); - if (clip->intersects(testBounds) == false) - continue; - if (clip->contains(testBounds) == false) { - if (direction & UP_DOWN) { -// if (testBounds.x() > clip->x() || testBounds.right() < clip->right()) -// continue; - testBounds.setX(clip->x()); - testBounds.setWidth(clip->width()); - } else { -// if (testBounds.y() > clip->y() || testBounds.bottom() < clip->bottom()) -// continue; - testBounds.setY(clip->y()); - testBounds.setHeight(clip->height()); - } - if (clip->contains(testBounds) == false) - continue; - } - int distance; - // seems like distance for UP for instance needs to be 'test top closest to - // clip bottom' -- keep the old code but try this instead - switch (direction) { -#if 0 - case LEFT: distance = testBounds.x() - clip->x(); break; - case RIGHT: distance = clip->right() - testBounds.right(); break; - case UP: distance = testBounds.y() - clip->y(); break; - case DOWN: distance = clip->bottom() - testBounds.bottom(); break; -#else - case LEFT: distance = clip->right() - testBounds.x(); break; - case RIGHT: distance = testBounds.right() - clip->x(); break; - case UP: distance = clip->bottom() - testBounds.y(); break; - case DOWN: distance = testBounds.bottom() - clip->y(); break; -#endif - default: - distance = 0; ASSERT(0); - } - if (distance < bestData->mDistance) { - bestData->mNode = test; - bestData->mFrame = this; - bestData->mDistance = distance; - bestData->mMouseBounds = bestData->mNodeBounds = - test->focusRings().at(part); - CachedHistory* cachedHistory = history(); - switch (direction) { - case LEFT: - bestData->setLeftDirection(cachedHistory); - break; - case RIGHT: - bestData->setRightDirection(cachedHistory); - break; - case UP: - bestData->setUpDirection(cachedHistory); - break; - case DOWN: - bestData->setDownDirection(cachedHistory); - break; - default: - ASSERT(0); - } - } - } - } -} - -bool CachedFrame::finishInit() -{ - CachedNode* lastCached = lastNode(); - lastCached->setLast(); - CachedFrame* child = mCachedFrames.begin(); - while (child != mCachedFrames.end()) { - child->mParent = this; - if (child->finishInit()) - setFocusIndex(child->indexInParent()); - child++; - } - return focusIndex() > 0; -} - -const CachedNode* CachedFrame::frameDown(const CachedNode* test, const CachedNode* limit, BestData* bestData, - const CachedNode* focus) const -{ - BestData originalData = *bestData; - do { - if (moveInFrame(&CachedFrame::frameDown, test, bestData, focus)) - continue; - BestData testData; - if (frameNodeCommon(testData, test, bestData, &originalData, focus) == REJECT_TEST) - continue; - if (checkVisited(test, DOWN) == false) - continue; - size_t parts = test->navableRects(); - for (size_t part = 0; part < parts; part++) { - testData.mNodeBounds = test->focusRings().at(part); - if (testData.setDownDirection(history())) - continue; - int result = framePartCommon(testData, test, bestData, focus); - if (result == REJECT_TEST) - continue; - if (result == 0 && limit == NULL) { // retry all data up to this point, since smaller may have replaced node preferable to larger - BestData innerData = testData; - frameDown(document(), test, &innerData, focus); - if (checkVisited(innerData.mNode, DOWN)) { - *bestData = innerData; - continue; - } - } - if (checkVisited(test, DOWN)) - *bestData = testData; - } - } while ((test = test->traverseNextNode()) != limit); - ASSERT(focus == NULL || bestData->mNode != focus); - // does the best contain something (or, is it contained by an area which is not the focus?) - // if so, is the conainer/containee should have been chosen, but wasn't -- so there's a better choice - // in the doc list prior to this choice - // - return bestData->mNode; -} - -const CachedNode* CachedFrame::frameLeft(const CachedNode* test, const CachedNode* limit, BestData* bestData, - const CachedNode* focus) const -{ - BestData originalData = *bestData; - do { - if (moveInFrame(&CachedFrame::frameLeft, test, bestData, focus)) - continue; - BestData testData; - if (frameNodeCommon(testData, test, bestData, &originalData, focus) == REJECT_TEST) - continue; - if (checkVisited(test, LEFT) == false) - continue; - size_t parts = test->navableRects(); - for (size_t part = 0; part < parts; part++) { - testData.mNodeBounds = test->focusRings().at(part); - if (testData.setLeftDirection(history())) - continue; - int result = framePartCommon(testData, test, bestData, focus); - if (result == REJECT_TEST) - continue; - if (result == 0 && limit == NULL) { // retry all data up to this point, since smaller may have replaced node preferable to larger - BestData innerData = testData; - frameLeft(document(), test, &innerData, focus); - if (checkVisited(innerData.mNode, LEFT)) { - *bestData = innerData; - continue; - } - } - if (checkVisited(test, LEFT)) - *bestData = testData; - } - } while ((test = test->traverseNextNode()) != limit); // FIXME ??? left and up should use traversePreviousNode to choose reverse document order - ASSERT(focus == NULL || bestData->mNode != focus); - return bestData->mNode; -} - -int CachedFrame::frameNodeCommon(BestData& testData, const CachedNode* test, BestData* bestData, BestData* originalData, - const CachedNode* focus) const -{ - testData.mFrame = this; - testData.mNode = test; - test->clearCondition(); - if (test->disabled()) { - testData.mNode->setCondition(CachedNode::DISABLED); - return REJECT_TEST; - } - if (mRoot->scrolledBounds().intersects(test->bounds()) == false) { - testData.mNode->setCondition(CachedNode::FOCUSABLE); - return REJECT_TEST; - } -// if (isFocusable(test, &testData.mNodeBounds, walk) == false) { -// testData.mNode->setCondition(CachedNode::FOCUSABLE); -// return REJECT_TEST; -// } -// - if (test == focus) { - testData.mNode->setCondition(CachedNode::NOT_FOCUS_NODE); - return REJECT_TEST; - } -// if (test->bounds().contains(history()->focusBounds())) { -// testData.mNode->setCondition(CachedNode::NOT_ENCLOSING_FOCUS); -// return REJECT_TEST; -// } - void* par = focus ? focus->parentGroup() : NULL; - testData.mFocusChild = test->parentGroup() == par; -#if 0 // not debugged - if (focus && focus->hasMouseOver() && test->hasMouseOver() == false && - focus->bounds().contains(test->bounds())) - return REJECT_TEST; -#endif - if (bestData->mNode == NULL) - return TEST_IS_BEST; -#if 0 // not debugged - if (focus && focus->hasMouseOver() && test->hasMouseOver() == false && - focus->bounds().contains(test->bounds())) - return REJECT_TEST; - if (test->hasMouseOver() != bestData->mNode->hasMouseOver()) { - if (test->hasMouseOver()) { - if (test->bounds().contains(bestData->mNode->bounds())) { - const_cast<CachedNode*>(bestData->mNode)->setDisabled(true); - bestData->mNode = NULL; // force part tests to be ignored, yet still set up remaining test data for later comparison - return TEST_IS_BEST; - } - } else { - if (bestData->mNode->bounds().contains(test->bounds())) { - test->setCondition(CachedNode::ANCHOR_IN_ANCHOR); - return REJECT_TEST; - } - } - } -#endif - if (focus && testData.mNode->parentIndex() != bestData->mNode->parentIndex()) { - int focusParentIndex = focus->parentIndex(); - if (focusParentIndex >= 0) { - if (bestData->mNode->parentIndex() == focusParentIndex) - return REJECT_TEST; - if (testData.mNode->parentIndex() == focusParentIndex) - return TEST_IS_BEST; - } - } - if (testData.mNode->parent() == bestData->mNode) { - testData.mNode->setCondition(CachedNode::CHILD); - return REJECT_TEST; - } - if (testData.mNode == bestData->mNode->parent()) - return TEST_IS_BEST; - int testInBest = testData.isContainer(bestData); /* -1 pick best over test, 0 no containership, 1 pick test over best */ - if (testInBest == 1) { - if (test->isArea() || bestData->mNode->isArea()) - return UNDECIDED; - bestData->mNode = NULL; // force part tests to be ignored, yet still set up remaining test data for later comparisons - return TEST_IS_BEST; - } - if (testInBest == -1) { - testData.mNode->setCondition(CachedNode::OUTSIDE_OF_BEST); - return REJECT_TEST; - } - if (originalData->mNode != NULL) { // test is best case - testInBest = testData.isContainer(originalData); - if (testInBest == -1) { /* test is inside best */ - testData.mNode->setCondition(CachedNode::OUTSIDE_OF_ORIGINAL); - return REJECT_TEST; - } - } - return UNDECIDED; -} - -int CachedFrame::framePartCommon(BestData& testData, - const CachedNode* test, BestData* bestData, const CachedNode* focus) const -{ - if (testData.mNodeBounds.contains(history()->focusBounds())) { - testData.mNode->setCondition(CachedNode::NOT_ENCLOSING_FOCUS); - return REJECT_TEST; - } - testData.setDistances(); - if (bestData->mNode != NULL) { - int compared = compare(testData, *bestData, focus); - if (compared == 0 && test->isArea() == false && bestData->mNode->isArea() == false) - goto pickTest; - if (compared >= 0) - return compared; - } -pickTest: - return -1; // pick test -} - -const CachedNode* CachedFrame::frameRight(const CachedNode* test, const CachedNode* limit, BestData* bestData, - const CachedNode* focus) const -{ - BestData originalData = *bestData; - do { - if (moveInFrame(&CachedFrame::frameRight, test, bestData, focus)) - continue; - BestData testData; - if (frameNodeCommon(testData, test, bestData, &originalData, focus) == REJECT_TEST) - continue; - if (checkVisited(test, RIGHT) == false) - continue; - size_t parts = test->navableRects(); - for (size_t part = 0; part < parts; part++) { - testData.mNodeBounds = test->focusRings().at(part); - if (testData.setRightDirection(history())) - continue; - int result = framePartCommon(testData, test, bestData, focus); - if (result == REJECT_TEST) - continue; - if (result == 0 && limit == NULL) { // retry all data up to this point, since smaller may have replaced node preferable to larger - BestData innerData = testData; - frameRight(document(), test, &innerData, focus); - if (checkVisited(innerData.mNode, RIGHT)) { - *bestData = innerData; - continue; - } - } - if (checkVisited(test, RIGHT)) - *bestData = testData; - } - } while ((test = test->traverseNextNode()) != limit); - ASSERT(focus == NULL || bestData->mNode != focus); - return bestData->mNode; -} - -const CachedNode* CachedFrame::frameUp(const CachedNode* test, const CachedNode* limit, BestData* bestData, - const CachedNode* focus) const -{ - BestData originalData = *bestData; - do { - if (moveInFrame(&CachedFrame::frameUp, test, bestData, focus)) - continue; - BestData testData; - if (frameNodeCommon(testData, test, bestData, &originalData, focus) == REJECT_TEST) - continue; - if (checkVisited(test, UP) == false) - continue; - size_t parts = test->navableRects(); - for (size_t part = 0; part < parts; part++) { - testData.mNodeBounds = test->focusRings().at(part); - if (testData.setUpDirection(history())) - continue; - int result = framePartCommon(testData, test, bestData, focus); - if (result == REJECT_TEST) - continue; - if (result == 0 && limit == NULL) { // retry all data up to this point, since smaller may have replaced node preferable to larger - BestData innerData = testData; - frameUp(document(), test, &innerData, focus); - if (checkVisited(innerData.mNode, UP)) { - *bestData = innerData; - continue; - } - } - if (checkVisited(test, UP)) - *bestData = testData; - } - } while ((test = test->traverseNextNode()) != limit); // FIXME ??? left and up should use traversePreviousNode to choose reverse document order - ASSERT(focus == NULL || bestData->mNode != focus); - return bestData->mNode; -} - -const CachedFrame* CachedFrame::hasFrame(const CachedNode* node) const -{ - return node->isFrame() ? &mCachedFrames[node->childFrameIndex()] : NULL; -} - -CachedHistory* CachedFrame::history() const -{ - return mRoot->rootHistory(); -} - -void CachedFrame::init(const CachedRoot* root, int childFrameIndex, - WebCore::FrameAndroid* frame) -{ - mContents = WebCore::IntRect(0, 0, 0, 0); // fixed up for real in setData() - mLocalViewBounds = WebCore::IntRect(0, 0, 0, 0); - mViewBounds = WebCore::IntRect(0, 0, 0, 0); - mRoot = root; - mFocus = -1; - mFrame = frame; - mParent = NULL; // set up parents after stretchy arrays are set up - mIndex = childFrameIndex; -} - -int CachedFrame::minWorkingHorizontal() const -{ - return history()->minWorkingHorizontal(); -} - -int CachedFrame::minWorkingVertical() const -{ - return history()->minWorkingVertical(); -} - -int CachedFrame::maxWorkingHorizontal() const -{ - return history()->maxWorkingHorizontal(); -} - -int CachedFrame::maxWorkingVertical() const -{ - return history()->maxWorkingVertical(); -} - -bool CachedFrame::moveInFrame(MoveInDirection moveInDirection, - const CachedNode* test, BestData* bestData, - const CachedNode* focus) const -{ - const CachedFrame* frame = hasFrame(test); - if (frame == NULL) - return false; // if it's not a frame, let the caller have another swing at it - const CachedNode* childDoc = frame->validDocument(); - if (childDoc == NULL) - return true; - (frame->*moveInDirection)(childDoc, NULL, bestData, focus); - return true; -} - -const WebCore::IntRect& CachedFrame::_navBounds() const -{ - return history()->navBounds(); -} - -void CachedFrame::resetClippedOut() -{ - for (CachedNode* test = mCachedNodes.begin(); test != mCachedNodes.end(); test++) - { - if (test->clippedOut()) { - test->setDisabled(false); - test->setClippedOut(false); - } - } - for (CachedFrame* frame = mCachedFrames.begin(); frame != mCachedFrames.end(); - frame++) { - frame->resetClippedOut(); - } -} - -void CachedFrame::setData() -{ - if (this != mRoot) { - mViewBounds = mLocalViewBounds; - mViewBounds.intersect(mRoot->mViewBounds); - } - int x, y; - if (parent() == NULL) - x = y = 0; - else { - x = mLocalViewBounds.x(); - y = mLocalViewBounds.y(); - } - mContents.setX(x); - mContents.setY(y); - CachedFrame* child = mCachedFrames.begin(); - while (child != mCachedFrames.end()) { - child->setData(); - child++; - } -} - -bool CachedFrame::setFocus(WebCore::Frame* frame, WebCore::Node* node, - int x, int y) -{ - if (NULL == node) { - const_cast<CachedRoot*>(mRoot)->setCachedFocus(NULL, NULL); - return true; - } - if (mFrame != frame) { - for (CachedFrame* testF = mCachedFrames.begin(); testF != mCachedFrames.end(); - testF++) { - if (testF->setFocus(frame, node, x, y)) - return true; - } - DBG_NAV_LOGD("no frame frame=%p node=%p", frame, node); - return false; - } - bool first = true; - CachedNode const * const end = mCachedNodes.end(); - do { - for (CachedNode* test = mCachedNodes.begin(); test != end; test++) { - if (test->nodePointer() != node && first) - continue; - size_t partMax = test->navableRects(); - WTF::Vector<WebCore::IntRect>& focusRings = test->focusRings(); - for (size_t part = 0; part < partMax; part++) { - const WebCore::IntRect& testBounds = focusRings.at(part); - if (testBounds.contains(x, y) == false) - continue; - if (test->isFocus()) { - DBG_NAV_LOGD("already set? test=%d frame=%p node=%p x=%d y=%d", - test->index(), frame, node, x, y); - return true; - } - const_cast<CachedRoot*>(mRoot)->setCachedFocus(this, test); - return true; - } - } - DBG_NAV_LOGD("moved? frame=%p node=%p x=%d y=%d", frame, node, x, y); - } while ((first ^= true) == false); -failed: - DBG_NAV_LOGD("no match frame=%p node=%p", frame, node); - return false; -} - -const CachedNode* CachedFrame::validDocument() const -{ - const CachedNode* doc = document(); - return doc != NULL && mViewBounds.isEmpty() == false ? doc : NULL; -} - -bool CachedFrame::BestData::canBeReachedByAnotherDirection() -{ - if (mMajorButt > -MIN_OVERLAP) - return false; - mMajorButt = -mMajorButt; - return mNavOutside; -} - -int CachedFrame::BestData::isContainer(CachedFrame::BestData* other) -{ - int _x = x(); - int otherRight = other->right(); - if (_x >= otherRight) - return 0; // does not intersect - int _y = y(); - int otherBottom = other->bottom(); - if (_y >= otherBottom) - return 0; // does not intersect - int _right = right(); - int otherX = other->x(); - if (otherX >= _right) - return 0; // does not intersect - int _bottom = bottom(); - int otherY = other->y(); - if (otherY >= _bottom) - return 0; // does not intersect - int intoX = otherX - _x; - int intoY = otherY - _y; - int intoRight = otherRight - _right; - int intoBottom = otherBottom - _bottom; - bool contains = intoX >= 0 && intoY >= 0 && intoRight <= 0 && intoBottom <= 0; - if (contains && mNode->partRectsContains(other->mNode)) { -// if (mIsArea == false && hasMouseOver()) -// other->mMouseOver = mNode; - return mNode->isArea() ? 1 : -1; - } - bool containedBy = intoX <= 0 && intoY <= 0 && intoRight >= 0 && intoBottom >= 0; - if (containedBy && other->mNode->partRectsContains(mNode)) { -// if (other->mIsArea == false && other->hasMouseOver()) -// mMouseOver = other->mNode; - return other->mNode->isArea() ? -1 : 1; - } - return 0; -} - -// distance scale factor factor as a 16.16 scalar -SkFixed CachedFrame::BestData::Overlap(int span, int left, int right) -{ - unsigned result; - if (left > 0 && left < span && right > span) - result = (unsigned) left; - else if (right > 0 && right < span && left > span) - result = (unsigned) right; - else if (left > 0 && right > 0) - return SK_Fixed1; - else - return 0; - result = (result << 16) / (unsigned) span; // linear proportion, always less than fixed 1 - return (SkFixed) result; -// !!! experiment with weight -- enable if overlaps are preferred too much -// or reverse weighting if overlaps are preferred to little -// return (SkFixed) (result * result >> 16); // but fall off with square -} - -void CachedFrame::BestData::setDistances() -{ - mDistance = abs(mMajorDelta); - int sideDistance = mWorkingDelta; - if (mWorkingOverlap < SK_Fixed1) { - if (mPreferred > 0) - sideDistance = mWorkingDelta2; - } else if (sideDistance >= 0 && mWorkingDelta2 >=- 0) - sideDistance = 0; - else { - ASSERT(sideDistance <= 0 && mWorkingDelta2 <= 0); - if (sideDistance < mWorkingDelta2) - sideDistance = mWorkingDelta2; - } - // if overlap, smaller abs mWorkingDelta is better, smaller abs majorDelta is better - // if not overlap, positive mWorkingDelta is better - mSideDistance = sideDistance; -} - -bool CachedFrame::BestData::setDownDirection(const CachedHistory* history) -{ - const WebCore::IntRect& navBounds = history->navBounds(); - mMajorButt = mNodeBounds.y() - navBounds.bottom(); - int testX = mNodeBounds.x(); - int testRight = mNodeBounds.right(); - setNavOverlap(navBounds.width(), navBounds.right() - testX, - testRight - navBounds.x()); - if (canBeReachedByAnotherDirection()) { - mNode->setCondition(CachedNode::BEST_DIRECTION); - return REJECT_TEST; - } - int inNavTop = mNodeBounds.y() - navBounds.y(); - mMajorDelta2 = inNavTop; - mMajorDelta = mMajorDelta2 + ((mNodeBounds.height() - - navBounds.height()) >> 1); - if (mMajorDelta2 <= 1 && mMajorDelta <= 1) { - mNode->setCondition(CachedNode::CENTER_FURTHER); // never move up or sideways - return REJECT_TEST; - } - int inNavBottom = navBounds.bottom() - mNodeBounds.bottom(); - setNavInclusion(testRight - navBounds.right(), navBounds.x() - testX); - bool subsumes = navBounds.height() > 0 && inOrSubsumesNav(); - if (inNavTop <= 0 && inNavBottom <= 0 && subsumes) { - mNode->setCondition(CachedNode::NOT_ENCLOSING_FOCUS); - return REJECT_TEST; - } - int maxV = history->maxWorkingVertical(); - int minV = history->minWorkingVertical(); - setWorkingOverlap(testRight - testX, maxV - testX, testRight - minV); - setWorkingInclusion(testRight - maxV, minV - testX); - if (mWorkingOverlap == 0 && mNavOverlap == 0 && inNavBottom >= 0) { - mNode->setCondition(CachedNode::OVERLAP_OR_EDGE_FURTHER); - return REJECT_TEST; - } - mInNav = history->directionChange() && inNavTop >= 0 && - inNavBottom > 0 && subsumes; - return false; -} - -bool CachedFrame::BestData::setLeftDirection(const CachedHistory* history) -{ - const WebCore::IntRect& navBounds = history->navBounds(); - mMajorButt = navBounds.x() - mNodeBounds.right(); - int testY = mNodeBounds.y(); - int testBottom = mNodeBounds.bottom(); - setNavOverlap(navBounds.height(), navBounds.bottom() - testY, - testBottom - navBounds.y()); - if (canBeReachedByAnotherDirection()) { - mNode->setCondition(CachedNode::BEST_DIRECTION); - return REJECT_TEST; - } - int inNavRight = navBounds.right() - mNodeBounds.right(); - mMajorDelta2 = inNavRight; - mMajorDelta = mMajorDelta2 - ((navBounds.width() - - mNodeBounds.width()) >> 1); - if (mMajorDelta2 <= 1 && mMajorDelta <= 1) { - mNode->setCondition(CachedNode::CENTER_FURTHER); // never move right or sideways - return REJECT_TEST; - } - int inNavLeft = mNodeBounds.x() - navBounds.x(); - setNavInclusion(navBounds.y() - testY, testBottom - navBounds.bottom()); - bool subsumes = navBounds.width() > 0 && inOrSubsumesNav(); - if (inNavLeft <= 0 && inNavRight <= 0 && subsumes) { - mNode->setCondition(CachedNode::NOT_ENCLOSING_FOCUS); - return REJECT_TEST; - } - int maxH = history->maxWorkingHorizontal(); - int minH = history->minWorkingHorizontal(); - setWorkingOverlap(testBottom - testY, maxH - testY, testBottom - minH); - setWorkingInclusion(minH - testY, testBottom - maxH); - if (mWorkingOverlap == 0 && mNavOverlap == 0 && inNavLeft >= 0) { - mNode->setCondition(CachedNode::OVERLAP_OR_EDGE_FURTHER); - return REJECT_TEST; - } - mInNav = history->directionChange() && inNavLeft >= 0 && - inNavRight > 0 && subsumes; /* both L/R in or out */ - return false; -} - -bool CachedFrame::BestData::setRightDirection(const CachedHistory* history) -{ - const WebCore::IntRect& navBounds = history->navBounds(); - mMajorButt = mNodeBounds.x() - navBounds.right(); - int testY = mNodeBounds.y(); - int testBottom = mNodeBounds.bottom(); - setNavOverlap(navBounds.height(), navBounds.bottom() - testY, - testBottom - navBounds.y()); - if (canBeReachedByAnotherDirection()) { - mNode->setCondition(CachedNode::BEST_DIRECTION); - return REJECT_TEST; - } - int inNavLeft = mNodeBounds.x() - navBounds.x(); - mMajorDelta2 = inNavLeft; - mMajorDelta = mMajorDelta2 + ((mNodeBounds.width() - - navBounds.width()) >> 1); - if (mMajorDelta2 <= 1 && mMajorDelta <= 1) { - mNode->setCondition(CachedNode::CENTER_FURTHER); // never move left or sideways - return REJECT_TEST; - } - int inNavRight = navBounds.right() - mNodeBounds.right(); - setNavInclusion(testBottom - navBounds.bottom(), navBounds.y() - testY); - bool subsumes = navBounds.width() > 0 && inOrSubsumesNav(); - if (inNavLeft <= 0 && inNavRight <= 0 && subsumes) { - mNode->setCondition(CachedNode::NOT_ENCLOSING_FOCUS); - return REJECT_TEST; - } - int maxH = history->maxWorkingHorizontal(); - int minH = history->minWorkingHorizontal(); - setWorkingOverlap(testBottom - testY, testBottom - minH, maxH - testY); - setWorkingInclusion(testBottom - maxH, minH - testY); - if (mWorkingOverlap == 0 && mNavOverlap == 0 && inNavRight >= 0) { - mNode->setCondition(CachedNode::OVERLAP_OR_EDGE_FURTHER); - return REJECT_TEST; - } - mInNav = history->directionChange() && inNavLeft >= 0 && - inNavRight > 0 && subsumes; /* both L/R in or out */ - return false; -} - -bool CachedFrame::BestData::setUpDirection(const CachedHistory* history) -{ - const WebCore::IntRect& navBounds = history->navBounds(); - mMajorButt = navBounds.y() - mNodeBounds.bottom(); - int testX = mNodeBounds.x(); - int testRight = mNodeBounds.right(); - setNavOverlap(navBounds.width(), navBounds.right() - testX, - testRight - navBounds.x()); - if (canBeReachedByAnotherDirection()) { - mNode->setCondition(CachedNode::BEST_DIRECTION); - return REJECT_TEST; - } - int inNavBottom = navBounds.bottom() - mNodeBounds.bottom(); - mMajorDelta2 = inNavBottom; - mMajorDelta = mMajorDelta2 - ((navBounds.height() - - mNodeBounds.height()) >> 1); - if (mMajorDelta2 <= 1 && mMajorDelta <= 1) { - mNode->setCondition(CachedNode::CENTER_FURTHER); // never move down or sideways - return REJECT_TEST; - } - int inNavTop = mNodeBounds.y() - navBounds.y(); - setNavInclusion(navBounds.x() - testX, testRight - navBounds.right()); - bool subsumes = navBounds.height() > 0 && inOrSubsumesNav(); - if (inNavTop <= 0 && inNavBottom <= 0 && subsumes) { - mNode->setCondition(CachedNode::NOT_ENCLOSING_FOCUS); - return REJECT_TEST; - } - int maxV = history->maxWorkingVertical(); - int minV = history->minWorkingVertical(); - setWorkingOverlap(testRight - testX, testRight - minV, maxV - testX); - setWorkingInclusion(minV - testX, testRight - maxV); - if (mWorkingOverlap == 0 && mNavOverlap == 0 && inNavTop >= 0) { - mNode->setCondition(CachedNode::OVERLAP_OR_EDGE_FURTHER); - return REJECT_TEST; - } - mInNav = history->directionChange() && inNavTop >= 0 && - inNavBottom > 0 && subsumes; /* both L/R in or out */ - return false; -} - -void CachedFrame::BestData::setNavInclusion(int left, int right) -{ - // if left and right <= 0, test node is completely in umbra of focus - // prefer leftmost center - // if left and right > 0, test node subsumes focus - mNavDelta = left; - mNavDelta2 = right; -} - -void CachedFrame::BestData::setNavOverlap(int span, int left, int right) -{ - mNavOutside = left < MIN_OVERLAP || right < MIN_OVERLAP; // if left or right < 0, test node is not in umbra of focus - mNavOverlap = Overlap(span, left, right); // prefer smallest negative left -} - -void CachedFrame::BestData::setWorkingInclusion(int left, int right) -{ - mWorkingDelta = left; - mWorkingDelta2 = right; -} - -// distance scale factor factor as a 16.16 scalar -void CachedFrame::BestData::setWorkingOverlap(int span, int left, int right) -{ - mWorkingOutside = left < MIN_OVERLAP || right < MIN_OVERLAP; // if left or right < 0, test node is not in umbra of focus - mWorkingOverlap = Overlap(span, left, right); - mPreferred = left <= 0 ? 0 : left; -} - -#if DUMP_NAV_CACHE - -#define DEBUG_PRINT_RECT(prefix, debugName, field) \ - { const WebCore::IntRect& r = b->field; \ - DUMP_NAV_LOGD("%s DebugTestRect TEST%s_" #debugName "={%d, %d, %d, %d}; //" #field "\n", \ - prefix, mFrameName, r.x(), r.y(), r.width(), r.height()); } - -CachedFrame* CachedFrame::Debug::base() const { - CachedFrame* nav = (CachedFrame*) ((char*) this - OFFSETOF(CachedFrame, mDebug)); - return nav; -} - -void CachedFrame::Debug::print() const -{ - CachedFrame* b = base(); - DEBUG_PRINT_RECT("//", CONTENTS, mContents); - DEBUG_PRINT_RECT("", BOUNDS, mLocalViewBounds); - DEBUG_PRINT_RECT("//", VIEW, mViewBounds); - DUMP_NAV_LOGD("// CachedNode mCachedNodes={ // count=%d\n", b->mCachedNodes.size()); - for (CachedNode* node = b->mCachedNodes.begin(); - node != b->mCachedNodes.end(); node++) - node->mDebug.print(); - DUMP_NAV_LOGD("// }; // end of nodes\n"); - DUMP_NAV_LOGD("// CachedFrame mCachedFrames={ // count=%d\n", b->mCachedFrames.size()); - for (CachedFrame* child = b->mCachedFrames.begin(); - child != b->mCachedFrames.end(); child++) - { - child->mDebug.print(); - } - DUMP_NAV_LOGD("// }; // end of child frames\n"); - DUMP_NAV_LOGD("// void* mFrame=(void*) %p;\n", b->mFrame); - DUMP_NAV_LOGD("// CachedFrame* mParent=%p;\n", b->mParent); - DUMP_NAV_LOGD("// int mIndex=%d;\n", b->mIndex); - DUMP_NAV_LOGD("// const CachedRoot* mRoot=%p;\n", b->mRoot); - DUMP_NAV_LOGD("// int mFocus=%d;\n", b->mFocus); -} - -bool CachedFrame::Debug::validate(const CachedNode* node) const -{ - const CachedFrame* b = base(); - if (b->mCachedNodes.size() == 0) - return false; - if (node >= b->mCachedNodes.begin() && node < b->mCachedNodes.end()) - return true; - for (const CachedFrame* child = b->mCachedFrames.begin(); - child != b->mCachedFrames.end(); child++) - if (child->mDebug.validate(node)) - return true; - return false; -} - -#undef DEBUG_PRINT_RECT - -#endif - -} diff --git a/WebCore/platform/android/nav/CachedFrame.h b/WebCore/platform/android/nav/CachedFrame.h deleted file mode 100644 index c7b1327..0000000 --- a/WebCore/platform/android/nav/CachedFrame.h +++ /dev/null @@ -1,220 +0,0 @@ -/* -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef CachedFrame_H -#define CachedFrame_H - -#include "CachedNode.h" -#include "IntRect.h" -#include "SkFixed.h" -#include "wtf/Vector.h" - -namespace WebCore { - class Frame; - class FrameAndroid; - class Node; -} - -namespace android { - -class CachedHistory; -class CachedRoot; - - // first node referenced by cache is always document -class CachedFrame { -public: - enum Direction { - UNINITIALIZED = -1, - LEFT, - RIGHT, - UP, - DOWN, - DIRECTION_COUNT, - DIRECTION_MASK = DIRECTION_COUNT - 1, - UP_DOWN = UP & DOWN, // mask and result - RIGHT_DOWN = RIGHT & DOWN, // mask and result - }; - enum Compare { - UNDECIDED = -1, - TEST_IS_BEST, - REJECT_TEST - }; - CachedFrame() {} - void add(CachedNode& node) { mCachedNodes.append(node); } - void addFrame(CachedFrame& child) { mCachedFrames.append(child); } - bool checkVisited(const CachedNode* , CachedFrame::Direction ) const; - size_t childCount() { return mCachedFrames.size(); } - void clearFocus(); - bool containsFrame(const CachedFrame* ) const; - const CachedNode* currentFocus() const { return currentFocus(NULL); } - const CachedNode* currentFocus(const CachedFrame** ) const; - bool directionChange() const; - const CachedNode* document() const { return mCachedNodes.begin(); } - bool empty() const { return mCachedNodes.size() < 2; } // must have 1 past doc - const CachedNode* findBestAt(const WebCore::IntRect& , int* best, - const CachedNode** , const CachedFrame** , int* x, int* y) const; - const CachedFrame* findBestFrameAt(int x, int y) const; - const CachedNode* findBestHitAt(const WebCore::IntRect& , - int* best, const CachedFrame** , int* x, int* y) const; - bool finishInit(); - CachedFrame* firstChild() { return mCachedFrames.begin(); } - const CachedFrame* firstChild() const { return mCachedFrames.begin(); } - int focusIndex() const { return mFocus; } - void* framePointer() const { return mFrame; } - CachedNode* getIndex(int index) { return index >= 0 ? - &mCachedNodes[index] : NULL; } - const CachedFrame* hasFrame(const CachedNode* node) const; - int indexInParent() const { return mIndex; } - void init(const CachedRoot* root, int index, WebCore::FrameAndroid* frame); - const CachedFrame* lastChild() const { return &mCachedFrames.last(); } - CachedNode* lastNode() { return &mCachedNodes.last(); } - CachedFrame* lastChild() { return &mCachedFrames.last(); } - const CachedFrame* parent() const { return mParent; } - CachedFrame* parent() { return mParent; } - void removeLast() { mCachedNodes.removeLast(); } - void resetClippedOut(); - void setContentsSize(int width, int height) { mContents.setWidth(width); - mContents.setHeight(height); } - void setData(); - bool setFocus(WebCore::Frame* , WebCore::Node* , int x, int y); - void setFocusIndex(int focusIndex) const { mFocus = focusIndex; } - void setLocalViewBounds(const WebCore::IntRect& bounds) { mLocalViewBounds = bounds; } - int size() { return mCachedNodes.size(); } - const CachedNode* validDocument() const; -protected: - struct BestData { - WebCore::IntRect mNodeBounds; - WebCore::IntRect mMouseBounds; - int mDistance; - int mSideDistance; - int mMajorDelta; // difference of center of object - // used only when leading and trailing edges contain another set of edges - int mMajorDelta2; // difference of leading edge (only used when center is same) - int mMajorButt; // checks for next cell butting up against or close to previous one - int mWorkingDelta; - int mWorkingDelta2; - int mNavDelta; - int mNavDelta2; - const CachedFrame* mFrame; - const CachedNode* mNode; - SkFixed mWorkingOverlap; // this and below are fuzzy answers instead of bools - SkFixed mNavOverlap; - SkFixed mPreferred; - bool mFocusChild; - bool mInNav; - bool mNavOutside; - bool mWorkingOutside; - int bottom() const { return bounds().bottom(); } - const WebCore::IntRect& bounds() const { return mNodeBounds; } - bool canBeReachedByAnotherDirection(); - int height() const { return bounds().height(); } - bool inOrSubsumesNav() const { return (mNavDelta ^ mNavDelta2) >= 0; } - bool inOrSubsumesWorking() const { return (mWorkingDelta ^ mWorkingDelta2) >= 0; } - int isContainer(BestData* ); - static SkFixed Overlap(int span, int left, int right); - void reset() { mNode = NULL; } - int right() const { return bounds().right(); } - void setDistances(); - bool setDownDirection(const CachedHistory* ); - bool setLeftDirection(const CachedHistory* ); - bool setRightDirection(const CachedHistory* ); - bool setUpDirection(const CachedHistory* ); - void setNavInclusion(int left, int right); - void setNavOverlap(int span, int left, int right); - void setWorkingInclusion(int left, int right); - void setWorkingOverlap(int span, int left, int right); - int width() const { return bounds().width(); } - int x() const { return bounds().x(); } - int y() const { return bounds().y(); } - }; - typedef const CachedNode* (CachedFrame::*MoveInDirection)( - const CachedNode* test, const CachedNode* limit, BestData* bestData, - const CachedNode* focus) const; - void adjustToTextColumn(int* delta) const; - static bool CheckBetween(Direction , const WebCore::IntRect& bestRect, - const WebCore::IntRect& prior, WebCore::IntRect* result); - bool checkBetween(BestData* , Direction ); - int compare(BestData& testData, const BestData& bestData, const - CachedNode* focus) const; - void findClosest(BestData* , Direction original, Direction test, - WebCore::IntRect* clip) const; - int frameNodeCommon(BestData& testData, const CachedNode* test, - BestData* bestData, BestData* originalData, - const CachedNode* focus) const; - int framePartCommon(BestData& testData, const CachedNode* test, - BestData* bestData, const CachedNode* focus) const; - const CachedNode* frameDown(const CachedNode* test, const CachedNode* limit, - BestData* , const CachedNode* focus) const; - const CachedNode* frameLeft(const CachedNode* test, const CachedNode* limit, - BestData* , const CachedNode* focus) const; - const CachedNode* frameRight(const CachedNode* test, const CachedNode* limit, - BestData* , const CachedNode* focus) const; - const CachedNode* frameUp(const CachedNode* test, const CachedNode* limit, - BestData* , const CachedNode* focus) const; - int minWorkingHorizontal() const; - int minWorkingVertical() const; - int maxWorkingHorizontal() const; - int maxWorkingVertical() const; - bool moveInFrame(MoveInDirection , const CachedNode* test, BestData* best, - const CachedNode* focus) const; - const WebCore::IntRect& _navBounds() const; - WebCore::IntRect mContents; - WebCore::IntRect mLocalViewBounds; - WebCore::IntRect mViewBounds; - WTF::Vector<CachedNode> mCachedNodes; - WTF::Vector<CachedFrame> mCachedFrames; - void* mFrame; // WebCore::Frame*, used only to compare pointers - CachedFrame* mParent; - int mIndex; // index within parent's array of children, or -1 if root - const CachedRoot* mRoot; - mutable int mFocus; -private: - CachedHistory* history() const; -#ifdef BROWSER_DEBUG -public: - CachedNode* find(WebCore::Node* ); // !!! probably debugging only - int mDebugIndex; - int mDebugLoopbackOffset; -#endif -#if !defined NDEBUG || DUMP_NAV_CACHE -public: - class Debug { -public: - Debug() { -#if DUMP_NAV_CACHE - mFrameName[0] = '\0'; -#endif -#if !defined NDEBUG - mInUse = true; -#endif - } -#if !defined NDEBUG - ~Debug() { mInUse = false; } - bool mInUse; -#endif -#if DUMP_NAV_CACHE - CachedFrame* base() const; - void print() const; - bool validate(const CachedNode* ) const; - char mFrameName[256]; -#endif - } mDebug; -#endif -}; - -} - -#endif diff --git a/WebCore/platform/android/nav/CachedHistory.cpp b/WebCore/platform/android/nav/CachedHistory.cpp deleted file mode 100644 index 589b64a..0000000 --- a/WebCore/platform/android/nav/CachedHistory.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/* -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "CachedPrefix.h" -#include "CachedFrame.h" -#include "CachedNode.h" -#if DUMP_NAV_CACHE -#include "CachedRoot.h" -#endif - -#include "CachedHistory.h" - -namespace android { - -CachedHistory::CachedHistory() { - memset(this, 0, sizeof(CachedHistory)); // this assume the class has no virtuals - mLastMove = CachedFrame::UNINITIALIZED; - mPriorMove = CachedFrame::UNINITIALIZED; -} - - -void CachedHistory::addToVisited(const CachedNode* node, CachedFrame::Direction direction) -{ - memmove(&mVisited[1], &mVisited[0], sizeof(mVisited) - sizeof(mVisited[0])); - mVisited[0].mNode = node; - mVisited[0].mDirection = direction; -} - -bool CachedHistory::checkVisited(const CachedNode* node, CachedFrame::Direction direction) const -{ - // if the direction is unchanged and we've already visited this node, don't visit it again - int index = 0; - while (index < NAVIGATION_VISIT_DEPTH - 1) { - if (direction != mVisited[index].mDirection) - break; - index++; // compare with last direction, previous to last node (where the arrow took us from) - if (node == mVisited[index].mNode) - return false; - } - return true; -} - -void CachedHistory::pinMaxMin(const WebCore::IntRect& viewBounds) -{ - if (mMinWorkingHorizontal < viewBounds.y() || - mMinWorkingHorizontal >= viewBounds.bottom()) - mMinWorkingHorizontal = viewBounds.y(); - if (mMaxWorkingHorizontal > viewBounds.bottom() || - mMaxWorkingHorizontal <= viewBounds.y()) - mMaxWorkingHorizontal = viewBounds.bottom(); - if (mMinWorkingVertical < viewBounds.x() || - mMinWorkingVertical >= viewBounds.right()) - mMinWorkingVertical = viewBounds.x(); - if (mMaxWorkingVertical > viewBounds.right() || - mMaxWorkingVertical <= viewBounds.x()) - mMaxWorkingVertical = viewBounds.right(); -} - -void CachedHistory::reset() -{ - memset(mVisited, 0, sizeof(mVisited)); -// mLastScroll = 0; - mPriorBounds = mFocusBounds = WebCore::IntRect(0, 0, 0, 0); - mDirectionChange = false; - mFocusIsInput = false; - mPriorIsInput = false; - mDidFirstLayout = false; - mPriorMove = mLastMove = CachedFrame::UNINITIALIZED; - mMinWorkingHorizontal = mMinWorkingVertical = INT_MIN; - mMaxWorkingHorizontal = mMaxWorkingVertical = INT_MAX; -} - -void CachedHistory::setWorking(CachedFrame::Direction newMove, - const CachedNode* focus, const WebCore::IntRect& viewBounds) -{ - CachedFrame::Direction lastAxis = (CachedFrame::Direction) (mLastMove & ~CachedFrame::RIGHT_DOWN); // up, left or uninitialized - CachedFrame::Direction newAxis = (CachedFrame::Direction) (newMove & ~CachedFrame::RIGHT_DOWN); - bool change = newAxis != lastAxis; - mDirectionChange = change && mLastMove != CachedFrame::UNINITIALIZED; - if (focus != NULL || mLastMove != CachedFrame::UNINITIALIZED) { - mPriorMove = mLastMove; - mLastMove = newMove; - } - const WebCore::IntRect* navBounds = &mNavBounds; - if (focus != NULL) { - WebCore::IntRect focusBounds; - focus->getBounds(&focusBounds); - if (focusBounds.isEmpty() == false && focusBounds != mFocusBounds) - mNavBounds = mFocusBounds = focusBounds; - mPriorIsInput = mFocusIsInput; - mFocusIsInput = focus->isInput(); // focus->localName() == "input"; - } else - mFocusBounds = WebCore::IntRect(0, 0, 0, 0); - if (change) { // uninitialized or change in direction - if (lastAxis != CachedFrame::LEFT && navBounds->height() > 0) { - mMinWorkingHorizontal = navBounds->y(); - mMaxWorkingHorizontal = navBounds->bottom(); - } - if (lastAxis != CachedFrame::UP && navBounds->width() > 0) { - mMinWorkingVertical = navBounds->x(); - mMaxWorkingVertical = navBounds->right(); - } - } else if (mPriorIsInput) { - if (newAxis == CachedFrame::UP_DOWN) { - if (mPriorBounds.x() == mMinWorkingVertical && mPriorBounds.right() == mMaxWorkingVertical) { - mMinWorkingVertical = navBounds->x(); - mMaxWorkingVertical = navBounds->right(); - } - } else { - if (mPriorBounds.y() == mMinWorkingHorizontal && mPriorBounds.bottom() == mMaxWorkingHorizontal) { - mMinWorkingHorizontal = navBounds->y(); - mMaxWorkingHorizontal = navBounds->bottom(); - } - } - } - pinMaxMin(viewBounds); -} - -#if DUMP_NAV_CACHE - -#define DEBUG_PRINT_BOOL(field) \ - DUMP_NAV_LOGD("// bool " #field "=%s;\n", b->field ? "true" : "false") - -#define DEBUG_PRINT_RECT(field) \ - { const WebCore::IntRect& r = b->field; \ - DUMP_NAV_LOGD("// IntRect " #field "={%d, %d, %d, %d};\n", \ - r.x(), r.y(), r.width(), r.height()); } - -CachedHistory* CachedHistory::Debug::base() const { - CachedHistory* nav = (CachedHistory*) ((char*) this - OFFSETOF(CachedHistory, mDebug)); - return nav; -} - -const char* CachedHistory::Debug::direction(CachedFrame::Direction d) const -{ - switch (d) { - case CachedFrame::LEFT: return "LEFT"; break; - case CachedFrame::RIGHT: return "RIGHT"; break; - case CachedFrame::UP: return "UP"; break; - case CachedFrame::DOWN: return "DOWN"; break; - default: return "UNINITIALIZED"; - } -} - -void CachedHistory::Debug::print(CachedRoot* root) const -{ - CachedHistory* b = base(); - DUMP_NAV_LOGD("// Visited mVisited[]={\n"); - for (size_t i = 0; i < NAVIGATION_VISIT_DEPTH; i++) { - const Visited& visit = b->mVisited[i]; - const CachedNode* node = visit.mNode; - int index = root != NULL && root->CachedFrame::mDebug.validate(node) ? - node->index() : -1; - DUMP_NAV_LOGD(" // { 0x%p (%d), %s },\n", node, index, direction(visit.mDirection)); - } - DUMP_NAV_LOGD("// };\n"); -// DUMP_NAV_LOGD("// int mLastScroll=%d;\n", b->mLastScroll); - DEBUG_PRINT_RECT(mFocusBounds); - DEBUG_PRINT_RECT(mNavBounds); - DEBUG_PRINT_RECT(mPriorBounds); - DEBUG_PRINT_BOOL(mDirectionChange); - DEBUG_PRINT_BOOL(mFocusIsInput); - DEBUG_PRINT_BOOL(mPriorIsInput); - DUMP_NAV_LOGD("// CachedFrame::Direction mLastMove=%s, mPriorMove=%s;\n", - direction(b->mLastMove), direction(b->mPriorMove)); - int max = b->mMaxWorkingHorizontal; - DUMP_NAV_LOGD("static int TEST_MAX_H = %d;\n", max); - int min = b->mMinWorkingHorizontal; - if (min == INT_MIN) - min++; - DUMP_NAV_LOGD("static int TEST_MIN_H = %d;\n", min); - max = b->mMaxWorkingVertical; - DUMP_NAV_LOGD("static int TEST_MAX_V = %d;\n", max); - min = b->mMinWorkingVertical; - if (min == INT_MIN) - min++; - DUMP_NAV_LOGD("static int TEST_MIN_V = %d;\n", min); - DUMP_NAV_LOGD("\n"); -} - -#endif - -} diff --git a/WebCore/platform/android/nav/CachedHistory.h b/WebCore/platform/android/nav/CachedHistory.h deleted file mode 100644 index 818115e..0000000 --- a/WebCore/platform/android/nav/CachedHistory.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef CachedHistory_H -#define CachedHistory_H - -#include "CachedFrame.h" - -#define NAVIGATION_VISIT_DEPTH 8 // the number of nodes last visited -- used to detect ping-ponging (number should be tuned) - -namespace android { - -class CachedRoot; - -// CachedHistory is maintained even if DOM is rebuilt by running script. -// It uses blind pointers for comparison in the previously visited nodes. -class CachedHistory { -public: - CachedHistory(); - void addToVisited(const CachedNode* , CachedFrame::Direction ); - bool checkVisited(const CachedNode* , CachedFrame::Direction ) const; - bool didFirstLayout() const { return mDidFirstLayout; } - bool directionChange() const { return mDirectionChange; } - const WebCore::IntRect& focusBounds() const { return mFocusBounds; } - int minWorkingHorizontal() const { return mMinWorkingHorizontal; } - int minWorkingVertical() const { return mMinWorkingVertical; } - int maxWorkingHorizontal() const { return mMaxWorkingHorizontal; } - int maxWorkingVertical() const { return mMaxWorkingVertical; } - const WebCore::IntRect& navBounds() const { return mNavBounds; } - const WebCore::IntRect& priorBounds() const { return mPriorBounds; } - void setDidFirstLayout(bool did) { mDidFirstLayout = did; } - void setNavBounds(const WebCore::IntRect& loc) { mNavBounds = loc; } - void setWorking(CachedFrame::Direction , const CachedNode* focus, - const WebCore::IntRect& viewBounds); - void reset(); -private: - void pinMaxMin(const WebCore::IntRect& viewBounds); - struct Visited { - const CachedNode* mNode; - CachedFrame::Direction mDirection; - } mVisited[NAVIGATION_VISIT_DEPTH]; - WebCore::IntRect mFocusBounds; // chosen focus ring - WebCore::IntRect mMouseBounds; // constricted bounds, if focus ring is partially visible - WebCore::IntRect mNavBounds; // focus ring bounds plus optional keystroke movement - WebCore::IntRect mPriorBounds; // prior chosen focus ring (for reversing narrowing) - bool mDirectionChange; - bool mFocusIsInput; // defer max/min to non-focus node if focus is too broad - bool mPriorIsInput; // defer max/min to non-focus node if focus is too broad - bool mDidFirstLayout; // set true when page is newly laid out - CachedFrame::Direction mLastMove; - CachedFrame::Direction mPriorMove; - int mMinWorkingHorizontal; - int mMaxWorkingHorizontal; - int mMinWorkingVertical; - int mMaxWorkingVertical; - friend class CachedRoot; -#if DUMP_NAV_CACHE -public: - class Debug { -public: - CachedHistory* base() const; - const char* direction(CachedFrame::Direction d) const; - void print(CachedRoot* ) const; - } mDebug; -#endif -}; - -} - -#endif diff --git a/WebCore/platform/android/nav/CachedNode.cpp b/WebCore/platform/android/nav/CachedNode.cpp deleted file mode 100644 index 0545b9b..0000000 --- a/WebCore/platform/android/nav/CachedNode.cpp +++ /dev/null @@ -1,332 +0,0 @@ -/* - * - * Copyright 2007, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "CachedPrefix.h" -#include "CachedFrame.h" -#include "CachedHistory.h" -#include "Node.h" -#include "PlatformString.h" - -#include "android_graphics.h" -#include "CachedNode.h" - -namespace android { - -void CachedNode::clearFocus(CachedFrame* parent) -{ - if (isFrame()) { - CachedFrame* child = const_cast<CachedFrame*>(parent->hasFrame(this)); - child->clearFocus(); - } - mIsFocus = false; -} - -bool CachedNode::Clip(const WebCore::IntRect& outer, WebCore::IntRect* inner, - WTF::Vector<WebCore::IntRect>* rings) -{ - if (outer.contains(*inner)) - return true; -// DBG_NAV_LOGD("outer:{%d,%d,%d,%d} does not contain inner:{%d,%d,%d,%d}", -// outer.x(), outer.y(), outer.width(), outer.height(), -// inner->x(), inner->y(), inner->width(), inner->height()); - bool intersects = outer.intersects(*inner); - size_t size = intersects ? rings->size() : 0; - *inner = WebCore::IntRect(0, 0, 0, 0); - if (intersects) { - WebCore::IntRect * const start = rings->begin(); - WebCore::IntRect* ring = start + size - 1; - do { - ring->intersect(outer); - if (ring->isEmpty()) { - if ((size_t) (ring - start) != --size) - *ring = start[size]; - } else - inner->unite(*ring); - } while (ring-- != start); - } - rings->shrink(size); -// DBG_NAV_LOGD("size:%d", size); - return size != 0; -} - -bool CachedNode::clip(const WebCore::IntRect& bounds) -{ - return Clip(bounds, &mBounds, &mFocusRing); -} - -#define OVERLAP 3 - -void CachedNode::fixUpFocusRects() -{ - if (mFixedUpFocusRects) - return; - mFixedUpFocusRects = true; - if (mNavableRects <= 1) - return; -#if DEBUG_NAV_UI - { - WebCore::IntRect* boundsPtr = mFocusRing.begin() - 1; - const WebCore::IntRect* const boundsEnd = mFocusRing.begin() + mFocusRing.size(); - while (++boundsPtr < boundsEnd) - LOGD("%s %d:(%d, %d, %d, %d)\n", __FUNCTION__, boundsPtr - mFocusRing.begin(), - boundsPtr->x(), boundsPtr->y(), boundsPtr->width(), boundsPtr->height()); - } -#endif - // q: need to know when rects are for drawing and hit-testing, but not mouse down calcs? - bool again; - do { - again = false; - size_t size = mFocusRing.size(); - WebCore::IntRect* unitBoundsPtr = mFocusRing.begin() - 1; - const WebCore::IntRect* const unitBoundsEnd = mFocusRing.begin() + size; - while (++unitBoundsPtr < unitBoundsEnd) { - // any other unitBounds to the left or right of this one? - int unitTop = unitBoundsPtr->y(); - int unitBottom = unitBoundsPtr->bottom(); - int unitLeft = unitBoundsPtr->x(); - int unitRight = unitBoundsPtr->right(); - WebCore::IntRect* testBoundsPtr = mFocusRing.begin() - 1; - while (++testBoundsPtr < unitBoundsEnd) { - if (unitBoundsPtr == testBoundsPtr) - continue; - int testTop = testBoundsPtr->y(); - int testBottom = testBoundsPtr->bottom(); - int testLeft = testBoundsPtr->x(); - int testRight = testBoundsPtr->right(); - int candidateTop = unitTop > testTop ? unitTop : testTop; - int candidateBottom = unitBottom < testBottom ? unitBottom : testBottom; - int candidateLeft = unitRight < testLeft ? unitRight : testRight; - int candidateRight = unitRight > testLeft ? unitLeft : testLeft; - bool leftRight = true; - if (candidateTop + OVERLAP >= candidateBottom || - candidateLeft + OVERLAP >= candidateRight) { - candidateTop = unitBottom < testTop ? unitBottom : testBottom; - candidateBottom = unitBottom > testTop ? unitTop : testTop; - candidateLeft = unitLeft > testLeft ? unitLeft : testLeft; - candidateRight = unitRight < testRight ? unitRight : testRight; - if (candidateTop + OVERLAP >= candidateBottom || - candidateLeft + OVERLAP >= candidateRight) - continue; - leftRight = false; - } - // construct candidate to add - WebCore::IntRect candidate = WebCore::IntRect(candidateLeft, candidateTop, - candidateRight - candidateLeft, candidateBottom - candidateTop); - // does a different unit bounds intersect the candidate? if so, don't add - WebCore::IntRect* checkBoundsPtr = mFocusRing.begin() - 1; - while (++checkBoundsPtr < unitBoundsEnd) { - if (checkBoundsPtr->intersects(candidate) == false) - continue; - if (leftRight) { - if (candidateTop >= checkBoundsPtr->y() && - candidateBottom > checkBoundsPtr->bottom()) - candidateTop = checkBoundsPtr->bottom(); - else if (candidateTop < checkBoundsPtr->y() && - candidateBottom <= checkBoundsPtr->bottom()) - candidateBottom = checkBoundsPtr->y(); - else - goto nextCheck; - } else { - if (candidateLeft >= checkBoundsPtr->x() && - candidateRight > checkBoundsPtr->right()) - candidateLeft = checkBoundsPtr->right(); - else if (candidateLeft < checkBoundsPtr->x() && - candidateRight <= checkBoundsPtr->right()) - candidateRight = checkBoundsPtr->x(); - else - goto nextCheck; - } - } - candidate = WebCore::IntRect(candidateLeft, candidateTop, - candidateRight - candidateLeft, candidateBottom - candidateTop); - ASSERT(candidate.isEmpty() == false); -#if DEBUG_NAV_UI - LOGD("%s %d:(%d, %d, %d, %d)\n", __FUNCTION__, mFocusRing.size(), - candidate.x(), candidate.y(), candidate.width(), candidate.height()); -#endif - mFocusRing.append(candidate); - again = true; - goto tryAgain; - nextCheck: - continue; - } - } -tryAgain: - ; - } while (again); -} - - -void CachedNode::focusRingBounds(WebCore::IntRect* bounds) const -{ - int partMax = mNavableRects; - ASSERT(partMax > 0); - *bounds = mFocusRing[0]; - for (int partIndex = 1; partIndex < partMax; partIndex++) - bounds->unite(mFocusRing[partIndex]); - bounds->inflate(FOCUS_RING_HIT_TEST_RADIUS); -} - -void CachedNode::init(CachedFrame* frame, WebCore::Node* node) -{ - bzero(this, sizeof(CachedNode)); - mExport = WebCore::String(); - mName = WebCore::String(); - mNode = node; - mParentIndex = mChildFrameIndex = -1; - mType = android::NORMAL_CACHEDNODETYPE; -} - -void CachedNode::move(int x, int y) -{ - mBounds.move(x, y); - // mHitTestBounds will be moved by caller - WebCore::IntRect* first = mFocusRing.begin(); - WebCore::IntRect* last = first + mFocusRing.size(); - --first; - while (++first != last) - first->move(x, y); -} - -bool CachedNode::partRectsContains(const CachedNode* other) const -{ - int outerIndex = 0; - int outerMax = mNavableRects; - int innerMax = other->mNavableRects; - do { - const WebCore::IntRect& outerBounds = mFocusRing[outerIndex]; - int innerIndex = 0; - do { - const WebCore::IntRect& innerBounds = other->mFocusRing[innerIndex]; - if (innerBounds.contains(outerBounds)) - return true; - } while (++innerIndex < innerMax); - } while (++outerIndex < outerMax); - return false; -} - -#if DUMP_NAV_CACHE - -#define DEBUG_PRINT_BOOL(field) \ - DUMP_NAV_LOGD("// bool " #field "=%s;\n", b->field ? "true" : "false") - -#define DEBUG_PRINT_RECT(field) \ - { const WebCore::IntRect& r = b->field; \ - DUMP_NAV_LOGD("// IntRect " #field "={%d, %d, %d, %d};\n", \ - r.x(), r.y(), r.width(), r.height()); } - -CachedNode* CachedNode::Debug::base() const { - CachedNode* nav = (CachedNode*) ((char*) this - OFFSETOF(CachedNode, mDebug)); - return nav; -} - -const char* CachedNode::Debug::condition(Condition t) const -{ - switch (t) { - case NOT_REJECTED: return "NOT_REJECTED"; break; - case BUTTED_UP: return "BUTTED_UP"; break; - case CENTER_FURTHER: return "CENTER_FURTHER"; break; - case CLOSER: return "CLOSER"; break; - case CLOSER_IN_FOCUS: return "CLOSER_IN_FOCUS"; break; - case CLOSER_OVERLAP: return "CLOSER_OVERLAP"; break; - case CLOSER_TOP: return "CLOSER_TOP"; break; - case FOCUSABLE: return "FOCUSABLE"; break; - case FURTHER: return "FURTHER"; break; - case IN_UMBRA: return "IN_UMBRA"; break; - case IN_WORKING: return "IN_WORKING"; break; - case LEFTMOST: return "LEFTMOST"; break; - case OVERLAP_OR_EDGE_FURTHER: return "OVERLAP_OR_EDGE_FURTHER"; break; - case PREFERRED: return "PREFERRED"; break; - case ANCHOR_IN_ANCHOR: return "ANCHOR_IN_ANCHOR"; break; - case BEST_DIRECTION: return "BEST_DIRECTION"; break; - case CHILD: return "CHILD"; break; - case DISABLED: return "DISABLED"; break; - case IN_FOCUS: return "IN_FOCUS"; break; - case IN_FOCUS_CHILDREN: return "IN_FOCUS_CHILDREN"; break; - case NOT_ENCLOSING_FOCUS: return "NOT_ENCLOSING_FOCUS"; break; - // case NOT_FOCUS_CHILD: return "NOT_FOCUS_CHILD"; break; - case NOT_FOCUS_NODE: return "NOT_FOCUS_NODE"; break; - case OUTSIDE_OF_BEST: return "OUTSIDE_OF_BEST"; break; - case OUTSIDE_OF_ORIGINAL: return "OUTSIDE_OF_ORIGINAL"; break; - default: return "???"; - } -} - -const char* CachedNode::Debug::type(android::CachedNodeType t) const -{ - switch (t) { - case NORMAL_CACHEDNODETYPE: return "NORMAL"; break; - case ADDRESS_CACHEDNODETYPE: return "ADDRESS"; break; - case EMAIL_CACHEDNODETYPE: return "EMAIL"; break; - case PHONE_CACHEDNODETYPE: return "PHONE"; break; - default: return "???"; - } -} - -void CachedNode::Debug::print() const -{ - CachedNode* b = base(); - char scratch[256]; - size_t index = snprintf(scratch, sizeof(scratch), "// char* mExport=\""); - const UChar* ch = b->mExport.characters(); - while (ch && *ch && index < sizeof(scratch)) - scratch[index++] = *ch++; - DUMP_NAV_LOGD("%.*s\"\n", index, scratch); - index = snprintf(scratch, sizeof(scratch), "// char* mName=\""); - ch = b->mName.characters(); - while (ch && *ch && index < sizeof(scratch)) - scratch[index++] = *ch++; - DUMP_NAV_LOGD("%.*s\"\n", index, scratch); - DEBUG_PRINT_RECT(mBounds); - const WTF::Vector<WebCore::IntRect>& rects = b->focusRings(); - size_t size = rects.size(); - DUMP_NAV_LOGD("// IntRect focusRings={ // size=%d\n", size); - for (size_t i = 0; i < size; i++) - DUMP_NAV_LOGD(" // {%d, %d, %d, %d}, // %d\n", rects[i].x(), rects[i].y(), - rects[i].width(), rects[i].height(), i); - DUMP_NAV_LOGD("// };\n"); - DUMP_NAV_LOGD("// void* mNode=%p; // (%d) \n", b->mNode, mNodeIndex); - DUMP_NAV_LOGD("// void* mParentGroup=%p; // (%d) \n", b->mParentGroup, mParentGroupIndex); - DUMP_NAV_LOGD("// int mChildFrameIndex=%d;\n", b->mChildFrameIndex); - DUMP_NAV_LOGD("// int mIndex=%d;\n", b->mIndex); - DUMP_NAV_LOGD("// int mMaxLength=%d;\n", b->mMaxLength); - DUMP_NAV_LOGD("// int mNavableRects=%d;\n", b->mNavableRects); - DUMP_NAV_LOGD("// int mParentIndex=%d;\n", b->mParentIndex); - DUMP_NAV_LOGD("// int mTextSize=%d;\n", b->mTextSize); - DUMP_NAV_LOGD("// Condition mCondition=%s;\n", condition(b->mCondition)); - DUMP_NAV_LOGD("// Type mType=%s;\n", type(b->mType)); - DEBUG_PRINT_BOOL(mClippedOut); - DEBUG_PRINT_BOOL(mDisabled); - DEBUG_PRINT_BOOL(mFixedUpFocusRects); - DEBUG_PRINT_BOOL(mHasMouseOver); - DEBUG_PRINT_BOOL(mIsAnchor); - DEBUG_PRINT_BOOL(mIsArea); - DEBUG_PRINT_BOOL(mIsFocus); - DEBUG_PRINT_BOOL(mIsInput); - DEBUG_PRINT_BOOL(mIsParentAnchor); - DEBUG_PRINT_BOOL(mIsPassword); - DEBUG_PRINT_BOOL(mIsTextArea); - DEBUG_PRINT_BOOL(mIsTextField); - DEBUG_PRINT_BOOL(mIsTransparent); - DEBUG_PRINT_BOOL(mIsUnclipped); - DEBUG_PRINT_BOOL(mLast); - DUMP_NAV_LOGD("\n"); -} - -#endif - -} diff --git a/WebCore/platform/android/nav/CachedNode.h b/WebCore/platform/android/nav/CachedNode.h deleted file mode 100644 index 5cc493d..0000000 --- a/WebCore/platform/android/nav/CachedNode.h +++ /dev/null @@ -1,217 +0,0 @@ -/* -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef CachedNode_H -#define CachedNode_H - -#include "AtomicString.h" -#include "CachedDebug.h" -#include "CachedNodeType.h" -#include "IntRect.h" -#include "PlatformString.h" -#include "wtf/Vector.h" - -namespace WebCore { - class Node; -} - -namespace android { - -class CachedFrame; - -class CachedNode { -public: -// Nodes are rejected because either they are spacially not the best (first set) -// or because they have the wrong DOM attribute (in focus, a focused child, etc) -// findClosest() gives only spacially rejected nodes a second chance - enum Condition { // if bigger than 32, increase bitfield size below - // rejections that get a second chance - NOT_REJECTED = 0, - SECOND_CHANCE_START = NOT_REJECTED, // must be first in list - BUTTED_UP, - CENTER_FURTHER, - CLOSER, - CLOSER_IN_FOCUS, - CLOSER_OVERLAP, - CLOSER_TOP, - FOCUSABLE, - FURTHER, - IN_UMBRA, - IN_WORKING, - LEFTMOST, - OVERLAP_OR_EDGE_FURTHER, - PREFERRED, // better overlap measure - SECOND_CHANCE_END = PREFERRED, // must be last in list - // rejections that don't get a second chance - ANCHOR_IN_ANCHOR, - BEST_DIRECTION, // can be reached by another direction - CHILD, - DISABLED, - IN_FOCUS, - IN_FOCUS_CHILDREN, - NOT_ENCLOSING_FOCUS, - // NOT_FOCUS_CHILD, - NOT_FOCUS_NODE, - OUTSIDE_OF_BEST, // containership - OUTSIDE_OF_ORIGINAL, // containership - CONDITION_SIZE // FIXME: test that CONDITION_SIZE fits in mCondition - }; - CachedNode() {} - bool anchorHasSrcUrl() const { return mAnchorHasSrcUrl; } - const WebCore::IntRect& bounds() const { return mBounds; } - WebCore::IntRect* boundsPtr() { return &mBounds; } - int childFrameIndex() const { return mChildFrameIndex; } - void clearCondition() const { mCondition = NOT_REJECTED; } - void clearFocus(CachedFrame* ); - static bool Clip(const WebCore::IntRect& outer, WebCore::IntRect* inner, - WTF::Vector<WebCore::IntRect>* rings); - bool clip(const WebCore::IntRect& ); - bool clippedOut() { return mClippedOut; } - bool disabled() const { return mDisabled; } - const CachedNode* document() const { return &this[-mIndex]; } - void fixUpFocusRects(); - void focusRingBounds(WebCore::IntRect* ) const; - WTF::Vector<WebCore::IntRect>& focusRings() { return mFocusRing; } - const WTF::Vector<WebCore::IntRect>& focusRings() const { return mFocusRing; } - const WebCore::IntRect& getBounds() const { return mBounds; } - void getBounds(WebCore::IntRect* bounds) const { *bounds = mBounds; } - const WebCore::String& getExport() const { return mExport; } - bool hasFocusRing() const { return mHasFocusRing; } - bool hasMouseOver() const { return mHasMouseOver; } - const WebCore::IntRect& hitBounds() const { return mHitBounds; } - int index() const { return mIndex; } - void init(CachedFrame* , WebCore::Node* node); - bool isAnchor() const { return mIsAnchor; } - bool isArea() const { return mIsArea; } - bool isFocus() const { return mIsFocus; } - bool isFocusable(const WebCore::IntRect& clip) const { - return clip.intersects(mBounds); - } - bool isFrame() const { return mChildFrameIndex >= 0 ; } - bool isInput() const { return mIsInput; } - bool isPassword() const { return mIsPassword; } - bool isRtlText() const { return mIsRtlText; } - bool isTextArea() const { return mIsTextArea; } - bool isTextField() const { return mIsTextField; } - bool isTransparent() const { return mIsTransparent; } - bool isUnclipped() const { return mIsUnclipped; } - int maxLength() const { return mMaxLength; }; - void move(int x, int y); - const WebCore::String& name() const { return mName; } - int navableRects() const { return mNavableRects; } - void* nodePointer() const { return mNode; } - bool noSecondChance() const { return mCondition > SECOND_CHANCE_END; } - const CachedNode* parent() const { return document() + mParentIndex; } - void* parentGroup() const { return mParentGroup; } - int parentIndex() const { return mParentIndex; } - bool partRectsContains(const CachedNode* other) const; - void reset(); - void setAnchorHasSrcUrl(bool isURL) { mAnchorHasSrcUrl = isURL; } - void setBounds(const WebCore::IntRect& bounds) { mBounds = bounds; } - void setChildFrameIndex(int index) { mChildFrameIndex = index; } - void setClippedOut(bool clipped) { mClippedOut = clipped; } - void setCondition(Condition condition) const { mCondition = condition; } - void setDisabled(bool disabled) { mDisabled = disabled; } - void setExport(const WebCore::String& exported) { mExport = exported; } - void setHasFocusRing(bool hasFocusRing) { mHasFocusRing = hasFocusRing; } - void setHasMouseOver(bool hasMouseOver) { mHasMouseOver = hasMouseOver; } - void setHitBounds(const WebCore::IntRect& bounds) { mHitBounds = bounds; } - void setIndex(int index) { mIndex = index; } - void setIsAnchor(bool isAnchor) { mIsAnchor = isAnchor; } - void setIsArea(bool isArea) { mIsArea = isArea; } - void setIsFocus(bool isFocus) { mIsFocus = isFocus; } - void setIsInput(bool isInput) { mIsInput = isInput; } - void setIsParentAnchor(bool isAnchor) { mIsParentAnchor = isAnchor; } - void setIsPassword(bool isPassword) { mIsPassword = isPassword; } - void setIsRtlText(bool isRtlText) { mIsRtlText = isRtlText; } - void setIsTextArea(bool isTextArea) { mIsTextArea = isTextArea; } - void setIsTextField(bool isTextField) { mIsTextField = isTextField; } - void setIsTransparent(bool isTransparent) { mIsTransparent = isTransparent; } - void setIsUnclipped(bool unclipped) { mIsUnclipped = unclipped; } - void setLast() { mLast = true; } - void setMaxLength(int maxLength) { mMaxLength = maxLength; } - void setName(const WebCore::String& name) { mName = name; } - void setNavableRects() { mNavableRects = mFocusRing.size(); } - void setParentGroup(void* group) { mParentGroup = group; } - void setParentIndex(int parent) { mParentIndex = parent; } - void setTextSize(int textSize) { mTextSize = textSize; } - void setType(CachedNodeType type) { mType = type; } - const CachedNode* traverseNextNode() const { return mLast ? NULL : &this[1]; } - int textSize() const { return mTextSize; } - CachedNodeType type() const { return mType; } -private: - WebCore::String mExport; - WebCore::String mName; - WebCore::IntRect mBounds; - WebCore::IntRect mHitBounds; - WTF::Vector<WebCore::IntRect> mFocusRing; - void* mNode; // WebCore::Node*, only used to match pointers - void* mParentGroup; // WebCore::Node*, only used to match pointers - int mChildFrameIndex; // set to -1 if node is not a frame - int mIndex; // index of itself, to find first in array (document) - int mMaxLength; - int mNavableRects; // FIXME: could be bitfield once I limit max number of rects - int mParentIndex; - int mTextSize; - mutable Condition mCondition : 5; // why the node was not chosen on the first pass - CachedNodeType mType : 3; - bool mAnchorHasSrcUrl : 1; - bool mClippedOut : 1; - bool mDisabled : 1; - bool mFixedUpFocusRects : 1; - bool mHasFocusRing : 1; - bool mHasMouseOver : 1; - bool mIsAnchor : 1; - bool mIsArea : 1; - bool mIsFocus : 1; - bool mIsInput : 1; - bool mIsParentAnchor : 1; - bool mIsPassword : 1; - bool mIsRtlText : 1; - bool mIsTextArea : 1; - bool mIsTextField : 1; - bool mIsTransparent : 1; - bool mIsUnclipped : 1; - bool mLast : 1; -#ifdef BROWSER_DEBUG -public: - WebCore::Node* webCoreNode() const { return (WebCore::Node*) mNode; } - bool mDisplayMeasure; - mutable bool mInCompare; - // mutable int mCondition; - int mSideDistance; - int mSecondSide; -#endif -#if DEBUG_NAV_UI || DUMP_NAV_CACHE -public: - class Debug { -public: - CachedNode* base() const; - const char* condition(Condition t) const; - void print() const; - const char* type(CachedNodeType t) const; -#if DUMP_NAV_CACHE - int mNodeIndex; - int mParentGroupIndex; -#endif - } mDebug; - friend class CachedNode::Debug; -#endif -}; - -} - -#endif diff --git a/WebCore/platform/android/nav/CachedNodeType.h b/WebCore/platform/android/nav/CachedNodeType.h deleted file mode 100644 index 93f4345..0000000 --- a/WebCore/platform/android/nav/CachedNodeType.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef CachedNodeType_H -#define CachedNodeType_H - -namespace android { - -enum CachedNodeType { - NORMAL_CACHEDNODETYPE = 0, - ADDRESS_CACHEDNODETYPE = 1, - EMAIL_CACHEDNODETYPE = 2, - PHONE_CACHEDNODETYPE = 4, - ALL_CACHEDNODETYPES = 7 -}; - -} - -#endif diff --git a/WebCore/platform/android/nav/CachedPrefix.h b/WebCore/platform/android/nav/CachedPrefix.h deleted file mode 100644 index 3994a5a..0000000 --- a/WebCore/platform/android/nav/CachedPrefix.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef CachedPrefix_H -#define CachedPrefix_H - -#ifndef LOG_TAG -#define LOG_TAG "navcache" -#endif - -#include "config.h" -#include "CachedDebug.h" - -#ifdef LOG -#undef LOG -#endif - -#include <utils/Log.h> - -#define OFFSETOF(type, field) ((char*)&(((type*)1)->field) - (char*)1) // avoids gnu warning - -#endif diff --git a/WebCore/platform/android/nav/CachedRoot.cpp b/WebCore/platform/android/nav/CachedRoot.cpp deleted file mode 100644 index 07b31b7..0000000 --- a/WebCore/platform/android/nav/CachedRoot.cpp +++ /dev/null @@ -1,1054 +0,0 @@ -/* -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "CachedPrefix.h" -#include "CachedHistory.h" -#include "CachedNode.h" -#include "SkBitmap.h" -#include "SkBounder.h" -#include "SkCanvas.h" -#include "SkRegion.h" - -#include "CachedRoot.h" - -#ifdef DUMP_NAV_CACHE_USING_PRINTF - extern android::Mutex gWriteLogMutex; -#endif - -namespace android { - -class CommonCheck : public SkBounder { -public: - enum Type { - kNo_Type, - kDrawBitmap_Type, - kDrawGlyph_Type, - kDrawPaint_Type, - kDrawPath_Type, - kDrawPicture_Type, - kDrawPoints_Type, - kDrawPosText_Type, - kDrawPosTextH_Type, - kDrawRect_Type, - kDrawSprite_Type, - kDrawText_Type, - kDrawTextOnPath_Type - }; - - static bool isTextType(Type t) { - return t == kDrawPosTextH_Type || t == kDrawText_Type; - } - - CommonCheck() : mType(kNo_Type), mAllOpaque(true), mIsOpaque(true) { - setEmpty(); - } - - bool doRect(Type type) { - mType = type; - return doIRect(mUnion); - } - - bool joinGlyphs(const SkIRect& rect) { - bool isGlyph = mType == kDrawGlyph_Type; - if (isGlyph) - mUnion.join(rect); - return isGlyph; - } - - void setAllOpaque(bool opaque) { mAllOpaque = opaque; } - void setEmpty() { mUnion.setEmpty(); } - void setIsOpaque(bool opaque) { mIsOpaque = opaque; } - void setType(Type type) { mType = type; } - - Type mType; - SkIRect mUnion; - bool mAllOpaque; - bool mIsOpaque; -}; - -#if DEBUG_NAV_UI && !defined BROWSER_DEBUG - static const char* TypeNames[] = { - "kNo_Type", - "kDrawBitmap_Type", - "kDrawGlyph_Type", - "kDrawPaint_Type", - "kDrawPath_Type", - "kDrawPicture_Type", - "kDrawPoints_Type", - "kDrawPosText_Type", - "kDrawPosTextH_Type", - "kDrawRect_Type", - "kDrawSprite_Type", - "kDrawText_Type", - "kDrawTextOnPath_Type" - }; -#endif - -#define kMargin 16 -#define kSlop 2 - -class BoundsCheck : public CommonCheck { -public: - BoundsCheck() { - mAllDrawnIn.setEmpty(); - mLastAll.setEmpty(); - mLastOver.setEmpty(); - } - - static int Area(SkIRect test) { - return test.width() * test.height(); - } - - void checkLast() { - if (mAllDrawnIn.isEmpty()) - return; - if (mLastAll.isEmpty() || Area(mLastAll) < Area(mAllDrawnIn)) { - mLastAll = mAllDrawnIn; - mDrawnOver.setEmpty(); - } - mAllDrawnIn.setEmpty(); - } - - bool hidden() { - return (mLastAll.isEmpty() && mLastOver.isEmpty()) || - mDrawnOver.contains(mBounds); - } - - virtual bool onIRect(const SkIRect& rect) { - if (joinGlyphs(rect)) - return false; - bool interestingType = mType == kDrawBitmap_Type || - mType == kDrawRect_Type || isTextType(mType); - if (SkIRect::Intersects(mBounds, rect) == false) { -#if DEBUG_NAV_UI && !defined BROWSER_DEBUG - LOGD("%s (no intersect) rect={%d,%d,%d,%d} mType=%s\n", __FUNCTION__, - rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, - TypeNames[mType]); -#endif - if (interestingType) - checkLast(); - return false; - } - if (interestingType == false) - return false; - if (mBoundsSlop.contains(rect) || - (mBounds.fLeft == rect.fLeft && mBounds.fRight == rect.fRight && - mBounds.fTop >= rect.fTop && mBounds.fBottom <= rect.fBottom) || - (mBounds.fTop == rect.fTop && mBounds.fBottom == rect.fBottom && - mBounds.fLeft >= rect.fLeft && mBounds.fRight <= rect.fRight)) { - mDrawnOver.setEmpty(); - mAllDrawnIn.join(rect); -#if DEBUG_NAV_UI && !defined BROWSER_DEBUG - LOGD("%s (contains) rect={%d,%d,%d,%d}" - " mAllDrawnIn={%d,%d,%d,%d} mType=%s\n", __FUNCTION__, - rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, - mAllDrawnIn.fLeft, mAllDrawnIn.fTop, mAllDrawnIn.fRight, mAllDrawnIn.fBottom, - TypeNames[mType]); -#endif - } else { - checkLast(); - if (!isTextType(mType)) { - if ( -#if 0 -// should the opaqueness of the bitmap disallow its ability to draw over? -// not sure that this test is needed - (mType != kDrawBitmap_Type || - (mIsOpaque && mAllOpaque)) && -#endif - mLastAll.isEmpty() == false) - mDrawnOver.op(rect, SkRegion::kUnion_Op); - } else { -// FIXME -// sometimes the text is not drawn entirely inside the focus area, even though -// it is the correct text. Until I figure out why, I allow text drawn at the -// end that is not covered up by something else to represent the focusable link -// example that triggers this that should be figured out: -// http://cdn.labpixies.com/campaigns/blackjack/blackjack.html?lang=en&country=US&libs=assets/feature/core -// ( http://tinyurl.com/ywsyzb ) - mLastOver = rect; - } -#if DEBUG_NAV_UI && !defined BROWSER_DEBUG - const SkIRect& drawnOver = mDrawnOver.getBounds(); - LOGD("%s (overlaps) rect={%d,%d,%d,%d}" - " mDrawnOver={%d,%d,%d,%d} mType=%s mIsOpaque=%s mAllOpaque=%s\n", __FUNCTION__, - rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, - drawnOver.fLeft, drawnOver.fTop, drawnOver.fRight, drawnOver.fBottom, - TypeNames[mType], mIsOpaque ? "true" : "false", mAllOpaque ? "true" : "false"); -#endif - } - return false; - } - - SkIRect mBounds; - SkIRect mBoundsSlop; - SkRegion mDrawnOver; - SkIRect mLastOver; - SkIRect mAllDrawnIn; - SkIRect mLastAll; -}; - -class BoundsCanvas : public SkCanvas { -public: - - BoundsCanvas(CommonCheck* bounder) : mBounder(*bounder) { - mTransparentLayer = 0; - setBounder(bounder); - } - - virtual ~BoundsCanvas() { - setBounder(NULL); - } - - virtual void drawPaint(const SkPaint& paint) { - mBounder.setType(CommonCheck::kDrawPaint_Type); - SkCanvas::drawPaint(paint); - } - - virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], - const SkPaint& paint) { - mBounder.setType(CommonCheck::kDrawPoints_Type); - SkCanvas::drawPoints(mode, count, pts, paint); - } - - virtual void drawRect(const SkRect& rect, const SkPaint& paint) { - mBounder.setType(CommonCheck::kDrawRect_Type); - SkCanvas::drawRect(rect, paint); - } - - virtual void drawPath(const SkPath& path, const SkPaint& paint) { - mBounder.setType(CommonCheck::kDrawPath_Type); - SkCanvas::drawPath(path, paint); - } - - virtual void commonDrawBitmap(const SkBitmap& bitmap, - const SkMatrix& matrix, const SkPaint& paint) { - mBounder.setType(CommonCheck::kDrawBitmap_Type); - mBounder.setIsOpaque(bitmap.isOpaque()); - SkCanvas::commonDrawBitmap(bitmap, matrix, paint); - } - - virtual void drawSprite(const SkBitmap& bitmap, int left, int top, - const SkPaint* paint = NULL) { - mBounder.setType(CommonCheck::kDrawSprite_Type); - mBounder.setIsOpaque(bitmap.isOpaque()); - SkCanvas::drawSprite(bitmap, left, top, paint); - } - - virtual void drawText(const void* text, size_t byteLength, SkScalar x, - SkScalar y, const SkPaint& paint) { - mBounder.setEmpty(); - mBounder.setType(CommonCheck::kDrawGlyph_Type); - SkCanvas::drawText(text, byteLength, x, y, paint); - mBounder.doRect(CommonCheck::kDrawText_Type); - } - - virtual void drawPosText(const void* text, size_t byteLength, - const SkPoint pos[], const SkPaint& paint) { - mBounder.setEmpty(); - mBounder.setType(CommonCheck::kDrawGlyph_Type); - SkCanvas::drawPosText(text, byteLength, pos, paint); - mBounder.doRect(CommonCheck::kDrawPosText_Type); - } - - virtual void drawPosTextH(const void* text, size_t byteLength, - const SkScalar xpos[], SkScalar constY, - const SkPaint& paint) { - mBounder.setEmpty(); - mBounder.setType(CommonCheck::kDrawGlyph_Type); - SkCanvas::drawPosTextH(text, byteLength, xpos, constY, paint); - if (mBounder.mUnion.isEmpty()) - return; - SkPaint::FontMetrics metrics; - paint.getFontMetrics(&metrics); - SkPoint upDown[2] = { {xpos[0], constY + metrics.fAscent}, - {xpos[0], constY + metrics.fDescent} }; - const SkMatrix& matrix = getTotalMatrix(); - matrix.mapPoints(upDown, 2); - if (upDown[0].fX == upDown[1].fX) { - mBounder.mUnion.fTop = SkScalarFloor(upDown[0].fY); - mBounder.mUnion.fBottom = SkScalarFloor(upDown[1].fY); - } - mBounder.doRect(CommonCheck::kDrawPosTextH_Type); - } - - virtual void drawTextOnPath(const void* text, size_t byteLength, - const SkPath& path, const SkMatrix* matrix, - const SkPaint& paint) { - mBounder.setEmpty(); - mBounder.setType(CommonCheck::kDrawGlyph_Type); - SkCanvas::drawTextOnPath(text, byteLength, path, matrix, paint); - mBounder.doRect(CommonCheck::kDrawTextOnPath_Type); - } - - virtual void drawPicture(SkPicture& picture) { - mBounder.setType(CommonCheck::kDrawPicture_Type); - SkCanvas::drawPicture(picture); - } - - virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags) { - int depth = SkCanvas::saveLayer(bounds, paint, flags); - if (mTransparentLayer == 0 && paint && paint->getAlpha() < 255) { - mTransparentLayer = depth; - mBounder.setAllOpaque(false); - } - return depth; - } - - virtual void restore() { - int depth = getSaveCount(); - if (depth == mTransparentLayer) { - mTransparentLayer = 0; - mBounder.setAllOpaque(true); - } - SkCanvas::restore(); - } - - int mTransparentLayer; - CommonCheck& mBounder; -}; - -/* -CenterCheck examines the text in a picture, within a viewable rectangle, -and returns via center() the optimal amount to scroll in x to display the -paragraph of text. - -The caller of CenterCheck has configured (but not allocated) a bitmap -the height and three times the width of the view. The picture is drawn centered -in the bitmap, so text that would be revealed, if the view was scrolled up to -a view-width to the left or right, is considered. -*/ -class CenterCheck : public CommonCheck { -public: - CenterCheck(int x, int y, int width) : mX(x), mY(y), - mHitLeft(x), mHitRight(x), mMostLeft(INT_MAX), mMostRight(-INT_MAX), - mViewLeft(width), mViewRight(width << 1) { - mHit.set(x - CENTER_SLOP, y - CENTER_SLOP, - x + CENTER_SLOP, y + CENTER_SLOP); - mPartial.setEmpty(); - } - - int center() { - doRect(); // process the final line of text - /* If the touch coordinates aren't near any text, return 0 */ - if (mHitLeft == mHitRight) { - DBG_NAV_LOGD("abort: mHitLeft=%d ==mHitRight", mHitLeft); - return 0; - } - int leftOver = mHitLeft - mViewLeft; - int rightOver = mHitRight - mViewRight; - int center; - /* If the touched text is too large to entirely fit on the screen, - center it. */ - if (leftOver < 0 && rightOver > 0) { - center = (leftOver + rightOver) >> 1; - DBG_NAV_LOGD("overlap: leftOver=%d rightOver=%d center=%d", - leftOver, rightOver, center); - return center; - } - center = (mMostLeft + mMostRight) >> 1; // the paragraph center - if (leftOver > 0 && rightOver >= 0) { // off to the right - if (center > mMostLeft) // move to center loses left-most text? - center = mMostLeft; - } else if (rightOver < 0 && leftOver <= 0) { // off to the left - if (center < mMostRight) // move to center loses right-most text? - center = mMostRight; - } else { -#ifdef DONT_CENTER_IF_ALREADY_VISIBLE - center = 0; // paragraph is already fully visible -#endif - } - DBG_NAV_LOGD("scroll: leftOver=%d rightOver=%d center=%d", - leftOver, rightOver, center); - return center; - } - -protected: - virtual bool onIRect(const SkIRect& rect) { - if (joinGlyphs(rect)) // assembles glyphs into a text string - return false; - if (!isTextType(mType)) - return false; - /* Text on one line may be broken into several parts. Reassemble - the text into a rectangle before considering it. */ - if (rect.fTop < mPartial.fBottom && rect.fBottom > - mPartial.fTop && mPartial.fRight + CENTER_SLOP >= rect.fLeft) { - DBG_NAV_LOGD("join mPartial=(%d, %d, %d, %d) rect=(%d, %d, %d, %d)", - mPartial.fLeft, mPartial.fTop, mPartial.fRight, mPartial.fBottom, - rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); - mPartial.join(rect); - return false; - } - if (mPartial.isEmpty() == false) - doRect(); // process the previous line of text - mPartial = rect; - return false; - } - - void doRect() - { - /* Record the outer bounds of the lines of text that was 'hit' by the - touch coordinates, given some slop */ - if (SkIRect::Intersects(mPartial, mHit)) { - if (mHitLeft > mPartial.fLeft) - mHitLeft = mPartial.fLeft; - if (mHitRight < mPartial.fRight) - mHitRight = mPartial.fRight; - DBG_NAV_LOGD("mHitLeft=%d mHitRight=%d", mHitLeft, mHitRight); - } - /* If the considered text is completely to the left or right of the - touch coordinates, skip it */ - if (mPartial.fLeft > mX || mPartial.fRight < mX) - return; - int leftOver = mPartial.fLeft - mViewLeft; - int rightOver = mPartial.fRight - mViewRight; - /* If leftOver <= 0, the text starts off the screen. - If rightOver >= 0, the text ends off the screen. - */ - if (leftOver <= 0 && rightOver >= 0) // discard wider than screen - return; -#ifdef DONT_CENTER_IF_ALREADY_VISIBLE - if (leftOver > 0 && rightOver < 0) // discard already visible - return; -#endif - /* record the smallest margins on the left and right */ - if (mMostLeft > leftOver) - mMostLeft = leftOver; - if (mMostRight < rightOver) - mMostRight = rightOver; - DBG_NAV_LOGD("leftOver=%d rightOver=%d mMostLeft=%d mMostRight=%d", - leftOver, rightOver, mMostLeft, mMostRight); - } - - static const int CENTER_SLOP = 10; // space between text parts and lines - /* const */ SkIRect mHit; // sloppy hit rectangle - SkIRect mPartial; // accumulated text bounds, per line - const int mX; // touch location - const int mY; - int mHitLeft; // touched text extremes - int mHitRight; - int mMostLeft; // paragraph extremes - int mMostRight; - const int mViewLeft; // middle third of 3x-wide view - const int mViewRight; -}; - -class ImageCheck : public CommonCheck { -public: - ImageCheck() : mLastIsImage(false) {} - - virtual bool onIRect(const SkIRect& rect) { - if (joinGlyphs(rect)) - return false; - mLastIsImage = mType == kDrawBitmap_Type; - return false; - } - - bool mLastIsImage; -}; - -class JiggleCheck : public CommonCheck { -public: - JiggleCheck(int delta, int width) : mDelta(delta), mMaxX(width) { - mMaxJiggle = 0; - mMinX = mMinJiggle = abs(delta); - mMaxWidth = width + mMinX; - } - - int jiggle() { - if (mMinJiggle > mMaxJiggle) - return mDelta; - int avg = (mMinJiggle + mMaxJiggle + 1) >> 1; - return mDelta < 0 ? -avg : avg; - } - - virtual bool onIRect(const SkIRect& rect) { - if (joinGlyphs(rect)) - return false; - if (mType != kDrawBitmap_Type && !isTextType(mType)) - return false; - int min, max; - if (mDelta < 0) { - min = mMinX - rect.fLeft; - max = mMaxWidth - rect.fRight; - } else { - min = rect.fRight - mMaxX; - max = rect.fLeft; - } - if (min <= 0) - return false; - if (max >= mMinX) - return false; - if (mMinJiggle > min) - mMinJiggle = min; - if (mMaxJiggle < max) - mMaxJiggle = max; - return false; - } - - int mDelta; - int mMaxJiggle; - int mMaxX; - int mMinJiggle; - int mMinX; - int mMaxWidth; -}; - -bool CachedRoot::adjustForScroll(BestData* best, CachedFrame::Direction direction, - WebCore::IntPoint* scrollPtr, bool findClosest) -{ - WebCore::IntRect newOutset; - const CachedNode* newNode = best->mNode; - // see if there's a middle node - // if the middle node is in the visited list, - // or if none was computed and the newNode is in the visited list, - // treat result as NULL - if (newNode != NULL && findClosest) { - if (best->bounds().intersects(mHistory->mPriorBounds) == false && - checkBetween(best, direction)) - newNode = best->mNode; - if (findClosest && maskIfHidden(best)) { - innerMove(document(), best, direction, scrollPtr, false); - return true; - } - newNode->focusRingBounds(&newOutset); - } - int delta; - bool newNodeInView = scrollDelta(newOutset, direction, &delta); - if (delta && scrollPtr && (newNode == NULL || newNodeInView == false || - (best->mNavOutside && best->mWorkingOutside))) - *scrollPtr = WebCore::IntPoint(direction & UP_DOWN ? 0 : delta, - direction & UP_DOWN ? delta : 0); - return false; -} - - -int CachedRoot::checkForCenter(int x, int y) const -{ - int width = mViewBounds.width(); - CenterCheck centerCheck(x + width - mViewBounds.x(), y - mViewBounds.y(), - width); - BoundsCanvas checker(¢erCheck); - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, width * 3, - mViewBounds.height()); - checker.setBitmapDevice(bitmap); - checker.translate(SkIntToScalar(width - mViewBounds.x()), - SkIntToScalar(-mViewBounds.y())); - checker.drawPicture(*mPicture); - return centerCheck.center(); -} - -void CachedRoot::checkForJiggle(int* xDeltaPtr) const -{ - int xDelta = *xDeltaPtr; - JiggleCheck jiggleCheck(xDelta, mViewBounds.width()); - BoundsCanvas checker(&jiggleCheck); - SkBitmap bitmap; - int absDelta = abs(xDelta); - bitmap.setConfig(SkBitmap::kARGB_8888_Config, mViewBounds.width() + - absDelta, mViewBounds.height()); - checker.setBitmapDevice(bitmap); - checker.translate(SkIntToScalar(-mViewBounds.x() - - (xDelta < 0 ? xDelta : 0)), SkIntToScalar(-mViewBounds.y())); - checker.drawPicture(*mPicture); - *xDeltaPtr = jiggleCheck.jiggle(); -} - -const CachedNode* CachedRoot::findAt(const WebCore::IntRect& rect, - const CachedFrame** framePtr, int* x, int* y) const -{ - int best = INT_MAX; - (const_cast<CachedRoot*>(this))->resetClippedOut(); - const CachedNode* directHit = NULL; - const CachedNode* node = findBestAt(rect, &best, &directHit, framePtr, x, y); - DBG_NAV_LOGD("node=%d (%p)", node == NULL ? 0 : node->index(), - node == NULL ? NULL : node->nodePointer()); - if (node == NULL) { - node = findBestHitAt(rect, &best, framePtr, x, y); - DBG_NAV_LOGD("node=%d (%p)", node == NULL ? 0 : node->index(), - node == NULL ? NULL : node->nodePointer()); - } - if (node == NULL) { - *framePtr = findBestFrameAt(rect.x() + (rect.width() >> 1), - rect.y() + (rect.height() >> 1)); - } - return node; -} - -WebCore::IntPoint CachedRoot::focusLocation() const -{ - const WebCore::IntRect& bounds = mHistory->mNavBounds; - return WebCore::IntPoint(bounds.x() + (bounds.width() >> 1), - bounds.y() + (bounds.height() >> 1)); -} - -// These reset the values because we only want to get the selection the first time. -// After that, the selection is no longer accurate. -int CachedRoot::getAndResetSelectionEnd() -{ - int end = mSelectionEnd; - mSelectionEnd = -1; - return end; -} - -int CachedRoot::getAndResetSelectionStart() -{ - int start = mSelectionStart; - mSelectionStart = -1; - return start; -} - -void CachedRoot::getSimulatedMousePosition(WebCore::IntPoint* point) -{ -#ifndef NDEBUG - ASSERT(CachedFrame::mDebug.mInUse); -#endif - const WebCore::IntRect& mouseBounds = mHistory->mMouseBounds; - point->setX(mouseBounds.x() + (mouseBounds.width() >> 1)); - point->setY(mouseBounds.y() + (mouseBounds.height() >> 1)); -#if DEBUG_NAV_UI && !defined BROWSER_DEBUG - const WebCore::IntRect& navBounds = mHistory->mNavBounds; - LOGD("%s mHistory->mNavBounds={%d,%d,%d,%d} " - "mHistory->mMouseBounds={%d,%d,%d,%d} point={%d,%d}\n", __FUNCTION__, - navBounds.x(), navBounds.y(), navBounds.width(), navBounds.height(), - mouseBounds.x(), mouseBounds.y(), mouseBounds.width(), mouseBounds.height(), - point->x(), point->y()); -#endif -} - -void CachedRoot::init(WebCore::FrameAndroid* frame, CachedHistory* history) -{ - CachedFrame::init(this, -1, frame); - reset(); - mHistory = history; - mPicture = NULL; -} - -bool CachedRoot::innerDown(const CachedNode* test, BestData* bestData) const -{ - ASSERT(minWorkingVertical() >= mViewBounds.x()); - ASSERT(maxWorkingVertical() <= mViewBounds.right()); - setupScrolledBounds(); - // (line up) - mScrolledBounds.setHeight(mScrolledBounds.height() + mMaxYScroll); - int testTop = mScrolledBounds.y(); - int viewBottom = mViewBounds.bottom(); - if (mHistory->mFocusBounds.isEmpty() == false && - mHistory->mFocusBounds.bottom() > viewBottom && viewBottom < mContents.height()) - return false; - if (mHistory->mNavBounds.isEmpty() == false) { - int navTop = mHistory->mNavBounds.y(); - int scrollBottom; - if (testTop < navTop && navTop < (scrollBottom = mScrolledBounds.bottom())) { - mScrolledBounds.setHeight(scrollBottom - navTop); - mScrolledBounds.setY(navTop); - } - } - frameDown(test, NULL, bestData, currentFocus()); - return true; -} - -bool CachedRoot::innerLeft(const CachedNode* test, BestData* bestData) const -{ - ASSERT(minWorkingHorizontal() >= mViewBounds.y()); - ASSERT(maxWorkingHorizontal() <= mViewBounds.bottom()); - setupScrolledBounds(); - mScrolledBounds.setX(mScrolledBounds.x() - mMaxXScroll); - mScrolledBounds.setWidth(mScrolledBounds.width() + mMaxXScroll); - int testRight = mScrolledBounds.right(); - int viewLeft = mViewBounds.x(); - if (mHistory->mFocusBounds.isEmpty() == false && - mHistory->mFocusBounds.x() < viewLeft && viewLeft > mContents.x()) - return false; - if (mHistory->mNavBounds.isEmpty() == false) { - int navRight = mHistory->mNavBounds.right(); - int scrollLeft; - if (testRight > navRight && navRight > (scrollLeft = mScrolledBounds.x())) - mScrolledBounds.setWidth(navRight - scrollLeft); - } - frameLeft(test, NULL, bestData, currentFocus()); - return true; -} - - -void CachedRoot::innerMove(const CachedNode* node, BestData* bestData, - Direction direction, WebCore::IntPoint* scroll, bool firstCall) -{ - bestData->reset(); - mFocusChild = false; - bool outOfFocus = mFocus < 0; - bool firstTime = mHistory->didFirstLayout() && outOfFocus; -#if DEBUG_NAV_UI && !defined BROWSER_DEBUG - LOGD("%s mHistory->didFirstLayout()=%s && mFocus=%d\n", __FUNCTION__, - mHistory->didFirstLayout() ? "true" : "false", mFocus); -#endif - if (firstTime) - mHistory->reset(); - mHistory->setWorking(direction, currentFocus(), mViewBounds); - bool findClosest = false; - if (mScrollOnly == false) { - switch (direction) { - case LEFT: - if (outOfFocus) - mHistory->mNavBounds = WebCore::IntRect(mViewBounds.right(), - mViewBounds.y(), 1, mViewBounds.height()); - findClosest = innerLeft(node, bestData); - break; - case RIGHT: - if (outOfFocus) - mHistory->mNavBounds = WebCore::IntRect(mViewBounds.x() - 1, - mViewBounds.y(), 1, mViewBounds.height()); - findClosest = innerRight(node, bestData); - break; - case UP: - if (outOfFocus) - mHistory->mNavBounds = WebCore::IntRect(mViewBounds.x(), - mViewBounds.bottom(), mViewBounds.width(), 1); - findClosest = innerUp(node, bestData); - break; - case DOWN: - if (outOfFocus) - mHistory->mNavBounds = WebCore::IntRect(mViewBounds.x(), - mViewBounds.y() - 1, mViewBounds.width(), 1); - findClosest = innerDown(node, bestData); - break; - case UNINITIALIZED: - default: - ASSERT(0); - } - } - if (firstCall) - mHistory->mPriorBounds = mHistory->mNavBounds; // bounds always advances, even if new node is ultimately NULL - bestData->mMouseBounds = bestData->mNodeBounds; - if (adjustForScroll(bestData, direction, scroll, findClosest)) - return; - if (bestData->mNode != NULL) { - mHistory->addToVisited(bestData->mNode, direction); - mHistory->mNavBounds = mHistory->mFocusBounds = bestData->mNodeBounds; - mHistory->mMouseBounds = bestData->mMouseBounds; - } else if (scroll->x() != 0 || scroll->y() != 0) { - WebCore::IntRect newBounds = mHistory->mNavBounds; - int offsetX = scroll->x(); - int offsetY = scroll->y(); - newBounds.move(offsetX, offsetY); - if (mViewBounds.x() > newBounds.x()) - offsetX = mViewBounds.x() - mHistory->mNavBounds.x(); - else if (mViewBounds.right() < newBounds.right()) - offsetX = mViewBounds.right() - mHistory->mNavBounds.right(); - if (mViewBounds.y() > newBounds.y()) - offsetY = mViewBounds.y() - mHistory->mNavBounds.y(); - else if (mViewBounds.bottom() < newBounds.bottom()) - offsetY = mViewBounds.bottom() - mHistory->mNavBounds.bottom(); - mHistory->mNavBounds.move(offsetX, offsetY); - } - mHistory->setDidFirstLayout(false); -} - -bool CachedRoot::innerRight(const CachedNode* test, BestData* bestData) const -{ - ASSERT(minWorkingHorizontal() >= mViewBounds.y()); - ASSERT(maxWorkingHorizontal() <= mViewBounds.bottom()); - setupScrolledBounds(); - // (align) - mScrolledBounds.setWidth(mScrolledBounds.width() + mMaxXScroll); - int testLeft = mScrolledBounds.x(); - int viewRight = mViewBounds.right(); - if (mHistory->mFocusBounds.isEmpty() == false && - mHistory->mFocusBounds.right() > viewRight && viewRight < mContents.width()) - return false; - if (mHistory->mNavBounds.isEmpty() == false) { - int navLeft = mHistory->mNavBounds.x(); - int scrollRight; - if (testLeft < navLeft && navLeft < (scrollRight = mScrolledBounds.right())) { - mScrolledBounds.setWidth(scrollRight - navLeft); - mScrolledBounds.setX(navLeft); - } - } - frameRight(test, NULL, bestData, currentFocus()); - return true; -} - -bool CachedRoot::innerUp(const CachedNode* test, BestData* bestData) const -{ - ASSERT(minWorkingVertical() >= mViewBounds.x()); - ASSERT(maxWorkingVertical() <= mViewBounds.right()); - setupScrolledBounds(); - mScrolledBounds.setY(mScrolledBounds.y() - mMaxYScroll); - mScrolledBounds.setHeight(mScrolledBounds.height() + mMaxYScroll); - int testBottom = mScrolledBounds.bottom(); - int viewTop = mViewBounds.y(); - if (mHistory->mFocusBounds.isEmpty() == false && - mHistory->mFocusBounds.y() < viewTop && viewTop > mContents.y()) - return false; - if (mHistory->mNavBounds.isEmpty() == false) { - int navBottom = mHistory->mNavBounds.bottom(); - int scrollTop; - if (testBottom > navBottom && navBottom > (scrollTop = mScrolledBounds.y())) - mScrolledBounds.setHeight(navBottom - scrollTop); - } - frameUp(test, NULL, bestData, currentFocus()); - return true; -} - -bool CachedRoot::isImage(int x, int y) const -{ - ImageCheck imageCheck; - BoundsCanvas checker(&imageCheck); - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1); - checker.setBitmapDevice(bitmap); - checker.translate(SkIntToScalar(-x), SkIntToScalar(-y)); - checker.drawPicture(*mPicture); - return imageCheck.mLastIsImage; -} - -bool CachedRoot::maskIfHidden(BestData* best) const -{ - if (mPicture == NULL) { -#if DEBUG_NAV_UI && !defined BROWSER_DEBUG - LOGD("%s missing picture\n", __FUNCTION__); -#endif - return false; - } - const CachedNode* bestNode = best->mNode; - if (bestNode->isUnclipped()) - return false; - // given the picture matching this nav cache - // create an SkBitmap with dimensions of the focus intersected w/ extended view - const WebCore::IntRect& nodeBounds = bestNode->getBounds(); - WebCore::IntRect bounds = nodeBounds; - bounds.intersect(mScrolledBounds); - int leftMargin = bounds.x() == nodeBounds.x() ? kMargin : 0; - int topMargin = bounds.y() == nodeBounds.y() ? kMargin : 0; - int rightMargin = bounds.right() == nodeBounds.right() ? kMargin : 0; - int bottomMargin = bounds.bottom() == nodeBounds.bottom() ? kMargin : 0; - bool unclipped = (leftMargin & topMargin & rightMargin & bottomMargin) != 0; - WebCore::IntRect marginBounds = nodeBounds; - marginBounds.inflate(kMargin); - marginBounds.intersect(mScrolledBounds); - BoundsCheck boundsCheck; - BoundsCanvas checker(&boundsCheck); - boundsCheck.mBounds.set(leftMargin, topMargin, - leftMargin + bounds.width(), topMargin + bounds.height()); - boundsCheck.mBoundsSlop = boundsCheck.mBounds; - boundsCheck.mBoundsSlop.inset(-kSlop, -kSlop); - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, marginBounds.width(), - marginBounds.height()); - checker.setBitmapDevice(bitmap); - // insert probes to be called when the data corresponding to this focus ring is drawn - // need to know if focus ring was generated by text, image, or parent (like div) - // ? need to know (like imdb menu bar) to give up sometimes (when?) - checker.translate(SkIntToScalar(leftMargin - bounds.x()), - SkIntToScalar(topMargin - bounds.y())); - checker.drawPicture(*mPicture); - boundsCheck.checkLast(); - // was it not drawn or clipped out? - if (boundsCheck.hidden()) { // if hidden, return false so that nav can try again - CachedNode* node = const_cast<CachedNode*>(best->mNode); -#if DEBUG_NAV_UI && !defined BROWSER_DEBUG - const SkIRect& m = boundsCheck.mBounds; - const SkIRect& s = boundsCheck.mBoundsSlop; - LOGD("%s hidden node:%p (%d) mBounds={%d,%d,%d,%d} mBoundsSlop=" - "{%d,%d,%d,%d}\n", __FUNCTION__, node, node->index(), - m.fLeft, m.fTop, m.fRight, m.fBottom, - s.fLeft, s.fTop, s.fRight, s.fBottom); - const SkIRect& o = boundsCheck.mDrawnOver.getBounds(); - const SkIRect& l = boundsCheck.mLastAll; - const SkIRect& u = boundsCheck.mUnion; - LOGD("%s hidden mDrawnOver={%d,%d,%d,%d} mLastAll={%d,%d,%d,%d}" - " mUnion={%d,%d,%d,%d}\n", __FUNCTION__, - o.fLeft, o.fTop, o.fRight, o.fBottom, - l.fLeft, l.fTop, l.fRight, l.fBottom, - u.fLeft, u.fTop, u.fRight, u.fBottom); - const SkIRect& a = boundsCheck.mAllDrawnIn; - const WebCore::IntRect& c = mScrolledBounds; - const WebCore::IntRect& b = nodeBounds; - LOGD("%s hidden mAllDrawnIn={%d,%d,%d,%d} mScrolledBounds={%d,%d,%d,%d}" - " nodeBounds={%d,%d,%d,%d}\n", __FUNCTION__, - a.fLeft, a.fTop, a.fRight, a.fBottom, - c.x(), c.y(), c.right(), c.bottom(), - b.x(), b.y(), b.right(), b.bottom()); - LOGD("%s bits.mWidth=%d bits.mHeight=%d transX=%d transY=%d\n", __FUNCTION__, - marginBounds.width(),marginBounds.height(), - kMargin - bounds.x(), kMargin - bounds.y()); -#endif - node->setDisabled(true); - node->setClippedOut(unclipped == false); - return true; - } - // was it partially occluded by later drawing? - // if partially occluded, modify the bounds so that the mouse click has a better x,y - const SkIRect& over = boundsCheck.mDrawnOver.getBounds(); - if (over.isEmpty() == false) { -#if DEBUG_NAV_UI && !defined BROWSER_DEBUG - SkIRect orig = boundsCheck.mBounds; -#endif - SkIRect& base = boundsCheck.mBounds; - if (base.fLeft < over.fRight && base.fRight > over.fRight) - base.fLeft = over.fRight; - else if (base.fRight > over.fLeft && base.fLeft < over.fLeft) - base.fRight = over.fLeft; - if (base.fTop < over.fBottom && base.fBottom > over.fBottom) - base.fTop = over.fBottom; - else if (base.fBottom > over.fTop && base.fTop < over.fTop) - base.fBottom = over.fTop; -#if DEBUG_NAV_UI && !defined BROWSER_DEBUG - const SkIRect& modded = boundsCheck.mBounds; - LOGD("%s partially occluded node:%p (%d) old:{%d,%d,%d,%d} new:{%d,%d,%d,%d}\n", - __FUNCTION__, best->mNode, best->mNode->index(), - orig.fLeft, orig.fTop, orig.fRight, orig.fBottom, - base.fLeft, base.fTop, base.fRight, base.fBottom); -#endif - best->mMouseBounds = WebCore::IntRect(bounds.x() + base.fLeft - kMargin, - bounds.y() + base.fTop - kMargin, base.width(), base.height()); - } - return false; -} - -const CachedNode* CachedRoot::moveFocus(Direction direction, const CachedFrame** framePtr, - WebCore::IntPoint* scroll) -{ -#ifndef NDEBUG - ASSERT(CachedFrame::mDebug.mInUse); -#endif - CachedRoot* frame = this; - const CachedNode* node = frame->document(); - if (node == NULL) - return NULL; - if (mViewBounds.isEmpty()) - return NULL; - resetClippedOut(); - setData(); - BestData bestData; - innerMove(node, &bestData, direction, scroll, true); - *framePtr = bestData.mFrame; - return const_cast<CachedNode*>(bestData.mNode); -} - -void CachedRoot::reset() -{ -#ifndef NDEBUG - ASSERT(CachedFrame::mDebug.mInUse); -#endif - mContents = mViewBounds = WebCore::IntRect(0, 0, 0, 0); - mMaxXScroll = mMaxYScroll = 0; - mSelectionStart = mSelectionEnd = -1; - mScrollOnly = false; -// resetNavClipBounds(); -} - -bool CachedRoot::scrollDelta(WebCore::IntRect& newOutset, Direction direction, int* delta) -{ - switch (direction) { - case LEFT: - *delta = -mMaxXScroll; - return newOutset.x() >= mViewBounds.x(); - case RIGHT: - *delta = mMaxXScroll; - return newOutset.right() <= mViewBounds.right(); - case UP: - *delta = -mMaxYScroll; - return newOutset.y() >= mViewBounds.y(); - case DOWN: - *delta = mMaxYScroll; - return newOutset.bottom() <= mViewBounds.bottom(); - default: - *delta = 0; - ASSERT(0); - } - return false; -} - -void CachedRoot::setCachedFocus(CachedFrame* frame, CachedNode* node) -{ -#if !defined NDEBUG - ASSERT(CachedFrame::mDebug.mInUse); -#endif -#if DEBUG_NAV_UI && !defined BROWSER_DEBUG - const CachedNode* focus = currentFocus(); - WebCore::IntRect bounds; - if (focus) - bounds = focus->bounds(); - LOGD("%s old focus %d (nodePointer=%p) bounds={%d,%d,%d,%d}\n", __FUNCTION__, - focus ? focus->index() : 0, - focus ? focus->nodePointer() : NULL, bounds.x(), bounds.y(), - bounds.width(), bounds.height()); -#endif - clearFocus(); - if (node == NULL) - return; - node->setIsFocus(true); - ASSERT(node->isFrame() == false); - frame->setFocusIndex(node - frame->document()); - ASSERT(frame->focusIndex() > 0 && frame->focusIndex() < (int) frame->size()); - CachedFrame* parent; - while ((parent = frame->parent()) != NULL) { - parent->setFocusIndex(frame->indexInParent()); - frame = parent; - } -#if DEBUG_NAV_UI && !defined BROWSER_DEBUG - focus = currentFocus(); - bounds = WebCore::IntRect(0, 0, 0, 0); - if (focus) - bounds = focus->bounds(); - LOGD("%s new focus %d (nodePointer=%p) bounds={%d,%d,%d,%d}\n", __FUNCTION__, - focus ? focus->index() : 0, - focus ? focus->nodePointer() : NULL, bounds.x(), bounds.y(), - bounds.width(), bounds.height()); -#endif -} - -void CachedRoot::setupScrolledBounds() const -{ - mScrolledBounds = mViewBounds; -} - -#if DUMP_NAV_CACHE - -#define DEBUG_PRINT_BOOL(field) \ - DUMP_NAV_LOGD("// bool " #field "=%s;\n", b->field ? "true" : "false") - -CachedRoot* CachedRoot::Debug::base() const { - CachedRoot* nav = (CachedRoot*) ((char*) this - OFFSETOF(CachedRoot, mDebug)); - return nav; -} - -void CachedRoot::Debug::print() const -{ -#ifdef DUMP_NAV_CACHE_USING_PRINTF - gWriteLogMutex.lock(); - ASSERT(gNavCacheLogFile == NULL); - gNavCacheLogFile = fopen(NAV_CACHE_LOG_FILE, "a"); -#endif - CachedRoot* b = base(); - b->CachedFrame::mDebug.print(); - b->mHistory->mDebug.print(b); - DUMP_NAV_LOGD("// int mMaxXScroll=%d, mMaxYScroll=%d;\n", - b->mMaxXScroll, b->mMaxYScroll); - DEBUG_PRINT_BOOL(mFocusChild); -#ifdef DUMP_NAV_CACHE_USING_PRINTF - if (gNavCacheLogFile) - fclose(gNavCacheLogFile); - gNavCacheLogFile = NULL; - gWriteLogMutex.unlock(); -#endif -} - -#endif - -} diff --git a/WebCore/platform/android/nav/CachedRoot.h b/WebCore/platform/android/nav/CachedRoot.h deleted file mode 100644 index e28141e..0000000 --- a/WebCore/platform/android/nav/CachedRoot.h +++ /dev/null @@ -1,101 +0,0 @@ -/* -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef CachedRoot_H -#define CachedRoot_H - -#include "CachedFrame.h" -#include "IntPoint.h" -#include "SkPicture.h" - -namespace android { - -class CachedHistory; -class CachedNode; - -class CachedRoot : public CachedFrame { -public: - bool adjustForScroll(BestData* , Direction , WebCore::IntPoint* scrollPtr, - bool findClosest); - int checkForCenter(int x, int y) const; - void checkForJiggle(int* ) const; - int documentHeight() { return mContents.height(); } - int documentWidth() { return mContents.width(); } - const CachedNode* findAt(const WebCore::IntRect& , const CachedFrame** , - int* x, int* y) const; - bool focusChild() const { return mFocusChild; } - WebCore::IntPoint focusLocation() const; - int generation() const { return mGeneration; } - int textGeneration() const { return mTextGeneration; } - int getAndResetSelectionEnd(); - int getAndResetSelectionStart(); -// const WebCore::IntRect& navClipBounds() const { return mClippedBounds; } - void getSimulatedMousePosition(WebCore::IntPoint* ); -// bool hasNavClipBounds() { return mClippedBounds.isEmpty() == false; } - void init(WebCore::FrameAndroid* , CachedHistory* ); - bool innerDown(const CachedNode* , BestData* ) const; - bool innerLeft(const CachedNode* , BestData* ) const; - void innerMove(const CachedNode* ,BestData* bestData, Direction , - WebCore::IntPoint* scroll, bool firstCall); - bool innerRight(const CachedNode* , BestData* ) const; - bool innerUp(const CachedNode* , BestData* ) const; - bool isImage(int x, int y) const; - bool maskIfHidden(BestData* ) const; - const CachedNode* moveFocus(Direction , const CachedFrame** , WebCore::IntPoint* scroll); - void reset(); -// void resetNavClipBounds() { mClippedBounds = WebCore::IntRect(-1, -1, 0, 0); } - CachedHistory* rootHistory() const { return mHistory; } - bool scrollDelta(WebCore::IntRect& focusRingBounds, Direction , int* delta); - const WebCore::IntRect& scrolledBounds() const { return mScrolledBounds; } - void setCachedFocus(CachedFrame* , CachedNode* ); - void setGeneration(int generation) { mGeneration = generation; } - void setTextGeneration(int textGeneration) { mTextGeneration = textGeneration; } - void setFocusChild(bool state) const { mFocusChild = state; } - void setMaxScroll(int x, int y) { mMaxXScroll = x; mMaxYScroll = y; } -// void setNavClipBounds(const WebCore::IntRect& r) { mClippedBounds = r; } - void setPicture(SkPicture* picture) { mPicture = picture; } - void setScrollOnly(bool state) { mScrollOnly = state; } - void setSelection(int start, int end) { mSelectionStart = start; mSelectionEnd = end; } - void setupScrolledBounds() const; - void setVisibleRect(const WebCore::IntRect& r) { mViewBounds = r; } - int width() const { return mPicture ? mPicture->width() : 0; } -private: - CachedHistory* mHistory; - SkPicture* mPicture; - // WebCore::IntRect mClippedBounds; - mutable WebCore::IntRect mScrolledBounds; // view bounds + amount visible as result of scroll - int mGeneration; - int mTextGeneration; - int mMaxXScroll; - int mMaxYScroll; - // These two are ONLY used when the tree is rebuilt and the focus is a textfield/area - int mSelectionStart; - int mSelectionEnd; - mutable bool mFocusChild; // temporary state set if walked nodes are children of focus - bool mScrollOnly; -#if DUMP_NAV_CACHE -public: - class Debug { -public: - CachedRoot* base() const; - void print() const; - } mDebug; -#endif -}; - -} - -#endif diff --git a/WebCore/platform/android/nav/SelectText.cpp b/WebCore/platform/android/nav/SelectText.cpp deleted file mode 100644 index e84d2dc..0000000 --- a/WebCore/platform/android/nav/SelectText.cpp +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright 2008, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "webcoreglue" - -#include <config.h> -#include "CachedDebug.h" -#include "SelectText.h" -#include "SkBitmap.h" -#include "SkBounder.h" -#include "SkCanvas.h" -#include "SkMatrix.h" -#include "SkPicture.h" -#include "SkPoint.h" -#include "SkRect.h" -#include "SkRegion.h" - -#ifdef LOG -#undef LOG -#endif - -#include <utils/Log.h> - -class CommonCheck : public SkBounder { -public: - CommonCheck() : mMatrix(NULL), mPaint(NULL) {} - - virtual void setUp(const SkPaint& paint, const SkMatrix& matrix, SkScalar y) { - mMatrix = &matrix; - mPaint = &paint; - mY = y; - mTop = INT_MAX; - mBottom = INT_MAX; - } - - int top() { - if (mTop == INT_MAX) { - SkPoint result; - SkPaint::FontMetrics metrics; - mPaint->getFontMetrics(&metrics); - mMatrix->mapXY(0, metrics.fAscent + mY, &result); - mTop = SkScalarFloor(result.fY); - DBG_NAV_LOGD("mMatrix:(%d, %d) mTop=%g", - mMatrix->getTranslateX(), mMatrix->getTranslateY(), mTop); - } - return mTop; - } - - int bottom() { - if (mBottom == INT_MAX) { - SkPoint result; - SkPaint::FontMetrics metrics; - mPaint->getFontMetrics(&metrics); - mMatrix->mapXY(0, metrics.fDescent + mY, &result); - mBottom = SkScalarCeil(result.fY); - } - return mBottom; - } - -protected: - const SkMatrix* mMatrix; - const SkPaint* mPaint; - int mBottom; - int mTop; - SkScalar mY; -}; - -class FirstCheck : public CommonCheck { -public: - FirstCheck(int x, int y) - : mDistance(INT_MAX), mFocusX(x), mFocusY(y) { - mBestBounds.setEmpty(); - } - - const SkIRect& bestBounds() { - DBG_NAV_LOGD("mBestBounds:(%d, %d, %d, %d) mTop=%g mBottom=%g", - mBestBounds.fLeft, mBestBounds.fTop, mBestBounds.fRight, - mBestBounds.fBottom, SkScalarToFloat(mTop), SkScalarToFloat(mBottom)); - return mBestBounds; - } - - void offsetBounds(int dx, int dy) { - mBestBounds.offset(dx, dy); - } - - virtual bool onIRect(const SkIRect& rect) { - if (mBestBounds.isEmpty()) { - mBestBounds.set(rect.fLeft, top(), rect.fRight, bottom()); - } else { - int dx = ((rect.fLeft + rect.fRight) >> 1) - mFocusX; - int dy = SkScalarRound(((top() + bottom()) / 2)) - mFocusY; - int distance = dx * dx + dy * dy; - if (mDistance > distance) { - mDistance = distance; - mBestBounds.set(rect.fLeft, top(), rect.fRight, bottom()); - } - } - return false; - } -protected: - SkIRect mBestBounds; - int mDistance; - int mFocusX; - int mFocusY; -}; - -class MultilineBuilder : public CommonCheck { -public: - MultilineBuilder(const SkIRect& start, const SkIRect& end, int dx, int dy, - SkRegion* region) - : mStart(start), mEnd(end), mSelectRegion(region), mCapture(false) { - mLast.setEmpty(); - mStart.offset(-dx, -dy); - mEnd.offset(-dx, -dy); - } - - virtual bool onIRect(const SkIRect& rect) { - bool captureLast = false; - if ((rect.fLeft == mStart.fLeft && rect.fRight == mStart.fRight && - top() == mStart.fTop && bottom() == mStart.fBottom) || - (rect.fLeft == mEnd.fLeft && rect.fRight == mEnd.fRight && - top() == mEnd.fTop && bottom() == mEnd.fBottom)) { - captureLast = mCapture; - mCapture ^= true; - } - if (mCapture || captureLast) { - SkIRect full; - full.set(rect.fLeft, top(), rect.fRight, bottom()); - if (mLast.fTop < full.fBottom && mLast.fBottom > full.fTop) { - if (full.fLeft > mLast.fRight) - full.fLeft = mLast.fRight; - else if (full.fRight < mLast.fLeft) - full.fRight = mLast.fLeft; - } - mSelectRegion->op(full, SkRegion::kUnion_Op); - mLast = full; - if (mStart == mEnd) - mCapture = false; - } - return false; - } -protected: - SkIRect mStart; - SkIRect mEnd; - SkIRect mLast; - SkRegion* mSelectRegion; - bool mCapture; -}; - -class TextCanvas : public SkCanvas { -public: - - TextCanvas(CommonCheck* bounder, const SkPicture& picture, const SkIRect& area) - : mBounder(*bounder) { - setBounder(bounder); - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, area.width(), - area.height()); - setBitmapDevice(bitmap); - translate(SkIntToScalar(-area.fLeft), SkIntToScalar(-area.fTop)); - } - - virtual ~TextCanvas() { - setBounder(NULL); - } - - virtual void drawPaint(const SkPaint& paint) { - } - - virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], - const SkPaint& paint) { - } - - virtual void drawRect(const SkRect& rect, const SkPaint& paint) { - } - - virtual void drawPath(const SkPath& path, const SkPaint& paint) { - } - - virtual void commonDrawBitmap(const SkBitmap& bitmap, - const SkMatrix& matrix, const SkPaint& paint) { - } - - virtual void drawSprite(const SkBitmap& bitmap, int left, int top, - const SkPaint* paint = NULL) { - } - - virtual void drawText(const void* text, size_t byteLength, SkScalar x, - SkScalar y, const SkPaint& paint) { - mBounder.setUp(paint, getTotalMatrix(), y); - SkCanvas::drawText(text, byteLength, x, y, paint); - } - - virtual void drawPosTextH(const void* text, size_t byteLength, - const SkScalar xpos[], SkScalar constY, - const SkPaint& paint) { - mBounder.setUp(paint, getTotalMatrix(), constY); - SkCanvas::drawPosTextH(text, byteLength, xpos, constY, paint); - } - - virtual void drawVertices(VertexMode vmode, int vertexCount, - const SkPoint vertices[], const SkPoint texs[], - const SkColor colors[], SkXfermode* xmode, - const uint16_t indices[], int indexCount, - const SkPaint& paint) { - } - - CommonCheck& mBounder; -}; - -void CopyPaste::buildSelection(const SkPicture& picture, const SkIRect& area, - const SkIRect& selStart, const SkIRect& selEnd, SkRegion* region) { - DBG_NAV_LOGD("area=(%d, %d, %d, %d) selStart=(%d, %d, %d, %d)" - " selEnd=(%d, %d, %d, %d)", - area.fLeft, area.fTop, area.fRight, area.fBottom, - selStart.fLeft, selStart.fTop, selStart.fRight, selStart.fBottom, - selEnd.fLeft, selEnd.fTop, selEnd.fRight, selEnd.fBottom); - MultilineBuilder builder(selStart, selEnd, area.fLeft, area.fTop, region); - TextCanvas checker(&builder, picture, area); - checker.drawPicture(const_cast<SkPicture&>(picture)); - region->translate(area.fLeft, area.fTop); -} - -SkIRect CopyPaste::findClosest(const SkPicture& picture, const SkIRect& area, - int x, int y) { - FirstCheck _check(x - area.fLeft, y - area.fTop); - DBG_NAV_LOGD("area=(%d, %d, %d, %d) x=%d y=%d", area.fLeft, area.fTop, - area.fRight, area.fBottom, x, y); - TextCanvas checker(&_check, picture, area); - checker.drawPicture(const_cast<SkPicture&>(picture)); - _check.offsetBounds(area.fLeft, area.fTop); - return _check.bestBounds(); -} diff --git a/WebCore/platform/android/nav/SelectText.h b/WebCore/platform/android/nav/SelectText.h deleted file mode 100644 index ba0b089..0000000 --- a/WebCore/platform/android/nav/SelectText.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * - * Copyright 2008, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SELECT_TEXT_H -#define SELECT_TEXT_H - -class SkPicture; -struct SkIRect; -struct SkIPoint; -class SkRegion; - -class CopyPaste { -public: - static void buildSelection(const SkPicture& , const SkIRect& area, - const SkIRect& selStart, const SkIRect& selEnd, SkRegion* region); - static SkIRect findClosest(const SkPicture& , const SkIRect& area, - int x, int y); -}; - -#endif diff --git a/WebCore/platform/android/nav/WebView.cpp b/WebCore/platform/android/nav/WebView.cpp deleted file mode 100644 index 7e4791d..0000000 --- a/WebCore/platform/android/nav/WebView.cpp +++ /dev/null @@ -1,1922 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "webviewglue" - -#include <config.h> - -#include "android_graphics.h" -#include "AtomicString.h" -#include "CachedFrame.h" -#include "CachedNode.h" -#include "CachedRoot.h" -#include "Frame.h" -#include "GraphicsJNI.h" -#include "IntPoint.h" -#include "IntRect.h" -#include "Node.h" -#include "PlatformGraphicsContext.h" -#include "PlatformString.h" -#include "SelectText.h" -#include "SkCanvas.h" -#include "SkPath.h" -#include "SkPicture.h" -#include "SkPixelXorXfermode.h" -#include "SkRect.h" -#include "SkTime.h" -#include "WebViewCore.h" - -#ifdef LOG // WebKit may define this as well; if so, undefine it so LOGD will work -#undef LOG -#endif - -#ifdef GET_NATIVE_VIEW -#undef GET_NATIVE_VIEW -#endif - -#define GET_NATIVE_VIEW(env, obj) ((WebView*)env->GetIntField(obj, gWebViewField)) - -#include <ui/KeycodeLabels.h> -#include <utils/Log.h> -#include <JNIHelp.h> -#include <jni.h> - -#define REPLAY_BUFFER_SIZE 4096 - -namespace android { - -// This class provides JNI for making calls into native code from the UI side -// of the multi-threaded WebView. -struct CommonParams { - enum Trigger { - NO_DATA, - CLEAR_FOCUS_PARAMS, - FIRST_MOVE_FOCUS_PARAMS, - MOVE_FOCUS_PARAMS, - MOTION_UP_PARAMS - } mTrigger; - int mGeneration; -}; - -struct CacheParams { - void setFocus(const CachedNode* node, - const CachedFrame* frame, const CachedRoot* root, - const WebCore::IntPoint& focusLocation) - { - mNode = (WebCore::Node* ) (node ? node->nodePointer() : NULL); - mFrame = (WebCore::Frame* ) (node ? frame->framePointer() : NULL); - mX = focusLocation.x(); - mY = focusLocation.y(); - } - - WebCore::Node* mNode; - WebCore::Frame* mFrame; - int mX; - int mY; -}; - -struct ClearFocusParams { - CommonParams d; - CacheParams c; - int mX; - int mY; -}; - -struct MotionUpParams { - CommonParams d; - int mX; - int mY; - int mSlop; - bool mIsClick; -}; - -struct FirstMoveFocusParams { - CommonParams d; - int mKeyCode; - int mCount; - bool mIgnoreScroll; -}; - -struct MoveFocusParams { - FirstMoveFocusParams d; - CacheParams c; - void* mSentFocus; - WebCore::IntRect mClipRect; - WebCore::IntRect mSentBounds; - WebCore::IntRect mVisibleRect; - CachedHistory mHistory; // FIXME: make this a subset - int mXMax; - int mYMax; -}; - -typedef MoveFocusParams LargestParams; - -#if DEBUG_NAV_UI -static const char* TriggerNames[] = { - "*** no data ! ***", - "clearFocus", - "firstMoveFocus", - "moveFocus", - "motionUp" -}; -#endif - -class FocusReplay { -public: -FocusReplay() : mStart(mBuffer), mEnd(mBuffer), mLastGeneration(0) -{ -} - -// find the most recent common data -void add(const CommonParams& data, size_t len) -{ - DBG_NAV_LOGD("mStart=%d mEnd=%d trigger=%s moveGeneration=%d", mStart - mBuffer, - mEnd - mBuffer, TriggerNames[data.mTrigger], data.mGeneration); - mLastGeneration = data.mGeneration; - char* limit = mBuffer + sizeof(mBuffer); - int used = mEnd - mStart; - if (used < 0) - used += sizeof(mBuffer); - int needed = (int) len - ((int) sizeof(mBuffer) - used); - if (needed >= 0) - reclaim(++needed); - if (mEnd + len <= limit) { - memcpy(mEnd, (void*) &data, len); - mEnd += len; - DBG_NAV_LOGD("mStart=%d mEnd=%d", mStart - mBuffer, mEnd - mBuffer); - return; - } - size_t partial = limit - mEnd; - memcpy(mEnd, (void*) &data, partial); - const void* remainder = (const void*) ((const char*) &data + partial); - partial = len - partial; - memcpy(mBuffer, remainder, partial); - mEnd = mBuffer + partial; - DBG_NAV_LOGD("wrap mStart=%d mEnd=%d", - mStart - mBuffer, mEnd - mBuffer); -} - -int count() -{ - DBG_NAV_LOGD("mStart=%d mEnd=%d", - mStart - mBuffer, mEnd - mBuffer); - if (mStart == mEnd) - return 0; - char* limit = mBuffer + sizeof(mBuffer); - char* saveStart = mStart; - int result = 0; - while (true) { - ++result; - mStart += triggerSize(); - if (mStart == mEnd) - break; - if (mStart >= limit) - mStart -= sizeof(mBuffer); - } - mStart = saveStart; - DBG_NAV_LOGD("count=%d", result); - return result; -} - -void discard(int generation) -{ - DBG_NAV_LOGD("generation=%d", generation); - LargestParams storage; - const CommonParams& params = storage.d.d; - char* pos = position(); - retrieve(&storage.d.d); - if (params.mGeneration > generation) { - DBG_NAV_LOGD("params.mGeneration=%d > generation=%d", - params.mGeneration, generation); - rewind(pos); - DBG_NAV_LOGD("mStart=%d mEnd=%d", mStart - mBuffer, mEnd - mBuffer); - return; - } - LOG_ASSERT(params.mGeneration == generation, "params.mGeneration != generation"); - DBG_NAV_LOGD("mStart=%d mEnd=%d", mStart - mBuffer, mEnd - mBuffer); -} - -int lastAdd() -{ - return mLastGeneration; -} - -char* position() -{ - return mStart; -} - -int retrieve(CommonParams* data) -{ - if (mEnd == mStart) { - // changed from LOGD to LOGV, as it always fires when I click to center - // text (mrr) - LOGV("%s *** no data to retrieve (error condition) ***", __FUNCTION__); - data->mTrigger = CommonParams::NO_DATA; - return data->mGeneration = INT_MAX; - } - DBG_NAV_LOGD("mStart=%d mEnd=%d", - mStart - mBuffer, mEnd - mBuffer); - char* limit = mBuffer + sizeof(mBuffer); - size_t size = triggerSize(); - if (mStart < mEnd) { - LOG_ASSERT((size_t) (mEnd - mStart) >= size, "mEnd - mStart < size"); - memcpy(data, mStart, size); - mStart += size; - } else { - int partial = limit - mStart; - if (partial > (int) size) - partial = size; - memcpy(data, mStart, partial); - mStart += partial; - void* remainder = (void*) ((char*) data + partial); - partial = size - partial; - if (partial > 0) { - memcpy(remainder, mBuffer, partial); - mStart = mBuffer + partial; - LOG_ASSERT(mStart <= mEnd, "mStart > mEnd"); - } - } - if (mStart == limit) { - mStart = mBuffer; - if (mEnd == limit) - mEnd = mBuffer; - } - DBG_NAV_LOGD("mStart=%d mEnd=%d trigger=%s moveGeneration=%d", - mStart - mBuffer, mEnd - mBuffer, TriggerNames[data->mTrigger], - data->mGeneration); - return data->mGeneration; -} - -void rewind(char* pos) -{ - mStart = pos; -} - -private: -void reclaim(int needed) -{ - DBG_NAV_LOGD("needed=%d", needed); - char* limit = mBuffer + sizeof(mBuffer); - do { - size_t size = triggerSize(); - mStart += size; - needed -= size; - if (mStart >= limit) { - mStart = mBuffer + (mStart - limit); - if (mEnd == limit) - mEnd = mBuffer; - } - } while (needed > 0 && mStart != mEnd); - DBG_NAV_LOGD("mStart=%d mEnd=%d", - mStart - mBuffer, mEnd - mBuffer); -} - -size_t triggerSize() -{ - LOG_ASSERT(mStart != mEnd, "mStart == mEnd"); - char* limit = mBuffer + sizeof(mBuffer); - LOG_ASSERT(mStart + sizeof(CommonParams::Trigger) <= limit, "trigger not in limit"); - CommonParams::Trigger trigger; - memcpy(&trigger, mStart, sizeof(trigger)); - switch (trigger) { - case CommonParams::CLEAR_FOCUS_PARAMS: - return sizeof(ClearFocusParams); - case CommonParams::FIRST_MOVE_FOCUS_PARAMS: - return sizeof(FirstMoveFocusParams); - case CommonParams::MOVE_FOCUS_PARAMS: - return sizeof(MoveFocusParams); - case CommonParams::MOTION_UP_PARAMS: - return sizeof(MotionUpParams); - default: - LOG_ASSERT(0, "trigger undefined"); - } - return 0; -} - -char mBuffer[REPLAY_BUFFER_SIZE]; -char* mStart; -char* mEnd; -int mLastGeneration; -}; // end of helper class ReplayFocus - -static jfieldID gWebViewField; - -//------------------------------------- - -extern JavaVM* jnienv_to_javavm(JNIEnv* env); -extern JNIEnv* javavm_to_jnienv(JavaVM* vm); - -static bool checkException(JNIEnv* env) -{ - if (env->ExceptionCheck() != 0) - { - LOGE("*** Uncaught exception returned from Java call!\n"); - env->ExceptionDescribe(); - return true; - } - return false; -} - -static jmethodID GetJMethod(JNIEnv* env, jclass clazz, const char name[], const char signature[]) -{ - jmethodID m = env->GetMethodID(clazz, name, signature); - LOG_ASSERT(m, "Could not find method %s", name); - return m; -} - -//------------------------------------- -class WebView -{ -public: -enum FrameCachePermission { - DONT_ALLOW_NEWER, - ALLOW_NEWER, - ALLOW_NEWEST -}; - -enum OutOfFocusFix { - DO_NOTHING, - CLEAR_TEXT_ENTRY, - UPDATE_TEXT_ENTRY -}; - -struct JavaGlue -{ - JavaVM* mJVM; - jobject mObj; - jmethodID mClearTextEntry; - jmethodID mScrollBy; - jmethodID mSendFinalFocus; - jmethodID mSendKitFocus; - jmethodID mSendMotionUp; - jmethodID mSetFocusData; - jmethodID mGetScaledMaxXScroll; - jmethodID mGetScaledMaxYScroll; - jmethodID mGetVisibleRect; - jmethodID mUpdateTextEntry; - jmethodID mViewInvalidate; - jmethodID mPostInvalidateDelayed; - jfieldID mRectLeft; - jfieldID mRectTop; - jmethodID mRectWidth; - jmethodID mRectHeight; - jfieldID mFocusNode; - jmethodID mSetAll; -} mJavaGlue; - -WebView(JNIEnv* env, jobject javaWebView, int viewImpl) -{ - jclass clazz = env->FindClass("android/webkit/WebView"); - // mJavaGlue = new JavaGlue; - mJavaGlue.mJVM = jnienv_to_javavm(env); - mJavaGlue.mObj = env->NewGlobalRef(javaWebView); - mJavaGlue.mScrollBy = GetJMethod(env, clazz, "setContentScrollBy", "(II)V"); - mJavaGlue.mClearTextEntry = GetJMethod(env, clazz, "clearTextEntry", "()V"); - mJavaGlue.mSendFinalFocus = GetJMethod(env, clazz, "sendFinalFocus", "(IIII)V"); - mJavaGlue.mSendKitFocus = GetJMethod(env, clazz, "sendKitFocus", "()V"); - mJavaGlue.mSendMotionUp = GetJMethod(env, clazz, "sendMotionUp", "(IIIIIIIZZ)V"); - mJavaGlue.mSetFocusData = GetJMethod(env, clazz, "setFocusData", "(IIIIIIZ)V"); - mJavaGlue.mGetScaledMaxXScroll = GetJMethod(env, clazz, "getScaledMaxXScroll", "()I"); - mJavaGlue.mGetScaledMaxYScroll = GetJMethod(env, clazz, "getScaledMaxYScroll", "()I"); - mJavaGlue.mGetVisibleRect = GetJMethod(env, clazz, "sendOurVisibleRect", "()Landroid/graphics/Rect;"); - mJavaGlue.mUpdateTextEntry = GetJMethod(env, clazz, "updateTextEntry", "()V"); - mJavaGlue.mViewInvalidate = GetJMethod(env, clazz, "viewInvalidate", "()V"); - jclass viewClass = env->FindClass("android/view/View"); - mJavaGlue.mPostInvalidateDelayed = GetJMethod(env, viewClass, - "postInvalidateDelayed", "(JIIII)V"); - jclass rectClass = env->FindClass("android/graphics/Rect"); - LOG_ASSERT(rectClass, "Could not find Rect class"); - mJavaGlue.mRectLeft = env->GetFieldID(rectClass, "left", "I"); - mJavaGlue.mRectTop = env->GetFieldID(rectClass, "top", "I"); - mJavaGlue.mRectWidth = GetJMethod(env, rectClass, "width", "()I"); - mJavaGlue.mRectHeight = GetJMethod(env, rectClass, "height", "()I"); - - // Set up class for updateFocusNode - jclass focusnodeClass = env->FindClass("android/webkit/WebView$FocusNode"); - LOG_ASSERT(focusnodeClass, "Could not find FocusNode class!"); - mJavaGlue.mFocusNode = env->GetFieldID(clazz, "mFocusNode", "Landroid/webkit/WebView$FocusNode;"); - mJavaGlue.mSetAll = GetJMethod(env, focusnodeClass, "setAll", "(ZZZZZIIIIIIIILjava/lang/String;Ljava/lang/String;I)V"); - env->DeleteLocalRef(focusnodeClass); - - env->SetIntField(javaWebView, gWebViewField, (jint)this); - mViewImpl = (WebViewCore*) viewImpl; - mFrameCacheUI = NULL; - mNavPictureUI = NULL; - mInvalidNode = NULL; - mGeneration = 0; - mHeightCanMeasure = false; - mFollowedLink = false; - mLastDx = 0; - mLastDxTime = 0; - mRingAnimationEnd = 0; - mUIButtons = NULL; - mSelStart.setEmpty(); - mSelEnd.setEmpty(); -} - -~WebView() -{ - if (mJavaGlue.mObj) - { - JNIEnv* env = javavm_to_jnienv(mJavaGlue.mJVM); - env->DeleteGlobalRef(mJavaGlue.mObj); - mJavaGlue.mObj = 0; - } - delete mFrameCacheUI; - delete mNavPictureUI; - if (mUIButtons != NULL) { - mUIButtons->deleteAll(); - delete mUIButtons; - } -} - -void clearFocus(int x, int y, bool inval) -{ - DBG_NAV_LOGD("x=%d y=%d inval=%s", x, y, - inval ? "true" : "false"); - clearTextEntry(); - CachedRoot* root = getFrameCache(ALLOW_NEWER); - if (root == NULL) - return; - const CachedFrame* oldFrame = NULL; - const CachedNode* oldFocusNode = root->currentFocus(&oldFrame); - WebCore::IntPoint focusLocation = WebCore::IntPoint(0, 0); - setFocusData(root->generation(), NULL, NULL, x, y, oldFocusNode == NULL); - sendKitFocus(); - if (oldFocusNode != NULL) { - DBG_NAV_LOG("oldFocusNode != NULL"); - focusLocation = root->focusLocation(); - root->setCachedFocus(NULL, NULL); - if (inval) - viewInvalidate(); - } - ClearFocusParams params; - params.d.mTrigger = CommonParams::CLEAR_FOCUS_PARAMS; - params.d.mGeneration = mGeneration; - params.c.setFocus(oldFocusNode, oldFrame, root, focusLocation); - params.mX = x; - params.mY = y; - mReplay.add(params.d, sizeof(params)); -} - -void clearTextEntry() -{ - DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); - JNIEnv* env = javavm_to_jnienv(mJavaGlue.mJVM); - env->CallVoidMethod(mJavaGlue.mObj, mJavaGlue.mClearTextEntry); - checkException(env); -} - -#if DUMP_NAV_CACHE -void debugDump() -{ - CachedRoot* root = getFrameCache(DONT_ALLOW_NEWER); - if (root) - root->mDebug.print(); -} -#endif - -#ifdef BUCKET_EXPERIMENT -void clearContentPicture() { - if (mViewImpl != NULL) { - mViewImpl->mUIBuckets.clear(); - } -} - -void drawContentPicture(SkCanvas* canvas) { - WTF::Vector<WebViewCore::Bucket>& buckets = mViewImpl->mUIBuckets; - const WebViewCore::Bucket* const end = buckets.end(); - for (WebViewCore::Bucket* bucket = buckets.begin(); bucket != end; bucket++) { - SkRect bounds; - const WebCore::IntRect& buckB = bucket->mBounds; - bounds.set(SkIntToScalar(buckB.x()), SkIntToScalar(buckB.y()), - SkIntToScalar(buckB.right()), SkIntToScalar(buckB.bottom())); - if (canvas->quickReject(bounds, SkCanvas::kBW_EdgeType)) { - continue; - } - canvas->drawPicture(*bucket->mPicture); - } -} -#endif - -// Traverse our stored array of buttons that are in our picture, and update -// their subpictures according to their current focus state. -// Called from the UI thread. This is the one place in the UI thread where we -// access the buttons stored in the WebCore thread. -void nativeRecordButtons() -{ - // Check to see if the WebCore thread has created a new set of buttons. - // We don't have to grab the mutex for this test, since the only place it - // could be set to null is right below, or in WebViewCore's constructor. - if (mViewImpl->mButtons != NULL) { - if (mUIButtons != NULL) { - mUIButtons->deleteAll(); - delete mUIButtons; - } - // Transfer ownership of the array from the WebCore thread (viewimpl) to - // the UI thread - mViewImpl->gButtonMutex.lock(); - mUIButtons = mViewImpl->mButtons; - mViewImpl->mButtons = NULL; - mViewImpl->gButtonMutex.unlock(); - } - - // If mUIButtons has never been set, or it has been set with an array of no - // buttons (which happens if a page does not have any buttons), then return. - if (mUIButtons == NULL || mUIButtons->count() == 0) - return; - - // Find the focused node so we can determine which node has focus, and - // therefore which state to paint them in. - // FIXME: In a future change, we should keep track of whether the focus has - // changed to short circuit (note that we would still need to update if we - // received new buttons from the WebCore thread). - WebCore::Node* focus = NULL; - CachedRoot* root = getFrameCache(DONT_ALLOW_NEWER); - if (root != NULL) { - const CachedNode* cachedNode = root->currentFocus(); - if (cachedNode != NULL) - focus = (WebCore::Node*) cachedNode->nodePointer(); - } - - // Traverse the array, and update each button, depending on whether it is - // focused. - Container** end = mUIButtons->end(); - for (Container** ptr = mUIButtons->begin(); ptr != end; ptr++) { - (*ptr)->updateFocusState(focus); - } -} - -void drawFocusRing(SkCanvas* canvas) -{ - const CachedRoot* root = getFrameCache(ALLOW_NEWER); - if (root == NULL) { - DBG_NAV_LOG("root==NULL"); - mFollowedLink = false; - return; - } - const CachedNode* node = root->currentFocus(); - if (node == NULL) { - DBG_NAV_LOG("node==NULL"); - mFollowedLink = false; - return; - } - if (node->hasFocusRing() == false) { - DBG_NAV_LOG("node->hasFocusRing() == false"); - return; - } - const WTF::Vector<WebCore::IntRect>& rings = node->focusRings(); - if (0 == rings.size()) { - DBG_NAV_LOG("rings.size()==0"); - return; - } - - bool isButton = false; - // If this is a button drawn by us (rather than webkit) do not draw the - // focus ring, since its focus will be shown by a change in what we draw. - if (mUIButtons != NULL) { - // Should be in sync with recordButtons, since that will be called - // before this. - if (mUIButtons->count() > 0) { - WebCore::Node* focusPointer = (WebCore::Node*) node->nodePointer(); - Container** end = mUIButtons->end(); - for (Container** ptr = mUIButtons->begin(); ptr != end; ptr++) { - if ((*ptr)->matches(focusPointer)) { - isButton = true; - break; - } - } - } - } - FocusRing::Flavor flavor = isButton ? FocusRing::BUTTON_NO_RING : - node->type() != NORMAL_CACHEDNODETYPE ? - FocusRing::FAKE_FLAVOR : node->nodePointer() == mInvalidNode ? - FocusRing::INVALID_FLAVOR : FocusRing::NORMAL_FLAVOR; - if (flavor != FocusRing::INVALID_FLAVOR && mFollowedLink) { - flavor = (FocusRing::Flavor) (flavor + FocusRing::NORMAL_ANIMATING); - } -#if DEBUG_NAV_UI - const WebCore::IntRect& ring = rings[0]; - DBG_NAV_LOGD("cachedFocusNode=%d (nodePointer=%p) flavor=%s rings=%d" - " (%d, %d, %d, %d)", node->index(), node->nodePointer(), - flavor == FocusRing::FAKE_FLAVOR ? "FAKE_FLAVOR" : - flavor == FocusRing::INVALID_FLAVOR ? "INVALID_FLAVOR" : - flavor == FocusRing::NORMAL_ANIMATING ? "NORMAL_ANIMATING" : - flavor == FocusRing::FAKE_ANIMATING ? "FAKE_ANIMATING" : - flavor == FocusRing::BUTTON_NO_RING ? "BUTTON_NO_RING" : - flavor == FocusRing::BUTTON_ANIMATING ? "BUTTON_ANIMATING" : "NORMAL_FLAVOR", - rings.size(), ring.x(), ring.y(), ring.width(), ring.height()); -#endif - if (flavor >= FocusRing::NORMAL_ANIMATING) { - SkMSec time = SkTime::GetMSecs(); - if (time < mRingAnimationEnd) { - WebCore::IntRect bounds = node->bounds(); - bounds.inflate(SkScalarCeil(FOCUS_RING_OUTER_DIAMETER)); - postInvalidateDelayed(mRingAnimationEnd - time, bounds); - } else { - mFollowedLink = false; - flavor = (FocusRing::Flavor) (flavor - FocusRing::NORMAL_ANIMATING); - } - } - FocusRing::DrawRing(canvas, rings, flavor); -} - -OutOfFocusFix fixOutOfDateFocus(bool useReplay) -{ - if (mFrameCacheUI == NULL) { - DBG_NAV_LOG("mFrameCacheUI == NULL"); - return DO_NOTHING; - } - const CachedFrame* cachedFrame = NULL; - const CachedNode* cachedFocusNode = mFrameCacheUI->currentFocus(&cachedFrame); - if (cachedFocusNode == NULL) { - DBG_NAV_LOG("cachedFocusNode == NULL"); - return DO_NOTHING; - } - CachedRoot* webRoot = mViewImpl->mFrameCacheKit; - if (webRoot == NULL) { - DBG_NAV_LOG("webRoot == NULL"); - return DO_NOTHING; - } - int uiWidth = mFrameCacheUI->width(); - int webWidth = webRoot->width(); - if (uiWidth != webWidth) { - DBG_NAV_LOGD("uiWidth=%d webWidth=%d", uiWidth, webWidth); - } else { - WebCore::IntRect cachedBounds = cachedFocusNode->bounds(); - const CachedFrame* webFrame = NULL; - const CachedNode* webFocusNode = webRoot->currentFocus(&webFrame); - if (webFocusNode != NULL && webRoot->containsFrame(cachedFrame)) { - if (useReplay && mReplay.count() == 0) { - DBG_NAV_LOG("mReplay.count() == 0"); - return DO_NOTHING; - } - if (webFocusNode->index() == cachedFocusNode->index() && - webFrame->indexInParent() == cachedFrame->indexInParent()) - { - DBG_NAV_LOG("index =="); - return DO_NOTHING; - } - WebCore::IntRect webBounds = webFocusNode->bounds(); - if (cachedBounds.contains(webBounds)) { - DBG_NAV_LOG("contains"); - return DO_NOTHING; - } - if (webBounds.contains(cachedBounds)) { - DBG_NAV_LOG("webBounds contains"); - return DO_NOTHING; - } - } - const CachedFrame* foundFrame = NULL; - int x, y; - const CachedNode* found = findAt(webRoot, cachedBounds, &foundFrame, &x, &y); -#if DEBUG_NAV_UI - DBG_NAV_LOGD("found=%p (%d) frame=%p (%d)", - found, found != NULL ? found->index() : -1, - foundFrame, foundFrame != NULL ? foundFrame->indexInParent() : -1); - if (found != NULL) { - WebCore::IntRect newBounds = found->bounds(); - DBG_NAV_LOGD("cachedBounds=(%d,%d,%d,%d) found=(%d,%d,%d,%d)", - cachedBounds.x(), cachedBounds.y(), cachedBounds.width(), cachedBounds.height(), - newBounds.x(), newBounds.y(), newBounds.width(), newBounds.height()); - } -#endif - webRoot->setCachedFocus(const_cast<CachedFrame*>(foundFrame), - const_cast<CachedNode*>(found)); - if (found != NULL) - webRoot->rootHistory()->setNavBounds(found->bounds()); - WebCore::Frame* framePointer = foundFrame != NULL ? (WebCore::Frame*) foundFrame->framePointer() : NULL; - WebCore::Node* nodePointer = found != NULL ? (WebCore::Node*) found->nodePointer() : NULL; - setFocusData(webRoot->generation(), framePointer, nodePointer, x, y, found == NULL); - sendFinalFocus(framePointer, nodePointer, x, y); - if (found && (found->isTextArea() || found->isTextField())) - return UPDATE_TEXT_ENTRY; - } -checkOldFocus: - return cachedFocusNode->isTextArea() || cachedFocusNode->isTextField() ? CLEAR_TEXT_ENTRY : DO_NOTHING; -} - -bool focusIsTextArea(FrameCachePermission allowNewer) -{ - CachedRoot* root = getFrameCache(allowNewer); - if (root == NULL) { - DBG_NAV_LOG("root==NULL"); - return false; - } - const CachedNode* focus = root->currentFocus(); - if (focus == NULL) - return false; - return focus->isTextArea() || focus->isTextField(); -} - -void focusRingBounds(WebCore::IntRect* bounds) -{ - DBG_NAV_LOGD("%s", ""); - CachedRoot* root = getFrameCache(DONT_ALLOW_NEWER); - if (root != NULL) { - const CachedNode* cachedNode = root->currentFocus(); - if (cachedNode != NULL) { - cachedNode->focusRingBounds(bounds); - DBG_NAV_LOGD("bounds={%d,%d,%d,%d}", bounds->x(), bounds->y(), - bounds->width(), bounds->height()); - return; - } - } - *bounds = WebCore::IntRect(0, 0, 0, 0); -} - -CachedRoot* getFrameCache(FrameCachePermission allowNewer) -{ - if (mViewImpl->mUpdatedFrameCache == false) - return mFrameCacheUI; - mViewImpl->gRecomputeFocusMutex.lock(); - bool recomputeInProgress = mViewImpl->mRecomputeEvents.size() > 0; - mViewImpl->gRecomputeFocusMutex.unlock(); - if (allowNewer != ALLOW_NEWEST && recomputeInProgress) - return mFrameCacheUI; - if (allowNewer == DONT_ALLOW_NEWER && mViewImpl->mLastGeneration < mGeneration) - return mFrameCacheUI; - DBG_NAV_LOGD("%s", "mViewImpl->mUpdatedFrameCache == true"); - mViewImpl->gFrameCacheMutex.lock(); - OutOfFocusFix fix = DO_NOTHING; - if (allowNewer != DONT_ALLOW_NEWER) - fix = fixOutOfDateFocus(mViewImpl->mUseReplay); - delete mFrameCacheUI; - delete mNavPictureUI; - mViewImpl->mUpdatedFrameCache = false; - mFrameCacheUI = mViewImpl->mFrameCacheKit; - mNavPictureUI = mViewImpl->mNavPictureKit; - mViewImpl->mFrameCacheKit = NULL; - mViewImpl->mNavPictureKit = NULL; - mViewImpl->gFrameCacheMutex.unlock(); - if (fix == UPDATE_TEXT_ENTRY) - updateTextEntry(); - else if (fix == CLEAR_TEXT_ENTRY) - clearTextEntry(); - return mFrameCacheUI; -} - -int getScaledMaxXScroll() -{ - LOG_ASSERT(mJavaGlue.mObj, "A java object was not associated with this native WebView!"); - JNIEnv* env = javavm_to_jnienv(mJavaGlue.mJVM); - int result = env->CallIntMethod(mJavaGlue.mObj, mJavaGlue.mGetScaledMaxXScroll); - checkException(env); - return result; -} - -int getScaledMaxYScroll() -{ - LOG_ASSERT(mJavaGlue.mObj, "A java object was not associated with this native WebView!"); - JNIEnv* env = javavm_to_jnienv(mJavaGlue.mJVM); - int result = env->CallIntMethod(mJavaGlue.mObj, mJavaGlue.mGetScaledMaxYScroll); - checkException(env); - return result; -} - -void getVisibleRect(WebCore::IntRect* rect) -{ - LOG_ASSERT(mJavaGlue.mObj, "A java object was not associated with this native WebView!"); - JNIEnv* env = javavm_to_jnienv(mJavaGlue.mJVM); - jobject jRect = env->CallObjectMethod(mJavaGlue.mObj, mJavaGlue.mGetVisibleRect); - checkException(env); - int left = (int) env->GetIntField(jRect, mJavaGlue.mRectLeft); - checkException(env); - rect->setX(left); - int top = (int) env->GetIntField(jRect, mJavaGlue.mRectTop); - checkException(env); - rect->setY(top); - int width = (int) env->CallIntMethod(jRect, mJavaGlue.mRectWidth); - checkException(env); - rect->setWidth(width); - int height = (int) env->CallIntMethod(jRect, mJavaGlue.mRectHeight); - checkException(env); - rect->setHeight(height); - env->DeleteLocalRef(jRect); - checkException(env); -} - -bool hasSrcUrl() -{ - const CachedRoot* root = getFrameCache(DONT_ALLOW_NEWER); - if (NULL == root) - return false; - const CachedNode* cachedNode = root->currentFocus(); - return NULL == cachedNode ? false : cachedNode->anchorHasSrcUrl(); -} - -static CachedFrame::Direction KeyToDirection(KeyCode keyCode) -{ - switch (keyCode) { - case kKeyCodeDpadRight: - DBG_NAV_LOGD("keyCode=%s", "right"); - return CachedFrame::RIGHT; - case kKeyCodeDpadLeft: - DBG_NAV_LOGD("keyCode=%s", "left"); - return CachedFrame::LEFT; - case kKeyCodeDpadDown: - DBG_NAV_LOGD("keyCode=%s", "down"); - return CachedFrame::DOWN; - case kKeyCodeDpadUp: - DBG_NAV_LOGD("keyCode=%s", "up"); - return CachedFrame::UP; - default: - LOGD("------- bad key sent to WebView::moveFocus"); - return CachedFrame::UNINITIALIZED; - } -} - -bool invalidFrame(WebCore::Frame* frame, const CachedRoot* root) -{ - if (frame == NULL) - return false; - int frameBuild = mViewImpl->retrieveFrameGeneration(frame); - int rootBuild = root->generation(); - return frameBuild > rootBuild; -} - -bool isImage(int x, int y) -{ - const CachedRoot* root = getFrameCache(DONT_ALLOW_NEWER); - return root ? root->isImage(x, y) : false; -} - -/* returns true if the key had no effect (neither scrolled nor changed focus) */ -bool moveFocus(int keyCode, int count, bool ignoreScroll, bool inval, - void* lastSentFocus, const WebCore::IntRect* lastSentBounds) -{ - CachedRoot* root = getFrameCache(ALLOW_NEWER); - if (root == NULL) { - DBG_NAV_LOG("root == NULL"); - setFocusData(0, NULL, NULL, 0, 0, true); - sendKitFocus(); // will build cache and retry - FirstMoveFocusParams params; - params.d.mTrigger = CommonParams::FIRST_MOVE_FOCUS_PARAMS; - params.d.mGeneration = mGeneration; - params.mKeyCode = keyCode; - params.mCount = count; - params.mIgnoreScroll = ignoreScroll; - mReplay.add(params.d, sizeof(params)); - return true; - } - - CachedFrame::Direction direction = KeyToDirection((KeyCode) keyCode); - const CachedFrame* cachedFrame, * oldFrame = NULL; - const CachedNode* focus = root->currentFocus(&oldFrame); - WebCore::IntPoint focusLocation = root->focusLocation(); - DBG_NAV_LOGD("old focus %d (nativeNode=%p) focusLocation={%d, %d}", - focus ? focus->index() : 0, - focus ? focus->nodePointer() : NULL, focusLocation.x(), focusLocation.y()); - WebCore::IntRect visibleRect; - getVisibleRect(&visibleRect); - DBG_NAV_LOGD("getVisibleRect %d,%d,%d,%d", - visibleRect.x(), visibleRect.y(), visibleRect.width(), visibleRect.height()); - root->setVisibleRect(visibleRect); - int xMax = getScaledMaxXScroll(); - int yMax = getScaledMaxYScroll(); - root->setMaxScroll(xMax, yMax); - CachedHistory savedHistory = *root->rootHistory(); -#if 0 && DUMP_NAV_CACHE - savedHistory.mDebug.print(root); -#endif - bool oldNodeIsTextArea = focusIsTextArea(DONT_ALLOW_NEWER); - const CachedNode* cachedNode = NULL; - int dx = 0; - int dy = 0; - int counter = count; - root->setScrollOnly(mFollowedLink); - while (--counter >= 0) { - WebCore::IntPoint scroll = WebCore::IntPoint(0, 0); - cachedNode = root->moveFocus(direction, &cachedFrame, &scroll); - dx += scroll.x(); - dy += scroll.y(); - } - DBG_NAV_LOGD("new focus %d (nativeNode=%p) focusLocation={%d, %d}", - cachedNode ? cachedNode->index() : 0, - cachedNode ? cachedNode->nodePointer() : NULL, root->focusLocation().x(), - root->focusLocation().y()); - // If !mHeightCanMeasure (such as in the browser), we want to scroll no - // matter what -#if 0 && DUMP_NAV_CACHE - root->rootHistory()->mDebug.print(root); -#endif - if (ignoreScroll == false && (mHeightCanMeasure == false || - NULL == cachedNode || - (focus && focus->nodePointer() == cachedNode->nodePointer()))) - { - if (count == 1 && dx != 0 && dy == 0 && -mLastDx == dx && - SkTime::GetMSecs() - mLastDxTime < 1000) - root->checkForJiggle(&dx); - DBG_NAV_LOGD("scrollBy %d,%d", dx, dy); - if ((dx | dy) != 0) - this->scrollBy(dx, dy); - mLastDx = dx; - mLastDxTime = SkTime::GetMSecs(); - ignoreScroll = true; // if move re-executes, don't scroll the second time - } - bool result = false; - if (cachedNode != NULL) { - WebCore::IntPoint pos; - root->setCachedFocus((CachedFrame*) cachedFrame, (CachedNode*) cachedNode); - root->getSimulatedMousePosition(&pos); - if (lastSentFocus == cachedNode->nodePointer() && lastSentBounds && - *lastSentBounds == cachedNode->bounds()) - { - sendFinalFocus((WebCore::Frame*) cachedFrame->framePointer(), - (WebCore::Node*) cachedNode->nodePointer(), pos.x(), pos.y()); - } else { - setFocusData(root->generation(), - (WebCore::Frame*) cachedFrame->framePointer(), - (WebCore::Node*) cachedNode->nodePointer(), pos.x(), pos.y(), - true); - sendKitFocus(); - if (inval) - viewInvalidate(); - MoveFocusParams params; - params.d.d.mTrigger = CommonParams::MOVE_FOCUS_PARAMS; - params.d.d.mGeneration = mGeneration; - params.c.setFocus(focus, oldFrame, root, focusLocation); - params.mSentFocus = cachedNode->nodePointer(); - params.mSentBounds = cachedNode->bounds(); - params.mVisibleRect = visibleRect; - params.mHistory = savedHistory; - DBG_NAV_LOGD("history.mDidFirstLayout=%s", - params.mHistory.didFirstLayout() ? "true" : "false"); - params.mXMax = xMax; - params.mYMax = yMax; - params.d.mKeyCode = keyCode; - params.d.mCount = count; - params.d.mIgnoreScroll = ignoreScroll; - mReplay.add(params.d.d, sizeof(params)); - } - } else { - if (visibleRect.intersects(root->rootHistory()->focusBounds()) == false) { - setFocusData(root->generation(), NULL, NULL, 0, 0, true); - sendKitFocus(); // will build cache and retry - } - FirstMoveFocusParams params; - params.d.mTrigger = CommonParams::FIRST_MOVE_FOCUS_PARAMS; - params.d.mGeneration = mGeneration; - params.mKeyCode = keyCode; - params.mCount = count; - params.mIgnoreScroll = ignoreScroll; - mReplay.add(params.d, sizeof(params)); - int docHeight = root->documentHeight(); - int docWidth = root->documentWidth(); - if (visibleRect.bottom() + dy > docHeight) - dy = docHeight - visibleRect.bottom(); - else if (visibleRect.y() + dy < 0) - dy = -visibleRect.y(); - if (visibleRect.right() + dx > docWidth) - dx = docWidth - visibleRect.right(); - else if (visibleRect.x() < 0) - dx = -visibleRect.x(); - result = direction == CachedFrame::LEFT ? dx >= 0 : - direction == CachedFrame::RIGHT ? dx <= 0 : - direction == CachedFrame::UP ? dy >= 0 : dy <= 0; - } - if (focusIsTextArea(DONT_ALLOW_NEWER)) - updateTextEntry(); - else if (oldNodeIsTextArea) - clearTextEntry(); - return result; -} - -void notifyFocusSet(FrameCachePermission inEditingMode) -{ - if (focusIsTextArea(inEditingMode)) - updateTextEntry(); - else if (inEditingMode) - clearTextEntry(); -#if DEBUG_NAV_UI - if (mFrameCacheUI != NULL) { - const CachedNode* focus = mFrameCacheUI->currentFocus(); - DBG_NAV_LOGD("focus %d (nativeNode=%p)", - focus ? focus->index() : 0, - focus ? focus->nodePointer() : NULL); - } -#endif -} - -void notifyProgressFinished() -{ - DBG_NAV_LOGD("focusIsTextArea=%d", focusIsTextArea(DONT_ALLOW_NEWER)); - updateTextEntry(); -#if DEBUG_NAV_UI - if (mFrameCacheUI != NULL) { - const CachedNode* focus = mFrameCacheUI->currentFocus(); - DBG_NAV_LOGD("focus %d (nativeNode=%p)", - focus ? focus->index() : 0, - focus ? focus->nodePointer() : NULL); - } -#endif -} - -void recomputeFocus() -{ - int generation; - do { - mViewImpl->gRecomputeFocusMutex.lock(); - if (mViewImpl->mRecomputeEvents.size() == 0) { - mViewImpl->gRecomputeFocusMutex.unlock(); - return; - } - generation = mViewImpl->mRecomputeEvents.first(); - mViewImpl->mRecomputeEvents.remove(0); - mViewImpl->gRecomputeFocusMutex.unlock(); - DBG_NAV_LOGD("generation=%d", generation); - CachedRoot* root = getFrameCache(ALLOW_NEWEST); - if (root == NULL) { - DBG_NAV_LOG("root==NULL"); - return; - } - LargestParams storage; - const CommonParams& params = storage.d.d; - char* pos = mReplay.position(); - while (mReplay.retrieve(&storage.d.d) < generation) - DBG_NAV_LOGD("dropped ", params.mGeneration); - if (params.mGeneration > generation) { - DBG_NAV_LOGD("params.mGeneration=%d > generation=%d", - params.mGeneration, generation); - mReplay.rewind(pos); - return; - } - int lastAdd = mReplay.lastAdd(); - do { - LOG_ASSERT(params.mTrigger != CommonParams::NO_DATA, "expected data"); - bool inval = generation == mGeneration; - switch (params.mTrigger) { - case CommonParams::CLEAR_FOCUS_PARAMS: { - const ClearFocusParams& sParams = *(ClearFocusParams*) &storage; - const CacheParams& cParams = sParams.c; - if (invalidFrame(cParams.mFrame, root)) { - DBG_NAV_LOGD("dropped %s generation=%d", - TriggerNames[params.mTrigger], generation); - return; - } - root->setFocus(cParams.mFrame, cParams.mNode, cParams.mX, cParams.mY); - clearFocus(sParams.mX, sParams.mY, inval); - DBG_NAV_LOGD("clearFocus(x,y)={%d,%d}", sParams.mX, sParams.mY); - } break; - case CommonParams::MOTION_UP_PARAMS: { - const MotionUpParams& mParams = *(MotionUpParams*) &storage; - // const CacheParams& cParams = mParams.c; - // if (invalidFrame(cParams.mFrame, root) == false) - // root->setFocus(cParams.mFrame, cParams.mNode, - // cParams.mX, cParams.mY); - motionUp(mParams.mX, mParams.mY, mParams.mSlop, mParams.mIsClick, inval, true); - DBG_NAV_LOGD("motionUp mX=%d mY=%d", mParams.mX, mParams.mY); - } break; - case CommonParams::FIRST_MOVE_FOCUS_PARAMS: { - if (invalidFrame((WebCore::Frame*) root->framePointer(), root)) { - DBG_NAV_LOGD("dropped %s generation=%d", - TriggerNames[params.mTrigger], generation); - return; - } - const FirstMoveFocusParams& fParams = *(FirstMoveFocusParams*) &storage; - DBG_NAV_LOGD("first moveFocus keyCode=%d count=%d" - " ignoreScroll=%s", fParams.mKeyCode, fParams.mCount, - fParams.mIgnoreScroll ? "true" : "false"); - moveFocus(fParams.mKeyCode, fParams.mCount, - fParams.mIgnoreScroll, inval, NULL, NULL); - } break; - case CommonParams::MOVE_FOCUS_PARAMS: { - const MoveFocusParams& mParams = *(MoveFocusParams*) &storage; - const CacheParams& cParams = mParams.c; - if (invalidFrame(cParams.mFrame, root)) { - DBG_NAV_LOGD("dropped %s generation=%d", - TriggerNames[params.mTrigger], generation); - return; - } - DBG_NAV_LOGD("moveFocus keyCode=%d count=%d ignoreScroll=%s " - "history.mDidFirstLayout=%s", mParams.d.mKeyCode, - mParams.d.mCount, mParams.d.mIgnoreScroll ? "true" : "false", - mParams.mHistory.didFirstLayout() ? "true" : "false"); - if (root->setFocus(cParams.mFrame, cParams.mNode, - cParams.mX, cParams.mY) == false) { - DBG_NAV_LOGD("can't restore focus frame=%p node=%p", - "x=%d y=%d %s", cParams.mFrame, cParams.mNode, - cParams.mX, cParams.mY, TriggerNames[params.mTrigger]); - return; - } - root->setVisibleRect(mParams.mVisibleRect); - root->setMaxScroll(mParams.mXMax, mParams.mYMax); - *root->rootHistory() = mParams.mHistory; - moveFocus(mParams.d.mKeyCode, mParams.d.mCount, - mParams.d.mIgnoreScroll, inval, - mParams.mSentFocus, &mParams.mSentBounds); - } break; - default: - LOG_ASSERT(0, "unknown trigger"); - } - if (params.mGeneration >= lastAdd) - break; - root = getFrameCache(DONT_ALLOW_NEWER); // re-execution may have retrieved newer cache - mReplay.retrieve(&storage.d.d); - DBG_NAV_LOGD("continuation mGeneration %d", params.mGeneration); - } while (true); - } while (true); -} - -void resetFocus() -{ - DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); - CachedRoot* root = getFrameCache(ALLOW_NEWER); - if (root == NULL) - return; - root->setCachedFocus(NULL, NULL); -} - -const CachedNode* findAt(CachedRoot* root, const WebCore::IntRect& rect, - const CachedFrame** framePtr, int* rxPtr, int* ryPtr) -{ - *rxPtr = 0; - *ryPtr = 0; - *framePtr = NULL; - if (root == NULL) - return NULL; - WebCore::IntRect visibleRect; - getVisibleRect(&visibleRect); - root->setVisibleRect(visibleRect); - return root->findAt(rect, framePtr, rxPtr, ryPtr); -} - -void selectBestAt(const WebCore::IntRect& rect) -{ - const CachedFrame* frame; - int rx, ry; - CachedRoot* root = getFrameCache(DONT_ALLOW_NEWER); - const CachedNode* node = findAt(root, rect, &frame, &rx, &ry); - int rootGeneration = root != NULL ? root->generation() : 0; - setFocusData(rootGeneration, - frame ? (WebCore::Frame*) frame->framePointer() : NULL, - node ? (WebCore::Node*) node->nodePointer() : NULL, rx, ry, false); - if (node == NULL) { - DBG_NAV_LOGD("no nodes found root=%p", root); - if (root != NULL) { - root->clearFocus(); - root->setCachedFocus(NULL, NULL); - } - sendKitFocus(); - viewInvalidate(); - clearTextEntry(); - return; - } - DBG_NAV_LOGD("CachedNode:%p (%d)", node, node->index()); - const CachedFrame* oldFrame = NULL; - const CachedNode* oldFocusNode = root->currentFocus(&oldFrame); - bool oldNodeIsTextArea = focusIsTextArea(DONT_ALLOW_NEWER); - root->setCachedFocus(const_cast<CachedFrame*>(frame), - const_cast<CachedNode*>(node)); - viewInvalidate(); - if (focusIsTextArea(DONT_ALLOW_NEWER)) - updateTextEntry(); - else if (oldNodeIsTextArea) - clearTextEntry(); -} - -WebCore::IntRect getNavBounds() -{ - CachedRoot* root = getFrameCache(DONT_ALLOW_NEWER); - if (NULL == root) - return WebCore::IntRect(0, 0, 0, 0); - return root->rootHistory()->navBounds(); -} - -void setNavBounds(const WebCore::IntRect& rect) -{ - CachedRoot* root = getFrameCache(DONT_ALLOW_NEWER); - if (NULL == root) - return; - root->rootHistory()->setNavBounds(rect); -} - -void markNodeInvalid(WebCore::Node* node) -{ - DBG_NAV_LOGD("node=%p", node); - mInvalidNode = node; - viewInvalidate(); -} - -void motionUp(int x, int y, int slop, bool isClick, bool inval, bool retry) -{ - mFollowedLink = false; - const CachedFrame* frame; - WebCore::IntRect rect = WebCore::IntRect(x - slop, y - slop, slop * 2, slop * 2); - int rx, ry; - CachedRoot* root = getFrameCache(ALLOW_NEWER); - const CachedNode* result = findAt(root, rect, &frame, &rx, &ry); - if (result == NULL) { - DBG_NAV_LOGD("no nodes found root=%p", root); - int rootGeneration = 0; - if (root != NULL) { - root->clearFocus(); - rootGeneration = root->generation(); - if (retry == false) { // scroll first time only - int dx = root->checkForCenter(x, y); - if (dx != 0) { - scrollBy(dx, 0); - retry = true; // don't recompute later since we scrolled - } - } - } - sendMotionUp(rootGeneration, frame ? - (WebCore::Frame*) frame->framePointer() : NULL, - NULL, x, y, slop, isClick, retry); - if (inval) - viewInvalidate(); - if (retry == false) { - MotionUpParams params; - params.d.mTrigger = CommonParams::MOTION_UP_PARAMS; - params.d.mGeneration = mGeneration; - params.mX = x; - params.mY = y; - params.mSlop = slop; - params.mIsClick = isClick; - mReplay.add(params.d, sizeof(params)); - } - clearTextEntry(); - return; - } - DBG_NAV_LOGD("CachedNode:%p (%d) x=%d y=%d rx=%d ry=%d", result, - result->index(), x, y, rx, ry); - // const CachedFrame* oldFrame = NULL; - // const CachedNode* oldFocusNode = root->currentFocus(&oldFrame); - // WebCore::IntPoint focusLocation = root->focusLocation(); - bool oldNodeIsTextArea = retry == false && focusIsTextArea(DONT_ALLOW_NEWER); - root->setCachedFocus(const_cast<CachedFrame*>(frame), - const_cast<CachedNode*>(result)); - bool newNodeIsTextArea = focusIsTextArea(DONT_ALLOW_NEWER); - const WebCore::String& exported = result->getExport(); - if (exported.length() == 0 || newNodeIsTextArea) { - sendMotionUp(root->generation(), - frame ? (WebCore::Frame*) frame->framePointer() : NULL, - result ? (WebCore::Node*) result->nodePointer() : NULL, rx, ry, - slop, isClick, retry); - if (inval) - viewInvalidate(); - if (retry == false) { - MotionUpParams params; - params.d.mTrigger = CommonParams::MOTION_UP_PARAMS; - params.d.mGeneration = mGeneration; - params.mX = x; - params.mY = y; - params.mSlop = slop; - params.mIsClick = isClick; - // params.c.setFocus(oldFocusNode, oldFrame, root, focusLocation); - mReplay.add(params.d, sizeof(params)); - } - } else if (inval) - viewInvalidate(); - if (newNodeIsTextArea) - updateTextEntry(); - else { - if (isClick) - setFollowedLink(true); - if (oldNodeIsTextArea) - clearTextEntry(); - } -} - -void setFollowedLink(bool followed) -{ - if ((mFollowedLink = followed) != false) { - mRingAnimationEnd = SkTime::GetMSecs() + 500; - viewInvalidate(); - } -} - -void setHeightCanMeasure(bool measure) -{ - mHeightCanMeasure = measure; -} - -SkIRect mSelStart, mSelEnd; -SkRegion mSelRegion; -#define MIN_ARROW_DISTANCE (20 * 20) - -void moveSelection(int x, int y, bool extendSelection) { - CachedRoot* root = getFrameCache(DONT_ALLOW_NEWER); - if (NULL == root) - return; - const SkPicture& picture = *mNavPictureUI; - WebCore::IntRect r; - getVisibleRect(&r); - SkIRect area; - area.set(r.x(), r.y(), r.right(), r.bottom()); - if (extendSelection == false) - mSelStart = mSelEnd = CopyPaste::findClosest(picture, area, x, y); - else - mSelEnd = CopyPaste::findClosest(picture, area, x, y); - DBG_NAV_LOGD("x=%d y=%d extendSelection=%s mSelStart=(%d, %d, %d, %d)" - " mSelEnd=(%d, %d, %d, %d)", x, y, extendSelection ? "true" : "false", - mSelStart.fLeft, mSelStart.fTop, mSelStart.fRight, mSelStart.fBottom, - mSelEnd.fLeft, mSelEnd.fTop, mSelEnd.fRight, mSelEnd.fBottom); -} - -const SkRegion& getSelection() { - return mSelRegion; -} - -void drawSelection(SkCanvas* canvas, int x, int y, bool extendSelection) { - if (extendSelection == false) { - int dx = x - mSelStart.fLeft; - dx *= dx; - int otherX = x - mSelStart.fRight; - if (dx > (otherX *= otherX)) - dx = otherX; - int dy = y - mSelStart.fTop; - int dist = dx * dx + dy * dy; - if (dist > MIN_ARROW_DISTANCE) - drawSelectionArrow(canvas, x, y); - else - drawSelectionPointer(canvas, x, y, true); - } else { - drawSelectionRegion(canvas); - drawSelectionPointer(canvas, x, y, false); - } -} - -void drawSelectionRegion(SkCanvas* canvas) { - CachedRoot* root = getFrameCache(DONT_ALLOW_NEWER); - if (NULL == root) - return; - WebCore::IntRect r; - getVisibleRect(&r); - SkIRect area; - area.set(r.x(), r.y(), r.right(), r.bottom()); - mSelRegion.setEmpty(); - CopyPaste::buildSelection(*mNavPictureUI, area, mSelStart, mSelEnd, &mSelRegion); - SkPath path; - mSelRegion.getBoundaryPath(&path); - SkPaint paint; - paint.setAntiAlias(true); - paint.setColor(SkColorSetARGB(0x40, 255, 51, 204)); - canvas->drawPath(path, paint); -} - -void drawSelectionPointer(SkCanvas* canvas, int x, int y, bool gridded) { - SkPath path; - getSelectionCaret(&path); - SkPaint paint; - paint.setAntiAlias(true); - paint.setStyle(SkPaint::kStroke_Style); - paint.setColor(SK_ColorBLACK); - SkPixelXorXfermode xorMode(SK_ColorWHITE); - paint.setXfermode(&xorMode); - int sc = canvas->save(); - if (gridded) { - bool useLeft = x <= (mSelStart.fLeft + mSelStart.fRight) >> 1; - canvas->translate(SkIntToScalar(useLeft ? mSelStart.fLeft : - mSelStart.fRight), SkIntToScalar(mSelStart.fTop)); - } else - canvas->translate(SkIntToScalar(x), SkIntToScalar(y)); - canvas->drawPath(path, paint); - canvas->restoreToCount(sc); -} - -void drawSelectionArrow(SkCanvas* canvas, int x, int y) { - SkPath path; - getSelectionArrow(&path); - SkPaint paint; - paint.setAntiAlias(true); - paint.setStyle(SkPaint::kStroke_Style); - paint.setColor(SK_ColorBLACK); - paint.setStrokeWidth(SK_Scalar1 * 2); - int sc = canvas->save(); - canvas->translate(SkIntToScalar(x), SkIntToScalar(y)); - canvas->drawPath(path, paint); - paint.setStyle(SkPaint::kFill_Style); - paint.setColor(SK_ColorWHITE); - canvas->drawPath(path, paint); - canvas->restoreToCount(sc); -} - -void getSelectionArrow(SkPath* path) { - const int arrow[] = { - 0, 14, 3, 11, 5, 15, 9, 15, 7, 11, 11, 11 - }; - for (unsigned index = 0; index < sizeof(arrow)/sizeof(arrow[0]); index += 2) - path->lineTo(SkIntToScalar(arrow[index]), SkIntToScalar(arrow[index + 1])); - path->close(); -} - -void getSelectionCaret(SkPath* path) { - SkScalar height = SkIntToScalar(mSelStart.fBottom - mSelStart.fTop); - SkScalar dist = height / 4; - path->lineTo(0, height); - SkScalar bottom = height + dist; - path->lineTo(-dist, bottom); - SkScalar edge = bottom - SK_Scalar1/2; - path->moveTo(-dist, edge); - path->lineTo(dist, edge); - path->moveTo(dist, bottom); - path->lineTo(0, height); -} - -void sendFinalFocus(WebCore::Frame* framePtr, WebCore::Node* nodePtr, int x, int y) -{ - DBG_NAV_LOGD("framePtr=%p nodePtr=%p x=%d y=%d", framePtr, nodePtr, x, y); - LOG_ASSERT(mJavaGlue.mObj, "A java object was not associated with this native WebView!"); - JNIEnv* env = javavm_to_jnienv(mJavaGlue.mJVM); - env->CallVoidMethod(mJavaGlue.mObj, mJavaGlue.mSendFinalFocus, - (jint) framePtr, (jint) nodePtr, x, y); - checkException(env); -} - -void sendKitFocus() -{ - LOG_ASSERT(mJavaGlue.mObj, "A java object was not associated with this native WebView!"); - JNIEnv* env = javavm_to_jnienv(mJavaGlue.mJVM); - env->CallVoidMethod(mJavaGlue.mObj, mJavaGlue.mSendKitFocus); - checkException(env); -} - -void sendMotionUp(int buildGeneration, - WebCore::Frame* framePtr, WebCore::Node* nodePtr, int x, int y, int slop, - bool isClick, bool retry) -{ - mViewImpl->mTouchGeneration = mViewImpl->mGeneration = ++mGeneration; - DBG_NAV_LOGD("buildGeneration=%d mGeneration=%d framePtr=%p nodePtr=%p" - " x=%d y=%d slop=%d", buildGeneration, - mGeneration, framePtr, nodePtr, x, y, slop); - LOG_ASSERT(mJavaGlue.mObj, "A WebView was not associated with this WebViewNative!"); - JNIEnv* env = javavm_to_jnienv(mJavaGlue.mJVM); - env->CallVoidMethod(mJavaGlue.mObj, mJavaGlue.mSendMotionUp, mGeneration, - buildGeneration, (jint) framePtr, (jint) nodePtr, x, y, slop, isClick, retry); - checkException(env); -} - -void setFocusData(int buildGeneration, WebCore::Frame* framePtr, - WebCore::Node* nodePtr, int x, int y, bool ignoreNullFocus) -{ - mViewImpl->mMoveGeneration = mViewImpl->mGeneration = ++mGeneration; - DBG_NAV_LOGD("moveGeneration=%d buildGeneration=%d framePtr=%p nodePtr=%p" - " x=%d y=%d", mGeneration, buildGeneration, framePtr, nodePtr, x, y); - LOG_ASSERT(mJavaGlue.mObj, "A java object was not associated with this native WebView!"); - JNIEnv* env = javavm_to_jnienv(mJavaGlue.mJVM); - env->CallVoidMethod(mJavaGlue.mObj, mJavaGlue.mSetFocusData, mGeneration, - buildGeneration, (jint) framePtr, (jint) nodePtr, x, y, ignoreNullFocus); - checkException(env); -} - -void scrollBy(int dx, int dy) -{ - LOG_ASSERT(mJavaGlue.mObj, "A java object was not associated with this native WebView!"); - - JNIEnv* env = javavm_to_jnienv(mJavaGlue.mJVM); - env->CallVoidMethod(mJavaGlue.mObj, mJavaGlue.mScrollBy, dx, dy); - checkException(env); -} - -bool updateFocusNode(JNIEnv* env) -{ - CachedRoot* root = getFrameCache(DONT_ALLOW_NEWER); - if (root == NULL) { - DBG_NAV_LOG("root==NULL"); - return false; - } - const CachedFrame* cachedFrame = NULL; - const CachedNode* cachedFocusNode = root->currentFocus(&cachedFrame); - if (cachedFocusNode == NULL) { - DBG_NAV_LOG("cachedFocusNode==NULL"); - return false; - } - DBG_NAV_LOGD("cachedFocusNode=%d (nodePointer=%p)", - cachedFocusNode->index(), - cachedFocusNode->nodePointer()); - jobject focusnode = env->GetObjectField(mJavaGlue.mObj, mJavaGlue.mFocusNode); - LOG_ASSERT(focusnode, "Could not find WebView's FocusNode"); - - bool isTextArea = cachedFocusNode->isTextArea(); - bool isTextField = cachedFocusNode->isTextField(); - int maxLength; - jstring jName; - if (isTextField) { - maxLength = cachedFocusNode->maxLength(); - const WebCore::String& name = cachedFocusNode->name(); - jName = env->NewString((jchar*)name.characters(), name.length()); - } else { - maxLength = -1; - jName = NULL; - } - WebCore::IntRect bounds = cachedFocusNode->bounds(); - WebCore::String value = cachedFocusNode->getExport(); - jstring val = !value.isEmpty() ? env->NewString((jchar *)value.characters(), value.length()) : NULL; - env->CallVoidMethod(focusnode, mJavaGlue.mSetAll, isTextField, isTextArea, cachedFocusNode->isPassword(), - cachedFocusNode->isAnchor(), cachedFocusNode->isRtlText(), maxLength, cachedFocusNode->textSize(), - bounds.x(), bounds.y(), bounds.right(), bounds.bottom(), (int)(cachedFocusNode->nodePointer()), - (int)(cachedFrame->framePointer()), val, jName, root->textGeneration()); - env->DeleteLocalRef(val); - env->DeleteLocalRef(focusnode); - if (isTextField) - env->DeleteLocalRef(jName); - return true; -} - -void updateTextEntry() -{ - JNIEnv* env = javavm_to_jnienv(mJavaGlue.mJVM); - env->CallVoidMethod(mJavaGlue.mObj, mJavaGlue.mUpdateTextEntry); - checkException(env); -} - -void viewInvalidate() -{ - JNIEnv* env = javavm_to_jnienv(mJavaGlue.mJVM); - env->CallVoidMethod(mJavaGlue.mObj, mJavaGlue.mViewInvalidate); - checkException(env); -} - -void postInvalidateDelayed(int64_t delay, const WebCore::IntRect& bounds) -{ - JNIEnv* env = javavm_to_jnienv(mJavaGlue.mJVM); - env->CallVoidMethod(mJavaGlue.mObj, mJavaGlue.mPostInvalidateDelayed, - delay, bounds.x(), bounds.y(), bounds.right(), bounds.bottom()); - checkException(env); -} - -private: // local state for WebView - // private to getFrameCache(); other functions operate in a different thread - CachedRoot* mFrameCacheUI; // navigation data ready for use - FocusReplay mReplay; - WebViewCore* mViewImpl; - SkTDArray<Container*>* mUIButtons; - WebCore::Node* mInvalidNode; - int mGeneration; // associate unique ID with sent kit focus to match with ui - SkPicture* mNavPictureUI; - bool mFollowedLink; - SkMSec mRingAnimationEnd; - // Corresponds to the same-named boolean on the java side. - bool mHeightCanMeasure; - int mLastDx; - SkMSec mLastDxTime; -}; // end of WebView class - -/* - * Native JNI methods - */ -static jstring WebCoreStringToJString(JNIEnv *env, WebCore::String string) -{ - int length = string.length(); - if (0 == length) - return 0; - jstring ret = env->NewString((jchar *)string.characters(), length); - env->DeleteLocalRef(ret); - return ret; -} - -#ifdef BUCKET_EXPERIMENT -static void nativeClearContentPicture(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->clearContentPicture(); -} -#endif - -static void nativeClearFocus(JNIEnv *env, jobject obj, int x, int y) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->clearFocus(x, y, true); -} - -static void nativeCreate(JNIEnv *env, jobject obj, int viewImpl) -{ - WebView* webview = new WebView(env, obj, viewImpl); - // NEED THIS OR SOMETHING LIKE IT! - //Release(obj); -} - -static void nativeDebugDump(JNIEnv *env, jobject obj) -{ -#if DUMP_NAV_CACHE - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->debugDump(); -#endif -} - -#ifdef BUCKET_EXPERIMENT -static void nativeDrawContentPicture(JNIEnv *env, jobject obj, - jobject canv) -{ - SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, canv); - if (canv == NULL) { - DBG_NAV_LOG("canv==NULL"); - return; - } - WebView* view = GET_NATIVE_VIEW(env, obj); - if (view == NULL) { - DBG_NAV_LOG("view==NULL"); - return; - } - view->drawContentPicture(canvas); -} -#endif - -static void nativeDrawFocusRing(JNIEnv *env, jobject obj, - jobject canv) -{ - SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, canv); - if (canv == NULL) { - DBG_NAV_LOG("canv==NULL"); - return; - } - WebView* view = GET_NATIVE_VIEW(env, obj); - if (view == NULL) { - DBG_NAV_LOG("view==NULL"); - return; - } - view->drawFocusRing(canvas); -} - -static void nativeDrawSelection(JNIEnv *env, jobject obj, - jobject canv, jint x, jint y, bool ex) -{ - SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, canv); - if (canv == NULL) { - DBG_NAV_LOG("canv==NULL"); - return; - } - WebView* view = GET_NATIVE_VIEW(env, obj); - if (view == NULL) { - DBG_NAV_LOG("view==NULL"); - return; - } - view->drawSelection(canvas, x, y, ex); -} - -static bool nativeHasSrcUrl(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - return view->hasSrcUrl(); -} - -static bool nativeIsImage(JNIEnv *env, jobject obj, jint x, jint y) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - return view->isImage(x,y); -} - -static WebCore::IntRect jrect_to_webrect(JNIEnv* env, jobject obj) -{ - int L, T, R, B; - GraphicsJNI::get_jrect(env, obj, &L, &T, &R, &B); - return WebCore::IntRect(L, T, R - L, B - T); -} - -static void nativeSelectBestAt(JNIEnv *env, jobject obj, jobject jrect) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - WebCore::IntRect rect = jrect_to_webrect(env, jrect); - view->selectBestAt(rect); -} - -static void nativeMarkNodeInvalid(JNIEnv *env, jobject obj, int node) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->markNodeInvalid((WebCore::Node*) node); -} - -static void nativeMotionUp(JNIEnv *env, jobject obj, - int x, int y, int slop, bool isClick) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->motionUp(x, y, slop, isClick, true, false); -} - -static bool nativeUpdateFocusNode(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - return view->updateFocusNode(env); -} - -static bool nativeMoveFocus(JNIEnv *env, jobject obj, - int key, int count, bool ignoreScroll) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - DBG_NAV_LOGD("env=%p obj=%p view=%p", env, obj, view); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - return view->moveFocus(key, count, ignoreScroll, true, NULL, NULL); -} - -static void nativeNotifyFocusSet(JNIEnv *env, jobject obj, bool inEditingMode) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->notifyFocusSet((WebView::FrameCachePermission) inEditingMode); -} - -static void nativeRecomputeFocus(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->recomputeFocus(); -} - -static void nativeRecordButtons(JNIEnv* env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->nativeRecordButtons(); -} - -static void nativeResetFocus(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->resetFocus(); -} - -static void nativeSetFollowedLink(JNIEnv *env, jobject obj, bool followed) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->setFollowedLink(followed); -} - -static void nativeSetHeightCanMeasure(JNIEnv *env, jobject obj, bool measure) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in nativeSetHeightCanMeasure"); - view->setHeightCanMeasure(measure); -} - -static jobject nativeGetFocusRingBounds(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - jclass rectClass = env->FindClass("android/graphics/Rect"); - LOG_ASSERT(rectClass, "Could not find Rect class!"); - jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); - LOG_ASSERT(init, "Could not find constructor for Rect"); - WebCore::IntRect webRect; - view->focusRingBounds(&webRect); - jobject rect = env->NewObject(rectClass, init, webRect.x(), - webRect.y(), webRect.right(), webRect.bottom()); - return rect; -} - -static jobject nativeGetNavBounds(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - jclass rectClass = env->FindClass("android/graphics/Rect"); - LOG_ASSERT(rectClass, "Could not find Rect class!"); - jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); - LOG_ASSERT(init, "Could not find constructor for Rect"); - WebCore::IntRect webRect = view->getNavBounds(); - jobject rect = env->NewObject(rectClass, init, webRect.x(), - webRect.y(), webRect.right(), webRect.bottom()); - return rect; -} - -static void nativeSetNavBounds(JNIEnv *env, jobject obj, jobject jrect) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - WebCore::IntRect rect = jrect_to_webrect(env, jrect); - view->setNavBounds(rect); -} - -static void nativeUpdateCachedTextfield(JNIEnv *env, jobject obj, jstring updatedText, jint generation) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in nativeUpdateCachedTextfield"); - CachedRoot* root = view->getFrameCache(WebView::DONT_ALLOW_NEWER); - if (!root) - return; - const CachedNode* cachedFocusNode = root->currentFocus(); - if (!cachedFocusNode || (!cachedFocusNode->isTextField() && !cachedFocusNode->isTextArea())) - return; - WebCore::String webcoreString; - const jchar* outputChars = NULL == updatedText ? NULL : env->GetStringChars(updatedText, NULL); - if (outputChars != NULL) { - webcoreString = WebCore::String((const UChar*) outputChars, env->GetStringLength(updatedText)); - } - (const_cast<CachedNode*>(cachedFocusNode))->setExport(webcoreString); - root->setTextGeneration(generation); - if (outputChars) - env->ReleaseStringChars(updatedText, outputChars); - checkException(env); -} - -static void nativeDestroy(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOGD("nativeDestroy view: %p", view); - LOG_ASSERT(view, "view not set in nativeDestroy"); - delete view; -} - -static void nativeMoveSelection(JNIEnv *env, jobject obj, int x, int y, bool ex) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->moveSelection(x, y, ex); -} - -static jobject nativeGetSelection(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - return GraphicsJNI::createRegion(env, new SkRegion(view->getSelection())); -} - -/* - * JNI registration - */ -static JNINativeMethod gJavaWebViewMethods[] = { -#ifdef BUCKET_EXPERIMENT - { "nativeClearContentPicture", "()V", - (void*) nativeClearContentPicture }, -#endif - { "nativeClearFocus", "(II)V", - (void*) nativeClearFocus }, - { "nativeCreate", "(I)V", - (void*) nativeCreate }, - { "nativeDebugDump", "()V", - (void*) nativeDebugDump }, - { "nativeDestroy", "()V", - (void*) nativeDestroy }, -#ifdef BUCKET_EXPERIMENT - { "nativeDrawContentPicture", "(Landroid/graphics/Canvas;)V", - (void*) nativeDrawContentPicture }, -#endif - { "nativeDrawFocusRing", "(Landroid/graphics/Canvas;)V", - (void*) nativeDrawFocusRing }, - { "nativeDrawSelection", "(Landroid/graphics/Canvas;IIZ)V", - (void*) nativeDrawSelection }, - { "nativeUpdateFocusNode", "()Z", - (void*) nativeUpdateFocusNode }, - { "nativeGetFocusRingBounds", "()Landroid/graphics/Rect;", - (void*) nativeGetFocusRingBounds }, - { "nativeGetNavBounds", "()Landroid/graphics/Rect;", - (void*) nativeGetNavBounds }, - { "nativeHasSrcUrl", "()Z", - (void*) nativeHasSrcUrl }, - { "nativeMarkNodeInvalid", "(I)V", - (void*) nativeMarkNodeInvalid }, - { "nativeMotionUp", "(IIIZ)V", - (void*) nativeMotionUp }, - { "nativeMoveFocus", "(IIZ)Z", - (void*) nativeMoveFocus }, - { "nativeNotifyFocusSet", "(Z)V", - (void*) nativeNotifyFocusSet }, - { "nativeRecomputeFocus", "()V", - (void*) nativeRecomputeFocus }, - { "nativeRecordButtons", "()V", - (void*) nativeRecordButtons }, - { "nativeResetFocus", "()V", - (void*) nativeResetFocus }, - { "nativeSelectBestAt", "(Landroid/graphics/Rect;)V", - (void*) nativeSelectBestAt }, - { "nativeSetFollowedLink", "(Z)V", - (void*) nativeSetFollowedLink }, - { "nativeSetHeightCanMeasure", "(Z)V", - (void*) nativeSetHeightCanMeasure }, - { "nativeSetNavBounds", "(Landroid/graphics/Rect;)V", - (void*) nativeSetNavBounds }, - { "nativeIsImage", "(II)Z", - (void*) nativeIsImage }, - { "nativeUpdateCachedTextfield", "(Ljava/lang/String;I)V", - (void*) nativeUpdateCachedTextfield }, - { "nativeMoveSelection", "(IIZ)V", - (void*) nativeMoveSelection }, - { "nativeGetSelection", "()Landroid/graphics/Region;", - (void*) nativeGetSelection } -}; - -int register_webview(JNIEnv* env) -{ - jclass clazz = env->FindClass("android/webkit/WebView"); - LOG_ASSERT(clazz != NULL, "Unable to find class android/webkit/WebView"); - gWebViewField = env->GetFieldID(clazz, "mNativeClass", "I"); - LOG_ASSERT(gWebViewField != NULL, "Unable to find android/webkit/WebView.mNativeClass"); - - return jniRegisterNativeMethods(env, "android/webkit/WebView", gJavaWebViewMethods, NELEM(gJavaWebViewMethods)); -} - -} // namespace android diff --git a/WebCore/platform/android/sort.cpp b/WebCore/platform/android/sort.cpp deleted file mode 100644 index 58b620d..0000000 --- a/WebCore/platform/android/sort.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "config.h" - -namespace std -{ - void sort(const void** start, const void** end, const void** temp, Comparator comp) - { - size_t endlen = end - start; - size_t midlen = endlen / 2; - const void** mid = start + midlen; - if (midlen > 1) - sort(start, mid, temp, comp); - if (end - mid > 1) - sort(mid, end, temp, comp); - memcpy(temp, start, midlen * sizeof(*start)); - size_t i = 0; - size_t j = midlen; - size_t off = 0; - while (i < midlen && j < endlen) - start[off++] = (*comp)(start[j], temp[i]) ? start[j++] : temp[i++]; - if (i < midlen) - memcpy(&start[off], &temp[i], (midlen - i) * sizeof(*start)); - } - - void sort(const void** start, const void** end, Comparator comp) { - if (end - start > 1) { - const void** temp = new sortType[(end - start) / 2]; - sort(start, end, temp, comp); - delete[] temp; - } - } -} diff --git a/WebCore/platform/android/stl/algorithm b/WebCore/platform/android/stl/algorithm deleted file mode 100644 index 9657ceb..0000000 --- a/WebCore/platform/android/stl/algorithm +++ /dev/null @@ -1,237 +0,0 @@ -#ifdef __cplusplus - -/* - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * - * Copyright (c) 1996-1998 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - */ - - // extracted from stl_algobase.h - // full STL is not compatible with the ARM build - // a limited number of STL functions is used by webkit: swap, max, and min are - // included below for webkit compatibility - -#ifdef __GLIBCPP_INTERNAL_ALGOBASE_H -#error "real STL defined" -#endif - -#ifndef __ANDROID_ALGORITHM -#define __ANDROID_ALGORITHM - -#ifndef __ANDROID_LIMITS -#include <limits> -#endif - -#include <SkScalar.h> // for SK_ScalarNaN -#ifdef PREFIX_FOR_WEBCORE -#include <SkTSearch.h> -namespace WebCore { - class InlineTextBox; - class RenderLayer; -} -#endif -#include <float.h> -#include <math.h> -#include <stdint.h> - -#ifndef WCHAR_MAX - #define WCHAR_MAX 0xFFFF -#endif - -namespace std -{ - template<typename _Tp> - inline void - swap(_Tp& __a, _Tp& __b) - { - _Tp __tmp = __a; - __a = __b; - __b = __tmp; - } - - #undef min - #undef max - - template<typename _Tp> - inline const _Tp& - min(const _Tp& __a, const _Tp& __b) - { - return __b < __a ? __b : __a; - } - - template<typename _Tp> - inline const _Tp& - max(const _Tp& __a, const _Tp& __b) - { - return __a < __b ? __b : __a; - } - -template <class _InputIter, class _OutputIter> -inline _OutputIter copy(_InputIter __first, _InputIter __last, - _OutputIter __result) -{ - for (size_t __n = __last - __first; __n > 0; --__n) { - *__result = *__first; - ++__first; - ++__result; - } - return __result; -} - -template <class _ForwardIter, class _Tp> -void fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __value) { - for ( ; __first != __last; ++__first) - *__first = __value; -} - -#ifndef UINTPTR_MAX -#define UINTPTR_MAX UINT32_MAX -#endif - -#ifndef UINT32_MAX -#define UINT32_MAX (0xffffffff) -#endif - -template <typename T> -struct numeric_limits { - /// Returns the minimum value for type T. - static inline T min (void) { return (T(0)); } - /// Returns the minimum value for type T. - static inline T max (void) { return (T(0)); } - static const bool is_signed = false; ///< True if the type is signed. - static const bool is_integer = false; ///< True if stores an exact value. - static const bool is_integral = false; ///< True if fixed size and cast-copyable. -}; - -template <typename T> -struct numeric_limits<T*> { - static inline T* min (void) { return (NULL); } - static inline T* max (void) { return (UINTPTR_MAX); } - static const bool is_signed = false; - static const bool is_integer = true; - static const bool is_integral = true; -}; - -#define _NUMERIC_LIMITS(type, minVal, maxVal, quietNaN, bSigned, bInteger, bIntegral) \ -template <> \ -struct numeric_limits<type> { \ - static inline type infinity (void) { return (maxVal); } \ - static inline type min (void) { return (minVal); } \ - static inline type max (void) { return (maxVal); } \ - static inline type quiet_NaN() { return (quietNaN); } \ - static const bool is_signed = bSigned; \ - static const bool is_integer = bInteger; \ - static const bool is_integral = bIntegral; \ -} - -//-------------------------------------------------------------------------------------- -// type min max NaN signed integer integral -//-------------------------------------------------------------------------------------- -_NUMERIC_LIMITS (bool, false, true, 0, false, true, true); -_NUMERIC_LIMITS (char, SCHAR_MIN, SCHAR_MAX, 0, true, true, true); -_NUMERIC_LIMITS (int, INT_MIN, INT_MAX, 0, true, true, true); -_NUMERIC_LIMITS (short, SHRT_MIN, SHRT_MAX, 0, true, true, true); -_NUMERIC_LIMITS (long, LONG_MIN, LONG_MAX, 0, true, true, true); -#if HAVE_THREE_CHAR_TYPES -_NUMERIC_LIMITS (signed char, SCHAR_MIN, SCHAR_MAX, 0, true, true, true); -#endif -_NUMERIC_LIMITS (unsigned char, 0, UCHAR_MAX, 0, false, true, true); -_NUMERIC_LIMITS (unsigned int, 0, UINT_MAX, 0, false, true, true); -_NUMERIC_LIMITS (unsigned short,0, USHRT_MAX, 0, false, true, true); -_NUMERIC_LIMITS (unsigned long, 0, ULONG_MAX, 0, false, true, true); -_NUMERIC_LIMITS (wchar_t, 0, WCHAR_MAX, 0, false, true, true); -_NUMERIC_LIMITS (float, FLT_MIN, FLT_MAX, SK_ScalarNaN, true, false, true); -_NUMERIC_LIMITS (double, DBL_MIN, DBL_MAX, SK_ScalarNaN, true, false, true); -_NUMERIC_LIMITS (long double, LDBL_MIN, LDBL_MAX, SK_ScalarNaN, true, false, true); -#ifdef HAVE_LONG_LONG -_NUMERIC_LIMITS (long long, LLONG_MIN, LLONG_MAX, 0, true, true, true); -_NUMERIC_LIMITS (unsigned long long, 0, ULLONG_MAX, 0, false, true, true); -#endif -//-------------------------------------------------------------------------------------- - -typedef int ptrdiff_t; - -#ifdef PREFIX_FOR_WEBCORE - typedef const void* sortType; - typedef bool (* Comparator)(const void*, const void*); - - inline bool binary_search(const unsigned short* const base, - const unsigned short* const end, - short target) - { - return SkTSearch<unsigned short>(base, end - base, target, sizeof(unsigned short)) >= 0; - } - - extern void sort(const void** start, const void** end, Comparator comp); - - inline void sort (WebCore::InlineTextBox** start, WebCore::InlineTextBox**end, - bool (* comp)(const WebCore::InlineTextBox*, const WebCore::InlineTextBox*)) - { - sort((const void**) start, (const void**) end, (Comparator) comp); - } - - template<typename P> inline void stable_sort(P** start, P** end, - bool (* comp)(P*, P*)) - { - sort((const void**) start, (const void**) end, (Comparator) comp); - } - - template<typename P> void stable_sort(P* start, P* end, P* temp, - bool (& comp)(const P&, const P&)) { - size_t endlen = end - start; - size_t midlen = endlen / 2; - P* mid = start + midlen; - if (midlen > 1) - stable_sort(start, mid, temp, comp); - if (end - mid > 1) - stable_sort(mid, end, temp, comp); - memcpy(temp, start, midlen * sizeof(*start)); - size_t i = 0; - size_t j = midlen; - size_t off = 0; - while (i < midlen && j < endlen) - start[off++] = (comp)(start[j], temp[i]) ? start[j++] : temp[i++]; - if (i < midlen) - memcpy(&start[off], &temp[i], (midlen - i) * sizeof(*start)); - } - - template<typename P> void stable_sort(P* start, P* end, - bool (& comp)(const P&, const P&)) { - if (end - start > 1) { - P* temp = new P[(end - start) / 2]; - stable_sort(start, end, temp, comp); - delete[] temp; - } - } - - class ostream { - int this_class_intentionally_left_empty; - }; -#endif - -} - -#endif - -#endif // __cplusplus - diff --git a/WebCore/platform/android/stl/concept_checks.h b/WebCore/platform/android/stl/concept_checks.h deleted file mode 100644 index 36df283..0000000 --- a/WebCore/platform/android/stl/concept_checks.h +++ /dev/null @@ -1,811 +0,0 @@ -/* - * Copyright (c) 1999 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - */ - -#ifndef __CONCEPT_CHECKS_H -#define __CONCEPT_CHECKS_H - -/* - Use these macro like assertions, but they assert properties - on types (usually template arguments). In technical terms they - verify whether a type "models" a "concept". - - This set of requirements and the terminology used here is derived - from the book "Generic Programming and the STL" by Matt Austern - (Addison Wesley). For further information please consult that - book. The requirements also are intended to match the ANSI/ISO C++ - standard. - - This file covers the basic concepts and the iterator concepts. - There are several other files that provide the requirements - for the STL containers: - container_concepts.h - sequence_concepts.h - assoc_container_concepts.h - - Jeremy Siek, 1999 - - TO DO: - - some issues with regards to concept classification and mutability - including AssociativeContianer -> ForwardContainer - and SortedAssociativeContainer -> ReversibleContainer - - HashedAssociativeContainer - - Allocator - - Function Object Concepts - - */ - -#ifndef __STL_USE_CONCEPT_CHECKS - -// Some compilers lack the features that are necessary for concept checks. -// On those compilers we define the concept check macros to do nothing. -#define __STL_REQUIRES(__type_var, __concept) do {} while(0) -#define __STL_CLASS_REQUIRES(__type_var, __concept) \ - static int __##__type_var##_##__concept -#define __STL_CONVERTIBLE(__type_x, __type_y) do {} while(0) -#define __STL_REQUIRES_SAME_TYPE(__type_x, __type_y) do {} while(0) -#define __STL_CLASS_REQUIRES_SAME_TYPE(__type_x, __type_y) \ - static int __##__type_x##__type_y##_require_same_type -#define __STL_GENERATOR_CHECK(__func, __ret) do {} while(0) -#define __STL_CLASS_GENERATOR_CHECK(__func, __ret) \ - static int __##__func##__ret##_generator_check -#define __STL_UNARY_FUNCTION_CHECK(__func, __ret, __arg) do {} while(0) -#define __STL_CLASS_UNARY_FUNCTION_CHECK(__func, __ret, __arg) \ - static int __##__func##__ret##__arg##_unary_function_check -#define __STL_BINARY_FUNCTION_CHECK(__func, __ret, __first, __second) \ - do {} while(0) -#define __STL_CLASS_BINARY_FUNCTION_CHECK(__func, __ret, __first, __second) \ - static int __##__func##__ret##__first##__second##_binary_function_check -#define __STL_REQUIRES_BINARY_OP(__opname, __ret, __first, __second) \ - do {} while(0) -#define __STL_CLASS_REQUIRES_BINARY_OP(__opname, __ret, __first, __second) \ - static int __##__opname##__ret##__first##__second##_require_binary_op - -#else /* __STL_USE_CONCEPT_CHECKS */ - -// This macro tests whether the template argument "__type_var" -// satisfies the requirements of "__concept". Here is a list of concepts -// that we know how to check: -// _Allocator -// _Assignable -// _DefaultConstructible -// _EqualityComparable -// _LessThanComparable -// _TrivialIterator -// _InputIterator -// _OutputIterator -// _ForwardIterator -// _BidirectionalIterator -// _RandomAccessIterator -// _Mutable_TrivialIterator -// _Mutable_ForwardIterator -// _Mutable_BidirectionalIterator -// _Mutable_RandomAccessIterator - -#define __STL_REQUIRES(__type_var, __concept) \ -do { \ - void (*__x)( __type_var ) = __concept##_concept_specification< __type_var >\ - ::__concept##_requirement_violation; __x = __x; } while (0) - -// Use this to check whether type X is convertible to type Y -#define __STL_CONVERTIBLE(__type_x, __type_y) \ -do { \ - void (*__x)( __type_x , __type_y ) = _STL_CONVERT_ERROR< __type_x , \ - __type_y >::__type_X_is_not_convertible_to_type_Y; \ - __x = __x; } while (0) - -// Use this to test whether two template arguments are the same type -#define __STL_REQUIRES_SAME_TYPE(__type_x, __type_y) \ -do { \ - void (*__x)( __type_x , __type_y ) = _STL_SAME_TYPE_ERROR< __type_x, \ - __type_y >::__type_X_not_same_as_type_Y; \ - __x = __x; } while (0) - - -// function object checks -#define __STL_GENERATOR_CHECK(__func, __ret) \ -do { \ - __ret (*__x)( __func&) = \ - _STL_GENERATOR_ERROR< \ - __func, __ret>::__generator_requirement_violation; \ - __x = __x; } while (0) - - -#define __STL_UNARY_FUNCTION_CHECK(__func, __ret, __arg) \ -do { \ - __ret (*__x)( __func&, const __arg& ) = \ - _STL_UNARY_FUNCTION_ERROR< \ - __func, __ret, __arg>::__unary_function_requirement_violation; \ - __x = __x; } while (0) - - -#define __STL_BINARY_FUNCTION_CHECK(__func, __ret, __first, __second) \ -do { \ - __ret (*__x)( __func&, const __first&, const __second& ) = \ - _STL_BINARY_FUNCTION_ERROR< \ - __func, __ret, __first, __second>::__binary_function_requirement_violation; \ - __x = __x; } while (0) - - -#define __STL_REQUIRES_BINARY_OP(__opname, __ret, __first, __second) \ - do { \ - __ret (*__x)( __first&, __second& ) = _STL_BINARY##__opname##_ERROR< \ - __ret, __first, __second>::__binary_operator_requirement_violation; \ - __ret (*__y)( const __first&, const __second& ) = \ - _STL_BINARY##__opname##_ERROR< __ret, __first, __second>:: \ - __const_binary_operator_requirement_violation; \ - __y = __y; __x = __x; } while (0) - - -#ifdef __STL_NO_FUNCTION_PTR_IN_CLASS_TEMPLATE - -#define __STL_CLASS_REQUIRES(__type_var, __concept) -#define __STL_CLASS_REQUIRES_SAME_TYPE(__type_x, __type_y) -#define __STL_CLASS_GENERATOR_CHECK(__func, __ret) -#define __STL_CLASS_UNARY_FUNCTION_CHECK(__func, __ret, __arg) -#define __STL_CLASS_BINARY_FUNCTION_CHECK(__func, __ret, __first, __second) -#define __STL_CLASS_REQUIRES_BINARY_OP(__opname, __ret, __first, __second) - -#else - -// Use this macro inside of template classes, where you would -// like to place requirements on the template arguments to the class -// Warning: do not pass pointers and such (e.g. T*) in as the __type_var, -// since the type_var is used to construct identifiers. Instead typedef -// the pointer type, then use the typedef name for the __type_var. -#define __STL_CLASS_REQUIRES(__type_var, __concept) \ - typedef void (* __func##__type_var##__concept)( __type_var ); \ - template <__func##__type_var##__concept _Tp1> \ - struct __dummy_struct_##__type_var##__concept { }; \ - static __dummy_struct_##__type_var##__concept< \ - __concept##_concept_specification< \ - __type_var>::__concept##_requirement_violation> \ - __dummy_ptr_##__type_var##__concept - - -#define __STL_CLASS_REQUIRES_SAME_TYPE(__type_x, __type_y) \ - typedef void (* __func_##__type_x##__type_y##same_type)( __type_x, \ - __type_y ); \ - template < __func_##__type_x##__type_y##same_type _Tp1> \ - struct __dummy_struct_##__type_x##__type_y##_same_type { }; \ - static __dummy_struct_##__type_x##__type_y##_same_type< \ - _STL_SAME_TYPE_ERROR<__type_x, __type_y>::__type_X_not_same_as_type_Y> \ - __dummy_ptr_##__type_x##__type_y##_same_type - - -#define __STL_CLASS_GENERATOR_CHECK(__func, __ret) \ - typedef __ret (* __f_##__func##__ret##_generator)( __func& ); \ - template <__f_##__func##__ret##_generator _Tp1> \ - struct __dummy_struct_##__func##__ret##_generator { }; \ - static __dummy_struct_##__func##__ret##_generator< \ - _STL_GENERATOR_ERROR< \ - __func, __ret>::__generator_requirement_violation> \ - __dummy_ptr_##__func##__ret##_generator - - -#define __STL_CLASS_UNARY_FUNCTION_CHECK(__func, __ret, __arg) \ - typedef __ret (* __f_##__func##__ret##__arg##_unary_check)( __func&, \ - const __arg& ); \ - template <__f_##__func##__ret##__arg##_unary_check _Tp1> \ - struct __dummy_struct_##__func##__ret##__arg##_unary_check { }; \ - static __dummy_struct_##__func##__ret##__arg##_unary_check< \ - _STL_UNARY_FUNCTION_ERROR< \ - __func, __ret, __arg>::__unary_function_requirement_violation> \ - __dummy_ptr_##__func##__ret##__arg##_unary_check - - -#define __STL_CLASS_BINARY_FUNCTION_CHECK(__func, __ret, __first, __second) \ - typedef __ret (* __f_##__func##__ret##__first##__second##_binary_check)( __func&, const __first&,\ - const __second& ); \ - template <__f_##__func##__ret##__first##__second##_binary_check _Tp1> \ - struct __dummy_struct_##__func##__ret##__first##__second##_binary_check { }; \ - static __dummy_struct_##__func##__ret##__first##__second##_binary_check< \ - _STL_BINARY_FUNCTION_ERROR<__func, __ret, __first, __second>:: \ - __binary_function_requirement_violation> \ - __dummy_ptr_##__func##__ret##__first##__second##_binary_check - - -#define __STL_CLASS_REQUIRES_BINARY_OP(__opname, __ret, __first, __second) \ - typedef __ret (* __f_##__func##__ret##__first##__second##_binary_op)(const __first&, \ - const __second& ); \ - template <__f_##__func##__ret##__first##__second##_binary_op _Tp1> \ - struct __dummy_struct_##__func##__ret##__first##__second##_binary_op { }; \ - static __dummy_struct_##__func##__ret##__first##__second##_binary_op< \ - _STL_BINARY##__opname##_ERROR<__ret, __first, __second>:: \ - __binary_operator_requirement_violation> \ - __dummy_ptr_##__func##__ret##__first##__second##_binary_op - -#endif - -/* helper class for finding non-const version of a type. Need to have - something to assign to etc. when testing constant iterators. */ - -template <class _Tp> -struct _Mutable_trait { - typedef _Tp _Type; -}; -template <class _Tp> -struct _Mutable_trait<const _Tp> { - typedef _Tp _Type; -}; - - -/* helper function for avoiding compiler warnings about unused variables */ -template <class _Type> -void __sink_unused_warning(_Type) { } - -template <class _TypeX, class _TypeY> -struct _STL_CONVERT_ERROR { - static void - __type_X_is_not_convertible_to_type_Y(_TypeX __x, _TypeY) { - _TypeY __y = __x; - __sink_unused_warning(__y); - } -}; - - -template <class _Type> struct __check_equal { }; - -template <class _TypeX, class _TypeY> -struct _STL_SAME_TYPE_ERROR { - static void - __type_X_not_same_as_type_Y(_TypeX , _TypeY ) { - __check_equal<_TypeX> t1 = __check_equal<_TypeY>(); - } -}; - - -// Some Functon Object Checks - -template <class _Func, class _Ret> -struct _STL_GENERATOR_ERROR { - static _Ret __generator_requirement_violation(_Func& __f) { - return __f(); - } -}; - -template <class _Func> -struct _STL_GENERATOR_ERROR<_Func, void> { - static void __generator_requirement_violation(_Func& __f) { - __f(); - } -}; - - -template <class _Func, class _Ret, class _Arg> -struct _STL_UNARY_FUNCTION_ERROR { - static _Ret - __unary_function_requirement_violation(_Func& __f, - const _Arg& __arg) { - return __f(__arg); - } -}; - -template <class _Func, class _Arg> -struct _STL_UNARY_FUNCTION_ERROR<_Func, void, _Arg> { - static void - __unary_function_requirement_violation(_Func& __f, - const _Arg& __arg) { - __f(__arg); - } -}; - -template <class _Func, class _Ret, class _First, class _Second> -struct _STL_BINARY_FUNCTION_ERROR { - static _Ret - __binary_function_requirement_violation(_Func& __f, - const _First& __first, - const _Second& __second) { - return __f(__first, __second); - } -}; - -template <class _Func, class _First, class _Second> -struct _STL_BINARY_FUNCTION_ERROR<_Func, void, _First, _Second> { - static void - __binary_function_requirement_violation(_Func& __f, - const _First& __first, - const _Second& __second) { - __f(__first, __second); - } -}; - - -#define __STL_DEFINE_BINARY_OP_CHECK(_OP, _NAME) \ -template <class _Ret, class _First, class _Second> \ -struct _STL_BINARY##_NAME##_ERROR { \ - static _Ret \ - __const_binary_operator_requirement_violation(const _First& __first, \ - const _Second& __second) { \ - return __first _OP __second; \ - } \ - static _Ret \ - __binary_operator_requirement_violation(_First& __first, \ - _Second& __second) { \ - return __first _OP __second; \ - } \ -} - -__STL_DEFINE_BINARY_OP_CHECK(==, _OP_EQUAL); -__STL_DEFINE_BINARY_OP_CHECK(!=, _OP_NOT_EQUAL); -__STL_DEFINE_BINARY_OP_CHECK(<, _OP_LESS_THAN); -__STL_DEFINE_BINARY_OP_CHECK(<=, _OP_LESS_EQUAL); -__STL_DEFINE_BINARY_OP_CHECK(>, _OP_GREATER_THAN); -__STL_DEFINE_BINARY_OP_CHECK(>=, _OP_GREATER_EQUAL); -__STL_DEFINE_BINARY_OP_CHECK(+, _OP_PLUS); -__STL_DEFINE_BINARY_OP_CHECK(*, _OP_TIMES); -__STL_DEFINE_BINARY_OP_CHECK(/, _OP_DIVIDE); -__STL_DEFINE_BINARY_OP_CHECK(-, _OP_SUBTRACT); -__STL_DEFINE_BINARY_OP_CHECK(%, _OP_MOD); -// ... - -// TODO, add unary operators (prefix and postfix) - -/* - The presence of this class is just to trick EDG into displaying - these error messages before any other errors. Without the - classes, the errors in the functions get reported after - other class errors deep inside the library. The name - choice just makes for an eye catching error message :) - */ -struct _STL_ERROR { - - template <class _Type> - static _Type - __default_constructor_requirement_violation(_Type) { - return _Type(); - } - template <class _Type> - static _Type - __assignment_operator_requirement_violation(_Type __a) { - __a = __a; - return __a; - } - template <class _Type> - static _Type - __copy_constructor_requirement_violation(_Type __a) { - _Type __c(__a); - return __c; - } - template <class _Type> - static _Type - __const_parameter_required_for_copy_constructor(_Type /* __a */, - const _Type& __b) { - _Type __c(__b); - return __c; - } - template <class _Type> - static _Type - __const_parameter_required_for_assignment_operator(_Type __a, - const _Type& __b) { - __a = __b; - return __a; - } - template <class _Type> - static _Type - __less_than_comparable_requirement_violation(_Type __a, _Type __b) { - if (__a < __b || __a > __b || __a <= __b || __a >= __b) return __a; - return __b; - } - template <class _Type> - static _Type - __equality_comparable_requirement_violation(_Type __a, _Type __b) { - if (__a == __b || __a != __b) return __a; - return __b; - } - template <class _Iterator> - static void - __dereference_operator_requirement_violation(_Iterator __i) { - __sink_unused_warning(*__i); - } - template <class _Iterator> - static void - __dereference_operator_and_assignment_requirement_violation(_Iterator __i) { - *__i = *__i; - } - template <class _Iterator> - static void - __preincrement_operator_requirement_violation(_Iterator __i) { - ++__i; - } - template <class _Iterator> - static void - __postincrement_operator_requirement_violation(_Iterator __i) { - __i++; - } - template <class _Iterator> - static void - __predecrement_operator_requirement_violation(_Iterator __i) { - --__i; - } - template <class _Iterator> - static void - __postdecrement_operator_requirement_violation(_Iterator __i) { - __i--; - } - template <class _Iterator, class _Type> - static void - __postincrement_operator_and_assignment_requirement_violation(_Iterator __i, - _Type __t) { - *__i++ = __t; - } - template <class _Iterator, class _Distance> - static _Iterator - __iterator_addition_assignment_requirement_violation(_Iterator __i, - _Distance __n) { - __i += __n; - return __i; - } - template <class _Iterator, class _Distance> - static _Iterator - __iterator_addition_requirement_violation(_Iterator __i, _Distance __n) { - __i = __i + __n; - __i = __n + __i; - return __i; - } - template <class _Iterator, class _Distance> - static _Iterator - __iterator_subtraction_assignment_requirement_violation(_Iterator __i, - _Distance __n) { - __i -= __n; - return __i; - } - template <class _Iterator, class _Distance> - static _Iterator - __iterator_subtraction_requirement_violation(_Iterator __i, _Distance __n) { - __i = __i - __n; - return __i; - } - template <class _Iterator, class _Distance> - static _Distance - __difference_operator_requirement_violation(_Iterator __i, _Iterator __j, - _Distance __n) { - __n = __i - __j; - return __n; - } - template <class _Exp, class _Type, class _Distance> - static _Type - __element_access_operator_requirement_violation(_Exp __x, _Type*, - _Distance __n) { - return __x[__n]; - } - template <class _Exp, class _Type, class _Distance> - static void - __element_assignment_operator_requirement_violation(_Exp __x, - _Type* __t, - _Distance __n) { - __x[__n] = *__t; - } - -}; /* _STL_ERROR */ - -/* Associated Type Requirements */ - -__STL_BEGIN_NAMESPACE -template <class _Iterator> struct iterator_traits; -__STL_END_NAMESPACE - -template <class _Iter> -struct __value_type_type_definition_requirement_violation { - typedef typename __STD::iterator_traits<_Iter>::value_type value_type; -}; - -template <class _Iter> -struct __difference_type_type_definition_requirement_violation { - typedef typename __STD::iterator_traits<_Iter>::difference_type - difference_type; -}; - -template <class _Iter> -struct __reference_type_definition_requirement_violation { - typedef typename __STD::iterator_traits<_Iter>::reference reference; -}; - -template <class _Iter> -struct __pointer_type_definition_requirement_violation { - typedef typename __STD::iterator_traits<_Iter>::pointer pointer; -}; - -template <class _Iter> -struct __iterator_category_type_definition_requirement_violation { - typedef typename __STD::iterator_traits<_Iter>::iterator_category - iterator_category; -}; - -/* Assignable Requirements */ - - -template <class _Type> -struct _Assignable_concept_specification { - static void _Assignable_requirement_violation(_Type __a) { - _STL_ERROR::__assignment_operator_requirement_violation(__a); - _STL_ERROR::__copy_constructor_requirement_violation(__a); - _STL_ERROR::__const_parameter_required_for_copy_constructor(__a,__a); - _STL_ERROR::__const_parameter_required_for_assignment_operator(__a,__a); - } -}; - -/* DefaultConstructible Requirements */ - - -template <class _Type> -struct _DefaultConstructible_concept_specification { - static void _DefaultConstructible_requirement_violation(_Type __a) { - _STL_ERROR::__default_constructor_requirement_violation(__a); - } -}; - -/* EqualityComparable Requirements */ - -template <class _Type> -struct _EqualityComparable_concept_specification { - static void _EqualityComparable_requirement_violation(_Type __a) { - _STL_ERROR::__equality_comparable_requirement_violation(__a, __a); - } -}; - -/* LessThanComparable Requirements */ -template <class _Type> -struct _LessThanComparable_concept_specification { - static void _LessThanComparable_requirement_violation(_Type __a) { - _STL_ERROR::__less_than_comparable_requirement_violation(__a, __a); - } -}; - -/* TrivialIterator Requirements */ - -template <class _TrivialIterator> -struct _TrivialIterator_concept_specification { -static void -_TrivialIterator_requirement_violation(_TrivialIterator __i) { - typedef typename - __value_type_type_definition_requirement_violation<_TrivialIterator>:: - value_type __T; - // Refinement of Assignable - _Assignable_concept_specification<_TrivialIterator>:: - _Assignable_requirement_violation(__i); - // Refinement of DefaultConstructible - _DefaultConstructible_concept_specification<_TrivialIterator>:: - _DefaultConstructible_requirement_violation(__i); - // Refinement of EqualityComparable - _EqualityComparable_concept_specification<_TrivialIterator>:: - _EqualityComparable_requirement_violation(__i); - // Valid Expressions - _STL_ERROR::__dereference_operator_requirement_violation(__i); -} -}; - -template <class _TrivialIterator> -struct _Mutable_TrivialIterator_concept_specification { -static void -_Mutable_TrivialIterator_requirement_violation(_TrivialIterator __i) { - _TrivialIterator_concept_specification<_TrivialIterator>:: - _TrivialIterator_requirement_violation(__i); - // Valid Expressions - _STL_ERROR::__dereference_operator_and_assignment_requirement_violation(__i); -} -}; - -/* InputIterator Requirements */ - -template <class _InputIterator> -struct _InputIterator_concept_specification { -static void -_InputIterator_requirement_violation(_InputIterator __i) { - // Refinement of TrivialIterator - _TrivialIterator_concept_specification<_InputIterator>:: - _TrivialIterator_requirement_violation(__i); - // Associated Types - __difference_type_type_definition_requirement_violation<_InputIterator>(); - __reference_type_definition_requirement_violation<_InputIterator>(); - __pointer_type_definition_requirement_violation<_InputIterator>(); - __iterator_category_type_definition_requirement_violation<_InputIterator>(); - // Valid Expressions - _STL_ERROR::__preincrement_operator_requirement_violation(__i); - _STL_ERROR::__postincrement_operator_requirement_violation(__i); -} -}; - -/* OutputIterator Requirements */ - -template <class _OutputIterator> -struct _OutputIterator_concept_specification { -static void -_OutputIterator_requirement_violation(_OutputIterator __i) { - // Refinement of Assignable - _Assignable_concept_specification<_OutputIterator>:: - _Assignable_requirement_violation(__i); - // Associated Types - __iterator_category_type_definition_requirement_violation<_OutputIterator>(); - // Valid Expressions - _STL_ERROR::__dereference_operator_requirement_violation(__i); - _STL_ERROR::__preincrement_operator_requirement_violation(__i); - _STL_ERROR::__postincrement_operator_requirement_violation(__i); - _STL_ERROR:: - __postincrement_operator_and_assignment_requirement_violation(__i, *__i); -} -}; - -/* ForwardIterator Requirements */ - -template <class _ForwardIterator> -struct _ForwardIterator_concept_specification { -static void -_ForwardIterator_requirement_violation(_ForwardIterator __i) { - // Refinement of InputIterator - _InputIterator_concept_specification<_ForwardIterator>:: - _InputIterator_requirement_violation(__i); -} -}; - -template <class _ForwardIterator> -struct _Mutable_ForwardIterator_concept_specification { -static void -_Mutable_ForwardIterator_requirement_violation(_ForwardIterator __i) { - _ForwardIterator_concept_specification<_ForwardIterator>:: - _ForwardIterator_requirement_violation(__i); - // Refinement of OutputIterator - _OutputIterator_concept_specification<_ForwardIterator>:: - _OutputIterator_requirement_violation(__i); -} -}; - -/* BidirectionalIterator Requirements */ - -template <class _BidirectionalIterator> -struct _BidirectionalIterator_concept_specification { -static void -_BidirectionalIterator_requirement_violation(_BidirectionalIterator __i) { - // Refinement of ForwardIterator - _ForwardIterator_concept_specification<_BidirectionalIterator>:: - _ForwardIterator_requirement_violation(__i); - // Valid Expressions - _STL_ERROR::__predecrement_operator_requirement_violation(__i); - _STL_ERROR::__postdecrement_operator_requirement_violation(__i); -} -}; - -template <class _BidirectionalIterator> -struct _Mutable_BidirectionalIterator_concept_specification { -static void -_Mutable_BidirectionalIterator_requirement_violation( - _BidirectionalIterator __i) -{ - _BidirectionalIterator_concept_specification<_BidirectionalIterator>:: - _BidirectionalIterator_requirement_violation(__i); - // Refinement of mutable_ForwardIterator - _Mutable_ForwardIterator_concept_specification<_BidirectionalIterator>:: - _Mutable_ForwardIterator_requirement_violation(__i); - typedef typename - __value_type_type_definition_requirement_violation< - _BidirectionalIterator>::value_type __T; - typename _Mutable_trait<__T>::_Type* __tmp_ptr = 0; - // Valid Expressions - _STL_ERROR:: - __postincrement_operator_and_assignment_requirement_violation(__i, - *__tmp_ptr); -} -}; - -/* RandomAccessIterator Requirements */ - -template <class _RandAccIter> -struct _RandomAccessIterator_concept_specification { -static void -_RandomAccessIterator_requirement_violation(_RandAccIter __i) { - // Refinement of BidirectionalIterator - _BidirectionalIterator_concept_specification<_RandAccIter>:: - _BidirectionalIterator_requirement_violation(__i); - // Refinement of LessThanComparable - _LessThanComparable_concept_specification<_RandAccIter>:: - _LessThanComparable_requirement_violation(__i); - typedef typename - __value_type_type_definition_requirement_violation<_RandAccIter> - ::value_type - value_type; - typedef typename - __difference_type_type_definition_requirement_violation<_RandAccIter> - ::difference_type - _Dist; - typedef typename _Mutable_trait<_Dist>::_Type _MutDist; - - // Valid Expressions - _STL_ERROR::__iterator_addition_assignment_requirement_violation(__i, - _MutDist()); - _STL_ERROR::__iterator_addition_requirement_violation(__i, - _MutDist()); - _STL_ERROR:: - __iterator_subtraction_assignment_requirement_violation(__i, - _MutDist()); - _STL_ERROR::__iterator_subtraction_requirement_violation(__i, - _MutDist()); - _STL_ERROR::__difference_operator_requirement_violation(__i, __i, - _MutDist()); - typename _Mutable_trait<value_type>::_Type* __dummy_ptr = 0; - _STL_ERROR::__element_access_operator_requirement_violation(__i, - __dummy_ptr, - _MutDist()); -} -}; - -template <class _RandAccIter> -struct _Mutable_RandomAccessIterator_concept_specification { -static void -_Mutable_RandomAccessIterator_requirement_violation(_RandAccIter __i) -{ - _RandomAccessIterator_concept_specification<_RandAccIter>:: - _RandomAccessIterator_requirement_violation(__i); - // Refinement of mutable_BidirectionalIterator - _Mutable_BidirectionalIterator_concept_specification<_RandAccIter>:: - _Mutable_BidirectionalIterator_requirement_violation(__i); - typedef typename - __value_type_type_definition_requirement_violation<_RandAccIter> - ::value_type - value_type; - typedef typename - __difference_type_type_definition_requirement_violation<_RandAccIter> - ::difference_type - _Dist; - - typename _Mutable_trait<value_type>::_Type* __tmp_ptr = 0; - // Valid Expressions - _STL_ERROR::__element_assignment_operator_requirement_violation(__i, - __tmp_ptr, _Dist()); -} -}; - -#define __STL_TYPEDEF_REQUIREMENT(__REQUIREMENT) \ -template <class Type> \ -struct __##__REQUIREMENT##__typedef_requirement_violation { \ - typedef typename Type::__REQUIREMENT __REQUIREMENT; \ -} - -__STL_TYPEDEF_REQUIREMENT(value_type); -__STL_TYPEDEF_REQUIREMENT(difference_type); -__STL_TYPEDEF_REQUIREMENT(size_type); -__STL_TYPEDEF_REQUIREMENT(reference); -__STL_TYPEDEF_REQUIREMENT(const_reference); -__STL_TYPEDEF_REQUIREMENT(pointer); -__STL_TYPEDEF_REQUIREMENT(const_pointer); - - -template <class _Alloc> -struct _Allocator_concept_specification { -static void -_Allocator_requirement_violation(_Alloc __a) { - // Refinement of DefaultConstructible - _DefaultConstructible_concept_specification<_Alloc>:: - _DefaultConstructible_requirement_violation(__a); - // Refinement of EqualityComparable - _EqualityComparable_concept_specification<_Alloc>:: - _EqualityComparable_requirement_violation(__a); - // Associated Types - __value_type__typedef_requirement_violation<_Alloc>(); - __difference_type__typedef_requirement_violation<_Alloc>(); - __size_type__typedef_requirement_violation<_Alloc>(); - __reference__typedef_requirement_violation<_Alloc>(); - __const_reference__typedef_requirement_violation<_Alloc>(); - __pointer__typedef_requirement_violation<_Alloc>(); - __const_pointer__typedef_requirement_violation<_Alloc>(); - typedef typename _Alloc::value_type _Tp; - //__STL_REQUIRES_SAME_TYPE(typename _Alloc::__STL_TEMPLATE rebind<_Tp>::other, - // _Alloc); -} -}; - -#endif /* __STL_USE_CONCEPT_CHECKS */ - -#endif /* __CONCEPT_CHECKS_H */ - -// Local Variables: -// mode:C++ -// End: diff --git a/WebCore/platform/android/stl/cstring b/WebCore/platform/android/stl/cstring deleted file mode 100644 index 77c9175..0000000 --- a/WebCore/platform/android/stl/cstring +++ /dev/null @@ -1,128 +0,0 @@ -// -*- C++ -*- forwarding header. - -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 -// Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2, or (at your option) -// any later version. - -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, -// USA. - -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. - -// -// ISO C++ 14882: 20.4.6 C library -// - -/** @file cstring - * This is a Standard C++ Library file. You should @c #include this file - * in your programs, rather than any of the "*.h" implementation files. - * - * This is the C++ version of the Standard C Library header @c string.h, - * and its contents are (mostly) the same as that header, but are all - * contained in the namespace @c std. - */ - -#ifndef _GLIBCXX_CSTRING -#define _GLIBCXX_CSTRING 1 - -#pragma GCC system_header - -#include <cstddef> - -#include <string.h> - -// Get rid of those macros defined in <string.h> in lieu of real functions. -#undef memcpy -#undef memmove -#undef strcpy -#undef strncpy -#undef strcat -#undef strncat -#undef memcmp -#undef strcmp -#undef strcoll -#undef strncmp -#undef strxfrm -#undef memchr -#undef strchr -#undef strcspn -#undef strpbrk -#undef strrchr -#undef strspn -#undef strstr -#undef strtok -#undef memset -#undef strerror -#undef strlen - -namespace std -{ - using ::memcpy; - using ::memmove; - using ::strcpy; - using ::strncpy; - using ::strcat; - using ::strncat; - using ::memcmp; - using ::strcmp; -// using ::strcoll; - using ::strncmp; -// using ::strxfrm; - using ::strcspn; - using ::strspn; - using ::strtok; - using ::memset; - using ::strerror; - using ::strlen; - - using ::memchr; - - inline void* - memchr(void* __p, int __c, size_t __n) - { return memchr(const_cast<const void*>(__p), __c, __n); } - - using ::strchr; - - inline char* - strchr(char* __s1, int __n) - { return __builtin_strchr(const_cast<const char*>(__s1), __n); } - - using ::strpbrk; - - inline char* - strpbrk(char* __s1, const char* __s2) - { return __builtin_strpbrk(const_cast<const char*>(__s1), __s2); } - - using ::strrchr; - - inline char* - strrchr(char* __s1, int __n) - { return __builtin_strrchr(const_cast<const char*>(__s1), __n); } - - using ::strstr; - - inline char* - strstr(char* __s1, const char* __s2) - { return __builtin_strstr(const_cast<const char*>(__s1), __s2); } -} - -#endif diff --git a/WebCore/platform/android/stl/heap.h b/WebCore/platform/android/stl/heap.h deleted file mode 100644 index d1fb319..0000000 --- a/WebCore/platform/android/stl/heap.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * Copyright (c) 1997 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - */ - -#ifndef __SGI_STL_HEAP_H -#define __SGI_STL_HEAP_H - -#include <concept_checks.h> -#include <stl_config.h> -#include <stl_heap.h> - -#ifdef __STL_USE_NAMESPACES - -using __STD::push_heap; -using __STD::pop_heap; -using __STD::make_heap; -using __STD::sort_heap; - -#endif /* __STL_USE_NAMESPACES */ - - -#endif /* __SGI_STL_HEAP_H */ - -// Local Variables: -// mode:C++ -// End: diff --git a/WebCore/platform/android/stl/iostream.h b/WebCore/platform/android/stl/iostream.h deleted file mode 100644 index 2b7d968..0000000 --- a/WebCore/platform/android/stl/iostream.h +++ /dev/null @@ -1 +0,0 @@ -// this file intentionally left blank diff --git a/WebCore/platform/android/stl/limits b/WebCore/platform/android/stl/limits deleted file mode 100644 index d4d7960..0000000 --- a/WebCore/platform/android/stl/limits +++ /dev/null @@ -1,23 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef __ANDROID_LIMITS -#define __ANDROID_LIMITS - -#include <limits.h> - -#endif // __ANDROID_LIMITS diff --git a/WebCore/platform/android/stl/memory b/WebCore/platform/android/stl/memory deleted file mode 100644 index b224c33..0000000 --- a/WebCore/platform/android/stl/memory +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 1997-1999 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - */ - -//minimal file to get build to work - -#ifdef _CPP_MEMORY -#error "real STL defined" -#endif - -#ifndef __ANDROID_MEMORY -#define __ANDROID_MEMORY -//we good to do this? -#define __STL_MEMBER_TEMPLATES - -#define __STL_NOTHROW - -/*#if defined(__SGI_STL_USE_AUTO_PTR_CONVERSIONS) && \*/ - -#if defined(__STL_MEMBER_TEMPLATES) -template<class _Tp1> struct auto_ptr_ref { - _Tp1* _M_ptr; - auto_ptr_ref(_Tp1* __p) : _M_ptr(__p) {} -}; -#endif - -namespace std { - -template <class _Tp> class auto_ptr { -private: - _Tp* _M_ptr; - -public: - typedef _Tp element_type; - - explicit auto_ptr(_Tp* __p = 0) __STL_NOTHROW : _M_ptr(__p) {} - auto_ptr(auto_ptr& __a) __STL_NOTHROW : _M_ptr(__a.release()) {} - -#ifdef __STL_MEMBER_TEMPLATES - template <class _Tp1> auto_ptr(auto_ptr<_Tp1>& __a) __STL_NOTHROW - : _M_ptr(__a.release()) {} -#endif /* __STL_MEMBER_TEMPLATES */ - - auto_ptr& operator=(auto_ptr& __a) __STL_NOTHROW { - if (&__a != this) { - delete _M_ptr; - _M_ptr = __a.release(); - } - return *this; - } - -#ifdef __STL_MEMBER_TEMPLATES - template <class _Tp1> - auto_ptr& operator=(auto_ptr<_Tp1>& __a) __STL_NOTHROW { - if (__a.get() != this->get()) { - delete _M_ptr; - _M_ptr = __a.release(); - } - return *this; - } -#endif /* __STL_MEMBER_TEMPLATES */ - - // Note: The C++ standard says there is supposed to be an empty throw - // specification here, but omitting it is standard conforming. Its - // presence can be detected only if _Tp::~_Tp() throws, but (17.4.3.6/2) - // this is prohibited. - ~auto_ptr() { delete _M_ptr; } - - _Tp& operator*() const __STL_NOTHROW { - return *_M_ptr; - } - _Tp* operator->() const __STL_NOTHROW { - return _M_ptr; - } - _Tp* get() const __STL_NOTHROW { - return _M_ptr; - } - _Tp* release() __STL_NOTHROW { - _Tp* __tmp = _M_ptr; - _M_ptr = 0; - return __tmp; - } - void reset(_Tp* __p = 0) __STL_NOTHROW { - if (__p != _M_ptr) { - delete _M_ptr; - _M_ptr = __p; - } - } - -/*#if defined(__SGI_STL_USE_AUTO_PTR_CONVERSIONS) && \*/ -#if defined(__STL_MEMBER_TEMPLATES) - -public: - auto_ptr(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW - : _M_ptr(__ref._M_ptr) {} - - auto_ptr& operator=(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW { - if (__ref._M_ptr != this->get()) { - delete _M_ptr; - _M_ptr = __ref._M_ptr; - } - return *this; - } - - template <class _Tp1> operator auto_ptr_ref<_Tp1>() __STL_NOTHROW - { return auto_ptr_ref<_Tp1>(this->release()); } - template <class _Tp1> operator auto_ptr<_Tp1>() __STL_NOTHROW - { return auto_ptr<_Tp1>(this->release()); } - -#endif /* auto ptr conversions && member templates */ - -}; - -} //namespace std - -#endif /* __ANDROID_MEMORY */ - - -// Local Variables: -// mode:C++ -// End: - diff --git a/WebCore/platform/android/stl/new.h b/WebCore/platform/android/stl/new.h deleted file mode 100644 index 13d6d4e..0000000 --- a/WebCore/platform/android/stl/new.h +++ /dev/null @@ -1,17 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - diff --git a/WebCore/platform/android/stl/stl_config.h b/WebCore/platform/android/stl/stl_config.h deleted file mode 100644 index 8c107c1..0000000 --- a/WebCore/platform/android/stl/stl_config.h +++ /dev/null @@ -1,576 +0,0 @@ -/* - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * Copyright (c) 1997 - * Silicon Graphics - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - */ - -#ifndef __STL_CONFIG_H -# define __STL_CONFIG_H - -// Flags: -// * __STL_NO_BOOL: defined if the compiler doesn't have bool as a builtin -// type. -// * __STL_HAS_WCHAR_T: defined if the compier has wchar_t as a builtin type. -// * __STL_NO_DRAND48: defined if the compiler doesn't have the drand48 -// function. -// * __STL_STATIC_TEMPLATE_MEMBER_BUG: defined if the compiler can't handle -// static members of template classes. -// * __STL_STATIC_CONST_INIT_BUG: defined if the compiler can't handle a -// constant-initializer in the declaration of a static const data member -// of integer type. (See section 9.4.2, paragraph 4, of the C++ standard.) -// * __STL_CLASS_PARTIAL_SPECIALIZATION: defined if the compiler supports -// partial specialization of template classes. -// * __STL_PARTIAL_SPECIALIZATION_SYNTAX: defined if the compiler -// supports partial specialization syntax for full specialization of -// class templates. (Even if it doesn't actually support partial -// specialization itself.) -// * __STL_FUNCTION_TMPL_PARTIAL_ORDER: defined if the compiler supports -// partial ordering of function templates. (a.k.a partial specialization -// of function templates.) -// * __STL_MEMBER_TEMPLATES: defined if the compiler supports template -// member functions of classes. -// * __STL_MEMBER_TEMPLATE_CLASSES: defined if the compiler supports -// nested classes that are member templates of other classes. -// * __STL_TEMPLATE_FRIENDS: defined if the compiler supports templatized -// friend declarations. -// * __STL_EXPLICIT_FUNCTION_TMPL_ARGS: defined if the compiler -// supports calling a function template by providing its template -// arguments explicitly. -// * __STL_LIMITED_DEFAULT_TEMPLATES: defined if the compiler is unable -// to handle default template parameters that depend on previous template -// parameters. -// * __STL_NON_TYPE_TMPL_PARAM_BUG: defined if the compiler has trouble with -// function template argument deduction for non-type template parameters. -// * __SGI_STL_NO_ARROW_OPERATOR: defined if the compiler is unable -// to support the -> operator for iterators. -// * __STL_DEFAULT_CONSTRUCTOR_BUG: defined if T() does not work properly -// when T is a builtin type. -// * __STL_USE_EXCEPTIONS: defined if the compiler (in the current compilation -// mode) supports exceptions. -// * __STL_USE_NAMESPACES: defined if the compiler has the necessary -// support for namespaces. -// * __STL_NO_EXCEPTION_HEADER: defined if the compiler does not have a -// standard-conforming header <exception>. -// * __STL_NO_BAD_ALLOC: defined if the compiler does not have a <new> -// header, or if <new> does not contain a bad_alloc class. If a bad_alloc -// class exists, it is assumed to be in namespace std. -// * __STL_SGI_THREADS: defined if this is being compiled for an SGI IRIX -// system in multithreaded mode, using native SGI threads instead of -// pthreads. -// * __STL_WIN32THREADS: defined if this is being compiled on a WIN32 -// compiler in multithreaded mode. -// * __STL_PTHREADS: defined if we should use portable pthreads -// synchronization. -// * __STL_UITHREADS: defined if we should use UI / solaris / UnixWare threads -// synchronization. UIthreads are similar to pthreads, but are based -// on an earlier version of the Posix threads standard. -// * __STL_LONG_LONG if the compiler has long long and unsigned long long -// types. (They're not in the C++ standard, but they are expected to be -// included in the forthcoming C9X standard.) -// * __STL_THREADS is defined if thread safety is needed. -// * __STL_VOLATILE is defined to be "volatile" if threads are being -// used, and the empty string otherwise. -// * __STL_USE_CONCEPT_CHECKS enables some extra compile-time error -// checking to make sure that user-defined template arguments satisfy -// all of the appropriate requirements. This may result in more -// comprehensible error messages. It incurs no runtime overhead. This -// feature requires member templates and partial specialization. -// * __STL_NO_USING_CLAUSE_IN_CLASS: The compiler does not handle "using" -// clauses inside of class definitions. -// * __STL_NO_FRIEND_TEMPLATE_CLASS: The compiler does not handle friend -// declaractions where the friend is a template class. -// * __STL_NO_FUNCTION_PTR_IN_CLASS_TEMPLATE: The compiler does not -// support the use of a function pointer type as the argument -// for a template. -// * __STL_MEMBER_TEMPLATE_KEYWORD: standard C++ requires the template -// keyword in a few new places (14.2.4). This flag is set for -// compilers that support (and require) this usage. - - -// User-settable macros that control compilation: -// * __STL_USE_SGI_ALLOCATORS: if defined, then the STL will use older -// SGI-style allocators, instead of standard-conforming allocators, -// even if the compiler supports all of the language features needed -// for standard-conforming allocators. -// * __STL_NO_NAMESPACES: if defined, don't put the library in namespace -// std, even if the compiler supports namespaces. -// * __STL_NO_RELOPS_NAMESPACE: if defined, don't put the relational -// operator templates (>, <=. >=, !=) in namespace std::rel_ops, even -// if the compiler supports namespaces and partial ordering of -// function templates. -// * __STL_ASSERTIONS: if defined, then enable runtime checking through the -// __stl_assert macro. -// * _PTHREADS: if defined, use Posix threads for multithreading support. -// * _UITHREADS:if defined, use SCO/Solaris/UI threads for multithreading -// support -// * _NOTHREADS: if defined, don't use any multithreading support. -// * _STL_NO_CONCEPT_CHECKS: if defined, disables the error checking that -// we get from __STL_USE_CONCEPT_CHECKS. -// * __STL_USE_NEW_IOSTREAMS: if defined, then the STL will use new, -// standard-conforming iostreams (e.g. the <iosfwd> header). If not -// defined, the STL will use old cfront-style iostreams (e.g. the -// <iostream.h> header). - -// Other macros defined by this file: - -// * bool, true, and false, if __STL_NO_BOOL is defined. -// * typename, as a null macro if it's not already a keyword. -// * explicit, as a null macro if it's not already a keyword. -// * namespace-related macros (__STD, __STL_BEGIN_NAMESPACE, etc.) -// * exception-related macros (__STL_TRY, __STL_UNWIND, etc.) -// * __stl_assert, either as a test or as a null macro, depending on -// whether or not __STL_ASSERTIONS is defined. - -# if defined(_PTHREADS) && !defined(_NOTHREADS) -# define __STL_PTHREADS -# endif - -# if defined(_UITHREADS) && !defined(_PTHREADS) && !defined(_NOTHREADS) -# define __STL_UITHREADS -# endif - -# if defined(__sgi) && !defined(__GNUC__) -# include <standards.h> -# if !defined(_BOOL) -# define __STL_NO_BOOL -# endif -# if defined(_MIPS_SIM) && _MIPS_SIM == _ABIO32 -# define __STL_STATIC_CONST_INIT_BUG -# endif -# if defined(_WCHAR_T_IS_KEYWORD) -# define __STL_HAS_WCHAR_T -# endif -# if !defined(_TYPENAME_IS_KEYWORD) -# define __STL_NEED_TYPENAME -# endif -# ifdef _PARTIAL_SPECIALIZATION_OF_CLASS_TEMPLATES -# define __STL_CLASS_PARTIAL_SPECIALIZATION -# endif -# if (_COMPILER_VERSION >= 730) && defined(_MIPS_SIM) && _MIPS_SIM != _ABIO32 -# define __STL_FUNCTION_TMPL_PARTIAL_ORDER -# endif -# ifdef _MEMBER_TEMPLATES -# define __STL_MEMBER_TEMPLATES -# define __STL_TEMPLATE_FRIENDS -# define __STL_MEMBER_TEMPLATE_CLASSES -# endif -# if defined(_MEMBER_TEMPLATE_KEYWORD) -# define __STL_MEMBER_TEMPLATE_KEYWORD -# endif -# if defined(_STANDARD_C_PLUS_PLUS) -# define __STL_EXPLICIT_FUNCTION_TMPL_ARGS -# endif -# if (_COMPILER_VERSION >= 730) && defined(_MIPS_SIM) && _MIPS_SIM != _ABIO32 -# define __STL_MEMBER_TEMPLATE_KEYWORD -# endif -# if COMPILER_VERSION < 720 || (defined(_MIPS_SIM) && _MIPS_SIM == _ABIO32) -# define __STL_DEFAULT_CONSTRUCTOR_BUG -# endif -# if !defined(_EXPLICIT_IS_KEYWORD) -# define __STL_NEED_EXPLICIT -# endif -# ifdef __EXCEPTIONS -# define __STL_USE_EXCEPTIONS -# endif -# if (_COMPILER_VERSION >= 721) && defined(_NAMESPACES) -# define __STL_HAS_NAMESPACES -# endif -# if (_COMPILER_VERSION < 721) || \ - !defined(__STL_HAS_NAMESPACES) || defined(__STL_NO_NAMESPACES) -# define __STL_NO_EXCEPTION_HEADER -# endif -# if _COMPILER_VERSION < 730 || !defined(_STANDARD_C_PLUS_PLUS) || \ - !defined(_NAMESPACES) -# define __STL_NO_BAD_ALLOC -# endif -# if !defined(_NOTHREADS) && !defined(__STL_PTHREADS) -# define __STL_SGI_THREADS -# endif -# if defined(_LONGLONG) && defined(_SGIAPI) && _SGIAPI -# define __STL_LONG_LONG -# endif -# if _COMPILER_VERSION >= 730 && defined(_STANDARD_C_PLUS_PLUS) -# define __STL_USE_NEW_IOSTREAMS -# endif -# if _COMPILER_VERSION >= 730 && defined(_STANDARD_C_PLUS_PLUS) -# define __STL_CAN_THROW_RANGE_ERRORS -# endif -# if _COMPILER_VERSION >= 730 && defined(_STANDARD_C_PLUS_PLUS) -# define __SGI_STL_USE_AUTO_PTR_CONVERSIONS -# endif -# endif - - -/* - * Jochen Schlick '1999 - added new #defines (__STL)_UITHREADS (for - * providing SCO / Solaris / UI thread support) - * - added the necessary defines for the SCO UDK 7 - * compiler (and its template friend behavior) - * - all UDK7 specific STL changes are based on the - * macro __USLC__ being defined - */ -// SCO UDK 7 compiler (UnixWare 7x, OSR 5, UnixWare 2x) -# if defined(__USLC__) -# define __STL_HAS_WCHAR_T -# define __STL_CLASS_PARTIAL_SPECIALIZATION -# define __STL_PARTIAL_SPECIALIZATION_SYNTAX -# define __STL_FUNCTION_TMPL_PARTIAL_ORDER -# define __STL_MEMBER_TEMPLATES -# define __STL_MEMBER_TEMPLATE_CLASSES -# define __STL_USE_EXCEPTIONS -# define __STL_HAS_NAMESPACES -# define __STL_USE_NAMESPACES -# define __STL_LONG_LONG -# if defined(_REENTRANT) -# define _UITHREADS /* if UnixWare < 7.0.1 */ -# define __STL_UITHREADS -// use the following defines instead of the UI threads defines when -// you want to use POSIX threads -//# define _PTHREADS /* only if UnixWare >=7.0.1 */ -//# define __STL_PTHREADS -# endif -# endif - - - -# ifdef __GNUC__ -# if __GNUC__ == 2 && __GNUC_MINOR__ <= 7 -# define __STL_STATIC_TEMPLATE_MEMBER_BUG -# endif -# if __GNUC__ < 2 -# define __STL_NEED_TYPENAME -# define __STL_NEED_EXPLICIT -# endif -# if __GNUC__ == 2 && __GNUC_MINOR__ <= 8 -# define __STL_NO_EXCEPTION_HEADER -# define __STL_NO_BAD_ALLOC -# endif -# if __GNUC__ == 2 && __GNUC_MINOR__ >= 8 || __GNUC__ > 2 -# define __STL_CLASS_PARTIAL_SPECIALIZATION -# define __STL_FUNCTION_TMPL_PARTIAL_ORDER -# define __STL_EXPLICIT_FUNCTION_TMPL_ARGS -# define __STL_MEMBER_TEMPLATES -# define __STL_CAN_THROW_RANGE_ERRORS - // g++ 2.8.1 supports member template functions, but not member - // template nested classes. -# if __GNUC_MINOR__ >= 9 || __GNUC__ > 2 -# define __STL_MEMBER_TEMPLATE_CLASSES -# define __STL_TEMPLATE_FRIENDS -# define __SGI_STL_USE_AUTO_PTR_CONVERSIONS -# define __STL_HAS_NAMESPACES -//# define __STL_USE_NEW_IOSTREAMS -# endif -# endif -# define __STL_DEFAULT_CONSTRUCTOR_BUG -# ifdef __EXCEPTIONS -# define __STL_USE_EXCEPTIONS -# endif -# ifdef _REENTRANT -# define __STL_PTHREADS -# endif -# if (__GNUC__ < 2) || (__GNUC__ == 2 && __GNUC_MINOR__ < 95) -# define __STL_NO_FUNCTION_PTR_IN_CLASS_TEMPLATE -# endif -# endif - -# if defined(__SUNPRO_CC) -# define __STL_NO_BOOL -# define __STL_NEED_TYPENAME -# define __STL_NEED_EXPLICIT -# define __STL_USE_EXCEPTIONS -# ifdef _REENTRANT -# define __STL_PTHREADS -# endif -# define __SGI_STL_NO_ARROW_OPERATOR -# define __STL_PARTIAL_SPECIALIZATION_SYNTAX -# define __STL_NO_EXCEPTION_HEADER -# define __STL_NO_BAD_ALLOC -# endif - -# if defined(__COMO__) -# define __STL_MEMBER_TEMPLATES -# define __STL_MEMBER_TEMPLATE_CLASSES -# define __STL_TEMPLATE_FRIENDS -# define __STL_CLASS_PARTIAL_SPECIALIZATION -# define __STL_USE_EXCEPTIONS -# define __STL_HAS_NAMESPACES -# endif - -// Intel compiler, which uses the EDG front end. -# if defined(__ICL) -# define __STL_LONG_LONG -# define __STL_MEMBER_TEMPLATES -# define __STL_MEMBER_TEMPLATE_CLASSES -# define __STL_TEMPLATE_FRIENDS -# define __STL_FUNCTION_TMPL_PARTIAL_ORDER -# define __STL_CLASS_PARTIAL_SPECIALIZATION -# define __STL_NO_DRAND48 -# define __STL_HAS_NAMESPACES -# define __STL_USE_EXCEPTIONS -# define __STL_MEMBER_TEMPLATE_KEYWORD -# ifdef _CPPUNWIND -# define __STL_USE_EXCEPTIONS -# endif -# ifdef _MT -# define __STL_WIN32THREADS -# endif -# endif - -// Mingw32, egcs compiler using the Microsoft C runtime -# if defined(__MINGW32__) -# define __STL_NO_DRAND48 -# ifdef _MT -# define __STL_WIN32THREADS -# endif -# endif - -// Cygwin32, egcs compiler on MS Windows -# if defined(__CYGWIN__) -# define __STL_NO_DRAND48 -# endif - - - -// Microsoft compiler. -# if defined(_MSC_VER) && !defined(__ICL) && !defined(__MWERKS__) -# define __STL_NO_DRAND48 -# define __STL_STATIC_CONST_INIT_BUG -# define __STL_NEED_TYPENAME -# define __STL_NO_USING_CLAUSE_IN_CLASS -# define __STL_NO_FRIEND_TEMPLATE_CLASS -# if _MSC_VER < 1100 /* 1000 is version 4.0, 1100 is 5.0, 1200 is 6.0. */ -# define __STL_NEED_EXPLICIT -# define __STL_NO_BOOL -# define __STL_NO_BAD_ALLOC -# endif -# if _MSC_VER > 1000 -# include <yvals.h> -# define __STL_DONT_USE_BOOL_TYPEDEF -# endif -# define __STL_NON_TYPE_TMPL_PARAM_BUG -# define __SGI_STL_NO_ARROW_OPERATOR -# define __STL_DEFAULT_CONSTRUCTOR_BUG -# ifdef _CPPUNWIND -# define __STL_USE_EXCEPTIONS -# endif -# ifdef _MT -# define __STL_WIN32THREADS -# endif -# if _MSC_VER >= 1200 -# define __STL_PARTIAL_SPECIALIZATION_SYNTAX -# define __STL_HAS_NAMESPACES -# define __STL_CAN_THROW_RANGE_ERRORS -# define NOMINMAX -# undef min -# undef max -// disable warning 'initializers put in unrecognized initialization area' -# pragma warning ( disable : 4075 ) -// disable warning 'empty controlled statement found' -# pragma warning ( disable : 4390 ) -// disable warning 'debug symbol greater than 255 chars' -# pragma warning ( disable : 4786 ) -# endif -# if _MSC_VER < 1100 -# define __STL_NO_EXCEPTION_HEADER -# define __STL_NO_BAD_ALLOC -# endif - // Because of a Microsoft front end bug, we must not provide a - // namespace qualifier when declaring a friend function. -# define __STD_QUALIFIER -# endif - -# if defined(__BORLANDC__) -# define __STL_NO_BAD_ALLOC -# define __STL_NO_DRAND48 -# define __STL_DEFAULT_CONSTRUCTOR_BUG -# if __BORLANDC__ >= 0x540 /* C++ Builder 4.0 */ -# define __STL_CLASS_PARTIAL_SPECIALIZATION -# define __STL_FUNCTION_TMPL_PARTIAL_ORDER -# define __STL_EXPLICIT_FUNCTION_TMPL_ARGS -# define __STL_MEMBER_TEMPLATES -# define __STL_TEMPLATE_FRIENDS -# else -# define __STL_NEED_TYPENAME -# define __STL_LIMITED_DEFAULT_TEMPLATES -# define __SGI_STL_NO_ARROW_OPERATOR -# define __STL_NON_TYPE_TMPL_PARAM_BUG -# endif -# ifdef _CPPUNWIND -# define __STL_USE_EXCEPTIONS -# endif -# ifdef __MT__ -# define __STL_WIN32THREADS -# endif -# endif - -# if defined(__STL_NO_BOOL) && !defined(__STL_DONT_USE_BOOL_TYPEDEF) - typedef int bool; -# define true 1 -# define false 0 -# endif - -# ifdef __STL_NEED_TYPENAME -# define typename -# endif - -# ifdef __STL_LIMITED_DEFAULT_TEMPLATES -# define __STL_DEPENDENT_DEFAULT_TMPL(_Tp) -# else -# define __STL_DEPENDENT_DEFAULT_TMPL(_Tp) = _Tp -# endif - -# ifdef __STL_MEMBER_TEMPLATE_KEYWORD -# define __STL_TEMPLATE template -# else -# define __STL_TEMPLATE -# endif - -# ifdef __STL_NEED_EXPLICIT -# define explicit -# endif - -# ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS -# define __STL_NULL_TMPL_ARGS <> -# else -# define __STL_NULL_TMPL_ARGS -# endif - -# if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) \ - || defined (__STL_PARTIAL_SPECIALIZATION_SYNTAX) -# define __STL_TEMPLATE_NULL template<> -# else -# define __STL_TEMPLATE_NULL -# endif - -// Use standard-conforming allocators if we have the necessary language -// features. __STL_USE_SGI_ALLOCATORS is a hook so that users can -// disable new-style allocators, and continue to use the same kind of -// allocators as before, without having to edit library headers. -# if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && \ - defined(__STL_MEMBER_TEMPLATES) && \ - defined(__STL_MEMBER_TEMPLATE_CLASSES) && \ - !defined(__STL_NO_BOOL) && \ - !defined(__STL_NON_TYPE_TMPL_PARAM_BUG) && \ - !defined(__STL_LIMITED_DEFAULT_TEMPLATES) && \ - !defined(__STL_USE_SGI_ALLOCATORS) -# define __STL_USE_STD_ALLOCATORS -# endif - -# ifndef __STL_DEFAULT_ALLOCATOR -# ifdef __STL_USE_STD_ALLOCATORS -# define __STL_DEFAULT_ALLOCATOR(T) allocator< T > -# else -# define __STL_DEFAULT_ALLOCATOR(T) alloc -# endif -# endif - -// __STL_NO_NAMESPACES is a hook so that users can disable namespaces -// without having to edit library headers. __STL_NO_RELOPS_NAMESPACE is -// a hook so that users can disable the std::rel_ops namespace, keeping -// the relational operator template in namespace std, without having to -// edit library headers. -# if defined(__STL_HAS_NAMESPACES) && !defined(__STL_NO_NAMESPACES) -# define __STL_USE_NAMESPACES -# define __STD std -# define __STL_BEGIN_NAMESPACE namespace std { -# define __STL_END_NAMESPACE } -# if defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) && \ - !defined(__STL_NO_RELOPS_NAMESPACE) -# define __STL_USE_NAMESPACE_FOR_RELOPS -# define __STL_BEGIN_RELOPS_NAMESPACE namespace std { namespace rel_ops { -# define __STL_END_RELOPS_NAMESPACE } } -# define __STD_RELOPS std::rel_ops -# else /* Use std::rel_ops namespace */ -# define __STL_USE_NAMESPACE_FOR_RELOPS -# define __STL_BEGIN_RELOPS_NAMESPACE namespace std { -# define __STL_END_RELOPS_NAMESPACE } -# define __STD_RELOPS std -# endif /* Use std::rel_ops namespace */ -# else -# define __STD -# define __STL_BEGIN_NAMESPACE -# define __STL_END_NAMESPACE -# undef __STL_USE_NAMESPACE_FOR_RELOPS -# define __STL_BEGIN_RELOPS_NAMESPACE -# define __STL_END_RELOPS_NAMESPACE -# define __STD_RELOPS -# undef __STL_USE_NAMESPACES -# endif - -// Some versions of the EDG front end sometimes require an explicit -// namespace spec where they shouldn't. This macro facilitates that. -// If the bug becomes irrelevant, then all uses of __STD_QUALIFIER -// should be removed. The 7.3 beta SGI compiler has this bug, but the -// MR version is not expected to have it. - -# if defined(__STL_USE_NAMESPACES) && !defined(__STD_QUALIFIER) -# define __STD_QUALIFIER std:: -# else -# define __STD_QUALIFIER -# endif - -# ifdef __STL_USE_EXCEPTIONS -# define __STL_TRY try -# define __STL_CATCH_ALL catch(...) -# define __STL_THROW(x) throw x -# define __STL_RETHROW throw -# define __STL_NOTHROW throw() -# define __STL_UNWIND(action) catch(...) { action; throw; } -# else -# define __STL_TRY -# define __STL_CATCH_ALL if (false) -# define __STL_THROW(x) -# define __STL_RETHROW -# define __STL_NOTHROW -# define __STL_UNWIND(action) -# endif - -#ifdef __STL_ASSERTIONS -# include <stdio.h> -# define __stl_assert(expr) \ - if (!(expr)) { fprintf(stderr, "%s:%d STL assertion failure: %s\n", \ - __FILE__, __LINE__, # expr); abort(); } -#else -# define __stl_assert(expr) -#endif - -#if defined(__STL_WIN32THREADS) || defined(__STL_SGI_THREADS) \ - || defined(__STL_PTHREADS) || defined(__STL_UITHREADS) -# define __STL_THREADS -# define __STL_VOLATILE volatile -#else -# define __STL_VOLATILE -#endif - -#if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) \ - && defined(__STL_MEMBER_TEMPLATES) \ - && !defined(_STL_NO_CONCEPT_CHECKS) -# define __STL_USE_CONCEPT_CHECKS -#endif - - -#endif /* __STL_CONFIG_H */ - -// Local Variables: -// mode:C++ -// End: diff --git a/WebCore/platform/android/stl/stl_heap.h b/WebCore/platform/android/stl/stl_heap.h deleted file mode 100644 index 651d21a..0000000 --- a/WebCore/platform/android/stl/stl_heap.h +++ /dev/null @@ -1,297 +0,0 @@ -/* - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * Copyright (c) 1997 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - */ - -/* NOTE: This is an internal header file, included by other STL headers. - * You should not attempt to use it directly. - */ - -#ifndef __SGI_STL_INTERNAL_HEAP_H -#define __SGI_STL_INTERNAL_HEAP_H - -__STL_BEGIN_NAMESPACE - -#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) -#pragma set woff 1209 -#endif - -// Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap. - -template <class _RandomAccessIterator, class _Distance, class _Tp> -void -__push_heap(_RandomAccessIterator __first, - _Distance __holeIndex, _Distance __topIndex, _Tp __value) -{ - _Distance __parent = (__holeIndex - 1) / 2; - while (__holeIndex > __topIndex && *(__first + __parent) < __value) { - *(__first + __holeIndex) = *(__first + __parent); - __holeIndex = __parent; - __parent = (__holeIndex - 1) / 2; - } - *(__first + __holeIndex) = __value; -} - -template <class _RandomAccessIterator, class _Distance, class _Tp> -inline void -__push_heap_aux(_RandomAccessIterator __first, - _RandomAccessIterator __last, _Distance*, _Tp*) -{ - __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0), - _Tp(*(__last - 1))); -} - -template <class _RandomAccessIterator> -inline void -push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) -{ - __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); - __STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type, - _LessThanComparable); - __push_heap_aux(__first, __last, - __DISTANCE_TYPE(__first), __VALUE_TYPE(__first)); -} - -template <class _RandomAccessIterator, class _Distance, class _Tp, - class _Compare> -void -__push_heap(_RandomAccessIterator __first, _Distance __holeIndex, - _Distance __topIndex, _Tp __value, _Compare __comp) -{ - _Distance __parent = (__holeIndex - 1) / 2; - while (__holeIndex > __topIndex && __comp(*(__first + __parent), __value)) { - *(__first + __holeIndex) = *(__first + __parent); - __holeIndex = __parent; - __parent = (__holeIndex - 1) / 2; - } - *(__first + __holeIndex) = __value; -} - -template <class _RandomAccessIterator, class _Compare, - class _Distance, class _Tp> -inline void -__push_heap_aux(_RandomAccessIterator __first, - _RandomAccessIterator __last, _Compare __comp, - _Distance*, _Tp*) -{ - __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0), - _Tp(*(__last - 1)), __comp); -} - -template <class _RandomAccessIterator, class _Compare> -inline void -push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, - _Compare __comp) -{ - __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); - __push_heap_aux(__first, __last, __comp, - __DISTANCE_TYPE(__first), __VALUE_TYPE(__first)); -} - -template <class _RandomAccessIterator, class _Distance, class _Tp> -void -__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, - _Distance __len, _Tp __value) -{ - _Distance __topIndex = __holeIndex; - _Distance __secondChild = 2 * __holeIndex + 2; - while (__secondChild < __len) { - if (*(__first + __secondChild) < *(__first + (__secondChild - 1))) - __secondChild--; - *(__first + __holeIndex) = *(__first + __secondChild); - __holeIndex = __secondChild; - __secondChild = 2 * (__secondChild + 1); - } - if (__secondChild == __len) { - *(__first + __holeIndex) = *(__first + (__secondChild - 1)); - __holeIndex = __secondChild - 1; - } - __push_heap(__first, __holeIndex, __topIndex, __value); -} - -template <class _RandomAccessIterator, class _Tp, class _Distance> -inline void -__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, - _RandomAccessIterator __result, _Tp __value, _Distance*) -{ - *__result = *__first; - __adjust_heap(__first, _Distance(0), _Distance(__last - __first), __value); -} - -template <class _RandomAccessIterator, class _Tp> -inline void -__pop_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last, - _Tp*) -{ - __pop_heap(__first, __last - 1, __last - 1, - _Tp(*(__last - 1)), __DISTANCE_TYPE(__first)); -} - -template <class _RandomAccessIterator> -inline void pop_heap(_RandomAccessIterator __first, - _RandomAccessIterator __last) -{ - __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); - __STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type, - _LessThanComparable); - __pop_heap_aux(__first, __last, __VALUE_TYPE(__first)); -} - -template <class _RandomAccessIterator, class _Distance, - class _Tp, class _Compare> -void -__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, - _Distance __len, _Tp __value, _Compare __comp) -{ - _Distance __topIndex = __holeIndex; - _Distance __secondChild = 2 * __holeIndex + 2; - while (__secondChild < __len) { - if (__comp(*(__first + __secondChild), *(__first + (__secondChild - 1)))) - __secondChild--; - *(__first + __holeIndex) = *(__first + __secondChild); - __holeIndex = __secondChild; - __secondChild = 2 * (__secondChild + 1); - } - if (__secondChild == __len) { - *(__first + __holeIndex) = *(__first + (__secondChild - 1)); - __holeIndex = __secondChild - 1; - } - __push_heap(__first, __holeIndex, __topIndex, __value, __comp); -} - -template <class _RandomAccessIterator, class _Tp, class _Compare, - class _Distance> -inline void -__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, - _RandomAccessIterator __result, _Tp __value, _Compare __comp, - _Distance*) -{ - *__result = *__first; - __adjust_heap(__first, _Distance(0), _Distance(__last - __first), - __value, __comp); -} - -template <class _RandomAccessIterator, class _Tp, class _Compare> -inline void -__pop_heap_aux(_RandomAccessIterator __first, - _RandomAccessIterator __last, _Tp*, _Compare __comp) -{ - __pop_heap(__first, __last - 1, __last - 1, _Tp(*(__last - 1)), __comp, - __DISTANCE_TYPE(__first)); -} - -template <class _RandomAccessIterator, class _Compare> -inline void -pop_heap(_RandomAccessIterator __first, - _RandomAccessIterator __last, _Compare __comp) -{ - __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); - __pop_heap_aux(__first, __last, __VALUE_TYPE(__first), __comp); -} - -template <class _RandomAccessIterator, class _Tp, class _Distance> -void -__make_heap(_RandomAccessIterator __first, - _RandomAccessIterator __last, _Tp*, _Distance*) -{ - if (__last - __first < 2) return; - _Distance __len = __last - __first; - _Distance __parent = (__len - 2)/2; - - while (true) { - __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent))); - if (__parent == 0) return; - __parent--; - } -} - -template <class _RandomAccessIterator> -inline void -make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) -{ - __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); - __STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type, - _LessThanComparable); - __make_heap(__first, __last, - __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); -} - -template <class _RandomAccessIterator, class _Compare, - class _Tp, class _Distance> -void -__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, - _Compare __comp, _Tp*, _Distance*) -{ - if (__last - __first < 2) return; - _Distance __len = __last - __first; - _Distance __parent = (__len - 2)/2; - - while (true) { - __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent)), - __comp); - if (__parent == 0) return; - __parent--; - } -} - -template <class _RandomAccessIterator, class _Compare> -inline void -make_heap(_RandomAccessIterator __first, - _RandomAccessIterator __last, _Compare __comp) -{ - __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); - __make_heap(__first, __last, __comp, - __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); -} - -template <class _RandomAccessIterator> -void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) -{ - __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); - __STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type, - _LessThanComparable); - while (__last - __first > 1) - pop_heap(__first, __last--); -} - -template <class _RandomAccessIterator, class _Compare> -void -sort_heap(_RandomAccessIterator __first, - _RandomAccessIterator __last, _Compare __comp) -{ - __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); - while (__last - __first > 1) - pop_heap(__first, __last--, __comp); -} - -#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) -#pragma reset woff 1209 -#endif - -__STL_END_NAMESPACE - -#endif /* __SGI_STL_INTERNAL_HEAP_H */ - -// Local Variables: -// mode:C++ -// End: diff --git a/WebCore/platform/android/stl/stl_iterator_base.h b/WebCore/platform/android/stl/stl_iterator_base.h deleted file mode 100644 index d03332b..0000000 --- a/WebCore/platform/android/stl/stl_iterator_base.h +++ /dev/null @@ -1,273 +0,0 @@ -/* - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * - * Copyright (c) 1996-1998 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - */ - -/* NOTE: This is an internal header file, included by other STL headers. - * You should not attempt to use it directly. - */ - -#ifndef __SGI_STL_INTERNAL_ITERATOR_BASE_H -#define __SGI_STL_INTERNAL_ITERATOR_BASE_H - -// This file contains all of the general iterator-related utilities. -// The internal file stl_iterator.h contains predefined iterators, -// such as front_insert_iterator and istream_iterator. - -#include <concept_checks.h> - -struct input_iterator_tag {}; -struct output_iterator_tag {}; -struct forward_iterator_tag : public input_iterator_tag {}; -struct bidirectional_iterator_tag : public forward_iterator_tag {}; -struct random_access_iterator_tag : public bidirectional_iterator_tag {}; - -// The base classes input_iterator, output_iterator, forward_iterator, -// bidirectional_iterator, and random_access_iterator are not part of -// the C++ standard. (They have been replaced by struct iterator.) -// They are included for backward compatibility with the HP STL. - -template <class _Tp, class _Distance> struct input_iterator { - typedef input_iterator_tag iterator_category; - typedef _Tp value_type; - typedef _Distance difference_type; - typedef _Tp* pointer; - typedef _Tp& reference; -}; - -struct output_iterator { - typedef output_iterator_tag iterator_category; - typedef void value_type; - typedef void difference_type; - typedef void pointer; - typedef void reference; -}; - -template <class _Tp, class _Distance> struct forward_iterator { - typedef forward_iterator_tag iterator_category; - typedef _Tp value_type; - typedef _Distance difference_type; - typedef _Tp* pointer; - typedef _Tp& reference; -}; - - -template <class _Tp, class _Distance> struct bidirectional_iterator { - typedef bidirectional_iterator_tag iterator_category; - typedef _Tp value_type; - typedef _Distance difference_type; - typedef _Tp* pointer; - typedef _Tp& reference; -}; - -template <class _Tp, class _Distance> struct random_access_iterator { - typedef random_access_iterator_tag iterator_category; - typedef _Tp value_type; - typedef _Distance difference_type; - typedef _Tp* pointer; - typedef _Tp& reference; -}; - -template <class _Category, class _Tp, class _Distance = ptrdiff_t, - class _Pointer = _Tp*, class _Reference = _Tp&> -struct iterator { - typedef _Category iterator_category; - typedef _Tp value_type; - typedef _Distance difference_type; - typedef _Pointer pointer; - typedef _Reference reference; -}; - -template <class _Iterator> -struct iterator_traits { - typedef typename _Iterator::iterator_category iterator_category; - typedef typename _Iterator::value_type value_type; - typedef typename _Iterator::difference_type difference_type; - typedef typename _Iterator::pointer pointer; - typedef typename _Iterator::reference reference; -}; - -template <class _Tp> -struct iterator_traits<_Tp*> { - typedef random_access_iterator_tag iterator_category; - typedef _Tp value_type; - typedef ptrdiff_t difference_type; - typedef _Tp* pointer; - typedef _Tp& reference; -}; - -template <class _Tp> -struct iterator_traits<const _Tp*> { - typedef random_access_iterator_tag iterator_category; - typedef _Tp value_type; - typedef ptrdiff_t difference_type; - typedef const _Tp* pointer; - typedef const _Tp& reference; -}; - -// The overloaded functions iterator_category, distance_type, and -// value_type are not part of the C++ standard. (They have been -// replaced by struct iterator_traits.) They are included for -// backward compatibility with the HP STL. - -// We introduce internal names for these functions. - -template <class _Iter> -inline typename iterator_traits<_Iter>::iterator_category -__iterator_category(const _Iter&) -{ - typedef typename iterator_traits<_Iter>::iterator_category _Category; - return _Category(); -} - -template <class _Iter> -inline typename iterator_traits<_Iter>::difference_type* -__distance_type(const _Iter&) -{ - return static_cast<typename iterator_traits<_Iter>::difference_type*>(0); -} - -template <class _Iter> -inline typename iterator_traits<_Iter>::value_type* -__value_type(const _Iter&) -{ - return static_cast<typename iterator_traits<_Iter>::value_type*>(0); -} - -template <class _Iter> -inline typename iterator_traits<_Iter>::iterator_category -iterator_category(const _Iter& __i) { return __iterator_category(__i); } - - -template <class _Iter> -inline typename iterator_traits<_Iter>::difference_type* -distance_type(const _Iter& __i) { return __distance_type(__i); } - -template <class _Iter> -inline typename iterator_traits<_Iter>::value_type* -value_type(const _Iter& __i) { return __value_type(__i); } - -#define __ITERATOR_CATEGORY(__i) __iterator_category(__i) -#define __DISTANCE_TYPE(__i) __distance_type(__i) -#define __VALUE_TYPE(__i) __value_type(__i) - -template <class _InputIterator, class _Distance> -inline void __distance(_InputIterator __first, _InputIterator __last, - _Distance& __n, input_iterator_tag) -{ - while (__first != __last) { ++__first; ++__n; } -} - -template <class _RandomAccessIterator, class _Distance> -inline void __distance(_RandomAccessIterator __first, - _RandomAccessIterator __last, - _Distance& __n, random_access_iterator_tag) -{ - __STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator); - __n += __last - __first; -} - -template <class _InputIterator, class _Distance> -inline void distance(_InputIterator __first, - _InputIterator __last, _Distance& __n) -{ - __STL_REQUIRES(_InputIterator, _InputIterator); - __distance(__first, __last, __n, iterator_category(__first)); -} - -#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION - -template <class _InputIterator> -inline typename iterator_traits<_InputIterator>::difference_type -__distance(_InputIterator __first, _InputIterator __last, input_iterator_tag) -{ - typename iterator_traits<_InputIterator>::difference_type __n = 0; - while (__first != __last) { - ++__first; ++__n; - } - return __n; -} - -template <class _RandomAccessIterator> -inline typename iterator_traits<_RandomAccessIterator>::difference_type -__distance(_RandomAccessIterator __first, _RandomAccessIterator __last, - random_access_iterator_tag) { - __STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator); - return __last - __first; -} - -template <class _InputIterator> -inline typename iterator_traits<_InputIterator>::difference_type -distance(_InputIterator __first, _InputIterator __last) { - typedef typename iterator_traits<_InputIterator>::iterator_category - _Category; - __STL_REQUIRES(_InputIterator, _InputIterator); - return __distance(__first, __last, _Category()); -} - -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - -template <class _InputIter, class _Distance> -inline void __advance(_InputIter& __i, _Distance __n, input_iterator_tag) { - while (__n--) ++__i; -} - -#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) -#pragma set woff 1183 -#endif - -template <class _BidirectionalIterator, class _Distance> -inline void __advance(_BidirectionalIterator& __i, _Distance __n, - bidirectional_iterator_tag) { - __STL_REQUIRES(_BidirectionalIterator, _BidirectionalIterator); - if (__n >= 0) - while (__n--) ++__i; - else - while (__n++) --__i; -} - -#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) -#pragma reset woff 1183 -#endif - -template <class _RandomAccessIterator, class _Distance> -inline void __advance(_RandomAccessIterator& __i, _Distance __n, - random_access_iterator_tag) { - __STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator); - __i += __n; -} - -template <class _InputIterator, class _Distance> -inline void advance(_InputIterator& __i, _Distance __n) { - __STL_REQUIRES(_InputIterator, _InputIterator); - __advance(__i, __n, iterator_category(__i)); -} - -#endif /* __SGI_STL_INTERNAL_ITERATOR_BASE_H */ - - - -// Local Variables: -// mode:C++ -// End: diff --git a/WebCore/platform/android/stl/strings.h b/WebCore/platform/android/stl/strings.h deleted file mode 100644 index 13d6d4e..0000000 --- a/WebCore/platform/android/stl/strings.h +++ /dev/null @@ -1,17 +0,0 @@ -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - |